From 1cb65c2d2784d8ac6fc716f7df08465e0577baf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 26 Nov 2024 14:09:18 +0200 Subject: [PATCH 1/5] Sketch GetTransferredValue(). Work in progress. --- process/block/preprocess/selectionSession.go | 87 +++++++++++++++++-- .../block/preprocess/selectionSession_test.go | 31 +++++-- process/block/preprocess/transactions.go | 6 +- 3 files changed, 113 insertions(+), 11 deletions(-) diff --git a/process/block/preprocess/selectionSession.go b/process/block/preprocess/selectionSession.go index 69a2b48e24..d3b95a06f6 100644 --- a/process/block/preprocess/selectionSession.go +++ b/process/block/preprocess/selectionSession.go @@ -1,32 +1,58 @@ package preprocess import ( + "bytes" "errors" + "math/big" + "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/transaction" + "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/storage/txcache" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" + "github.com/multiversx/mx-chain-vm-common-go/parsers" ) type selectionSession struct { accountsAdapter state.AccountsAdapter transactionsProcessor process.TransactionProcessor + callArgumentsParser process.CallArgumentsParser + esdtTransferParser vmcommon.ESDTTransferParser } -func newSelectionSession(accountsAdapter state.AccountsAdapter, transactionsProcessor process.TransactionProcessor) (*selectionSession, error) { - if check.IfNil(accountsAdapter) { +type argsSelectionSession struct { + accountsAdapter state.AccountsAdapter + transactionsProcessor process.TransactionProcessor + marshalizer marshal.Marshalizer +} + +func newSelectionSession(args argsSelectionSession) (*selectionSession, error) { + if check.IfNil(args.accountsAdapter) { return nil, process.ErrNilAccountsAdapter } - if check.IfNil(transactionsProcessor) { + if check.IfNil(args.transactionsProcessor) { return nil, process.ErrNilTxProcessor } + if check.IfNil(args.marshalizer) { + return nil, process.ErrNilMarshalizer + } + + argsParser := parsers.NewCallArgsParser() + + esdtTransferParser, err := parsers.NewESDTTransferParser(args.marshalizer) + if err != nil { + return nil, err + } return &selectionSession{ - accountsAdapter: accountsAdapter, - transactionsProcessor: transactionsProcessor, + accountsAdapter: args.accountsAdapter, + transactionsProcessor: args.transactionsProcessor, + callArgumentsParser: argsParser, + esdtTransferParser: esdtTransferParser, }, nil } @@ -72,6 +98,57 @@ func (session *selectionSession) IsBadlyGuarded(tx data.TransactionHandler) bool return errors.Is(err, process.ErrTransactionNotExecutable) } +// GetTransferredValue returns the value transferred by a transaction. +func (session *selectionSession) GetTransferredValue(tx data.TransactionHandler) *big.Int { + hasValue := tx.GetValue() != nil && tx.GetValue().Sign() != 0 + if hasValue { + // Early exit (optimization): a transaction can either bear a regular value or be a "MultiESDTNFTTransfer". + return tx.GetValue() + } + + hasData := len(tx.GetData()) > 0 + if !hasData { + // Early exit (optimization): no "MultiESDTNFTTransfer" to parse. + return tx.GetValue() + } + + maybeMultiTransfer := bytes.HasPrefix(tx.GetData(), []byte(core.BuiltInFunctionMultiESDTNFTTransfer)) + if !maybeMultiTransfer { + // Early exit (optimization). + return nil + } + + function, args, err := session.callArgumentsParser.ParseData(string(tx.GetData())) + if err != nil { + return nil + } + + if function != core.BuiltInFunctionMultiESDTNFTTransfer { + // Early exit (optimization). + return nil + } + + esdtTransfers, err := session.esdtTransferParser.ParseESDTTransfers(tx.GetSndAddr(), tx.GetRcvAddr(), function, args) + if err != nil { + return nil + } + + accumulatedNativeValue := big.NewInt(0) + + for _, transfer := range esdtTransfers.ESDTTransfers { + if transfer.ESDTTokenNonce != 0 { + continue + } + if string(transfer.ESDTTokenName) != vmcommon.EGLDIdentifier { + continue + } + + _ = accumulatedNativeValue.Add(accumulatedNativeValue, transfer.ESDTValue) + } + + return accumulatedNativeValue +} + // IsInterfaceNil returns true if there is no value under the interface func (session *selectionSession) IsInterfaceNil() bool { return session == nil diff --git a/process/block/preprocess/selectionSession_test.go b/process/block/preprocess/selectionSession_test.go index 2969f6f4c7..55616845f5 100644 --- a/process/block/preprocess/selectionSession_test.go +++ b/process/block/preprocess/selectionSession_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/multiversx/mx-chain-core-go/data/transaction" + "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/state" "github.com/multiversx/mx-chain-go/testscommon" @@ -17,15 +18,27 @@ import ( func TestNewSelectionSession(t *testing.T) { t.Parallel() - session, err := newSelectionSession(nil, &testscommon.TxProcessorStub{}) + session, err := newSelectionSession(argsSelectionSession{ + accountsAdapter: nil, + transactionsProcessor: &testscommon.TxProcessorStub{}, + marshalizer: &marshal.GogoProtoMarshalizer{}, + }) require.Nil(t, session) require.ErrorIs(t, err, process.ErrNilAccountsAdapter) - session, err = newSelectionSession(&stateMock.AccountsStub{}, nil) + session, err = newSelectionSession(argsSelectionSession{ + accountsAdapter: &stateMock.AccountsStub{}, + transactionsProcessor: nil, + marshalizer: &marshal.GogoProtoMarshalizer{}, + }) require.Nil(t, session) require.ErrorIs(t, err, process.ErrNilTxProcessor) - session, err = newSelectionSession(&stateMock.AccountsStub{}, &testscommon.TxProcessorStub{}) + session, err = newSelectionSession(argsSelectionSession{ + accountsAdapter: &stateMock.AccountsStub{}, + transactionsProcessor: &testscommon.TxProcessorStub{}, + marshalizer: &marshal.GogoProtoMarshalizer{}, + }) require.NoError(t, err) require.NotNil(t, session) } @@ -57,7 +70,11 @@ func TestSelectionSession_GetAccountState(t *testing.T) { return nil, fmt.Errorf("account not found: %s", address) } - session, err := newSelectionSession(accounts, processor) + session, err := newSelectionSession(argsSelectionSession{ + accountsAdapter: accounts, + transactionsProcessor: processor, + marshalizer: &marshal.GogoProtoMarshalizer{}, + }) require.NoError(t, err) require.NotNil(t, session) @@ -95,7 +112,11 @@ func TestSelectionSession_IsBadlyGuarded(t *testing.T) { return nil } - session, err := newSelectionSession(accounts, processor) + session, err := newSelectionSession(argsSelectionSession{ + accountsAdapter: accounts, + transactionsProcessor: processor, + marshalizer: &marshal.GogoProtoMarshalizer{}, + }) require.NoError(t, err) require.NotNil(t, session) diff --git a/process/block/preprocess/transactions.go b/process/block/preprocess/transactions.go index 30775a30fc..5abddf9d18 100644 --- a/process/block/preprocess/transactions.go +++ b/process/block/preprocess/transactions.go @@ -1411,7 +1411,11 @@ func (txs *transactions) computeSortedTxs( sortedTransactionsProvider := createSortedTransactionsProvider(txShardPool) log.Debug("computeSortedTxs.GetSortedTransactions") - session, err := newSelectionSession(txs.basePreProcess.accounts, txs.txProcessor) + session, err := newSelectionSession(argsSelectionSession{ + accountsAdapter: txs.accounts, + transactionsProcessor: txs.txProcessor, + marshalizer: txs.marshalizer, + }) if err != nil { return nil, nil, err } From 16e35e21b36511dcd87b41ec77aeed6958f3c16d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Tue, 26 Nov 2024 17:52:34 +0200 Subject: [PATCH 2/5] Additional tests. --- process/block/preprocess/selectionSession.go | 1 + .../block/preprocess/selectionSession_test.go | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/process/block/preprocess/selectionSession.go b/process/block/preprocess/selectionSession.go index d3b95a06f6..d6dee23934 100644 --- a/process/block/preprocess/selectionSession.go +++ b/process/block/preprocess/selectionSession.go @@ -140,6 +140,7 @@ func (session *selectionSession) GetTransferredValue(tx data.TransactionHandler) continue } if string(transfer.ESDTTokenName) != vmcommon.EGLDIdentifier { + // We only care about native transfers. continue } diff --git a/process/block/preprocess/selectionSession_test.go b/process/block/preprocess/selectionSession_test.go index 55616845f5..e4e7809046 100644 --- a/process/block/preprocess/selectionSession_test.go +++ b/process/block/preprocess/selectionSession_test.go @@ -3,6 +3,7 @@ package preprocess import ( "bytes" "fmt" + "math/big" "testing" "github.com/multiversx/mx-chain-core-go/data/transaction" @@ -129,3 +130,48 @@ func TestSelectionSession_IsBadlyGuarded(t *testing.T) { isBadlyGuarded = session.IsBadlyGuarded(&transaction.Transaction{Nonce: 44, SndAddr: []byte("alice")}) require.False(t, isBadlyGuarded) } + +func TestSelectionSession_GetTransferredValue(t *testing.T) { + t.Parallel() + + session, err := newSelectionSession(argsSelectionSession{ + accountsAdapter: &stateMock.AccountsStub{}, + transactionsProcessor: &testscommon.TxProcessorStub{}, + marshalizer: &marshal.GogoProtoMarshalizer{}, + }) + require.NoError(t, err) + require.NotNil(t, session) + + t.Run("with value", func(t *testing.T) { + value := session.GetTransferredValue(&transaction.Transaction{ + Value: big.NewInt(1000000000000000000), + }) + require.Equal(t, big.NewInt(1000000000000000000), value) + }) + + t.Run("with value and data", func(t *testing.T) { + value := session.GetTransferredValue(&transaction.Transaction{ + Value: big.NewInt(1000000000000000000), + Data: []byte("data"), + }) + require.Equal(t, big.NewInt(1000000000000000000), value) + }) + + t.Run("native transfer within MultiESDTNFTTransfer", func(t *testing.T) { + value := session.GetTransferredValue(&transaction.Transaction{ + SndAddr: testscommon.TestPubKeyAlice, + RcvAddr: testscommon.TestPubKeyAlice, + Data: []byte("MultiESDTNFTTransfer@8049d639e5a6980d1cd2392abcce41029cda74a1563523a202f09641cc2618f8@03@4e46542d313233343536@0a@01@544553542d393837363534@01@01@45474c442d303030303030@@0de0b6b3a7640000"), + }) + require.Equal(t, big.NewInt(1000000000000000000), value) + }) + + t.Run("native transfer within MultiESDTNFTTransfer; transfer & execute", func(t *testing.T) { + value := session.GetTransferredValue(&transaction.Transaction{ + SndAddr: testscommon.TestPubKeyAlice, + RcvAddr: testscommon.TestPubKeyAlice, + Data: []byte("MultiESDTNFTTransfer@00000000000000000500b9353fe8407f87310c87e12fa1ac807f0485da39d152@03@4e46542d313233343536@01@01@4e46542d313233343536@2a@01@45474c442d303030303030@@0de0b6b3a7640000@64756d6d79@07"), + }) + require.Equal(t, big.NewInt(1000000000000000000), value) + }) +} From 6090ae4bdf72601bfffa925ab63741a87ffd534a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 27 Nov 2024 14:51:55 +0200 Subject: [PATCH 3/5] Update reference to storage-go. --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2b91dda5d4..2ffb82fc2e 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/multiversx/mx-chain-es-indexer-go v1.7.10 github.com/multiversx/mx-chain-logger-go v1.0.15 github.com/multiversx/mx-chain-scenario-go v1.4.4 - github.com/multiversx/mx-chain-storage-go v1.0.18-0.20241127074354-d1b4205add9f + github.com/multiversx/mx-chain-storage-go v1.0.18-0.20241127074704-cde9ed9f1a4b github.com/multiversx/mx-chain-vm-common-go v1.5.16 github.com/multiversx/mx-chain-vm-go v1.5.37 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.68 diff --git a/go.sum b/go.sum index e77c63d66e..cd7dbf9176 100644 --- a/go.sum +++ b/go.sum @@ -397,8 +397,8 @@ github.com/multiversx/mx-chain-logger-go v1.0.15 h1:HlNdK8etyJyL9NQ+6mIXyKPEBo+w github.com/multiversx/mx-chain-logger-go v1.0.15/go.mod h1:t3PRKaWB1M+i6gUfD27KXgzLJJC+mAQiN+FLlL1yoGQ= github.com/multiversx/mx-chain-scenario-go v1.4.4 h1:DVE2V+FPeyD/yWoC+KEfPK3jsFzHeruelESfpTlf460= github.com/multiversx/mx-chain-scenario-go v1.4.4/go.mod h1:kI+TWR3oIEgUkbwkHCPo2CQ3VjIge+ezGTibiSGwMxo= -github.com/multiversx/mx-chain-storage-go v1.0.18-0.20241127074354-d1b4205add9f h1:neI7W8hMHlCfhK1UIb2+jf3SwkpymmCb6BG/0OS7yfI= -github.com/multiversx/mx-chain-storage-go v1.0.18-0.20241127074354-d1b4205add9f/go.mod h1:eFDEOrG7Wiyk5I/ObpwcN2eoBlOnnfeEMTvTer1cymk= +github.com/multiversx/mx-chain-storage-go v1.0.18-0.20241127074704-cde9ed9f1a4b h1:hLbvchGiCZOieZloc20GLvJcs1s2/evx6hkuqRtZKcg= +github.com/multiversx/mx-chain-storage-go v1.0.18-0.20241127074704-cde9ed9f1a4b/go.mod h1:eFDEOrG7Wiyk5I/ObpwcN2eoBlOnnfeEMTvTer1cymk= github.com/multiversx/mx-chain-vm-common-go v1.5.16 h1:g1SqYjxl7K66Y1O/q6tvDJ37fzpzlxCSfRzSm/woQQY= github.com/multiversx/mx-chain-vm-common-go v1.5.16/go.mod h1:1rSkXreUZNXyPTTdhj47M+Fy62yjxbu3aAsXEtKN3UY= github.com/multiversx/mx-chain-vm-go v1.5.37 h1:Iy3KCvM+DOq1f9UPA7uYK/rI3ZbBOXc2CVNO2/vm5zw= From 6e33cbf3d81c03acd8a62db21bdc10511e518344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 28 Nov 2024 14:49:58 +0200 Subject: [PATCH 4/5] Fix after review. Benchmark. --- go.mod | 2 +- go.sum | 4 +- process/block/preprocess/selectionSession.go | 12 ++- .../block/preprocess/selectionSession_test.go | 100 ++++++++++++++++++ 4 files changed, 110 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index c1d46238d5..0a330e9cef 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/multiversx/mx-chain-es-indexer-go v1.7.10 github.com/multiversx/mx-chain-logger-go v1.0.15 github.com/multiversx/mx-chain-scenario-go v1.4.4 - github.com/multiversx/mx-chain-storage-go v1.0.18-0.20241128102604-90581ee84b60 + github.com/multiversx/mx-chain-storage-go v1.0.18-0.20241128110709-156b1244e04f github.com/multiversx/mx-chain-vm-common-go v1.5.16 github.com/multiversx/mx-chain-vm-go v1.5.37 github.com/multiversx/mx-chain-vm-v1_2-go v1.2.68 diff --git a/go.sum b/go.sum index aeb3451d8a..5b6066d216 100644 --- a/go.sum +++ b/go.sum @@ -397,8 +397,8 @@ github.com/multiversx/mx-chain-logger-go v1.0.15 h1:HlNdK8etyJyL9NQ+6mIXyKPEBo+w github.com/multiversx/mx-chain-logger-go v1.0.15/go.mod h1:t3PRKaWB1M+i6gUfD27KXgzLJJC+mAQiN+FLlL1yoGQ= github.com/multiversx/mx-chain-scenario-go v1.4.4 h1:DVE2V+FPeyD/yWoC+KEfPK3jsFzHeruelESfpTlf460= github.com/multiversx/mx-chain-scenario-go v1.4.4/go.mod h1:kI+TWR3oIEgUkbwkHCPo2CQ3VjIge+ezGTibiSGwMxo= -github.com/multiversx/mx-chain-storage-go v1.0.18-0.20241128102604-90581ee84b60 h1:XFO7MbjpdSJE/mC8wv3937iIWoAQC9YL2vwzO0bvmMg= -github.com/multiversx/mx-chain-storage-go v1.0.18-0.20241128102604-90581ee84b60/go.mod h1:eFDEOrG7Wiyk5I/ObpwcN2eoBlOnnfeEMTvTer1cymk= +github.com/multiversx/mx-chain-storage-go v1.0.18-0.20241128110709-156b1244e04f h1:sRPekt5fzNr+c7w2IzwufOeqANTT3Du6ciD3FX5mCvI= +github.com/multiversx/mx-chain-storage-go v1.0.18-0.20241128110709-156b1244e04f/go.mod h1:eFDEOrG7Wiyk5I/ObpwcN2eoBlOnnfeEMTvTer1cymk= github.com/multiversx/mx-chain-vm-common-go v1.5.16 h1:g1SqYjxl7K66Y1O/q6tvDJ37fzpzlxCSfRzSm/woQQY= github.com/multiversx/mx-chain-vm-common-go v1.5.16/go.mod h1:1rSkXreUZNXyPTTdhj47M+Fy62yjxbu3aAsXEtKN3UY= github.com/multiversx/mx-chain-vm-go v1.5.37 h1:Iy3KCvM+DOq1f9UPA7uYK/rI3ZbBOXc2CVNO2/vm5zw= diff --git a/process/block/preprocess/selectionSession.go b/process/block/preprocess/selectionSession.go index e01748a142..6d0f8a6d39 100644 --- a/process/block/preprocess/selectionSession.go +++ b/process/block/preprocess/selectionSession.go @@ -101,25 +101,27 @@ func (session *selectionSession) IsIncorrectlyGuarded(tx data.TransactionHandler // GetTransferredValue returns the value transferred by a transaction. func (session *selectionSession) GetTransferredValue(tx data.TransactionHandler) *big.Int { - hasValue := tx.GetValue() != nil && tx.GetValue().Sign() != 0 + value := tx.GetValue() + hasValue := value != nil && value.Sign() != 0 if hasValue { // Early exit (optimization): a transaction can either bear a regular value or be a "MultiESDTNFTTransfer". - return tx.GetValue() + return value } - hasData := len(tx.GetData()) > 0 + data := tx.GetData() + hasData := len(data) > 0 if !hasData { // Early exit (optimization): no "MultiESDTNFTTransfer" to parse. return tx.GetValue() } - maybeMultiTransfer := bytes.HasPrefix(tx.GetData(), []byte(core.BuiltInFunctionMultiESDTNFTTransfer)) + maybeMultiTransfer := bytes.HasPrefix(data, []byte(core.BuiltInFunctionMultiESDTNFTTransfer)) if !maybeMultiTransfer { // Early exit (optimization). return nil } - function, args, err := session.callArgumentsParser.ParseData(string(tx.GetData())) + function, args, err := session.callArgumentsParser.ParseData(string(data)) if err != nil { return nil } diff --git a/process/block/preprocess/selectionSession_test.go b/process/block/preprocess/selectionSession_test.go index 39754d5935..9f69a994f0 100644 --- a/process/block/preprocess/selectionSession_test.go +++ b/process/block/preprocess/selectionSession_test.go @@ -2,10 +2,12 @@ package preprocess import ( "bytes" + "encoding/hex" "fmt" "math/big" "testing" + "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/process" @@ -182,3 +184,101 @@ func TestSelectionSession_GetTransferredValue(t *testing.T) { require.Equal(t, big.NewInt(1000000000000000000), value) }) } + +func TestBenchmarkSelectionSession_GetTransferredValue(t *testing.T) { + session, err := newSelectionSession(argsSelectionSession{ + accountsAdapter: &stateMock.AccountsStub{}, + transactionsProcessor: &testscommon.TxProcessorStub{}, + marshalizer: &marshal.GogoProtoMarshalizer{}, + }) + require.NoError(t, err) + require.NotNil(t, session) + + sw := core.NewStopWatch() + + valueMultiplier := int64(1_000_000_000_000) + + t.Run("numTransactions = 5_000", func(t *testing.T) { + numTransactions := 5_000 + transactions := createMultiESDTNFTTransfersWithNativeTransfer(numTransactions, valueMultiplier) + + sw.Start(t.Name()) + + for i := 0; i < numTransactions; i++ { + tx := transactions[i] + value := session.GetTransferredValue(tx) + require.Equal(t, big.NewInt(int64(i)*valueMultiplier), value) + } + + sw.Stop(t.Name()) + }) + + t.Run("numTransactions = 10_000", func(t *testing.T) { + numTransactions := 10_000 + transactions := createMultiESDTNFTTransfersWithNativeTransfer(numTransactions, valueMultiplier) + + sw.Start(t.Name()) + + for i := 0; i < numTransactions; i++ { + tx := transactions[i] + value := session.GetTransferredValue(tx) + require.Equal(t, big.NewInt(int64(i)*valueMultiplier), value) + } + + sw.Stop(t.Name()) + }) + + t.Run("numTransactions = 20_000", func(t *testing.T) { + numTransactions := 20_000 + transactions := createMultiESDTNFTTransfersWithNativeTransfer(numTransactions, valueMultiplier) + + sw.Start(t.Name()) + + for i := 0; i < numTransactions; i++ { + tx := transactions[i] + value := session.GetTransferredValue(tx) + require.Equal(t, big.NewInt(int64(i)*valueMultiplier), value) + } + + sw.Stop(t.Name()) + }) + + for name, measurement := range sw.GetMeasurementsMap() { + fmt.Printf("%fs (%s)\n", measurement, name) + } + + // (1) + // Vendor ID: GenuineIntel + // Model name: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz + // CPU family: 6 + // Model: 140 + // Thread(s) per core: 2 + // Core(s) per socket: 4 + // + // NOTE: 20% is also due to the require() / assert() calls. + // 0.012993s (TestBenchmarkSelectionSession_GetTransferredValue/numTransactions_=_5_000) + // 0.024580s (TestBenchmarkSelectionSession_GetTransferredValue/numTransactions_=_10_000) + // 0.048808s (TestBenchmarkSelectionSession_GetTransferredValue/numTransactions_=_20_000) +} + +func createMultiESDTNFTTransfersWithNativeTransfer(numTransactions int, valueMultiplier int64) []*transaction.Transaction { + transactions := make([]*transaction.Transaction, 0, numTransactions) + + for i := 0; i < numTransactions; i++ { + nativeValue := big.NewInt(int64(i) * valueMultiplier) + data := fmt.Sprintf( + "MultiESDTNFTTransfer@8049d639e5a6980d1cd2392abcce41029cda74a1563523a202f09641cc2618f8@03@4e46542d313233343536@0a@01@544553542d393837363534@01@01@45474c442d303030303030@@%s", + hex.EncodeToString(nativeValue.Bytes()), + ) + + tx := &transaction.Transaction{ + SndAddr: testscommon.TestPubKeyAlice, + RcvAddr: testscommon.TestPubKeyAlice, + Data: []byte(data), + } + + transactions = append(transactions, tx) + } + + return transactions +} From 7eed6f59b840a12705579efb462fbfcad2b1873d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Thu, 28 Nov 2024 16:22:26 +0200 Subject: [PATCH 5/5] Fix long test. --- .../executingMiniblocks_test.go | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/integrationTests/singleShard/block/executingMiniblocks/executingMiniblocks_test.go b/integrationTests/singleShard/block/executingMiniblocks/executingMiniblocks_test.go index 8d6c00af8a..2c7bb0f7a7 100644 --- a/integrationTests/singleShard/block/executingMiniblocks/executingMiniblocks_test.go +++ b/integrationTests/singleShard/block/executingMiniblocks/executingMiniblocks_test.go @@ -82,12 +82,11 @@ func TestShardShouldNotProposeAndExecuteTwoBlocksInSameRound(t *testing.T) { } // TestShardShouldProposeBlockContainingInvalidTransactions tests the following scenario: -// 1. generate 3 move balance transactions: one that can be executed, one that can not be executed but the account has -// the balance for the fee and one that is completely invalid (no balance left for it) +// 1. generate 3 move balance transactions: one that can be executed, one to be processed as invalid, and one that isn't executable (no balance left for fee). // 2. proposer will have those 3 transactions in its pools and will propose a block // 3. another node will be able to sync the proposed block (and request - receive) the 2 transactions that // will end up in the block (one valid and one invalid) -// 4. the non-executable transaction will be removed from the proposer's pool +// 4. the non-executable transaction will not be immediately removed from the proposer's pool. See MX-16200. func TestShardShouldProposeBlockContainingInvalidTransactions(t *testing.T) { if testing.Short() { t.Skip("this is not a short test") @@ -195,7 +194,18 @@ func testStateOnNodes(t *testing.T, nodes []*integrationTests.TestProcessorNode, testTxIsInMiniblock(t, proposer, hashes[txValidIdx], block.TxBlock) testTxIsInMiniblock(t, proposer, hashes[txInvalidIdx], block.InvalidBlock) testTxIsInNotInBody(t, proposer, hashes[txDeletedIdx]) - testTxHashNotPresentInPool(t, proposer, hashes[txDeletedIdx]) + + // Removed from mempool. + _, ok := proposer.DataPool.Transactions().SearchFirstData(hashes[txValidIdx]) + assert.False(t, ok) + + // Removed from mempool. + _, ok = proposer.DataPool.Transactions().SearchFirstData(hashes[txInvalidIdx]) + assert.False(t, ok) + + // Not removed from mempool (see MX-16200). + _, ok = proposer.DataPool.Transactions().SearchFirstData(hashes[txDeletedIdx]) + assert.True(t, ok) } func testSameBlockHeight(t *testing.T, nodes []*integrationTests.TestProcessorNode, idxProposer int, expectedHeight uint64) { @@ -208,11 +218,6 @@ func testSameBlockHeight(t *testing.T, nodes []*integrationTests.TestProcessorNo } } -func testTxHashNotPresentInPool(t *testing.T, proposer *integrationTests.TestProcessorNode, hash []byte) { - txCache := proposer.DataPool.Transactions() - _, ok := txCache.SearchFirstData(hash) - assert.False(t, ok) -} func testTxIsInMiniblock(t *testing.T, proposer *integrationTests.TestProcessorNode, hash []byte, bt block.Type) { hdrHandler := proposer.BlockChain.GetCurrentBlockHeader()