Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Large MemoryPool Performance - Sort + intelligent TX reverification #500

Merged
merged 46 commits into from
Jan 13, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
8aefd5d
Initial Cut: Improve Large Mempool Performance - Sorted MemoryPool + …
Dec 5, 2018
dfd0b43
Address PR comments. Fix retrieving 'MaxFreeTransactionsPerBlock' fro…
Dec 5, 2018
ed6eaf1
Merge branch 'master' into SortedMempool
Dec 5, 2018
dc79b8a
Reverify unverified transactions if necessary when blockchain actor i…
Dec 5, 2018
2b056d9
Update MemoryPool.cs
shargon Dec 5, 2018
472b91a
Fix comments.
Dec 5, 2018
2078f72
Merge branch 'master' into SortedMempool
Dec 6, 2018
6a8a708
Handle re-enquing IDLE message if there are still more unverified tra…
Dec 6, 2018
17e8592
Implement simplifications called out in PR comments.
Dec 7, 2018
d5d8670
Merge branch 'master' into SortedMempool
Dec 7, 2018
d6ea86a
Remove duplicated code.
Dec 9, 2018
cfc8bce
Address PR comment: MaxHighPriorityTxsPerBlock can be the MaxTransact…
Dec 9, 2018
ca46ea0
Reduce duplicate code for getting the lowest fee transaction.
Dec 9, 2018
4483e51
Merge branch 'master' into SortedMempool
Dec 9, 2018
ad178b3
Improvements for consensus.
Dec 9, 2018
82e99b8
Merge branch 'master' into SortedMempool
vncoelho Dec 10, 2018
4ad73e9
Don't reverify transactions needlessly when not at the tip of the chain.
Dec 11, 2018
fb35ffb
moved FeePerByte to Transaction
igormcoelho Dec 12, 2018
d04c10e
Fix FeePerByte compilation error. Restore saving calculated FeePerByt…
Dec 12, 2018
9170667
caching on FeePerByte on Transaction
igormcoelho Dec 12, 2018
0344347
using minus satoshi as null
igormcoelho Dec 12, 2018
00916e6
removed cached FeePerByte
igormcoelho Dec 12, 2018
e5e6459
Back to original calculation
igormcoelho Dec 12, 2018
7eab439
Move away from ConcurrnetDictionary and handle locking efficiently to…
Dec 12, 2018
de31ad6
Merge branch 'master' into SortedMempool
Dec 12, 2018
5f3f01d
Use Transaction.FeePerByte.
Dec 12, 2018
205c3ae
Support passing a flag to 'getrawmempool' to retieve both verified an…
Dec 12, 2018
6d310db
Remove unused FeePerByte from PoolItem.
Dec 12, 2018
56e5b41
Update comment. Fix thread safety of default enumerator for MemoryPool.
Dec 12, 2018
8cbf639
Get blockchian height before reading MemoryPool transactions.
Dec 13, 2018
d51a353
Fix bug removing unverified transactions.
Dec 22, 2018
b9cff0d
Remove items from the unverified pool that are invalid upon attempt t…
Dec 22, 2018
97a3eb1
Merge branch 'master' into SortedMempool
Jan 8, 2019
278fab0
Fix build.
Jan 8, 2019
6fb2b1f
Merge branch 'master' into SortedMempool
Jan 8, 2019
a7f00c6
Derive MaxTransactionsPerBlock and MaxFreeTransactionsPerBlock from P…
Jan 8, 2019
928f566
Rebroadcast reverified transactions if it has been a while since last…
Jan 8, 2019
c60cdc3
Merge branch 'master' into SortedMempool
shargon Jan 10, 2019
e8dad65
Rebroadcast high proirity transactions staying in the pool more frequ…
Jan 10, 2019
dad6624
Fix a bug when removing over-capacity items from the pool.
Jan 10, 2019
a3dd1d1
Don't expire old free transactions, since there is no advantage in do…
Jan 10, 2019
cdee395
Expose MemoryPool from Blockchain since unsafe methods are marked int…
Jan 11, 2019
5a99b96
MemoryPool public.
Jan 11, 2019
2b63445
Merge branch 'master' into SortedMempool
shargon Jan 12, 2019
3009d49
Clean code
shargon Jan 12, 2019
02bc089
Update MemoryPool.cs
shargon Jan 12, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion neo/Consensus/ConsensusContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ public void Reset()

public void Fill()
{
IEnumerable<Transaction> mem_pool = Blockchain.Singleton.GetMemoryPool();
IEnumerable<Transaction> mem_pool = Blockchain.Singleton.GetMemoryPoolVerified();
foreach (IPolicyPlugin plugin in Plugin.Policies)
mem_pool = plugin.FilterForBlock(mem_pool);
List<Transaction> transactions = mem_pool.ToList();
Expand Down
37 changes: 17 additions & 20 deletions neo/Ledger/Blockchain.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Akka.Actor;
using Akka.Configuration;
using Neo.Cryptography;
using Neo.Cryptography.ECC;
using Neo.IO;
using Neo.IO.Actors;
Expand All @@ -12,10 +11,8 @@
using Neo.SmartContract;
using Neo.VM;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Threading;

namespace Neo.Ledger
Expand Down Expand Up @@ -114,14 +111,14 @@ public class ImportCompleted { }
}
};

