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

sovereign chain simulator updates #6773

Merged
merged 7 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions cmd/sovereignnode/chainSimulator/sovereignChainSimulator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,65 @@ func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) {
require.Nil(t, err)
}

func TestSovereignChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are duplicated from:
1.TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork
2. TestSimulator_TriggerChangeOfEpoch

Also, I think we can delete that time.Sleep if it works regardless

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could add a common test functoinality with chainSimulator interface in which you pass which node(shardID) to use

if testing.Short() {
t.Skip("this is not a short test")
}

chainSimulator, err := NewSovereignChainSimulator(ArgsSovereignChainSimulator{
SovereignConfigPath: sovereignConfigPath,
ArgsChainSimulator: &chainSim.ArgsChainSimulator{
BypassTxSignatureCheck: false,
TempDir: t.TempDir(),
PathToInitialConfig: defaultPathToInitialConfig,
GenesisTimestamp: time.Now().Unix(),
RoundDurationInMillis: uint64(6000),
RoundsPerEpoch: core.OptionalUint64{
HasValue: true,
Value: 20,
},
ApiInterface: api.NewNoApiInterface(),
MinNodesPerShard: 2,
},
})
require.Nil(t, err)
require.NotNil(t, chainSimulator)

defer chainSimulator.Close()

chainSimulatorCommon.GenerateBlocksAndEpochChange(t, chainSimulator)
}

func TestSovereignSimulator_TriggerChangeOfEpoch(t *testing.T) {
if testing.Short() {
t.Skip("this is not a short test")
}

chainSimulator, err := NewSovereignChainSimulator(ArgsSovereignChainSimulator{
SovereignConfigPath: sovereignConfigPath,
ArgsChainSimulator: &chainSim.ArgsChainSimulator{
BypassTxSignatureCheck: false,
TempDir: t.TempDir(),
PathToInitialConfig: defaultPathToInitialConfig,
GenesisTimestamp: time.Now().Unix(),
RoundDurationInMillis: uint64(6000),
RoundsPerEpoch: core.OptionalUint64{
HasValue: true,
Value: 20,
},
ApiInterface: api.NewNoApiInterface(),
MinNodesPerShard: 1,
},
})
require.Nil(t, err)
require.NotNil(t, chainSimulator)

defer chainSimulator.Close()

nodeHandler := chainSimulator.GetNodeHandler(core.SovereignChainShardId)
chainSimulatorCommon.TriggerChangeOfEpoch(t, chainSimulator, nodeHandler)
}

