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

Simple Way to Parallel Verification Transaction #1298

Merged
merged 38 commits into from
Dec 1, 2019
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
1bab96b
parallel verify
eryeer Nov 11, 2019
539875c
add create parallel verifier after terminated
eryeer Nov 12, 2019
4f5a229
update UT
eryeer Nov 12, 2019
b2e3600
format
eryeer Nov 12, 2019
6697e13
add UT
eryeer Nov 12, 2019
2df2035
optimize
eryeer Nov 12, 2019
1cbbbf2
Add readonly
shargon Nov 12, 2019
ef36f25
remove numerics
eryeer Nov 12, 2019
08cd901
Merge branch 'pr_multiTxVerifierActor' of github.com:eryeer/neoUT int…
eryeer Nov 12, 2019
5c4013a
Update TransactionParallelVerifier.cs
shargon Nov 12, 2019
9982459
Move feePeerByte again inside the lock
shargon Nov 12, 2019
c755139
Clean
shargon Nov 12, 2019
9756837
update tryGet
eryeer Nov 12, 2019
af606d3
format
eryeer Nov 12, 2019
4b5ff44
format
eryeer Nov 12, 2019
64619f6
Merge branch 'master' into pr_multiTxVerifierActor
erikzhang Nov 13, 2019
782d5a2
Merge branch 'master' into pr_multiTxVerifierActor
lock9 Nov 13, 2019
cfa6598
Merge branch 'master' into pr_multiTxVerifierActor
eryeer Nov 14, 2019
be24593
Merge branch 'master' into pr_multiTxVerifierActor
eryeer Nov 18, 2019
faf8e09
merge Conflict
eryeer Nov 27, 2019
932d529
use new parallel approach
eryeer Nov 27, 2019
9e41b2f
update
eryeer Nov 27, 2019
a000fd9
update
eryeer Nov 27, 2019
919ea0c
refactor
eryeer Nov 28, 2019
4cb2e12
Merge branch 'master' into pr_multiTxVerifierActor
eryeer Nov 28, 2019
09142db
Reorganise
erikzhang Nov 28, 2019
295450d
Remove the useless UT
erikzhang Nov 28, 2019
8fdfcc2
Merge branch 'master' into pr_multiTxVerifierActor
eryeer Nov 29, 2019
6d40876
Merge branch 'master' into pr_multiTxVerifierActor
erikzhang Nov 29, 2019
bff2210
Merge branch 'master' into pr_multiTxVerifierActor
vncoelho Nov 29, 2019
0fb410e
Rename Reverify to VerifyForEachBlock
vncoelho Nov 29, 2019
c84b217
Reorder methods
erikzhang Nov 29, 2019
62e5fe9
Update Transaction.cs
erikzhang Nov 29, 2019
e5124ed
Remove duplicate
shargon Nov 29, 2019
081dac5
Should check `CanTransactionFitInPool()` again
erikzhang Nov 29, 2019
e07331a
Remove duplicate check
erikzhang Nov 29, 2019
e333115
Merge branch 'master' into pr_multiTxVerifierActor
erikzhang Dec 1, 2019
d72241d
More RelayResultReason
erikzhang Dec 1, 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
56 changes: 41 additions & 15 deletions src/neo/Ledger/Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Neo.Ledger
{
Expand All @@ -26,6 +27,7 @@ public class Import { public IEnumerable<Block> Blocks; }
public class ImportCompleted { }
public class FillMemoryPool { public IEnumerable<Transaction> Transactions; }
public class FillCompleted { }
private class ParallelVerified { public Transaction Transaction; public bool ShouldRelay; public bool VerifyResult; }

public static readonly uint MillisecondsPerBlock = ProtocolSettings.Default.MillisecondsPerBlock;
public const uint DecrementInterval = 2000000;
Expand Down Expand Up @@ -395,22 +397,43 @@ private void OnNewHeaders(Header[] headers)
system.TaskManager.Tell(new TaskManager.HeaderTaskCompleted(), Sender);
}

