From dd0217481012501a586c933a340d56e85e175ad6 Mon Sep 17 00:00:00 2001 From: radu chis Date: Wed, 16 Nov 2022 11:35:11 +0200 Subject: [PATCH 01/11] added RandSeed and prevRandSeed to apiBlock --- data/api/apiBlock.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/api/apiBlock.go b/data/api/apiBlock.go index 9f5670933..8981fa58f 100644 --- a/data/api/apiBlock.go +++ b/data/api/apiBlock.go @@ -23,6 +23,8 @@ type Block struct { AccumulatedFeesInEpoch string `json:"accumulatedFeesInEpoch,omitempty"` DeveloperFeesInEpoch string `json:"developerFeesInEpoch,omitempty"` Status string `json:"status,omitempty"` + RandSeed string `json:"randSeed,omitempty"` + PrevRandSeed string `json:"prevRandSeed,omitempty"` Timestamp time.Duration `json:"timestamp,omitempty"` NotarizedBlocks []*NotarizedBlock `json:"notarizedBlocks,omitempty"` MiniBlocks []*MiniBlock `json:"miniBlocks,omitempty"` From 0e6e795c1ebd4e1ac265e3533041ffe06bdd253f Mon Sep 17 00:00:00 2001 From: radu chis Date: Thu, 17 Nov 2022 12:16:56 +0200 Subject: [PATCH 02/11] added transaction sort logic --- core/transaction/transactionSorter.go | 42 +++++++++++++++ core/transaction/transactionSorter_test.go | 61 ++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 core/transaction/transactionSorter.go create mode 100644 core/transaction/transactionSorter_test.go diff --git a/core/transaction/transactionSorter.go b/core/transaction/transactionSorter.go new file mode 100644 index 000000000..90028b3d3 --- /dev/null +++ b/core/transaction/transactionSorter.go @@ -0,0 +1,42 @@ +package transaction + +import ( + "bytes" + "github.com/ElrondNetwork/elrond-go-core/data/transaction" + "github.com/ElrondNetwork/elrond-go-core/hashing" + "sort" +) + +func SortTransactionsBySenderAndNonceWithFrontRunningProtection(transactions []*transaction.Transaction, hasher hashing.Hasher, randomness []byte) { + // make sure randomness is 32bytes and uniform + randSeed := hasher.Compute(string(randomness)) + xoredAddresses := make(map[string][]byte) + + for _, tx := range transactions { + xoredBytes := xorBytes(tx.GetSndAddr(), randSeed) + xoredAddresses[string(tx.GetSndAddr())] = hasher.Compute(string(xoredBytes)) + } + + sorter := func(i, j int) bool { + txI := transactions[i] + txJ := transactions[j] + + delta := bytes.Compare(xoredAddresses[string(txI.GetSndAddr())], xoredAddresses[string(txJ.GetSndAddr())]) + if delta == 0 { + delta = int(txI.GetNonce()) - int(txJ.GetNonce()) + } + + return delta < 0 + } + + sort.Slice(transactions, sorter) +} + +// parameters need to be of the same len, otherwise it will panic (if second slice shorter) +func xorBytes(a, b []byte) []byte { + res := make([]byte, len(a)) + for i := range a { + res[i] = a[i] ^ b[i] + } + return res +} diff --git a/core/transaction/transactionSorter_test.go b/core/transaction/transactionSorter_test.go new file mode 100644 index 000000000..5f450caec --- /dev/null +++ b/core/transaction/transactionSorter_test.go @@ -0,0 +1,61 @@ +package transaction + +import ( + "encoding/hex" + "fmt" + "github.com/ElrondNetwork/elrond-go-core/core/mock" + "github.com/ElrondNetwork/elrond-go-core/data/transaction" +) + +func Example_sortTransactionsBySenderAndNonceWithFrontRunningProtection() { + randomness := "randomness" + nbSenders := 5 + + hasher := &mock.HasherStub{ + ComputeCalled: func(s string) []byte { + if s == randomness { + return []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} + } + + return []byte(s) + }, + } + + usedRandomness := hasher.Compute(randomness) + senders := make([][]byte, 0) + for i := 0; i < nbSenders; i++ { + sender := make([]byte, len(usedRandomness)) + copy(sender, usedRandomness) + sender[len(usedRandomness)-1-i] = 0 + senders = append(senders, sender) + } + + txs := []*transaction.Transaction{ + {Nonce: 1, SndAddr: senders[0]}, + {Nonce: 2, SndAddr: senders[2]}, + {Nonce: 1, SndAddr: senders[2]}, + {Nonce: 2, SndAddr: senders[0]}, + {Nonce: 7, SndAddr: senders[1]}, + {Nonce: 6, SndAddr: senders[1]}, + {Nonce: 1, SndAddr: senders[4]}, + {Nonce: 3, SndAddr: senders[3]}, + {Nonce: 3, SndAddr: senders[2]}, + } + + SortTransactionsBySenderAndNonceWithFrontRunningProtection(txs, hasher, []byte(randomness)) + + for _, item := range txs { + fmt.Println(item.GetNonce(), hex.EncodeToString(item.GetSndAddr())) + } + + // Output: + // 1 ffffffffffffffffffffffffffffff00 + // 2 ffffffffffffffffffffffffffffff00 + // 6 ffffffffffffffffffffffffffff00ff + // 7 ffffffffffffffffffffffffffff00ff + // 1 ffffffffffffffffffffffffff00ffff + // 2 ffffffffffffffffffffffffff00ffff + // 3 ffffffffffffffffffffffffff00ffff + // 3 ffffffffffffffffffffffff00ffffff + // 1 ffffffffffffffffffffff00ffffffff +} From e9d526de7d729daf6222b67a993558486f3f599f Mon Sep 17 00:00:00 2001 From: radu chis Date: Thu, 17 Nov 2022 12:26:36 +0200 Subject: [PATCH 03/11] changed *Transaction to TransactionsHandler in sorter --- core/transaction/transactionSorter.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/transaction/transactionSorter.go b/core/transaction/transactionSorter.go index 90028b3d3..407d4e6df 100644 --- a/core/transaction/transactionSorter.go +++ b/core/transaction/transactionSorter.go @@ -2,12 +2,12 @@ package transaction import ( "bytes" - "github.com/ElrondNetwork/elrond-go-core/data/transaction" + "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/hashing" "sort" ) -func SortTransactionsBySenderAndNonceWithFrontRunningProtection(transactions []*transaction.Transaction, hasher hashing.Hasher, randomness []byte) { +func SortTransactionsBySenderAndNonceWithFrontRunningProtection(transactions []data.TransactionHandler, hasher hashing.Hasher, randomness []byte) { // make sure randomness is 32bytes and uniform randSeed := hasher.Compute(string(randomness)) xoredAddresses := make(map[string][]byte) From f9c4e512e629ac5da0e5c264fd99c32e2d48ddad Mon Sep 17 00:00:00 2001 From: radu chis Date: Thu, 17 Nov 2022 12:26:36 +0200 Subject: [PATCH 04/11] changed *Transaction to TransactionsHandler in sorter --- core/transaction/transactionSorter.go | 4 ++-- core/transaction/transactionSorter_test.go | 21 +++++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/core/transaction/transactionSorter.go b/core/transaction/transactionSorter.go index 90028b3d3..407d4e6df 100644 --- a/core/transaction/transactionSorter.go +++ b/core/transaction/transactionSorter.go @@ -2,12 +2,12 @@ package transaction import ( "bytes" - "github.com/ElrondNetwork/elrond-go-core/data/transaction" + "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/hashing" "sort" ) -func SortTransactionsBySenderAndNonceWithFrontRunningProtection(transactions []*transaction.Transaction, hasher hashing.Hasher, randomness []byte) { +func SortTransactionsBySenderAndNonceWithFrontRunningProtection(transactions []data.TransactionHandler, hasher hashing.Hasher, randomness []byte) { // make sure randomness is 32bytes and uniform randSeed := hasher.Compute(string(randomness)) xoredAddresses := make(map[string][]byte) diff --git a/core/transaction/transactionSorter_test.go b/core/transaction/transactionSorter_test.go index 5f450caec..0226e4ec9 100644 --- a/core/transaction/transactionSorter_test.go +++ b/core/transaction/transactionSorter_test.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "fmt" "github.com/ElrondNetwork/elrond-go-core/core/mock" + "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/transaction" ) @@ -30,16 +31,16 @@ func Example_sortTransactionsBySenderAndNonceWithFrontRunningProtection() { senders = append(senders, sender) } - txs := []*transaction.Transaction{ - {Nonce: 1, SndAddr: senders[0]}, - {Nonce: 2, SndAddr: senders[2]}, - {Nonce: 1, SndAddr: senders[2]}, - {Nonce: 2, SndAddr: senders[0]}, - {Nonce: 7, SndAddr: senders[1]}, - {Nonce: 6, SndAddr: senders[1]}, - {Nonce: 1, SndAddr: senders[4]}, - {Nonce: 3, SndAddr: senders[3]}, - {Nonce: 3, SndAddr: senders[2]}, + txs := []data.TransactionHandler{ + &transaction.Transaction{Nonce: 1, SndAddr: senders[0]}, + &transaction.Transaction{Nonce: 2, SndAddr: senders[2]}, + &transaction.Transaction{Nonce: 1, SndAddr: senders[2]}, + &transaction.Transaction{Nonce: 2, SndAddr: senders[0]}, + &transaction.Transaction{Nonce: 7, SndAddr: senders[1]}, + &transaction.Transaction{Nonce: 6, SndAddr: senders[1]}, + &transaction.Transaction{Nonce: 1, SndAddr: senders[4]}, + &transaction.Transaction{Nonce: 3, SndAddr: senders[3]}, + &transaction.Transaction{Nonce: 3, SndAddr: senders[2]}, } SortTransactionsBySenderAndNonceWithFrontRunningProtection(txs, hasher, []byte(randomness)) From 39046bdfbcdd043a2bddb0b796c2829418d26ea2 Mon Sep 17 00:00:00 2001 From: radu chis Date: Thu, 17 Nov 2022 16:40:57 +0200 Subject: [PATCH 05/11] fix after review --- core/transaction/transactionSorter.go | 4 ++- core/transaction/transactionSorter_test.go | 30 ++++++++++++---------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/core/transaction/transactionSorter.go b/core/transaction/transactionSorter.go index 407d4e6df..7232d48da 100644 --- a/core/transaction/transactionSorter.go +++ b/core/transaction/transactionSorter.go @@ -2,11 +2,13 @@ package transaction import ( "bytes" + "sort" + "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/hashing" - "sort" ) +// SortTransactionsBySenderAndNonceWithFrontRunningProtection - sorts the transactions by address and randomness source to protect from front running func SortTransactionsBySenderAndNonceWithFrontRunningProtection(transactions []data.TransactionHandler, hasher hashing.Hasher, randomness []byte) { // make sure randomness is 32bytes and uniform randSeed := hasher.Compute(string(randomness)) diff --git a/core/transaction/transactionSorter_test.go b/core/transaction/transactionSorter_test.go index 0226e4ec9..41473d469 100644 --- a/core/transaction/transactionSorter_test.go +++ b/core/transaction/transactionSorter_test.go @@ -3,12 +3,15 @@ package transaction import ( "encoding/hex" "fmt" + "testing" + "github.com/ElrondNetwork/elrond-go-core/core/mock" "github.com/ElrondNetwork/elrond-go-core/data" "github.com/ElrondNetwork/elrond-go-core/data/transaction" + "github.com/stretchr/testify/assert" ) -func Example_sortTransactionsBySenderAndNonceWithFrontRunningProtection() { +func Test_sortTransactionsBySenderAndNonceWithFrontRunningProtection(t *testing.T) { randomness := "randomness" nbSenders := 5 @@ -45,18 +48,19 @@ func Example_sortTransactionsBySenderAndNonceWithFrontRunningProtection() { SortTransactionsBySenderAndNonceWithFrontRunningProtection(txs, hasher, []byte(randomness)) - for _, item := range txs { - fmt.Println(item.GetNonce(), hex.EncodeToString(item.GetSndAddr())) + expectedOutput := []string{ + "1 ffffffffffffffffffffffffffffff00", + "2 ffffffffffffffffffffffffffffff00", + "6 ffffffffffffffffffffffffffff00ff", + "7 ffffffffffffffffffffffffffff00ff", + "1 ffffffffffffffffffffffffff00ffff", + "2 ffffffffffffffffffffffffff00ffff", + "3 ffffffffffffffffffffffffff00ffff", + "3 ffffffffffffffffffffffff00ffffff", + "1 ffffffffffffffffffffff00ffffffff", } - // Output: - // 1 ffffffffffffffffffffffffffffff00 - // 2 ffffffffffffffffffffffffffffff00 - // 6 ffffffffffffffffffffffffffff00ff - // 7 ffffffffffffffffffffffffffff00ff - // 1 ffffffffffffffffffffffffff00ffff - // 2 ffffffffffffffffffffffffff00ffff - // 3 ffffffffffffffffffffffffff00ffff - // 3 ffffffffffffffffffffffff00ffffff - // 1 ffffffffffffffffffffff00ffffffff + for i, item := range txs { + assert.Equal(t, expectedOutput[i], fmt.Sprintf("%d %s", item.GetNonce(), hex.EncodeToString(item.GetSndAddr()))) + } } From d5261a33b367b4057e66090ce16c8135610a4e63 Mon Sep 17 00:00:00 2001 From: radu chis Date: Fri, 18 Nov 2022 12:50:02 +0200 Subject: [PATCH 06/11] added legacy sorting --- core/transaction/transactionSorter.go | 17 +++++++++++ core/transaction/transactionSorter_test.go | 33 +++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/core/transaction/transactionSorter.go b/core/transaction/transactionSorter.go index 7232d48da..2b01c218c 100644 --- a/core/transaction/transactionSorter.go +++ b/core/transaction/transactionSorter.go @@ -34,6 +34,23 @@ func SortTransactionsBySenderAndNonceWithFrontRunningProtection(transactions []d sort.Slice(transactions, sorter) } +// SortTransactionsBySenderAndNonce - sorts the transactions by address without the front running protection +func SortTransactionsBySenderAndNonce(transactions []data.TransactionHandler) { + sorter := func(i, j int) bool { + txI := transactions[i] + txJ := transactions[j] + + delta := bytes.Compare(txI.GetSndAddr(), txJ.GetSndAddr()) + if delta == 0 { + delta = int(txI.GetNonce()) - int(txJ.GetNonce()) + } + + return delta < 0 + } + + sort.Slice(transactions, sorter) +} + // parameters need to be of the same len, otherwise it will panic (if second slice shorter) func xorBytes(a, b []byte) []byte { res := make([]byte, len(a)) diff --git a/core/transaction/transactionSorter_test.go b/core/transaction/transactionSorter_test.go index 41473d469..24c5141e4 100644 --- a/core/transaction/transactionSorter_test.go +++ b/core/transaction/transactionSorter_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/assert" ) -func Test_sortTransactionsBySenderAndNonceWithFrontRunningProtection(t *testing.T) { +func Test_SortTransactionsBySenderAndNonceWithFrontRunningProtection(t *testing.T) { randomness := "randomness" nbSenders := 5 @@ -64,3 +64,34 @@ func Test_sortTransactionsBySenderAndNonceWithFrontRunningProtection(t *testing. assert.Equal(t, expectedOutput[i], fmt.Sprintf("%d %s", item.GetNonce(), hex.EncodeToString(item.GetSndAddr()))) } } + +func Test_SortTransactionsBySenderAndNonceLegacy(t *testing.T) { + txs := []data.TransactionHandler{ + &transaction.Transaction{Nonce: 3, SndAddr: []byte("bbbb")}, + &transaction.Transaction{Nonce: 1, SndAddr: []byte("aaaa")}, + &transaction.Transaction{Nonce: 5, SndAddr: []byte("bbbb")}, + &transaction.Transaction{Nonce: 2, SndAddr: []byte("aaaa")}, + &transaction.Transaction{Nonce: 7, SndAddr: []byte("aabb")}, + &transaction.Transaction{Nonce: 6, SndAddr: []byte("aabb")}, + &transaction.Transaction{Nonce: 3, SndAddr: []byte("ffff")}, + &transaction.Transaction{Nonce: 3, SndAddr: []byte("eeee")}, + } + + SortTransactionsBySenderAndNonce(txs) + + expectedOutput := []string{ + "1 aaaa", + "2 aaaa", + "6 aabb", + "7 aabb", + "3 bbbb", + "5 bbbb", + "3 eeee", + "3 ffff", + } + + for i, item := range txs { + assert.Equal(t, expectedOutput[i], fmt.Sprintf("%d %s", item.GetNonce(), string(item.GetSndAddr()))) + } + +} From 96a7d5973f70c7bdfed0f6c9486c8efb812aa50e Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 7 Dec 2022 14:20:38 +0200 Subject: [PATCH 07/11] continue implementation --- core/transaction/transactionSorter.go | 28 +++++++++++++++++++++++++++ data/interface.go | 2 ++ data/outport/txWithFee.go | 11 +++++++++++ 3 files changed, 41 insertions(+) diff --git a/core/transaction/transactionSorter.go b/core/transaction/transactionSorter.go index 2b01c218c..325d760cf 100644 --- a/core/transaction/transactionSorter.go +++ b/core/transaction/transactionSorter.go @@ -34,6 +34,34 @@ func SortTransactionsBySenderAndNonceWithFrontRunningProtection(transactions []d sort.Slice(transactions, sorter) } +// TODO remove duplicated function when will use the new version of go + +// SortTransactionsBySenderAndNonceWithFrontRunningProtectionExtendedTransactions - sorts the transactions by address and randomness source to protect from front running +func SortTransactionsBySenderAndNonceWithFrontRunningProtectionExtendedTransactions(transactions []data.TransactionHandlerWithGasUsedAndFee, hasher hashing.Hasher, randomness []byte) { + // make sure randomness is 32bytes and uniform + randSeed := hasher.Compute(string(randomness)) + xoredAddresses := make(map[string][]byte) + + for _, tx := range transactions { + xoredBytes := xorBytes(tx.GetSndAddr(), randSeed) + xoredAddresses[string(tx.GetSndAddr())] = hasher.Compute(string(xoredBytes)) + } + + sorter := func(i, j int) bool { + txI := transactions[i] + txJ := transactions[j] + + delta := bytes.Compare(xoredAddresses[string(txI.GetSndAddr())], xoredAddresses[string(txJ.GetSndAddr())]) + if delta == 0 { + delta = int(txI.GetNonce()) - int(txJ.GetNonce()) + } + + return delta < 0 + } + + sort.Slice(transactions, sorter) +} + // SortTransactionsBySenderAndNonce - sorts the transactions by address without the front running protection func SortTransactionsBySenderAndNonce(transactions []data.TransactionHandler) { sorter := func(i, j int) bool { diff --git a/data/interface.go b/data/interface.go index cd8edde7f..e2ac94b2a 100644 --- a/data/interface.go +++ b/data/interface.go @@ -291,6 +291,8 @@ type TransactionHandlerWithGasUsedAndFee interface { GetGasUsed() uint64 GetFee() *big.Int GetTxHandler() TransactionHandler + SetExecutionOrder(order int) + GetExecutionOrder() int } // LogHandler defines the type for a log resulted from executing a transaction or smart contract call diff --git a/data/outport/txWithFee.go b/data/outport/txWithFee.go index b5bffa89f..d8c71c576 100644 --- a/data/outport/txWithFee.go +++ b/data/outport/txWithFee.go @@ -17,6 +17,7 @@ type FeeInfo struct { type TransactionHandlerWithGasAndFee struct { data.TransactionHandler FeeInfo + ExecutionOrder int } // NewTransactionHandlerWithGasAndFee returns a new instance of transactionHandlerWithGasAndFee which matches the interface @@ -65,6 +66,16 @@ func (t *TransactionHandlerWithGasAndFee) GetTxHandler() data.TransactionHandler return t.TransactionHandler } +// SetExecutionOrder will set the execution order of the TransactionHandler +func (t *TransactionHandlerWithGasAndFee) SetExecutionOrder(order int) { + t.ExecutionOrder = order +} + +// GetExecutionOrder will return the execution order of the TransactionHandler +func (t *TransactionHandlerWithGasAndFee) GetExecutionOrder() int { + return t.ExecutionOrder +} + // WrapTxsMap will wrap the provided transactions map in a map fo transactions with fee and gas used func WrapTxsMap(txs map[string]data.TransactionHandler) map[string]data.TransactionHandlerWithGasUsedAndFee { newMap := make(map[string]data.TransactionHandlerWithGasUsedAndFee, len(txs)) From 978ce3e1571bac57631822a4259ed4cf1ecb3e4d Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Tue, 13 Dec 2022 10:43:09 +0200 Subject: [PATCH 08/11] extend test --- core/transaction/transactionSorter_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/transaction/transactionSorter_test.go b/core/transaction/transactionSorter_test.go index 24c5141e4..607e25870 100644 --- a/core/transaction/transactionSorter_test.go +++ b/core/transaction/transactionSorter_test.go @@ -3,10 +3,12 @@ package transaction import ( "encoding/hex" "fmt" + "math/big" "testing" "github.com/ElrondNetwork/elrond-go-core/core/mock" "github.com/ElrondNetwork/elrond-go-core/data" + "github.com/ElrondNetwork/elrond-go-core/data/outport" "github.com/ElrondNetwork/elrond-go-core/data/transaction" "github.com/stretchr/testify/assert" ) @@ -45,8 +47,13 @@ func Test_SortTransactionsBySenderAndNonceWithFrontRunningProtection(t *testing. &transaction.Transaction{Nonce: 3, SndAddr: senders[3]}, &transaction.Transaction{Nonce: 3, SndAddr: senders[2]}, } + wrappedTxs := make([]data.TransactionHandlerWithGasUsedAndFee, 0, len(txs)) + for _, tx := range txs { + wrappedTxs = append(wrappedTxs, outport.NewTransactionHandlerWithGasAndFee(tx, 0, big.NewInt(0))) + } SortTransactionsBySenderAndNonceWithFrontRunningProtection(txs, hasher, []byte(randomness)) + SortTransactionsBySenderAndNonceWithFrontRunningProtectionExtendedTransactions(wrappedTxs, hasher, []byte(randomness)) expectedOutput := []string{ "1 ffffffffffffffffffffffffffffff00", @@ -62,6 +69,7 @@ func Test_SortTransactionsBySenderAndNonceWithFrontRunningProtection(t *testing. for i, item := range txs { assert.Equal(t, expectedOutput[i], fmt.Sprintf("%d %s", item.GetNonce(), hex.EncodeToString(item.GetSndAddr()))) + assert.Equal(t, expectedOutput[i], fmt.Sprintf("%d %s", wrappedTxs[i].GetNonce(), hex.EncodeToString(wrappedTxs[i].GetSndAddr()))) } } From 721dd217ea1232e1103271bcbe24d4b343d95803 Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Wed, 14 Dec 2022 17:02:47 +0200 Subject: [PATCH 09/11] sort extended transactions --- core/transaction/transactionSorter.go | 17 +++++++++++++++++ core/transaction/transactionSorter_test.go | 7 ++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/core/transaction/transactionSorter.go b/core/transaction/transactionSorter.go index 325d760cf..04bdb59b4 100644 --- a/core/transaction/transactionSorter.go +++ b/core/transaction/transactionSorter.go @@ -79,6 +79,23 @@ func SortTransactionsBySenderAndNonce(transactions []data.TransactionHandler) { sort.Slice(transactions, sorter) } +// SortTransactionsBySenderAndNonceExtendedTransactions - sorts the transactions by address without the front running protection +func SortTransactionsBySenderAndNonceExtendedTransactions(transactions []data.TransactionHandlerWithGasUsedAndFee) { + sorter := func(i, j int) bool { + txI := transactions[i] + txJ := transactions[j] + + delta := bytes.Compare(txI.GetSndAddr(), txJ.GetSndAddr()) + if delta == 0 { + delta = int(txI.GetNonce()) - int(txJ.GetNonce()) + } + + return delta < 0 + } + + sort.Slice(transactions, sorter) +} + // parameters need to be of the same len, otherwise it will panic (if second slice shorter) func xorBytes(a, b []byte) []byte { res := make([]byte, len(a)) diff --git a/core/transaction/transactionSorter_test.go b/core/transaction/transactionSorter_test.go index 607e25870..3e88e3837 100644 --- a/core/transaction/transactionSorter_test.go +++ b/core/transaction/transactionSorter_test.go @@ -84,8 +84,13 @@ func Test_SortTransactionsBySenderAndNonceLegacy(t *testing.T) { &transaction.Transaction{Nonce: 3, SndAddr: []byte("ffff")}, &transaction.Transaction{Nonce: 3, SndAddr: []byte("eeee")}, } + wrappedTxs := make([]data.TransactionHandlerWithGasUsedAndFee, 0, len(txs)) + for _, tx := range txs { + wrappedTxs = append(wrappedTxs, outport.NewTransactionHandlerWithGasAndFee(tx, 0, big.NewInt(0))) + } SortTransactionsBySenderAndNonce(txs) + SortTransactionsBySenderAndNonceExtendedTransactions(wrappedTxs) expectedOutput := []string{ "1 aaaa", @@ -100,6 +105,6 @@ func Test_SortTransactionsBySenderAndNonceLegacy(t *testing.T) { for i, item := range txs { assert.Equal(t, expectedOutput[i], fmt.Sprintf("%d %s", item.GetNonce(), string(item.GetSndAddr()))) + assert.Equal(t, expectedOutput[i], fmt.Sprintf("%d %s", wrappedTxs[i].GetNonce(), string(wrappedTxs[i].GetSndAddr()))) } - } From 0e69a10c3cb5132775181fb3d49edc6f0788433f Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 15 Dec 2022 12:11:51 +0200 Subject: [PATCH 10/11] extend transactions pool --- data/outport/dtos.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/data/outport/dtos.go b/data/outport/dtos.go index cd36752b6..f32188ff6 100644 --- a/data/outport/dtos.go +++ b/data/outport/dtos.go @@ -71,12 +71,14 @@ type HeaderGasConsumption struct { // Pool will hold all types of transaction type Pool struct { - Txs map[string]data.TransactionHandlerWithGasUsedAndFee - Scrs map[string]data.TransactionHandlerWithGasUsedAndFee - Rewards map[string]data.TransactionHandlerWithGasUsedAndFee - Invalid map[string]data.TransactionHandlerWithGasUsedAndFee - Receipts map[string]data.TransactionHandlerWithGasUsedAndFee - Logs []*data.LogData + Txs map[string]data.TransactionHandlerWithGasUsedAndFee + Scrs map[string]data.TransactionHandlerWithGasUsedAndFee + Rewards map[string]data.TransactionHandlerWithGasUsedAndFee + Invalid map[string]data.TransactionHandlerWithGasUsedAndFee + Receipts map[string]data.TransactionHandlerWithGasUsedAndFee + Logs []*data.LogData + ScheduledExecutedSCRSHashesPrevBlock []string + ScheduledExecutedInvalidTxsHashesPrevBlock []string } // ValidatorRatingInfo is a structure containing validator rating information From 4470c3627b04dcfbfa53c93f333c66911e61325d Mon Sep 17 00:00:00 2001 From: Iuga Mihai Date: Thu, 15 Dec 2022 12:20:38 +0200 Subject: [PATCH 11/11] fix todo --- core/transaction/transactionSorter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/transaction/transactionSorter.go b/core/transaction/transactionSorter.go index 04bdb59b4..e6448aa2e 100644 --- a/core/transaction/transactionSorter.go +++ b/core/transaction/transactionSorter.go @@ -34,7 +34,7 @@ func SortTransactionsBySenderAndNonceWithFrontRunningProtection(transactions []d sort.Slice(transactions, sorter) } -// TODO remove duplicated function when will use the new version of go +// TODO remove duplicated function when will use the version of elrond-go which exports transaction order during processing // SortTransactionsBySenderAndNonceWithFrontRunningProtectionExtendedTransactions - sorts the transactions by address and randomness source to protect from front running func SortTransactionsBySenderAndNonceWithFrontRunningProtectionExtendedTransactions(transactions []data.TransactionHandlerWithGasUsedAndFee, hasher hashing.Hasher, randomness []byte) {