Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed the initialization of the chain simulator when working with 0-value activation epochs #6126

Merged
merged 6 commits into from
Apr 24, 2024
3 changes: 2 additions & 1 deletion epochStart/metachain/legacySystemSCs.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ func (s *legacySystemSCProcessor) processLegacy(
}
}

if s.flagChangeMaxNodesEnabled.IsSet() {
// the updateMaxNodes call needs the StakingV2Flag functionality to be enabled. Otherwise, the call will error
if s.flagChangeMaxNodesEnabled.IsSet() && s.enableEpochsHandler.IsFlagEnabled(common.StakingV2Flag) {
err := s.updateMaxNodes(validatorsInfoMap, nonce)
if err != nil {
return err
Expand Down
3 changes: 3 additions & 0 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,3 +595,6 @@ var ErrInvalidNodeOperationMode = errors.New("invalid node operation mode")

// ErrNilSentSignatureTracker defines the error for setting a nil SentSignatureTracker
var ErrNilSentSignatureTracker = errors.New("nil sent signature tracker")

// ErrNilEpochSystemSCProcessor defines the error for setting a nil EpochSystemSCProcessor
var ErrNilEpochSystemSCProcessor = errors.New("nil epoch system SC processor")
42 changes: 42 additions & 0 deletions factory/disabled/epochStartSystemSCProcessor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package disabled

import (
"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"
)

type epochStartSystemSCProcessor struct {
}

// NewDisabledEpochStartSystemSC creates a new disabled EpochStartSystemSCProcessor instance
func NewDisabledEpochStartSystemSC() *epochStartSystemSCProcessor {
return &epochStartSystemSCProcessor{}
}

// ToggleUnStakeUnBond returns nil
func (e *epochStartSystemSCProcessor) ToggleUnStakeUnBond(_ bool) error {
return nil
}

// ProcessSystemSmartContract returns nil
func (e *epochStartSystemSCProcessor) ProcessSystemSmartContract(
_ state.ShardValidatorsInfoMapHandler,
_ data.HeaderHandler,
) error {
return nil
}

// ProcessDelegationRewards returns nil
func (e *epochStartSystemSCProcessor) ProcessDelegationRewards(
_ block.MiniBlockSlice,
_ epochStart.TransactionCacher,
) error {
return nil
}

// IsInterfaceNil returns true if there is no value under the interface
func (e *epochStartSystemSCProcessor) IsInterfaceNil() bool {
return e == nil
}
1 change: 1 addition & 0 deletions factory/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ type ProcessComponentsHolder interface {
AccountsParser() genesis.AccountsParser
ReceiptsRepository() ReceiptsRepository
SentSignaturesTracker() process.SentSignaturesTracker
EpochSystemSCProcessor() process.EpochStartSystemSCProcessor
IsInterfaceNil() bool
}

Expand Down
6 changes: 6 additions & 0 deletions factory/mock/processComponentsStub.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type ProcessComponentsMock struct {
AccountsParserInternal genesis.AccountsParser
ReceiptsRepositoryInternal factory.ReceiptsRepository
SentSignaturesTrackerInternal process.SentSignaturesTracker
EpochSystemSCProcessorInternal process.EpochStartSystemSCProcessor
}

// Create -
Expand Down Expand Up @@ -284,6 +285,11 @@ func (pcm *ProcessComponentsMock) SentSignaturesTracker() process.SentSignatures
return pcm.SentSignaturesTrackerInternal
}

// EpochSystemSCProcessor -
func (pcm *ProcessComponentsMock) EpochSystemSCProcessor() process.EpochStartSystemSCProcessor {
return pcm.EpochSystemSCProcessorInternal
}

// IsInterfaceNil -
func (pcm *ProcessComponentsMock) IsInterfaceNil() bool {
return pcm == nil
Expand Down
3 changes: 3 additions & 0 deletions factory/processing/blockProcessorCreator.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import (
type blockProcessorAndVmFactories struct {
blockProcessor process.BlockProcessor
vmFactoryForProcessing process.VirtualMachinesContainerFactory
epochSystemSCProcessor process.EpochStartSystemSCProcessor
}

func (pcf *processComponentsFactory) newBlockProcessor(
Expand Down Expand Up @@ -453,6 +454,7 @@ func (pcf *processComponentsFactory) newShardBlockProcessor(
blockProcessorComponents := &blockProcessorAndVmFactories{
blockProcessor: blockProcessor,
vmFactoryForProcessing: vmFactory,
epochSystemSCProcessor: factoryDisabled.NewDisabledEpochStartSystemSC(),
}

pcf.stakingDataProviderAPI = factoryDisabled.NewDisabledStakingDataProvider()
Expand Down Expand Up @@ -982,6 +984,7 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor(
blockProcessorComponents := &blockProcessorAndVmFactories{
blockProcessor: metaProcessor,
vmFactoryForProcessing: vmFactory,
epochSystemSCProcessor: epochStartSystemSCProcessor,
}

return blockProcessorComponents, nil
Expand Down
7 changes: 5 additions & 2 deletions factory/processing/blockProcessorCreator_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package processing_test

import (
"fmt"
"sync"
"testing"

Expand Down Expand Up @@ -40,7 +41,7 @@ func Test_newBlockProcessorCreatorForShard(t *testing.T) {
_, err = pcf.Create()
require.NoError(t, err)

bp, err := pcf.NewBlockProcessor(
bp, epochStartSCProc, err := pcf.NewBlockProcessor(
&testscommon.RequestHandlerStub{},
&processMocks.ForkDetectorStub{},
&mock.EpochStartTriggerStub{},
Expand All @@ -60,6 +61,7 @@ func Test_newBlockProcessorCreatorForShard(t *testing.T) {

require.NoError(t, err)
require.NotNil(t, bp)
require.Equal(t, "*disabled.epochStartSystemSCProcessor", fmt.Sprintf("%T", epochStartSCProc))
}

func Test_newBlockProcessorCreatorForMeta(t *testing.T) {
Expand Down Expand Up @@ -166,7 +168,7 @@ func Test_newBlockProcessorCreatorForMeta(t *testing.T) {
_, err = pcf.Create()
require.NoError(t, err)

bp, err := pcf.NewBlockProcessor(
bp, epochStartSCProc, err := pcf.NewBlockProcessor(
&testscommon.RequestHandlerStub{},
&processMocks.ForkDetectorStub{},
&mock.EpochStartTriggerStub{},
Expand All @@ -186,6 +188,7 @@ func Test_newBlockProcessorCreatorForMeta(t *testing.T) {

require.NoError(t, err)
require.NotNil(t, bp)
require.Equal(t, "*metachain.systemSCProcessor", fmt.Sprintf("%T", epochStartSCProc))
}

func createAccountAdapter(
Expand Down
6 changes: 3 additions & 3 deletions factory/processing/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (pcf *processComponentsFactory) NewBlockProcessor(
blockProcessingCutoff cutoff.BlockProcessingCutoffHandler,
missingTrieNodesNotifier common.MissingTrieNodesNotifier,
sentSignaturesTracker process.SentSignaturesTracker,
) (process.BlockProcessor, error) {
) (process.BlockProcessor, process.EpochStartSystemSCProcessor, error) {
blockProcessorComponents, err := pcf.newBlockProcessor(
requestHandler,
forkDetector,
Expand All @@ -44,10 +44,10 @@ func (pcf *processComponentsFactory) NewBlockProcessor(
sentSignaturesTracker,
)
if err != nil {
return nil, err
return nil, nil, err
}

return blockProcessorComponents.blockProcessor, nil
return blockProcessorComponents.blockProcessor, blockProcessorComponents.epochSystemSCProcessor, nil
}

// CreateAPITransactionEvaluator -
Expand Down
2 changes: 2 additions & 0 deletions factory/processing/processComponents.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ type processComponents struct {
accountsParser genesis.AccountsParser
receiptsRepository mainFactory.ReceiptsRepository
sentSignaturesTracker process.SentSignaturesTracker
epochSystemSCProcessor process.EpochStartSystemSCProcessor
}

// ProcessComponentsFactoryArgs holds the arguments needed to create a process components factory
Expand Down Expand Up @@ -751,6 +752,7 @@ func (pcf *processComponentsFactory) Create() (*processComponents, error) {
currentEpochProvider: currentEpochProvider,
vmFactoryForTxSimulator: vmFactoryForTxSimulate,
vmFactoryForProcessing: blockProcessorComponents.vmFactoryForProcessing,
epochSystemSCProcessor: blockProcessorComponents.epochSystemSCProcessor,
scheduledTxsExecutionHandler: scheduledTxsExecutionHandler,
txsSender: txsSenderWithAccumulator,
hardforkTrigger: hardforkTrigger,
Expand Down
15 changes: 15 additions & 0 deletions factory/processing/processComponentsHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ func (m *managedProcessComponents) CheckSubcomponents() error {
if check.IfNil(m.processComponents.sentSignaturesTracker) {
return errors.ErrNilSentSignatureTracker
}
if check.IfNil(m.processComponents.epochSystemSCProcessor) {
return errors.ErrNilEpochSystemSCProcessor
}

return nil
}
Expand Down Expand Up @@ -673,6 +676,18 @@ func (m *managedProcessComponents) SentSignaturesTracker() process.SentSignature
return m.processComponents.sentSignaturesTracker
}

// EpochSystemSCProcessor returns the epoch start system SC processor
func (m *managedProcessComponents) EpochSystemSCProcessor() process.EpochStartSystemSCProcessor {
m.mutProcessComponents.RLock()
defer m.mutProcessComponents.RUnlock()

if m.processComponents == nil {
return nil
}

return m.processComponents.epochSystemSCProcessor
}

// IsInterfaceNil returns true if the interface is nil
func (m *managedProcessComponents) IsInterfaceNil() bool {
return m == nil
Expand Down
2 changes: 2 additions & 0 deletions factory/processing/processComponentsHandler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func TestManagedProcessComponents_Create(t *testing.T) {
require.True(t, check.IfNil(managedProcessComponents.FullArchivePeerShardMapper()))
require.True(t, check.IfNil(managedProcessComponents.FullArchiveInterceptorsContainer()))
require.True(t, check.IfNil(managedProcessComponents.SentSignaturesTracker()))
require.True(t, check.IfNil(managedProcessComponents.EpochSystemSCProcessor()))

err := managedProcessComponents.Create()
require.NoError(t, err)
Expand Down Expand Up @@ -137,6 +138,7 @@ func TestManagedProcessComponents_Create(t *testing.T) {
require.False(t, check.IfNil(managedProcessComponents.FullArchivePeerShardMapper()))
require.False(t, check.IfNil(managedProcessComponents.FullArchiveInterceptorsContainer()))
require.False(t, check.IfNil(managedProcessComponents.SentSignaturesTracker()))
require.False(t, check.IfNil(managedProcessComponents.EpochSystemSCProcessor()))

require.Equal(t, factory.ProcessComponentsName, managedProcessComponents.String())
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ func TestChainSimulator_MakeNewContractFromValidatorData(t *testing.T) {
NumNodesWaitingListMeta: 3,
NumNodesWaitingListShard: 3,
AlterConfigsFunction: func(cfg *config.Configs) {
maxNodesChangeEnableEpoch := cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch
blsMultiSignerEnableEpoch := cfg.EpochConfig.EnableEpochs.BLSMultiSignerEnableEpoch

cfg.EpochConfig.EnableEpochs = config.EnableEpochs{}
cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch = maxNodesChangeEnableEpoch
cfg.EpochConfig.EnableEpochs.BLSMultiSignerEnableEpoch = blsMultiSignerEnableEpoch

cfg.EpochConfig.EnableEpochs.StakingV4Step1EnableEpoch = 100
cfg.EpochConfig.EnableEpochs.StakingV4Step2EnableEpoch = 101
cfg.EpochConfig.EnableEpochs.StakingV4Step3EnableEpoch = 102
Expand All @@ -96,6 +103,57 @@ func TestChainSimulator_MakeNewContractFromValidatorData(t *testing.T) {
testChainSimulatorMakeNewContractFromValidatorData(t, cs, 1)
})

// 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 and all is done in epoch 0", 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) {
maxNodesChangeEnableEpoch := cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch
blsMultiSignerEnableEpoch := cfg.EpochConfig.EnableEpochs.BLSMultiSignerEnableEpoch

// set all activation epoch values on 0
cfg.EpochConfig.EnableEpochs = config.EnableEpochs{}
cfg.EpochConfig.EnableEpochs.MaxNodesChangeEnableEpoch = maxNodesChangeEnableEpoch
cfg.EpochConfig.EnableEpochs.BLSMultiSignerEnableEpoch = blsMultiSignerEnableEpoch

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()

// we need a little time to enable the VM queries on the http server
time.Sleep(time.Second)
// also, propose a couple of blocks
err = cs.GenerateBlocks(3)
require.Nil(t, err)

testChainSimulatorMakeNewContractFromValidatorData(t, cs, 0)
})

// 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
Expand Down
6 changes: 6 additions & 0 deletions integrationTests/mock/processComponentsStub.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type ProcessComponentsStub struct {
ReceiptsRepositoryInternal factory.ReceiptsRepository
ESDTDataStorageHandlerForAPIInternal vmcommon.ESDTNFTStorageHandler
SentSignaturesTrackerInternal process.SentSignaturesTracker
EpochSystemSCProcessorInternal process.EpochStartSystemSCProcessor
}

// Create -
Expand Down Expand Up @@ -296,6 +297,11 @@ func (pcs *ProcessComponentsStub) SentSignaturesTracker() process.SentSignatures
return pcs.SentSignaturesTrackerInternal
}

// EpochSystemSCProcessor -
func (pcs *ProcessComponentsStub) EpochSystemSCProcessor() process.EpochStartSystemSCProcessor {
return pcs.EpochSystemSCProcessorInternal
}

// IsInterfaceNil -
func (pcs *ProcessComponentsStub) IsInterfaceNil() bool {
return pcs == nil
Expand Down