private RelayResultReason OnNewTransaction(Transaction transaction, bool relay)
private void OnNewTransaction(Transaction transaction, bool relay)
{
RelayResultReason reason = RelayResultReason.Succeed;
if (ContainsTransaction(transaction.Hash))
return RelayResultReason.AlreadyExists;
if (!MemPool.CanTransactionFitInPool(transaction))
return RelayResultReason.OutOfMemory;
if (!transaction.Verify(currentSnapshot, MemPool.SendersFeeMonitor.GetSenderFee(transaction.Sender)))
return RelayResultReason.Invalid;
if (!NativeContract.Policy.CheckPolicy(transaction, currentSnapshot))
return RelayResultReason.PolicyFail;

if (!MemPool.TryAdd(transaction.Hash, transaction))
return RelayResultReason.OutOfMemory;
if (relay)
system.LocalNode.Tell(new LocalNode.RelayDirectly { Inventory = transaction });
return RelayResultReason.Succeed;
reason = RelayResultReason.AlreadyExists;
else if (!MemPool.CanTransactionFitInPool(transaction))
reason = RelayResultReason.OutOfMemory;
else if (!transaction.VerifyForEachBlock(currentSnapshot, MemPool.SendersFeeMonitor.GetSenderFee(transaction.Sender)))
reason = RelayResultReason.Invalid;
else if (!NativeContract.Policy.CheckPolicy(transaction, currentSnapshot))
reason = RelayResultReason.PolicyFail;
if (reason != RelayResultReason.Succeed)
{
Sender.Tell(reason);
return;
}
Task.Run(() =>
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
{
return new ParallelVerified
{
Transaction = transaction,
ShouldRelay = relay,
VerifyResult = transaction.VerifyParallelParts(currentSnapshot)
};
}).PipeTo(Self, Sender);
}

private void OnParallelVerified(ParallelVerified parallelVerified)
{
RelayResultReason reason = RelayResultReason.Succeed;
if (!parallelVerified.VerifyResult)
reason = RelayResultReason.Invalid;
else if (!MemPool.TryAdd(parallelVerified.Transaction.Hash, parallelVerified.Transaction))
reason = RelayResultReason.OutOfMemory;
if (reason == RelayResultReason.Succeed && parallelVerified.ShouldRelay)
system.LocalNode.Tell(new LocalNode.RelayDirectly { Inventory = parallelVerified.Transaction });
Sender.Tell(reason);
}