func TestChainSimulator_SetState(t *testing.T) {
if testing.Short() {
t.Skip("this is not a short test")
Expand Down
62 changes: 57 additions & 5 deletions integrationTests/chainSimulator/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,70 @@ import (
"testing"
"time"

"github.com/multiversx/mx-chain-go/node/chainSimulator/dtos"
"github.com/multiversx/mx-chain-go/node/chainSimulator/errors"
chainSimulatorProcess "github.com/multiversx/mx-chain-go/node/chainSimulator/process"
"github.com/multiversx/mx-chain-go/process"

"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"
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/node/chainSimulator/dtos"
"github.com/multiversx/mx-chain-go/node/chainSimulator/errors"
chainSimulatorProcess "github.com/multiversx/mx-chain-go/node/chainSimulator/process"
"github.com/multiversx/mx-chain-go/process"
)

// GenerateBlocksAndEpochChange -
func GenerateBlocksAndEpochChange(t *testing.T, chainSimulator ChainSimulator) {
genesisBalances := make(map[string]*big.Int)
for _, stakeWallet := range chainSimulator.GetInitialWalletKeys().StakeWallets {
initialAccount, errGet := getAccount(chainSimulator, stakeWallet.Address)
require.Nil(t, errGet)

genesisBalances[stakeWallet.Address.Bech32] = initialAccount.GetBalance()
}

time.Sleep(time.Second)

err := chainSimulator.GenerateBlocksUntilEpochIsReached(4)
require.Nil(t, err)

numAccountsWithIncreasedBalances := 0
for _, stakeWallet := range chainSimulator.GetInitialWalletKeys().StakeWallets {
account, errGet := getAccount(chainSimulator, stakeWallet.Address)
require.Nil(t, errGet)

if account.GetBalance().Cmp(genesisBalances[stakeWallet.Address.Bech32]) > 0 {
numAccountsWithIncreasedBalances++
}
}

require.True(t, numAccountsWithIncreasedBalances > 0)
}

func getAccount(chainSimulator ChainSimulator, address dtos.WalletAddress) (vmcommon.UserAccountHandler, error) {
shardID := GetShardForAddress(chainSimulator, address.Bech32)
account, err := chainSimulator.GetNodeHandler(shardID).GetStateComponents().AccountsAdapter().GetExistingAccount(address.Bytes)
if err != nil {
return nil, err
}

return account.(vmcommon.UserAccountHandler), nil
}

// TriggerChangeOfEpoch -
func TriggerChangeOfEpoch(t *testing.T, chainSimulator ChainSimulator, nodeHandler chainSimulatorProcess.NodeHandler) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This func can definelty fail if called from any other epoch than 0.

We can do it better and iterate from i:= currentEpoch; i< currentEpoch+4

startEpoch := nodeHandler.GetProcessComponents().EpochStartTrigger().Epoch()

for i := startEpoch; i < startEpoch+4; i++ {
err := chainSimulator.ForceChangeOfEpoch()
require.Nil(t, err)

currentEpoch := nodeHandler.GetProcessComponents().EpochStartTrigger().Epoch()
require.Equal(t, i+1, currentEpoch)
}
}

// CheckSetState -
func CheckSetState(t *testing.T, chainSimulator ChainSimulator, nodeHandler chainSimulatorProcess.NodeHandler) {
keyValueMap := map[string]string{
Expand Down
51 changes: 6 additions & 45 deletions node/chainSimulator/chainSimulator_test.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package chainSimulator

import (
"github.com/multiversx/mx-chain-go/errors"
"math/big"
"strings"
"testing"
"time"

"github.com/multiversx/mx-chain-core-go/core"
"github.com/multiversx/mx-chain-core-go/data/transaction"
"github.com/stretchr/testify/require"

"github.com/multiversx/mx-chain-go/config"
"github.com/multiversx/mx-chain-go/errors"
chainSimulatorCommon "github.com/multiversx/mx-chain-go/integrationTests/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/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

const (
Expand Down Expand Up @@ -119,33 +119,7 @@ func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) {

defer chainSimulator.Close()

facade, err := NewChainSimulatorFacade(chainSimulator)
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)

numAccountsWithIncreasedBalances := 0
for _, stakeWallet := range chainSimulator.initialWalletKeys.StakeWallets {
account, errGet := facade.GetExistingAccountFromBech32AddressString(stakeWallet.Address.Bech32)
require.Nil(t, errGet)

if account.GetBalance().Cmp(genesisBalances[stakeWallet.Address.Bech32]) > 0 {
numAccountsWithIncreasedBalances++
}
}

assert.True(t, numAccountsWithIncreasedBalances > 0)
chainSimulatorCommon.GenerateBlocksAndEpochChange(t, chainSimulator)
}

func TestSimulator_TriggerChangeOfEpoch(t *testing.T) {
Expand Down Expand Up @@ -176,21 +150,8 @@ func TestSimulator_TriggerChangeOfEpoch(t *testing.T) {

defer chainSimulator.Close()

err = chainSimulator.ForceChangeOfEpoch()
require.Nil(t, err)

err = chainSimulator.ForceChangeOfEpoch()
require.Nil(t, err)

err = chainSimulator.ForceChangeOfEpoch()
require.Nil(t, err)

err = chainSimulator.ForceChangeOfEpoch()
require.Nil(t, err)

metaNode := chainSimulator.GetNodeHandler(core.MetachainShardId)
currentEpoch := metaNode.GetProcessComponents().EpochStartTrigger().Epoch()
require.Equal(t, uint32(4), currentEpoch)
nodeHandler := chainSimulator.GetNodeHandler(core.MetachainShardId)
chainSimulatorCommon.TriggerChangeOfEpoch(t, chainSimulator, nodeHandler)
}

func TestChainSimulator_SetState(t *testing.T) {
Expand Down
27 changes: 27 additions & 0 deletions node/chainSimulator/sovereignChainSimulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package chainSimulator

import (
"fmt"

"github.com/multiversx/mx-chain-core-go/core"
)

type sovereignChainSimulator struct {
Expand Down Expand Up @@ -53,3 +55,28 @@ func (ss *sovereignChainSimulator) isSovereignTargetEpochReached(targetEpoch int

return true
}

// ForceResetValidatorStatisticsCache will force the reset of the cache used for the validators statistics endpoint
func (ss *sovereignChainSimulator) ForceResetValidatorStatisticsCache() error {
return ss.GetNodeHandler(core.SovereignChainShardId).GetProcessComponents().ValidatorsProvider().ForceUpdate()
}

// ForceChangeOfEpoch will force the change of current epoch
// This method will call the epoch change trigger and generate block till a new epoch is reached
func (ss *sovereignChainSimulator) ForceChangeOfEpoch() error {
log.Info("force change of epoch")

ss.mutex.Lock()

node := ss.nodes[core.SovereignChainShardId]
err := node.ForceChangeOfEpoch()
if err != nil {
ss.mutex.Unlock()
return fmt.Errorf("force change of epoch error-%w", err)
}

epoch := node.GetProcessComponents().EpochStartTrigger().Epoch()
ss.mutex.Unlock()

return ss.GenerateBlocksUntilEpochIsReached(int32(epoch + 1))
}