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

Relocate transaction verification #1507

Merged
Merged
Show file tree
Hide file tree
Changes from 87 commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
1d0ef09
Merge pull request #13 from neo-project/master
Qiao-Jin Mar 19, 2020
b14a589
Relocate transaction verifcation
Mar 20, 2020
e81cc6b
Merge pull request #17 from neo-project/master
Qiao-Jin Mar 23, 2020
915794e
Merge pull request #23 from neo-project/master
Qiao-Jin Mar 24, 2020
58b6731
Merge pull request #29 from neo-project/master
Qiao-Jin Mar 24, 2020
df5a99f
Merge branch 'master' of https://github.com/neo-project/neo into neo-…
Mar 25, 2020
28e3f48
Merge branch 'neo-project-master' into relocate_transaction_verification
Mar 25, 2020
9f2f7c6
Code optimization
Mar 25, 2020
241a92d
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Mar 27, 2020
ab4bb26
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Mar 27, 2020
fcaf7e4
Seperate sender fee check from transaction verification
Mar 30, 2020
2cfa56b
Merge branch 'relocate_transaction_verification' of https://github.co…
Mar 30, 2020
f7ba395
Format modification
Mar 30, 2020
eedb714
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Mar 31, 2020
b9f3a46
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Apr 2, 2020
3828ab2
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Apr 3, 2020
e407aad
Function rename and add parallel strategy
Apr 3, 2020
382605e
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Apr 3, 2020
6896500
Code optimization
Apr 6, 2020
b3b8c25
Code optimization
Apr 7, 2020
27ef0af
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Apr 8, 2020
0173cd3
Code optimization
Apr 8, 2020
78b304f
Format optimization
Apr 8, 2020
eb6f41f
Code optimization
Apr 8, 2020
35d7995
Merge branch 'master' of https://github.com/neo-project/neo into neo-…
Apr 10, 2020
08fa2a2
Merge branch 'neo-project-master' into relocate_transaction_verification
Apr 10, 2020
e65623a
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Apr 13, 2020
1e63267
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Apr 20, 2020
a0dcaf0
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Apr 26, 2020
7b605af
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Apr 27, 2020
4dad4d0
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin May 6, 2020
729d2ce
Fix VerifyWitnesses
May 6, 2020
fcc3c12
Revert "Fix VerifyWitnesses"
May 6, 2020
e578754
Rewrite verify_witness and corresponding logic
May 7, 2020
d228a51
code format
May 7, 2020
c08dc91
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin May 7, 2020
51e785c
Add statedependent to witness
May 9, 2020
a494053
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin May 9, 2020
83ee355
Code optimization
May 9, 2020
5c10326
Update src/neo/Network/P2P/Payloads/Witness.cs
Qiao-Jin May 9, 2020
f78503e
Update src/neo/Network/P2P/Payloads/Witness.cs
Qiao-Jin May 9, 2020
64d2a3f
Update src/neo/Network/P2P/Payloads/Witness.cs
Qiao-Jin May 9, 2020
5bea75d
Revert "Update src/neo/Network/P2P/Payloads/Witness.cs"
May 9, 2020
a4b38f0
Revert "Update src/neo/Network/P2P/Payloads/Witness.cs"
May 9, 2020
f119e18
Revert "Update src/neo/Network/P2P/Payloads/Witness.cs"
May 9, 2020
47567ae
optimize Witness
May 9, 2020
e0a5752
optimize witness and IVerifiable.verifyWitness
May 9, 2020
406e1d0
fix tx.Verify
May 9, 2020
116b59a
optimize code
May 9, 2020
fb9853a
optimize tx.GetScriptHashesForVerifying
May 9, 2020
b8c139e
Remove verifyForEachBlock
May 9, 2020
33a70fc
add VerifyResult.InvalidWitness
May 9, 2020
e263a06
Disallow witness.verificationScript to access the snapshot
May 9, 2020
2016da9
Optimize tx.VerifyStateDependent and verifiable.VerifyWitness
May 9, 2020
0bd4479
format
May 9, 2020
8666976
fix VerifyWitness
May 10, 2020
4f832ba
optimize tx.verify
May 10, 2020
5d1a218
optimize verifywitness
May 10, 2020
de81ddd
reset InteropService
May 11, 2020
0638e0b
add UT
May 11, 2020
4d1e1ac
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin May 12, 2020
9696c6a
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin May 15, 2020
c32f0fa
Split func OnInventoryReceived to avoid dirty write
May 15, 2020
be04b26
Merge branch 'master' into relocate_transaction_verification
shargon May 15, 2020
f9f2661
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin May 18, 2020
80ffb08
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin May 19, 2020
c198d6a
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin May 26, 2020
f3a5390
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin May 27, 2020
7ab56c3
Renew UT
May 27, 2020
235c9b9
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Jun 3, 2020
689d269
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Jul 10, 2020
a06c26a
Merge branch 'local_master' into relocate_transaction_verification
Aug 7, 2020
9d81c55
Check transaction size before creating task
Aug 7, 2020
13df078
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Aug 7, 2020
151dbac
Add missing note
Aug 7, 2020
1e76ed3
Merge branch 'relocate_transaction_verification' of https://github.co…
Aug 7, 2020
0ab3d71
Fix gas
shargon Aug 7, 2020
c8be765
Re-fix
shargon Aug 7, 2020
8f9bd7e
Merge branch 'master' into relocate_transaction_verification
shargon Aug 7, 2020
868ff31
Redefine WitnessFlag
Aug 7, 2020
a77ea11
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Aug 10, 2020
5288f27
Change multi task to actor pool
Aug 12, 2020
8c6ce68
Format correction
Aug 12, 2020
1320c78
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Aug 12, 2020
16fb3de
Update Transaction.cs
erikzhang Aug 13, 2020
d9c80ec
Rename
erikzhang Aug 13, 2020
90027d9
Update Witness.cs
erikzhang Aug 13, 2020
06e5d19
Merge branch 'master' into relocate_transaction_verification
Qiao-Jin Aug 13, 2020
f3b691a
Public transaction router
Aug 13, 2020
e6880d6
Fix and optimize
erikzhang Aug 14, 2020
c944e86
Move namespace
erikzhang Aug 14, 2020
cd0cd41
Move namespace
erikzhang Aug 14, 2020
3811cf6
Optimize
erikzhang Aug 14, 2020
f079a0f
Use the correct CallFlags
erikzhang Aug 14, 2020
55e3597
Merge branch 'master' into relocate_transaction_verification
erikzhang Aug 14, 2020
ea94018
Merge branch 'master' into relocate_transaction_verification
shargon Aug 16, 2020
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
4 changes: 2 additions & 2 deletions src/neo/Ledger/MemoryPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ internal VerifyResult TryAdd(Transaction tx, StoreView snapshot)
_txRwLock.EnterWriteLock();
try
{
VerifyResult result = tx.Verify(snapshot, VerificationContext);
VerifyResult result = tx.VerifyStateDependent(snapshot, VerificationContext);
if (result != VerifyResult.Succeed) return result;

_unsortedTransactions.Add(tx.Hash, poolItem);
Expand Down Expand Up @@ -425,7 +425,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.VerifyForEachBlock(snapshot, VerificationContext) == VerifyResult.Succeed)
if (item.Tx.VerifyStateDependent(snapshot, VerificationContext) == VerifyResult.Succeed)
{
reverifiedItems.Add(item);
VerificationContext.AddTransaction(item.Tx);
Expand Down
29 changes: 16 additions & 13 deletions src/neo/Network/P2P/Payloads/Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ bool IInventory.Verify(StoreView snapshot)
return Verify(snapshot, null) == VerifyResult.Succeed;
}

