From 1aa75b730971f36987b5c5d5c8f9fd35351fe4e7 Mon Sep 17 00:00:00 2001 From: axenteoctavian Date: Tue, 11 Feb 2025 14:40:02 +0200 Subject: [PATCH 1/4] sovereign chain simulator genesis file adaptation --- .../chainSimulator/configs/configs.go | 85 +++++++++++++++++++ .../chainSimulator/configs/configs_test.go | 27 ++++++ .../chainSimulator/sovereignChainSimulator.go | 6 ++ node/chainSimulator/chainSimulator.go | 7 ++ node/chainSimulator/configs/configs.go | 69 ++++++++------- 5 files changed, 165 insertions(+), 29 deletions(-) create mode 100644 cmd/sovereignnode/chainSimulator/configs/configs.go create mode 100644 cmd/sovereignnode/chainSimulator/configs/configs_test.go diff --git a/cmd/sovereignnode/chainSimulator/configs/configs.go b/cmd/sovereignnode/chainSimulator/configs/configs.go new file mode 100644 index 00000000000..067d71c2d4f --- /dev/null +++ b/cmd/sovereignnode/chainSimulator/configs/configs.go @@ -0,0 +1,85 @@ +package configs + +import ( + "encoding/json" + "math/big" + "os" + + "github.com/multiversx/mx-chain-core-go/core" + + "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/integrationTests/chainSimulator" + chainSimulatorConfigs "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" + "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" +) + +var initialStakedEgldPerNode = big.NewInt(0).Mul(chainSimulator.OneEGLD, big.NewInt(2500)) +var initialEgldPerNode = big.NewInt(0).Mul(chainSimulator.OneEGLD, big.NewInt(5000)) +var initialSupply = big.NewInt(0).Mul(chainSimulator.OneEGLD, big.NewInt(20000000)) // 20 million EGLD + +// GenerateSovereignGenesisFile will generate sovereign initial wallet keys +func GenerateSovereignGenesisFile(args chainSimulatorConfigs.ArgsChainSimulatorConfigs, configs *config.Configs) (*dtos.InitialWalletKeys, error) { + addressConverter, err := factory.NewPubkeyConverter(configs.GeneralConfig.AddressPubkeyConverter) + if err != nil { + return nil, err + } + + initialWalletKeys := &dtos.InitialWalletKeys{ + BalanceWallets: make(map[uint32]*dtos.WalletKey), + StakeWallets: make([]*dtos.WalletKey, 0), + } + addresses := make([]data.InitialAccount, 0) + numOfNodes := int((args.NumNodesWaitingListShard+args.MinNodesPerShard)*args.NumOfShards + args.NumNodesWaitingListMeta + args.MetaChainMinNodes) + + totalStakedValue := big.NewInt(0).Set(initialStakedEgldPerNode) + totalStakedValue.Mul(totalStakedValue, big.NewInt(int64(numOfNodes))) + + initialBalance := big.NewInt(0).Set(initialSupply) + initialBalance.Sub(initialBalance, totalStakedValue) + + for i := 0; i < numOfNodes; i++ { + initialEgld := big.NewInt(0).Set(initialEgldPerNode) + + if i == numOfNodes-1 { + remainingSupply := big.NewInt(0).Set(initialBalance) + allBalances := big.NewInt(0).Set(initialEgld) + allBalances.Mul(allBalances, big.NewInt(int64(numOfNodes))) + remainingSupply.Sub(remainingSupply, allBalances) + if remainingSupply.Cmp(big.NewInt(0)) > 0 { + initialEgld.Add(initialEgld, remainingSupply) + } + } + + walletKey, errG := chainSimulatorConfigs.GenerateWalletKeyForShard(core.SovereignChainShardId, args.NumOfShards, addressConverter) + if errG != nil { + return nil, errG + } + + supply := big.NewInt(0).Set(initialEgld) + supply.Add(supply, big.NewInt(0).Set(initialStakedEgldPerNode)) + + addresses = append(addresses, data.InitialAccount{ + Address: walletKey.Address.Bech32, + Balance: initialEgld, + Supply: supply, + StakingValue: big.NewInt(0).Set(initialStakedEgldPerNode), + }) + + initialWalletKeys.StakeWallets = append(initialWalletKeys.StakeWallets, walletKey) + initialWalletKeys.BalanceWallets[uint32(i)] = 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 +} diff --git a/cmd/sovereignnode/chainSimulator/configs/configs_test.go b/cmd/sovereignnode/chainSimulator/configs/configs_test.go new file mode 100644 index 00000000000..810a9b92797 --- /dev/null +++ b/cmd/sovereignnode/chainSimulator/configs/configs_test.go @@ -0,0 +1,27 @@ +package configs + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" +) + +func TestGenerateSovereignGenesisFile(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + outputConfig, err := configs.CreateChainSimulatorConfigs(configs.ArgsChainSimulatorConfigs{ + NumOfShards: 1, + OriginalConfigsPath: "../../../../cmd/node/config", + RoundDurationInMillis: 6000, + GenesisTimeStamp: 0, + TempDir: t.TempDir(), + MinNodesPerShard: 1, + GenerateGenesisFile: GenerateSovereignGenesisFile, + }) + require.Nil(t, err) + require.NotNil(t, outputConfig) +} diff --git a/cmd/sovereignnode/chainSimulator/sovereignChainSimulator.go b/cmd/sovereignnode/chainSimulator/sovereignChainSimulator.go index 042e185f971..a1f6e428ece 100644 --- a/cmd/sovereignnode/chainSimulator/sovereignChainSimulator.go +++ b/cmd/sovereignnode/chainSimulator/sovereignChainSimulator.go @@ -11,9 +11,12 @@ import ( chainSimulatorIntegrationTests "github.com/multiversx/mx-chain-go/integrationTests/chainSimulator" "github.com/multiversx/mx-chain-go/node" "github.com/multiversx/mx-chain-go/node/chainSimulator" + chainSimulatorConfigs "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/process/block/sovereign/incomingHeader" sovCommon "github.com/multiversx/mx-chain-go/sovereignnode/chainSimulator/common" + sovChainSimConfig "github.com/multiversx/mx-chain-go/sovereignnode/chainSimulator/configs" sovereignConfig "github.com/multiversx/mx-chain-go/sovereignnode/config" ) @@ -65,6 +68,9 @@ func NewSovereignChainSimulator(args ArgsSovereignChainSimulator) (chainSimulato } args.NodeFactory = node.NewSovereignNodeFactory(configs.SovereignExtraConfig.GenesisConfig.NativeESDT) args.ChainProcessorFactory = NewSovereignChainHandlerFactory() + args.GenerateGenesisFile = func(args chainSimulatorConfigs.ArgsChainSimulatorConfigs, configs *config.Configs) (*dtos.InitialWalletKeys, error) { + return sovChainSimConfig.GenerateSovereignGenesisFile(args, configs) + } return chainSimulator.NewSovereignChainSimulator(*args.ArgsChainSimulator) } diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index c7a2ac183bd..9629b536bf8 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -70,6 +70,7 @@ type ArgsChainSimulator struct { CreateRunTypeComponents func(args runType.ArgsRunTypeComponents) (factory.RunTypeComponentsHolder, error) NodeFactory node.NodeFactory ChainProcessorFactory ChainHandlerFactory + GenerateGenesisFile func(args configs.ArgsChainSimulatorConfigs, configs *config.Configs) (*dtos.InitialWalletKeys, error) } // ArgsBaseChainSimulator holds the arguments needed to create a new instance of simulator @@ -144,6 +145,11 @@ func setSimulatorRunTypeArguments(args *ArgsChainSimulator) { if args.ChainProcessorFactory == nil { args.ChainProcessorFactory = NewChainHandlerFactory() } + if args.GenerateGenesisFile == nil { + args.GenerateGenesisFile = func(args configs.ArgsChainSimulatorConfigs, config *config.Configs) (*dtos.InitialWalletKeys, error) { + return configs.GenerateGenesisFile(args, config) + } + } } func createRunTypeCoreComponents() (factory.RunTypeCoreComponentsHolder, error) { @@ -193,6 +199,7 @@ func (s *simulator) createChainHandlers(args ArgsBaseChainSimulator) error { AlterConfigsFunction: args.AlterConfigsFunction, NumNodesWaitingListShard: args.NumNodesWaitingListShard, NumNodesWaitingListMeta: args.NumNodesWaitingListMeta, + GenerateGenesisFile: args.GenerateGenesisFile, }) if err != nil { return err diff --git a/node/chainSimulator/configs/configs.go b/node/chainSimulator/configs/configs.go index 300bdf9fb20..31b731e138d 100644 --- a/node/chainSimulator/configs/configs.go +++ b/node/chainSimulator/configs/configs.go @@ -31,7 +31,6 @@ import ( var oneEgld = big.NewInt(1000000000000000000) var initialStakedEgldPerNode = big.NewInt(0).Mul(oneEgld, big.NewInt(2500)) -var initialEgldPerNode = big.NewInt(0).Mul(oneEgld, big.NewInt(5000)) var initialSupply = big.NewInt(0).Mul(oneEgld, big.NewInt(20000000)) // 20 million EGLD const ( // ChainID contains the chain id @@ -58,6 +57,7 @@ type ArgsChainSimulatorConfigs struct { NumNodesWaitingListShard uint32 NumNodesWaitingListMeta uint32 AlterConfigsFunction func(cfg *config.Configs) + GenerateGenesisFile func(args ArgsChainSimulatorConfigs, configs *config.Configs) (*dtos.InitialWalletKeys, error) } // ArgsConfigsSimulator holds the configs for the chain simulator @@ -84,7 +84,7 @@ func CreateChainSimulatorConfigs(args ArgsChainSimulatorConfigs) (*ArgsConfigsSi } // update genesis.json - initialWallets, err := generateGenesisFile(args, configs) + initialWallets, err := args.GenerateGenesisFile(args, configs) if err != nil { return nil, err } @@ -191,7 +191,8 @@ func SetStakingV4ActivationEpochs(cfg *config.Configs, initialEpoch uint32) { cfg.SystemSCConfig.StakingSystemSCConfig.NodeLimitPercentage = 1 } -func generateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs) (*dtos.InitialWalletKeys, error) { +// GenerateGenesisFile will generate initial wallet keys +func GenerateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs) (*dtos.InitialWalletKeys, error) { addressConverter, err := factory.NewPubkeyConverter(configs.GeneralConfig.AddressPubkeyConverter) if err != nil { return nil, err @@ -201,47 +202,56 @@ func generateGenesisFile(args ArgsChainSimulatorConfigs, configs *config.Configs BalanceWallets: make(map[uint32]*dtos.WalletKey), StakeWallets: make([]*dtos.WalletKey, 0), } + 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 + } - totalStakedValue := big.NewInt(0).Set(initialStakedEgldPerNode) - totalStakedValue.Mul(totalStakedValue, big.NewInt(int64(numOfNodes))) + stakedValue := big.NewInt(0).Set(initialStakedEgldPerNode) + addresses = append(addresses, data.InitialAccount{ + Address: wallet.Address.Bech32, + StakingValue: stakedValue, + Supply: stakedValue, + }) + + initialWalletKeys.StakeWallets = append(initialWalletKeys.StakeWallets, wallet) + } + // generate an address for every shard initialBalance := big.NewInt(0).Set(initialSupply) - initialBalance.Sub(initialBalance, totalStakedValue) + totalStakedValue := big.NewInt(int64(numOfNodes)) + totalStakedValue = totalStakedValue.Mul(totalStakedValue, big.NewInt(0).Set(initialStakedEgldPerNode)) + initialBalance = initialBalance.Sub(initialBalance, totalStakedValue) - for i := 0; i < numOfNodes; i++ { - initialEgld := big.NewInt(0).Set(initialEgldPerNode) - - if i == numOfNodes-1 { - remainingSupply := big.NewInt(0).Set(initialBalance) - allBalances := big.NewInt(0).Set(initialEgld) - allBalances.Mul(allBalances, big.NewInt(int64(numOfNodes))) - remainingSupply.Sub(remainingSupply, allBalances) - if remainingSupply.Cmp(big.NewInt(0)) > 0 { - initialEgld.Add(initialEgld, remainingSupply) - } - } + walletBalance := big.NewInt(0).Set(initialBalance) + walletBalance.Div(walletBalance, big.NewInt(int64(args.NumOfShards))) - walletKey, errG := generateWalletKeyForShard(0, args.NumOfShards, addressConverter) + // 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 } - supply := big.NewInt(0).Set(initialEgld) - supply.Add(supply, big.NewInt(0).Set(initialStakedEgldPerNode)) - addresses = append(addresses, data.InitialAccount{ - Address: walletKey.Address.Bech32, - Balance: initialEgld, - Supply: supply, - StakingValue: big.NewInt(0).Set(initialStakedEgldPerNode), + Address: walletKey.Address.Bech32, + Balance: big.NewInt(0).Set(walletBalance), + Supply: big.NewInt(0).Set(walletBalance), }) - initialWalletKeys.StakeWallets = append(initialWalletKeys.StakeWallets, walletKey) - initialWalletKeys.BalanceWallets[uint32(i)] = walletKey + initialWalletKeys.BalanceWallets[shardID] = walletKey } + addresses[len(addresses)-1].Balance.Add(walletBalance, remainder) + addresses[len(addresses)-1].Supply.Add(walletBalance, remainder) + addressesBytes, errM := json.Marshal(addresses) if errM != nil { return nil, errM @@ -410,7 +420,8 @@ func GetLatestGasScheduleFilename(directory string) (string, error) { return path.Join(directory, filename), nil } -func generateWalletKeyForShard(shardID, numOfShards uint32, converter core.PubkeyConverter) (*dtos.WalletKey, error) { +// GenerateWalletKeyForShard will generate a wallet key in a specific shard +func GenerateWalletKeyForShard(shardID, numOfShards uint32, converter core.PubkeyConverter) (*dtos.WalletKey, error) { for { walletKey, err := generateWalletKey(converter) if err != nil { From 5ea91d2cb7cd2632f3a1a790bec4d751ffc86c55 Mon Sep 17 00:00:00 2001 From: axenteoctavian Date: Tue, 11 Feb 2025 15:43:22 +0200 Subject: [PATCH 2/4] fixes after testing --- node/chainSimulator/components/testOnlyProcessingNode_test.go | 3 +++ node/chainSimulator/configs/configs_test.go | 1 + 2 files changed, 4 insertions(+) diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index ded220066fb..090ec13939b 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -41,6 +41,9 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo MetaChainMinNodes: 1, ConsensusGroupSize: 1, MetaChainConsensusGroupSize: 1, + GenerateGenesisFile: func(args configs.ArgsChainSimulatorConfigs, config *config.Configs) (*dtos.InitialWalletKeys, error) { + return configs.GenerateGenesisFile(args, config) + }, }) require.Nil(t, err) diff --git a/node/chainSimulator/configs/configs_test.go b/node/chainSimulator/configs/configs_test.go index 03e464c5f36..7259a5ae1b4 100644 --- a/node/chainSimulator/configs/configs_test.go +++ b/node/chainSimulator/configs/configs_test.go @@ -23,6 +23,7 @@ func TestNewProcessorRunnerChainArguments(t *testing.T) { MinNodesPerShard: 1, ConsensusGroupSize: 1, MetaChainConsensusGroupSize: 1, + GenerateGenesisFile: GenerateGenesisFile, }) require.Nil(t, err) From 3fea782d76e5833fb48aa8a66674db536ea2e789 Mon Sep 17 00:00:00 2001 From: axenteoctavian Date: Wed, 12 Feb 2025 13:02:45 +0200 Subject: [PATCH 3/4] fixes after review --- cmd/sovereignnode/chainSimulator/configs/configs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/sovereignnode/chainSimulator/configs/configs.go b/cmd/sovereignnode/chainSimulator/configs/configs.go index 067d71c2d4f..aefbc6a949e 100644 --- a/cmd/sovereignnode/chainSimulator/configs/configs.go +++ b/cmd/sovereignnode/chainSimulator/configs/configs.go @@ -31,7 +31,7 @@ func GenerateSovereignGenesisFile(args chainSimulatorConfigs.ArgsChainSimulatorC StakeWallets: make([]*dtos.WalletKey, 0), } addresses := make([]data.InitialAccount, 0) - numOfNodes := int((args.NumNodesWaitingListShard+args.MinNodesPerShard)*args.NumOfShards + args.NumNodesWaitingListMeta + args.MetaChainMinNodes) + numOfNodes := int(args.NumNodesWaitingListShard + args.MinNodesPerShard) totalStakedValue := big.NewInt(0).Set(initialStakedEgldPerNode) totalStakedValue.Mul(totalStakedValue, big.NewInt(int64(numOfNodes))) From c83f6aa63b41ae577db42fe5cd7b6ba0debe8da8 Mon Sep 17 00:00:00 2001 From: axenteoctavian Date: Wed, 12 Feb 2025 14:23:07 +0200 Subject: [PATCH 4/4] function rename --- cmd/sovereignnode/chainSimulator/configs/configs_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/sovereignnode/chainSimulator/configs/configs_test.go b/cmd/sovereignnode/chainSimulator/configs/configs_test.go index 810a9b92797..672a9eb4f59 100644 --- a/cmd/sovereignnode/chainSimulator/configs/configs_test.go +++ b/cmd/sovereignnode/chainSimulator/configs/configs_test.go @@ -8,7 +8,7 @@ import ( "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" ) -func TestGenerateSovereignGenesisFile(t *testing.T) { +func TestCreateChainSimulatorConfigsWithSovereignGenesisFile(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") }