diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index a4b5d0a845..bef6f53e43 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v1
+ uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
@@ -39,7 +39,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v1
+ uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
@@ -61,7 +61,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v1
+ uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
@@ -79,7 +79,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v1
+ uses: actions/checkout@v2
- name: Get version
id: get_version
run: |
diff --git a/src/neo/Consensus/ConsensusContext.cs b/src/neo/Consensus/ConsensusContext.cs
index 3d3a4fcb5d..763fa2e77f 100644
--- a/src/neo/Consensus/ConsensusContext.cs
+++ b/src/neo/Consensus/ConsensusContext.cs
@@ -40,7 +40,7 @@ internal class ConsensusContext : IDisposable, ISerializable
///
/// Store all verified unsorted transactions' senders' fee currently in the consensus context.
///
- public SendersFeeMonitor SendersFeeMonitor = new SendersFeeMonitor();
+ public TransactionVerificationContext VerificationContext = new TransactionVerificationContext();
public SnapshotView Snapshot { get; private set; }
private KeyPair keyPair;
@@ -109,18 +109,18 @@ public void Deserialize(BinaryReader reader)
ViewNumber = reader.ReadByte();
TransactionHashes = reader.ReadSerializableArray();
Transaction[] transactions = reader.ReadSerializableArray(Block.MaxTransactionsPerBlock);
- PreparationPayloads = reader.ReadNullableArray(ProtocolSettings.Default.MaxValidatorsCount);
- CommitPayloads = reader.ReadNullableArray(ProtocolSettings.Default.MaxValidatorsCount);
- ChangeViewPayloads = reader.ReadNullableArray(ProtocolSettings.Default.MaxValidatorsCount);
- LastChangeViewPayloads = reader.ReadNullableArray(ProtocolSettings.Default.MaxValidatorsCount);
+ PreparationPayloads = reader.ReadNullableArray(ProtocolSettings.Default.ValidatorsCount);
+ CommitPayloads = reader.ReadNullableArray(ProtocolSettings.Default.ValidatorsCount);
+ ChangeViewPayloads = reader.ReadNullableArray(ProtocolSettings.Default.ValidatorsCount);
+ LastChangeViewPayloads = reader.ReadNullableArray(ProtocolSettings.Default.ValidatorsCount);
if (TransactionHashes.Length == 0 && !RequestSentOrReceived)
TransactionHashes = null;
Transactions = transactions.Length == 0 && !RequestSentOrReceived ? null : transactions.ToDictionary(p => p.Hash);
- SendersFeeMonitor = new SendersFeeMonitor();
+ VerificationContext = new TransactionVerificationContext();
if (Transactions != null)
{
foreach (Transaction tx in Transactions.Values)
- SendersFeeMonitor.AddSenderFee(tx);
+ VerificationContext.AddTransaction(tx);
}
}
@@ -266,7 +266,7 @@ internal void EnsureMaxBlockLimitation(IEnumerable txs)
txs = txs.Take((int)maxTransactionsPerBlock);
List hashes = new List();
Transactions = new Dictionary();
- SendersFeeMonitor = new SendersFeeMonitor();
+ VerificationContext = new TransactionVerificationContext();
// Expected block size
var blockSize = GetExpectedBlockSizeWithoutTransactions(txs.Count());
@@ -285,7 +285,7 @@ internal void EnsureMaxBlockLimitation(IEnumerable txs)
hashes.Add(tx.Hash);
Transactions.Add(tx.Hash, tx);
- SendersFeeMonitor.AddSenderFee(tx);
+ VerificationContext.AddTransaction(tx);
}
TransactionHashes = hashes.ToArray();
diff --git a/src/neo/Consensus/ConsensusService.cs b/src/neo/Consensus/ConsensusService.cs
index 26648c4429..9caca4b651 100644
--- a/src/neo/Consensus/ConsensusService.cs
+++ b/src/neo/Consensus/ConsensusService.cs
@@ -64,20 +64,24 @@ internal ConsensusService(IActorRef localNode, IActorRef taskManager, IActorRef
private bool AddTransaction(Transaction tx, bool verify)
{
- if (verify && tx.Verify(context.Snapshot, context.SendersFeeMonitor.GetSenderFee(tx.Sender)) != VerifyResult.Succeed)
+ if (verify)
{
- Log($"Invalid transaction: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning);
- RequestChangeView(ChangeViewReason.TxInvalid);
- return false;
- }
- if (!NativeContract.Policy.CheckPolicy(tx, context.Snapshot))
- {
- Log($"reject tx: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning);
- RequestChangeView(ChangeViewReason.TxRejectedByPolicy);
- return false;
+ VerifyResult result = tx.Verify(context.Snapshot, context.VerificationContext);
+ if (result == VerifyResult.PolicyFail)
+ {
+ Log($"reject tx: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning);
+ RequestChangeView(ChangeViewReason.TxRejectedByPolicy);
+ return false;
+ }
+ else if (result != VerifyResult.Succeed)
+ {
+ Log($"Invalid transaction: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning);
+ RequestChangeView(ChangeViewReason.TxInvalid);
+ return false;
+ }
}
context.Transactions[tx.Hash] = tx;
- context.SendersFeeMonitor.AddSenderFee(tx);
+ context.VerificationContext.AddTransaction(tx);
return CheckPrepareResponse();
}
@@ -433,7 +437,7 @@ private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest m
context.Block.ConsensusData.Nonce = message.Nonce;
context.TransactionHashes = message.TransactionHashes;
context.Transactions = new Dictionary();
- context.SendersFeeMonitor = new SendersFeeMonitor();
+ context.VerificationContext = new TransactionVerificationContext();
for (int i = 0; i < context.PreparationPayloads.Length; i++)
if (context.PreparationPayloads[i] != null)
if (!context.PreparationPayloads[i].GetDeserializedMessage().PreparationHash.Equals(payload.Hash))
diff --git a/src/neo/Consensus/RecoveryMessage.cs b/src/neo/Consensus/RecoveryMessage.cs
index cadb137b80..b082f2aeb2 100644
--- a/src/neo/Consensus/RecoveryMessage.cs
+++ b/src/neo/Consensus/RecoveryMessage.cs
@@ -31,7 +31,7 @@ public RecoveryMessage() : base(ConsensusMessageType.RecoveryMessage)
public override void Deserialize(BinaryReader reader)
{
base.Deserialize(reader);
- ChangeViewMessages = reader.ReadSerializableArray(ProtocolSettings.Default.MaxValidatorsCount).ToDictionary(p => (int)p.ValidatorIndex);
+ ChangeViewMessages = reader.ReadSerializableArray(ProtocolSettings.Default.ValidatorsCount).ToDictionary(p => (int)p.ValidatorIndex);
if (reader.ReadBoolean())
PrepareRequestMessage = reader.ReadSerializable();
else
@@ -41,8 +41,8 @@ public override void Deserialize(BinaryReader reader)
PreparationHash = new UInt256(reader.ReadFixedBytes(preparationHashSize));
}
- PreparationMessages = reader.ReadSerializableArray(ProtocolSettings.Default.MaxValidatorsCount).ToDictionary(p => (int)p.ValidatorIndex);
- CommitMessages = reader.ReadSerializableArray(ProtocolSettings.Default.MaxValidatorsCount).ToDictionary(p => (int)p.ValidatorIndex);
+ PreparationMessages = reader.ReadSerializableArray(ProtocolSettings.Default.ValidatorsCount).ToDictionary(p => (int)p.ValidatorIndex);
+ CommitMessages = reader.ReadSerializableArray(ProtocolSettings.Default.ValidatorsCount).ToDictionary(p => (int)p.ValidatorIndex);
}
internal ConsensusPayload[] GetChangeViewPayloads(ConsensusContext context, ConsensusPayload payload)
diff --git a/src/neo/IO/Helper.cs b/src/neo/IO/Helper.cs
index e165016139..e871bbaedf 100644
--- a/src/neo/IO/Helper.cs
+++ b/src/neo/IO/Helper.cs
@@ -1,6 +1,7 @@
using K4os.Compression.LZ4;
using System;
using System.Buffers;
+using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -69,20 +70,19 @@ public static byte[] CompressLz4(this byte[] data)
int maxLength = LZ4Codec.MaximumOutputSize(data.Length);
using var buffer = MemoryPool.Shared.Rent(maxLength);
int length = LZ4Codec.Encode(data, buffer.Memory.Span);
- byte[] result = new byte[length];
- buffer.Memory[..length].CopyTo(result);
+ byte[] result = new byte[sizeof(uint) + length];
+ BinaryPrimitives.WriteInt32LittleEndian(result, data.Length);
+ buffer.Memory[..length].CopyTo(result.AsMemory(4));
return result;
}
public static byte[] DecompressLz4(this byte[] data, int maxOutput)
{
- var maxDecompressDataLength = data.Length * 255;
- if (maxDecompressDataLength > 0) maxOutput = Math.Min(maxOutput, maxDecompressDataLength);
- using var buffer = MemoryPool.Shared.Rent(maxOutput);
- int length = LZ4Codec.Decode(data, buffer.Memory.Span);
+ int length = BinaryPrimitives.ReadInt32LittleEndian(data);
if (length < 0 || length > maxOutput) throw new FormatException();
byte[] result = new byte[length];
- buffer.Memory[..length].CopyTo(result);
+ if (LZ4Codec.Decode(data.AsSpan(4), result) != length)
+ throw new FormatException();
return result;
}
diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs
index 50cee9509d..0ac37aa5ab 100644
--- a/src/neo/Ledger/Blockchain.cs
+++ b/src/neo/Ledger/Blockchain.cs
@@ -32,8 +32,8 @@ public class RelayResult { public IInventory Inventory; public VerifyResult Resu
public const uint DecrementInterval = 2000000;
public static readonly uint[] GenerationAmount = { 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
public static readonly TimeSpan TimePerBlock = TimeSpan.FromMilliseconds(MillisecondsPerBlock);
- public static readonly ECPoint[] StandbyCommittee = ProtocolSettings.Default.StandbyCommittee.Take(ProtocolSettings.Default.MaxCommitteeMembersCount).Select(p => ECPoint.DecodePoint(p.HexToBytes(), ECCurve.Secp256r1)).ToArray();
- public static readonly ECPoint[] StandbyValidators = StandbyCommittee.Take(ProtocolSettings.Default.MaxValidatorsCount).ToArray();
+ public static readonly ECPoint[] StandbyCommittee = ProtocolSettings.Default.StandbyCommittee.Select(p => ECPoint.DecodePoint(p.HexToBytes(), ECCurve.Secp256r1)).ToArray();
+ public static readonly ECPoint[] StandbyValidators = StandbyCommittee[0..ProtocolSettings.Default.ValidatorsCount];
public static readonly Block GenesisBlock = new Block
{
@@ -166,8 +166,15 @@ private static Transaction DeployNativeContracts()
{
Version = 0,
Script = script,
- Sender = (new[] { (byte)OpCode.PUSH1 }).ToScriptHash(),
SystemFee = 0,
+ Signers = new[]
+ {
+ new Signer
+ {
+ Account = (new[] { (byte)OpCode.PUSH1 }).ToScriptHash(),
+ Scopes = WitnessScope.FeeOnly
+ }
+ },
Attributes = Array.Empty(),
Witnesses = new[]
{
@@ -283,15 +290,10 @@ private void OnFillMemoryPool(IEnumerable transactions)
{
if (View.ContainsTransaction(tx.Hash))
continue;
- if (!NativeContract.Policy.CheckPolicy(tx, currentSnapshot))
- continue;
// First remove the tx if it is unverified in the pool.
MemPool.TryRemoveUnVerified(tx.Hash, out _);
- // Verify the the transaction
- if (tx.Verify(currentSnapshot, MemPool.SendersFeeMonitor.GetSenderFee(tx.Sender)) != VerifyResult.Succeed)
- continue;
// Add to the memory pool
- MemPool.TryAdd(tx.Hash, tx);
+ MemPool.TryAdd(tx, currentSnapshot);
}
// Transactions originally in the pool will automatically be reverified based on their priority.
@@ -355,11 +357,7 @@ private VerifyResult OnNewInventory(IInventory inventory)
private VerifyResult OnNewTransaction(Transaction transaction)
{
if (ContainsTransaction(transaction.Hash)) return VerifyResult.AlreadyExists;
- if (!MemPool.CanTransactionFitInPool(transaction)) return VerifyResult.OutOfMemory;
- VerifyResult reason = transaction.Verify(currentSnapshot, MemPool.SendersFeeMonitor.GetSenderFee(transaction.Sender));
- if (reason != VerifyResult.Succeed) return reason;
- if (!MemPool.TryAdd(transaction.Hash, transaction)) return VerifyResult.OutOfMemory;
- return VerifyResult.Succeed;
+ return MemPool.TryAdd(transaction, currentSnapshot);
}
protected override void OnReceive(object message)
@@ -404,7 +402,7 @@ private void Persist(Block block)
snapshot.PersistingBlock = block;
if (block.Index > 0)
{
- using (ApplicationEngine engine = new ApplicationEngine(TriggerType.System, null, snapshot, 0, true))
+ using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.System, null, snapshot, 0, true))
{
engine.LoadScript(onPersistNativeContractScript);
if (engine.Execute() != VMState.HALT) throw new InvalidOperationException();
@@ -427,7 +425,7 @@ private void Persist(Block block)
clonedSnapshot.Transactions.Add(tx.Hash, state);
clonedSnapshot.Transactions.Commit();
- using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee))
+ using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, tx.SystemFee))
{
engine.LoadScript(tx.Script);
state.VMState = engine.Execute();
diff --git a/src/neo/Ledger/ContractState.cs b/src/neo/Ledger/ContractState.cs
index 504175ee4b..882abb4e2e 100644
--- a/src/neo/Ledger/ContractState.cs
+++ b/src/neo/Ledger/ContractState.cs
@@ -32,7 +32,7 @@ public UInt160 ScriptHash
}
}
- int ISerializable.Size => sizeof(int) + Script.GetVarSize() + Manifest.ToJson().ToString().GetVarSize();
+ int ISerializable.Size => sizeof(int) + Script.GetVarSize() + Manifest.Size;
ContractState ICloneable.Clone()
{
@@ -82,7 +82,7 @@ public JObject ToJson()
public StackItem ToStackItem(ReferenceCounter referenceCounter)
{
- return new Array(referenceCounter, new StackItem[] { Script, HasStorage, Payable });
+ return new Array(referenceCounter, new StackItem[] { Script, Manifest.ToString(), HasStorage, Payable });
}
}
}
diff --git a/src/neo/Ledger/MemoryPool.cs b/src/neo/Ledger/MemoryPool.cs
index 62466d65e8..9a8b42b6e6 100644
--- a/src/neo/Ledger/MemoryPool.cs
+++ b/src/neo/Ledger/MemoryPool.cs
@@ -71,7 +71,7 @@ public class MemoryPool : IReadOnlyCollection
///
/// Store all verified unsorted transactions' senders' fee currently in the memory pool.
///
- public SendersFeeMonitor SendersFeeMonitor = new SendersFeeMonitor();
+ private TransactionVerificationContext VerificationContext = new TransactionVerificationContext();
///
/// Total count of transactions in the pool.
@@ -261,18 +261,21 @@ internal bool CanTransactionFitInPool(Transaction tx)
///
///
///
- internal bool TryAdd(UInt256 hash, Transaction tx)
+ internal VerifyResult TryAdd(Transaction tx, StoreView snapshot)
{
var poolItem = new PoolItem(tx);
- if (_unsortedTransactions.ContainsKey(hash)) return false;
+ if (_unsortedTransactions.ContainsKey(tx.Hash)) return VerifyResult.AlreadyExists;
List removedTransactions = null;
_txRwLock.EnterWriteLock();
try
{
- _unsortedTransactions.Add(hash, poolItem);
- SendersFeeMonitor.AddSenderFee(tx);
+ VerifyResult result = tx.Verify(snapshot, VerificationContext);
+ if (result != VerifyResult.Succeed) return result;
+
+ _unsortedTransactions.Add(tx.Hash, poolItem);
+ VerificationContext.AddTransaction(tx);
_sortedTransactions.Add(poolItem);
if (Count > Capacity)
@@ -290,7 +293,8 @@ internal bool TryAdd(UInt256 hash, Transaction tx)
plugin.TransactionsRemoved(MemoryPoolTxRemovalReason.CapacityExceeded, removedTransactions);
}
- return _unsortedTransactions.ContainsKey(hash);
+ if (!_unsortedTransactions.ContainsKey(tx.Hash)) return VerifyResult.OutOfMemory;
+ return VerifyResult.Succeed;
}
private List RemoveOverCapacity()
@@ -303,6 +307,9 @@ private List RemoveOverCapacity()
unsortedPool.Remove(minItem.Tx.Hash);
sortedPool.Remove(minItem);
removedTransactions.Add(minItem.Tx);
+
+ if (ReferenceEquals(sortedPool, _sortedTransactions))
+ VerificationContext.RemoveTransaction(minItem.Tx);
} while (Count > Capacity);
return removedTransactions;
@@ -315,7 +322,6 @@ private bool TryRemoveVerified(UInt256 hash, out PoolItem item)
return false;
_unsortedTransactions.Remove(hash);
- SendersFeeMonitor.RemoveSenderFee(item.Tx);
_sortedTransactions.Remove(item);
return true;
@@ -343,7 +349,7 @@ internal void InvalidateVerifiedTransactions()
// Clear the verified transactions now, since they all must be reverified.
_unsortedTransactions.Clear();
- SendersFeeMonitor = new SendersFeeMonitor();
+ VerificationContext = new TransactionVerificationContext();
_sortedTransactions.Clear();
}
@@ -413,23 +419,23 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool,
List reverifiedItems = new List(count);
List invalidItems = new List();
- // Since unverifiedSortedTxPool is ordered in an ascending manner, we take from the end.
- foreach (PoolItem item in unverifiedSortedTxPool.Reverse().Take(count))
+ _txRwLock.EnterWriteLock();
+ try
{
- if (item.Tx.VerifyForEachBlock(snapshot, SendersFeeMonitor.GetSenderFee(item.Tx.Sender)) == VerifyResult.Succeed)
+ // Since unverifiedSortedTxPool is ordered in an ascending manner, we take from the end.
+ foreach (PoolItem item in unverifiedSortedTxPool.Reverse().Take(count))
{
- reverifiedItems.Add(item);
- SendersFeeMonitor.AddSenderFee(item.Tx);
- }
- else // Transaction no longer valid -- it will be removed from unverifiedTxPool.
- invalidItems.Add(item);
+ if (item.Tx.VerifyForEachBlock(snapshot, VerificationContext) == VerifyResult.Succeed)
+ {
+ reverifiedItems.Add(item);
+ VerificationContext.AddTransaction(item.Tx);
+ }
+ else // Transaction no longer valid -- it will be removed from unverifiedTxPool.
+ invalidItems.Add(item);
- if (DateTime.UtcNow > reverifyCutOffTimeStamp) break;
- }
+ if (DateTime.UtcNow > reverifyCutOffTimeStamp) break;
+ }
- _txRwLock.EnterWriteLock();
- try
- {
int blocksTillRebroadcast = BlocksTillRebroadcast;
// Increases, proportionally, blocksTillRebroadcast if mempool has more items than threshold bigger RebroadcastMultiplierThreshold
if (Count > RebroadcastMultiplierThreshold)
@@ -450,7 +456,7 @@ private int ReverifyTransactions(SortedSet verifiedSortedTxPool,
}
}
else
- SendersFeeMonitor.RemoveSenderFee(item.Tx);
+ VerificationContext.RemoveTransaction(item.Tx);
_unverifiedTransactions.Remove(item.Tx.Hash);
unverifiedSortedTxPool.Remove(item);
diff --git a/src/neo/Ledger/SendersFeeMonitor.cs b/src/neo/Ledger/SendersFeeMonitor.cs
deleted file mode 100644
index efe3ac6ebe..0000000000
--- a/src/neo/Ledger/SendersFeeMonitor.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using Neo.Network.P2P.Payloads;
-using System.Collections.Generic;
-using System.Numerics;
-using System.Threading;
-
-namespace Neo.Ledger
-{
- public class SendersFeeMonitor
- {
- private readonly ReaderWriterLockSlim _senderFeeRwLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
-
- ///
- /// Store all verified unsorted transactions' senders' fee currently in the memory pool.
- ///
- private readonly Dictionary _senderFee = new Dictionary();
-
- public BigInteger GetSenderFee(UInt160 sender)
- {
- _senderFeeRwLock.EnterReadLock();
- if (!_senderFee.TryGetValue(sender, out var value))
- value = BigInteger.Zero;
- _senderFeeRwLock.ExitReadLock();
- return value;
- }
-
- public void AddSenderFee(Transaction tx)
- {
- _senderFeeRwLock.EnterWriteLock();
- if (_senderFee.TryGetValue(tx.Sender, out var value))
- _senderFee[tx.Sender] = value + tx.SystemFee + tx.NetworkFee;
- else
- _senderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee);
- _senderFeeRwLock.ExitWriteLock();
- }
-
- public void RemoveSenderFee(Transaction tx)
- {
- _senderFeeRwLock.EnterWriteLock();
- if ((_senderFee[tx.Sender] -= tx.SystemFee + tx.NetworkFee) == 0) _senderFee.Remove(tx.Sender);
- _senderFeeRwLock.ExitWriteLock();
- }
- }
-}
diff --git a/src/neo/Ledger/StorageItem.cs b/src/neo/Ledger/StorageItem.cs
index 801f0c72a0..5304d926df 100644
--- a/src/neo/Ledger/StorageItem.cs
+++ b/src/neo/Ledger/StorageItem.cs
@@ -1,13 +1,16 @@
using Neo.IO;
using Neo.SmartContract;
+using System;
+using System.Collections.Generic;
using System.IO;
+using System.Numerics;
namespace Neo.Ledger
{
public class StorageItem : ICloneable, ISerializable
{
private byte[] value;
- private IInteroperable interoperable;
+ private object cache;
public bool IsConstant;
public int Size => Value.GetVarSize() + sizeof(bool);
@@ -16,20 +19,23 @@ public byte[] Value
{
get
{
- if (value is null && interoperable != null)
- value = BinarySerializer.Serialize(interoperable.ToStackItem(null), 4096);
- return value;
+ return value ??= cache switch
+ {
+ BigInteger bi => bi.ToByteArrayStandard(),
+ IInteroperable interoperable => BinarySerializer.Serialize(interoperable.ToStackItem(null), 4096),
+ IReadOnlyCollection list => list.ToByteArray(),
+ null => null,
+ _ => throw new InvalidCastException()
+ };
}
set
{
- interoperable = null;
this.value = value;
+ cache = null;
}
}
- public StorageItem()
- {
- }
+ public StorageItem() { }
public StorageItem(byte[] value, bool isConstant = false)
{
@@ -37,12 +43,23 @@ public StorageItem(byte[] value, bool isConstant = false)
this.IsConstant = isConstant;
}
+ public StorageItem(BigInteger value, bool isConstant = false)
+ {
+ this.cache = value;
+ this.IsConstant = isConstant;
+ }
+
public StorageItem(IInteroperable interoperable, bool isConstant = false)
{
- this.interoperable = interoperable;
+ this.cache = interoperable;
this.IsConstant = isConstant;
}
+ public void Add(BigInteger integer)
+ {
+ Set(this + integer);
+ }
+
StorageItem ICloneable.Clone()
{
return new StorageItem
@@ -66,13 +83,21 @@ void ICloneable.FromReplica(StorageItem replica)
public T GetInteroperable() where T : IInteroperable, new()
{
- if (interoperable is null)
+ if (cache is null)
{
- interoperable = new T();
+ var interoperable = new T();
interoperable.FromStackItem(BinarySerializer.Deserialize(value, 16, 34));
+ cache = interoperable;
}
value = null;
- return (T)interoperable;
+ return (T)cache;
+ }
+
+ public List GetSerializableList() where T : ISerializable, new()
+ {
+ cache ??= new List(value.AsSerializableArray());
+ value = null;
+ return (List)cache;
}
public void Serialize(BinaryWriter writer)
@@ -80,5 +105,17 @@ public void Serialize(BinaryWriter writer)
writer.WriteVarBytes(Value);
writer.Write(IsConstant);
}
+
+ public void Set(BigInteger integer)
+ {
+ cache = integer;
+ value = null;
+ }
+
+ public static implicit operator BigInteger(StorageItem item)
+ {
+ item.cache ??= new BigInteger(item.value);
+ return (BigInteger)item.cache;
+ }
}
}
diff --git a/src/neo/Ledger/TransactionVerificationContext.cs b/src/neo/Ledger/TransactionVerificationContext.cs
new file mode 100644
index 0000000000..a2bae45b0b
--- /dev/null
+++ b/src/neo/Ledger/TransactionVerificationContext.cs
@@ -0,0 +1,37 @@
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.SmartContract.Native;
+using System.Collections.Generic;
+using System.Numerics;
+
+namespace Neo.Ledger
+{
+ public class TransactionVerificationContext
+ {
+ ///
+ /// Store all verified unsorted transactions' senders' fee currently in the memory pool.
+ ///
+ private readonly Dictionary senderFee = new Dictionary();
+
+ public void AddTransaction(Transaction tx)
+ {
+ if (senderFee.TryGetValue(tx.Sender, out var value))
+ senderFee[tx.Sender] = value + tx.SystemFee + tx.NetworkFee;
+ else
+ senderFee.Add(tx.Sender, tx.SystemFee + tx.NetworkFee);
+ }
+
+ public bool CheckTransaction(Transaction tx, StoreView snapshot)
+ {
+ BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, tx.Sender);
+ senderFee.TryGetValue(tx.Sender, out var totalSenderFeeFromPool);
+ BigInteger fee = tx.SystemFee + tx.NetworkFee + totalSenderFeeFromPool;
+ return balance >= fee;
+ }
+
+ public void RemoveTransaction(Transaction tx)
+ {
+ if ((senderFee[tx.Sender] -= tx.SystemFee + tx.NetworkFee) == 0) senderFee.Remove(tx.Sender);
+ }
+ }
+}
diff --git a/src/neo/Network/P2P/Payloads/ConsensusData.cs b/src/neo/Network/P2P/Payloads/ConsensusData.cs
index 7bbee151fb..8a63f2350f 100644
--- a/src/neo/Network/P2P/Payloads/ConsensusData.cs
+++ b/src/neo/Network/P2P/Payloads/ConsensusData.cs
@@ -27,7 +27,7 @@ public UInt256 Hash
void ISerializable.Deserialize(BinaryReader reader)
{
- PrimaryIndex = (uint)reader.ReadVarInt((ulong)ProtocolSettings.Default.MaxValidatorsCount - 1);
+ PrimaryIndex = (uint)reader.ReadVarInt((ulong)ProtocolSettings.Default.ValidatorsCount - 1);
Nonce = reader.ReadUInt64();
}
diff --git a/src/neo/Network/P2P/Payloads/Cosigner.cs b/src/neo/Network/P2P/Payloads/Signer.cs
similarity index 77%
rename from src/neo/Network/P2P/Payloads/Cosigner.cs
rename to src/neo/Network/P2P/Payloads/Signer.cs
index ba8a6fa3dd..4be59a349f 100644
--- a/src/neo/Network/P2P/Payloads/Cosigner.cs
+++ b/src/neo/Network/P2P/Payloads/Signer.cs
@@ -1,12 +1,13 @@
using Neo.Cryptography.ECC;
using Neo.IO;
using Neo.IO.Json;
+using System;
using System.IO;
using System.Linq;
namespace Neo.Network.P2P.Payloads
{
- public class Cosigner : TransactionAttribute
+ public class Signer : ISerializable
{
// This limits maximum number of AllowedContracts or AllowedGroups here
private const int MaxSubitems = 16;
@@ -16,19 +17,20 @@ public class Cosigner : TransactionAttribute
public UInt160[] AllowedContracts;
public ECPoint[] AllowedGroups;
- public override TransactionAttributeType Type => TransactionAttributeType.Cosigner;
- public override bool AllowMultiple => true;
-
- public override int Size => base.Size +
+ public int Size =>
/*Account*/ UInt160.Length +
/*Scopes*/ sizeof(WitnessScope) +
/*AllowedContracts*/ (Scopes.HasFlag(WitnessScope.CustomContracts) ? AllowedContracts.GetVarSize() : 0) +
/*AllowedGroups*/ (Scopes.HasFlag(WitnessScope.CustomGroups) ? AllowedGroups.GetVarSize() : 0);
- protected override void DeserializeWithoutType(BinaryReader reader)
+ public void Deserialize(BinaryReader reader)
{
Account = reader.ReadSerializable();
Scopes = (WitnessScope)reader.ReadByte();
+ if ((Scopes & ~(WitnessScope.CalledByEntry | WitnessScope.CustomContracts | WitnessScope.CustomGroups | WitnessScope.Global)) != 0)
+ throw new FormatException();
+ if (Scopes.HasFlag(WitnessScope.Global) && Scopes != WitnessScope.Global)
+ throw new FormatException();
AllowedContracts = Scopes.HasFlag(WitnessScope.CustomContracts)
? reader.ReadSerializableArray(MaxSubitems)
: new UInt160[0];
@@ -37,7 +39,7 @@ protected override void DeserializeWithoutType(BinaryReader reader)
: new ECPoint[0];
}
- protected override void SerializeWithoutType(BinaryWriter writer)
+ public void Serialize(BinaryWriter writer)
{
writer.Write(Account);
writer.Write((byte)Scopes);
@@ -47,9 +49,9 @@ protected override void SerializeWithoutType(BinaryWriter writer)
writer.Write(AllowedGroups);
}
- public override JObject ToJson()
+ public JObject ToJson()
{
- JObject json = base.ToJson();
+ var json = new JObject();
json["account"] = Account.ToString();
json["scopes"] = Scopes;
if (Scopes.HasFlag(WitnessScope.CustomContracts))
diff --git a/src/neo/Network/P2P/Payloads/Transaction.cs b/src/neo/Network/P2P/Payloads/Transaction.cs
index 127f56cb17..1671b70085 100644
--- a/src/neo/Network/P2P/Payloads/Transaction.cs
+++ b/src/neo/Network/P2P/Payloads/Transaction.cs
@@ -12,7 +12,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Numerics;
using Array = Neo.VM.Types.Array;
namespace Neo.Network.P2P.Payloads
@@ -28,10 +27,10 @@ public class Transaction : IEquatable, IInventory, IInteroperable
private byte version;
private uint nonce;
- private UInt160 sender;
private long sysfee;
private long netfee;
private uint validUntilBlock;
+ private Signer[] _signers;
private TransactionAttribute[] attributes;
private byte[] script;
private Witness[] witnesses;
@@ -39,20 +38,17 @@ public class Transaction : IEquatable, IInventory, IInteroperable
public const int HeaderSize =
sizeof(byte) + //Version
sizeof(uint) + //Nonce
- 20 + //Sender
sizeof(long) + //SystemFee
sizeof(long) + //NetworkFee
sizeof(uint); //ValidUntilBlock
+ private Dictionary _attributesCache;
public TransactionAttribute[] Attributes
{
get => attributes;
- set { attributes = value; _cosigners = null; _hash = null; _size = 0; }
+ set { attributes = value; _attributesCache = null; _hash = null; _size = 0; }
}
- private Dictionary _cosigners;
- public IReadOnlyDictionary Cosigners => _cosigners ??= attributes.OfType().ToDictionary(p => p.Account);
-
///
/// The NetworkFee for the transaction divided by its Size.
/// Note that this property must be used with care. Getting the value of this property multiple times will return the same result. The value of this property can only be obtained after the transaction has been completely built (no longer modified).
@@ -95,10 +91,15 @@ public byte[] Script
set { script = value; _hash = null; _size = 0; }
}
- public UInt160 Sender
+ ///
+ /// Correspond with the first entry of Signers
+ ///
+ public UInt160 Sender => _signers[0].Account;
+
+ public Signer[] Signers
{
- get => sender;
- set { sender = value; _hash = null; }
+ get => _signers;
+ set { _signers = value; _hash = null; _size = 0; }
}
private int _size;
@@ -109,6 +110,7 @@ public int Size
if (_size == 0)
{
_size = HeaderSize +
+ Signers.GetVarSize() + // Signers
Attributes.GetVarSize() + // Attributes
Script.GetVarSize() + // Script
Witnesses.GetVarSize(); // Witnesses
@@ -155,9 +157,9 @@ void ISerializable.Deserialize(BinaryReader reader)
_size = (int)reader.BaseStream.Position - startPosition;
}
- private static IEnumerable DeserializeAttributes(BinaryReader reader)
+ private static IEnumerable DeserializeAttributes(BinaryReader reader, int maxCount)
{
- int count = (int)reader.ReadVarInt(MaxTransactionAttributes);
+ int count = (int)reader.ReadVarInt((ulong)maxCount);
HashSet hashset = new HashSet();
while (count-- > 0)
{
@@ -168,27 +170,35 @@ private static IEnumerable DeserializeAttributes(BinaryRea
}
}
+ private static IEnumerable DeserializeSigners(BinaryReader reader, int maxCount)
+ {
+ int count = (int)reader.ReadVarInt((ulong)maxCount);
+ if (count == 0) throw new FormatException();
+ HashSet hashset = new HashSet();
+ for (int i = 0; i < count; i++)
+ {
+ Signer signer = reader.ReadSerializable();
+ if (i > 0 && signer.Scopes == WitnessScope.FeeOnly)
+ throw new FormatException();
+ if (!hashset.Add(signer.Account))
+ throw new FormatException();
+ yield return signer;
+ }
+ }
+
public void DeserializeUnsigned(BinaryReader reader)
{
Version = reader.ReadByte();
if (Version > 0) throw new FormatException();
Nonce = reader.ReadUInt32();
- Sender = reader.ReadSerializable();
SystemFee = reader.ReadInt64();
if (SystemFee < 0) throw new FormatException();
NetworkFee = reader.ReadInt64();
if (NetworkFee < 0) throw new FormatException();
if (SystemFee + NetworkFee < SystemFee) throw new FormatException();
ValidUntilBlock = reader.ReadUInt32();
- Attributes = DeserializeAttributes(reader).ToArray();
- try
- {
- _ = Cosigners;
- }
- catch (ArgumentException)
- {
- throw new FormatException();
- }
+ Signers = DeserializeSigners(reader, MaxTransactionAttributes).ToArray();
+ Attributes = DeserializeAttributes(reader, MaxTransactionAttributes - Signers.Length).ToArray();
Script = reader.ReadVarBytes(ushort.MaxValue);
if (Script.Length == 0) throw new FormatException();
}
@@ -210,6 +220,18 @@ void IInteroperable.FromStackItem(StackItem stackItem)
throw new NotSupportedException();
}
+ public T GetAttribute() where T : TransactionAttribute
+ {
+ return GetAttributes()?.First();
+ }
+
+ public T[] GetAttributes() where T : TransactionAttribute
+ {
+ _attributesCache ??= attributes.GroupBy(p => p.GetType()).ToDictionary(p => p.Key, p => (TransactionAttribute[])p.OfType().ToArray());
+ _attributesCache.TryGetValue(typeof(T), out var result);
+ return (T[])result;
+ }
+
public override int GetHashCode()
{
return Hash.GetHashCode();
@@ -217,8 +239,7 @@ public override int GetHashCode()
public UInt160[] GetScriptHashesForVerifying(StoreView snapshot)
{
- var hashes = new HashSet(Cosigners.Keys) { Sender };
- return hashes.OrderBy(p => p).ToArray();
+ return Signers.Select(p => p.Account).ToArray();
}
void ISerializable.Serialize(BinaryWriter writer)
@@ -231,10 +252,10 @@ void IVerifiable.SerializeUnsigned(BinaryWriter writer)
{
writer.Write(Version);
writer.Write(Nonce);
- writer.Write(Sender);
writer.Write(SystemFee);
writer.Write(NetworkFee);
writer.Write(ValidUntilBlock);
+ writer.Write(Signers);
writer.Write(Attributes);
writer.WriteVarBytes(Script);
}
@@ -250,6 +271,7 @@ public JObject ToJson()
json["sysfee"] = SystemFee.ToString();
json["netfee"] = NetworkFee.ToString();
json["validuntilblock"] = ValidUntilBlock;
+ json["signers"] = Signers.Select(p => p.ToJson()).ToArray();
json["attributes"] = Attributes.Select(p => p.ToJson()).ToArray();
json["script"] = Convert.ToBase64String(Script);
json["witnesses"] = Witnesses.Select(p => p.ToJson()).ToArray();
@@ -258,10 +280,10 @@ public JObject ToJson()
bool IInventory.Verify(StoreView snapshot)
{
- return Verify(snapshot, BigInteger.Zero) == VerifyResult.Succeed;
+ return Verify(snapshot, null) == VerifyResult.Succeed;
}
- public virtual VerifyResult VerifyForEachBlock(StoreView snapshot, BigInteger totalSenderFeeFromPool)
+ public virtual VerifyResult VerifyForEachBlock(StoreView snapshot, TransactionVerificationContext context)
{
if (ValidUntilBlock <= snapshot.Height || ValidUntilBlock > snapshot.Height + MaxValidUntilBlockIncrement)
return VerifyResult.Expired;
@@ -270,9 +292,7 @@ public virtual VerifyResult VerifyForEachBlock(StoreView snapshot, BigInteger to
return VerifyResult.PolicyFail;
if (NativeContract.Policy.GetMaxBlockSystemFee(snapshot) < SystemFee)
return VerifyResult.PolicyFail;
- BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, Sender);
- BigInteger fee = SystemFee + NetworkFee + totalSenderFeeFromPool;
- if (balance < fee) return VerifyResult.InsufficientFunds;
+ if (!(context?.CheckTransaction(this, snapshot) ?? true)) return VerifyResult.InsufficientFunds;
if (hashes.Length != Witnesses.Length) return VerifyResult.Invalid;
for (int i = 0; i < hashes.Length; i++)
{
@@ -282,9 +302,9 @@ public virtual VerifyResult VerifyForEachBlock(StoreView snapshot, BigInteger to
return VerifyResult.Succeed;
}
- public virtual VerifyResult Verify(StoreView snapshot, BigInteger totalSenderFeeFromPool)
+ public virtual VerifyResult Verify(StoreView snapshot, TransactionVerificationContext context)
{
- VerifyResult result = VerifyForEachBlock(snapshot, totalSenderFeeFromPool);
+ VerifyResult result = VerifyForEachBlock(snapshot, context);
if (result != VerifyResult.Succeed) return result;
int size = Size;
if (size > MaxTransactionSize) return VerifyResult.Invalid;
diff --git a/src/neo/Network/P2P/Payloads/TransactionAttributeType.cs b/src/neo/Network/P2P/Payloads/TransactionAttributeType.cs
index f1e2d704da..c3f32ddecf 100644
--- a/src/neo/Network/P2P/Payloads/TransactionAttributeType.cs
+++ b/src/neo/Network/P2P/Payloads/TransactionAttributeType.cs
@@ -1,10 +1,6 @@
-using Neo.IO.Caching;
-
namespace Neo.Network.P2P.Payloads
{
public enum TransactionAttributeType : byte
{
- [ReflectionCache(typeof(Cosigner))]
- Cosigner = 0x01
}
}
diff --git a/src/neo/Network/P2P/Payloads/WitnessScope.cs b/src/neo/Network/P2P/Payloads/WitnessScope.cs
index f35e550a34..9cc3cd99fd 100644
--- a/src/neo/Network/P2P/Payloads/WitnessScope.cs
+++ b/src/neo/Network/P2P/Payloads/WitnessScope.cs
@@ -6,10 +6,9 @@ namespace Neo.Network.P2P.Payloads
public enum WitnessScope : byte
{
///
- /// Global allows this witness in all contexts (default Neo2 behavior)
- /// This cannot be combined with other flags
+ /// It's only valid for be a sender, it can't be used during the execution
///
- Global = 0x00,
+ FeeOnly = 0,
///
/// CalledByEntry means that this condition must hold: EntryScriptHash == CallingScriptHash
@@ -26,6 +25,12 @@ public enum WitnessScope : byte
///
/// Custom pubkey for group members
///
- CustomGroups = 0x20
+ CustomGroups = 0x20,
+
+ ///
+ /// Global allows this witness in all contexts (default Neo2 behavior)
+ /// This cannot be combined with other flags
+ ///
+ Global = 0x80
}
}
diff --git a/src/neo/Plugins/IApplicationEngineProvider.cs b/src/neo/Plugins/IApplicationEngineProvider.cs
new file mode 100644
index 0000000000..ed74147fa0
--- /dev/null
+++ b/src/neo/Plugins/IApplicationEngineProvider.cs
@@ -0,0 +1,11 @@
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.SmartContract;
+
+namespace Neo.Plugins
+{
+ public interface IApplicationEngineProvider
+ {
+ ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false);
+ }
+}
diff --git a/src/neo/Plugins/IStoragePlugin.cs b/src/neo/Plugins/IStorageProvider.cs
similarity index 70%
rename from src/neo/Plugins/IStoragePlugin.cs
rename to src/neo/Plugins/IStorageProvider.cs
index 68f75dd2bb..5ef2d9f098 100644
--- a/src/neo/Plugins/IStoragePlugin.cs
+++ b/src/neo/Plugins/IStorageProvider.cs
@@ -2,7 +2,7 @@
namespace Neo.Plugins
{
- public interface IStoragePlugin
+ public interface IStorageProvider
{
IStore GetStore();
}
diff --git a/src/neo/Plugins/Plugin.cs b/src/neo/Plugins/Plugin.cs
index d98d1703a6..690c202d53 100644
--- a/src/neo/Plugins/Plugin.cs
+++ b/src/neo/Plugins/Plugin.cs
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Configuration;
+using Neo.SmartContract;
using System;
using System.Collections.Generic;
using System.IO;
@@ -13,7 +14,7 @@ public abstract class Plugin : IDisposable
{
public static readonly List Plugins = new List();
internal static readonly List Loggers = new List();
- internal static readonly Dictionary Storages = new Dictionary();
+ internal static readonly Dictionary Storages = new Dictionary();
internal static readonly List PersistencePlugins = new List();
internal static readonly List P2PPlugins = new List();
internal static readonly List TxObserverPlugins = new List();
@@ -50,10 +51,11 @@ protected Plugin()
Plugins.Add(this);
if (this is ILogPlugin logger) Loggers.Add(logger);
- if (this is IStoragePlugin storage) Storages.Add(Name, storage);
+ if (this is IStorageProvider storage) Storages.Add(Name, storage);
if (this is IP2PPlugin p2p) P2PPlugins.Add(p2p);
if (this is IPersistencePlugin persistence) PersistencePlugins.Add(persistence);
if (this is IMemoryPoolTxObserverPlugin txObserver) TxObserverPlugins.Add(txObserver);
+ if (this is IApplicationEngineProvider provider) ApplicationEngine.SetApplicationEngineProvider(provider);
Configure();
}
diff --git a/src/neo/ProtocolSettings.cs b/src/neo/ProtocolSettings.cs
index e004b637a8..7ac2f16273 100644
--- a/src/neo/ProtocolSettings.cs
+++ b/src/neo/ProtocolSettings.cs
@@ -10,8 +10,8 @@ public class ProtocolSettings
public uint Magic { get; }
public byte AddressVersion { get; }
public string[] StandbyCommittee { get; }
- public byte MaxCommitteeMembersCount { get; }
- public byte MaxValidatorsCount { get; }
+ public int CommitteeMembersCount { get; }
+ public int ValidatorsCount { get; }
public string[] SeedList { get; }
public uint MillisecondsPerBlock { get; }
public int MemoryPoolMaxTransactions { get; }
@@ -47,9 +47,9 @@ private ProtocolSettings(IConfigurationSection section)
{
this.Magic = section.GetValue("Magic", 0x4F454Eu);
this.AddressVersion = section.GetValue("AddressVersion", (byte)0x35);
- IConfigurationSection section_sv = section.GetSection("StandbyValidators");
- if (section_sv.Exists())
- this.StandbyCommittee = section_sv.GetChildren().Select(p => p.Get()).ToArray();
+ IConfigurationSection section_sc = section.GetSection("StandbyCommittee");
+ if (section_sc.Exists())
+ this.StandbyCommittee = section_sc.GetChildren().Select(p => p.Get()).ToArray();
else
this.StandbyCommittee = new[]
{
@@ -78,8 +78,8 @@ private ProtocolSettings(IConfigurationSection section)
"03cdcea66032b82f5c30450e381e5295cae85c5e6943af716cc6b646352a6067dc",
"02cd5a5547119e24feaa7c2a0f37b8c9366216bab7054de0065c9be42084003c8a"
};
- this.MaxCommitteeMembersCount = section.GetValue("MaxCommitteeMembersCount", (byte)21);
- this.MaxValidatorsCount = section.GetValue("MaxValidatorsCount", (byte)7);
+ this.CommitteeMembersCount = StandbyCommittee.Length;
+ this.ValidatorsCount = section.GetValue("ValidatorsCount", (byte)7);
IConfigurationSection section_sl = section.GetSection("SeedList");
if (section_sl.Exists())
this.SeedList = section_sl.GetChildren().Select(p => p.Get()).ToArray();
diff --git a/src/neo/SmartContract/ApplicationEngine.Binary.cs b/src/neo/SmartContract/ApplicationEngine.Binary.cs
index 1dd240efdb..d004dd633e 100644
--- a/src/neo/SmartContract/ApplicationEngine.Binary.cs
+++ b/src/neo/SmartContract/ApplicationEngine.Binary.cs
@@ -5,10 +5,10 @@ namespace Neo.SmartContract
{
partial class ApplicationEngine
{
- public static readonly InteropDescriptor System_Binary_Serialize = Register("System.Binary.Serialize", nameof(BinarySerialize), 0_00100000, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor System_Binary_Deserialize = Register("System.Binary.Deserialize", nameof(BinaryDeserialize), 0_00500000, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor System_Binary_Base64Encode = Register("System.Binary.Base64Encode", nameof(Base64Encode), 0_00100000, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor System_Binary_Base64Decode = Register("System.Binary.Base64Decode", nameof(Base64Decode), 0_00100000, TriggerType.All, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Binary_Serialize = Register("System.Binary.Serialize", nameof(BinarySerialize), 0_00100000, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Binary_Deserialize = Register("System.Binary.Deserialize", nameof(BinaryDeserialize), 0_00500000, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Binary_Base64Encode = Register("System.Binary.Base64Encode", nameof(Base64Encode), 0_00100000, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Binary_Base64Decode = Register("System.Binary.Base64Decode", nameof(Base64Decode), 0_00100000, CallFlags.None, true);
internal byte[] BinarySerialize(StackItem item)
{
diff --git a/src/neo/SmartContract/ApplicationEngine.Blockchain.cs b/src/neo/SmartContract/ApplicationEngine.Blockchain.cs
index a4d5cd8bd3..628a746a3a 100644
--- a/src/neo/SmartContract/ApplicationEngine.Blockchain.cs
+++ b/src/neo/SmartContract/ApplicationEngine.Blockchain.cs
@@ -10,12 +10,12 @@ partial class ApplicationEngine
{
public const uint MaxTraceableBlocks = Transaction.MaxValidUntilBlockIncrement;
- public static readonly InteropDescriptor System_Blockchain_GetHeight = Register("System.Blockchain.GetHeight", nameof(GetBlockchainHeight), 0_00000400, TriggerType.Application, CallFlags.AllowStates, true);
- public static readonly InteropDescriptor System_Blockchain_GetBlock = Register("System.Blockchain.GetBlock", nameof(GetBlock), 0_02500000, TriggerType.Application, CallFlags.AllowStates, true);
- public static readonly InteropDescriptor System_Blockchain_GetTransaction = Register("System.Blockchain.GetTransaction", nameof(GetTransaction), 0_01000000, TriggerType.Application, CallFlags.AllowStates, true);
- public static readonly InteropDescriptor System_Blockchain_GetTransactionHeight = Register("System.Blockchain.GetTransactionHeight", nameof(GetTransactionHeight), 0_01000000, TriggerType.Application, CallFlags.AllowStates, true);
- public static readonly InteropDescriptor System_Blockchain_GetTransactionFromBlock = Register("System.Blockchain.GetTransactionFromBlock", nameof(GetTransactionFromBlock), 0_01000000, TriggerType.Application, CallFlags.AllowStates, true);
- public static readonly InteropDescriptor System_Blockchain_GetContract = Register("System.Blockchain.GetContract", nameof(GetContract), 0_01000000, TriggerType.Application, CallFlags.AllowStates, true);
+ public static readonly InteropDescriptor System_Blockchain_GetHeight = Register("System.Blockchain.GetHeight", nameof(GetBlockchainHeight), 0_00000400, CallFlags.AllowStates, true);
+ public static readonly InteropDescriptor System_Blockchain_GetBlock = Register("System.Blockchain.GetBlock", nameof(GetBlock), 0_02500000, CallFlags.AllowStates, true);
+ public static readonly InteropDescriptor System_Blockchain_GetTransaction = Register("System.Blockchain.GetTransaction", nameof(GetTransaction), 0_01000000, CallFlags.AllowStates, true);
+ public static readonly InteropDescriptor System_Blockchain_GetTransactionHeight = Register("System.Blockchain.GetTransactionHeight", nameof(GetTransactionHeight), 0_01000000, CallFlags.AllowStates, true);
+ public static readonly InteropDescriptor System_Blockchain_GetTransactionFromBlock = Register("System.Blockchain.GetTransactionFromBlock", nameof(GetTransactionFromBlock), 0_01000000, CallFlags.AllowStates, true);
+ public static readonly InteropDescriptor System_Blockchain_GetContract = Register("System.Blockchain.GetContract", nameof(GetContract), 0_01000000, CallFlags.AllowStates, true);
internal uint GetBlockchainHeight()
{
diff --git a/src/neo/SmartContract/ApplicationEngine.Callback.cs b/src/neo/SmartContract/ApplicationEngine.Callback.cs
index 633a6c6fe2..673de39039 100644
--- a/src/neo/SmartContract/ApplicationEngine.Callback.cs
+++ b/src/neo/SmartContract/ApplicationEngine.Callback.cs
@@ -7,10 +7,10 @@ namespace Neo.SmartContract
{
partial class ApplicationEngine
{
- public static readonly InteropDescriptor System_Callback_Create = Register("System.Callback.Create", nameof(CreateCallback), 0_00000400, TriggerType.All, CallFlags.None, false);
- public static readonly InteropDescriptor System_Callback_CreateFromMethod = Register("System.Callback.CreateFromMethod", nameof(CreateCallbackFromMethod), 0_01000000, TriggerType.All, CallFlags.None, false);
- public static readonly InteropDescriptor System_Callback_CreateFromSyscall = Register("System.Callback.CreateFromSyscall", nameof(CreateCallbackFromSyscall), 0_00000400, TriggerType.All, CallFlags.None, false);
- public static readonly InteropDescriptor System_Callback_Invoke = Register("System.Callback.Invoke", nameof(InvokeCallback), 0_01000000, TriggerType.All, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Callback_Create = Register("System.Callback.Create", nameof(CreateCallback), 0_00000400, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Callback_CreateFromMethod = Register("System.Callback.CreateFromMethod", nameof(CreateCallbackFromMethod), 0_01000000, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Callback_CreateFromSyscall = Register("System.Callback.CreateFromSyscall", nameof(CreateCallbackFromSyscall), 0_00000400, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Callback_Invoke = Register("System.Callback.Invoke", nameof(InvokeCallback), 0_01000000, CallFlags.None, false);
internal void InvokeCallback(CallbackBase callback, Array args)
{
diff --git a/src/neo/SmartContract/ApplicationEngine.Contract.cs b/src/neo/SmartContract/ApplicationEngine.Contract.cs
index 5b84938289..4ecfdde31e 100644
--- a/src/neo/SmartContract/ApplicationEngine.Contract.cs
+++ b/src/neo/SmartContract/ApplicationEngine.Contract.cs
@@ -15,18 +15,18 @@ partial class ApplicationEngine
{
public const int MaxContractLength = 1024 * 1024;
- public static readonly InteropDescriptor System_Contract_Create = Register("System.Contract.Create", nameof(CreateContract), 0, TriggerType.Application, CallFlags.AllowModifyStates, false);
- public static readonly InteropDescriptor System_Contract_Update = Register("System.Contract.Update", nameof(UpdateContract), 0, TriggerType.Application, CallFlags.AllowModifyStates, false);
- public static readonly InteropDescriptor System_Contract_Destroy = Register("System.Contract.Destroy", nameof(DestroyContract), 0_01000000, TriggerType.Application, CallFlags.AllowModifyStates, false);
- public static readonly InteropDescriptor System_Contract_Call = Register("System.Contract.Call", nameof(CallContract), 0_01000000, TriggerType.System | TriggerType.Application, CallFlags.AllowCall, false);
- public static readonly InteropDescriptor System_Contract_CallEx = Register("System.Contract.CallEx", nameof(CallContractEx), 0_01000000, TriggerType.System | TriggerType.Application, CallFlags.AllowCall, false);
- public static readonly InteropDescriptor System_Contract_IsStandard = Register("System.Contract.IsStandard", nameof(IsStandardContract), 0_00030000, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor System_Contract_GetCallFlags = Register("System.Contract.GetCallFlags", nameof(GetCallFlags), 0_00030000, TriggerType.All, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Contract_Create = Register("System.Contract.Create", nameof(CreateContract), 0, CallFlags.AllowModifyStates, false);
+ public static readonly InteropDescriptor System_Contract_Update = Register("System.Contract.Update", nameof(UpdateContract), 0, CallFlags.AllowModifyStates, false);
+ public static readonly InteropDescriptor System_Contract_Destroy = Register("System.Contract.Destroy", nameof(DestroyContract), 0_01000000, CallFlags.AllowModifyStates, false);
+ public static readonly InteropDescriptor System_Contract_Call = Register("System.Contract.Call", nameof(CallContract), 0_01000000, CallFlags.AllowCall, false);
+ public static readonly InteropDescriptor System_Contract_CallEx = Register("System.Contract.CallEx", nameof(CallContractEx), 0_01000000, CallFlags.AllowCall, false);
+ public static readonly InteropDescriptor System_Contract_IsStandard = Register("System.Contract.IsStandard", nameof(IsStandardContract), 0_00030000, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Contract_GetCallFlags = Register("System.Contract.GetCallFlags", nameof(GetCallFlags), 0_00030000, CallFlags.None, false);
///
/// Calculate corresponding account scripthash for given public key
/// Warning: check first that input public key is valid, before creating the script.
///
- public static readonly InteropDescriptor System_Contract_CreateStandardAccount = Register("System.Contract.CreateStandardAccount", nameof(CreateStandardAccount), 0_00010000, TriggerType.All, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Contract_CreateStandardAccount = Register("System.Contract.CreateStandardAccount", nameof(CreateStandardAccount), 0_00010000, CallFlags.None, true);
internal ContractState CreateContract(byte[] script, byte[] manifest)
{
diff --git a/src/neo/SmartContract/ApplicationEngine.Crypto.cs b/src/neo/SmartContract/ApplicationEngine.Crypto.cs
index 13a8edab9e..e448e60374 100644
--- a/src/neo/SmartContract/ApplicationEngine.Crypto.cs
+++ b/src/neo/SmartContract/ApplicationEngine.Crypto.cs
@@ -2,7 +2,6 @@
using Neo.Cryptography.ECC;
using Neo.Network.P2P;
using Neo.Network.P2P.Payloads;
-using Neo.VM;
using Neo.VM.Types;
using System;
@@ -12,12 +11,12 @@ partial class ApplicationEngine
{
public const long ECDsaVerifyPrice = 0_01000000;
- public static readonly InteropDescriptor Neo_Crypto_RIPEMD160 = Register("Neo.Crypto.RIPEMD160", nameof(RIPEMD160), 0_01000000, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor Neo_Crypto_SHA256 = Register("Neo.Crypto.SHA256", nameof(Sha256), 0_01000000, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor Neo_Crypto_VerifyWithECDsaSecp256r1 = Register("Neo.Crypto.VerifyWithECDsaSecp256r1", nameof(VerifyWithECDsaSecp256r1), ECDsaVerifyPrice, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor Neo_Crypto_VerifyWithECDsaSecp256k1 = Register("Neo.Crypto.VerifyWithECDsaSecp256k1", nameof(VerifyWithECDsaSecp256k1), ECDsaVerifyPrice, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor Neo_Crypto_CheckMultisigWithECDsaSecp256r1 = Register("Neo.Crypto.CheckMultisigWithECDsaSecp256r1", nameof(CheckMultisigWithECDsaSecp256r1), 0, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor Neo_Crypto_CheckMultisigWithECDsaSecp256k1 = Register("Neo.Crypto.CheckMultisigWithECDsaSecp256k1", nameof(CheckMultisigWithECDsaSecp256k1), 0, TriggerType.All, CallFlags.None, true);
+ public static readonly InteropDescriptor Neo_Crypto_RIPEMD160 = Register("Neo.Crypto.RIPEMD160", nameof(RIPEMD160), 0_01000000, CallFlags.None, true);
+ public static readonly InteropDescriptor Neo_Crypto_SHA256 = Register("Neo.Crypto.SHA256", nameof(Sha256), 0_01000000, CallFlags.None, true);
+ public static readonly InteropDescriptor Neo_Crypto_VerifyWithECDsaSecp256r1 = Register("Neo.Crypto.VerifyWithECDsaSecp256r1", nameof(VerifyWithECDsaSecp256r1), ECDsaVerifyPrice, CallFlags.None, true);
+ public static readonly InteropDescriptor Neo_Crypto_VerifyWithECDsaSecp256k1 = Register("Neo.Crypto.VerifyWithECDsaSecp256k1", nameof(VerifyWithECDsaSecp256k1), ECDsaVerifyPrice, CallFlags.None, true);
+ public static readonly InteropDescriptor Neo_Crypto_CheckMultisigWithECDsaSecp256r1 = Register("Neo.Crypto.CheckMultisigWithECDsaSecp256r1", nameof(CheckMultisigWithECDsaSecp256r1), 0, CallFlags.None, true);
+ public static readonly InteropDescriptor Neo_Crypto_CheckMultisigWithECDsaSecp256k1 = Register("Neo.Crypto.CheckMultisigWithECDsaSecp256k1", nameof(CheckMultisigWithECDsaSecp256k1), 0, CallFlags.None, true);
internal byte[] RIPEMD160(StackItem item)
{
diff --git a/src/neo/SmartContract/ApplicationEngine.Enumerator.cs b/src/neo/SmartContract/ApplicationEngine.Enumerator.cs
index 02f1409310..765bdaa901 100644
--- a/src/neo/SmartContract/ApplicationEngine.Enumerator.cs
+++ b/src/neo/SmartContract/ApplicationEngine.Enumerator.cs
@@ -8,10 +8,10 @@ namespace Neo.SmartContract
{
partial class ApplicationEngine
{
- public static readonly InteropDescriptor System_Enumerator_Create = Register("System.Enumerator.Create", nameof(CreateEnumerator), 0_00000400, TriggerType.All, CallFlags.None, false);
- public static readonly InteropDescriptor System_Enumerator_Next = Register("System.Enumerator.Next", nameof(EnumeratorNext), 0_01000000, TriggerType.All, CallFlags.None, false);
- public static readonly InteropDescriptor System_Enumerator_Value = Register("System.Enumerator.Value", nameof(EnumeratorValue), 0_00000400, TriggerType.All, CallFlags.None, false);
- public static readonly InteropDescriptor System_Enumerator_Concat = Register("System.Enumerator.Concat", nameof(ConcatEnumerators), 0_00000400, TriggerType.All, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Enumerator_Create = Register("System.Enumerator.Create", nameof(CreateEnumerator), 0_00000400, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Enumerator_Next = Register("System.Enumerator.Next", nameof(EnumeratorNext), 0_01000000, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Enumerator_Value = Register("System.Enumerator.Value", nameof(EnumeratorValue), 0_00000400, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Enumerator_Concat = Register("System.Enumerator.Concat", nameof(ConcatEnumerators), 0_00000400, CallFlags.None, false);
internal IEnumerator CreateEnumerator(StackItem item)
{
diff --git a/src/neo/SmartContract/ApplicationEngine.Iterator.cs b/src/neo/SmartContract/ApplicationEngine.Iterator.cs
index c902c50979..cfe5509e0a 100644
--- a/src/neo/SmartContract/ApplicationEngine.Iterator.cs
+++ b/src/neo/SmartContract/ApplicationEngine.Iterator.cs
@@ -8,11 +8,11 @@ namespace Neo.SmartContract
{
partial class ApplicationEngine
{
- public static readonly InteropDescriptor System_Iterator_Create = Register("System.Iterator.Create", nameof(CreateIterator), 0_00000400, TriggerType.All, CallFlags.None, false);
- public static readonly InteropDescriptor System_Iterator_Key = Register("System.Iterator.Key", nameof(IteratorKey), 0_00000400, TriggerType.All, CallFlags.None, false);
- public static readonly InteropDescriptor System_Iterator_Keys = Register("System.Iterator.Keys", nameof(IteratorKeys), 0_00000400, TriggerType.All, CallFlags.None, false);
- public static readonly InteropDescriptor System_Iterator_Values = Register("System.Iterator.Values", nameof(IteratorValues), 0_00000400, TriggerType.All, CallFlags.None, false);
- public static readonly InteropDescriptor System_Iterator_Concat = Register("System.Iterator.Concat", nameof(ConcatIterators), 0_00000400, TriggerType.All, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Iterator_Create = Register("System.Iterator.Create", nameof(CreateIterator), 0_00000400, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Iterator_Key = Register("System.Iterator.Key", nameof(IteratorKey), 0_00000400, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Iterator_Keys = Register("System.Iterator.Keys", nameof(IteratorKeys), 0_00000400, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Iterator_Values = Register("System.Iterator.Values", nameof(IteratorValues), 0_00000400, CallFlags.None, false);
+ public static readonly InteropDescriptor System_Iterator_Concat = Register("System.Iterator.Concat", nameof(ConcatIterators), 0_00000400, CallFlags.None, false);
internal IIterator CreateIterator(StackItem item)
{
diff --git a/src/neo/SmartContract/ApplicationEngine.Json.cs b/src/neo/SmartContract/ApplicationEngine.Json.cs
index 047ff2920f..491e1365b2 100644
--- a/src/neo/SmartContract/ApplicationEngine.Json.cs
+++ b/src/neo/SmartContract/ApplicationEngine.Json.cs
@@ -5,8 +5,8 @@ namespace Neo.SmartContract
{
partial class ApplicationEngine
{
- public static readonly InteropDescriptor System_Json_Serialize = Register("System.Json.Serialize", nameof(JsonSerialize), 0_00100000, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor System_Json_Deserialize = Register("System.Json.Deserialize", nameof(JsonDeserialize), 0_00500000, TriggerType.All, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Json_Serialize = Register("System.Json.Serialize", nameof(JsonSerialize), 0_00100000, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Json_Deserialize = Register("System.Json.Deserialize", nameof(JsonDeserialize), 0_00500000, CallFlags.None, true);
internal byte[] JsonSerialize(StackItem item)
{
diff --git a/src/neo/SmartContract/ApplicationEngine.Native.cs b/src/neo/SmartContract/ApplicationEngine.Native.cs
index 7ea7736745..9cc38c369b 100644
--- a/src/neo/SmartContract/ApplicationEngine.Native.cs
+++ b/src/neo/SmartContract/ApplicationEngine.Native.cs
@@ -6,8 +6,8 @@ namespace Neo.SmartContract
{
partial class ApplicationEngine
{
- public static readonly InteropDescriptor Neo_Native_Deploy = Register("Neo.Native.Deploy", nameof(DeployNativeContracts), 0, TriggerType.Application, CallFlags.AllowModifyStates, false);
- public static readonly InteropDescriptor Neo_Native_Call = Register("Neo.Native.Call", nameof(CallNativeContract), 0, TriggerType.System | TriggerType.Application, CallFlags.None, false);
+ public static readonly InteropDescriptor Neo_Native_Deploy = Register("Neo.Native.Deploy", nameof(DeployNativeContracts), 0, CallFlags.AllowModifyStates, false);
+ public static readonly InteropDescriptor Neo_Native_Call = Register("Neo.Native.Call", nameof(CallNativeContract), 0, CallFlags.None, false);
internal void DeployNativeContracts()
{
diff --git a/src/neo/SmartContract/ApplicationEngine.Runtime.cs b/src/neo/SmartContract/ApplicationEngine.Runtime.cs
index a000f06e34..9713d03893 100644
--- a/src/neo/SmartContract/ApplicationEngine.Runtime.cs
+++ b/src/neo/SmartContract/ApplicationEngine.Runtime.cs
@@ -14,19 +14,19 @@ partial class ApplicationEngine
public const int MaxEventName = 32;
public const int MaxNotificationSize = 1024;
- public static readonly InteropDescriptor System_Runtime_Platform = Register("System.Runtime.Platform", nameof(GetPlatform), 0_00000250, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor System_Runtime_GetTrigger = Register("System.Runtime.GetTrigger", nameof(Trigger), 0_00000250, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor System_Runtime_GetTime = Register("System.Runtime.GetTime", nameof(GetTime), 0_00000250, TriggerType.Application, CallFlags.AllowStates, true);
- public static readonly InteropDescriptor System_Runtime_GetScriptContainer = Register("System.Runtime.GetScriptContainer", nameof(GetScriptContainer), 0_00000250, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor System_Runtime_GetExecutingScriptHash = Register("System.Runtime.GetExecutingScriptHash", nameof(CurrentScriptHash), 0_00000400, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor System_Runtime_GetCallingScriptHash = Register("System.Runtime.GetCallingScriptHash", nameof(CallingScriptHash), 0_00000400, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor System_Runtime_GetEntryScriptHash = Register("System.Runtime.GetEntryScriptHash", nameof(EntryScriptHash), 0_00000400, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor System_Runtime_CheckWitness = Register("System.Runtime.CheckWitness", nameof(CheckWitness), 0_00030000, TriggerType.All, CallFlags.AllowStates, true);
- public static readonly InteropDescriptor System_Runtime_GetInvocationCounter = Register("System.Runtime.GetInvocationCounter", nameof(GetInvocationCounter), 0_00000400, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor System_Runtime_Log = Register("System.Runtime.Log", nameof(RuntimeLog), 0_01000000, TriggerType.All, CallFlags.AllowNotify, false);
- public static readonly InteropDescriptor System_Runtime_Notify = Register("System.Runtime.Notify", nameof(RuntimeNotify), 0_01000000, TriggerType.All, CallFlags.AllowNotify, false);
- public static readonly InteropDescriptor System_Runtime_GetNotifications = Register("System.Runtime.GetNotifications", nameof(GetNotifications), 0_00010000, TriggerType.All, CallFlags.None, true);
- public static readonly InteropDescriptor System_Runtime_GasLeft = Register("System.Runtime.GasLeft", nameof(GasLeft), 0_00000400, TriggerType.All, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Runtime_Platform = Register("System.Runtime.Platform", nameof(GetPlatform), 0_00000250, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Runtime_GetTrigger = Register("System.Runtime.GetTrigger", nameof(Trigger), 0_00000250, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Runtime_GetTime = Register("System.Runtime.GetTime", nameof(GetTime), 0_00000250, CallFlags.AllowStates, true);
+ public static readonly InteropDescriptor System_Runtime_GetScriptContainer = Register("System.Runtime.GetScriptContainer", nameof(GetScriptContainer), 0_00000250, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Runtime_GetExecutingScriptHash = Register("System.Runtime.GetExecutingScriptHash", nameof(CurrentScriptHash), 0_00000400, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Runtime_GetCallingScriptHash = Register("System.Runtime.GetCallingScriptHash", nameof(CallingScriptHash), 0_00000400, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Runtime_GetEntryScriptHash = Register("System.Runtime.GetEntryScriptHash", nameof(EntryScriptHash), 0_00000400, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Runtime_CheckWitness = Register("System.Runtime.CheckWitness", nameof(CheckWitness), 0_00030000, CallFlags.AllowStates, true);
+ public static readonly InteropDescriptor System_Runtime_GetInvocationCounter = Register("System.Runtime.GetInvocationCounter", nameof(GetInvocationCounter), 0_00000400, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Runtime_Log = Register("System.Runtime.Log", nameof(RuntimeLog), 0_01000000, CallFlags.AllowNotify, false);
+ public static readonly InteropDescriptor System_Runtime_Notify = Register("System.Runtime.Notify", nameof(RuntimeNotify), 0_01000000, CallFlags.AllowNotify, false);
+ public static readonly InteropDescriptor System_Runtime_GetNotifications = Register("System.Runtime.GetNotifications", nameof(GetNotifications), 0_00010000, CallFlags.None, true);
+ public static readonly InteropDescriptor System_Runtime_GasLeft = Register("System.Runtime.GasLeft", nameof(GasLeft), 0_00000400, CallFlags.None, true);
private static bool CheckItemForNotification(StackItem state)
{
@@ -104,23 +104,24 @@ internal bool CheckWitnessInternal(UInt160 hash)
{
if (ScriptContainer is Transaction tx)
{
- if (!tx.Cosigners.TryGetValue(hash, out Cosigner cosigner)) return false;
- if (cosigner.Scopes == WitnessScope.Global) return true;
- if (cosigner.Scopes.HasFlag(WitnessScope.CalledByEntry))
+ Signer signer = tx.Signers.FirstOrDefault(p => p.Account.Equals(hash));
+ if (signer is null) return false;
+ if (signer.Scopes == WitnessScope.Global) return true;
+ if (signer.Scopes.HasFlag(WitnessScope.CalledByEntry))
{
if (CallingScriptHash == EntryScriptHash)
return true;
}
- if (cosigner.Scopes.HasFlag(WitnessScope.CustomContracts))
+ if (signer.Scopes.HasFlag(WitnessScope.CustomContracts))
{
- if (cosigner.AllowedContracts.Contains(CurrentScriptHash))
+ if (signer.AllowedContracts.Contains(CurrentScriptHash))
return true;
}
- if (cosigner.Scopes.HasFlag(WitnessScope.CustomGroups))
+ if (signer.Scopes.HasFlag(WitnessScope.CustomGroups))
{
var contract = Snapshot.Contracts[CallingScriptHash];
// check if current group is the required one
- if (contract.Manifest.Groups.Select(p => p.PubKey).Intersect(cosigner.AllowedGroups).Any())
+ if (contract.Manifest.Groups.Select(p => p.PubKey).Intersect(signer.AllowedGroups).Any())
return true;
}
return false;
diff --git a/src/neo/SmartContract/ApplicationEngine.Storage.cs b/src/neo/SmartContract/ApplicationEngine.Storage.cs
index 97ccb5494c..f790b6f7e7 100644
--- a/src/neo/SmartContract/ApplicationEngine.Storage.cs
+++ b/src/neo/SmartContract/ApplicationEngine.Storage.cs
@@ -12,14 +12,14 @@ partial class ApplicationEngine
public const int MaxStorageKeySize = 64;
public const int MaxStorageValueSize = ushort.MaxValue;
- public static readonly InteropDescriptor System_Storage_GetContext = Register("System.Storage.GetContext", nameof(GetStorageContext), 0_00000400, TriggerType.Application, CallFlags.AllowStates, false);
- public static readonly InteropDescriptor System_Storage_GetReadOnlyContext = Register("System.Storage.GetReadOnlyContext", nameof(GetReadOnlyContext), 0_00000400, TriggerType.Application, CallFlags.AllowStates, false);
- public static readonly InteropDescriptor System_Storage_AsReadOnly = Register("System.Storage.AsReadOnly", nameof(AsReadOnly), 0_00000400, TriggerType.Application, CallFlags.AllowStates, false);
- public static readonly InteropDescriptor System_Storage_Get = Register("System.Storage.Get", nameof(Get), 0_01000000, TriggerType.Application, CallFlags.AllowStates, false);
- public static readonly InteropDescriptor System_Storage_Find = Register("System.Storage.Find", nameof(Find), 0_01000000, TriggerType.Application, CallFlags.AllowStates, false);
- public static readonly InteropDescriptor System_Storage_Put = Register("System.Storage.Put", nameof(Put), 0, TriggerType.Application, CallFlags.AllowModifyStates, false);
- public static readonly InteropDescriptor System_Storage_PutEx = Register("System.Storage.PutEx", nameof(PutEx), 0, TriggerType.Application, CallFlags.AllowModifyStates, false);
- public static readonly InteropDescriptor System_Storage_Delete = Register("System.Storage.Delete", nameof(Delete), 1 * StoragePrice, TriggerType.Application, CallFlags.AllowModifyStates, false);
+ public static readonly InteropDescriptor System_Storage_GetContext = Register("System.Storage.GetContext", nameof(GetStorageContext), 0_00000400, CallFlags.AllowStates, false);
+ public static readonly InteropDescriptor System_Storage_GetReadOnlyContext = Register("System.Storage.GetReadOnlyContext", nameof(GetReadOnlyContext), 0_00000400, CallFlags.AllowStates, false);
+ public static readonly InteropDescriptor System_Storage_AsReadOnly = Register("System.Storage.AsReadOnly", nameof(AsReadOnly), 0_00000400, CallFlags.AllowStates, false);
+ public static readonly InteropDescriptor System_Storage_Get = Register("System.Storage.Get", nameof(Get), 0_01000000, CallFlags.AllowStates, false);
+ public static readonly InteropDescriptor System_Storage_Find = Register("System.Storage.Find", nameof(Find), 0_01000000, CallFlags.AllowStates, false);
+ public static readonly InteropDescriptor System_Storage_Put = Register("System.Storage.Put", nameof(Put), 0, CallFlags.AllowModifyStates, false);
+ public static readonly InteropDescriptor System_Storage_PutEx = Register("System.Storage.PutEx", nameof(PutEx), 0, CallFlags.AllowModifyStates, false);
+ public static readonly InteropDescriptor System_Storage_Delete = Register("System.Storage.Delete", nameof(Delete), 1 * StoragePrice, CallFlags.AllowModifyStates, false);
internal StorageContext GetStorageContext()
{
diff --git a/src/neo/SmartContract/ApplicationEngine.cs b/src/neo/SmartContract/ApplicationEngine.cs
index 05f963ddb2..81c462f9de 100644
--- a/src/neo/SmartContract/ApplicationEngine.cs
+++ b/src/neo/SmartContract/ApplicationEngine.cs
@@ -2,6 +2,7 @@
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
+using Neo.Plugins;
using Neo.VM;
using Neo.VM.Types;
using System;
@@ -9,6 +10,7 @@
using System.Linq;
using System.Numerics;
using System.Reflection;
+using static System.Threading.Interlocked;
using Array = System.Array;
using VMArray = Neo.VM.Types.Array;
@@ -26,6 +28,7 @@ private class InvocationState
public static event EventHandler Notify;
public static event EventHandler Log;
+ private static IApplicationEngineProvider applicationEngineProvider;
private static Dictionary services;
private readonly long gas_amount;
private readonly bool testMode;
@@ -40,12 +43,13 @@ private class InvocationState
public StoreView Snapshot { get; }
public long GasConsumed { get; private set; } = 0;
public long GasLeft => testMode ? -1 : gas_amount - GasConsumed;
+ public Exception FaultException { get; private set; }
public UInt160 CurrentScriptHash => CurrentContext?.GetState().ScriptHash;
public UInt160 CallingScriptHash => CurrentContext?.GetState().CallingScriptHash;
public UInt160 EntryScriptHash => EntryContext?.GetState().ScriptHash;
public IReadOnlyList Notifications => notifications ?? (IReadOnlyList)Array.Empty();
- public ApplicationEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false)
+ protected ApplicationEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false)
{
this.Trigger = trigger;
this.ScriptContainer = container;
@@ -61,6 +65,12 @@ internal void AddGas(long gas)
throw new InvalidOperationException("Insufficient GAS.");
}
+ protected override void OnFault(Exception e)
+ {
+ FaultException = e;
+ base.OnFault(e);
+ }
+
internal void CallFromNativeContract(Action onComplete, UInt160 hash, string method, params StackItem[] args)
{
InvocationState state = GetInvocationState(CurrentContext);
@@ -101,6 +111,10 @@ protected override void ContextUnloaded(ExecutionContext context)
}
}
+ public static ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false)
+ => applicationEngineProvider?.Create(trigger, container, snapshot, gas, testMode)
+ ?? new ApplicationEngine(trigger, container, snapshot, gas, testMode);
+
private InvocationState GetInvocationState(ExecutionContext context)
{
if (!invocationStates.TryGetValue(context, out InvocationState state))
@@ -206,8 +220,6 @@ public override void Dispose()
protected override void OnSysCall(uint method)
{
InteropDescriptor descriptor = services[method];
- if (!descriptor.AllowedTriggers.HasFlag(Trigger))
- throw new InvalidOperationException($"Cannot call this SYSCALL with the trigger {Trigger}.");
ExecutionContextState state = CurrentContext.GetState();
if (!state.CallFlags.HasFlag(descriptor.RequiredCallFlags))
throw new InvalidOperationException($"Cannot call this SYSCALL with the flag {state.CallFlags}.");
@@ -249,21 +261,26 @@ private static Block CreateDummyBlock(StoreView snapshot)
};
}
- private static InteropDescriptor Register(string name, string handler, long fixedPrice, TriggerType allowedTriggers, CallFlags requiredCallFlags, bool allowCallback)
+ private static InteropDescriptor Register(string name, string handler, long fixedPrice, CallFlags requiredCallFlags, bool allowCallback)
{
MethodInfo method = typeof(ApplicationEngine).GetMethod(handler, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
?? typeof(ApplicationEngine).GetProperty(handler, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetMethod;
- InteropDescriptor descriptor = new InteropDescriptor(name, method, fixedPrice, allowedTriggers, requiredCallFlags, allowCallback);
+ InteropDescriptor descriptor = new InteropDescriptor(name, method, fixedPrice, requiredCallFlags, allowCallback);
services ??= new Dictionary();
services.Add(descriptor.Hash, descriptor);
return descriptor;
}
+ internal static void ResetApplicationEngineProvider()
+ {
+ Exchange(ref applicationEngineProvider, null);
+ }
+
public static ApplicationEngine Run(byte[] script, StoreView snapshot,
IVerifiable container = null, Block persistingBlock = null, int offset = 0, bool testMode = false, long gas = default)
{
snapshot.PersistingBlock = persistingBlock ?? snapshot.PersistingBlock ?? CreateDummyBlock(snapshot);
- ApplicationEngine engine = new ApplicationEngine(TriggerType.Application, container, snapshot, gas, testMode);
+ ApplicationEngine engine = Create(TriggerType.Application, container, snapshot, gas, testMode);
engine.LoadScript(script).InstructionPointer = offset;
engine.Execute();
return engine;
@@ -276,5 +293,10 @@ public static ApplicationEngine Run(byte[] script, IVerifiable container = null,
return Run(script, snapshot, container, persistingBlock, offset, testMode, gas);
}
}
+
+ internal static bool SetApplicationEngineProvider(IApplicationEngineProvider provider)
+ {
+ return CompareExchange(ref applicationEngineProvider, provider, null) is null;
+ }
}
}
diff --git a/src/neo/SmartContract/Helper.cs b/src/neo/SmartContract/Helper.cs
index 6fedd8b9f9..b2cdb416a2 100644
--- a/src/neo/SmartContract/Helper.cs
+++ b/src/neo/SmartContract/Helper.cs
@@ -162,7 +162,7 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snap
if (hashes[i] != verifiable.Witnesses[i].ScriptHash) return false;
offset = 0;
}
- using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, verifiable, snapshot, gas))
+ using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot.Clone(), gas))
{
engine.LoadScript(verification, CallFlags.ReadOnly).InstructionPointer = offset;
engine.LoadScript(verifiable.Witnesses[i].InvocationScript, CallFlags.None);
diff --git a/src/neo/SmartContract/InteropDescriptor.cs b/src/neo/SmartContract/InteropDescriptor.cs
index b41d2ec57a..5a3b833f18 100644
--- a/src/neo/SmartContract/InteropDescriptor.cs
+++ b/src/neo/SmartContract/InteropDescriptor.cs
@@ -13,18 +13,16 @@ public class InteropDescriptor
internal MethodInfo Handler { get; }
internal InteropParameterDescriptor[] Parameters { get; }
public long FixedPrice { get; }
- public TriggerType AllowedTriggers { get; }
public CallFlags RequiredCallFlags { get; }
public bool AllowCallback { get; }
- internal InteropDescriptor(string name, MethodInfo handler, long fixedPrice, TriggerType allowedTriggers, CallFlags requiredCallFlags, bool allowCallback)
+ internal InteropDescriptor(string name, MethodInfo handler, long fixedPrice, CallFlags requiredCallFlags, bool allowCallback)
{
this.Name = name;
this.Hash = BitConverter.ToUInt32(Encoding.ASCII.GetBytes(name).Sha256(), 0);
this.Handler = handler;
this.Parameters = handler.GetParameters().Select(p => new InteropParameterDescriptor(p)).ToArray();
this.FixedPrice = fixedPrice;
- this.AllowedTriggers = allowedTriggers;
this.RequiredCallFlags = requiredCallFlags;
this.AllowCallback = allowCallback;
}
diff --git a/src/neo/SmartContract/Manifest/ContractManifest.cs b/src/neo/SmartContract/Manifest/ContractManifest.cs
index b68eefbe89..990a400929 100644
--- a/src/neo/SmartContract/Manifest/ContractManifest.cs
+++ b/src/neo/SmartContract/Manifest/ContractManifest.cs
@@ -20,7 +20,14 @@ public class ContractManifest : ISerializable
///
/// Serialized size
///
- public int Size => ToJson().ToString().GetVarSize();
+ public int Size
+ {
+ get
+ {
+ int size = Utility.StrictUTF8.GetByteCount(ToString());
+ return IO.Helper.GetVarSize(size) + size;
+ }
+ }
///
/// Contract hash
@@ -37,6 +44,11 @@ public class ContractManifest : ISerializable
///
public ContractFeatures Features { get; set; }
+ ///
+ /// NEP10 - SupportedStandards
+ ///
+ public string[] SupportedStandards { get; set; }
+
///
/// For technical details of ABI, please refer to NEP-3: NeoContract ABI. (https://github.com/neo-project/proposals/blob/master/nep-3.mediawiki)
///
@@ -101,20 +113,21 @@ public static ContractManifest FromJson(JObject json)
///
public JObject ToJson()
{
- var feature = new JObject();
- feature["storage"] = Features.HasFlag(ContractFeatures.HasStorage);
- feature["payable"] = Features.HasFlag(ContractFeatures.Payable);
-
- var json = new JObject();
- json["groups"] = new JArray(Groups.Select(u => u.ToJson()).ToArray());
- json["features"] = feature;
- json["abi"] = Abi.ToJson();
- json["permissions"] = Permissions.Select(p => p.ToJson()).ToArray();
- json["trusts"] = Trusts.ToJson();
- json["safemethods"] = SafeMethods.ToJson();
- json["extra"] = Extra;
-
- return json;
+ return new JObject
+ {
+ ["groups"] = Groups.Select(u => u.ToJson()).ToArray(),
+ ["features"] = new JObject
+ {
+ ["storage"] = Features.HasFlag(ContractFeatures.HasStorage),
+ ["payable"] = Features.HasFlag(ContractFeatures.Payable)
+ },
+ ["supportedstandards"] = SupportedStandards.Select(u => new JString(u)).ToArray(),
+ ["abi"] = Abi.ToJson(),
+ ["permissions"] = Permissions.Select(p => p.ToJson()).ToArray(),
+ ["trusts"] = Trusts.ToJson(),
+ ["safemethods"] = SafeMethods.ToJson(),
+ ["extra"] = Extra
+ };
}
///
@@ -127,6 +140,7 @@ public ContractManifest Clone()
{
Groups = Groups.Select(p => p.Clone()).ToArray(),
Features = Features,
+ SupportedStandards = SupportedStandards[..],
Abi = Abi.Clone(),
Permissions = Permissions.Select(p => p.Clone()).ToArray(),
Trusts = Trusts,
@@ -143,7 +157,7 @@ public ContractManifest Clone()
public void Serialize(BinaryWriter writer)
{
- writer.WriteVarString(ToJson().ToString());
+ writer.WriteVarString(ToString());
}
public void Deserialize(BinaryReader reader)
@@ -153,15 +167,16 @@ public void Deserialize(BinaryReader reader)
private void DeserializeFromJson(JObject json)
{
- Abi = ContractAbi.FromJson(json["abi"]);
Groups = ((JArray)json["groups"]).Select(u => ContractGroup.FromJson(u)).ToArray();
Features = ContractFeatures.NoProperty;
+ if (json["features"]["storage"].AsBoolean()) Features |= ContractFeatures.HasStorage;
+ if (json["features"]["payable"].AsBoolean()) Features |= ContractFeatures.Payable;
+ SupportedStandards = ((JArray)json["supportedstandards"]).Select(u => u.AsString()).ToArray();
+ Abi = ContractAbi.FromJson(json["abi"]);
Permissions = ((JArray)json["permissions"]).Select(u => ContractPermission.FromJson(u)).ToArray();
Trusts = WildcardContainer.FromJson(json["trusts"], u => UInt160.Parse(u.AsString()));
SafeMethods = WildcardContainer.FromJson(json["safemethods"], u => u.AsString());
Extra = json["extra"];
- if (json["features"]["storage"].AsBoolean()) Features |= ContractFeatures.HasStorage;
- if (json["features"]["payable"].AsBoolean()) Features |= ContractFeatures.Payable;
}
///
diff --git a/src/neo/SmartContract/Native/KeyBuilder.cs b/src/neo/SmartContract/Native/KeyBuilder.cs
index a5cafedfd9..79ae513df8 100644
--- a/src/neo/SmartContract/Native/KeyBuilder.cs
+++ b/src/neo/SmartContract/Native/KeyBuilder.cs
@@ -37,6 +37,14 @@ unsafe public KeyBuilder Add(T key) where T : unmanaged
return Add(new ReadOnlySpan(&key, sizeof(T)));
}
+ public byte[] ToArray()
+ {
+ using (stream)
+ {
+ return StorageKey.CreateSearchPrefix(id, stream.ToArray());
+ }
+ }
+
public static implicit operator StorageKey(KeyBuilder builder)
{
using (builder.stream)
diff --git a/src/neo/SmartContract/Native/NativeContract.cs b/src/neo/SmartContract/Native/NativeContract.cs
index 0f86ce91ba..217c4c9091 100644
--- a/src/neo/SmartContract/Native/NativeContract.cs
+++ b/src/neo/SmartContract/Native/NativeContract.cs
@@ -30,8 +30,6 @@ public abstract class NativeContract
public UInt160 Hash { get; }
public abstract int Id { get; }
public ContractManifest Manifest { get; }
- [ContractMethod(0, CallFlags.None)]
- public virtual string[] SupportedStandards { get; } = { "NEP-10" };
protected NativeContract()
{
@@ -60,18 +58,19 @@ protected NativeContract()
}
this.Manifest = new ContractManifest
{
- Permissions = new[] { ContractPermission.DefaultPermission },
+ Groups = System.Array.Empty(),
+ Features = ContractFeatures.NoProperty,
+ SupportedStandards = new string[0],
Abi = new ContractAbi()
{
Hash = Hash,
Events = System.Array.Empty(),
Methods = descriptors.ToArray()
},
- Features = ContractFeatures.NoProperty,
- Groups = System.Array.Empty(),
- SafeMethods = WildcardContainer.Create(safeMethods.ToArray()),
+ Permissions = new[] { ContractPermission.DefaultPermission },
Trusts = WildcardContainer.Create(),
- Extra = null,
+ SafeMethods = WildcardContainer.Create(safeMethods.ToArray()),
+ Extra = null
};
contractsList.Add(this);
contractsNameDictionary.Add(Name, this);
diff --git a/src/neo/SmartContract/Native/PolicyContract.cs b/src/neo/SmartContract/Native/PolicyContract.cs
index 6fd173b409..872e9ec666 100644
--- a/src/neo/SmartContract/Native/PolicyContract.cs
+++ b/src/neo/SmartContract/Native/PolicyContract.cs
@@ -2,12 +2,11 @@
using Neo.IO;
using Neo.Ledger;
-using Neo.Network.P2P.Payloads;
using Neo.Persistence;
using Neo.SmartContract.Manifest;
using System;
using System.Collections.Generic;
-using System.Linq;
+using System.Numerics;
namespace Neo.SmartContract.Native
{
@@ -27,14 +26,6 @@ public PolicyContract()
Manifest.Features = ContractFeatures.HasStorage;
}
- internal bool CheckPolicy(Transaction tx, StoreView snapshot)
- {
- UInt160[] blockedAccounts = GetBlockedAccounts(snapshot);
- if (blockedAccounts.Intersect(tx.GetScriptHashesForVerifying(snapshot)).Any())
- return false;
- return true;
- }
-
private bool CheckCommittees(ApplicationEngine engine)
{
UInt160 committeeMultiSigAddr = NEO.GetCommitteeAddress(engine.Snapshot);
@@ -68,31 +59,31 @@ internal override void Initialize(ApplicationEngine engine)
[ContractMethod(0_01000000, CallFlags.AllowStates)]
public uint GetMaxTransactionsPerBlock(StoreView snapshot)
{
- return BitConverter.ToUInt32(snapshot.Storages[CreateStorageKey(Prefix_MaxTransactionsPerBlock)].Value, 0);
+ return (uint)(BigInteger)snapshot.Storages[CreateStorageKey(Prefix_MaxTransactionsPerBlock)];
}
[ContractMethod(0_01000000, CallFlags.AllowStates)]
public uint GetMaxBlockSize(StoreView snapshot)
{
- return BitConverter.ToUInt32(snapshot.Storages[CreateStorageKey(Prefix_MaxBlockSize)].Value, 0);
+ return (uint)(BigInteger)snapshot.Storages[CreateStorageKey(Prefix_MaxBlockSize)];
}
[ContractMethod(0_01000000, CallFlags.AllowStates)]
public long GetMaxBlockSystemFee(StoreView snapshot)
{
- return BitConverter.ToInt64(snapshot.Storages[CreateStorageKey(Prefix_MaxBlockSystemFee)].Value, 0);
+ return (long)(BigInteger)snapshot.Storages[CreateStorageKey(Prefix_MaxBlockSystemFee)];
}
[ContractMethod(0_01000000, CallFlags.AllowStates)]
public long GetFeePerByte(StoreView snapshot)
{
- return BitConverter.ToInt64(snapshot.Storages[CreateStorageKey(Prefix_FeePerByte)].Value, 0);
+ return (long)(BigInteger)snapshot.Storages[CreateStorageKey(Prefix_FeePerByte)];
}
[ContractMethod(0_01000000, CallFlags.AllowStates)]
public UInt160[] GetBlockedAccounts(StoreView snapshot)
{
- return snapshot.Storages[CreateStorageKey(Prefix_BlockedAccounts)].Value.AsSerializableArray();
+ return snapshot.Storages[CreateStorageKey(Prefix_BlockedAccounts)].GetSerializableList().ToArray();
}
[ContractMethod(0_03000000, CallFlags.AllowModifyStates)]
@@ -101,7 +92,7 @@ private bool SetMaxBlockSize(ApplicationEngine engine, uint value)
if (!CheckCommittees(engine)) return false;
if (Network.P2P.Message.PayloadMaxSize <= value) return false;
StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_MaxBlockSize));
- storage.Value = BitConverter.GetBytes(value);
+ storage.Set(value);
return true;
}
@@ -110,7 +101,7 @@ private bool SetMaxTransactionsPerBlock(ApplicationEngine engine, uint value)
{
if (!CheckCommittees(engine)) return false;
StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_MaxTransactionsPerBlock));
- storage.Value = BitConverter.GetBytes(value);
+ storage.Set(value);
return true;
}
@@ -120,7 +111,7 @@ private bool SetMaxBlockSystemFee(ApplicationEngine engine, long value)
if (!CheckCommittees(engine)) return false;
if (value <= 4007600) return false;
StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_MaxBlockSystemFee));
- storage.Value = BitConverter.GetBytes(value);
+ storage.Set(value);
return true;
}
@@ -129,7 +120,7 @@ private bool SetFeePerByte(ApplicationEngine engine, long value)
{
if (!CheckCommittees(engine)) return false;
StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_FeePerByte));
- storage.Value = BitConverter.GetBytes(value);
+ storage.Set(value);
return true;
}
@@ -139,10 +130,10 @@ private bool BlockAccount(ApplicationEngine engine, UInt160 account)
if (!CheckCommittees(engine)) return false;
StorageKey key = CreateStorageKey(Prefix_BlockedAccounts);
StorageItem storage = engine.Snapshot.Storages[key];
- SortedSet accounts = new SortedSet(storage.Value.AsSerializableArray());
- if (!accounts.Add(account)) return false;
- storage = engine.Snapshot.Storages.GetAndChange(key);
- storage.Value = accounts.ToByteArray();
+ List accounts = storage.GetSerializableList();
+ if (accounts.Contains(account)) return false;
+ engine.Snapshot.Storages.GetAndChange(key);
+ accounts.Add(account);
return true;
}
@@ -152,10 +143,11 @@ private bool UnblockAccount(ApplicationEngine engine, UInt160 account)
if (!CheckCommittees(engine)) return false;
StorageKey key = CreateStorageKey(Prefix_BlockedAccounts);
StorageItem storage = engine.Snapshot.Storages[key];
- SortedSet accounts = new SortedSet(storage.Value.AsSerializableArray());
- if (!accounts.Remove(account)) return false;
- storage = engine.Snapshot.Storages.GetAndChange(key);
- storage.Value = accounts.ToByteArray();
+ List accounts = storage.GetSerializableList();
+ int index = accounts.IndexOf(account);
+ if (index < 0) return false;
+ engine.Snapshot.Storages.GetAndChange(key);
+ accounts.RemoveAt(index);
return true;
}
}
diff --git a/src/neo/SmartContract/Native/Tokens/NeoToken.cs b/src/neo/SmartContract/Native/Tokens/NeoToken.cs
index aef7abd14d..4024de5690 100644
--- a/src/neo/SmartContract/Native/Tokens/NeoToken.cs
+++ b/src/neo/SmartContract/Native/Tokens/NeoToken.cs
@@ -21,6 +21,9 @@ public sealed class NeoToken : Nep5Token
public override byte Decimals => 0;
public BigInteger TotalAmount { get; }
+ public const decimal EffectiveVoterTurnout = 0.2M;
+
+ private const byte Prefix_VotersCount = 1;
private const byte Prefix_Candidate = 33;
private const byte Prefix_NextValidators = 14;
@@ -40,9 +43,8 @@ protected override void OnBalanceChanging(ApplicationEngine engine, UInt160 acco
if (amount.IsZero) return;
if (state.VoteTo != null)
{
- StorageItem storage_validator = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Candidate).Add(state.VoteTo));
- CandidateState state_validator = storage_validator.GetInteroperable();
- state_validator.Votes += amount;
+ engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Candidate).Add(state.VoteTo)).GetInteroperable().Votes += amount;
+ engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_VotersCount)).Add(amount);
}
}
@@ -87,19 +89,8 @@ private BigInteger CalculateBonus(BigInteger value, uint start, uint end)
internal override void Initialize(ApplicationEngine engine)
{
- BigInteger amount = TotalAmount;
- for (int i = 0; i < Blockchain.StandbyCommittee.Length; i++)
- {
- ECPoint pubkey = Blockchain.StandbyCommittee[i];
- RegisterCandidateInternal(engine.Snapshot, pubkey);
- BigInteger balance = TotalAmount / 2 / (Blockchain.StandbyValidators.Length * 2 + (Blockchain.StandbyCommittee.Length - Blockchain.StandbyValidators.Length));
- if (i < Blockchain.StandbyValidators.Length) balance *= 2;
- UInt160 account = Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash();
- Mint(engine, account, balance);
- VoteInternal(engine.Snapshot, account, pubkey);
- amount -= balance;
- }
- Mint(engine, Blockchain.GetConsensusAddress(Blockchain.StandbyValidators), amount);
+ engine.Snapshot.Storages.Add(CreateStorageKey(Prefix_VotersCount), new StorageItem(new byte[0]));
+ Mint(engine, Blockchain.GetConsensusAddress(Blockchain.StandbyValidators), TotalAmount);
}
protected override void OnPersist(ApplicationEngine engine)
@@ -123,16 +114,11 @@ private bool RegisterCandidate(ApplicationEngine engine, ECPoint pubkey)
{
if (!engine.CheckWitnessInternal(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash()))
return false;
- RegisterCandidateInternal(engine.Snapshot, pubkey);
- return true;
- }
-
- private void RegisterCandidateInternal(StoreView snapshot, ECPoint pubkey)
- {
StorageKey key = CreateStorageKey(Prefix_Candidate).Add(pubkey);
- StorageItem item = snapshot.Storages.GetAndChange(key, () => new StorageItem(new CandidateState()));
+ StorageItem item = engine.Snapshot.Storages.GetAndChange(key, () => new StorageItem(new CandidateState()));
CandidateState state = item.GetInteroperable();
state.Registered = true;
+ return true;
}
[ContractMethod(0_05000000, CallFlags.AllowModifyStates)]
@@ -155,30 +141,33 @@ private bool UnregisterCandidate(ApplicationEngine engine, ECPoint pubkey)
private bool Vote(ApplicationEngine engine, UInt160 account, ECPoint voteTo)
{
if (!engine.CheckWitnessInternal(account)) return false;
- return VoteInternal(engine.Snapshot, account, voteTo);
- }
-
- private bool VoteInternal(StoreView snapshot, UInt160 account, ECPoint voteTo)
- {
StorageKey key_account = CreateStorageKey(Prefix_Account).Add(account);
- if (snapshot.Storages.TryGet(key_account) is null) return false;
- StorageItem storage_account = snapshot.Storages.GetAndChange(key_account);
+ if (engine.Snapshot.Storages.TryGet(key_account) is null) return false;
+ StorageItem storage_account = engine.Snapshot.Storages.GetAndChange(key_account);
NeoAccountState state_account = storage_account.GetInteroperable();
+ if (state_account.VoteTo is null ^ voteTo is null)
+ {
+ StorageItem item = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_VotersCount));
+ if (state_account.VoteTo is null)
+ item.Add(state_account.Balance);
+ else
+ item.Add(-state_account.Balance);
+ }
if (state_account.VoteTo != null)
{
StorageKey key = CreateStorageKey(Prefix_Candidate).Add(state_account.VoteTo);
- StorageItem storage_validator = snapshot.Storages.GetAndChange(key);
+ StorageItem storage_validator = engine.Snapshot.Storages.GetAndChange(key);
CandidateState state_validator = storage_validator.GetInteroperable();
state_validator.Votes -= state_account.Balance;
if (!state_validator.Registered && state_validator.Votes.IsZero)
- snapshot.Storages.Delete(key);
+ engine.Snapshot.Storages.Delete(key);
}
state_account.VoteTo = voteTo;
if (voteTo != null)
{
StorageKey key = CreateStorageKey(Prefix_Candidate).Add(voteTo);
- if (snapshot.Storages.TryGet(key) is null) return false;
- StorageItem storage_validator = snapshot.Storages.GetAndChange(key);
+ if (engine.Snapshot.Storages.TryGet(key) is null) return false;
+ StorageItem storage_validator = engine.Snapshot.Storages.GetAndChange(key);
CandidateState state_validator = storage_validator.GetInteroperable();
if (!state_validator.Registered) return false;
state_validator.Votes += state_account.Balance;
@@ -189,29 +178,24 @@ private bool VoteInternal(StoreView snapshot, UInt160 account, ECPoint voteTo)
[ContractMethod(1_00000000, CallFlags.AllowStates)]
public (ECPoint PublicKey, BigInteger Votes)[] GetCandidates(StoreView snapshot)
{
- return GetCandidatesInternal(snapshot).ToArray();
- }
-
- private IEnumerable<(ECPoint PublicKey, BigInteger Votes)> GetCandidatesInternal(StoreView snapshot)
- {
- byte[] prefix_key = StorageKey.CreateSearchPrefix(Id, new[] { Prefix_Candidate });
+ byte[] prefix_key = CreateStorageKey(Prefix_Candidate).ToArray();
return snapshot.Storages.Find(prefix_key).Select(p =>
(
p.Key.Key.AsSerializable(1),
p.Value.GetInteroperable()
- )).Where(p => p.Item2.Registered).Select(p => (p.Item1, p.Item2.Votes));
+ )).Where(p => p.Item2.Registered).Select(p => (p.Item1, p.Item2.Votes)).ToArray();
}
[ContractMethod(1_00000000, CallFlags.AllowStates)]
public ECPoint[] GetValidators(StoreView snapshot)
{
- return GetCommitteeMembers(snapshot, ProtocolSettings.Default.MaxValidatorsCount).OrderBy(p => p).ToArray();
+ return GetCommitteeMembers(snapshot).Take(ProtocolSettings.Default.ValidatorsCount).OrderBy(p => p).ToArray();
}
[ContractMethod(1_00000000, CallFlags.AllowStates)]
public ECPoint[] GetCommittee(StoreView snapshot)
{
- return GetCommitteeMembers(snapshot, ProtocolSettings.Default.MaxCommitteeMembersCount).OrderBy(p => p).ToArray();
+ return GetCommitteeMembers(snapshot).OrderBy(p => p).ToArray();
}
public UInt160 GetCommitteeAddress(StoreView snapshot)
@@ -220,9 +204,16 @@ public UInt160 GetCommitteeAddress(StoreView snapshot)
return Contract.CreateMultiSigRedeemScript(committees.Length - (committees.Length - 1) / 2, committees).ToScriptHash();
}
- private IEnumerable GetCommitteeMembers(StoreView snapshot, int count)
+ private IEnumerable GetCommitteeMembers(StoreView snapshot)
{
- return GetCandidatesInternal(snapshot).OrderByDescending(p => p.Votes).ThenBy(p => p.PublicKey).Select(p => p.PublicKey).Take(count);
+ decimal votersCount = (decimal)(BigInteger)snapshot.Storages[CreateStorageKey(Prefix_VotersCount)];
+ decimal VoterTurnout = votersCount / (decimal)TotalAmount;
+ if (VoterTurnout < EffectiveVoterTurnout)
+ return Blockchain.StandbyCommittee;
+ var candidates = GetCandidates(snapshot);
+ if (candidates.Length < ProtocolSettings.Default.CommitteeMembersCount)
+ return Blockchain.StandbyCommittee;
+ return candidates.OrderByDescending(p => p.Votes).ThenBy(p => p.PublicKey).Select(p => p.PublicKey).Take(ProtocolSettings.Default.CommitteeMembersCount);
}
[ContractMethod(1_00000000, CallFlags.AllowStates)]
@@ -230,7 +221,7 @@ public ECPoint[] GetNextBlockValidators(StoreView snapshot)
{
StorageItem storage = snapshot.Storages.TryGet(CreateStorageKey(Prefix_NextValidators));
if (storage is null) return Blockchain.StandbyValidators;
- return storage.Value.AsSerializableArray();
+ return storage.GetSerializableList().ToArray();
}
public class NeoAccountState : AccountState
diff --git a/src/neo/SmartContract/Native/Tokens/Nep5Token.cs b/src/neo/SmartContract/Native/Tokens/Nep5Token.cs
index 6e7598ab70..ed4308b73c 100644
--- a/src/neo/SmartContract/Native/Tokens/Nep5Token.cs
+++ b/src/neo/SmartContract/Native/Tokens/Nep5Token.cs
@@ -13,7 +13,6 @@ namespace Neo.SmartContract.Native.Tokens
public abstract class Nep5Token : NativeContract
where TState : AccountState, new()
{
- public override string[] SupportedStandards { get; } = { "NEP-5", "NEP-10" };
[ContractMethod(0, CallFlags.None)]
public abstract string Symbol { get; }
[ContractMethod(0, CallFlags.None)]
@@ -28,6 +27,7 @@ protected Nep5Token()
this.Factor = BigInteger.Pow(10, Decimals);
Manifest.Features = ContractFeatures.HasStorage;
+ Manifest.SupportedStandards = new[] { "NEP-5" };
var events = new List(Manifest.Abi.Events)
{
@@ -66,13 +66,8 @@ internal protected virtual void Mint(ApplicationEngine engine, UInt160 account,
TState state = storage.GetInteroperable();
OnBalanceChanging(engine, account, state, amount);
state.Balance += amount;
- storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_TotalSupply), () => new StorageItem
- {
- Value = BigInteger.Zero.ToByteArrayStandard()
- });
- BigInteger totalSupply = new BigInteger(storage.Value);
- totalSupply += amount;
- storage.Value = totalSupply.ToByteArrayStandard();
+ storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_TotalSupply), () => new StorageItem(BigInteger.Zero));
+ storage.Add(amount);
engine.SendNotification(Hash, "Transfer", new Array { StackItem.Null, account.ToArray(), amount });
}
@@ -90,9 +85,7 @@ internal protected virtual void Burn(ApplicationEngine engine, UInt160 account,
else
state.Balance -= amount;
storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_TotalSupply));
- BigInteger totalSupply = new BigInteger(storage.Value);
- totalSupply -= amount;
- storage.Value = totalSupply.ToByteArrayStandard();
+ storage.Add(-amount);
engine.SendNotification(Hash, "Transfer", new Array { account.ToArray(), StackItem.Null, amount });
}
@@ -101,7 +94,7 @@ public virtual BigInteger TotalSupply(StoreView snapshot)
{
StorageItem storage = snapshot.Storages.TryGet(CreateStorageKey(Prefix_TotalSupply));
if (storage is null) return BigInteger.Zero;
- return new BigInteger(storage.Value);
+ return storage;
}
[ContractMethod(0_01000000, CallFlags.AllowStates)]
diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs
index d70fa23f8b..d77532abb9 100644
--- a/src/neo/Wallets/Wallet.cs
+++ b/src/neo/Wallets/Wallet.cs
@@ -192,6 +192,26 @@ public static byte[] GetPrivateKeyFromWIF(string wif)
return privateKey;
}
+ private static Signer[] GetSigners(UInt160 sender, Signer[] cosigners)
+ {
+ for (int i = 0; i < cosigners.Length; i++)
+ {
+ if (cosigners[i].Account.Equals(sender))
+ {
+ if (i == 0) return cosigners;
+ List list = new List(cosigners);
+ list.RemoveAt(i);
+ list.Insert(0, cosigners[i]);
+ return list.ToArray();
+ }
+ }
+ return cosigners.Prepend(new Signer
+ {
+ Account = sender,
+ Scopes = WitnessScope.FeeOnly
+ }).ToArray();
+ }
+
public virtual WalletAccount Import(X509Certificate2 cert)
{
byte[] privateKey;
@@ -277,19 +297,18 @@ public Transaction MakeTransaction(TransferOutput[] outputs, UInt160 from = null
if (balances_gas is null)
balances_gas = accounts.Select(p => (Account: p, Value: NativeContract.GAS.BalanceOf(snapshot, p))).Where(p => p.Value.Sign > 0).ToList();
- var cosigners = cosignerList.Select(p =>
- new Cosigner()
- {
- // default access for transfers should be valid only for first invocation
- Scopes = WitnessScope.CalledByEntry,
- Account = new UInt160(p.ToArray())
- }).ToArray();
+ var cosigners = cosignerList.Select(p => new Signer()
+ {
+ // default access for transfers should be valid only for first invocation
+ Scopes = WitnessScope.CalledByEntry,
+ Account = p
+ }).ToArray();
- return MakeTransaction(snapshot, script, cosigners, balances_gas);
+ return MakeTransaction(snapshot, script, cosigners, Array.Empty(), balances_gas);
}
}
- public Transaction MakeTransaction(byte[] script, UInt160 sender = null, TransactionAttribute[] attributes = null)
+ public Transaction MakeTransaction(byte[] script, UInt160 sender = null, Signer[] cosigners = null, TransactionAttribute[] attributes = null)
{
UInt160[] accounts;
if (sender is null)
@@ -299,17 +318,17 @@ public Transaction MakeTransaction(byte[] script, UInt160 sender = null, Transac
else
{
if (!Contains(sender))
- throw new ArgumentException($"The address {sender.ToString()} was not found in the wallet");
+ throw new ArgumentException($"The address {sender} was not found in the wallet");
accounts = new[] { sender };
}
using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
{
var balances_gas = accounts.Select(p => (Account: p, Value: NativeContract.GAS.BalanceOf(snapshot, p))).Where(p => p.Value.Sign > 0).ToList();
- return MakeTransaction(snapshot, script, attributes ?? new TransactionAttribute[0], balances_gas);
+ return MakeTransaction(snapshot, script, cosigners ?? Array.Empty(), attributes ?? Array.Empty(), balances_gas);
}
}
- private Transaction MakeTransaction(StoreView snapshot, byte[] script, TransactionAttribute[] attributes, List<(UInt160 Account, BigInteger Value)> balances_gas)
+ private Transaction MakeTransaction(StoreView snapshot, byte[] script, Signer[] cosigners, TransactionAttribute[] attributes, List<(UInt160 Account, BigInteger Value)> balances_gas)
{
Random rand = new Random();
foreach (var (account, value) in balances_gas)
@@ -319,23 +338,25 @@ private Transaction MakeTransaction(StoreView snapshot, byte[] script, Transacti
Version = 0,
Nonce = (uint)rand.Next(),
Script = script,
- Sender = account,
ValidUntilBlock = snapshot.Height + Transaction.MaxValidUntilBlockIncrement,
+ Signers = GetSigners(account, cosigners),
Attributes = attributes,
};
// will try to execute 'transfer' script to check if it works
using (ApplicationEngine engine = ApplicationEngine.Run(script, snapshot.Clone(), tx, testMode: true))
{
- if (engine.State.HasFlag(VMState.FAULT))
- throw new InvalidOperationException($"Failed execution for '{script.ToHexString()}'");
+ if (engine.State == VMState.FAULT)
+ {
+ throw new InvalidOperationException($"Failed execution for '{script.ToHexString()}'", engine.FaultException);
+ }
tx.SystemFee = engine.GasConsumed;
}
UInt160[] hashes = tx.GetScriptHashesForVerifying(snapshot);
- // base size for transaction: includes const_header + attributes + script + hashes
- int size = Transaction.HeaderSize + tx.Attributes.GetVarSize() + script.GetVarSize() + IO.Helper.GetVarSize(hashes.Length);
+ // base size for transaction: includes const_header + signers + attributes + script + hashes
+ int size = Transaction.HeaderSize + tx.Signers.GetVarSize() + tx.Attributes.GetVarSize() + script.GetVarSize() + IO.Helper.GetVarSize(hashes.Length);
foreach (UInt160 hash in hashes)
{
diff --git a/tests/neo.UnitTests/Consensus/UT_ConsensusContext.cs b/tests/neo.UnitTests/Consensus/UT_ConsensusContext.cs
index 2f32b4b7ff..ca12f676a0 100644
--- a/tests/neo.UnitTests/Consensus/UT_ConsensusContext.cs
+++ b/tests/neo.UnitTests/Consensus/UT_ConsensusContext.cs
@@ -125,10 +125,10 @@ private Transaction CreateTransactionWithSize(int v)
var tx = new Transaction()
{
Attributes = System.Array.Empty(),
+ Signers = new Signer[] { new Signer() { Account = UInt160.Zero } },
NetworkFee = 0,
Nonce = (uint)Environment.TickCount,
Script = new byte[0],
- Sender = UInt160.Zero,
SystemFee = 0,
ValidUntilBlock = (uint)r.Next(),
Version = 0,
@@ -145,10 +145,10 @@ private Transaction CreateTransactionWithSytemFee(long fee)
var tx = new Transaction()
{
Attributes = System.Array.Empty(),
+ Signers = new Signer[] { new Signer() { Account = UInt160.Zero } },
NetworkFee = 0,
Nonce = (uint)Environment.TickCount,
Script = new byte[0],
- Sender = UInt160.Zero,
SystemFee = fee,
ValidUntilBlock = int.MaxValue,
Version = 0,
diff --git a/tests/neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs b/tests/neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs
index b2c5775903..65aa81e0c0 100644
--- a/tests/neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs
+++ b/tests/neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs
@@ -152,8 +152,8 @@ public void TestTest()
Transaction tx = new Transaction
{
Script = TestUtils.GetByteArray(32, 0x42),
- Sender = UInt160.Zero,
SystemFee = 4200000000,
+ Signers = Array.Empty(),
Attributes = Array.Empty(),
Witnesses = new[]
{
diff --git a/tests/neo.UnitTests/Extensions/NativeContractExtensions.cs b/tests/neo.UnitTests/Extensions/NativeContractExtensions.cs
index cbf4a109d9..dfd2cb7005 100644
--- a/tests/neo.UnitTests/Extensions/NativeContractExtensions.cs
+++ b/tests/neo.UnitTests/Extensions/NativeContractExtensions.cs
@@ -17,7 +17,7 @@ public static StackItem Call(this NativeContract contract, StoreView snapshot, s
public static StackItem Call(this NativeContract contract, StoreView snapshot, IVerifiable container, string method, params ContractParameter[] args)
{
- var engine = new ApplicationEngine(TriggerType.Application, container, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, container, snapshot, 0, true);
engine.LoadScript(contract.Script);
diff --git a/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs b/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs
index e3a5fc9adf..b0cd686022 100644
--- a/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs
+++ b/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs
@@ -6,7 +6,6 @@
using Neo.VM;
using System;
using System.IO;
-using System.Linq;
using System.Numerics;
namespace Neo.UnitTests.Extensions
@@ -43,7 +42,7 @@ public void SerializeUnsigned(BinaryWriter writer) { }
public static bool Transfer(this NativeContract contract, StoreView snapshot, byte[] from, byte[] to, BigInteger amount, bool signFrom)
{
- var engine = new ApplicationEngine(TriggerType.Application,
+ var engine = ApplicationEngine.Create(TriggerType.Application,
new ManualWitness(signFrom ? new UInt160(from) : null), snapshot, 0, true);
engine.LoadScript(contract.Script);
@@ -68,31 +67,9 @@ public static bool Transfer(this NativeContract contract, StoreView snapshot, by
return result.GetBoolean();
}
- public static string[] SupportedStandards(this NativeContract contract)
- {
- var engine = new ApplicationEngine(TriggerType.Application, null, null, 0, testMode: true);
-
- engine.LoadScript(contract.Script);
-
- var script = new ScriptBuilder();
- script.EmitPush(0);
- script.Emit(OpCode.PACK);
- script.EmitPush("supportedStandards");
- engine.LoadScript(script.ToArray());
-
- engine.Execute().Should().Be(VMState.HALT);
-
- var result = engine.ResultStack.Pop();
- result.Should().BeOfType(typeof(VM.Types.Array));
-
- return (result as VM.Types.Array).ToArray()
- .Select(u => u.GetString())
- .ToArray();
- }
-
public static BigInteger TotalSupply(this NativeContract contract, StoreView snapshot)
{
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(contract.Script);
@@ -112,7 +89,7 @@ public static BigInteger TotalSupply(this NativeContract contract, StoreView sna
public static BigInteger BalanceOf(this NativeContract contract, StoreView snapshot, byte[] account)
{
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(contract.Script);
@@ -133,7 +110,7 @@ public static BigInteger BalanceOf(this NativeContract contract, StoreView snaps
public static BigInteger Decimals(this NativeContract contract)
{
- var engine = new ApplicationEngine(TriggerType.Application, null, null, 0, testMode: true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 0, testMode: true);
engine.LoadScript(contract.Script);
@@ -153,7 +130,7 @@ public static BigInteger Decimals(this NativeContract contract)
public static string Symbol(this NativeContract contract)
{
- var engine = new ApplicationEngine(TriggerType.Application, null, null, 0, testMode: true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 0, testMode: true);
engine.LoadScript(contract.Script);
@@ -173,7 +150,7 @@ public static string Symbol(this NativeContract contract)
public static string Name(this NativeContract contract)
{
- var engine = new ApplicationEngine(TriggerType.Application, null, null, 0, testMode: true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 0, testMode: true);
engine.LoadScript(contract.Script);
diff --git a/tests/neo.UnitTests/IO/Caching/UT_RelayCache.cs b/tests/neo.UnitTests/IO/Caching/UT_RelayCache.cs
index d442a018e9..659b7f5797 100644
--- a/tests/neo.UnitTests/IO/Caching/UT_RelayCache.cs
+++ b/tests/neo.UnitTests/IO/Caching/UT_RelayCache.cs
@@ -24,16 +24,15 @@ public void TestGetKeyForItem()
{
Version = 0,
Nonce = 1,
- Sender = UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01"),
SystemFee = 0,
NetworkFee = 0,
ValidUntilBlock = 100,
Attributes = Array.Empty(),
+ Signers = Array.Empty(),
Script = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04 },
- Witnesses = new Witness[0]
+ Witnesses = Array.Empty()
};
relayCache.Add(tx);
-
relayCache.Contains(tx).Should().BeTrue();
relayCache.TryGet(tx.Hash, out IInventory tmp).Should().BeTrue();
(tmp is Transaction).Should().BeTrue();
diff --git a/tests/neo.UnitTests/IO/UT_IOHelper.cs b/tests/neo.UnitTests/IO/UT_IOHelper.cs
index 1128270716..b126b7f485 100644
--- a/tests/neo.UnitTests/IO/UT_IOHelper.cs
+++ b/tests/neo.UnitTests/IO/UT_IOHelper.cs
@@ -119,6 +119,37 @@ public void TestAsSerializable()
}
}
+ [TestMethod]
+ public void TestCompression()
+ {
+ var data = new byte[] { 1, 2, 3, 4 };
+ var byteArray = Neo.IO.Helper.CompressLz4(data);
+ var result = Neo.IO.Helper.DecompressLz4(byteArray, byte.MaxValue);
+
+ CollectionAssert.AreEqual(result, data);
+
+ // Compress
+
+ data = new byte[255];
+ for (int x = 0; x < data.Length; x++) data[x] = 1;
+
+ byteArray = Neo.IO.Helper.CompressLz4(data);
+ result = Neo.IO.Helper.DecompressLz4(byteArray, byte.MaxValue);
+
+ Assert.IsTrue(byteArray.Length < result.Length);
+ CollectionAssert.AreEqual(result, data);
+
+ // Error max length
+
+ Assert.ThrowsException(() => Neo.IO.Helper.DecompressLz4(byteArray, byte.MaxValue - 1));
+ Assert.ThrowsException(() => Neo.IO.Helper.DecompressLz4(byteArray, -1));
+
+ // Error length
+
+ byteArray[0]++;
+ Assert.ThrowsException(() => Neo.IO.Helper.DecompressLz4(byteArray, byte.MaxValue));
+ }
+
[TestMethod]
public void TestAsSerializableArray()
{
diff --git a/tests/neo.UnitTests/Ledger/UT_Blockchain.cs b/tests/neo.UnitTests/Ledger/UT_Blockchain.cs
index 7e04dfe229..e4bf204d47 100644
--- a/tests/neo.UnitTests/Ledger/UT_Blockchain.cs
+++ b/tests/neo.UnitTests/Ledger/UT_Blockchain.cs
@@ -54,7 +54,7 @@ public class UT_Blockchain : TestKit
public void Initialize()
{
system = TestBlockchain.TheNeoSystem;
- Blockchain.Singleton.MemPool.TryAdd(txSample.Hash, txSample);
+ Blockchain.Singleton.MemPool.TryAdd(txSample, Blockchain.Singleton.GetSnapshot());
}
[TestMethod]
@@ -73,13 +73,13 @@ public void TestContainsTransaction()
[TestMethod]
public void TestGetCurrentBlockHash()
{
- Blockchain.Singleton.CurrentBlockHash.Should().Be(UInt256.Parse("0x3843c6d0dd2082a801cf3da0fe0e847ba8d5571e0606c5018f9a35ce49c55e18"));
+ Blockchain.Singleton.CurrentBlockHash.Should().Be(UInt256.Parse("0xecaee33262f1bc7c7c28f2b25b54a5d61d50670871f45c0c6fe755a40cbde4a8"));
}
[TestMethod]
public void TestGetCurrentHeaderHash()
{
- Blockchain.Singleton.CurrentHeaderHash.Should().Be(UInt256.Parse("0x3843c6d0dd2082a801cf3da0fe0e847ba8d5571e0606c5018f9a35ce49c55e18"));
+ Blockchain.Singleton.CurrentHeaderHash.Should().Be(UInt256.Parse("0xecaee33262f1bc7c7c28f2b25b54a5d61d50670871f45c0c6fe755a40cbde4a8"));
}
[TestMethod]
@@ -91,7 +91,7 @@ public void TestGetBlock()
[TestMethod]
public void TestGetBlockHash()
{
- Blockchain.Singleton.GetBlockHash(0).Should().Be(UInt256.Parse("0x3843c6d0dd2082a801cf3da0fe0e847ba8d5571e0606c5018f9a35ce49c55e18"));
+ Blockchain.Singleton.GetBlockHash(0).Should().Be(UInt256.Parse("0xecaee33262f1bc7c7c28f2b25b54a5d61d50670871f45c0c6fe755a40cbde4a8"));
Blockchain.Singleton.GetBlockHash(10).Should().BeNull();
}
@@ -109,33 +109,29 @@ public void TestValidTransaction()
var snapshot = Blockchain.Singleton.GetSnapshot();
var walletA = TestUtils.GenerateTestWallet();
- using (var unlockA = walletA.Unlock("123"))
- {
- var acc = walletA.CreateAccount();
-
- // Fake balance
+ using var unlockA = walletA.Unlock("123");
+ var acc = walletA.CreateAccount();
- var key = NativeContract.GAS.CreateStorageKey(20, acc.ScriptHash);
- var entry = snapshot.Storages.GetAndChange(key, () => new StorageItem(new AccountState()));
+ // Fake balance
- entry.GetInteroperable().Balance = 100_000_000 * NativeContract.GAS.Factor;
+ var key = new KeyBuilder(NativeContract.GAS.Id, 20).Add(acc.ScriptHash);
+ var entry = snapshot.Storages.GetAndChange(key, () => new StorageItem(new AccountState()));
+ entry.GetInteroperable().Balance = 100_000_000 * NativeContract.GAS.Factor;
+ snapshot.Commit();
- snapshot.Commit();
+ typeof(Blockchain)
+ .GetMethod("UpdateCurrentSnapshot", BindingFlags.Instance | BindingFlags.NonPublic)
+ .Invoke(Blockchain.Singleton, null);
- typeof(Blockchain)
- .GetMethod("UpdateCurrentSnapshot", BindingFlags.Instance | BindingFlags.NonPublic)
- .Invoke(Blockchain.Singleton, null);
+ // Make transaction
- // Make transaction
+ var tx = CreateValidTx(walletA, acc.ScriptHash, 0);
- var tx = CreateValidTx(walletA, acc.ScriptHash, 0);
+ senderProbe.Send(system.Blockchain, tx);
+ senderProbe.ExpectMsg(p => p.Result == VerifyResult.Succeed);
- senderProbe.Send(system.Blockchain, tx);
- senderProbe.ExpectMsg(p => p.Result == VerifyResult.Succeed);
-
- senderProbe.Send(system.Blockchain, tx);
- senderProbe.ExpectMsg(p => p.Result == VerifyResult.AlreadyExists);
- }
+ senderProbe.Send(system.Blockchain, tx);
+ senderProbe.ExpectMsg(p => p.Result == VerifyResult.AlreadyExists);
}
[TestMethod]
@@ -145,10 +141,10 @@ public void TestInvalidTransactionInPersist()
var tx = new Transaction()
{
Attributes = Array.Empty(),
+ Signers = Array.Empty(),
NetworkFee = 0,
Nonce = (uint)Environment.TickCount,
Script = new byte[] { 1 },
- Sender = UInt160.Zero,
SystemFee = 0,
ValidUntilBlock = Blockchain.GenesisBlock.Index + 1,
Version = 0,
@@ -184,9 +180,9 @@ private Transaction CreateValidTx(NEP6Wallet wallet, UInt160 account, uint nonce
{
new TransferOutput()
{
- AssetId = NativeContract.GAS.Hash,
- ScriptHash = account,
- Value = new BigDecimal(1,8)
+ AssetId = NativeContract.GAS.Hash,
+ ScriptHash = account,
+ Value = new BigDecimal(1,8)
}
},
account);
@@ -198,7 +194,6 @@ private Transaction CreateValidTx(NEP6Wallet wallet, UInt160 account, uint nonce
Assert.IsTrue(data.Completed);
tx.Witnesses = data.GetWitnesses();
-
return tx;
}
}
diff --git a/tests/neo.UnitTests/Ledger/UT_ContractState.cs b/tests/neo.UnitTests/Ledger/UT_ContractState.cs
index 40e4a6a23d..76c48c4c3e 100644
--- a/tests/neo.UnitTests/Ledger/UT_ContractState.cs
+++ b/tests/neo.UnitTests/Ledger/UT_ContractState.cs
@@ -84,7 +84,7 @@ public void TestDeserialize()
public void TestGetSize()
{
ISerializable newContract = contract;
- newContract.Size.Should().Be(239);
+ newContract.Size.Should().Be(265);
}
[TestMethod]
diff --git a/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs b/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs
index 4e96605b7b..106e60adc5 100644
--- a/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs
+++ b/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs
@@ -27,12 +27,20 @@ public void TransactionsRemoved(MemoryPoolTxRemovalReason reason, IEnumerable mock = new Mock();
- mock.Setup(p => p.VerifyForEachBlock(It.IsAny(), It.IsAny())).Returns(VerifyResult.Succeed);
- mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(VerifyResult.Succeed);
+ mock.Setup(p => p.VerifyForEachBlock(It.IsAny(), It.IsAny())).Returns(VerifyResult.Succeed);
+ mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(VerifyResult.Succeed);
mock.Object.Script = randomBytes;
- mock.Object.Sender = UInt160.Zero;
mock.Object.NetworkFee = fee;
mock.Object.Attributes = Array.Empty();
+ mock.Object.Signers = new Signer[] { new Signer() { Account = UInt160.Zero, Scopes = WitnessScope.FeeOnly } };
mock.Object.Witnesses = new[]
{
new Witness
@@ -97,13 +105,12 @@ private Transaction CreateTransactionWithFeeAndBalanceVerify(long fee)
var randomBytes = new byte[16];
random.NextBytes(randomBytes);
Mock mock = new Mock();
- UInt160 sender = UInt160.Zero;
- mock.Setup(p => p.VerifyForEachBlock(It.IsAny(), It.IsAny())).Returns((StoreView snapshot, BigInteger amount) => NativeContract.GAS.BalanceOf(snapshot, sender) >= amount + fee ? VerifyResult.Succeed : VerifyResult.InsufficientFunds);
- mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(VerifyResult.Succeed);
+ mock.Setup(p => p.VerifyForEachBlock(It.IsAny(), It.IsAny())).Returns((StoreView snapshot, TransactionVerificationContext context) => context.CheckTransaction(mock.Object, snapshot) ? VerifyResult.Succeed : VerifyResult.InsufficientFunds);
+ mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(VerifyResult.Succeed);
mock.Object.Script = randomBytes;
- mock.Object.Sender = sender;
mock.Object.NetworkFee = fee;
mock.Object.Attributes = Array.Empty();
+ mock.Object.Signers = new Signer[] { new Signer() { Account = UInt160.Zero, Scopes = WitnessScope.FeeOnly } };
mock.Object.Witnesses = new[]
{
new Witness
@@ -124,10 +131,11 @@ private Transaction CreateTransaction(long fee = -1)
private void AddTransactions(int count)
{
+ var snapshot = Blockchain.Singleton.GetSnapshot();
for (int i = 0; i < count; i++)
{
var txToAdd = CreateTransaction();
- _unit.TryAdd(txToAdd.Hash, txToAdd);
+ _unit.TryAdd(txToAdd, snapshot);
}
Console.WriteLine($"created {count} tx");
@@ -135,15 +143,17 @@ private void AddTransactions(int count)
private void AddTransaction(Transaction txToAdd)
{
- _unit.TryAdd(txToAdd.Hash, txToAdd);
+ var snapshot = Blockchain.Singleton.GetSnapshot();
+ _unit.TryAdd(txToAdd, snapshot);
}
private void AddTransactionsWithBalanceVerify(int count, long fee)
{
+ var snapshot = Blockchain.Singleton.GetSnapshot();
for (int i = 0; i < count; i++)
{
var txToAdd = CreateTransactionWithFeeAndBalanceVerify(fee);
- _unit.TryAdd(txToAdd.Hash, txToAdd);
+ _unit.TryAdd(txToAdd, snapshot);
}
Console.WriteLine($"created {count} tx");
@@ -223,7 +233,7 @@ public void BlockPersistAndReverificationWillAbandonTxAsBalanceTransfered()
SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, sender);
- ApplicationEngine applicationEngine = new ApplicationEngine(TriggerType.All, block, snapshot, (long)balance);
+ ApplicationEngine applicationEngine = ApplicationEngine.Create(TriggerType.All, block, snapshot, (long)balance);
NativeContract.GAS.Burn(applicationEngine, sender, balance);
NativeContract.GAS.Mint(applicationEngine, sender, txFee * 30); // Set the balance to meet 30 txs only
@@ -355,10 +365,11 @@ public void TestInvalidateAll()
[TestMethod]
public void TestContainsKey()
{
+ var snapshot = Blockchain.Singleton.GetSnapshot();
AddTransactions(10);
var txToAdd = CreateTransaction();
- _unit.TryAdd(txToAdd.Hash, txToAdd);
+ _unit.TryAdd(txToAdd, snapshot);
_unit.ContainsKey(txToAdd.Hash).Should().BeTrue();
_unit.InvalidateVerifiedTransactions();
_unit.ContainsKey(txToAdd.Hash).Should().BeTrue();
@@ -394,11 +405,12 @@ public void TestIEnumerableGetEnumerator()
[TestMethod]
public void TestGetVerifiedTransactions()
{
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var tx1 = CreateTransaction();
var tx2 = CreateTransaction();
- _unit.TryAdd(tx1.Hash, tx1);
+ _unit.TryAdd(tx1, snapshot);
_unit.InvalidateVerifiedTransactions();
- _unit.TryAdd(tx2.Hash, tx2);
+ _unit.TryAdd(tx2, snapshot);
IEnumerable enumerable = _unit.GetVerifiedTransactions();
enumerable.Count().Should().Be(1);
var enumerator = enumerable.GetEnumerator();
@@ -445,17 +457,19 @@ public void TestReVerifyTopUnverifiedTransactionsIfNeeded()
[TestMethod]
public void TestTryAdd()
{
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var tx1 = CreateTransaction();
- _unit.TryAdd(tx1.Hash, tx1).Should().BeTrue();
- _unit.TryAdd(tx1.Hash, tx1).Should().BeFalse();
- _unit2.TryAdd(tx1.Hash, tx1).Should().BeFalse();
+ _unit.TryAdd(tx1, snapshot).Should().Be(VerifyResult.Succeed);
+ _unit.TryAdd(tx1, snapshot).Should().NotBe(VerifyResult.Succeed);
+ _unit2.TryAdd(tx1, snapshot).Should().NotBe(VerifyResult.Succeed);
}
[TestMethod]
public void TestTryGetValue()
{
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var tx1 = CreateTransaction();
- _unit.TryAdd(tx1.Hash, tx1);
+ _unit.TryAdd(tx1, snapshot);
_unit.TryGetValue(tx1.Hash, out Transaction tx).Should().BeTrue();
tx.Should().BeEquivalentTo(tx1);
@@ -491,7 +505,7 @@ public void TestUpdatePoolForBlockPersisted()
var tx1 = CreateTransaction();
var tx2 = CreateTransaction();
Transaction[] transactions = { tx1, tx2 };
- _unit.TryAdd(tx1.Hash, tx1);
+ _unit.TryAdd(tx1, snapshot);
var block = new Block { Transactions = transactions };
diff --git a/tests/neo.UnitTests/Ledger/UT_PoolItem.cs b/tests/neo.UnitTests/Ledger/UT_PoolItem.cs
index 09b6e71fba..4c4c406c62 100644
--- a/tests/neo.UnitTests/Ledger/UT_PoolItem.cs
+++ b/tests/neo.UnitTests/Ledger/UT_PoolItem.cs
@@ -118,9 +118,9 @@ public static Transaction GenerateTx(long networkFee, int size, byte[] overrideS
{
Nonce = (uint)TestRandom.Next(),
Script = overrideScriptBytes ?? new byte[0],
- Sender = UInt160.Zero,
NetworkFee = networkFee,
Attributes = Array.Empty(),
+ Signers = Array.Empty(),
Witnesses = new[]
{
new Witness
@@ -132,7 +132,7 @@ public static Transaction GenerateTx(long networkFee, int size, byte[] overrideS
};
tx.Attributes.Length.Should().Be(0);
- tx.Cosigners.Count.Should().Be(0);
+ tx.Signers.Length.Should().Be(0);
int diff = size - tx.Size;
if (diff < 0) throw new ArgumentException();
diff --git a/tests/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs b/tests/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs
deleted file mode 100644
index cd8a5af463..0000000000
--- a/tests/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Moq;
-using Neo.Ledger;
-using Neo.Network.P2P.Payloads;
-using Neo.Persistence;
-using System;
-using System.Numerics;
-
-namespace Neo.UnitTests.Ledger
-{
- [TestClass]
- public class UT_SendersFeeMonitor
- {
- private Transaction CreateTransactionWithFee(long networkFee, long systemFee)
- {
- Random random = new Random();
- var randomBytes = new byte[16];
- random.NextBytes(randomBytes);
- Mock mock = new Mock();
- mock.Setup(p => p.VerifyForEachBlock(It.IsAny(), It.IsAny())).Returns(VerifyResult.Succeed);
- mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(VerifyResult.Succeed);
- mock.Object.Script = randomBytes;
- mock.Object.Sender = UInt160.Zero;
- mock.Object.NetworkFee = networkFee;
- mock.Object.SystemFee = systemFee;
- mock.Object.Attributes = Array.Empty();
- mock.Object.Witnesses = new[]
- {
- new Witness
- {
- InvocationScript = new byte[0],
- VerificationScript = new byte[0]
- }
- };
- return mock.Object;
- }
-
- [TestMethod]
- public void TestMemPoolSenderFee()
- {
- Transaction transaction = CreateTransactionWithFee(1, 2);
- SendersFeeMonitor sendersFeeMonitor = new SendersFeeMonitor();
- sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(0);
- sendersFeeMonitor.AddSenderFee(transaction);
- sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(3);
- sendersFeeMonitor.AddSenderFee(transaction);
- sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(6);
- sendersFeeMonitor.RemoveSenderFee(transaction);
- sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(3);
- sendersFeeMonitor.RemoveSenderFee(transaction);
- sendersFeeMonitor.GetSenderFee(transaction.Sender).Should().Be(0);
- }
- }
-}
diff --git a/tests/neo.UnitTests/Ledger/UT_TransactionState.cs b/tests/neo.UnitTests/Ledger/UT_TransactionState.cs
index 9446b954d2..e30416a136 100644
--- a/tests/neo.UnitTests/Ledger/UT_TransactionState.cs
+++ b/tests/neo.UnitTests/Ledger/UT_TransactionState.cs
@@ -61,7 +61,7 @@ public void TestDeserialize()
[TestMethod]
public void TestGetSize()
{
- ((ISerializable)origin).Size.Should().Be(61);
+ ((ISerializable)origin).Size.Should().Be(63);
}
}
}
diff --git a/tests/neo.UnitTests/Ledger/UT_TransactionVerificationContext.cs b/tests/neo.UnitTests/Ledger/UT_TransactionVerificationContext.cs
new file mode 100644
index 0000000000..a3636a4c91
--- /dev/null
+++ b/tests/neo.UnitTests/Ledger/UT_TransactionVerificationContext.cs
@@ -0,0 +1,71 @@
+using FluentAssertions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Neo.Ledger;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.SmartContract;
+using Neo.SmartContract.Native;
+using System;
+using System.Numerics;
+
+namespace Neo.UnitTests.Ledger
+{
+ [TestClass]
+ public class UT_TransactionVerificationContext
+ {
+ private static NeoSystem testBlockchain;
+
+ [ClassInitialize]
+ public static void TestSetup(TestContext ctx)
+ {
+ testBlockchain = TestBlockchain.TheNeoSystem;
+ }
+
+ private Transaction CreateTransactionWithFee(long networkFee, long systemFee)
+ {
+ Random random = new Random();
+ var randomBytes = new byte[16];
+ random.NextBytes(randomBytes);
+ Mock mock = new Mock();
+ mock.Setup(p => p.VerifyForEachBlock(It.IsAny(), It.IsAny())).Returns(VerifyResult.Succeed);
+ mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(VerifyResult.Succeed);
+ mock.Object.Script = randomBytes;
+ mock.Object.NetworkFee = networkFee;
+ mock.Object.SystemFee = systemFee;
+ mock.Object.Signers = new[] { new Signer { Account = UInt160.Zero } };
+ mock.Object.Attributes = Array.Empty();
+ mock.Object.Witnesses = new[]
+ {
+ new Witness
+ {
+ InvocationScript = new byte[0],
+ VerificationScript = new byte[0]
+ }
+ };
+ return mock.Object;
+ }
+
+ [TestMethod]
+ public void TestTransactionSenderFee()
+ {
+ var snapshot = Blockchain.Singleton.GetSnapshot();
+ ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, long.MaxValue);
+ BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, UInt160.Zero);
+ NativeContract.GAS.Burn(engine, UInt160.Zero, balance);
+ NativeContract.GAS.Mint(engine, UInt160.Zero, 8);
+
+ TransactionVerificationContext verificationContext = new TransactionVerificationContext();
+ var tx = CreateTransactionWithFee(1, 2);
+ verificationContext.CheckTransaction(tx, snapshot).Should().BeTrue();
+ verificationContext.AddTransaction(tx);
+ verificationContext.CheckTransaction(tx, snapshot).Should().BeTrue();
+ verificationContext.AddTransaction(tx);
+ verificationContext.CheckTransaction(tx, snapshot).Should().BeFalse();
+ verificationContext.RemoveTransaction(tx);
+ verificationContext.CheckTransaction(tx, snapshot).Should().BeTrue();
+ verificationContext.AddTransaction(tx);
+ verificationContext.CheckTransaction(tx, snapshot).Should().BeFalse();
+ }
+ }
+}
diff --git a/tests/neo.UnitTests/Ledger/UT_TrimmedBlock.cs b/tests/neo.UnitTests/Ledger/UT_TrimmedBlock.cs
index b74a0b2a9e..c8b0e30fb8 100644
--- a/tests/neo.UnitTests/Ledger/UT_TrimmedBlock.cs
+++ b/tests/neo.UnitTests/Ledger/UT_TrimmedBlock.cs
@@ -35,7 +35,7 @@ public static TrimmedBlock GetTrimmedBlockWithNoTransaction()
public void TestGetIsBlock()
{
TrimmedBlock block = GetTrimmedBlockWithNoTransaction();
- block.Hashes = new UInt256[] { TestUtils.GetTransaction().Hash };
+ block.Hashes = new UInt256[] { TestUtils.GetTransaction(UInt160.Zero).Hash };
block.IsBlock.Should().BeTrue();
}
@@ -43,7 +43,7 @@ public void TestGetIsBlock()
public void TestGetBlock()
{
var snapshot = Blockchain.Singleton.GetSnapshot();
- var tx1 = TestUtils.GetTransaction();
+ var tx1 = TestUtils.GetTransaction(UInt160.Zero);
tx1.Script = new byte[] { 0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,
@@ -53,7 +53,7 @@ public void TestGetBlock()
Transaction = tx1,
BlockIndex = 1
};
- var tx2 = TestUtils.GetTransaction();
+ var tx2 = TestUtils.GetTransaction(UInt160.Zero);
tx2.Script = new byte[] { 0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,
@@ -89,7 +89,7 @@ public void TestGetHeader()
public void TestGetSize()
{
TrimmedBlock tblock = GetTrimmedBlockWithNoTransaction();
- tblock.Hashes = new UInt256[] { TestUtils.GetTransaction().Hash };
+ tblock.Hashes = new UInt256[] { TestUtils.GetTransaction(UInt160.Zero).Hash };
tblock.Size.Should().Be(146);
}
@@ -97,7 +97,7 @@ public void TestGetSize()
public void TestDeserialize()
{
TrimmedBlock tblock = GetTrimmedBlockWithNoTransaction();
- tblock.Hashes = new UInt256[] { TestUtils.GetTransaction().Hash };
+ tblock.Hashes = new UInt256[] { TestUtils.GetTransaction(UInt160.Zero).Hash };
var newBlock = new TrimmedBlock();
using (MemoryStream ms = new MemoryStream(1024))
using (BinaryWriter writer = new BinaryWriter(ms))
@@ -119,7 +119,7 @@ public void TestDeserialize()
public void TestClone()
{
TrimmedBlock tblock = GetTrimmedBlockWithNoTransaction();
- tblock.Hashes = new UInt256[] { TestUtils.GetTransaction().Hash };
+ tblock.Hashes = new UInt256[] { TestUtils.GetTransaction(UInt160.Zero).Hash };
ICloneable cloneable = tblock;
var clonedBlock = cloneable.Clone();
clonedBlock.ToJson().ToString().Should().Be(tblock.ToJson().ToString());
@@ -129,7 +129,7 @@ public void TestClone()
public void TestFromReplica()
{
TrimmedBlock tblock = GetTrimmedBlockWithNoTransaction();
- tblock.Hashes = new UInt256[] { TestUtils.GetTransaction().Hash };
+ tblock.Hashes = new UInt256[] { TestUtils.GetTransaction(UInt160.Zero).Hash };
ICloneable cloneable = new TrimmedBlock();
cloneable.FromReplica(tblock);
((TrimmedBlock)cloneable).ToJson().ToString().Should().Be(tblock.ToJson().ToString());
diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Block.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Block.cs
index 1efd90a3a8..0d5208de5a 100644
--- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Block.cs
+++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Block.cs
@@ -56,10 +56,10 @@ public void Size_Get_1_Transaction()
uut.Transactions = new[]
{
- TestUtils.GetTransaction()
+ TestUtils.GetTransaction(UInt160.Zero)
};
- uut.Size.Should().Be(165);
+ uut.Size.Should().Be(167);
}
[TestMethod]
@@ -70,12 +70,12 @@ public void Size_Get_3_Transaction()
uut.Transactions = new[]
{
- TestUtils.GetTransaction(),
- TestUtils.GetTransaction(),
- TestUtils.GetTransaction()
+ TestUtils.GetTransaction(UInt160.Zero),
+ TestUtils.GetTransaction(UInt160.Zero),
+ TestUtils.GetTransaction(UInt160.Zero)
};
- uut.Size.Should().Be(267);
+ uut.Size.Should().Be(273);
}
[TestMethod]
@@ -84,7 +84,7 @@ public void Serialize()
UInt256 val256 = UInt256.Zero;
TestUtils.SetupBlockWithValues(uut, val256, out var _, out var _, out var _, out var _, out var _, out var _, 1);
- var hex = "000000000000000000000000000000000000000000000000000000000000000000000000bc72014eb4f1fcdd27831b79c42ffa71e1b949086a97c87654a644585dd616f6e913ff854c0000000000000000000000000000000000000000000000000000000100011102000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000";
+ var hex = "000000000000000000000000000000000000000000000000000000000000000000000000add6632f6f3d29cdf94555bb191fb5296683e5446f9937c56bb94c8608023044e913ff854c00000000000000000000000000000000000000000000000000000001000111020000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000001000100010000";
uut.ToArray().ToHexString().Should().Be(hex);
}
@@ -94,7 +94,7 @@ public void Deserialize()
UInt256 val256 = UInt256.Zero;
TestUtils.SetupBlockWithValues(new Block(), val256, out var merkRoot, out var val160, out var timestampVal, out var indexVal, out var scriptVal, out var transactionsVal, 1);
- var hex = "000000000000000000000000000000000000000000000000000000000000000000000000bc72014eb4f1fcdd27831b79c42ffa71e1b949086a97c87654a644585dd616f6e913ff854c0000000000000000000000000000000000000000000000000000000100011102000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000";
+ var hex = "000000000000000000000000000000000000000000000000000000000000000000000000add6632f6f3d29cdf94555bb191fb5296683e5446f9937c56bb94c8608023044e913ff854c00000000000000000000000000000000000000000000000000000001000111020000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000001000100010000";
using (MemoryStream ms = new MemoryStream(hex.HexToBytes(), false))
using (BinaryReader reader = new BinaryReader(ms))
@@ -199,11 +199,11 @@ public void ToJson()
JObject jObj = uut.ToJson();
jObj.Should().NotBeNull();
- jObj["hash"].AsString().Should().Be("0xac84cebc5825cbe78941b301789bc43e8906bb9d86edd80cc94591088a26d9cc");
- jObj["size"].AsNumber().Should().Be(165);
+ jObj["hash"].AsString().Should().Be("0x9a164d5b9a1ab8745c97dbaaaef8eb30b0d80a00205acdc82daf502bee69bc20");
+ jObj["size"].AsNumber().Should().Be(167);
jObj["version"].AsNumber().Should().Be(0);
jObj["previousblockhash"].AsString().Should().Be("0x0000000000000000000000000000000000000000000000000000000000000000");
- jObj["merkleroot"].AsString().Should().Be("0xf616d65d5844a65476c8976a0849b9e171fa2fc4791b8327ddfcf1b44e0172bc");
+ jObj["merkleroot"].AsString().Should().Be("0x44300208864cb96bc537996f44e5836629b51f19bb5545f9cd293d6f2f63d6ad");
jObj["time"].AsNumber().Should().Be(328665601001);
jObj["index"].AsNumber().Should().Be(0);
jObj["nextconsensus"].AsString().Should().Be("NKuyBkoGdZZSLyPbJEetheRhMjeznFZszf");
@@ -214,8 +214,8 @@ public void ToJson()
jObj["tx"].Should().NotBeNull();
JArray txObj = (JArray)jObj["tx"];
- txObj[0]["hash"].AsString().Should().Be("0x5f9b7409b6cf21fb0bf63c3890f62cccfe5fb9c3277ea33935e0a09f4255407c");
- txObj[0]["size"].AsNumber().Should().Be(51);
+ txObj[0]["hash"].AsString().Should().Be("0x995ce8ff19c30f6b0d6b03e5ed8bd30b08027c92177923782d3a64f573421931");
+ txObj[0]["size"].AsNumber().Should().Be(53);
txObj[0]["version"].AsNumber().Should().Be(0);
((JArray)txObj[0]["attributes"]).Count.Should().Be(0);
txObj[0]["netfee"].AsString().Should().Be("0");
diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Cosigner.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Signers.cs
similarity index 66%
rename from tests/neo.UnitTests/Network/P2P/Payloads/UT_Cosigner.cs
rename to tests/neo.UnitTests/Network/P2P/Payloads/UT_Signers.cs
index 22ca14cb82..82799f233f 100644
--- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Cosigner.cs
+++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Signers.cs
@@ -7,21 +7,21 @@
namespace Neo.UnitTests.Network.P2P.Payloads
{
[TestClass]
- public class UT_Cosigner
+ public class UT_Signers
{
[TestMethod]
public void Serialize_Deserialize_Global()
{
- var attr = new Cosigner()
+ var attr = new Signer()
{
Scopes = WitnessScope.Global,
Account = UInt160.Zero
};
- var hex = "01000000000000000000000000000000000000000000";
+ var hex = "000000000000000000000000000000000000000080";
attr.ToArray().ToHexString().Should().Be(hex);
- var copy = hex.HexToBytes().AsSerializable();
+ var copy = hex.HexToBytes().AsSerializable();
Assert.AreEqual(attr.Scopes, copy.Scopes);
Assert.AreEqual(attr.Account, copy.Account);
@@ -30,16 +30,16 @@ public void Serialize_Deserialize_Global()
[TestMethod]
public void Serialize_Deserialize_CalledByEntry()
{
- var attr = new Cosigner()
+ var attr = new Signer()
{
Scopes = WitnessScope.CalledByEntry,
Account = UInt160.Zero
};
- var hex = "01000000000000000000000000000000000000000001";
+ var hex = "000000000000000000000000000000000000000001";
attr.ToArray().ToHexString().Should().Be(hex);
- var copy = hex.HexToBytes().AsSerializable();
+ var copy = hex.HexToBytes().AsSerializable();
Assert.AreEqual(attr.Scopes, copy.Scopes);
Assert.AreEqual(attr.Account, copy.Account);
@@ -48,17 +48,17 @@ public void Serialize_Deserialize_CalledByEntry()
[TestMethod]
public void Serialize_Deserialize_CustomContracts()
{
- var attr = new Cosigner()
+ var attr = new Signer()
{
Scopes = WitnessScope.CustomContracts,
AllowedContracts = new[] { UInt160.Zero },
Account = UInt160.Zero
};
- var hex = "01000000000000000000000000000000000000000010010000000000000000000000000000000000000000";
+ var hex = "000000000000000000000000000000000000000010010000000000000000000000000000000000000000";
attr.ToArray().ToHexString().Should().Be(hex);
- var copy = hex.HexToBytes().AsSerializable();
+ var copy = hex.HexToBytes().AsSerializable();
Assert.AreEqual(attr.Scopes, copy.Scopes);
CollectionAssert.AreEqual(attr.AllowedContracts, copy.AllowedContracts);
@@ -68,17 +68,17 @@ public void Serialize_Deserialize_CustomContracts()
[TestMethod]
public void Serialize_Deserialize_CustomGroups()
{
- var attr = new Cosigner()
+ var attr = new Signer()
{
Scopes = WitnessScope.CustomGroups,
AllowedGroups = new[] { ECPoint.Parse("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c", ECCurve.Secp256r1) },
Account = UInt160.Zero
};
- var hex = "010000000000000000000000000000000000000000200103b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c";
+ var hex = "0000000000000000000000000000000000000000200103b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c";
attr.ToArray().ToHexString().Should().Be(hex);
- var copy = hex.HexToBytes().AsSerializable();
+ var copy = hex.HexToBytes().AsSerializable();
Assert.AreEqual(attr.Scopes, copy.Scopes);
CollectionAssert.AreEqual(attr.AllowedGroups, copy.AllowedGroups);
@@ -88,54 +88,54 @@ public void Serialize_Deserialize_CustomGroups()
[TestMethod]
public void Json_Global()
{
- var attr = new Cosigner()
+ var attr = new Signer()
{
Scopes = WitnessScope.Global,
Account = UInt160.Zero
};
- var json = "{\"type\":\"Cosigner\",\"account\":\"0x0000000000000000000000000000000000000000\",\"scopes\":\"Global\"}";
+ var json = "{\"account\":\"0x0000000000000000000000000000000000000000\",\"scopes\":\"Global\"}";
attr.ToJson().ToString().Should().Be(json);
}
[TestMethod]
public void Json_CalledByEntry()
{
- var attr = new Cosigner()
+ var attr = new Signer()
{
Scopes = WitnessScope.CalledByEntry,
Account = UInt160.Zero
};
- var json = "{\"type\":\"Cosigner\",\"account\":\"0x0000000000000000000000000000000000000000\",\"scopes\":\"CalledByEntry\"}";
+ var json = "{\"account\":\"0x0000000000000000000000000000000000000000\",\"scopes\":\"CalledByEntry\"}";
attr.ToJson().ToString().Should().Be(json);
}
[TestMethod]
public void Json_CustomContracts()
{
- var attr = new Cosigner()
+ var attr = new Signer()
{
Scopes = WitnessScope.CustomContracts,
AllowedContracts = new[] { UInt160.Zero },
Account = UInt160.Zero
};
- var json = "{\"type\":\"Cosigner\",\"account\":\"0x0000000000000000000000000000000000000000\",\"scopes\":\"CustomContracts\",\"allowedcontracts\":[\"0x0000000000000000000000000000000000000000\"]}";
+ var json = "{\"account\":\"0x0000000000000000000000000000000000000000\",\"scopes\":\"CustomContracts\",\"allowedcontracts\":[\"0x0000000000000000000000000000000000000000\"]}";
attr.ToJson().ToString().Should().Be(json);
}
[TestMethod]
public void Json_CustomGroups()
{
- var attr = new Cosigner()
+ var attr = new Signer()
{
Scopes = WitnessScope.CustomGroups,
AllowedGroups = new[] { ECPoint.Parse("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c", ECCurve.Secp256r1) },
Account = UInt160.Zero
};
- var json = "{\"type\":\"Cosigner\",\"account\":\"0x0000000000000000000000000000000000000000\",\"scopes\":\"CustomGroups\",\"allowedgroups\":[\"03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c\"]}";
+ var json = "{\"account\":\"0x0000000000000000000000000000000000000000\",\"scopes\":\"CustomGroups\",\"allowedgroups\":[\"03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c\"]}";
attr.ToJson().ToString().Should().Be(json);
}
}
diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
index 61ea913867..e6f7c3414a 100644
--- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
+++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
@@ -64,7 +64,7 @@ public void Gas_Set()
public void Size_Get()
{
uut.Script = TestUtils.GetByteArray(32, 0x42);
- uut.Sender = UInt160.Zero;
+ uut.Signers = Array.Empty();
uut.Attributes = Array.Empty();
uut.Witnesses = new[]
{
@@ -78,7 +78,7 @@ public void Size_Get()
uut.Version.Should().Be(0);
uut.Script.Length.Should().Be(32);
uut.Script.GetVarSize().Should().Be(33);
- uut.Size.Should().Be(82);
+ uut.Size.Should().Be(63);
}
[TestMethod]
@@ -145,7 +145,7 @@ public void FeeIsMultiSigContract()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
- using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
+ using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
@@ -158,8 +158,8 @@ public void FeeIsMultiSigContract()
var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot);
Assert.AreEqual(2000810, verificationGas);
- Assert.AreEqual(367000, sizeGas);
- Assert.AreEqual(2367810, tx.NetworkFee);
+ Assert.AreEqual(347000, sizeGas);
+ Assert.AreEqual(2347810, tx.NetworkFee);
}
}
@@ -200,7 +200,7 @@ public void FeeIsSignatureContractDetailed()
Assert.IsNull(tx.Witnesses);
// check pre-computed network fee (already guessing signature sizes)
- tx.NetworkFee.Should().Be(1264390);
+ tx.NetworkFee.Should().Be(1244390L);
// ----
// Sign
@@ -227,7 +227,7 @@ public void FeeIsSignatureContractDetailed()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
- using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
+ using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
@@ -242,32 +242,32 @@ public void FeeIsSignatureContractDetailed()
// ------------------
// check tx_size cost
// ------------------
- Assert.AreEqual(264, tx.Size);
+ Assert.AreEqual(244, tx.Size);
// will verify tx size, step by step
// Part I
- Assert.AreEqual(45, Transaction.HeaderSize);
+ Assert.AreEqual(25, Transaction.HeaderSize);
// Part II
- Assert.AreEqual(23, tx.Attributes.GetVarSize());
- Assert.AreEqual(1, tx.Attributes.Length);
- Assert.AreEqual(1, tx.Cosigners.Count);
- Assert.AreEqual(23, tx.Cosigners.Values.ToArray().GetVarSize());
+ Assert.AreEqual(1, tx.Attributes.GetVarSize());
+ Assert.AreEqual(0, tx.Attributes.Length);
+ Assert.AreEqual(1, tx.Signers.Length);
// Note that Data size and Usage size are different (because of first byte on GetVarSize())
- Assert.AreEqual(22, tx.Cosigners.Values.First().Size);
+ Assert.AreEqual(22, tx.Signers.GetVarSize());
// Part III
Assert.AreEqual(86, tx.Script.GetVarSize());
// Part IV
Assert.AreEqual(110, tx.Witnesses.GetVarSize());
// I + II + III + IV
- Assert.AreEqual(45 + 23 + 86 + 110, tx.Size);
+ Assert.AreEqual(25 + 22 + 1 + 86 + 110, tx.Size);
Assert.AreEqual(1000, NativeContract.Policy.GetFeePerByte(snapshot));
var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot);
- Assert.AreEqual(264000, sizeGas);
- // final check on sum: verification_cost + tx_size
- Assert.AreEqual(1264390, verificationGas + sizeGas);
+ // final check: verification_cost and tx_size
+ Assert.AreEqual(244000, sizeGas);
+ Assert.AreEqual(1000390, verificationGas);
+
// final assert
Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas);
}
@@ -301,14 +301,14 @@ public void FeeIsSignatureContract_TestScope_Global()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
- System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value;
+ BigInteger value = (new BigDecimal(1, 8)).Value;
sb.EmitAppCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
}
// trying global scope
- var cosigners = new Cosigner[]{ new Cosigner
+ var signers = new Signer[]{ new Signer
{
Account = acc.ScriptHash,
Scopes = WitnessScope.Global
@@ -316,7 +316,7 @@ public void FeeIsSignatureContract_TestScope_Global()
// using this...
- var tx = wallet.MakeTransaction(script, acc.ScriptHash, cosigners);
+ var tx = wallet.MakeTransaction(script, acc.ScriptHash, signers);
Assert.IsNotNull(tx);
Assert.IsNull(tx.Witnesses);
@@ -340,7 +340,7 @@ public void FeeIsSignatureContract_TestScope_Global()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
- using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
+ using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
@@ -353,7 +353,7 @@ public void FeeIsSignatureContract_TestScope_Global()
// get sizeGas
var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot);
// final check on sum: verification_cost + tx_size
- Assert.AreEqual(1264390, verificationGas + sizeGas);
+ Assert.AreEqual(1244390, verificationGas + sizeGas);
// final assert
Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas);
}
@@ -387,14 +387,14 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
- System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value;
+ BigInteger value = (new BigDecimal(1, 8)).Value;
sb.EmitAppCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
}
// trying global scope
- var cosigners = new Cosigner[]{ new Cosigner
+ var signers = new Signer[]{ new Signer
{
Account = acc.ScriptHash,
Scopes = WitnessScope.CustomContracts,
@@ -403,7 +403,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS()
// using this...
- var tx = wallet.MakeTransaction(script, acc.ScriptHash, cosigners);
+ var tx = wallet.MakeTransaction(script, acc.ScriptHash, signers);
Assert.IsNotNull(tx);
Assert.IsNull(tx.Witnesses);
@@ -427,7 +427,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
- using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
+ using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
@@ -440,7 +440,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS()
// get sizeGas
var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot);
// final check on sum: verification_cost + tx_size
- Assert.AreEqual(1285390, verificationGas + sizeGas);
+ Assert.AreEqual(1265390, verificationGas + sizeGas);
// final assert
Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas);
}
@@ -481,7 +481,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS()
}
// trying CalledByEntry together with GAS
- var cosigners = new Cosigner[]{ new Cosigner
+ var signers = new Signer[]{ new Signer
{
Account = acc.ScriptHash,
// This combination is supposed to actually be an OR,
@@ -493,7 +493,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS()
// using this...
- var tx = wallet.MakeTransaction(script, acc.ScriptHash, cosigners);
+ var tx = wallet.MakeTransaction(script, acc.ScriptHash, signers);
Assert.IsNotNull(tx);
Assert.IsNull(tx.Witnesses);
@@ -517,7 +517,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
- using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
+ using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
@@ -530,7 +530,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS()
// get sizeGas
var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot);
// final check on sum: verification_cost + tx_size
- Assert.AreEqual(1285390, verificationGas + sizeGas);
+ Assert.AreEqual(1265390, verificationGas + sizeGas);
// final assert
Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas);
}
@@ -569,7 +569,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_FAULT()
}
// trying global scope
- var cosigners = new Cosigner[]{ new Cosigner
+ var signers = new Signer[]{ new Signer
{
Account = acc.ScriptHash,
Scopes = WitnessScope.CustomContracts,
@@ -581,7 +581,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_FAULT()
// expects FAULT on execution of 'transfer' Application script
// due to lack of a valid witness validation
Transaction tx = null;
- Assert.ThrowsException(() => tx = wallet.MakeTransaction(script, acc.ScriptHash, cosigners));
+ Assert.ThrowsException(() => tx = wallet.MakeTransaction(script, acc.ScriptHash, signers));
Assert.IsNull(tx);
}
}
@@ -614,14 +614,14 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
- System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value;
+ BigInteger value = (new BigDecimal(1, 8)).Value;
sb.EmitAppCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
}
// trying two custom hashes, for same target account
- var cosigners = new Cosigner[]{ new Cosigner
+ var signers = new Signer[]{ new Signer
{
Account = acc.ScriptHash,
Scopes = WitnessScope.CustomContracts,
@@ -630,7 +630,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS()
// using this...
- var tx = wallet.MakeTransaction(script, acc.ScriptHash, cosigners);
+ var tx = wallet.MakeTransaction(script, acc.ScriptHash, signers);
Assert.IsNotNull(tx);
Assert.IsNull(tx.Witnesses);
@@ -648,9 +648,9 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS()
// only a single witness should exist
tx.Witnesses.Length.Should().Be(1);
// no attributes must exist
- tx.Attributes.Length.Should().Be(1);
+ tx.Attributes.Length.Should().Be(0);
// one cosigner must exist
- tx.Cosigners.Count.Should().Be(1);
+ tx.Signers.Length.Should().Be(1);
// Fast check
Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee));
@@ -659,7 +659,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
- using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
+ using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
@@ -672,7 +672,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS()
// get sizeGas
var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot);
// final check on sum: verification_cost + tx_size
- Assert.AreEqual(1305390, verificationGas + sizeGas);
+ Assert.AreEqual(1285390, verificationGas + sizeGas);
// final assert
Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas);
}
@@ -704,7 +704,7 @@ public void FeeIsSignatureContract_TestScope_NoScopeFAULT()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
- System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value;
+ BigInteger value = (new BigDecimal(1, 8)).Value;
sb.EmitAppCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
@@ -713,12 +713,19 @@ public void FeeIsSignatureContract_TestScope_NoScopeFAULT()
// trying with no scope
var attributes = new TransactionAttribute[] { };
+ var signers = new Signer[]{ new Signer
+ {
+ Account = acc.ScriptHash,
+ Scopes = (WitnessScope) 0xFF,
+ AllowedContracts = new[] { NativeContract.NEO.Hash, NativeContract.GAS.Hash }
+ } };
+
// using this...
// expects FAULT on execution of 'transfer' Application script
// due to lack of a valid witness validation
Transaction tx = null;
- Assert.ThrowsException(() => tx = wallet.MakeTransaction(script, acc.ScriptHash, attributes));
+ Assert.ThrowsException(() => tx = wallet.MakeTransaction(script, acc.ScriptHash, signers, attributes));
Assert.IsNull(tx);
}
}
@@ -731,13 +738,12 @@ public void Transaction_Reverify_Hashes_Length_Unequal_To_Witnesses_Length()
{
Version = 0x00,
Nonce = 0x01020304,
- Sender = UInt160.Zero,
SystemFee = (long)BigInteger.Pow(10, 8), // 1 GAS
NetworkFee = 0x0000000000000001,
ValidUntilBlock = 0x01020304,
- Attributes = new[]
- {
- new Cosigner
+ Attributes = Array.Empty(),
+ Signers = new[]{
+ new Signer
{
Account = UInt160.Parse("0x0001020304050607080900010203040506070809"),
Scopes = WitnessScope.Global
@@ -747,8 +753,8 @@ public void Transaction_Reverify_Hashes_Length_Unequal_To_Witnesses_Length()
Witnesses = new Witness[0] { }
};
UInt160[] hashes = txSimple.GetScriptHashesForVerifying(snapshot);
- Assert.AreEqual(2, hashes.Length);
- Assert.AreNotEqual(VerifyResult.Succeed, txSimple.VerifyForEachBlock(snapshot, BigInteger.Zero));
+ Assert.AreEqual(1, hashes.Length);
+ Assert.AreNotEqual(VerifyResult.Succeed, txSimple.VerifyForEachBlock(snapshot, new TransactionVerificationContext()));
}
[TestMethod]
@@ -759,10 +765,10 @@ public void Transaction_Serialize_Deserialize_Simple()
{
Version = 0x00,
Nonce = 0x01020304,
- Sender = UInt160.Zero,
SystemFee = (long)BigInteger.Pow(10, 8), // 1 GAS
NetworkFee = 0x0000000000000001,
ValidUntilBlock = 0x01020304,
+ Signers = new Signer[] { new Signer() { Account = UInt160.Zero } },
Attributes = Array.Empty(),
Script = new byte[] { (byte)OpCode.PUSH1 },
Witnesses = new Witness[0] { }
@@ -771,15 +777,16 @@ public void Transaction_Serialize_Deserialize_Simple()
byte[] sTx = txSimple.ToArray();
// detailed hexstring info (basic checking)
- sTx.ToHexString().Should().Be("00" + // version
- "04030201" + // nonce
- "0000000000000000000000000000000000000000" + // sender
- "00e1f50500000000" + // system fee (1 GAS)
- "0100000000000000" + // network fee (1 satoshi)
- "04030201" + // timelimit
- "00" + // no attributes
- "0111" + // push1 script
- "00"); // no witnesses
+ sTx.ToHexString().Should().Be(
+ "00" + // version
+ "04030201" + // nonce
+ "00e1f50500000000" + // system fee (1 GAS)
+ "0100000000000000" + // network fee (1 satoshi)
+ "04030201" + // timelimit
+ "01000000000000000000000000000000000000000000" + // empty signer
+ "00" + // no attributes
+ "0111" + // push1 script
+ "00"); // no witnesses
// try to deserialize
Transaction tx2 = Neo.IO.Helper.AsSerializable(sTx);
@@ -791,7 +798,14 @@ public void Transaction_Serialize_Deserialize_Simple()
tx2.NetworkFee.Should().Be(0x0000000000000001);
tx2.ValidUntilBlock.Should().Be(0x01020304);
tx2.Attributes.Should().BeEquivalentTo(new TransactionAttribute[0] { });
- tx2.Cosigners.Should().BeEquivalentTo(new Cosigner[0] { });
+ tx2.Signers.Should().BeEquivalentTo(new Signer[] {
+ new Signer()
+ {
+ Account = UInt160.Zero,
+ AllowedContracts = Array.Empty(),
+ AllowedGroups = Array.Empty() }
+ }
+ );
tx2.Script.Should().BeEquivalentTo(new byte[] { (byte)OpCode.PUSH1 });
tx2.Witnesses.Should().BeEquivalentTo(new Witness[0] { });
}
@@ -805,18 +819,18 @@ public void Transaction_Serialize_Deserialize_DistinctCosigners()
{
Version = 0x00,
Nonce = 0x01020304,
- Sender = UInt160.Zero,
SystemFee = (long)BigInteger.Pow(10, 8), // 1 GAS
NetworkFee = 0x0000000000000001,
ValidUntilBlock = 0x01020304,
- Attributes = new[]
+ Attributes = Array.Empty(),
+ Signers = new Signer[]
{
- new Cosigner
+ new Signer()
{
Account = UInt160.Parse("0x0001020304050607080900010203040506070809"),
Scopes = WitnessScope.Global
},
- new Cosigner
+ new Signer()
{
Account = UInt160.Parse("0x0001020304050607080900010203040506070809"), // same account as above
Scopes = WitnessScope.CalledByEntry // different scope, but still, same account (cannot do that)
@@ -829,7 +843,7 @@ public void Transaction_Serialize_Deserialize_DistinctCosigners()
byte[] sTx = txDoubleCosigners.ToArray();
// no need for detailed hexstring here (see basic tests for it)
- sTx.ToHexString().Should().Be("0004030201000000000000000000000000000000000000000000e1f50500000000010000000000000004030201020109080706050403020100090807060504030201000001090807060504030201000908070605040302010001011100");
+ sTx.ToHexString().Should().Be("000403020100e1f505000000000100000000000000040302010209080706050403020100090807060504030201008009080706050403020100090807060504030201000100011100");
// back to transaction (should fail, due to non-distinct cosigners)
Transaction tx2 = null;
@@ -850,15 +864,16 @@ public void Transaction_Serialize_Deserialize_MaxSizeCosigners()
// --------------------------------------
// this should pass (respecting max size)
- var cosigners1 = new Cosigner[maxCosigners];
+ var cosigners1 = new Signer[maxCosigners];
for (int i = 0; i < cosigners1.Length; i++)
{
string hex = i.ToString("X4");
while (hex.Length < 40)
hex = hex.Insert(0, "0");
- cosigners1[i] = new Cosigner
+ cosigners1[i] = new Signer
{
- Account = UInt160.Parse(hex)
+ Account = UInt160.Parse(hex),
+ Scopes = WitnessScope.CalledByEntry
};
}
@@ -866,11 +881,11 @@ public void Transaction_Serialize_Deserialize_MaxSizeCosigners()
{
Version = 0x00,
Nonce = 0x01020304,
- Sender = UInt160.Zero,
SystemFee = (long)BigInteger.Pow(10, 8), // 1 GAS
NetworkFee = 0x0000000000000001,
ValidUntilBlock = 0x01020304,
- Attributes = cosigners1, // max + 1 (should fail)
+ Attributes = Array.Empty(),
+ Signers = cosigners1, // max + 1 (should fail)
Script = new byte[] { (byte)OpCode.PUSH1 },
Witnesses = new Witness[0] { }
};
@@ -884,13 +899,13 @@ public void Transaction_Serialize_Deserialize_MaxSizeCosigners()
// ----------------------------
// this should fail (max + 1)
- var cosigners = new Cosigner[maxCosigners + 1];
+ var cosigners = new Signer[maxCosigners + 1];
for (var i = 0; i < maxCosigners + 1; i++)
{
string hex = i.ToString("X4");
while (hex.Length < 40)
hex = hex.Insert(0, "0");
- cosigners[i] = new Cosigner
+ cosigners[i] = new Signer
{
Account = UInt160.Parse(hex)
};
@@ -900,11 +915,11 @@ public void Transaction_Serialize_Deserialize_MaxSizeCosigners()
{
Version = 0x00,
Nonce = 0x01020304,
- Sender = UInt160.Zero,
SystemFee = (long)BigInteger.Pow(10, 8), // 1 GAS
NetworkFee = 0x0000000000000001,
ValidUntilBlock = 0x01020304,
- Attributes = cosigners, // max + 1 (should fail)
+ Attributes = Array.Empty(),
+ Signers = cosigners, // max + 1 (should fail)
Script = new byte[] { (byte)OpCode.PUSH1 },
Witnesses = new Witness[0] { }
};
@@ -920,12 +935,12 @@ public void Transaction_Serialize_Deserialize_MaxSizeCosigners()
}
[TestMethod]
- public void FeeIsSignatureContract_TestScope_Global_Default()
+ public void FeeIsSignatureContract_TestScope_FeeOnly_Default()
{
// Global is supposed to be default
- Cosigner cosigner = new Cosigner();
- cosigner.Scopes.Should().Be(WitnessScope.Global);
+ Signer cosigner = new Signer();
+ cosigner.Scopes.Should().Be(WitnessScope.FeeOnly);
var wallet = TestUtils.GenerateTestWallet();
var snapshot = Blockchain.Singleton.GetSnapshot();
@@ -952,21 +967,25 @@ public void FeeIsSignatureContract_TestScope_Global_Default()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
- System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value;
+ BigInteger value = (new BigDecimal(1, 8)).Value;
sb.EmitAppCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
}
- // default to global scope
- var cosigners = new Cosigner[]{ new Cosigner
+ // try to use fee only inside the smart contract
+ var signers = new Signer[]{ new Signer
{
- Account = acc.ScriptHash
+ Account = acc.ScriptHash,
+ Scopes = WitnessScope.FeeOnly
} };
- // using this...
+ Assert.ThrowsException(() => wallet.MakeTransaction(script, acc.ScriptHash, signers));
+
+ // change to global scope
+ signers[0].Scopes = WitnessScope.Global;
- var tx = wallet.MakeTransaction(script, acc.ScriptHash, cosigners);
+ var tx = wallet.MakeTransaction(script, acc.ScriptHash, signers);
Assert.IsNotNull(tx);
Assert.IsNull(tx.Witnesses);
@@ -990,7 +1009,7 @@ public void FeeIsSignatureContract_TestScope_Global_Default()
long verificationGas = 0;
foreach (var witness in tx.Witnesses)
{
- using (ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
+ using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot, tx.NetworkFee, false))
{
engine.LoadScript(witness.VerificationScript);
engine.LoadScript(witness.InvocationScript);
@@ -1003,7 +1022,7 @@ public void FeeIsSignatureContract_TestScope_Global_Default()
// get sizeGas
var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot);
// final check on sum: verification_cost + tx_size
- Assert.AreEqual(1264390, verificationGas + sizeGas);
+ Assert.AreEqual(1244390, verificationGas + sizeGas);
// final assert
Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas);
}
@@ -1013,8 +1032,8 @@ public void FeeIsSignatureContract_TestScope_Global_Default()
public void ToJson()
{
uut.Script = TestUtils.GetByteArray(32, 0x42);
- uut.Sender = UInt160.Zero;
uut.SystemFee = 4200000000;
+ uut.Signers = new Signer[] { new Signer() { Account = UInt160.Zero } };
uut.Attributes = Array.Empty();
uut.Witnesses = new[]
{
@@ -1027,8 +1046,8 @@ public void ToJson()
JObject jObj = uut.ToJson();
jObj.Should().NotBeNull();
- jObj["hash"].AsString().Should().Be("0xfe08a23db645733a95914622ead5e738b03918680e927e00928116395e571758");
- jObj["size"].AsNumber().Should().Be(82);
+ jObj["hash"].AsString().Should().Be("0xe17382d26702bde77b00a9f23ea156b77c418764cbc45b2692088b5fde0336e3");
+ jObj["size"].AsNumber().Should().Be(84);
jObj["version"].AsNumber().Should().Be(0);
((JArray)jObj["attributes"]).Count.Should().Be(0);
jObj["netfee"].AsString().Should().Be("0");
diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs
index a6cc76682f..ff47beef29 100644
--- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs
+++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs
@@ -54,8 +54,12 @@ private Witness PrepareDummyWitness(int maxAccounts)
var data = new ContractParametersContext(new Transaction()
{
- Sender = multiSignContract.ScriptHash,
Attributes = Array.Empty(),
+ Signers = new[] {new Signer()
+ {
+ Account = multiSignContract.ScriptHash,
+ Scopes = WitnessScope.CalledByEntry
+ }},
NetworkFee = 0,
Nonce = 0,
Script = new byte[0],
diff --git a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs
index ef2df0acff..fbd8e10f4e 100644
--- a/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs
+++ b/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs
@@ -11,7 +11,7 @@ public class UT_ContractManifest
[TestMethod]
public void ParseFromJson_Default()
{
- var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}";
+ var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}";
var manifest = ContractManifest.Parse(json);
Assert.AreEqual(manifest.ToString(), json);
@@ -22,7 +22,7 @@ public void ParseFromJson_Default()
[TestMethod]
public void ParseFromJson_Features()
{
- var json = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}";
+ var json = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}";
var manifest = ContractManifest.Parse(json);
Assert.AreEqual(manifest.ToJson().ToString(), json);
@@ -34,7 +34,7 @@ public void ParseFromJson_Features()
[TestMethod]
public void ParseFromJson_Permissions()
{
- var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safemethods"":[],""extra"":null}";
+ var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safemethods"":[],""extra"":null}";
var manifest = ContractManifest.Parse(json);
Assert.AreEqual(manifest.ToString(), json);
@@ -53,7 +53,7 @@ public void ParseFromJson_Permissions()
[TestMethod]
public void ParseFromJson_SafeMethods()
{
- var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[""balanceOf""],""extra"":null}";
+ var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[""balanceOf""],""extra"":null}";
var manifest = ContractManifest.Parse(json);
Assert.AreEqual(manifest.ToString(), json);
@@ -65,7 +65,7 @@ public void ParseFromJson_SafeMethods()
[TestMethod]
public void ParseFromJson_Trust()
{
- var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safemethods"":[],""extra"":null}";
+ var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safemethods"":[],""extra"":null}";
var manifest = ContractManifest.Parse(json);
Assert.AreEqual(manifest.ToString(), json);
@@ -77,7 +77,7 @@ public void ParseFromJson_Trust()
[TestMethod]
public void ParseFromJson_Groups()
{
- var json = @"{""groups"":[{""pubkey"":""03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"",""signature"":""QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==""}],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}";
+ var json = @"{""groups"":[{""pubkey"":""03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"",""signature"":""QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==""}],""features"":{""storage"":false,""payable"":false},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}";
var manifest = ContractManifest.Parse(json);
Assert.AreEqual(manifest.ToString(), json);
@@ -89,7 +89,7 @@ public void ParseFromJson_Groups()
[TestMethod]
public void ParseFromJson_Extra()
{
- var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":{""key"":""value""}}";
+ var json = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":{""key"":""value""}}";
var manifest = ContractManifest.Parse(json);
Assert.AreEqual(json, json);
Assert.AreEqual("value", manifest.Extra["key"].AsString(), false);
@@ -122,7 +122,7 @@ public void TestGetHash()
public void TestGetSize()
{
var temp = TestUtils.CreateDefaultManifest(UInt160.Zero);
- Assert.AreEqual(233, temp.Size);
+ Assert.AreEqual(259, temp.Size);
}
[TestMethod]
diff --git a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs
index e2910ae1e5..380bdb65a6 100644
--- a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs
+++ b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs
@@ -31,9 +31,6 @@ public void TestSetup()
[TestMethod]
public void Check_Decimals() => NativeContract.GAS.Decimals().Should().Be(8);
- [TestMethod]
- public void Check_SupportedStandards() => NativeContract.GAS.SupportedStandards().Should().BeEquivalentTo(new string[] { "NEP-5", "NEP-10" });
-
[TestMethod]
public void Check_BalanceOfTransferAndBurn()
{
@@ -52,16 +49,16 @@ public void Check_BalanceOfTransferAndBurn()
// Check unclaim
var unclaim = UT_NeoToken.Check_UnclaimedGas(snapshot, from);
- unclaim.Value.Should().Be(new BigInteger(300000048000));
+ unclaim.Value.Should().Be(new BigInteger(600000000000));
unclaim.State.Should().BeTrue();
// Transfer
NativeContract.NEO.Transfer(snapshot, from, to, BigInteger.Zero, true).Should().BeTrue();
- NativeContract.NEO.BalanceOf(snapshot, from).Should().Be(50000008);
+ NativeContract.NEO.BalanceOf(snapshot, from).Should().Be(100000000);
NativeContract.NEO.BalanceOf(snapshot, to).Should().Be(0);
- NativeContract.GAS.BalanceOf(snapshot, from).Should().Be(3000300000048000);
+ NativeContract.GAS.BalanceOf(snapshot, from).Should().Be(30006000_00000000);
NativeContract.GAS.BalanceOf(snapshot, to).Should().Be(0);
// Check unclaim
@@ -71,7 +68,7 @@ public void Check_BalanceOfTransferAndBurn()
unclaim.State.Should().BeTrue();
supply = NativeContract.GAS.TotalSupply(snapshot);
- supply.Should().Be(3000300000048000);
+ supply.Should().Be(30006000_00000000);
snapshot.Storages.GetChangeSet().Count().Should().Be(keyCount + 3); // Gas
@@ -79,20 +76,20 @@ public void Check_BalanceOfTransferAndBurn()
keyCount = snapshot.Storages.GetChangeSet().Count();
- NativeContract.GAS.Transfer(snapshot, from, to, 3000300000048000, false).Should().BeFalse(); // Not signed
- NativeContract.GAS.Transfer(snapshot, from, to, 3000300000048001, true).Should().BeFalse(); // More than balance
- NativeContract.GAS.Transfer(snapshot, from, to, 3000300000048000, true).Should().BeTrue(); // All balance
+ NativeContract.GAS.Transfer(snapshot, from, to, 30006000_00000000, false).Should().BeFalse(); // Not signed
+ NativeContract.GAS.Transfer(snapshot, from, to, 30006000_00000001, true).Should().BeFalse(); // More than balance
+ NativeContract.GAS.Transfer(snapshot, from, to, 30006000_00000000, true).Should().BeTrue(); // All balance
// Balance of
- NativeContract.GAS.BalanceOf(snapshot, to).Should().Be(3000300000048000);
+ NativeContract.GAS.BalanceOf(snapshot, to).Should().Be(30006000_00000000);
NativeContract.GAS.BalanceOf(snapshot, from).Should().Be(0);
snapshot.Storages.GetChangeSet().Count().Should().Be(keyCount + 1); // All
// Burn
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0);
keyCount = snapshot.Storages.GetChangeSet().Count();
Assert.ThrowsException(() =>
@@ -101,19 +98,19 @@ public void Check_BalanceOfTransferAndBurn()
// Burn more than expected
Assert.ThrowsException(() =>
- NativeContract.GAS.Burn(engine, new UInt160(to), new BigInteger(3000300000048001)));
+ NativeContract.GAS.Burn(engine, new UInt160(to), new BigInteger(30006000_00000001)));
// Real burn
NativeContract.GAS.Burn(engine, new UInt160(to), new BigInteger(1));
- NativeContract.GAS.BalanceOf(snapshot, to).Should().Be(3000300000047999);
+ NativeContract.GAS.BalanceOf(snapshot, to).Should().Be(30005999_99999999);
keyCount.Should().Be(snapshot.Storages.GetChangeSet().Count());
// Burn all
- NativeContract.GAS.Burn(engine, new UInt160(to), new BigInteger(3000300000047999));
+ NativeContract.GAS.Burn(engine, new UInt160(to), new BigInteger(30005999_99999999));
(keyCount - 1).Should().Be(snapshot.Storages.GetChangeSet().Count());
@@ -127,7 +124,7 @@ public void Check_BalanceOfTransferAndBurn()
[TestMethod]
public void Check_BadScript()
{
- var engine = new ApplicationEngine(TriggerType.Application, null, Blockchain.Singleton.GetSnapshot(), 0);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, Blockchain.Singleton.GetSnapshot(), 0);
var script = new ScriptBuilder();
script.Emit(OpCode.NOP);
diff --git a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs
index dafb1f9a72..846f03d5cc 100644
--- a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs
+++ b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs
@@ -36,9 +36,6 @@ public void TestSetup()
[TestMethod]
public void Check_Decimals() => NativeContract.NEO.Decimals().Should().Be(0);
- [TestMethod]
- public void Check_SupportedStandards() => NativeContract.NEO.SupportedStandards().Should().BeEquivalentTo(new string[] { "NEP-5", "NEP-10" });
-
[TestMethod]
public void Check_Vote()
{
@@ -87,7 +84,7 @@ public void Check_UnclaimedGas()
byte[] from = Blockchain.GetConsensusAddress(Blockchain.StandbyValidators).ToArray();
var unclaim = Check_UnclaimedGas(snapshot, from);
- unclaim.Value.Should().Be(new BigInteger(300000048000));
+ unclaim.Value.Should().Be(new BigInteger(600000000000));
unclaim.State.Should().BeTrue();
unclaim = Check_UnclaimedGas(snapshot, new byte[19]);
@@ -119,16 +116,8 @@ public void Check_RegisterValidator()
// Check GetRegisteredValidators
- var members = NativeContract.NEO.GetCandidates(snapshot).OrderBy(u => u.PublicKey).ToArray();
- var check = Blockchain.StandbyCommittee.Select(u => u.EncodePoint(true)).ToList();
- check.Add(point); // Add the new member
-
- for (int x = 0; x < members.Length; x++)
- {
- Assert.AreEqual(1, check.RemoveAll(u => u.SequenceEqual(members[x].PublicKey.EncodePoint(true))));
- }
-
- Assert.AreEqual(0, check.Count);
+ var members = NativeContract.NEO.GetCandidates(snapshot);
+ Assert.AreEqual(2, members.Length);
}
[TestMethod]
@@ -146,14 +135,14 @@ public void Check_Transfer()
// Check unclaim
var unclaim = Check_UnclaimedGas(snapshot, from);
- unclaim.Value.Should().Be(new BigInteger(300000048000));
+ unclaim.Value.Should().Be(new BigInteger(600000000000));
unclaim.State.Should().BeTrue();
// Transfer
NativeContract.NEO.Transfer(snapshot, from, to, BigInteger.One, false).Should().BeFalse(); // Not signed
NativeContract.NEO.Transfer(snapshot, from, to, BigInteger.One, true).Should().BeTrue();
- NativeContract.NEO.BalanceOf(snapshot, from).Should().Be(50000007);
+ NativeContract.NEO.BalanceOf(snapshot, from).Should().Be(99999999);
NativeContract.NEO.BalanceOf(snapshot, to).Should().Be(1);
// Check unclaim
@@ -189,7 +178,7 @@ public void Check_BalanceOf()
var snapshot = Blockchain.Singleton.GetSnapshot();
byte[] account = Blockchain.GetConsensusAddress(Blockchain.StandbyValidators).ToArray();
- NativeContract.NEO.BalanceOf(snapshot, account).Should().Be(50_000_008);
+ NativeContract.NEO.BalanceOf(snapshot, account).Should().Be(100_000_000);
account[5]++; // Without existing balance
@@ -209,7 +198,7 @@ public void Check_Initialize()
[TestMethod]
public void Check_BadScript()
{
- var engine = new ApplicationEngine(TriggerType.Application, null, Blockchain.Singleton.GetSnapshot(), 0);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, Blockchain.Singleton.GetSnapshot(), 0);
var script = new ScriptBuilder();
script.Emit(OpCode.NOP);
@@ -279,53 +268,23 @@ public void TestGetNextBlockValidators2()
}
[TestMethod]
- public void TestGetRegisteredValidators1()
+ public void TestGetCandidates1()
{
- using (ApplicationEngine engine = NativeContract.NEO.TestCall("getCandidates"))
- {
- var array = engine.ResultStack.Pop();
- array.Count.Should().Be(21);
- ((VM.Types.Struct)array[0])[0].GetSpan().ToHexString().Should().Be("020f2887f41474cfeb11fd262e982051c1541418137c02a0f4961af911045de639");
- ((VM.Types.Struct)array[0])[1].GetInteger().Should().Be(new BigInteger(1785714));
- ((VM.Types.Struct)array[1])[0].GetSpan().ToHexString().Should().Be("0222038884bbd1d8ff109ed3bdef3542e768eef76c1247aea8bc8171f532928c30");
- ((VM.Types.Struct)array[1])[1].GetInteger().Should().Be(new BigInteger(1785714));
- ((VM.Types.Struct)array[2])[0].GetSpan().ToHexString().Should().Be("0226933336f1b75baa42d42b71d9091508b638046d19abd67f4e119bf64a7cfb4d");
- ((VM.Types.Struct)array[2])[1].GetInteger().Should().Be(new BigInteger(1785714));
- ((VM.Types.Struct)array[3])[0].GetSpan().ToHexString().Should().Be("023a36c72844610b4d34d1968662424011bf783ca9d984efa19a20babf5582f3fe");
- ((VM.Types.Struct)array[3])[1].GetInteger().Should().Be(new BigInteger(1785714));
- ((VM.Types.Struct)array[4])[0].GetSpan().ToHexString().Should().Be("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70");
- ((VM.Types.Struct)array[4])[1].GetInteger().Should().Be(new BigInteger(3571428));
- ((VM.Types.Struct)array[5])[0].GetSpan().ToHexString().Should().Be("024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d");
- ((VM.Types.Struct)array[5])[1].GetInteger().Should().Be(new BigInteger(3571428));
- ((VM.Types.Struct)array[6])[0].GetSpan().ToHexString().Should().Be("02504acbc1f4b3bdad1d86d6e1a08603771db135a73e61c9d565ae06a1938cd2ad");
- ((VM.Types.Struct)array[6])[1].GetInteger().Should().Be(new BigInteger(1785714));
- }
+ using ApplicationEngine engine = NativeContract.NEO.TestCall("getCandidates");
+ var array = engine.ResultStack.Pop();
+ array.Count.Should().Be(0);
}
[TestMethod]
- public void TestGetRegisteredValidators2()
+ public void TestGetCandidates2()
{
var snapshot = Blockchain.Singleton.GetSnapshot();
- var result = NativeContract.NEO.GetCandidates(snapshot).ToArray();
- result.Length.Should().Be(21);
- result[0].PublicKey.ToArray().ToHexString().Should().Be("020f2887f41474cfeb11fd262e982051c1541418137c02a0f4961af911045de639");
- result[0].Votes.Should().Be(new BigInteger(1785714));
- result[1].PublicKey.ToArray().ToHexString().Should().Be("0222038884bbd1d8ff109ed3bdef3542e768eef76c1247aea8bc8171f532928c30");
- result[1].Votes.Should().Be(new BigInteger(1785714));
- result[2].PublicKey.ToArray().ToHexString().Should().Be("0226933336f1b75baa42d42b71d9091508b638046d19abd67f4e119bf64a7cfb4d");
- result[2].Votes.Should().Be(new BigInteger(1785714));
- result[3].PublicKey.ToArray().ToHexString().Should().Be("023a36c72844610b4d34d1968662424011bf783ca9d984efa19a20babf5582f3fe");
- result[3].Votes.Should().Be(new BigInteger(1785714));
- result[4].PublicKey.ToArray().ToHexString().Should().Be("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70");
- result[4].Votes.Should().Be(new BigInteger(3571428));
- result[5].PublicKey.ToArray().ToHexString().Should().Be("024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d");
- result[5].Votes.Should().Be(new BigInteger(3571428));
- result[6].PublicKey.ToArray().ToHexString().Should().Be("02504acbc1f4b3bdad1d86d6e1a08603771db135a73e61c9d565ae06a1938cd2ad");
- result[6].Votes.Should().Be(new BigInteger(1785714));
+ var result = NativeContract.NEO.GetCandidates(snapshot);
+ result.Length.Should().Be(0);
StorageKey key = NativeContract.NEO.CreateStorageKey(33, ECCurve.Secp256r1.G);
snapshot.Storages.Add(key, new StorageItem(new CandidateState()));
- NativeContract.NEO.GetCandidates(snapshot).ToArray().Length.Should().Be(22);
+ NativeContract.NEO.GetCandidates(snapshot).Length.Should().Be(1);
}
[TestMethod]
@@ -427,7 +386,7 @@ public void TestVote()
{
var snapshot = Blockchain.Singleton.GetSnapshot();
snapshot.PersistingBlock = Blockchain.GenesisBlock;
- var engine = new ApplicationEngine(TriggerType.Application, Blockchain.GenesisBlock, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, Blockchain.GenesisBlock, snapshot, 0, true);
ScriptBuilder sb = new ScriptBuilder();
var tmp = engine.ScriptContainer.GetScriptHashesForVerifying(engine.Snapshot);
UInt160 from = engine.ScriptContainer.GetScriptHashesForVerifying(engine.Snapshot)[0];
@@ -458,7 +417,7 @@ public void TestVote()
internal static (bool State, bool Result) Check_Vote(StoreView snapshot, byte[] account, byte[] pubkey, bool signAccount)
{
- var engine = new ApplicationEngine(TriggerType.Application,
+ var engine = ApplicationEngine.Create(TriggerType.Application,
new Nep5NativeContractExtensions.ManualWitness(signAccount ? new UInt160(account) : UInt160.Zero), snapshot, 0, true);
engine.LoadScript(NativeContract.NEO.Script);
@@ -488,7 +447,7 @@ internal static (bool State, bool Result) Check_Vote(StoreView snapshot, byte[]
internal static (bool State, bool Result) Check_RegisterValidator(StoreView snapshot, byte[] pubkey)
{
- var engine = new ApplicationEngine(TriggerType.Application,
+ var engine = ApplicationEngine.Create(TriggerType.Application,
new Nep5NativeContractExtensions.ManualWitness(Contract.CreateSignatureRedeemScript(ECPoint.DecodePoint(pubkey, ECCurve.Secp256r1)).ToScriptHash()), snapshot, 0, true);
engine.LoadScript(NativeContract.NEO.Script);
@@ -513,7 +472,7 @@ internal static (bool State, bool Result) Check_RegisterValidator(StoreView snap
internal static ECPoint[] Check_GetValidators(StoreView snapshot)
{
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(NativeContract.NEO.Script);
@@ -533,7 +492,7 @@ internal static ECPoint[] Check_GetValidators(StoreView snapshot)
internal static (BigInteger Value, bool State) Check_UnclaimedGas(StoreView snapshot, byte[] address)
{
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(NativeContract.NEO.Script);
diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs
index 90970a506b..3188bddb4c 100644
--- a/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs
+++ b/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs
@@ -24,7 +24,7 @@ public void TestSetup()
[TestMethod]
public void TestInitialize()
{
- ApplicationEngine ae = new ApplicationEngine(TriggerType.Application, null, null, 0);
+ ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, null, 0);
testNativeContract.Initialize(ae);
}
@@ -32,7 +32,7 @@ public void TestInitialize()
public void TestInvoke()
{
var snapshot = Blockchain.Singleton.GetSnapshot();
- ApplicationEngine engine = new ApplicationEngine(TriggerType.System, null, snapshot, 0);
+ ApplicationEngine engine = ApplicationEngine.Create(TriggerType.System, null, snapshot, 0);
engine.LoadScript(testNativeContract.Script);
ByteString method1 = new ByteString(System.Text.Encoding.Default.GetBytes("wrongMethod"));
@@ -53,10 +53,10 @@ public void TestOnPersistWithArgs()
{
var snapshot = Blockchain.Singleton.GetSnapshot();
- ApplicationEngine engine1 = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
+ ApplicationEngine engine1 = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0);
Assert.ThrowsException(() => testNativeContract.TestOnPersist(engine1));
- ApplicationEngine engine2 = new ApplicationEngine(TriggerType.System, null, snapshot, 0);
+ ApplicationEngine engine2 = ApplicationEngine.Create(TriggerType.System, null, snapshot, 0);
testNativeContract.TestOnPersist(engine2);
}
diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs
index a33b209a12..8eba15bf5c 100644
--- a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs
+++ b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs
@@ -19,16 +19,13 @@ public void TestSetup()
TestBlockchain.InitializeMockNeoSystem();
}
- [TestMethod]
- public void Check_SupportedStandards() => NativeContract.Policy.SupportedStandards().Should().BeEquivalentTo(new string[] { "NEP-10" });
-
[TestMethod]
public void Check_Initialize()
{
var snapshot = Blockchain.Singleton.GetSnapshot();
var keyCount = snapshot.Storages.GetChangeSet().Count();
- NativeContract.Policy.Initialize(new ApplicationEngine(TriggerType.Application, null, snapshot, 0));
+ NativeContract.Policy.Initialize(ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0));
(keyCount + 5).Should().Be(snapshot.Storages.GetChangeSet().Count());
@@ -65,7 +62,7 @@ public void Check_SetMaxBlockSize()
UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeAddress(snapshot);
- NativeContract.Policy.Initialize(new ApplicationEngine(TriggerType.Application, null, snapshot, 0));
+ NativeContract.Policy.Initialize(ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0));
// Without signature
@@ -113,7 +110,7 @@ public void Check_SetMaxBlockSystemFee()
UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeAddress(snapshot);
- NativeContract.Policy.Initialize(new ApplicationEngine(TriggerType.Application, null, snapshot, 0));
+ NativeContract.Policy.Initialize(ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0));
// Without signature
@@ -159,7 +156,7 @@ public void Check_SetMaxTransactionsPerBlock()
snapshot.PersistingBlock = new Block() { Index = 1000, PrevHash = UInt256.Zero };
snapshot.Blocks.Add(UInt256.Zero, new Neo.Ledger.TrimmedBlock() { NextConsensus = UInt160.Zero });
- NativeContract.Policy.Initialize(new ApplicationEngine(TriggerType.Application, null, snapshot, 0));
+ NativeContract.Policy.Initialize(ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0));
// Without signature
@@ -194,7 +191,7 @@ public void Check_SetFeePerByte()
snapshot.PersistingBlock = new Block() { Index = 1000, PrevHash = UInt256.Zero };
snapshot.Blocks.Add(UInt256.Zero, new Neo.Ledger.TrimmedBlock() { NextConsensus = UInt160.Zero });
- NativeContract.Policy.Initialize(new ApplicationEngine(TriggerType.Application, null, snapshot, 0));
+ NativeContract.Policy.Initialize(ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0));
// Without signature
@@ -231,7 +228,7 @@ public void Check_Block_UnblockAccount()
UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeAddress(snapshot);
- NativeContract.Policy.Initialize(new ApplicationEngine(TriggerType.Application, null, snapshot, 0));
+ NativeContract.Policy.Initialize(ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0));
// Block without signature
@@ -279,28 +276,5 @@ public void Check_Block_UnblockAccount()
ret.Should().BeOfType();
((VM.Types.Array)ret).Count.Should().Be(0);
}
-
- [TestMethod]
- public void TestCheckPolicy()
- {
- Transaction tx = Blockchain.GenesisBlock.Transactions[0];
- var snapshot = Blockchain.Singleton.GetSnapshot();
-
- StorageKey storageKey = new StorageKey
- {
- Id = NativeContract.Policy.Id,
- Key = new byte[sizeof(byte)]
- };
- storageKey.Key[0] = 15;
- snapshot.Storages.Add(storageKey, new StorageItem
- {
- Value = new UInt160[] { tx.Sender }.ToByteArray(),
- });
-
- NativeContract.Policy.CheckPolicy(tx, snapshot).Should().BeFalse();
-
- snapshot = Blockchain.Singleton.GetSnapshot();
- NativeContract.Policy.CheckPolicy(tx, snapshot).Should().BeTrue();
- }
}
}
diff --git a/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs b/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs
index 6bccb8f179..3d8c435a06 100644
--- a/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs
+++ b/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs
@@ -21,7 +21,7 @@ public void TestSetup()
public void TestNotify()
{
var snapshot = Blockchain.Singleton.GetSnapshot();
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
ApplicationEngine.Notify += Test_Notify1;
const string notifyEvent = "TestEvent";
diff --git a/tests/neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs b/tests/neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs
new file mode 100644
index 0000000000..81c32cd8b5
--- /dev/null
+++ b/tests/neo.UnitTests/SmartContract/UT_ApplicationEngineProvider.cs
@@ -0,0 +1,80 @@
+using FluentAssertions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
+using Neo.Plugins;
+using Neo.SmartContract;
+
+namespace Neo.UnitTests.SmartContract
+{
+ [TestClass]
+ public class UT_ApplicationEngineProvider
+ {
+ [TestInitialize]
+ public void TestInitialize()
+ {
+ ApplicationEngine.ResetApplicationEngineProvider();
+ }
+
+ [TestCleanup]
+ public void TestCleanup()
+ {
+ ApplicationEngine.ResetApplicationEngineProvider();
+ }
+
+ [TestMethod]
+ public void TestSetAppEngineProvider()
+ {
+ var provider = new TestProvider();
+ ApplicationEngine.SetApplicationEngineProvider(provider).Should().BeTrue();
+
+ using var appEngine = ApplicationEngine.Create(TriggerType.Application, null, null, 0);
+ (appEngine is TestEngine).Should().BeTrue();
+ }
+
+ [TestMethod]
+ public void TestDefaultAppEngineProvider()
+ {
+ using var appEngine = ApplicationEngine.Create(TriggerType.Application, null, null, 0);
+ (appEngine is ApplicationEngine).Should().BeTrue();
+ }
+
+ [TestMethod]
+ public void TestCantSetAppEngineProviderTwice()
+ {
+ var provider = new TestProvider();
+ ApplicationEngine.SetApplicationEngineProvider(provider).Should().BeTrue();
+
+ var provider2 = new TestProvider();
+ ApplicationEngine.SetApplicationEngineProvider(provider2).Should().BeFalse();
+ }
+
+ [TestMethod]
+ public void TestCanResetAppEngineProviderTwice()
+ {
+ var provider = new TestProvider();
+ ApplicationEngine.SetApplicationEngineProvider(provider).Should().BeTrue();
+
+ ApplicationEngine.ResetApplicationEngineProvider();
+
+ var provider2 = new TestProvider();
+ ApplicationEngine.SetApplicationEngineProvider(provider2).Should().BeTrue();
+ }
+
+ class TestProvider : IApplicationEngineProvider
+ {
+ public ApplicationEngine Create(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false)
+ {
+ return new TestEngine(trigger, container, snapshot, gas, testMode);
+ }
+ }
+
+ class TestEngine : ApplicationEngine
+ {
+ public TestEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false)
+ : base(trigger, container, snapshot, gas, testMode)
+ {
+ }
+ }
+ }
+}
diff --git a/tests/neo.UnitTests/SmartContract/UT_ContractParameterContext.cs b/tests/neo.UnitTests/SmartContract/UT_ContractParameterContext.cs
index 23e474e4b8..b96c06ae3c 100644
--- a/tests/neo.UnitTests/SmartContract/UT_ContractParameterContext.cs
+++ b/tests/neo.UnitTests/SmartContract/UT_ContractParameterContext.cs
@@ -33,8 +33,7 @@ public static void ClassSetUp(TestContext context)
[TestMethod]
public void TestGetComplete()
{
- Transaction tx = TestUtils.GetTransaction();
- tx.Sender = UInt160.Parse("0x1bd5c777ec35768892bd3daab60fb7a1cb905066");
+ Transaction tx = TestUtils.GetTransaction(UInt160.Parse("0x1bd5c777ec35768892bd3daab60fb7a1cb905066"));
var context = new ContractParametersContext(tx);
context.Completed.Should().BeFalse();
}
@@ -42,18 +41,17 @@ public void TestGetComplete()
[TestMethod]
public void TestToString()
{
- Transaction tx = TestUtils.GetTransaction();
- tx.Sender = UInt160.Parse("0x1bd5c777ec35768892bd3daab60fb7a1cb905066");
+ Transaction tx = TestUtils.GetTransaction(UInt160.Parse("0x1bd5c777ec35768892bd3daab60fb7a1cb905066"));
var context = new ContractParametersContext(tx);
context.Add(contract, 0, new byte[] { 0x01 });
string str = context.ToString();
- str.Should().Be(@"{""type"":""Neo.Network.P2P.Payloads.Transaction"",""hex"":""AAAAAABmUJDLobcPtqo9vZKIdjXsd8fVGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA"",""items"":{}}");
+ str.Should().Be(@"{""type"":""Neo.Network.P2P.Payloads.Transaction"",""hex"":""AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFmUJDLobcPtqo9vZKIdjXsd8fVGwEAAQA="",""items"":{}}");
}
[TestMethod]
public void TestParse()
{
- var ret = ContractParametersContext.Parse("{\"type\":\"Neo.Network.P2P.Payloads.Transaction\",\"hex\":\"AAAAAABmUJDLobcPtqo9vZKIdjXsd8fVGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAEA\",\"items\":{\"0xbecaad15c0ea585211faf99738a4354014f177f2\":{\"script\":\"IQJv8DuUkkHOHa3UNRnmlg4KhbQaaaBcMoEDqivOFZTKFmh0dHaq\",\"parameters\":[{\"type\":\"Signature\",\"value\":\"AQ==\"}]}}}");
+ var ret = ContractParametersContext.Parse("{\"type\":\"Neo.Network.P2P.Payloads.Transaction\",\"hex\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFmUJDLobcPtqo9vZKIdjXsd8fVGwEAAQA=\",\"items\":{\"0xbecaad15c0ea585211faf99738a4354014f177f2\":{\"script\":\"IQJv8DuUkkHOHa3UNRnmlg4KhbQaaaBcMoEDqivOFZTKFmh0dHaq\",\"parameters\":[{\"type\":\"Signature\",\"value\":\"AQ==\"}]}}}");
ret.ScriptHashes[0].ToString().Should().Be("0x1bd5c777ec35768892bd3daab60fb7a1cb905066");
((Transaction)ret.Verifiable).Script.ToHexString().Should().Be(new byte[1].ToHexString());
}
@@ -68,11 +66,11 @@ public void TestFromJson()
[TestMethod]
public void TestAdd()
{
- Transaction tx = TestUtils.GetTransaction();
+ Transaction tx = TestUtils.GetTransaction(UInt160.Zero);
var context1 = new ContractParametersContext(tx);
context1.Add(contract, 0, new byte[] { 0x01 }).Should().BeFalse();
- tx.Sender = UInt160.Parse("0x282646ee0afa5508bb999318f35074b84a17c9f0");
+ tx = TestUtils.GetTransaction(UInt160.Parse("0x282646ee0afa5508bb999318f35074b84a17c9f0"));
var context2 = new ContractParametersContext(tx);
context2.Add(contract, 0, new byte[] { 0x01 }).Should().BeTrue();
//test repeatlly createItem
@@ -82,8 +80,7 @@ public void TestAdd()
[TestMethod]
public void TestGetParameter()
{
- Transaction tx = TestUtils.GetTransaction();
- tx.Sender = UInt160.Parse("0x282646ee0afa5508bb999318f35074b84a17c9f0");
+ Transaction tx = TestUtils.GetTransaction(UInt160.Parse("0x282646ee0afa5508bb999318f35074b84a17c9f0"));
var context = new ContractParametersContext(tx);
context.GetParameter(tx.Sender, 0).Should().BeNull();
@@ -95,8 +92,7 @@ public void TestGetParameter()
[TestMethod]
public void TestGetWitnesses()
{
- Transaction tx = TestUtils.GetTransaction();
- tx.Sender = UInt160.Parse("0x282646ee0afa5508bb999318f35074b84a17c9f0");
+ Transaction tx = TestUtils.GetTransaction(UInt160.Parse("0x282646ee0afa5508bb999318f35074b84a17c9f0"));
var context = new ContractParametersContext(tx);
context.Add(contract, 0, new byte[] { 0x01 });
Witness[] witnesses = context.GetWitnesses();
@@ -108,9 +104,8 @@ public void TestGetWitnesses()
[TestMethod]
public void TestAddSignature()
{
- Transaction tx = TestUtils.GetTransaction();
var singleSender = UInt160.Parse("0x282646ee0afa5508bb999318f35074b84a17c9f0");
- tx.Sender = singleSender;
+ Transaction tx = TestUtils.GetTransaction(singleSender);
//singleSign
@@ -140,16 +135,16 @@ public void TestAddSignature()
key2.PublicKey
});
var multiSender = UInt160.Parse("0x3593816cc1085a6328fea2b899c24d78cd0ba372");
- tx.Sender = multiSender;
+ tx = TestUtils.GetTransaction(multiSender);
context = new ContractParametersContext(tx);
context.AddSignature(multiSignContract, key.PublicKey, new byte[] { 0x01 }).Should().BeTrue();
context.AddSignature(multiSignContract, key2.PublicKey, new byte[] { 0x01 }).Should().BeTrue();
- tx.Sender = singleSender;
+ tx = TestUtils.GetTransaction(singleSender);
context = new ContractParametersContext(tx);
context.AddSignature(multiSignContract, key.PublicKey, new byte[] { 0x01 }).Should().BeFalse();
- tx.Sender = multiSender;
+ tx = TestUtils.GetTransaction(multiSender);
context = new ContractParametersContext(tx);
byte[] privateKey3 = new byte[] { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs b/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs
index cf93e5abb3..1635e431e8 100644
--- a/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs
+++ b/tests/neo.UnitTests/SmartContract/UT_InteropPrices.cs
@@ -21,7 +21,7 @@ public void ApplicationEngineFixedPrices()
{
// System.Runtime.CheckWitness: f827ec8c (price is 200)
byte[] SyscallSystemRuntimeCheckWitnessHash = new byte[] { 0x68, 0xf8, 0x27, 0xec, 0x8c };
- using (ApplicationEngine ae = new ApplicationEngine(TriggerType.Application, null, null, 0))
+ using (ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, null, 0))
{
ae.LoadScript(SyscallSystemRuntimeCheckWitnessHash);
ApplicationEngine.System_Runtime_CheckWitness.FixedPrice.Should().Be(0_00030000L);
@@ -29,7 +29,7 @@ public void ApplicationEngineFixedPrices()
// System.Storage.GetContext: 9bf667ce (price is 1)
byte[] SyscallSystemStorageGetContextHash = new byte[] { 0x68, 0x9b, 0xf6, 0x67, 0xce };
- using (ApplicationEngine ae = new ApplicationEngine(TriggerType.Application, null, null, 0))
+ using (ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, null, 0))
{
ae.LoadScript(SyscallSystemStorageGetContextHash);
ApplicationEngine.System_Storage_GetContext.FixedPrice.Should().Be(0_00000400L);
@@ -37,7 +37,7 @@ public void ApplicationEngineFixedPrices()
// System.Storage.Get: 925de831 (price is 100)
byte[] SyscallSystemStorageGetHash = new byte[] { 0x68, 0x92, 0x5d, 0xe8, 0x31 };
- using (ApplicationEngine ae = new ApplicationEngine(TriggerType.Application, null, null, 0))
+ using (ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, null, 0))
{
ae.LoadScript(SyscallSystemStorageGetHash);
ApplicationEngine.System_Storage_Get.FixedPrice.Should().Be(0_01000000L);
@@ -65,7 +65,7 @@ public void ApplicationEngineRegularPut()
snapshot.Storages.Add(skey, sItem);
snapshot.Contracts.Add(script.ToScriptHash(), contractState);
- using (ApplicationEngine ae = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, testMode: true))
+ using (ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, testMode: true))
{
Debugger debugger = new Debugger(ae);
ae.LoadScript(script);
@@ -99,7 +99,7 @@ public void ApplicationEngineReusedStorage_FullReuse()
snapshot.Storages.Add(skey, sItem);
snapshot.Contracts.Add(script.ToScriptHash(), contractState);
- using (ApplicationEngine applicationEngine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, testMode: true))
+ using (ApplicationEngine applicationEngine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, testMode: true))
{
Debugger debugger = new Debugger(applicationEngine);
applicationEngine.LoadScript(script);
@@ -135,7 +135,7 @@ public void ApplicationEngineReusedStorage_PartialReuse()
snapshot.Storages.Add(skey, sItem);
snapshot.Contracts.Add(script.ToScriptHash(), contractState);
- using (ApplicationEngine ae = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, testMode: true))
+ using (ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, testMode: true))
{
Debugger debugger = new Debugger(ae);
ae.LoadScript(script);
@@ -172,7 +172,7 @@ public void ApplicationEngineReusedStorage_PartialReuseTwice()
snapshot.Storages.Add(skey, sItem);
snapshot.Contracts.Add(script.ToScriptHash(), contractState);
- using (ApplicationEngine ae = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, testMode: true))
+ using (ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, testMode: true))
{
Debugger debugger = new Debugger(ae);
ae.LoadScript(script);
diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs
index 5d78c4ebd5..4d4eaf4b07 100644
--- a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs
+++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs
@@ -115,12 +115,12 @@ public void TestAccount_IsStandard()
var snapshot = Blockchain.Singleton.GetSnapshot();
var state = TestUtils.GetContract();
snapshot.Contracts.Add(state.ScriptHash, state);
- engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(new byte[] { 0x01 });
engine.IsStandardContract(state.ScriptHash).Should().BeFalse();
state.Script = Contract.CreateSignatureRedeemScript(Blockchain.StandbyValidators[0]);
- engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(new byte[] { 0x01 });
engine.IsStandardContract(state.ScriptHash).Should().BeTrue();
}
@@ -141,7 +141,7 @@ public void TestContract_Create()
var snapshot = Blockchain.Singleton.GetSnapshot();
var state = TestUtils.GetContract();
snapshot.Contracts.Add(state.ScriptHash, state);
- engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0);
engine.LoadScript(new byte[] { 0x01 });
Assert.ThrowsException(() => engine.CreateContract(state.Script, manifest.ToJson().ToByteArray(false)));
}
@@ -184,7 +184,7 @@ public void TestContract_Update()
};
snapshot.Contracts.Add(state.ScriptHash, state);
snapshot.Storages.Add(storageKey, storageItem);
- engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(state.Script);
engine.UpdateContract(script, manifest.ToJson().ToByteArray(false));
engine.Snapshot.Storages.Find(BitConverter.GetBytes(state.Id)).ToList().Count().Should().Be(1);
@@ -209,7 +209,7 @@ public void TestStorage_Find()
};
snapshot.Contracts.Add(state.ScriptHash, state);
snapshot.Storages.Add(storageKey, storageItem);
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(new byte[] { 0x01 });
var iterator = engine.Find(new StorageContext
diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs
index 670c2530a5..3a0062275f 100644
--- a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs
+++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs
@@ -58,7 +58,7 @@ public void Runtime_GetNotifications_Test()
// Wrong length
- using (var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true))
+ using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true))
using (var script = new ScriptBuilder())
{
// Retrive
@@ -75,7 +75,7 @@ public void Runtime_GetNotifications_Test()
// All test
- using (var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true))
+ using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true))
using (var script = new ScriptBuilder())
{
// Notification
@@ -127,7 +127,7 @@ public void Runtime_GetNotifications_Test()
// Script notifications
- using (var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true))
+ using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true))
using (var script = new ScriptBuilder())
{
// Notification
@@ -250,7 +250,7 @@ public void TestRuntime_CheckWitness()
ECPoint pubkey = keyPair.PublicKey;
var engine = GetEngine(true);
- ((Transaction)engine.ScriptContainer).Sender = Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash();
+ ((Transaction)engine.ScriptContainer).Signers[0].Account = Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash();
engine.CheckWitness(pubkey.EncodePoint(true)).Should().BeFalse();
engine.CheckWitness(((Transaction)engine.ScriptContainer).Sender.ToArray()).Should().BeFalse();
@@ -386,7 +386,7 @@ public void TestBlockchain_GetContract()
var snapshot = Blockchain.Singleton.GetSnapshot();
var state = TestUtils.GetContract();
snapshot.Contracts.Add(state.ScriptHash, state);
- engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(new byte[] { 0x01 });
engine.GetContract(state.ScriptHash).Should().BeSameAs(state);
}
@@ -433,7 +433,7 @@ public void TestStorage_Get()
};
snapshot.Contracts.Add(state.ScriptHash, state);
snapshot.Storages.Add(storageKey, storageItem);
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(new byte[] { 0x01 });
engine.Get(new StorageContext
@@ -491,7 +491,7 @@ public void TestStorage_Put()
};
snapshot.Contracts.Add(state.ScriptHash, state);
snapshot.Storages.Add(storageKey, storageItem);
- engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(new byte[] { 0x01 });
key = new byte[] { 0x01 };
value = new byte[] { 0x02 };
@@ -527,7 +527,7 @@ public void TestStorage_PutEx()
};
snapshot.Contracts.Add(state.ScriptHash, state);
snapshot.Storages.Add(storageKey, storageItem);
- engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(new byte[] { 0x01 });
var key = new byte[] { 0x01 };
var value = new byte[] { 0x02 };
@@ -558,7 +558,7 @@ public void TestStorage_Delete()
};
snapshot.Contracts.Add(state.ScriptHash, state);
snapshot.Storages.Add(storageKey, storageItem);
- engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(new byte[] { 0x01 });
state.Manifest.Features = ContractFeatures.HasStorage;
var key = new byte[] { 0x01 };
@@ -597,7 +597,7 @@ public void TestContract_Call()
state.Manifest.Features = ContractFeatures.HasStorage;
snapshot.Contracts.Add(state.ScriptHash, state);
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(new byte[] { 0x01 });
engine.CallContract(state.ScriptHash, method, args);
@@ -627,7 +627,7 @@ public void TestContract_CallEx()
foreach (var flags in new CallFlags[] { CallFlags.None, CallFlags.AllowCall, CallFlags.AllowModifyStates, CallFlags.All })
{
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(new byte[] { 0x01 });
engine.CallContractEx(state.ScriptHash, method, args, CallFlags.All);
@@ -667,7 +667,7 @@ public void TestContract_Destroy()
};
snapshot.Contracts.Add(scriptHash, state);
snapshot.Storages.Add(storageKey, storageItem);
- engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(new byte[0]);
engine.DestroyContract();
engine.Snapshot.Storages.Find(BitConverter.GetBytes(0x43000000)).Any().Should().BeFalse();
@@ -676,7 +676,7 @@ public void TestContract_Destroy()
snapshot = Blockchain.Singleton.GetSnapshot();
state = TestUtils.GetContract();
snapshot.Contracts.Add(scriptHash, state);
- engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(new byte[0]);
engine.DestroyContract();
engine.Snapshot.Storages.Find(BitConverter.GetBytes(0x43000000)).Any().Should().BeFalse();
@@ -698,24 +698,24 @@ public static void LogEvent(object sender, LogEventArgs args)
private static ApplicationEngine GetEngine(bool hasContainer = false, bool hasSnapshot = false, bool addScript = true)
{
- var tx = TestUtils.GetTransaction();
+ var tx = TestUtils.GetTransaction(UInt160.Zero);
var snapshot = Blockchain.Singleton.GetSnapshot();
ApplicationEngine engine;
if (hasContainer && hasSnapshot)
{
- engine = new ApplicationEngine(TriggerType.Application, tx, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, 0, true);
}
else if (hasContainer && !hasSnapshot)
{
- engine = new ApplicationEngine(TriggerType.Application, tx, null, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, tx, null, 0, true);
}
else if (!hasContainer && hasSnapshot)
{
- engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
}
else
{
- engine = new ApplicationEngine(TriggerType.Application, null, null, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, null, 0, true);
}
if (addScript)
{
diff --git a/tests/neo.UnitTests/SmartContract/UT_Syscalls.Callback.cs b/tests/neo.UnitTests/SmartContract/UT_Syscalls.Callback.cs
index e97e144637..92444fa92c 100644
--- a/tests/neo.UnitTests/SmartContract/UT_Syscalls.Callback.cs
+++ b/tests/neo.UnitTests/SmartContract/UT_Syscalls.Callback.cs
@@ -21,7 +21,7 @@ public void CreateCallbackTest()
// Execute
- var engine = new ApplicationEngine(TriggerType.Application, null, null, 100_000_000, false);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 100_000_000, false);
engine.LoadScript(script.ToArray());
Assert.AreEqual(engine.Execute(), VMState.HALT);
@@ -54,7 +54,7 @@ public void InvokeCallbackTest()
// Execute
- var engine = new ApplicationEngine(TriggerType.Application, null, null, 100_000_000, false);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 100_000_000, false);
engine.LoadScript(script.ToArray());
Assert.AreEqual(engine.Execute(), VMState.HALT);
@@ -79,7 +79,7 @@ public void CreateSyscallCallbackTest()
// Execute
- var engine = new ApplicationEngine(TriggerType.Application, null, null, 100_000_000, false);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 100_000_000, false);
engine.LoadScript(script.ToArray());
Assert.AreEqual(engine.Execute(), VMState.HALT);
diff --git a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs
index 192e7292ff..72b33f41b5 100644
--- a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs
+++ b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs
@@ -26,13 +26,13 @@ public void System_Blockchain_GetBlock()
{
Script = new byte[] { 0x01 },
Attributes = Array.Empty(),
+ Signers = Array.Empty(),
NetworkFee = 0x02,
SystemFee = 0x03,
Nonce = 0x04,
ValidUntilBlock = 0x05,
Version = 0x06,
Witnesses = new Witness[] { new Witness() { VerificationScript = new byte[] { 0x07 } } },
- Sender = UInt160.Parse("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
};
var block = new Block()
@@ -61,7 +61,7 @@ public void System_Blockchain_GetBlock()
// Without block
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(script.ToArray());
Assert.AreEqual(engine.Execute(), VMState.HALT);
@@ -78,7 +78,7 @@ public void System_Blockchain_GetBlock()
blocks.Add(block.Hash, block.Trim());
txs.Add(tx.Hash, new TransactionState() { Transaction = tx, BlockIndex = block.Index, VMState = VMState.HALT });
- engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(script.ToArray());
Assert.AreEqual(engine.Execute(), VMState.HALT);
@@ -89,7 +89,7 @@ public void System_Blockchain_GetBlock()
height.Index = block.Index;
- engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(script.ToArray());
Assert.AreEqual(engine.Execute(), VMState.HALT);
@@ -117,7 +117,7 @@ public void Json_Deserialize()
script.EmitPush("null");
script.EmitSysCall(ApplicationEngine.System_Json_Deserialize);
- using (var engine = new ApplicationEngine(TriggerType.Application, null, null, 0, true))
+ using (var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 0, true))
{
engine.LoadScript(script.ToArray());
@@ -136,7 +136,7 @@ public void Json_Deserialize()
script.EmitPush("***");
script.EmitSysCall(ApplicationEngine.System_Json_Deserialize);
- using (var engine = new ApplicationEngine(TriggerType.Application, null, null, 0, true))
+ using (var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 0, true))
{
engine.LoadScript(script.ToArray());
@@ -152,7 +152,7 @@ public void Json_Deserialize()
script.EmitPush("123.45");
script.EmitSysCall(ApplicationEngine.System_Json_Deserialize);
- using (var engine = new ApplicationEngine(TriggerType.Application, null, null, 0, true))
+ using (var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 0, true))
{
engine.LoadScript(script.ToArray());
@@ -185,7 +185,7 @@ public void Json_Serialize()
script.Emit(OpCode.SETITEM);
script.EmitSysCall(ApplicationEngine.System_Json_Serialize);
- using (var engine = new ApplicationEngine(TriggerType.Application, null, null, 0, true))
+ using (var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 0, true))
{
engine.LoadScript(script.ToArray());
@@ -207,7 +207,7 @@ public void Json_Serialize()
script.EmitSysCall(ApplicationEngine.System_Storage_GetContext);
script.EmitSysCall(ApplicationEngine.System_Json_Serialize);
- using (var engine = new ApplicationEngine(TriggerType.Application, null, null, 0, true))
+ using (var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 0, true))
{
engine.LoadScript(script.ToArray());
@@ -227,7 +227,7 @@ public void System_ExecutionEngine_GetScriptContainer()
// Without tx
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(script.ToArray());
Assert.AreEqual(engine.Execute(), VMState.HALT);
@@ -239,6 +239,7 @@ public void System_ExecutionEngine_GetScriptContainer()
var tx = new Transaction()
{
Script = new byte[] { 0x01 },
+ Signers = new Signer[] { new Signer() { Account = UInt160.Zero, Scopes = WitnessScope.FeeOnly } },
Attributes = Array.Empty(),
NetworkFee = 0x02,
SystemFee = 0x03,
@@ -246,10 +247,9 @@ public void System_ExecutionEngine_GetScriptContainer()
ValidUntilBlock = 0x05,
Version = 0x06,
Witnesses = new Witness[] { new Witness() { VerificationScript = new byte[] { 0x07 } } },
- Sender = UInt160.Parse("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
};
- engine = new ApplicationEngine(TriggerType.Application, tx, snapshot, 0, true);
+ engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, 0, true);
engine.LoadScript(script.ToArray());
Assert.AreEqual(engine.Execute(), VMState.HALT);
@@ -278,7 +278,7 @@ public void System_Runtime_GasLeft()
// Execute
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 100_000_000, false);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 100_000_000, false);
engine.LoadScript(script.ToArray());
Assert.AreEqual(engine.Execute(), VMState.HALT);
@@ -299,7 +299,7 @@ public void System_Runtime_GasLeft()
// Execute
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(script.ToArray());
// Check the results
@@ -353,7 +353,7 @@ public void System_Runtime_GetInvocationCounter()
// Execute
- var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
+ var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(script.ToArray());
Assert.AreEqual(VMState.HALT, engine.Execute());
diff --git a/tests/neo.UnitTests/TestUtils.cs b/tests/neo.UnitTests/TestUtils.cs
index adaf205ea1..a97869c8b5 100644
--- a/tests/neo.UnitTests/TestUtils.cs
+++ b/tests/neo.UnitTests/TestUtils.cs
@@ -22,18 +22,19 @@ public static ContractManifest CreateDefaultManifest(UInt160 hash)
{
return new ContractManifest()
{
- Permissions = new[] { ContractPermission.DefaultPermission },
+ Groups = new ContractGroup[0],
+ Features = ContractFeatures.NoProperty,
+ SupportedStandards = Array.Empty(),
Abi = new ContractAbi()
{
Hash = hash,
Events = new ContractEventDescriptor[0],
Methods = new ContractMethodDescriptor[0]
},
- Features = ContractFeatures.NoProperty,
- Groups = new ContractGroup[0],
- SafeMethods = WildcardContainer.Create(),
+ Permissions = new[] { ContractPermission.DefaultPermission },
Trusts = WildcardContainer.Create(),
- Extra = null,
+ SafeMethods = WildcardContainer.Create(),
+ Extra = null
};
}
@@ -80,7 +81,7 @@ public static NEP6Wallet GenerateTestWallet()
{
JObject wallet = new JObject();
wallet["name"] = "noname";
- wallet["version"] = new System.Version("3.0").ToString();
+ wallet["version"] = new Version("3.0").ToString();
wallet["scrypt"] = new ScryptParameters(0, 0, 0).ToJson();
wallet["accounts"] = new JArray();
wallet["extra"] = null;
@@ -88,13 +89,17 @@ public static NEP6Wallet GenerateTestWallet()
return new NEP6Wallet(wallet);
}
- public static Transaction GetTransaction()
+ public static Transaction GetTransaction(UInt160 sender)
{
return new Transaction
{
Script = new byte[1],
- Sender = UInt160.Zero,
Attributes = Array.Empty(),
+ Signers = new[]{ new Signer()
+ {
+ Account = sender,
+ Scopes = WitnessScope.CalledByEntry
+ } },
Witnesses = new Witness[]{ new Witness
{
InvocationScript = new byte[0],
@@ -154,7 +159,7 @@ public static void SetupBlockWithValues(Block block, UInt256 val256, out UInt256
{
for (int i = 0; i < numberOfTransactions; i++)
{
- transactionsVal[i] = TestUtils.GetTransaction();
+ transactionsVal[i] = TestUtils.GetTransaction(UInt160.Zero);
}
}
@@ -189,8 +194,8 @@ public static Transaction CreateRandomHashTransaction()
return new Transaction
{
Script = randomBytes,
- Sender = UInt160.Zero,
Attributes = Array.Empty(),
+ Signers = new Signer[] { new Signer() { Account = UInt160.Zero } },
Witnesses = new[]
{
new Witness
diff --git a/tests/neo.UnitTests/Wallets/UT_Wallet.cs b/tests/neo.UnitTests/Wallets/UT_Wallet.cs
index e63145ff5d..7f4ad69332 100644
--- a/tests/neo.UnitTests/Wallets/UT_Wallet.cs
+++ b/tests/neo.UnitTests/Wallets/UT_Wallet.cs
@@ -367,8 +367,8 @@ public void TestMakeTransaction1()
public void TestMakeTransaction2()
{
MyWallet wallet = new MyWallet();
- Action action = () => wallet.MakeTransaction(new byte[] { }, UInt160.Zero, new TransactionAttribute[] { });
- action.Should().Throw();
+ Action action = () => wallet.MakeTransaction(new byte[] { }, null, null, Array.Empty());
+ action.Should().Throw();
Contract contract = Contract.Create(new ContractParameterType[] { ContractParameterType.Boolean }, new byte[] { 1 });
WalletAccount account = wallet.CreateAccount(contract, glkey.PrivateKey);
@@ -381,10 +381,15 @@ public void TestMakeTransaction2()
entry.GetInteroperable().Balance = 1000000 * NativeContract.GAS.Factor;
snapshot.Commit();
- var tx = wallet.MakeTransaction(new byte[] { }, account.ScriptHash, new TransactionAttribute[] { });
+ var tx = wallet.MakeTransaction(new byte[] { }, account.ScriptHash, new[]{ new Signer()
+ {
+ Account = account.ScriptHash,
+ Scopes = WitnessScope.CalledByEntry
+ }}, new TransactionAttribute[] { });
+
tx.Should().NotBeNull();
- tx = wallet.MakeTransaction(new byte[] { }, null, new TransactionAttribute[] { });
+ tx = wallet.MakeTransaction(new byte[] { }, null, null, Array.Empty());
tx.Should().NotBeNull();
entry = snapshot.Storages.GetAndChange(key, () => new StorageItem(new AccountState()));