From 5cc4d74936f15ff82d003be905c59598e2ba761f Mon Sep 17 00:00:00 2001 From: robertsasu Date: Thu, 21 Apr 2022 22:11:02 +0300 Subject: [PATCH] integrated new flag --- cmd/node/config/enableEpochs.toml | 3 + config/epochConfig.go | 1 + factory/apiResolverFactory.go | 26 +-- factory/blockProcessorCreator.go | 23 +-- genesis/process/shardGenesisBlockCreator.go | 25 +-- go.mod | 2 +- go.sum | 4 +- integrationTests/vm/esdt/nft/esdtNft_test.go | 165 ++++++++++++++++++ node/nodeRunner.go | 1 + .../smartContract/builtInFunctions/factory.go | 26 +-- 10 files changed, 228 insertions(+), 48 deletions(-) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index d0781c78ae3..050a6357ab4 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -190,6 +190,9 @@ # SCRSizeInvariantOnBuiltInResultEnableEpoch represents the epoch when scr size invariant on built in result is enabled SCRSizeInvariantOnBuiltInResultEnableEpoch = 1 + # CheckCorrectTokenIDForTransferRoleEnableEpoch represents the epoch when the correct token ID check is applied for transfer role verification + CheckCorrectTokenIDForTransferRoleEnableEpoch = 2 + # 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 2857dc8c78d..1e62def39ce 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -76,6 +76,7 @@ type EnableEpochs struct { DoNotReturnOldBlockInBlockchainHookEnableEpoch uint32 AddFailedRelayedTxToInvalidMBsDisableEpoch uint32 SCRSizeInvariantOnBuiltInResultEnableEpoch uint32 + CheckCorrectTokenIDForTransferRoleEnableEpoch uint32 } // GasScheduleByEpochs represents a gas schedule toml entry that will be applied from the provided epoch diff --git a/factory/apiResolverFactory.go b/factory/apiResolverFactory.go index 7fd72accba9..57b1cd3c32e 100644 --- a/factory/apiResolverFactory.go +++ b/factory/apiResolverFactory.go @@ -111,6 +111,7 @@ func CreateApiResolver(args *ApiResolverArgs) (facade.ApiResolver, error) { args.Configs.EpochConfig.EnableEpochs.ESDTTransferRoleEnableEpoch, args.Configs.EpochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, args.Configs.EpochConfig.EnableEpochs.OptimizeNFTStoreEnableEpoch, + args.Configs.EpochConfig.EnableEpochs.CheckCorrectTokenIDForTransferRoleEnableEpoch, ) if err != nil { return nil, err @@ -249,6 +250,7 @@ func createScQueryElement( args.epochConfig.EnableEpochs.ESDTTransferRoleEnableEpoch, args.epochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, args.epochConfig.EnableEpochs.OptimizeNFTStoreEnableEpoch, + args.epochConfig.EnableEpochs.CheckCorrectTokenIDForTransferRoleEnableEpoch, ) if err != nil { return nil, err @@ -362,19 +364,21 @@ func createBuiltinFuncs( esdtTransferRoleEnableEpoch uint32, transferToMetaEnableEpoch uint32, optimizeNFTStoreEnableEpoch uint32, + checkCorrectTokenIDEnableEpoch uint32, ) (vmcommon.BuiltInFunctionContainer, vmcommon.SimpleESDTNFTStorageHandler, error) { argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{ - GasSchedule: gasScheduleNotifier, - MapDNSAddresses: make(map[string]struct{}), - Marshalizer: marshalizer, - Accounts: accnts, - ShardCoordinator: shardCoordinator, - EpochNotifier: epochNotifier, - ESDTMultiTransferEnableEpoch: esdtMultiTransferEnableEpoch, - ESDTTransferRoleEnableEpoch: esdtTransferRoleEnableEpoch, - GlobalMintBurnDisableEpoch: esdtGlobalMintBurnDisableEpoch, - ESDTTransferMetaEnableEpoch: transferToMetaEnableEpoch, - OptimizeNFTStoreEnableEpoch: optimizeNFTStoreEnableEpoch, + GasSchedule: gasScheduleNotifier, + MapDNSAddresses: make(map[string]struct{}), + Marshalizer: marshalizer, + Accounts: accnts, + ShardCoordinator: shardCoordinator, + EpochNotifier: epochNotifier, + ESDTMultiTransferEnableEpoch: esdtMultiTransferEnableEpoch, + ESDTTransferRoleEnableEpoch: esdtTransferRoleEnableEpoch, + GlobalMintBurnDisableEpoch: esdtGlobalMintBurnDisableEpoch, + ESDTTransferMetaEnableEpoch: transferToMetaEnableEpoch, + OptimizeNFTStoreEnableEpoch: optimizeNFTStoreEnableEpoch, + CheckCorrectTokenIDEnableEpoch: checkCorrectTokenIDEnableEpoch, } return builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) } diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index 7f6fe1e901c..ca12a36c1b4 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -1109,17 +1109,18 @@ func (pcf *processComponentsFactory) createBuiltInFunctionContainer( mapDNSAddresses map[string]struct{}, ) (vmcommon.BuiltInFunctionContainer, vmcommon.SimpleESDTNFTStorageHandler, error) { argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{ - GasSchedule: pcf.gasSchedule, - MapDNSAddresses: mapDNSAddresses, - Marshalizer: pcf.coreData.InternalMarshalizer(), - Accounts: accounts, - ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), - EpochNotifier: pcf.epochNotifier, - ESDTMultiTransferEnableEpoch: pcf.epochConfig.EnableEpochs.ESDTMultiTransferEnableEpoch, - ESDTTransferRoleEnableEpoch: pcf.epochConfig.EnableEpochs.ESDTTransferRoleEnableEpoch, - GlobalMintBurnDisableEpoch: pcf.epochConfig.EnableEpochs.GlobalMintBurnDisableEpoch, - ESDTTransferMetaEnableEpoch: pcf.epochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, - OptimizeNFTStoreEnableEpoch: pcf.epochConfig.EnableEpochs.OptimizeNFTStoreEnableEpoch, + GasSchedule: pcf.gasSchedule, + MapDNSAddresses: mapDNSAddresses, + Marshalizer: pcf.coreData.InternalMarshalizer(), + Accounts: accounts, + ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), + EpochNotifier: pcf.epochNotifier, + ESDTMultiTransferEnableEpoch: pcf.epochConfig.EnableEpochs.ESDTMultiTransferEnableEpoch, + ESDTTransferRoleEnableEpoch: pcf.epochConfig.EnableEpochs.ESDTTransferRoleEnableEpoch, + GlobalMintBurnDisableEpoch: pcf.epochConfig.EnableEpochs.GlobalMintBurnDisableEpoch, + ESDTTransferMetaEnableEpoch: pcf.epochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, + OptimizeNFTStoreEnableEpoch: pcf.epochConfig.EnableEpochs.OptimizeNFTStoreEnableEpoch, + CheckCorrectTokenIDEnableEpoch: pcf.epochConfig.EnableEpochs.CheckCorrectTokenIDForTransferRoleEnableEpoch, } return builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) diff --git a/genesis/process/shardGenesisBlockCreator.go b/genesis/process/shardGenesisBlockCreator.go index 90f6ea2c2d6..84f4f282e1c 100644 --- a/genesis/process/shardGenesisBlockCreator.go +++ b/genesis/process/shardGenesisBlockCreator.go @@ -115,6 +115,7 @@ func createGenesisConfig() config.EnableEpochs { ScheduledMiniBlocksEnableEpoch: unreachableEpoch, AddFailedRelayedTxToInvalidMBsDisableEpoch: unreachableEpoch, SCRSizeInvariantOnBuiltInResultEnableEpoch: unreachableEpoch, + CheckCorrectTokenIDForTransferRoleEnableEpoch: unreachableEpoch, } } @@ -349,17 +350,19 @@ func createProcessorsForShardGenesisBlock(arg ArgsGenesisBlockCreator, enableEpo epochNotifier := forking.NewGenericEpochNotifier() argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{ - GasSchedule: arg.GasSchedule, - MapDNSAddresses: make(map[string]struct{}), - EnableUserNameChange: false, - Marshalizer: arg.Core.InternalMarshalizer(), - Accounts: arg.Accounts, - ShardCoordinator: arg.ShardCoordinator, - EpochNotifier: epochNotifier, - ESDTMultiTransferEnableEpoch: enableEpochs.ESDTMultiTransferEnableEpoch, - ESDTTransferRoleEnableEpoch: enableEpochs.ESDTTransferRoleEnableEpoch, - GlobalMintBurnDisableEpoch: enableEpochs.GlobalMintBurnDisableEpoch, - ESDTTransferMetaEnableEpoch: enableEpochs.BuiltInFunctionOnMetaEnableEpoch, + GasSchedule: arg.GasSchedule, + MapDNSAddresses: make(map[string]struct{}), + EnableUserNameChange: false, + Marshalizer: arg.Core.InternalMarshalizer(), + Accounts: arg.Accounts, + ShardCoordinator: arg.ShardCoordinator, + EpochNotifier: epochNotifier, + ESDTMultiTransferEnableEpoch: enableEpochs.ESDTMultiTransferEnableEpoch, + ESDTTransferRoleEnableEpoch: enableEpochs.ESDTTransferRoleEnableEpoch, + GlobalMintBurnDisableEpoch: enableEpochs.GlobalMintBurnDisableEpoch, + ESDTTransferMetaEnableEpoch: enableEpochs.BuiltInFunctionOnMetaEnableEpoch, + OptimizeNFTStoreEnableEpoch: enableEpochs.OptimizeNFTStoreEnableEpoch, + CheckCorrectTokenIDEnableEpoch: enableEpochs.CheckCorrectTokenIDForTransferRoleEnableEpoch, } builtInFuncs, nftStorageHandler, err := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn) if err != nil { diff --git a/go.mod b/go.mod index f521c87a561..e55546cc912 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/ElrondNetwork/elrond-go-core v1.1.15 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.2.12 + github.com/ElrondNetwork/elrond-vm-common v1.2.14-0.20220421185714-edf68ab67a9e github.com/ElrondNetwork/notifier-go v1.0.3 github.com/beevik/ntp v0.3.0 github.com/btcsuite/btcd v0.22.0-beta diff --git a/go.sum b/go.sum index 830339c992e..97265ebc4ee 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,8 @@ 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.2.9/go.mod h1:B/Y8WiqHyDd7xsjNYsaYbVMp1jQgQ+z4jTJkFvj/EWI= -github.com/ElrondNetwork/elrond-vm-common v1.2.12 h1:MHsWE24BJbpmdm9v4apBQo6mz3jsHV+rKZLYllJ1M/E= -github.com/ElrondNetwork/elrond-vm-common v1.2.12/go.mod h1:B/Y8WiqHyDd7xsjNYsaYbVMp1jQgQ+z4jTJkFvj/EWI= +github.com/ElrondNetwork/elrond-vm-common v1.2.14-0.20220421185714-edf68ab67a9e h1:9cTldeCNE+0oIHMIZEQXHfRdzi0sAoT1aFxNZARI6ho= +github.com/ElrondNetwork/elrond-vm-common v1.2.14-0.20220421185714-edf68ab67a9e/go.mod h1:B/Y8WiqHyDd7xsjNYsaYbVMp1jQgQ+z4jTJkFvj/EWI= github.com/ElrondNetwork/go-libp2p-pubsub v0.5.5-gamma h1:k3Ko5UI2HNZlrU9laVeWx13+jnm79Maame4wIhf6J7Y= github.com/ElrondNetwork/go-libp2p-pubsub v0.5.5-gamma/go.mod h1:gVOzwebXVdSMDQBTfH8ACO5EJ4SQrvsHqCmYsCZpD0E= github.com/ElrondNetwork/notifier-go v1.0.3 h1:LhecyXqKuc/Q4NtIOlb9rw4hfMSj6usmxvYQWvb7Pn4= diff --git a/integrationTests/vm/esdt/nft/esdtNft_test.go b/integrationTests/vm/esdt/nft/esdtNft_test.go index f68bb3218ca..6f215519b63 100644 --- a/integrationTests/vm/esdt/nft/esdtNft_test.go +++ b/integrationTests/vm/esdt/nft/esdtNft_test.go @@ -744,6 +744,171 @@ func TestESDTNFTSendCreateRoleInCrossShard(t *testing.T) { testNFTSendCreateRole(t, 2) } +func TestESDTSemiFungibleWithTransferRoleIntraShard(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + testESDTSemiFungibleTokenTransferRole(t, 1) +} + +func TestESDTSemiFungibleWithTransferRoleCrossShard(t *testing.T) { + if testing.Short() { + t.Skip("this is not a short test") + } + + testESDTSemiFungibleTokenTransferRole(t, 2) +} + +func testESDTSemiFungibleTokenTransferRole(t *testing.T, numOfShards int) { + nodesPerShard := 2 + numMetachainNodes := 2 + + nodes := integrationTests.CreateNodes( + numOfShards, + nodesPerShard, + numMetachainNodes, + ) + + idxProposers := make([]int, numOfShards+1) + for i := 0; i < numOfShards; i++ { + idxProposers[i] = i * nodesPerShard + } + idxProposers[numOfShards] = numOfShards * nodesPerShard + + integrationTests.DisplayAndStartNodes(nodes) + + defer func() { + for _, n := range nodes { + _ = n.Messenger.Close() + } + }() + + initialVal := big.NewInt(10000000000) + integrationTests.MintAllNodes(nodes, initialVal) + + round := uint64(0) + nonce := uint64(0) + round = integrationTests.IncrementAndPrintRound(round) + nonce++ + + // get a node from a different shard + var nodeInDifferentShard = nodes[0] + for _, node := range nodes { + if node.ShardCoordinator.SelfId() != nodes[0].ShardCoordinator.SelfId() { + nodeInDifferentShard = node + break + } + } + + roles := [][]byte{ + []byte(core.ESDTRoleNFTCreate), + []byte(core.ESDTRoleNFTAddQuantity), + []byte(core.ESDTRoleNFTBurn), + []byte(core.ESDTRoleTransfer), + } + + initialQuantity := int64(5) + tokenIdentifier, nftMetaData := prepareNFTWithRoles( + t, + nodes, + idxProposers, + nodeInDifferentShard, + &round, + &nonce, + core.SemiFungibleESDT, + initialQuantity, + roles, + ) + + // increase quantity + nonceArg := hex.EncodeToString(big.NewInt(0).SetUint64(1).Bytes()) + quantityToAdd := int64(4) + quantityToAddArg := hex.EncodeToString(big.NewInt(quantityToAdd).Bytes()) + txData := []byte(core.BuiltInFunctionESDTNFTAddQuantity + "@" + hex.EncodeToString([]byte(tokenIdentifier)) + + "@" + nonceArg + "@" + quantityToAddArg) + integrationTests.CreateAndSendTransaction( + nodeInDifferentShard, + nodes, + big.NewInt(0), + nodeInDifferentShard.OwnAccount.Address, + string(txData), + integrationTests.AdditionalGasLimit, + ) + + time.Sleep(time.Second) + nrRoundsToPropagateMultiShard := 5 + nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) + time.Sleep(time.Second) + + nftMetaData.quantity += quantityToAdd + checkNftData( + t, + nodeInDifferentShard.OwnAccount.Address, + nodeInDifferentShard.OwnAccount.Address, + nodes, + []byte(tokenIdentifier), + nftMetaData, + 1, + ) + + time.Sleep(time.Second) + nrRoundsToPropagateMultiShard = 5 + nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) + time.Sleep(time.Second) + + checkNftData( + t, + nodeInDifferentShard.OwnAccount.Address, + nodeInDifferentShard.OwnAccount.Address, + nodes, + []byte(tokenIdentifier), + nftMetaData, + 1, + ) + + // transfer + quantityToTransfer := int64(4) + quantityToTransferArg := hex.EncodeToString(big.NewInt(quantityToTransfer).Bytes()) + txData = []byte(core.BuiltInFunctionESDTNFTTransfer + "@" + hex.EncodeToString([]byte(tokenIdentifier)) + + "@" + nonceArg + "@" + quantityToTransferArg + "@" + hex.EncodeToString(nodes[0].OwnAccount.Address)) + integrationTests.CreateAndSendTransaction( + nodeInDifferentShard, + nodes, + big.NewInt(0), + nodeInDifferentShard.OwnAccount.Address, + string(txData), + integrationTests.AdditionalGasLimit, + ) + + time.Sleep(time.Second) + nrRoundsToPropagateMultiShard = 11 + nonce, round = integrationTests.WaitOperationToBeDone(t, nodes, nrRoundsToPropagateMultiShard, nonce, round, idxProposers) + time.Sleep(time.Second) + + nftMetaData.quantity = initialQuantity + quantityToAdd - quantityToTransfer + checkNftData( + t, + nodeInDifferentShard.OwnAccount.Address, + nodeInDifferentShard.OwnAccount.Address, + nodes, + []byte(tokenIdentifier), + nftMetaData, + 1, + ) + + nftMetaData.quantity = quantityToTransfer + checkNftData( + t, + nodeInDifferentShard.OwnAccount.Address, + nodes[0].OwnAccount.Address, + nodes, + []byte(tokenIdentifier), + nftMetaData, + 1, + ) +} + func prepareNFTWithRoles( t *testing.T, nodes []*integrationTests.TestProcessorNode, diff --git a/node/nodeRunner.go b/node/nodeRunner.go index 410d3b305fb..ea945b3f960 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -175,6 +175,7 @@ func printEnableEpochs(configs *config.Configs) { log.Debug(readEpochFor("correct jailed not unstaked if empty queue"), "epoch", enableEpochs.CorrectJailedNotUnstakedEmptyQueueEpoch) log.Debug(readEpochFor("do not return old block in blockchain hook"), "epoch", enableEpochs.DoNotReturnOldBlockInBlockchainHookEnableEpoch) log.Debug(readEpochFor("scr size invariant check on built in"), "epoch", enableEpochs.SCRSizeInvariantOnBuiltInResultEnableEpoch) + log.Debug(readEpochFor("correct check on tokenID for transfer role"), "epoch", enableEpochs.CheckCorrectTokenIDForTransferRoleEnableEpoch) gasSchedule := configs.EpochConfig.GasSchedule diff --git a/process/smartContract/builtInFunctions/factory.go b/process/smartContract/builtInFunctions/factory.go index a1d2b593e26..70c84f8c1a4 100644 --- a/process/smartContract/builtInFunctions/factory.go +++ b/process/smartContract/builtInFunctions/factory.go @@ -13,18 +13,19 @@ import ( // ArgsCreateBuiltInFunctionContainer defines the argument structure to create new built in function container type ArgsCreateBuiltInFunctionContainer struct { - GasSchedule core.GasScheduleNotifier - MapDNSAddresses map[string]struct{} - EnableUserNameChange bool - Marshalizer marshal.Marshalizer - Accounts state.AccountsAdapter - ShardCoordinator sharding.Coordinator - EpochNotifier vmcommon.EpochNotifier - ESDTMultiTransferEnableEpoch uint32 - ESDTTransferRoleEnableEpoch uint32 - GlobalMintBurnDisableEpoch uint32 - ESDTTransferMetaEnableEpoch uint32 - OptimizeNFTStoreEnableEpoch uint32 + GasSchedule core.GasScheduleNotifier + MapDNSAddresses map[string]struct{} + EnableUserNameChange bool + Marshalizer marshal.Marshalizer + Accounts state.AccountsAdapter + ShardCoordinator sharding.Coordinator + EpochNotifier vmcommon.EpochNotifier + ESDTMultiTransferEnableEpoch uint32 + ESDTTransferRoleEnableEpoch uint32 + GlobalMintBurnDisableEpoch uint32 + ESDTTransferMetaEnableEpoch uint32 + OptimizeNFTStoreEnableEpoch uint32 + CheckCorrectTokenIDEnableEpoch uint32 } // CreateBuiltInFuncContainerAndNFTStorageHandler creates a container that will hold all the available built in functions @@ -66,6 +67,7 @@ func CreateBuiltInFuncContainerAndNFTStorageHandler(args ArgsCreateBuiltInFuncti ESDTTransferRoleEnableEpoch: args.ESDTTransferRoleEnableEpoch, GlobalMintBurnDisableEpoch: args.GlobalMintBurnDisableEpoch, SaveNFTToSystemAccountEnableEpoch: args.OptimizeNFTStoreEnableEpoch, + CheckCorrectTokenIDEnableEpoch: args.CheckCorrectTokenIDEnableEpoch, } bContainerFactory, err := vmcommonBuiltInFunctions.NewBuiltInFunctionsCreator(modifiedArgs)