private const int MaxTxToReverifyPerIdle = 10;
private static readonly object lockObj = new object();
private readonly NeoSystem system;
private readonly List<UInt256> header_index = new List<UInt256>();
private uint stored_header_count = 0;
private readonly Dictionary<UInt256, Block> block_cache = new Dictionary<UInt256, Block>();
private readonly Dictionary<uint, LinkedList<Block>> block_cache_unverified = new Dictionary<uint, LinkedList<Block>>();
private readonly MemoryPool mem_pool = new MemoryPool(50_000);
private readonly ConcurrentDictionary<UInt256, Transaction> mem_pool_unverified = new ConcurrentDictionary<UInt256, Transaction>();
internal readonly RelayCache RelayCache = new RelayCache(100);
private readonly HashSet<IActorRef> subscribers = new HashSet<IActorRef>();
private Snapshot currentSnapshot;
Expand Down Expand Up @@ -223,6 +220,11 @@ public IEnumerable<Transaction> GetMemoryPool()
return mem_pool;
}

public IEnumerable<Transaction> GetMemoryPoolVerified()
{
return mem_pool.GetVerifiedTransactions();
}

public Snapshot GetSnapshot()
{
return Store.GetSnapshot();
Expand All @@ -237,7 +239,7 @@ public Transaction GetTransaction(UInt256 hash)

internal Transaction GetUnverifiedTransaction(UInt256 hash)
{
mem_pool_unverified.TryGetValue(hash, out Transaction transaction);
mem_pool.TryGetUnverified(hash, out Transaction transaction);
return transaction;
}

Expand Down Expand Up @@ -289,7 +291,7 @@ private RelayResultReason OnNewBlock(Block block)
if (block.Index == Height + 1)
{
Block block_persist = block;
List<Block> blocksToPersistList = new List<Block>();
List<Block> blocksToPersistList = new List<Block>();
while (true)
{
blocksToPersistList.Add(block_persist);
Expand All @@ -315,7 +317,7 @@ private RelayResultReason OnNewBlock(Block block)
if (block_cache_unverified.TryGetValue(Height + 1, out LinkedList<Block> unverifiedBlocks))
{
foreach (var unverifiedBlock in unverifiedBlocks)
Self.Tell(unverifiedBlock, ActorRefs.NoSender);
Self.Tell(unverifiedBlock, ActorRefs.NoSender);
block_cache_unverified.Remove(Height + 1);
}
}
Expand Down Expand Up @@ -385,7 +387,9 @@ private RelayResultReason OnNewTransaction(Transaction transaction)
return RelayResultReason.Invalid;
if (ContainsTransaction(transaction.Hash))
return RelayResultReason.AlreadyExists;
if (!transaction.Verify(currentSnapshot, GetMemoryPool()))
if (!mem_pool.CanTransactionFitInPool(transaction))
return RelayResultReason.OutOfMemory;
if (!transaction.Verify(currentSnapshot, GetMemoryPoolVerified()))
return RelayResultReason.Invalid;
if (!Plugin.CheckPolicy(transaction))
return RelayResultReason.Unknown;
Expand All @@ -400,18 +404,7 @@ private RelayResultReason OnNewTransaction(Transaction transaction)
private void OnPersistCompleted(Block block)
{
block_cache.Remove(block.Hash);
foreach (Transaction tx in block.Transactions)
mem_pool.TryRemove(tx.Hash, out _);
mem_pool_unverified.Clear();
foreach (Transaction tx in mem_pool
.OrderByDescending(p => p.NetworkFee / p.Size)
.ThenByDescending(p => p.NetworkFee)
.ThenByDescending(p => new BigInteger(p.Hash.ToArray())))
{
mem_pool_unverified.TryAdd(tx.Hash, tx);
Self.Tell(tx, ActorRefs.NoSender);
}
mem_pool.Clear();
mem_pool.UpdatePoolForBlockPersisted(block, currentSnapshot);
PersistCompleted completed = new PersistCompleted { Block = block };
system.Consensus?.Tell(completed);
Distribute(completed);
Expand Down Expand Up @@ -439,6 +432,10 @@ protected override void OnReceive(object message)
case ConsensusPayload payload:
Sender.Tell(OnNewConsensus(payload));
break;
case Idle _:
if (mem_pool.ReVerifyTopUnverifiedTransactionsIfNeeded(MaxTxToReverifyPerIdle, currentSnapshot))
Self.Tell(Idle.Instance, ActorRefs.NoSender);
break;
case Terminated terminated:
subscribers.Remove(terminated.ActorRef);
break;
Expand Down
Loading