From a55e36fb0c514f9c831977c404a60f54ab6ec618 Mon Sep 17 00:00:00 2001 From: jules01 Date: Mon, 24 Oct 2022 15:48:28 +0300 Subject: [PATCH 1/2] - fixed concurrency issues on transaction simulator --- process/txsimulator/txSimulator.go | 5 ++++ process/txsimulator/txSimulator_test.go | 34 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/process/txsimulator/txSimulator.go b/process/txsimulator/txSimulator.go index 851ffea5e3d..cdf18b31b10 100644 --- a/process/txsimulator/txSimulator.go +++ b/process/txsimulator/txSimulator.go @@ -2,6 +2,7 @@ package txsimulator import ( "encoding/hex" + "sync" "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/core/check" @@ -30,6 +31,7 @@ type ArgsTxSimulator struct { } type transactionSimulator struct { + mutCriticalSection sync.Mutex txProcessor TransactionProcessor intermProcContainer process.IntermediateProcessorContainer addressPubKeyConverter core.PubkeyConverter @@ -76,6 +78,9 @@ func NewTransactionSimulator(args ArgsTxSimulator) (*transactionSimulator, error // ProcessTx will process the transaction in a special environment, where state-writing is not allowed func (ts *transactionSimulator) ProcessTx(tx *transaction.Transaction) (*txSimData.SimulationResults, error) { + ts.mutCriticalSection.Lock() + defer ts.mutCriticalSection.Unlock() + txStatus := transaction.TxStatusPending failReason := "" diff --git a/process/txsimulator/txSimulator_test.go b/process/txsimulator/txSimulator_test.go index 031093ecbe1..a79bdcfd56b 100644 --- a/process/txsimulator/txSimulator_test.go +++ b/process/txsimulator/txSimulator_test.go @@ -3,7 +3,9 @@ package txsimulator import ( "encoding/hex" "errors" + "sync" "testing" + "time" "github.com/ElrondNetwork/elrond-go-core/core" "github.com/ElrondNetwork/elrond-go-core/data" @@ -18,6 +20,7 @@ import ( "github.com/ElrondNetwork/elrond-go/testscommon" "github.com/ElrondNetwork/elrond-go/testscommon/hashingMocks" vmcommon "github.com/ElrondNetwork/elrond-vm-common" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -228,3 +231,34 @@ func getTxSimulatorArgs() ArgsTxSimulator { Hasher: &hashingMocks.HasherMock{}, } } + +func TestTransactionSimulator_ProcessTxConcurrentCalls(t *testing.T) { + t.Parallel() + + numTransactionProcessorCalls := 0 + args := getTxSimulatorArgs() + args.TransactionProcessor = &testscommon.TxProcessorStub{ + ProcessTransactionCalled: func(transaction *transaction.Transaction) (vmcommon.ReturnCode, error) { + // deliberately not used a mutex here as to catch race conditions + numTransactionProcessorCalls++ + + return vmcommon.Ok, nil + }, + } + txSimulator, _ := NewTransactionSimulator(args) + tx := &transaction.Transaction{Nonce: 37} + + numCalls := 100 + wg := sync.WaitGroup{} + wg.Add(numCalls) + for i := 0; i < numCalls; i++ { + go func(idx int) { + time.Sleep(time.Millisecond * 10) + _, _ = txSimulator.ProcessTx(tx) + wg.Done() + }(i) + } + + wg.Wait() + assert.Equal(t, numCalls, numTransactionProcessorCalls) +} From 755cf88314ee94717b47c8e2c1537568b260ffba Mon Sep 17 00:00:00 2001 From: jules01 Date: Mon, 24 Oct 2022 15:56:00 +0300 Subject: [PATCH 2/2] - renamed mutex --- process/txsimulator/txSimulator.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/process/txsimulator/txSimulator.go b/process/txsimulator/txSimulator.go index cdf18b31b10..7ada4477f6e 100644 --- a/process/txsimulator/txSimulator.go +++ b/process/txsimulator/txSimulator.go @@ -31,7 +31,7 @@ type ArgsTxSimulator struct { } type transactionSimulator struct { - mutCriticalSection sync.Mutex + mutOperation sync.Mutex txProcessor TransactionProcessor intermProcContainer process.IntermediateProcessorContainer addressPubKeyConverter core.PubkeyConverter @@ -78,8 +78,8 @@ func NewTransactionSimulator(args ArgsTxSimulator) (*transactionSimulator, error // ProcessTx will process the transaction in a special environment, where state-writing is not allowed func (ts *transactionSimulator) ProcessTx(tx *transaction.Transaction) (*txSimData.SimulationResults, error) { - ts.mutCriticalSection.Lock() - defer ts.mutCriticalSection.Unlock() + ts.mutOperation.Lock() + defer ts.mutOperation.Unlock() txStatus := transaction.TxStatusPending failReason := ""