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

fix-transferRole-check-on-esdtTransfer #4014

Merged
merged 3 commits into from Apr 25, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/node/config/enableEpochs.toml
Expand Up @@ -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 },
Expand Down
1 change: 1 addition & 0 deletions config/epochConfig.go
Expand Up @@ -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
Expand Down
26 changes: 15 additions & 11 deletions factory/apiResolverFactory.go
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
23 changes: 12 additions & 11 deletions factory/blockProcessorCreator.go
Expand Up @@ -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)
Expand Down
25 changes: 14 additions & 11 deletions genesis/process/shardGenesisBlockCreator.go
Expand Up @@ -115,6 +115,7 @@ func createGenesisConfig() config.EnableEpochs {
ScheduledMiniBlocksEnableEpoch: unreachableEpoch,
AddFailedRelayedTxToInvalidMBsDisableEpoch: unreachableEpoch,
SCRSizeInvariantOnBuiltInResultEnableEpoch: unreachableEpoch,
CheckCorrectTokenIDForTransferRoleEnableEpoch: unreachableEpoch,
}
}

Expand Down Expand Up @@ -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,
Copy link
Contributor

Choose a reason for hiding this comment

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

this was a forgotten flag. Does the code is still backwards compatible now?

Copy link
Contributor

Choose a reason for hiding this comment

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

having a second thought, let's keep it this way as this is the correct way. Will deal with the import-db process afterwards

CheckCorrectTokenIDEnableEpoch: enableEpochs.CheckCorrectTokenIDForTransferRoleEnableEpoch,
}
builtInFuncs, nftStorageHandler, err := builtInFunctions.CreateBuiltInFuncContainerAndNFTStorageHandler(argsBuiltIn)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -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
github.com/ElrondNetwork/notifier-go v1.0.3
github.com/beevik/ntp v0.3.0
github.com/btcsuite/btcd v0.22.0-beta
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -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 h1:wEXghtHU8dgnYpraI7PQENQpeDPP0g9ojdy0CzYYpDM=
github.com/ElrondNetwork/elrond-vm-common v1.2.14/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=
Expand Down
165 changes: 165 additions & 0 deletions integrationTests/vm/esdt/nft/esdtNft_test.go
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions node/nodeRunner.go
Expand Up @@ -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

Expand Down
26 changes: 14 additions & 12 deletions process/smartContract/builtInFunctions/factory.go
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down