public virtual VerifyResult VerifyForEachBlock(StoreView snapshot, TransactionVerificationContext context)
public virtual VerifyResult VerifyStateDependent(StoreView snapshot, TransactionVerificationContext context)
{
if (ValidUntilBlock <= snapshot.Height || ValidUntilBlock > snapshot.Height + MaxValidUntilBlockIncrement)
return VerifyResult.Expired;
Expand All @@ -294,24 +294,27 @@ public virtual VerifyResult VerifyForEachBlock(StoreView snapshot, TransactionVe
foreach (TransactionAttribute attribute in Attributes)
if (!attribute.Verify(snapshot, this))
return VerifyResult.Invalid;
if (hashes.Length != Witnesses.Length) return VerifyResult.Invalid;
for (int i = 0; i < hashes.Length; i++)
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
{
if (Witnesses[i].VerificationScript.Length > 0) continue;
if (snapshot.Contracts.TryGet(hashes[i]) is null) return VerifyResult.Invalid;
}
long net_fee = NetworkFee - Size * NativeContract.Policy.GetFeePerByte(snapshot);
if (!this.VerifyWitnesses(snapshot, net_fee, WitnessFlag.StateDependent))
return VerifyResult.Invalid;
return VerifyResult.Succeed;
}

public virtual VerifyResult VerifyStateIndependent()
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
{
if (Size > MaxTransactionSize)
return VerifyResult.Invalid;
if (!this.VerifyWitnesses(null, NetworkFee, WitnessFlag.StateIndependent))
return VerifyResult.Invalid;
return VerifyResult.Succeed;
}

public virtual VerifyResult Verify(StoreView snapshot, TransactionVerificationContext context)
{
VerifyResult result = VerifyForEachBlock(snapshot, context);
VerifyResult result = VerifyStateIndependent();
if (result != VerifyResult.Succeed) return result;
if (Size > MaxTransactionSize) return VerifyResult.Invalid;
long net_fee = NetworkFee - Size * NativeContract.Policy.GetFeePerByte(snapshot);
if (net_fee < 0) return VerifyResult.InsufficientFunds;
if (!this.VerifyWitnesses(snapshot, net_fee)) return VerifyResult.Invalid;
return VerifyResult.Succeed;
result = VerifyStateDependent(snapshot, context);
return result;
}

public StackItem ToStackItem(ReferenceCounter referenceCounter)
Expand Down
4 changes: 4 additions & 0 deletions src/neo/Network/P2P/Payloads/Witness.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ public class Witness : ISerializable
public byte[] InvocationScript;
public byte[] VerificationScript;

public WitnessFlag Flag => VerificationScript.Length == 0 ? WitnessFlag.StateDependent : WitnessFlag.StateIndependent;

internal long GasConsumed { get; set; }

private UInt160 _scriptHash;
public virtual UInt160 ScriptHash
{
Expand Down
15 changes: 15 additions & 0 deletions src/neo/Network/P2P/Payloads/WitnessFlag.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;

namespace Neo.SmartContract
{
[Flags]
public enum WitnessFlag : byte
{
None = 0,

StateIndependent = 0b00000001,
StateDependent = 0b00000010,

All = StateIndependent | StateDependent
}
}
58 changes: 47 additions & 11 deletions src/neo/Network/P2P/RemoteNode.ProtocolHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,40 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

namespace Neo.Network.P2P
{
partial class RemoteNode
{
private class TransactionRouter : UntypedActor
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
{
private readonly NeoSystem system;

public TransactionRouter(NeoSystem system)
{
this.system = system;
}

protected override void OnReceive(object message)
{
switch (message)
{
case Transaction tx:
if (tx.VerifyStateIndependent() == VerifyResult.Succeed)
OnTransactionReceived(tx);
break;
}
}

private void OnTransactionReceived(Transaction tx)
{
system.TaskManager.Tell(tx);
system.Consensus?.Tell(tx);
system.Blockchain.Tell(tx, ActorRefs.NoSender);
}
}

private class Timer { }
private class PendingKnownHashesCollection : KeyedCollection<UInt256, (UInt256, DateTime)>
{
Expand All @@ -31,6 +60,7 @@ protected override UInt256 GetKeyForItem((UInt256, DateTime) item)
private readonly HashSetCache<UInt256> sentHashes = new HashSetCache<UInt256>(Blockchain.Singleton.MemPool.Capacity * 2 / 5);
private bool verack = false;
private BloomFilter bloom_filter;
private IActorRef transactionRouter;

private static readonly TimeSpan TimerInterval = TimeSpan.FromSeconds(30);
private static readonly TimeSpan PendingTimeout = TimeSpan.FromMinutes(1);
Expand Down Expand Up @@ -62,10 +92,17 @@ private void OnMessage(Message msg)
OnAddrMessageReceived((AddrPayload)msg.Payload);
break;
case MessageCommand.Block:
OnInventoryReceived((Block)msg.Payload);
Block block = (Block)msg.Payload;
system.TaskManager.Tell(block);
system.Blockchain.Tell(block, ActorRefs.NoSender);
UpdateLastBlockIndex(block.Index, false);
RenewKnownHashes(block.Hash);
break;
case MessageCommand.Consensus:
OnInventoryReceived((ConsensusPayload)msg.Payload);
ConsensusPayload consensusPayload = (ConsensusPayload)msg.Payload;
system.TaskManager.Tell(consensusPayload);
system.Blockchain.Tell(consensusPayload, ActorRefs.NoSender);
RenewKnownHashes(consensusPayload.Hash);
break;
case MessageCommand.FilterAdd:
OnFilterAddMessageReceived((FilterAddPayload)msg.Payload);
Expand Down Expand Up @@ -104,8 +141,12 @@ private void OnMessage(Message msg)
OnPongMessageReceived((PingPayload)msg.Payload);
break;
case MessageCommand.Transaction:
Transaction tx = (Transaction)msg.Payload;
RenewKnownHashes(tx.Hash);
if (msg.Payload.Size <= Transaction.MaxTransactionSize)
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
OnInventoryReceived((Transaction)msg.Payload);
{
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
transactionRouter.Tell(tx);
}
break;
case MessageCommand.Verack:
case MessageCommand.Version:
Expand Down Expand Up @@ -284,15 +325,10 @@ private void OnGetHeadersMessageReceived(GetBlockByIndexPayload payload)
EnqueueMessage(Message.Create(MessageCommand.Headers, HeadersPayload.Create(headers.ToArray())));
}

private void OnInventoryReceived(IInventory inventory)
private void RenewKnownHashes(UInt256 hash)
shargon marked this conversation as resolved.
Show resolved Hide resolved
{
system.TaskManager.Tell(inventory);
if (inventory is Transaction transaction)
system.Consensus?.Tell(transaction);
system.Blockchain.Tell(inventory, ActorRefs.NoSender);
pendingKnownHashes.Remove(inventory.Hash);
knownHashes.Add(inventory.Hash);
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
if (inventory is Block b) UpdateLastBlockIndex(b.Index, false);
pendingKnownHashes.Remove(hash);
knownHashes.Add(hash);
}

private void OnInvMessageReceived(InvPayload payload)
Expand Down
2 changes: 2 additions & 0 deletions src/neo/Network/P2P/RemoteNode.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Akka.Actor;
using Akka.Configuration;
using Akka.IO;
using Akka.Routing;
using Neo.Cryptography;
using Neo.IO;
using Neo.IO.Actors;
Expand Down Expand Up @@ -36,6 +37,7 @@ public RemoteNode(NeoSystem system, object connection, IPEndPoint remote, IPEndP
{
this.system = system;
LocalNode.Singleton.RemoteNodes.TryAdd(Self, this);
transactionRouter = Context.ActorOf(Akka.Actor.Props.Create(() => new TransactionRouter(system)).WithMailbox("remote-node-mailbox").WithRouter(new SmallestMailboxPool(20)));
}

/// <summary>
Expand Down
12 changes: 10 additions & 2 deletions src/neo/SmartContract/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public static UInt160 ToScriptHash(this ReadOnlySpan<byte> script)
return new UInt160(Crypto.Hash160(script));
}

internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas)
internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas, WitnessFlag filter = WitnessFlag.All)
{
if (gas < 0) return false;
if (gas > MaxVerificationGas) gas = MaxVerificationGas;
Expand All @@ -146,6 +146,13 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snap
if (hashes.Length != verifiable.Witnesses.Length) return false;
for (int i = 0; i < hashes.Length; i++)
{
if (filter != WitnessFlag.All && !filter.HasFlag(verifiable.Witnesses[i].Flag))
{
gas -= verifiable.Witnesses[i].GasConsumed;
if (gas < 0) return false;
continue;
}

int offset;
ContractMethodDescriptor init = null;
byte[] verification = verifiable.Witnesses[i].VerificationScript;
Expand All @@ -164,14 +171,15 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snap
if (hashes[i] != verifiable.Witnesses[i].ScriptHash) return false;
offset = 0;
}
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot.Clone(), gas))
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot != null ? snapshot.Clone() : snapshot, gas))
{
ExecutionContext context = engine.LoadScript(verification, CallFlags.None, offset);
if (init != null) engine.LoadContext(context.Clone(init.Offset), false);
engine.LoadScript(verifiable.Witnesses[i].InvocationScript, CallFlags.None);
if (engine.Execute() == VMState.FAULT) return false;
if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) return false;
gas -= engine.GasConsumed;
verifiable.Witnesses[i].GasConsumed = engine.GasConsumed;
}
}
return true;
Expand Down
28 changes: 18 additions & 10 deletions tests/neo.UnitTests/Ledger/UT_MemoryPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Neo.Plugins;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.SmartContract.Native.Tokens;
using System;
using System.Collections;
using System.Collections.Generic;
Expand All @@ -31,6 +32,7 @@ public class UT_MemoryPool