private void OnPersistCompleted(Block block)
Expand Down Expand Up @@ -443,7 +466,10 @@ protected override void OnReceive(object message)
break;
}
case Transaction transaction:
Sender.Tell(OnNewTransaction(transaction, true));
OnNewTransaction(transaction, true);
break;
case ParallelVerified parallelVerified:
OnParallelVerified(parallelVerified);
break;
case ConsensusPayload payload:
Sender.Tell(OnNewConsensus(payload));
Expand Down
2 changes: 1 addition & 1 deletion src/neo/Ledger/MemoryPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ private int ReverifyTransactions(SortedSet<PoolItem> verifiedSortedTxPool,
// Since unverifiedSortedTxPool is ordered in an ascending manner, we take from the end.
foreach (PoolItem item in unverifiedSortedTxPool.Reverse().Take(count))
{
if (item.Tx.Reverify(snapshot, SendersFeeMonitor.GetSenderFee(item.Tx.Sender)))
if (item.Tx.VerifyForEachBlock(snapshot, SendersFeeMonitor.GetSenderFee(item.Tx.Sender)))
{
reverifiedItems.Add(item);
SendersFeeMonitor.AddSenderFee(item.Tx);
Expand Down
45 changes: 25 additions & 20 deletions src/neo/Network/P2P/Payloads/Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,25 +205,6 @@ public UInt160[] GetScriptHashesForVerifying(StoreView snapshot)
return hashes.OrderBy(p => p).ToArray();
}

public virtual bool Reverify(StoreView snapshot, BigInteger totalSenderFeeFromPool)
{
if (ValidUntilBlock <= snapshot.Height || ValidUntilBlock > snapshot.Height + MaxValidUntilBlockIncrement)
return false;
if (NativeContract.Policy.GetBlockedAccounts(snapshot).Intersect(GetScriptHashesForVerifying(snapshot)).Count() > 0)
return false;
BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, Sender);
BigInteger fee = SystemFee + NetworkFee + totalSenderFeeFromPool;
if (balance < fee) return false;
UInt160[] hashes = GetScriptHashesForVerifying(snapshot);
if (hashes.Length != Witnesses.Length) return false;
for (int i = 0; i < hashes.Length; i++)
{
if (Witnesses[i].VerificationScript.Length > 0) continue;
if (snapshot.Contracts.TryGet(hashes[i]) is null) return false;
}
return true;
}

void ISerializable.Serialize(BinaryWriter writer)
{
((IVerifiable)this).SerializeUnsigned(writer);
Expand Down Expand Up @@ -284,7 +265,31 @@ bool IInventory.Verify(StoreView snapshot)

public virtual bool Verify(StoreView snapshot, BigInteger totalSenderFeeFromPool)
vncoelho marked this conversation as resolved.
Show resolved Hide resolved
{
if (!Reverify(snapshot, totalSenderFeeFromPool)) return false;
return VerifyForEachBlock(snapshot, totalSenderFeeFromPool)
&& VerifyParallelParts(snapshot);
}

public virtual bool VerifyForEachBlock(StoreView snapshot, BigInteger totalSenderFeeFromPool)
{
if (ValidUntilBlock <= snapshot.Height || ValidUntilBlock > snapshot.Height + MaxValidUntilBlockIncrement)
return false;
UInt160[] hashes = GetScriptHashesForVerifying(snapshot);
if (NativeContract.Policy.GetBlockedAccounts(snapshot).Intersect(hashes).Count() > 0)
return false;
BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, Sender);
BigInteger fee = SystemFee + NetworkFee + totalSenderFeeFromPool;
if (balance < fee) return false;
if (hashes.Length != Witnesses.Length) return false;
for (int i = 0; i < hashes.Length; i++)
{
if (Witnesses[i].VerificationScript.Length > 0) continue;
if (snapshot.Contracts.TryGet(hashes[i]) is null) return false;
}
return true;
}

public bool VerifyParallelParts(StoreView snapshot)
{
int size = Size;
if (size > MaxTransactionSize) return false;
long net_fee = NetworkFee - size * NativeContract.Policy.GetFeePerByte(snapshot);
Expand Down
4 changes: 2 additions & 2 deletions tests/neo.UnitTests/Ledger/UT_MemoryPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ private Transaction CreateTransactionWithFee(long fee)
var randomBytes = new byte[16];
random.NextBytes(randomBytes);
Mock<Transaction> mock = new Mock<Transaction>();
mock.Setup(p => p.Reverify(It.IsAny<StoreView>(), It.IsAny<BigInteger>())).Returns(true);
mock.Setup(p => p.VerifyForEachBlock(It.IsAny<StoreView>(), It.IsAny<BigInteger>())).Returns(true);
mock.Setup(p => p.Verify(It.IsAny<StoreView>(), It.IsAny<BigInteger>())).Returns(true);
mock.Object.Script = randomBytes;
mock.Object.Sender = UInt160.Zero;
Expand All @@ -99,7 +99,7 @@ private Transaction CreateTransactionWithFeeAndBalanceVerify(long fee)
random.NextBytes(randomBytes);
Mock<Transaction> mock = new Mock<Transaction>();
UInt160 sender = UInt160.Zero;
mock.Setup(p => p.Reverify(It.IsAny<StoreView>(), It.IsAny<BigInteger>())).Returns(((StoreView snapshot, BigInteger amount) => NativeContract.GAS.BalanceOf(snapshot, sender) >= amount + fee));
mock.Setup(p => p.VerifyForEachBlock(It.IsAny<StoreView>(), It.IsAny<BigInteger>())).Returns(((StoreView snapshot, BigInteger amount) => NativeContract.GAS.BalanceOf(snapshot, sender) >= amount + fee));
mock.Setup(p => p.Verify(It.IsAny<StoreView>(), It.IsAny<BigInteger>())).Returns(true);
mock.Object.Script = randomBytes;
mock.Object.Sender = sender;
Expand Down
2 changes: 1 addition & 1 deletion tests/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ private Transaction CreateTransactionWithFee(long networkFee, long systemFee)
var randomBytes = new byte[16];
random.NextBytes(randomBytes);
Mock<Transaction> mock = new Mock<Transaction>();
mock.Setup(p => p.Reverify(It.IsAny<StoreView>(), It.IsAny<BigInteger>())).Returns(true);
mock.Setup(p => p.VerifyForEachBlock(It.IsAny<StoreView>(), It.IsAny<BigInteger>())).Returns(true);
mock.Setup(p => p.Verify(It.IsAny<StoreView>(), It.IsAny<BigInteger>())).Returns(true);
mock.Object.Script = randomBytes;
mock.Object.Sender = UInt160.Zero;
Expand Down
2 changes: 1 addition & 1 deletion tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,7 @@ public void Transaction_Reverify_Hashes_Length_Unequal_To_Witnesses_Length()
};
UInt160[] hashes = txSimple.GetScriptHashesForVerifying(snapshot);
Assert.AreEqual(2, hashes.Length);
Assert.IsFalse(txSimple.Reverify(snapshot, BigInteger.Zero));
Assert.IsFalse(txSimple.VerifyForEachBlock(snapshot, BigInteger.Zero));
}

[TestMethod]
Expand Down