From 5d68f8819670ea1a86ab52052bb454538af0fe82 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 13 Dec 2019 23:23:33 +0300 Subject: [PATCH 1/2] core: fix and speed up mempool Verify() First of all, it was wrong, it was not checking for inputs really, it compared tx hashes for some reason, second, when it did compare inputs it compared only the PrevIndex part of them which is also wrong. Also, there is absolutely no reason to go through GetVerifiedTransactions() here, we don't need this copy of pointers and it can also be outdated by the time we're to finish our check. Before: BenchmarkTXPerformanceTest-4 5000 485506 ns/op 65886 B/op 409 allocs/op ok github.com/CityOfZion/neo-go/integration 3.212s After: enchmarkTXPerformanceTest-4 5000 371104 ns/op 44367 B/op 408 allocs/op ok github.com/CityOfZion/neo-go/integration 2.712s --- pkg/core/mem_pool.go | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/pkg/core/mem_pool.go b/pkg/core/mem_pool.go index a01793a5d..2a629d403 100644 --- a/pkg/core/mem_pool.go +++ b/pkg/core/mem_pool.go @@ -287,23 +287,17 @@ func (mp *MemPool) GetVerifiedTransactions() []*transaction.Transaction { // If yes, the transaction tx is not a valid transaction and the function return false. // If no, the transaction tx is a valid transaction and the function return true. func (mp MemPool) Verify(tx *transaction.Transaction) bool { - count := 0 - inputs := make([]*transaction.Input, 0) - for _, item := range mp.GetVerifiedTransactions() { - if tx.Hash().Equals(item.Hash()) { - for i := range item.Inputs { - inputs = append(inputs, &item.Inputs[i]) + mp.lock.RLock() + defer mp.lock.RUnlock() + for _, item := range mp.unsortedTxn { + for i := range item.txn.Inputs { + for j := 0; j < len(tx.Inputs); j++ { + if item.txn.Inputs[i] == tx.Inputs[j] { + return false + } } } } - for i := 0; i < len(inputs); i++ { - for j := 0; j < len(tx.Inputs); j++ { - if inputs[i].PrevHash.Equals(tx.Inputs[j].PrevHash) { - count++ - } - } - } - - return count == 0 + return true } From 7a5e995030eabc5d012ce105a1a08d5f500ec6de Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Sat, 14 Dec 2019 00:03:04 +0300 Subject: [PATCH 2/2] core: add MemPool Verify() test --- pkg/core/mem_pool_test.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/pkg/core/mem_pool_test.go b/pkg/core/mem_pool_test.go index bfd12230b..b75419d17 100644 --- a/pkg/core/mem_pool_test.go +++ b/pkg/core/mem_pool_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/CityOfZion/neo-go/pkg/core/transaction" + "github.com/CityOfZion/neo-go/pkg/internal/random" "github.com/CityOfZion/neo-go/pkg/util" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -62,3 +63,28 @@ func TestMemPoolAddRemove(t *testing.T) { fs.lowPriority = true t.Run("high priority", func(t *testing.T) { testMemPoolAddRemoveWithFeer(t, fs) }) } + +func TestMemPoolVerify(t *testing.T) { + mp := NewMemPool(10) + tx := newMinerTX() + inhash1 := random.Uint256() + tx.Inputs = append(tx.Inputs, transaction.Input{PrevHash: inhash1, PrevIndex: 0}) + require.Equal(t, true, mp.Verify(tx)) + item := NewPoolItem(tx, &FeerStub{}) + require.Equal(t, true, mp.TryAdd(tx.Hash(), item)) + + tx2 := newMinerTX() + inhash2 := random.Uint256() + tx2.Inputs = append(tx2.Inputs, transaction.Input{PrevHash: inhash2, PrevIndex: 0}) + require.Equal(t, true, mp.Verify(tx2)) + item = NewPoolItem(tx2, &FeerStub{}) + require.Equal(t, true, mp.TryAdd(tx2.Hash(), item)) + + tx3 := newMinerTX() + // Different index number, but the same PrevHash as in tx1. + tx3.Inputs = append(tx3.Inputs, transaction.Input{PrevHash: inhash1, PrevIndex: 1}) + require.Equal(t, true, mp.Verify(tx3)) + // The same input as in tx2. + tx3.Inputs = append(tx3.Inputs, transaction.Input{PrevHash: inhash2, PrevIndex: 0}) + require.Equal(t, false, mp.Verify(tx3)) +}