From 518a59ec99e5b7a7c2e5a0f6e15dc2924c985454 Mon Sep 17 00:00:00 2001 From: jsolman Date: Sat, 19 Jan 2019 19:26:55 -0800 Subject: [PATCH] Treat Claim transactions as the highest low priority transactions. (#565) --- neo.UnitTests/UT_PoolItem.cs | 26 ++++++++++++++++++++++++++ neo/Ledger/PoolItem.cs | 25 ++++++++++++++----------- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/neo.UnitTests/UT_PoolItem.cs b/neo.UnitTests/UT_PoolItem.cs index 3ef28356dc..0d8a8bc19a 100644 --- a/neo.UnitTests/UT_PoolItem.cs +++ b/neo.UnitTests/UT_PoolItem.cs @@ -33,6 +33,19 @@ public void TestCleanup() TimeProvider.ResetToDefault(); } + [TestMethod] + public void PoolItem_CompareTo_ClaimTx() + { + var tx1 = GenerateClaimTx(); + // Non-free low-priority transaction + var tx2 = MockGenerateInvocationTx(new Fixed8(99999), 50).Object; + + var poolItem1 = new PoolItem(tx1); + var poolItem2 = new PoolItem(tx2); + poolItem1.CompareTo(poolItem2).Should().Be(1); + poolItem2.CompareTo(poolItem1).Should().Be(-1); + } + [TestMethod] public void PoolItem_CompareTo_Fee() { @@ -122,6 +135,19 @@ public Mock GenerateMockTxWithFirstByteOfHashLessThanOrEq return mockTx; } + public static Transaction GenerateClaimTx() + { + var mockTx = new Mock(); + mockTx.CallBase = true; + mockTx.SetupGet(mr => mr.NetworkFee).Returns(Fixed8.Zero); + mockTx.SetupGet(mr => mr.Size).Returns(50); + var tx = mockTx.Object; + tx.Attributes = new TransactionAttribute[0]; + tx.Inputs = new CoinReference[0]; + tx.Outputs = new TransactionOutput[0]; + tx.Witnesses = new Witness[0]; + return mockTx.Object; + } // Generate Mock InvocationTransaction with different sizes and prices public static Mock MockGenerateInvocationTx(Fixed8 networkFee, int size, byte[] overrideScriptBytes=null) diff --git a/neo/Ledger/PoolItem.cs b/neo/Ledger/PoolItem.cs index 13dc9b9344..3810330dc4 100644 --- a/neo/Ledger/PoolItem.cs +++ b/neo/Ledger/PoolItem.cs @@ -1,19 +1,10 @@ using Neo.Network.P2P.Payloads; using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Threading; -using Akka.Util.Internal; -using Neo.Network.P2P; -using Neo.Persistence; -using Neo.Plugins; namespace Neo.Ledger { /// - /// Represents an item in the Memory Pool. + /// Represents an item in the Memory Pool. /// // Note: PoolItem objects don't consider transaction priority (low or high) in their compare CompareTo method. /// This is because items of differing priority are never added to the same sorted set in MemoryPool. @@ -31,7 +22,7 @@ internal class PoolItem : IComparable public readonly DateTime Timestamp; /// - /// Timestamp where this transaction was last broadcast to other nodes + /// Timestamp when this transaction was last broadcast to other nodes /// public DateTime LastBroadcastTimestamp; @@ -45,6 +36,18 @@ internal PoolItem(Transaction tx) public int CompareTo(Transaction otherTx) { if (otherTx == null) return 1; + if (Tx.IsLowPriority && otherTx.IsLowPriority) + { + bool thisIsClaimTx = Tx is ClaimTransaction; + bool otherIsClaimTx = otherTx is ClaimTransaction; + if (thisIsClaimTx != otherIsClaimTx) + { + // This is a claim Tx and other isn't. + if (thisIsClaimTx) return 1; + // The other is claim Tx and this isn't. + return -1; + } + } // Fees sorted ascending int ret = Tx.FeePerByte.CompareTo(otherTx.FeePerByte); if (ret != 0) return ret;