private const byte Prefix_MaxTransactionsPerBlock = 23;
private const byte Prefix_FeePerByte = 10;
private readonly UInt160 senderAccount = UInt160.Zero;
private MemoryPool _unit;
private MemoryPool _unit2;
private TestIMemoryPoolTxObserverPlugin plugin;
Expand Down Expand Up @@ -82,12 +84,13 @@ private Transaction CreateTransactionWithFee(long fee)
var randomBytes = new byte[16];
random.NextBytes(randomBytes);
Mock<Transaction> mock = new Mock<Transaction>();
mock.Setup(p => p.VerifyForEachBlock(It.IsAny<StoreView>(), It.IsAny<TransactionVerificationContext>())).Returns(VerifyResult.Succeed);
mock.Setup(p => p.Verify(It.IsAny<StoreView>(), It.IsAny<TransactionVerificationContext>())).Returns(VerifyResult.Succeed);
mock.Setup(p => p.VerifyStateDependent(It.IsAny<StoreView>(), It.IsAny<TransactionVerificationContext>())).Returns(VerifyResult.Succeed);
mock.Setup(p => p.VerifyStateIndependent()).Returns(VerifyResult.Succeed);
mock.Object.Script = randomBytes;
mock.Object.NetworkFee = fee;
mock.Object.Attributes = Array.Empty<TransactionAttribute>();
mock.Object.Signers = new Signer[] { new Signer() { Account = UInt160.Zero, Scopes = WitnessScope.None } };
mock.Object.Signers = new Signer[] { new Signer() { Account = senderAccount, Scopes = WitnessScope.None } };
mock.Object.Witnesses = new[]
{
new Witness
Expand All @@ -105,12 +108,14 @@ private Transaction CreateTransactionWithFeeAndBalanceVerify(long fee)
var randomBytes = new byte[16];
random.NextBytes(randomBytes);
Mock<Transaction> mock = new Mock<Transaction>();
mock.Setup(p => p.VerifyForEachBlock(It.IsAny<StoreView>(), It.IsAny<TransactionVerificationContext>())).Returns((StoreView snapshot, TransactionVerificationContext context) => context.CheckTransaction(mock.Object, snapshot) ? VerifyResult.Succeed : VerifyResult.InsufficientFunds);
UInt160 sender = senderAccount;
mock.Setup(p => p.Verify(It.IsAny<StoreView>(), It.IsAny<TransactionVerificationContext>())).Returns(VerifyResult.Succeed);
mock.Setup(p => p.VerifyStateDependent(It.IsAny<StoreView>(), It.IsAny<TransactionVerificationContext>())).Returns((StoreView snapshot, TransactionVerificationContext context) => context.CheckTransaction(mock.Object, snapshot) ? VerifyResult.Succeed : VerifyResult.InsufficientFunds);
mock.Setup(p => p.VerifyStateIndependent()).Returns(VerifyResult.Succeed);
mock.Object.Script = randomBytes;
mock.Object.NetworkFee = fee;
mock.Object.Attributes = Array.Empty<TransactionAttribute>();
mock.Object.Signers = new Signer[] { new Signer() { Account = UInt160.Zero, Scopes = WitnessScope.None } };
mock.Object.Signers = new Signer[] { new Signer() { Account = senderAccount, Scopes = WitnessScope.None } };
mock.Object.Witnesses = new[]
{
new Witness
Expand Down Expand Up @@ -147,9 +152,8 @@ private void AddTransaction(Transaction txToAdd)
_unit.TryAdd(txToAdd, snapshot);
}

private void AddTransactionsWithBalanceVerify(int count, long fee)
private void AddTransactionsWithBalanceVerify(int count, long fee, SnapshotView snapshot)
{
var snapshot = Blockchain.Singleton.GetSnapshot();
for (int i = 0; i < count; i++)
{
var txToAdd = CreateTransactionWithFeeAndBalanceVerify(fee);
Expand Down Expand Up @@ -218,8 +222,14 @@ public void BlockPersistMovesTxToUnverifiedAndReverification()
[TestMethod]
public void BlockPersistAndReverificationWillAbandonTxAsBalanceTransfered()
{
SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, senderAccount);
ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, long.MaxValue);
NativeContract.GAS.Burn(engine, UInt160.Zero, balance);
NativeContract.GAS.Mint(engine, UInt160.Zero, 70);

long txFee = 1;
AddTransactionsWithBalanceVerify(70, txFee);
AddTransactionsWithBalanceVerify(70, txFee, snapshot);

_unit.SortedTxCount.Should().Be(70);

Expand All @@ -230,11 +240,9 @@ public void BlockPersistAndReverificationWillAbandonTxAsBalanceTransfered()

// Simulate the transfer process in tx by burning the balance
UInt160 sender = block.Transactions[0].Sender;
SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, sender);

ApplicationEngine applicationEngine = ApplicationEngine.Create(TriggerType.All, block, snapshot, (long)balance);
NativeContract.GAS.Burn(applicationEngine, sender, balance);
NativeContract.GAS.Burn(applicationEngine, sender, NativeContract.GAS.BalanceOf(snapshot, sender));
NativeContract.GAS.Mint(applicationEngine, sender, txFee * 30); // Set the balance to meet 30 txs only

// Persist block and reverify all the txs in mempool, but half of the txs will be discarded
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ 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.VerifyForEachBlock(It.IsAny<StoreView>(), It.IsAny<TransactionVerificationContext>())).Returns(VerifyResult.Succeed);
mock.Setup(p => p.Verify(It.IsAny<StoreView>(), It.IsAny<TransactionVerificationContext>())).Returns(VerifyResult.Succeed);
mock.Setup(p => p.VerifyStateDependent(It.IsAny<StoreView>(), It.IsAny<TransactionVerificationContext>())).Returns(VerifyResult.Succeed);
mock.Setup(p => p.VerifyStateIndependent()).Returns(VerifyResult.Succeed);
mock.Object.Script = randomBytes;
mock.Object.NetworkFee = networkFee;
mock.Object.SystemFee = systemFee;
Expand Down
Loading