From ba1e4d9ef4a164b380e1a030c9089fa1f9bb9287 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 22 Sep 2021 18:53:05 +0300 Subject: [PATCH 01/11] new flags for backward compatibility --- config/epochConfig.go | 1 + config/tomlConfig_test.go | 4 ++++ factory/blockProcessorCreator.go | 2 ++ genesis/process/metaGenesisBlockCreator.go | 1 + genesis/process/shardGenesisBlockCreator.go | 2 ++ integrationTests/testProcessorNode.go | 2 ++ node/nodeRunner.go | 1 + process/smartContract/process.go | 6 ++++++ 8 files changed, 19 insertions(+) diff --git a/config/epochConfig.go b/config/epochConfig.go index 0e32e1d34b9..22270ae9e29 100644 --- a/config/epochConfig.go +++ b/config/epochConfig.go @@ -51,6 +51,7 @@ type EnableEpochs struct { BuiltInFunctionOnMetaEnableEpoch uint32 ComputeRewardCheckpointEnableEpoch uint32 SCRSizeInvariantCheckEnableEpoch uint32 + BackwardCompSaveKeyValueEnableEpoch uint32 } // GasScheduleByEpochs represents a gas schedule toml entry that will be applied from the provided epoch diff --git a/config/tomlConfig_test.go b/config/tomlConfig_test.go index 1d65408ba2e..3a6b50c6cf5 100644 --- a/config/tomlConfig_test.go +++ b/config/tomlConfig_test.go @@ -587,6 +587,9 @@ func TestEnableEpochConfig(t *testing.T) { # SCRSizeInvariantCheckEnableEpoch represents the epoch when the scr size invariant check is enabled SCRSizeInvariantCheckEnableEpoch = 37 + # BackwardCompSaveKeyValueEnableEpoch represents the epoch when backward compatibility save key value is enabled + BackwardCompSaveKeyValueEnableEpoch = 38 + # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ { EpochEnable = 36, MaxNumNodes = 37, NodesToShufflePerShard = 38 }, @@ -651,6 +654,7 @@ func TestEnableEpochConfig(t *testing.T) { BuiltInFunctionOnMetaEnableEpoch: 35, ComputeRewardCheckpointEnableEpoch: 36, SCRSizeInvariantCheckEnableEpoch: 37, + BackwardCompSaveKeyValueEnableEpoch: 38, }, GasSchedule: GasScheduleConfig{ GasScheduleByEpochs: []GasScheduleByEpochs{ diff --git a/factory/blockProcessorCreator.go b/factory/blockProcessorCreator.go index adc478eae19..efe463c62f6 100644 --- a/factory/blockProcessorCreator.go +++ b/factory/blockProcessorCreator.go @@ -258,6 +258,7 @@ func (pcf *processComponentsFactory) newShardBlockProcessor( StakingV2EnableEpoch: pcf.epochConfig.EnableEpochs.StakingV2EnableEpoch, BuiltInFunctionOnMetachainEnableEpoch: pcf.epochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, SCRSizeInvariantCheckEnableEpoch: pcf.epochConfig.EnableEpochs.SCRSizeInvariantCheckEnableEpoch, + BackwardCompSaveKeyValueEnableEpoch: pcf.epochConfig.EnableEpochs.BackwardCompSaveKeyValueEnableEpoch, VMOutputCacher: txcache.NewDisabledCache(), ArwenChangeLocker: arwenChangeLocker, @@ -584,6 +585,7 @@ func (pcf *processComponentsFactory) newMetaBlockProcessor( StakingV2EnableEpoch: pcf.epochConfig.EnableEpochs.StakingV2EnableEpoch, BuiltInFunctionOnMetachainEnableEpoch: pcf.epochConfig.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, SCRSizeInvariantCheckEnableEpoch: pcf.epochConfig.EnableEpochs.SCRSizeInvariantCheckEnableEpoch, + BackwardCompSaveKeyValueEnableEpoch: pcf.epochConfig.EnableEpochs.BackwardCompSaveKeyValueEnableEpoch, VMOutputCacher: txcache.NewDisabledCache(), ArwenChangeLocker: arwenChangeLocker, diff --git a/genesis/process/metaGenesisBlockCreator.go b/genesis/process/metaGenesisBlockCreator.go index 862d4dba1a3..455f9c864a4 100644 --- a/genesis/process/metaGenesisBlockCreator.go +++ b/genesis/process/metaGenesisBlockCreator.go @@ -370,6 +370,7 @@ func createProcessorsForMetaGenesisBlock(arg ArgsGenesisBlockCreator, enableEpoc SenderInOutTransferEnableEpoch: enableEpochs.SenderInOutTransferEnableEpoch, BuiltInFunctionOnMetachainEnableEpoch: enableEpochs.BuiltInFunctionOnMetaEnableEpoch, SCRSizeInvariantCheckEnableEpoch: enableEpochs.SCRSizeInvariantCheckEnableEpoch, + BackwardCompSaveKeyValueEnableEpoch: enableEpochs.BackwardCompSaveKeyValueEnableEpoch, IsGenesisProcessing: true, StakingV2EnableEpoch: arg.EpochConfig.EnableEpochs.StakingV2EnableEpoch, ArwenChangeLocker: &sync.RWMutex{}, // local Locker as to not interfere with the rest of the components diff --git a/genesis/process/shardGenesisBlockCreator.go b/genesis/process/shardGenesisBlockCreator.go index f04dfa2ef55..c4e891d92a8 100644 --- a/genesis/process/shardGenesisBlockCreator.go +++ b/genesis/process/shardGenesisBlockCreator.go @@ -62,6 +62,7 @@ func createGenesisConfig() config.EnableEpochs { ComputeRewardCheckpointEnableEpoch: unreachableEpoch, IncrementSCRNonceInMultiTransferEnableEpoch: unreachableEpoch, SCRSizeInvariantCheckEnableEpoch: unreachableEpoch, + BackwardCompSaveKeyValueEnableEpoch: unreachableEpoch, } } @@ -422,6 +423,7 @@ func createProcessorsForShardGenesisBlock(arg ArgsGenesisBlockCreator, enableEpo SenderInOutTransferEnableEpoch: enableEpochs.SenderInOutTransferEnableEpoch, BuiltInFunctionOnMetachainEnableEpoch: enableEpochs.BuiltInFunctionOnMetaEnableEpoch, SCRSizeInvariantCheckEnableEpoch: enableEpochs.SCRSizeInvariantCheckEnableEpoch, + BackwardCompSaveKeyValueEnableEpoch: enableEpochs.BackwardCompSaveKeyValueEnableEpoch, IsGenesisProcessing: true, StakingV2EnableEpoch: arg.EpochConfig.EnableEpochs.StakingV2EnableEpoch, VMOutputCacher: txcache.NewDisabledCache(), diff --git a/integrationTests/testProcessorNode.go b/integrationTests/testProcessorNode.go index 581e95488d4..67773e6e1cd 100644 --- a/integrationTests/testProcessorNode.go +++ b/integrationTests/testProcessorNode.go @@ -1450,6 +1450,7 @@ func (tpn *TestProcessorNode) initInnerProcessors(gasMap map[string]map[string]u ArwenChangeLocker: tpn.ArwenChangeLocker, BuiltInFunctionOnMetachainEnableEpoch: tpn.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, SCRSizeInvariantCheckEnableEpoch: tpn.EnableEpochs.SCRSizeInvariantCheckEnableEpoch, + BackwardCompSaveKeyValueEnableEpoch: tpn.EnableEpochs.BackwardCompSaveKeyValueEnableEpoch, } sc, _ := smartContract.NewSmartContractProcessor(argsNewScProcessor) tpn.ScProcessor = smartContract.NewTestScProcessor(sc) @@ -1680,6 +1681,7 @@ func (tpn *TestProcessorNode) initMetaInnerProcessors() { ArwenChangeLocker: tpn.ArwenChangeLocker, BuiltInFunctionOnMetachainEnableEpoch: tpn.EnableEpochs.BuiltInFunctionOnMetaEnableEpoch, SCRSizeInvariantCheckEnableEpoch: tpn.EnableEpochs.SCRSizeInvariantCheckEnableEpoch, + BackwardCompSaveKeyValueEnableEpoch: tpn.EnableEpochs.BackwardCompSaveKeyValueEnableEpoch, } scProcessor, _ := smartContract.NewSmartContractProcessor(argsNewScProcessor) tpn.ScProcessor = smartContract.NewTestScProcessor(scProcessor) diff --git a/node/nodeRunner.go b/node/nodeRunner.go index c518991ac88..e027cecbf45 100644 --- a/node/nodeRunner.go +++ b/node/nodeRunner.go @@ -148,6 +148,7 @@ func printEnableEpochs(configs *config.Configs) { log.Debug(readEpochFor("built in functions on metachain"), "epoch", enableEpochs.BuiltInFunctionOnMetaEnableEpoch) log.Debug(readEpochFor("compute rewards checkpoint on delegation"), "epoch", enableEpochs.ComputeRewardCheckpointEnableEpoch) log.Debug(readEpochFor("SCR size invariant check"), "epoch", enableEpochs.SCRSizeInvariantCheckEnableEpoch) + log.Debug(readEpochFor("backward compatibility flag for save key value"), "epoch", enableEpochs.BackwardCompSaveKeyValueEnableEpoch) gasSchedule := configs.EpochConfig.GasSchedule diff --git a/process/smartContract/process.go b/process/smartContract/process.go index bbf0a49d0df..fcd09908c78 100644 --- a/process/smartContract/process.go +++ b/process/smartContract/process.go @@ -68,6 +68,7 @@ type scProcessor struct { incrementSCRNonceInMultiTransferEnableEpoch uint32 builtInFunctionOnMetachainEnableEpoch uint32 scrSizeInvariantCheckEnableEpoch uint32 + backwardCompSaveKeyValueEnableEpoch uint32 flagStakingV2 atomic.Flag flagDeploy atomic.Flag flagBuiltin atomic.Flag @@ -78,6 +79,7 @@ type scProcessor struct { flagIncrementSCRNonceInMultiTransfer atomic.Flag flagBuiltInFunctionOnMetachain atomic.Flag flagSCRSizeInvariantCheck atomic.Flag + flagBackwardCompOnSaveKeyValue atomic.Flag arwenChangeLocker process.Locker badTxForwarder process.IntermediateTransactionHandler @@ -122,6 +124,7 @@ type ArgsNewSmartContractProcessor struct { IncrementSCRNonceInMultiTransferEnableEpoch uint32 BuiltInFunctionOnMetachainEnableEpoch uint32 SCRSizeInvariantCheckEnableEpoch uint32 + BackwardCompSaveKeyValueEnableEpoch uint32 EpochNotifier process.EpochNotifier VMOutputCacher storage.Cacher ArwenChangeLocker process.Locker @@ -2471,6 +2474,9 @@ func (sc *scProcessor) EpochConfirmed(epoch uint32, _ uint64) { sc.flagSCRSizeInvariantCheck.Toggle(epoch >= sc.scrSizeInvariantCheckEnableEpoch) log.Debug("scProcessor: scr size invariant check", "enabled", sc.flagSCRSizeInvariantCheck.IsSet()) + + sc.flagBackwardCompOnSaveKeyValue.Toggle(epoch < sc.backwardCompSaveKeyValueEnableEpoch) + log.Debug("scProcessor: backward compatibility on save key value", "enabled", sc.flagBackwardCompOnSaveKeyValue.IsSet()) } // IsInterfaceNil returns true if there is no value under the interface From 352d9263f6a912632423498b16c63512e51a4c61 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 22 Sep 2021 19:16:30 +0300 Subject: [PATCH 02/11] ugly code for backward compatibility fix --- process/smartContract/process.go | 44 +++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/process/smartContract/process.go b/process/smartContract/process.go index fcd09908c78..918cb61d1f2 100644 --- a/process/smartContract/process.go +++ b/process/smartContract/process.go @@ -90,6 +90,9 @@ type scProcessor struct { gasHandler process.GasHandler builtInGasCosts map[string]uint64 + persistPerByte uint64 + storePerByte uint64 + gasConfig vmcommon.BaseOperationCost mutGasLock sync.RWMutex txLogsProcessor process.TransactionLogProcessor vmOutputCacher storage.Cacher @@ -192,6 +195,7 @@ func NewSmartContractProcessor(args ArgsNewSmartContractProcessor) (*scProcessor } builtInFuncCost := args.GasSchedule.LatestGasSchedule()[common.BuiltInCost] + baseOperationCost := args.GasSchedule.LatestGasSchedule()[common.BaseOperationCost] sc := &scProcessor{ vmContainer: args.VmContainer, argsParser: args.ArgsParser, @@ -221,7 +225,8 @@ func NewSmartContractProcessor(args ArgsNewSmartContractProcessor) (*scProcessor scrSizeInvariantCheckEnableEpoch: args.SCRSizeInvariantCheckEnableEpoch, arwenChangeLocker: args.ArwenChangeLocker, vmOutputCacher: args.VMOutputCacher, - + storePerByte: baseOperationCost["StorePerByte"], + persistPerByte: baseOperationCost["PersistPerByte"], incrementSCRNonceInMultiTransferEnableEpoch: args.IncrementSCRNonceInMultiTransferEnableEpoch, } @@ -258,6 +263,8 @@ func (sc *scProcessor) GasScheduleChange(gasSchedule map[string]map[string]uint6 } sc.builtInGasCosts = builtInFuncCost + sc.storePerByte = gasSchedule[common.BaseOperationCost]["StorePerByte"] + sc.persistPerByte = gasSchedule[common.BaseOperationCost]["PersistPerByte"] } func (sc *scProcessor) checkTxValidity(tx data.TransactionHandler) error { @@ -1234,6 +1241,8 @@ func (sc *scProcessor) ProcessIfError( return err } + sc.setEmptyRoothashOnErrorIfSaveKeyValue(tx, acntSnd) + scrIfError, consumedFee := sc.createSCRsWhenError(acntSnd, txHash, tx, returnCode, returnMessage, gasLocked) err = sc.addBackTxValues(acntSnd, scrIfError, tx) if err != nil { @@ -1262,6 +1271,39 @@ func (sc *scProcessor) ProcessIfError( return nil } +func (sc *scProcessor) setEmptyRoothashOnErrorIfSaveKeyValue(tx data.TransactionHandler, account state.UserAccountHandler) { + if !sc.flagBackwardCompOnSaveKeyValue.IsSet() { + return + } + + if account.GetRootHash() != nil { + return + } + function, args, err := sc.argsParser.ParseCallData(string(tx.GetData())) + if err != nil { + return + } + if function != core.BuiltInFunctionSaveKeyValue { + return + } + if len(args) < 3 { + return + } + + txGasProvided, err := sc.prepareGasProvided(tx) + if err != nil { + return + } + + lenKeyVal := len(args[0]) + len(args[1]) + gasToUseForOneSave := (sc.persistPerByte + sc.storePerByte) * uint64(lenKeyVal) + if txGasProvided < gasToUseForOneSave { + return + } + + account.SetRootHash(make([]byte, 32)) +} + func (sc *scProcessor) processForRelayerWhenError( originalTx data.TransactionHandler, txHash []byte, From c66ff6cb10eff2b1f85a3da5841b0bfeccec690b Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 22 Sep 2021 19:20:12 +0300 Subject: [PATCH 03/11] unused --- process/smartContract/process.go | 1 - 1 file changed, 1 deletion(-) diff --git a/process/smartContract/process.go b/process/smartContract/process.go index 918cb61d1f2..b0b3935e33d 100644 --- a/process/smartContract/process.go +++ b/process/smartContract/process.go @@ -92,7 +92,6 @@ type scProcessor struct { builtInGasCosts map[string]uint64 persistPerByte uint64 storePerByte uint64 - gasConfig vmcommon.BaseOperationCost mutGasLock sync.RWMutex txLogsProcessor process.TransactionLogProcessor vmOutputCacher storage.Cacher From a82e0f89e181633e96c7e9999f292a775751f8e7 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 22 Sep 2021 19:24:32 +0300 Subject: [PATCH 04/11] forgot flag --- cmd/node/config/enableEpochs.toml | 3 ++ .../vm/txsFee/builtInFunctions_test.go | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/cmd/node/config/enableEpochs.toml b/cmd/node/config/enableEpochs.toml index eda631c0c2a..12b639326f2 100644 --- a/cmd/node/config/enableEpochs.toml +++ b/cmd/node/config/enableEpochs.toml @@ -114,6 +114,9 @@ # SCRSizeInvariantCheckEnableEpoch represents the epoch when the scr size invariant check is enabled SCRSizeInvariantCheckEnableEpoch = 5 + # BackwardCompSaveKeyValueEnableEpoch represents the epoch when the backward compatibility for save key value error is enabled + BackwardCompSaveKeyValueEnableEpoch = 5 + # MaxNodesChangeEnableEpoch holds configuration for changing the maximum number of nodes and the enabling epoch MaxNodesChangeEnableEpoch = [ { EpochEnable = 0, MaxNumNodes = 36, NodesToShufflePerShard = 4 }, diff --git a/integrationTests/vm/txsFee/builtInFunctions_test.go b/integrationTests/vm/txsFee/builtInFunctions_test.go index 3f3fc47deba..2a7dda3a248 100644 --- a/integrationTests/vm/txsFee/builtInFunctions_test.go +++ b/integrationTests/vm/txsFee/builtInFunctions_test.go @@ -11,6 +11,8 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data/block" + logger "github.com/ElrondNetwork/elrond-go-logger" + "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/integrationTests/vm" "github.com/ElrondNetwork/elrond-go/integrationTests/vm/txsFee/utils" "github.com/ElrondNetwork/elrond-go/process" @@ -266,3 +268,29 @@ func TestBuildInFunctionSaveKeyValue_WrongDestination(t *testing.T) { requiredData := hex.EncodeToString([]byte("nil destination SC account")) require.Equal(t, "@"+requiredData, string(intermediateTxs[0].GetData())) } + +func TestBuildInFunctionSaveKeyValue_NotEnoughGasFor3rdSave(t *testing.T) { + shardCoord, _ := sharding.NewMultiShardCoordinator(2, 0) + + testContext, err := vm.CreatePreparedTxProcessorWithVMsWithShardCoordinator(vm.ArgEnableEpoch{SaveAccountAlwaysEnableEpoch: 5}, shardCoord) + require.Nil(t, err) + defer testContext.Close() + + sndAddr := []byte("12345678901234567890123456789112") + + senderBalance := big.NewInt(100000) + _, _ = vm.CreateAccount(testContext.Accounts, sndAddr, 0, senderBalance) + + txData := []byte(core.BuiltInFunctionSaveKeyValue + "@01000000@02000000@03000000@04000000@05000000@06000000") + gasLimit := uint64(len(txData) + 20) + gasPrice := uint64(10) + + _ = logger.SetLogLevel("*:TRACE") + tx := vm.CreateTransaction(0, big.NewInt(0), sndAddr, sndAddr, gasPrice, gasLimit, txData) + retCode, err := testContext.TxProcessor.ProcessTransaction(tx) + require.Equal(t, vmcommon.UserError, retCode) + require.Equal(t, process.ErrFailedTransaction, err) + + intermediateTxs := testContext.GetIntermediateTransactions(t) + require.True(t, len(intermediateTxs) > 1) +} From 61c3fd802ed20d9935e347aa52b4412ccbfca06b Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 22 Sep 2021 19:26:59 +0300 Subject: [PATCH 05/11] add test --- integrationTests/vm/testInitializer.go | 58 ++++++++++--------- .../vm/txsFee/builtInFunctions_test.go | 3 +- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/integrationTests/vm/testInitializer.go b/integrationTests/vm/testInitializer.go index ac6d74eef77..64319a4d127 100644 --- a/integrationTests/vm/testInitializer.go +++ b/integrationTests/vm/testInitializer.go @@ -80,12 +80,13 @@ const maxTrieLevelInMemory = uint(5) // ArgEnableEpoch will specify the enable epoch values for certain flags type ArgEnableEpoch struct { - PenalizedTooMuchGasEnableEpoch uint32 - BuiltinEnableEpoch uint32 - DeployEnableEpoch uint32 - MetaProtectionEnableEpoch uint32 - RelayedTxEnableEpoch uint32 - UnbondTokensV2EnableEpoch uint32 + PenalizedTooMuchGasEnableEpoch uint32 + BuiltinEnableEpoch uint32 + DeployEnableEpoch uint32 + MetaProtectionEnableEpoch uint32 + RelayedTxEnableEpoch uint32 + UnbondTokensV2EnableEpoch uint32 + BackwardCompSaveKeyValueEnableEpoch uint32 } // VMTestAccount - @@ -786,28 +787,29 @@ func CreateTxProcessorWithOneSCExecutorWithVMs( intermediateTxHandler := &mock.IntermediateTransactionHandlerMock{} argsNewSCProcessor := smartContract.ArgsNewSmartContractProcessor{ - VmContainer: vmContainer, - ArgsParser: smartContract.NewArgumentParser(), - Hasher: testHasher, - Marshalizer: testMarshalizer, - AccountsDB: accnts, - BlockChainHook: blockChainHook, - PubkeyConv: pubkeyConv, - ShardCoordinator: shardCoordinator, - ScrForwarder: intermediateTxHandler, - BadTxForwarder: intermediateTxHandler, - TxFeeHandler: feeAccumulator, - EconomicsFee: economicsData, - TxTypeHandler: txTypeHandler, - GasHandler: gasComp, - GasSchedule: mock.NewGasScheduleNotifierMock(gasSchedule), - TxLogsProcessor: &mock.TxLogsProcessorStub{}, - EpochNotifier: forking.NewGenericEpochNotifier(), - PenalizedTooMuchGasEnableEpoch: argEnableEpoch.PenalizedTooMuchGasEnableEpoch, - DeployEnableEpoch: argEnableEpoch.DeployEnableEpoch, - BuiltinEnableEpoch: argEnableEpoch.BuiltinEnableEpoch, - ArwenChangeLocker: arwenChangeLocker, - VMOutputCacher: txcache.NewDisabledCache(), + VmContainer: vmContainer, + ArgsParser: smartContract.NewArgumentParser(), + Hasher: testHasher, + Marshalizer: testMarshalizer, + AccountsDB: accnts, + BlockChainHook: blockChainHook, + PubkeyConv: pubkeyConv, + ShardCoordinator: shardCoordinator, + ScrForwarder: intermediateTxHandler, + BadTxForwarder: intermediateTxHandler, + TxFeeHandler: feeAccumulator, + EconomicsFee: economicsData, + TxTypeHandler: txTypeHandler, + GasHandler: gasComp, + GasSchedule: mock.NewGasScheduleNotifierMock(gasSchedule), + TxLogsProcessor: &mock.TxLogsProcessorStub{}, + EpochNotifier: forking.NewGenericEpochNotifier(), + PenalizedTooMuchGasEnableEpoch: argEnableEpoch.PenalizedTooMuchGasEnableEpoch, + DeployEnableEpoch: argEnableEpoch.DeployEnableEpoch, + BuiltinEnableEpoch: argEnableEpoch.BuiltinEnableEpoch, + ArwenChangeLocker: arwenChangeLocker, + VMOutputCacher: txcache.NewDisabledCache(), + BackwardCompSaveKeyValueEnableEpoch: argEnableEpoch.BackwardCompSaveKeyValueEnableEpoch, } scProcessor, err := smartContract.NewSmartContractProcessor(argsNewSCProcessor) diff --git a/integrationTests/vm/txsFee/builtInFunctions_test.go b/integrationTests/vm/txsFee/builtInFunctions_test.go index 2a7dda3a248..f40c9b8877d 100644 --- a/integrationTests/vm/txsFee/builtInFunctions_test.go +++ b/integrationTests/vm/txsFee/builtInFunctions_test.go @@ -12,7 +12,6 @@ import ( "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data/block" logger "github.com/ElrondNetwork/elrond-go-logger" - "github.com/ElrondNetwork/elrond-go/config" "github.com/ElrondNetwork/elrond-go/integrationTests/vm" "github.com/ElrondNetwork/elrond-go/integrationTests/vm/txsFee/utils" "github.com/ElrondNetwork/elrond-go/process" @@ -272,7 +271,7 @@ func TestBuildInFunctionSaveKeyValue_WrongDestination(t *testing.T) { func TestBuildInFunctionSaveKeyValue_NotEnoughGasFor3rdSave(t *testing.T) { shardCoord, _ := sharding.NewMultiShardCoordinator(2, 0) - testContext, err := vm.CreatePreparedTxProcessorWithVMsWithShardCoordinator(vm.ArgEnableEpoch{SaveAccountAlwaysEnableEpoch: 5}, shardCoord) + testContext, err := vm.CreatePreparedTxProcessorWithVMsWithShardCoordinator(vm.ArgEnableEpoch{BackwardCompSaveKeyValueEnableEpoch: 5}, shardCoord) require.Nil(t, err) defer testContext.Close() From dbe0b711948a7b2f1939131da5b01db9dc17f5dd Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 22 Sep 2021 19:30:30 +0300 Subject: [PATCH 06/11] forgot set --- process/smartContract/process.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/process/smartContract/process.go b/process/smartContract/process.go index b0b3935e33d..e8f4575e0eb 100644 --- a/process/smartContract/process.go +++ b/process/smartContract/process.go @@ -222,6 +222,7 @@ func NewSmartContractProcessor(args ArgsNewSmartContractProcessor) (*scProcessor senderInOutTransferEnableEpoch: args.SenderInOutTransferEnableEpoch, builtInFunctionOnMetachainEnableEpoch: args.BuiltInFunctionOnMetachainEnableEpoch, scrSizeInvariantCheckEnableEpoch: args.SCRSizeInvariantCheckEnableEpoch, + backwardCompSaveKeyValueEnableEpoch: args.BackwardCompSaveKeyValueEnableEpoch, arwenChangeLocker: args.ArwenChangeLocker, vmOutputCacher: args.VMOutputCacher, storePerByte: baseOperationCost["StorePerByte"], @@ -244,6 +245,7 @@ func NewSmartContractProcessor(args ArgsNewSmartContractProcessor) (*scProcessor "epoch", sc.incrementSCRNonceInMultiTransferEnableEpoch) log.Debug("smartContract/process: enable epoch for built in functions on metachain", "epoch", sc.builtInFunctionOnMetachainEnableEpoch) log.Debug("smartContract/process: enable epoch for scr size invariant check", "epoch", sc.scrSizeInvariantCheckEnableEpoch) + log.Debug("smartContract/process: disable epoch for backward compatibility check on save key value error", "epoch", sc.scrSizeInvariantCheckEnableEpoch) args.EpochNotifier.RegisterNotifyHandler(sc) args.GasSchedule.RegisterNotifyHandler(sc) From e57ee1209b4d739a718b8b0fb47cb884a0b5ac76 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 22 Sep 2021 19:34:58 +0300 Subject: [PATCH 07/11] delete logger - add check for roothash --- integrationTests/vm/txsFee/builtInFunctions_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/integrationTests/vm/txsFee/builtInFunctions_test.go b/integrationTests/vm/txsFee/builtInFunctions_test.go index f40c9b8877d..122772bd0f7 100644 --- a/integrationTests/vm/txsFee/builtInFunctions_test.go +++ b/integrationTests/vm/txsFee/builtInFunctions_test.go @@ -5,17 +5,18 @@ package txsFee import ( + "bytes" "encoding/hex" "math/big" "testing" "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data/block" - logger "github.com/ElrondNetwork/elrond-go-logger" "github.com/ElrondNetwork/elrond-go/integrationTests/vm" "github.com/ElrondNetwork/elrond-go/integrationTests/vm/txsFee/utils" "github.com/ElrondNetwork/elrond-go/process" "github.com/ElrondNetwork/elrond-go/sharding" + "github.com/ElrondNetwork/elrond-go/state" vmcommon "github.com/ElrondNetwork/elrond-vm-common" "github.com/stretchr/testify/require" ) @@ -284,7 +285,6 @@ func TestBuildInFunctionSaveKeyValue_NotEnoughGasFor3rdSave(t *testing.T) { gasLimit := uint64(len(txData) + 20) gasPrice := uint64(10) - _ = logger.SetLogLevel("*:TRACE") tx := vm.CreateTransaction(0, big.NewInt(0), sndAddr, sndAddr, gasPrice, gasLimit, txData) retCode, err := testContext.TxProcessor.ProcessTransaction(tx) require.Equal(t, vmcommon.UserError, retCode) @@ -292,4 +292,8 @@ func TestBuildInFunctionSaveKeyValue_NotEnoughGasFor3rdSave(t *testing.T) { intermediateTxs := testContext.GetIntermediateTransactions(t) require.True(t, len(intermediateTxs) > 1) + + account, _ := testContext.Accounts.LoadAccount(sndAddr) + userAcc, _ := account.(state.UserAccountHandler) + require.True(t, bytes.Equal(make([]byte, 32), userAcc.GetRootHash())) } From c3777c145f7e804395833e69fa32bcae93f00c54 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 22 Sep 2021 19:59:47 +0300 Subject: [PATCH 08/11] gas cost as vmcommon --- process/smartContract/process.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/process/smartContract/process.go b/process/smartContract/process.go index e8f4575e0eb..fc1fb74167b 100644 --- a/process/smartContract/process.go +++ b/process/smartContract/process.go @@ -1296,8 +1296,9 @@ func (sc *scProcessor) setEmptyRoothashOnErrorIfSaveKeyValue(tx data.Transaction return } + lenVal := len(args[1]) lenKeyVal := len(args[0]) + len(args[1]) - gasToUseForOneSave := (sc.persistPerByte + sc.storePerByte) * uint64(lenKeyVal) + gasToUseForOneSave := sc.persistPerByte*uint64(lenKeyVal) + sc.storePerByte*uint64(lenVal) if txGasProvided < gasToUseForOneSave { return } From db9345f0ab1a41775193afeb6f5057e6d1e0932a Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Wed, 22 Sep 2021 20:05:18 +0300 Subject: [PATCH 09/11] gas cost as vmcommon --- process/smartContract/process.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/smartContract/process.go b/process/smartContract/process.go index fc1fb74167b..374e2065fc8 100644 --- a/process/smartContract/process.go +++ b/process/smartContract/process.go @@ -1298,7 +1298,7 @@ func (sc *scProcessor) setEmptyRoothashOnErrorIfSaveKeyValue(tx data.Transaction lenVal := len(args[1]) lenKeyVal := len(args[0]) + len(args[1]) - gasToUseForOneSave := sc.persistPerByte*uint64(lenKeyVal) + sc.storePerByte*uint64(lenVal) + gasToUseForOneSave := sc.builtInGasCosts[function] + sc.persistPerByte*uint64(lenKeyVal) + sc.storePerByte*uint64(lenVal) if txGasProvided < gasToUseForOneSave { return } From 939827c404e94a06f2170b4295e42ed2d366e4f0 Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Thu, 23 Sep 2021 08:17:10 +0300 Subject: [PATCH 10/11] narrowing down even more --- process/smartContract/process.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/process/smartContract/process.go b/process/smartContract/process.go index 374e2065fc8..cae25a2045a 100644 --- a/process/smartContract/process.go +++ b/process/smartContract/process.go @@ -1276,10 +1276,19 @@ func (sc *scProcessor) setEmptyRoothashOnErrorIfSaveKeyValue(tx data.Transaction if !sc.flagBackwardCompOnSaveKeyValue.IsSet() { return } - + if sc.shardCoordinator.SelfId() == core.MetachainShardId { + return + } + if check.IfNil(account) { + return + } + if !bytes.Equal(tx.GetSndAddr(), tx.GetRcvAddr()) { + return + } if account.GetRootHash() != nil { return } + function, args, err := sc.argsParser.ParseCallData(string(tx.GetData())) if err != nil { return From 6baef23da12f3b997829a9e6270570d0a09f900e Mon Sep 17 00:00:00 2001 From: Robert Sasu Date: Thu, 23 Sep 2021 13:56:00 +0300 Subject: [PATCH 11/11] more backward compatibility --- vm/systemSmartContracts/esdt.go | 4 ++++ vm/systemSmartContracts/esdt_test.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/vm/systemSmartContracts/esdt.go b/vm/systemSmartContracts/esdt.go index 367b3a8b368..57217e43339 100644 --- a/vm/systemSmartContracts/esdt.go +++ b/vm/systemSmartContracts/esdt.go @@ -228,6 +228,10 @@ func (e *esdt) checkBasicCreateArguments(args *vmcommon.ContractCallInput) vmcom e.eei.AddReturnMessage(err.Error()) return vmcommon.UserError } + if len(args.Arguments) < 2 { + e.eei.AddReturnMessage("not enough arguments") + return vmcommon.UserError + } if len(args.Arguments[0]) < minLengthForTokenName || len(args.Arguments[0]) > int(esdtConfig.MaxTokenNameLength) { e.eei.AddReturnMessage("token name length not in parameters") diff --git a/vm/systemSmartContracts/esdt_test.go b/vm/systemSmartContracts/esdt_test.go index b3ff6a68aa2..652ff1c53eb 100644 --- a/vm/systemSmartContracts/esdt_test.go +++ b/vm/systemSmartContracts/esdt_test.go @@ -175,6 +175,10 @@ func TestEsdt_ExecuteIssueAlways6charactersForRandom(t *testing.T) { assert.Equal(t, vmcommon.Ok, output) lastOutput = eei.output[len(eei.output)-1] assert.Equal(t, len(lastOutput), len(ticker)+1+6) + + vmInput.Arguments = nil + output = e.Execute(vmInput) + assert.Equal(t, vmcommon.UserError, output) } func TestEsdt_ExecuteIssue(t *testing.T) {