From c0802e081e3043549ee95f6de8daf456b6e2f194 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 26 Jan 2024 12:51:37 +0200 Subject: [PATCH 1/2] fix tx cost api route --- facade/interface.go | 3 ++- .../processing/txSimulatorProcessComponents.go | 5 +++++ process/mock/transactionSimulatorStub.go | 7 ++++--- .../transactionEvaluator/transactionEvaluator.go | 14 ++++++++++++-- .../transactionEvaluator_test.go | 16 +++++++++------- .../transactionEvaluator/transactionSimulator.go | 11 ++++++++++- .../transactionSimulator_test.go | 7 ++++--- 7 files changed, 46 insertions(+), 17 deletions(-) diff --git a/facade/interface.go b/facade/interface.go index 910948b57a7..8269dfe0b3b 100644 --- a/facade/interface.go +++ b/facade/interface.go @@ -5,6 +5,7 @@ import ( "math/big" "github.com/multiversx/mx-chain-core-go/core" + coreData "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/alteredAccount" "github.com/multiversx/mx-chain-core-go/data/api" "github.com/multiversx/mx-chain-core-go/data/esdt" @@ -106,7 +107,7 @@ type NodeHandler interface { // TransactionSimulatorProcessor defines the actions which a transaction simulator processor has to implement type TransactionSimulatorProcessor interface { - ProcessTx(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) + ProcessTx(tx *transaction.Transaction, currentHeader coreData.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) IsInterfaceNil() bool } diff --git a/factory/processing/txSimulatorProcessComponents.go b/factory/processing/txSimulatorProcessComponents.go index 2a5e8c5a7a2..257a46af1a5 100644 --- a/factory/processing/txSimulatorProcessComponents.go +++ b/factory/processing/txSimulatorProcessComponents.go @@ -79,6 +79,7 @@ func (pcf *processComponentsFactory) createAPITransactionEvaluator() (factory.Tr Accounts: simulationAccountsDB, ShardCoordinator: pcf.bootstrapComponents.ShardCoordinator(), EnableEpochsHandler: pcf.coreData.EnableEpochsHandler(), + BlockChain: pcf.data.Blockchain(), }) return apiTransactionEvaluator, vmContainerFactory, err @@ -141,6 +142,8 @@ func (pcf *processComponentsFactory) createArgsTxSimulatorProcessorForMeta( return args, nil, nil, err } + args.BlockChainHook = vmContainerFactory.BlockChainHookImpl() + vmContainer, err := vmContainerFactory.Create() if err != nil { return args, nil, nil, err @@ -301,6 +304,8 @@ func (pcf *processComponentsFactory) createArgsTxSimulatorProcessorShard( return args, nil, nil, err } + args.BlockChainHook = vmContainerFactory.BlockChainHookImpl() + err = builtInFuncFactory.SetPayableHandler(vmContainerFactory.BlockChainHookImpl()) if err != nil { return args, nil, nil, err diff --git a/process/mock/transactionSimulatorStub.go b/process/mock/transactionSimulatorStub.go index 70363230936..971cda66d04 100644 --- a/process/mock/transactionSimulatorStub.go +++ b/process/mock/transactionSimulatorStub.go @@ -1,19 +1,20 @@ package mock import ( + "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/transaction" txSimData "github.com/multiversx/mx-chain-go/process/transactionEvaluator/data" ) // TransactionSimulatorStub - type TransactionSimulatorStub struct { - ProcessTxCalled func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) + ProcessTxCalled func(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) } // ProcessTx - -func (tss *TransactionSimulatorStub) ProcessTx(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { +func (tss *TransactionSimulatorStub) ProcessTx(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { if tss.ProcessTxCalled != nil { - return tss.ProcessTxCalled(tx) + return tss.ProcessTxCalled(tx, currentHeader) } return nil, nil diff --git a/process/transactionEvaluator/transactionEvaluator.go b/process/transactionEvaluator/transactionEvaluator.go index b20652774d0..be8cc322307 100644 --- a/process/transactionEvaluator/transactionEvaluator.go +++ b/process/transactionEvaluator/transactionEvaluator.go @@ -8,6 +8,7 @@ import ( "sync" "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/facade" @@ -31,6 +32,7 @@ type ArgsApiTransactionEvaluator struct { Accounts state.AccountsAdapterWithClean ShardCoordinator sharding.Coordinator EnableEpochsHandler common.EnableEpochsHandler + BlockChain data.ChainHandler } type apiTransactionEvaluator struct { @@ -40,6 +42,7 @@ type apiTransactionEvaluator struct { feeHandler process.FeeHandler txSimulator facade.TransactionSimulatorProcessor enableEpochsHandler common.EnableEpochsHandler + blockChain data.ChainHandler mutExecution sync.RWMutex } @@ -63,6 +66,9 @@ func NewAPITransactionEvaluator(args ArgsApiTransactionEvaluator) (*apiTransacti if check.IfNil(args.EnableEpochsHandler) { return nil, process.ErrNilEnableEpochsHandler } + if check.IfNil(args.BlockChain) { + return nil, process.ErrNilBlockChain + } tce := &apiTransactionEvaluator{ txTypeHandler: args.TxTypeHandler, @@ -71,6 +77,7 @@ func NewAPITransactionEvaluator(args ArgsApiTransactionEvaluator) (*apiTransacti accounts: args.Accounts, shardCoordinator: args.ShardCoordinator, enableEpochsHandler: args.EnableEpochsHandler, + blockChain: args.BlockChain, } return tce, nil @@ -84,7 +91,9 @@ func (ate *apiTransactionEvaluator) SimulateTransactionExecution(tx *transaction ate.mutExecution.Unlock() }() - return ate.txSimulator.ProcessTx(tx) + currentHeader := ate.blockChain.GetCurrentBlockHeader() + + return ate.txSimulator.ProcessTx(tx, currentHeader) } // ComputeTransactionGasLimit will calculate how many gas units a transaction will consume @@ -133,8 +142,9 @@ func (ate *apiTransactionEvaluator) simulateTransactionCost(tx *transaction.Tran } costResponse := &transaction.CostResponse{} + currentHeader := ate.blockChain.GetCurrentBlockHeader() - res, err := ate.txSimulator.ProcessTx(tx) + res, err := ate.txSimulator.ProcessTx(tx, currentHeader) if err != nil { costResponse.ReturnMessage = err.Error() return costResponse, nil diff --git a/process/transactionEvaluator/transactionEvaluator_test.go b/process/transactionEvaluator/transactionEvaluator_test.go index d9e72eb579b..cff678b0599 100644 --- a/process/transactionEvaluator/transactionEvaluator_test.go +++ b/process/transactionEvaluator/transactionEvaluator_test.go @@ -29,6 +29,7 @@ func createArgs() ArgsApiTransactionEvaluator { Accounts: &stateMock.AccountsStub{}, ShardCoordinator: &mock.ShardCoordinatorStub{}, EnableEpochsHandler: &enableEpochsHandlerMock.EnableEpochsHandlerStub{}, + BlockChain: &testscommon.ChainHandlerMock{}, } } @@ -103,7 +104,7 @@ func TestComputeTransactionGasLimit_MoveBalance(t *testing.T) { }, } args.TxSimulator = &mock.TransactionSimulatorStub{ - ProcessTxCalled: func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { + ProcessTxCalled: func(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { return &txSimData.SimulationResultsWithVMOutput{}, nil }, } @@ -142,7 +143,7 @@ func TestComputeTransactionGasLimit_MoveBalanceInvalidNonceShouldStillComputeCos }, } args.TxSimulator = &mock.TransactionSimulatorStub{ - ProcessTxCalled: func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { + ProcessTxCalled: func(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { return nil, simulationErr }, } @@ -173,7 +174,7 @@ func TestComputeTransactionGasLimit_BuiltInFunction(t *testing.T) { }, } args.TxSimulator = &mock.TransactionSimulatorStub{ - ProcessTxCalled: func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { + ProcessTxCalled: func(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { return &txSimData.SimulationResultsWithVMOutput{ VMOutput: &vmcommon.VMOutput{ ReturnCode: vmcommon.Ok, @@ -209,7 +210,7 @@ func TestComputeTransactionGasLimit_BuiltInFunctionShouldErr(t *testing.T) { }, } args.TxSimulator = &mock.TransactionSimulatorStub{ - ProcessTxCalled: func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { + ProcessTxCalled: func(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { return nil, localErr }, } @@ -239,7 +240,7 @@ func TestComputeTransactionGasLimit_NilVMOutput(t *testing.T) { }, } args.TxSimulator = &mock.TransactionSimulatorStub{ - ProcessTxCalled: func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { + ProcessTxCalled: func(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { return &txSimData.SimulationResultsWithVMOutput{}, nil }, } @@ -248,7 +249,8 @@ func TestComputeTransactionGasLimit_NilVMOutput(t *testing.T) { return &stateMock.UserAccountStub{Balance: big.NewInt(100000)}, nil }, } - tce, _ := NewAPITransactionEvaluator(args) + tce, err := NewAPITransactionEvaluator(args) + require.Nil(t, err) tx := &transaction.Transaction{} cost, err := tce.ComputeTransactionGasLimit(tx) @@ -269,7 +271,7 @@ func TestComputeTransactionGasLimit_RetCodeNotOk(t *testing.T) { }, } args.TxSimulator = &mock.TransactionSimulatorStub{ - ProcessTxCalled: func(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { + ProcessTxCalled: func(tx *transaction.Transaction, _ data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { return &txSimData.SimulationResultsWithVMOutput{ VMOutput: &vmcommon.VMOutput{ ReturnCode: vmcommon.UserError, diff --git a/process/transactionEvaluator/transactionSimulator.go b/process/transactionEvaluator/transactionSimulator.go index 8d1a405643d..c87e79b0472 100644 --- a/process/transactionEvaluator/transactionSimulator.go +++ b/process/transactionEvaluator/transactionSimulator.go @@ -6,6 +6,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/data/receipt" "github.com/multiversx/mx-chain-core-go/data/smartContractResult" @@ -33,6 +34,7 @@ type ArgsTxSimulator struct { Hasher hashing.Hasher Marshalizer marshal.Marshalizer DataFieldParser DataFieldParser + BlockChainHook process.BlockChainHookHandler } type refundHandler interface { @@ -50,6 +52,7 @@ type transactionSimulator struct { marshalizer marshal.Marshalizer refundDetector refundHandler dataFieldParser DataFieldParser + blockChainHook process.BlockChainHookHandler } // NewTransactionSimulator returns a new instance of a transactionSimulator @@ -78,6 +81,9 @@ func NewTransactionSimulator(args ArgsTxSimulator) (*transactionSimulator, error if check.IfNilReflect(args.DataFieldParser) { return nil, ErrNilDataFieldParser } + if check.IfNil(args.BlockChainHook) { + return nil, process.ErrNilBlockChainHook + } return &transactionSimulator{ txProcessor: args.TransactionProcessor, @@ -89,17 +95,20 @@ func NewTransactionSimulator(args ArgsTxSimulator) (*transactionSimulator, error hasher: args.Hasher, refundDetector: transactionAPI.NewRefundDetector(), dataFieldParser: args.DataFieldParser, + blockChainHook: args.BlockChainHook, }, nil } // ProcessTx will process the transaction in a special environment, where state-writing is not allowed -func (ts *transactionSimulator) ProcessTx(tx *transaction.Transaction) (*txSimData.SimulationResultsWithVMOutput, error) { +func (ts *transactionSimulator) ProcessTx(tx *transaction.Transaction, currentHeader data.HeaderHandler) (*txSimData.SimulationResultsWithVMOutput, error) { ts.mutOperation.Lock() defer ts.mutOperation.Unlock() txStatus := transaction.TxStatusPending failReason := "" + ts.blockChainHook.SetCurrentHeader(currentHeader) + retCode, err := ts.txProcessor.ProcessTransaction(tx) if err != nil { failReason = err.Error() diff --git a/process/transactionEvaluator/transactionSimulator_test.go b/process/transactionEvaluator/transactionSimulator_test.go index 727f158c7eb..ad477c25640 100644 --- a/process/transactionEvaluator/transactionSimulator_test.go +++ b/process/transactionEvaluator/transactionSimulator_test.go @@ -125,7 +125,7 @@ func TestTransactionSimulator_ProcessTxProcessingErrShouldSignal(t *testing.T) { } ts, _ := NewTransactionSimulator(args) - results, err := ts.ProcessTx(&transaction.Transaction{Nonce: 37}) + results, err := ts.ProcessTx(&transaction.Transaction{Nonce: 37}, &block.Header{}) require.NoError(t, err) require.Equal(t, expErr.Error(), results.FailReason) } @@ -207,7 +207,7 @@ func TestTransactionSimulator_ProcessTxShouldIncludeScrsAndReceipts(t *testing.T txHash, _ := core.CalculateHash(args.Marshalizer, args.Hasher, tx) args.VMOutputCacher.Put(txHash, &vmcommon.VMOutput{}, 0) - results, err := ts.ProcessTx(tx) + results, err := ts.ProcessTx(tx, &block.Header{}) require.NoError(t, err) require.Equal( t, @@ -236,6 +236,7 @@ func getTxSimulatorArgs() ArgsTxSimulator { Marshalizer: &mock.MarshalizerMock{}, Hasher: &hashingMocks.HasherMock{}, DataFieldParser: dataFieldParser, + BlockChainHook: &testscommon.BlockChainHookStub{}, } } @@ -261,7 +262,7 @@ func TestTransactionSimulator_ProcessTxConcurrentCalls(t *testing.T) { for i := 0; i < numCalls; i++ { go func(idx int) { time.Sleep(time.Millisecond * 10) - _, _ = txSimulator.ProcessTx(tx) + _, _ = txSimulator.ProcessTx(tx, &block.Header{}) wg.Done() }(i) } From fb1a7a6603143ba3506cd4aea33d3f930528ef1a Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Fri, 26 Jan 2024 13:12:32 +0200 Subject: [PATCH 2/2] fix tests --- integrationTests/testProcessorNodeWithTestWebServer.go | 2 ++ integrationTests/vm/testInitializer.go | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/integrationTests/testProcessorNodeWithTestWebServer.go b/integrationTests/testProcessorNodeWithTestWebServer.go index f177c08cfd8..e05393417c2 100644 --- a/integrationTests/testProcessorNodeWithTestWebServer.go +++ b/integrationTests/testProcessorNodeWithTestWebServer.go @@ -179,6 +179,7 @@ func createFacadeComponents(tpn *TestProcessorNode) nodeFacade.ApiResolver { Hasher: TestHasher, VMOutputCacher: &testscommon.CacherMock{}, DataFieldParser: dataFieldParser, + BlockChainHook: tpn.BlockchainHook, } txSimulator, err := transactionEvaluator.NewTransactionSimulator(argSimulator) @@ -194,6 +195,7 @@ func createFacadeComponents(tpn *TestProcessorNode) nodeFacade.ApiResolver { Accounts: wrappedAccounts, ShardCoordinator: tpn.ShardCoordinator, EnableEpochsHandler: tpn.EnableEpochsHandler, + BlockChain: tpn.BlockChain, } apiTransactionEvaluator, err := transactionEvaluator.NewAPITransactionEvaluator(argsTransactionEvaluator) log.LogIfError(err) diff --git a/integrationTests/vm/testInitializer.go b/integrationTests/vm/testInitializer.go index 0c9fa15b273..5230a14c841 100644 --- a/integrationTests/vm/testInitializer.go +++ b/integrationTests/vm/testInitializer.go @@ -818,6 +818,7 @@ func CreateTxProcessorWithOneSCExecutorWithVMs( epochNotifierInstance process.EpochNotifier, guardianChecker process.GuardianChecker, roundNotifierInstance process.RoundNotifier, + chainHandler data.ChainHandler, ) (*ResultsCreateTxProcessor, error) { if check.IfNil(poolsHolder) { poolsHolder = dataRetrieverMock.NewPoolsHolderMock() @@ -980,6 +981,7 @@ func CreateTxProcessorWithOneSCExecutorWithVMs( Marshalizer: integrationtests.TestMarshalizer, Hasher: integrationtests.TestHasher, DataFieldParser: dataFieldParser, + BlockChainHook: blockChainHook, } argsNewSCProcessor.VMOutputCacher = txSimulatorProcessorArgs.VMOutputCacher @@ -1006,6 +1008,7 @@ func CreateTxProcessorWithOneSCExecutorWithVMs( Accounts: simulationAccountsDB, ShardCoordinator: shardCoordinator, EnableEpochsHandler: argsNewSCProcessor.EnableEpochsHandler, + BlockChain: chainHandler, } apiTransactionEvaluator, err := transactionEvaluator.NewAPITransactionEvaluator(argsTransactionEvaluator) if err != nil { @@ -1128,6 +1131,7 @@ func CreatePreparedTxProcessorAndAccountsWithVMsWithRoundsConfig( epochNotifierInstance, guardedAccountHandler, roundNotifierInstance, + chainHandler, ) if err != nil { return nil, err @@ -1279,6 +1283,7 @@ func CreatePreparedTxProcessorWithVMConfigWithShardCoordinatorDBAndGasAndRoundCo epochNotifierInstance, guardedAccountHandler, roundNotifierInstance, + chainHandler, ) if err != nil { return nil, err @@ -1374,6 +1379,7 @@ func CreateTxProcessorArwenVMWithGasScheduleAndRoundConfig( epochNotifierInstance, guardedAccountHandler, roundNotifierInstance, + chainHandler, ) if err != nil { return nil, err @@ -1455,6 +1461,7 @@ func CreateTxProcessorArwenWithVMConfigAndRoundConfig( epochNotifierInstance, guardedAccountHandler, roundNotifierInstance, + chainHandler, ) if err != nil { return nil, err @@ -1885,6 +1892,7 @@ func CreatePreparedTxProcessorWithVMsMultiShardRoundVMConfig( epochNotifierInstance, guardedAccountHandler, roundNotifierInstance, + chainHandler, ) if err != nil { return nil, err