diff --git a/src/neo/Consensus/ConsensusContext.cs b/src/neo/Consensus/ConsensusContext.cs
index d05b4a64ea..cab0ce8370 100644
--- a/src/neo/Consensus/ConsensusContext.cs
+++ b/src/neo/Consensus/ConsensusContext.cs
@@ -21,7 +21,7 @@ internal class ConsensusContext : IDisposable, ISerializable
///
/// Key for saving consensus state.
///
- private static readonly byte[] ConsensusStateKey = { 0xf4 };
+ private const byte ConsensusStatePrefix = 0xf4;
public Block Block;
public byte ViewNumber;
@@ -42,11 +42,11 @@ internal class ConsensusContext : IDisposable, ISerializable
///
public SendersFeeMonitor SendersFeeMonitor = new SendersFeeMonitor();
- public Snapshot Snapshot { get; private set; }
+ public SnapshotView Snapshot { get; private set; }
private KeyPair keyPair;
private int _witnessSize;
private readonly Wallet wallet;
- private readonly Store store;
+ private readonly IStore store;
public int F => (Validators.Length - 1) / 3;
public int M => Validators.Length - F;
@@ -74,7 +74,7 @@ internal class ConsensusContext : IDisposable, ISerializable
public int Size => throw new NotImplementedException();
- public ConsensusContext(Wallet wallet, Store store)
+ public ConsensusContext(Wallet wallet, IStore store)
{
this.wallet = wallet;
this.store = store;
@@ -146,7 +146,7 @@ public uint GetPrimaryIndex(byte viewNumber)
public bool Load()
{
- byte[] data = store.Get(ConsensusStateKey);
+ byte[] data = store.TryGet(ConsensusStatePrefix, null);
if (data is null || data.Length == 0) return false;
using (MemoryStream ms = new MemoryStream(data, false))
using (BinaryReader reader = new BinaryReader(ms))
@@ -409,7 +409,7 @@ public void Reset(byte viewNumber)
public void Save()
{
- store.PutSync(ConsensusStateKey, this.ToArray());
+ store.PutSync(ConsensusStatePrefix, null, this.ToArray());
}
public void Serialize(BinaryWriter writer)
diff --git a/src/neo/Consensus/ConsensusService.cs b/src/neo/Consensus/ConsensusService.cs
index 9d0bd5a343..3c5c334e11 100644
--- a/src/neo/Consensus/ConsensusService.cs
+++ b/src/neo/Consensus/ConsensusService.cs
@@ -46,7 +46,7 @@ internal class Timer { public uint Height; public byte ViewNumber; }
///
private bool isRecovering = false;
- public ConsensusService(IActorRef localNode, IActorRef taskManager, Store store, Wallet wallet)
+ public ConsensusService(IActorRef localNode, IActorRef taskManager, IStore store, Wallet wallet)
: this(localNode, taskManager, new ConsensusContext(wallet, store))
{
}
@@ -601,7 +601,7 @@ protected override void PostStop()
base.PostStop();
}
- public static Props Props(IActorRef localNode, IActorRef taskManager, Store store, Wallet wallet)
+ public static Props Props(IActorRef localNode, IActorRef taskManager, IStore store, Wallet wallet)
{
return Akka.Actor.Props.Create(() => new ConsensusService(localNode, taskManager, store, wallet)).WithMailbox("consensus-service-mailbox");
}
diff --git a/src/neo/IO/Caching/CloneCache.cs b/src/neo/IO/Caching/CloneCache.cs
index 0dd030fcb6..559ee3d279 100644
--- a/src/neo/IO/Caching/CloneCache.cs
+++ b/src/neo/IO/Caching/CloneCache.cs
@@ -19,15 +19,15 @@ protected override void AddInternal(TKey key, TValue value)
innerCache.Add(key, value);
}
- public override void DeleteInternal(TKey key)
+ protected override void DeleteInternal(TKey key)
{
innerCache.Delete(key);
}
- protected override IEnumerable> FindInternal(byte[] key_prefix)
+ protected override IEnumerable<(TKey, TValue)> FindInternal(byte[] key_prefix)
{
- foreach (KeyValuePair pair in innerCache.Find(key_prefix))
- yield return new KeyValuePair(pair.Key, pair.Value.Clone());
+ foreach (var (key, value) in innerCache.Find(key_prefix))
+ yield return (key, value.Clone());
}
protected override TValue GetInternal(TKey key)
diff --git a/src/neo/IO/Caching/DataCache.cs b/src/neo/IO/Caching/DataCache.cs
index dc97031d10..373c4f2757 100644
--- a/src/neo/IO/Caching/DataCache.cs
+++ b/src/neo/IO/Caching/DataCache.cs
@@ -107,7 +107,7 @@ public void Delete(TKey key)
}
}
- public abstract void DeleteInternal(TKey key);
+ protected abstract void DeleteInternal(TKey key);
public void DeleteWhere(Func predicate)
{
@@ -123,7 +123,7 @@ public void DeleteWhere(Func predicate)
///
/// Must maintain the deserialized format of TKey
/// Entries found with the desired prefix
- public IEnumerable> Find(byte[] key_prefix = null)
+ public IEnumerable<(TKey Key, TValue Value)> Find(byte[] key_prefix = null)
{
IEnumerable<(byte[], TKey, TValue)> cached;
lock (dictionary)
@@ -159,13 +159,13 @@ public void DeleteWhere(Func predicate)
{
if (!c2 || (c1 && ByteArrayComparer.Default.Compare(i1.KeyBytes, i2.KeyBytes) < 0))
{
- yield return new KeyValuePair(i1.Key, i1.Item);
+ yield return (i1.Key, i1.Item);
c1 = e1.MoveNext();
i1 = c1 ? e1.Current : default;
}
else
{
- yield return new KeyValuePair(i2.Key, i2.Item);
+ yield return (i2.Key, i2.Item);
c2 = e2.MoveNext();
i2 = c2 ? e2.Current : default;
}
@@ -173,7 +173,7 @@ public void DeleteWhere(Func predicate)
}
}
- protected abstract IEnumerable> FindInternal(byte[] key_prefix);
+ protected abstract IEnumerable<(TKey Key, TValue Value)> FindInternal(byte[] key_prefix);
public IEnumerable GetChangeSet()
{
diff --git a/src/neo/IO/Data/LevelDB/SliceBuilder.cs b/src/neo/IO/Data/LevelDB/SliceBuilder.cs
index d5888c6b5e..cf1cff0264 100644
--- a/src/neo/IO/Data/LevelDB/SliceBuilder.cs
+++ b/src/neo/IO/Data/LevelDB/SliceBuilder.cs
@@ -38,19 +38,22 @@ public SliceBuilder Add(long value)
public SliceBuilder Add(IEnumerable value)
{
- data.AddRange(value);
+ if (value != null)
+ data.AddRange(value);
return this;
}
public SliceBuilder Add(string value)
{
- data.AddRange(Encoding.UTF8.GetBytes(value));
+ if (value != null)
+ data.AddRange(Encoding.UTF8.GetBytes(value));
return this;
}
public SliceBuilder Add(ISerializable value)
{
- data.AddRange(value.ToArray());
+ if (value != null)
+ data.AddRange(value.ToArray());
return this;
}
diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs
index 07575b895e..14b38860cf 100644
--- a/src/neo/Ledger/Blockchain.cs
+++ b/src/neo/Ledger/Blockchain.cs
@@ -62,9 +62,10 @@ public class FillCompleted { }
private readonly Dictionary block_cache = new Dictionary();
private readonly Dictionary> block_cache_unverified = new Dictionary>();
internal readonly RelayCache ConsensusRelayCache = new RelayCache(100);
- private Snapshot currentSnapshot;
+ private SnapshotView currentSnapshot;
- public Store Store { get; }
+ public IStore Store { get; }
+ public ReadOnlyView View { get; }
public MemoryPool MemPool { get; }
public uint Height => currentSnapshot.Height;
public uint HeaderHeight => currentSnapshot.HeaderHeight;
@@ -95,27 +96,28 @@ static Blockchain()
}
}
- public Blockchain(NeoSystem system, Store store)
+ public Blockchain(NeoSystem system, IStore store)
{
this.system = system;
this.MemPool = new MemoryPool(system, ProtocolSettings.Default.MemoryPoolMaxTransactions);
this.Store = store;
+ this.View = new ReadOnlyView(store);
lock (lockObj)
{
if (singleton != null)
throw new InvalidOperationException();
- header_index.AddRange(store.GetHeaderHashList().Find().OrderBy(p => (uint)p.Key).SelectMany(p => p.Value.Hashes));
+ header_index.AddRange(View.HeaderHashList.Find().OrderBy(p => (uint)p.Key).SelectMany(p => p.Value.Hashes));
stored_header_count += (uint)header_index.Count;
if (stored_header_count == 0)
{
- header_index.AddRange(store.GetBlocks().Find().OrderBy(p => p.Value.Index).Select(p => p.Key));
+ header_index.AddRange(View.Blocks.Find().OrderBy(p => p.Value.Index).Select(p => p.Key));
}
else
{
- HashIndexState hashIndex = store.GetHeaderHashIndex().Get();
+ HashIndexState hashIndex = View.HeaderHashIndex.Get();
if (hashIndex.Index >= stored_header_count)
{
- DataCache cache = store.GetBlocks();
+ DataCache cache = View.Blocks;
for (UInt256 hash = hashIndex.Hash; hash != header_index[(int)stored_header_count - 1];)
{
header_index.Insert((int)stored_header_count, hash);
@@ -139,13 +141,13 @@ public Blockchain(NeoSystem system, Store store)
public bool ContainsBlock(UInt256 hash)
{
if (block_cache.ContainsKey(hash)) return true;
- return Store.ContainsBlock(hash);
+ return View.ContainsBlock(hash);
}
public bool ContainsTransaction(UInt256 hash)
{
if (MemPool.ContainsKey(hash)) return true;
- return Store.ContainsTransaction(hash);
+ return View.ContainsTransaction(hash);
}
private static Transaction DeployNativeContracts()
@@ -175,11 +177,19 @@ private static Transaction DeployNativeContracts()
};
}
+ public Block GetBlock(uint index)
+ {
+ if (index == 0) return GenesisBlock;
+ UInt256 hash = GetBlockHash(index);
+ if (hash == null) return null;
+ return GetBlock(hash);
+ }
+
public Block GetBlock(UInt256 hash)
{
if (block_cache.TryGetValue(hash, out Block block))
return block;
- return Store.GetBlock(hash);
+ return View.GetBlock(hash);
}
public UInt256 GetBlockHash(uint index)
@@ -193,16 +203,38 @@ public static UInt160 GetConsensusAddress(ECPoint[] validators)
return Contract.CreateMultiSigRedeemScript(validators.Length - (validators.Length - 1) / 3, validators).ToScriptHash();
}
- public Snapshot GetSnapshot()
+ public Header GetHeader(uint index)
+ {
+ if (index == 0) return GenesisBlock.Header;
+ UInt256 hash = GetBlockHash(index);
+ if (hash == null) return null;
+ return GetHeader(hash);
+ }
+
+ public Header GetHeader(UInt256 hash)
+ {
+ if (block_cache.TryGetValue(hash, out Block block))
+ return block.Header;
+ return View.GetHeader(hash);
+ }
+
+ public UInt256 GetNextBlockHash(UInt256 hash)
+ {
+ Header header = GetHeader(hash);
+ if (header == null) return null;
+ return GetBlockHash(header.Index + 1);
+ }
+
+ public SnapshotView GetSnapshot()
{
- return Store.GetSnapshot();
+ return new SnapshotView(Store);
}
public Transaction GetTransaction(UInt256 hash)
{
if (MemPool.TryGetValue(hash, out Transaction transaction))
return transaction;
- return Store.GetTransaction(hash);
+ return View.GetTransaction(hash);
}
private void OnImport(IEnumerable blocks)
@@ -237,7 +269,7 @@ private void OnFillMemoryPool(IEnumerable transactions)
// Add the transactions to the memory pool
foreach (var tx in transactions)
{
- if (Store.ContainsTransaction(tx.Hash))
+ if (View.ContainsTransaction(tx.Hash))
continue;
if (!NativeContract.Policy.CheckPolicy(tx, currentSnapshot))
continue;
@@ -320,7 +352,7 @@ private RelayResultReason OnNewBlock(Block block)
if (block.Index == header_index.Count)
{
header_index.Add(block.Hash);
- using (Snapshot snapshot = GetSnapshot())
+ using (SnapshotView snapshot = GetSnapshot())
{
snapshot.Blocks.Add(block.Hash, block.Header.Trim());
snapshot.HeaderHashIndex.GetAndChange().Set(block);
@@ -344,7 +376,7 @@ private RelayResultReason OnNewConsensus(ConsensusPayload payload)
private void OnNewHeaders(Header[] headers)
{
- using (Snapshot snapshot = GetSnapshot())
+ using (SnapshotView snapshot = GetSnapshot())
{
foreach (Header header in headers)
{
@@ -425,7 +457,7 @@ protected override void OnReceive(object message)
private void Persist(Block block)
{
- using (Snapshot snapshot = GetSnapshot())
+ using (SnapshotView snapshot = GetSnapshot())
{
List all_application_executed = new List();
snapshot.PersistingBlock = block;
@@ -503,12 +535,12 @@ protected override void PostStop()
currentSnapshot?.Dispose();
}
- public static Props Props(NeoSystem system, Store store)
+ public static Props Props(NeoSystem system, IStore store)
{
return Akka.Actor.Props.Create(() => new Blockchain(system, store)).WithMailbox("blockchain-mailbox");
}
- private void SaveHeaderHashList(Snapshot snapshot = null)
+ private void SaveHeaderHashList(SnapshotView snapshot = null)
{
if ((header_index.Count - stored_header_count < 2000))
return;
diff --git a/src/neo/Ledger/MemoryPool.cs b/src/neo/Ledger/MemoryPool.cs
index 78df9b97f6..4b9f1b8139 100644
--- a/src/neo/Ledger/MemoryPool.cs
+++ b/src/neo/Ledger/MemoryPool.cs
@@ -105,7 +105,7 @@ public MemoryPool(NeoSystem system, int capacity)
Capacity = capacity;
}
- internal bool LoadPolicy(Snapshot snapshot)
+ internal bool LoadPolicy(StoreView snapshot)
{
_maxTxPerBlock = (int)NativeContract.Policy.GetMaxTransactionsPerBlock(snapshot);
long newFeePerByte = NativeContract.Policy.GetFeePerByte(snapshot);
@@ -348,7 +348,7 @@ internal void InvalidateVerifiedTransactions()
}
// Note: this must only be called from a single thread (the Blockchain actor)
- internal void UpdatePoolForBlockPersisted(Block block, Snapshot snapshot)
+ internal void UpdatePoolForBlockPersisted(Block block, StoreView snapshot)
{
bool policyChanged = LoadPolicy(snapshot);
@@ -407,7 +407,7 @@ internal void InvalidateAllTransactions()
}
private int ReverifyTransactions(SortedSet verifiedSortedTxPool,
- SortedSet unverifiedSortedTxPool, int count, double millisecondsTimeout, Snapshot snapshot)
+ SortedSet unverifiedSortedTxPool, int count, double millisecondsTimeout, StoreView snapshot)
{
DateTime reverifyCutOffTimeStamp = DateTime.UtcNow.AddMilliseconds(millisecondsTimeout);
List reverifiedItems = new List(count);
@@ -483,7 +483,7 @@ internal void InvalidateAllTransactions()
/// Max transactions to reverify, the value passed can be >=1
/// The snapshot to use for verifying.
/// true if more unsorted messages exist, otherwise false
- internal bool ReVerifyTopUnverifiedTransactionsIfNeeded(int maxToVerify, Snapshot snapshot)
+ internal bool ReVerifyTopUnverifiedTransactionsIfNeeded(int maxToVerify, StoreView snapshot)
{
if (Blockchain.Singleton.Height < Blockchain.Singleton.HeaderHeight)
return false;
diff --git a/src/neo/NeoSystem.cs b/src/neo/NeoSystem.cs
index 9265f47645..b1ef9b6ec8 100644
--- a/src/neo/NeoSystem.cs
+++ b/src/neo/NeoSystem.cs
@@ -26,11 +26,11 @@ public class NeoSystem : IDisposable
public IActorRef Consensus { get; private set; }
public RpcServer RpcServer { get; private set; }
- private readonly Store store;
+ private readonly IStore store;
private ChannelsConfig start_message = null;
private bool suspend = false;
- public NeoSystem(Store store)
+ public NeoSystem(IStore store)
{
this.store = store;
Plugin.LoadPlugins(this);
@@ -69,7 +69,7 @@ internal void ResumeNodeStartup()
}
}
- public void StartConsensus(Wallet wallet, Store consensus_store = null, bool ignoreRecoveryLogs = false)
+ public void StartConsensus(Wallet wallet, IStore consensus_store = null, bool ignoreRecoveryLogs = false)
{
Consensus = ActorSystem.ActorOf(ConsensusService.Props(this.LocalNode, this.TaskManager, consensus_store ?? store, wallet));
Consensus.Tell(new ConsensusService.Start { IgnoreRecoveryLogs = ignoreRecoveryLogs }, Blockchain);
diff --git a/src/neo/Network/P2P/Payloads/BlockBase.cs b/src/neo/Network/P2P/Payloads/BlockBase.cs
index 4274cb990a..37ab7abe66 100644
--- a/src/neo/Network/P2P/Payloads/BlockBase.cs
+++ b/src/neo/Network/P2P/Payloads/BlockBase.cs
@@ -74,7 +74,7 @@ void IVerifiable.DeserializeUnsigned(BinaryReader reader)
NextConsensus = reader.ReadSerializable();
}
- UInt160[] IVerifiable.GetScriptHashesForVerifying(Snapshot snapshot)
+ UInt160[] IVerifiable.GetScriptHashesForVerifying(StoreView snapshot)
{
if (PrevHash == UInt256.Zero) return new[] { Witness.ScriptHash };
Header prev_header = snapshot.GetHeader(PrevHash);
@@ -124,7 +124,7 @@ public void FromJson(JObject json)
Witness = ((JArray)json["witnesses"]).Select(p => Witness.FromJson(p)).FirstOrDefault();
}
- public virtual bool Verify(Snapshot snapshot)
+ public virtual bool Verify(StoreView snapshot)
{
Header prev_header = snapshot.GetHeader(PrevHash);
if (prev_header == null) return false;
diff --git a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs
index 062e5d9830..21730a3470 100644
--- a/src/neo/Network/P2P/Payloads/ConsensusPayload.cs
+++ b/src/neo/Network/P2P/Payloads/ConsensusPayload.cs
@@ -95,7 +95,7 @@ void IVerifiable.DeserializeUnsigned(BinaryReader reader)
Data = reader.ReadVarBytes();
}
- UInt160[] IVerifiable.GetScriptHashesForVerifying(Snapshot snapshot)
+ UInt160[] IVerifiable.GetScriptHashesForVerifying(StoreView snapshot)
{
ECPoint[] validators = NativeContract.NEO.GetNextBlockValidators(snapshot);
if (validators.Length <= ValidatorIndex)
@@ -118,7 +118,7 @@ void IVerifiable.SerializeUnsigned(BinaryWriter writer)
writer.WriteVarBytes(Data);
}
- public bool Verify(Snapshot snapshot)
+ public bool Verify(StoreView snapshot)
{
if (BlockIndex <= snapshot.Height)
return false;
diff --git a/src/neo/Network/P2P/Payloads/IInventory.cs b/src/neo/Network/P2P/Payloads/IInventory.cs
index 26b62346d9..2b175647c5 100644
--- a/src/neo/Network/P2P/Payloads/IInventory.cs
+++ b/src/neo/Network/P2P/Payloads/IInventory.cs
@@ -8,6 +8,6 @@ public interface IInventory : IVerifiable
InventoryType InventoryType { get; }
- bool Verify(Snapshot snapshot);
+ bool Verify(StoreView snapshot);
}
}
diff --git a/src/neo/Network/P2P/Payloads/IVerifiable.cs b/src/neo/Network/P2P/Payloads/IVerifiable.cs
index 8540d8a626..cecd0570da 100644
--- a/src/neo/Network/P2P/Payloads/IVerifiable.cs
+++ b/src/neo/Network/P2P/Payloads/IVerifiable.cs
@@ -10,7 +10,7 @@ public interface IVerifiable : ISerializable
void DeserializeUnsigned(BinaryReader reader);
- UInt160[] GetScriptHashesForVerifying(Snapshot snapshot);
+ UInt160[] GetScriptHashesForVerifying(StoreView snapshot);
void SerializeUnsigned(BinaryWriter writer);
}
diff --git a/src/neo/Network/P2P/Payloads/Transaction.cs b/src/neo/Network/P2P/Payloads/Transaction.cs
index de81275877..6bda3f8c6b 100644
--- a/src/neo/Network/P2P/Payloads/Transaction.cs
+++ b/src/neo/Network/P2P/Payloads/Transaction.cs
@@ -123,14 +123,14 @@ public override int GetHashCode()
return Hash.GetHashCode();
}
- public UInt160[] GetScriptHashesForVerifying(Snapshot snapshot)
+ public UInt160[] GetScriptHashesForVerifying(StoreView snapshot)
{
var hashes = new HashSet { Sender };
hashes.UnionWith(Cosigners.Select(p => p.Account));
return hashes.OrderBy(p => p).ToArray();
}
- public virtual bool Reverify(Snapshot snapshot, BigInteger totalSenderFeeFromPool)
+ public virtual bool Reverify(StoreView snapshot, BigInteger totalSenderFeeFromPool)
{
if (ValidUntilBlock <= snapshot.Height || ValidUntilBlock > snapshot.Height + MaxValidUntilBlockIncrement)
return false;
@@ -202,12 +202,12 @@ public static Transaction FromJson(JObject json)
return tx;
}
- bool IInventory.Verify(Snapshot snapshot)
+ bool IInventory.Verify(StoreView snapshot)
{
return Verify(snapshot, BigInteger.Zero);
}
- public virtual bool Verify(Snapshot snapshot, BigInteger totalSenderFeeFromPool)
+ public virtual bool Verify(StoreView snapshot, BigInteger totalSenderFeeFromPool)
{
if (!Reverify(snapshot, totalSenderFeeFromPool)) return false;
int size = Size;
diff --git a/src/neo/Network/P2P/ProtocolHandler.cs b/src/neo/Network/P2P/ProtocolHandler.cs
index 1e62e4dfbf..e16d7f238c 100644
--- a/src/neo/Network/P2P/ProtocolHandler.cs
+++ b/src/neo/Network/P2P/ProtocolHandler.cs
@@ -162,7 +162,7 @@ private void OnGetBlocksMessageReceived(GetBlocksPayload payload)
{
UInt256 hash = payload.HashStart;
int count = payload.Count < 0 || payload.Count > InvPayload.MaxHashesCount ? InvPayload.MaxHashesCount : payload.Count;
- TrimmedBlock state = Blockchain.Singleton.Store.GetBlocks().TryGet(hash);
+ TrimmedBlock state = Blockchain.Singleton.View.Blocks.TryGet(hash);
if (state == null) return;
List hashes = new List();
for (uint i = 1; i <= count; i++)
@@ -182,7 +182,7 @@ private void OnGetBlockDataMessageReceived(GetBlockDataPayload payload)
{
for (uint i = payload.IndexStart, max = payload.IndexStart + payload.Count; i < max; i++)
{
- Block block = Blockchain.Singleton.Store.GetBlock(i);
+ Block block = Blockchain.Singleton.GetBlock(i);
if (block == null)
break;
@@ -237,7 +237,7 @@ private void OnGetHeadersMessageReceived(GetBlocksPayload payload)
{
UInt256 hash = payload.HashStart;
int count = payload.Count < 0 || payload.Count > HeadersPayload.MaxHeadersCount ? HeadersPayload.MaxHeadersCount : payload.Count;
- DataCache cache = Blockchain.Singleton.Store.GetBlocks();
+ DataCache cache = Blockchain.Singleton.View.Blocks;
TrimmedBlock state = cache.TryGet(hash);
if (state == null) return;
List headers = new List();
@@ -273,11 +273,11 @@ private void OnInvMessageReceived(InvPayload payload)
switch (payload.Type)
{
case InventoryType.Block:
- using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot())
+ using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
hashes = hashes.Where(p => !snapshot.ContainsBlock(p)).ToArray();
break;
case InventoryType.TX:
- using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot())
+ using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
hashes = hashes.Where(p => !snapshot.ContainsTransaction(p)).ToArray();
break;
}
diff --git a/src/neo/Network/RPC/RpcServer.cs b/src/neo/Network/RPC/RpcServer.cs
index 7414d54d10..953783b5ed 100644
--- a/src/neo/Network/RPC/RpcServer.cs
+++ b/src/neo/Network/RPC/RpcServer.cs
@@ -57,7 +57,7 @@ public void DeserializeUnsigned(BinaryReader reader)
throw new NotImplementedException();
}
- public UInt160[] GetScriptHashesForVerifying(Snapshot snapshot)
+ public UInt160[] GetScriptHashesForVerifying(StoreView snapshot)
{
return _scriptHashesForVerifying;
}
@@ -435,12 +435,12 @@ private JObject GetBlock(JObject key, bool verbose)
if (key is JNumber)
{
uint index = uint.Parse(key.AsString());
- block = Blockchain.Singleton.Store.GetBlock(index);
+ block = Blockchain.Singleton.GetBlock(index);
}
else
{
UInt256 hash = UInt256.Parse(key.AsString());
- block = Blockchain.Singleton.Store.GetBlock(hash);
+ block = Blockchain.Singleton.View.GetBlock(hash);
}
if (block == null)
throw new RpcException(-100, "Unknown block");
@@ -448,7 +448,7 @@ private JObject GetBlock(JObject key, bool verbose)
{
JObject json = block.ToJson();
json["confirmations"] = Blockchain.Singleton.Height - block.Index + 1;
- UInt256 hash = Blockchain.Singleton.Store.GetNextBlockHash(block.Hash);
+ UInt256 hash = Blockchain.Singleton.GetNextBlockHash(block.Hash);
if (hash != null)
json["nextblockhash"] = hash.ToString();
return json;
@@ -476,12 +476,12 @@ private JObject GetBlockHeader(JObject key, bool verbose)
if (key is JNumber)
{
uint height = uint.Parse(key.AsString());
- header = Blockchain.Singleton.Store.GetHeader(height);
+ header = Blockchain.Singleton.GetHeader(height);
}
else
{
UInt256 hash = UInt256.Parse(key.AsString());
- header = Blockchain.Singleton.Store.GetHeader(hash);
+ header = Blockchain.Singleton.View.GetHeader(hash);
}
if (header == null)
throw new RpcException(-100, "Unknown block");
@@ -490,7 +490,7 @@ private JObject GetBlockHeader(JObject key, bool verbose)
{
JObject json = header.ToJson();
json["confirmations"] = Blockchain.Singleton.Height - header.Index + 1;
- UInt256 hash = Blockchain.Singleton.Store.GetNextBlockHash(header.Hash);
+ UInt256 hash = Blockchain.Singleton.GetNextBlockHash(header.Hash);
if (hash != null)
json["nextblockhash"] = hash.ToString();
return json;
@@ -516,7 +516,7 @@ private JObject GetConnectionCount()
private JObject GetContractState(UInt160 script_hash)
{
- ContractState contract = Blockchain.Singleton.Store.GetContracts().TryGet(script_hash);
+ ContractState contract = Blockchain.Singleton.View.Contracts.TryGet(script_hash);
return contract?.ToJson() ?? throw new RpcException(-100, "Unknown contract");
}
@@ -564,10 +564,10 @@ private JObject GetRawTransaction(UInt256 hash, bool verbose)
if (verbose)
{
JObject json = tx.ToJson();
- TransactionState txState = Blockchain.Singleton.Store.GetTransactions().TryGet(hash);
+ TransactionState txState = Blockchain.Singleton.View.Transactions.TryGet(hash);
if (txState != null)
{
- Header header = Blockchain.Singleton.Store.GetHeader(txState.BlockIndex);
+ Header header = Blockchain.Singleton.GetHeader(txState.BlockIndex);
json["blockhash"] = header.Hash.ToString();
json["confirmations"] = Blockchain.Singleton.Height - header.Index + 1;
json["blocktime"] = header.Timestamp;
@@ -580,7 +580,7 @@ private JObject GetRawTransaction(UInt256 hash, bool verbose)
private JObject GetStorage(UInt160 script_hash, byte[] key)
{
- StorageItem item = Blockchain.Singleton.Store.GetStorages().TryGet(new StorageKey
+ StorageItem item = Blockchain.Singleton.View.Storages.TryGet(new StorageKey
{
ScriptHash = script_hash,
Key = key
@@ -590,14 +590,14 @@ private JObject GetStorage(UInt160 script_hash, byte[] key)
private JObject GetTransactionHeight(UInt256 hash)
{
- uint? height = Blockchain.Singleton.Store.GetTransactions().TryGet(hash)?.BlockIndex;
+ uint? height = Blockchain.Singleton.View.Transactions.TryGet(hash)?.BlockIndex;
if (height.HasValue) return height.Value;
throw new RpcException(-100, "Unknown transaction");
}
private JObject GetValidators()
{
- using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot())
+ using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
{
var validators = NativeContract.NEO.GetValidators(snapshot);
return NativeContract.NEO.GetRegisteredValidators(snapshot).Select(p =>
diff --git a/src/neo/Persistence/CloneSnapshot.cs b/src/neo/Persistence/ClonedView.cs
similarity index 52%
rename from src/neo/Persistence/CloneSnapshot.cs
rename to src/neo/Persistence/ClonedView.cs
index 0b79bd2739..927207d6a1 100644
--- a/src/neo/Persistence/CloneSnapshot.cs
+++ b/src/neo/Persistence/ClonedView.cs
@@ -4,7 +4,7 @@
namespace Neo.Persistence
{
- internal class CloneSnapshot : Snapshot
+ internal class ClonedView : StoreView
{
public override DataCache Blocks { get; }
public override DataCache Transactions { get; }
@@ -14,16 +14,16 @@ internal class CloneSnapshot : Snapshot
public override MetaDataCache BlockHashIndex { get; }
public override MetaDataCache HeaderHashIndex { get; }
- public CloneSnapshot(Snapshot snapshot)
+ public ClonedView(StoreView view)
{
- this.PersistingBlock = snapshot.PersistingBlock;
- this.Blocks = snapshot.Blocks.CreateSnapshot();
- this.Transactions = snapshot.Transactions.CreateSnapshot();
- this.Contracts = snapshot.Contracts.CreateSnapshot();
- this.Storages = snapshot.Storages.CreateSnapshot();
- this.HeaderHashList = snapshot.HeaderHashList.CreateSnapshot();
- this.BlockHashIndex = snapshot.BlockHashIndex.CreateSnapshot();
- this.HeaderHashIndex = snapshot.HeaderHashIndex.CreateSnapshot();
+ this.PersistingBlock = view.PersistingBlock;
+ this.Blocks = view.Blocks.CreateSnapshot();
+ this.Transactions = view.Transactions.CreateSnapshot();
+ this.Contracts = view.Contracts.CreateSnapshot();
+ this.Storages = view.Storages.CreateSnapshot();
+ this.HeaderHashList = view.HeaderHashList.CreateSnapshot();
+ this.BlockHashIndex = view.BlockHashIndex.CreateSnapshot();
+ this.HeaderHashIndex = view.HeaderHashIndex.CreateSnapshot();
}
}
}
diff --git a/src/neo/Persistence/Helper.cs b/src/neo/Persistence/Helper.cs
deleted file mode 100644
index 7f412e47d3..0000000000
--- a/src/neo/Persistence/Helper.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using Neo.Ledger;
-using Neo.Network.P2P.Payloads;
-
-namespace Neo.Persistence
-{
- public static class Helper
- {
- public static bool ContainsBlock(this IPersistence persistence, UInt256 hash)
- {
- TrimmedBlock state = persistence.Blocks.TryGet(hash);
- if (state == null) return false;
- return state.IsBlock;
- }
-
- public static bool ContainsTransaction(this IPersistence persistence, UInt256 hash)
- {
- TransactionState state = persistence.Transactions.TryGet(hash);
- return state != null;
- }
-
- public static Block GetBlock(this IPersistence persistence, uint index)
- {
- if (index == 0) return Blockchain.GenesisBlock;
- UInt256 hash = Blockchain.Singleton.GetBlockHash(index);
- if (hash == null) return null;
- return persistence.GetBlock(hash);
- }
-
- public static Block GetBlock(this IPersistence persistence, UInt256 hash)
- {
- TrimmedBlock state = persistence.Blocks.TryGet(hash);
- if (state == null) return null;
- if (!state.IsBlock) return null;
- return state.GetBlock(persistence.Transactions);
- }
-
- public static Header GetHeader(this IPersistence persistence, uint index)
- {
- if (index == 0) return Blockchain.GenesisBlock.Header;
- UInt256 hash = Blockchain.Singleton.GetBlockHash(index);
- if (hash == null) return null;
- return persistence.GetHeader(hash);
- }
-
- public static Header GetHeader(this IPersistence persistence, UInt256 hash)
- {
- return persistence.Blocks.TryGet(hash)?.Header;
- }
-
- public static UInt256 GetNextBlockHash(this IPersistence persistence, UInt256 hash)
- {
- TrimmedBlock state = persistence.Blocks.TryGet(hash);
- if (state == null) return null;
- return Blockchain.Singleton.GetBlockHash(state.Index + 1);
- }
-
- public static Transaction GetTransaction(this IPersistence persistence, UInt256 hash)
- {
- return persistence.Transactions.TryGet(hash)?.Transaction;
- }
- }
-}
diff --git a/src/neo/Persistence/IPersistence.cs b/src/neo/Persistence/IPersistence.cs
deleted file mode 100644
index 0632b5d0fa..0000000000
--- a/src/neo/Persistence/IPersistence.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using Neo.IO.Caching;
-using Neo.IO.Wrappers;
-using Neo.Ledger;
-
-namespace Neo.Persistence
-{
- public interface IPersistence
- {
- DataCache Blocks { get; }
- DataCache Transactions { get; }
- DataCache Contracts { get; }
- DataCache Storages { get; }
- DataCache HeaderHashList { get; }
- MetaDataCache BlockHashIndex { get; }
- MetaDataCache HeaderHashIndex { get; }
- }
-}
diff --git a/src/neo/Persistence/IReadOnlyStore.cs b/src/neo/Persistence/IReadOnlyStore.cs
new file mode 100644
index 0000000000..7a23bd4c80
--- /dev/null
+++ b/src/neo/Persistence/IReadOnlyStore.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+
+namespace Neo.Persistence
+{
+ ///
+ /// This interface provides methods to read from the database.
+ ///
+ public interface IReadOnlyStore
+ {
+ IEnumerable<(byte[] Key, byte[] Value)> Find(byte table, byte[] prefix);
+ byte[] TryGet(byte table, byte[] key);
+ }
+}
diff --git a/src/neo/Persistence/ISnapshot.cs b/src/neo/Persistence/ISnapshot.cs
new file mode 100644
index 0000000000..335089d4bc
--- /dev/null
+++ b/src/neo/Persistence/ISnapshot.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace Neo.Persistence
+{
+ ///
+ /// This interface provides methods for reading, writing, and committing from/to snapshot.
+ ///
+ public interface ISnapshot : IDisposable, IReadOnlyStore
+ {
+ void Commit();
+ void Delete(byte table, byte[] key);
+ void Put(byte table, byte[] key, byte[] value);
+ }
+}
diff --git a/src/neo/Persistence/IStore.cs b/src/neo/Persistence/IStore.cs
new file mode 100644
index 0000000000..e91e0b9386
--- /dev/null
+++ b/src/neo/Persistence/IStore.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace Neo.Persistence
+{
+ ///
+ /// This interface provides methods for reading, writing from/to database. Developers should implement this interface to provide new storage engines for NEO.
+ ///
+ public interface IStore : IDisposable, IReadOnlyStore
+ {
+ void Delete(byte table, byte[] key);
+ ISnapshot GetSnapshot();
+ void Put(byte table, byte[] key, byte[] value);
+ void PutSync(byte table, byte[] key, byte[] value);
+ }
+}
diff --git a/src/neo/Persistence/LevelDB/DbCache.cs b/src/neo/Persistence/LevelDB/DbCache.cs
deleted file mode 100644
index ae55b31326..0000000000
--- a/src/neo/Persistence/LevelDB/DbCache.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-using Neo.IO;
-using Neo.IO.Caching;
-using Neo.IO.Data.LevelDB;
-using System;
-using System.Collections.Generic;
-
-namespace Neo.Persistence.LevelDB
-{
- public class DbCache : DataCache
- where TKey : IEquatable, ISerializable, new()
- where TValue : class, ICloneable, ISerializable, new()
- {
- private readonly DB db;
- private readonly ReadOptions options;
- private readonly WriteBatch batch;
- private readonly byte prefix;
-
- public DbCache(DB db, ReadOptions options, WriteBatch batch, byte prefix)
- {
- this.db = db;
- this.options = options ?? ReadOptions.Default;
- this.batch = batch;
- this.prefix = prefix;
- }
-
- protected override void AddInternal(TKey key, TValue value)
- {
- batch?.Put(prefix, key, value);
- }
-
- public override void DeleteInternal(TKey key)
- {
- batch?.Delete(prefix, key);
- }
-
- protected override IEnumerable> FindInternal(byte[] key_prefix)
- {
- return db.Find(options, SliceBuilder.Begin(prefix).Add(key_prefix), (k, v) => new KeyValuePair(k.ToArray().AsSerializable(1), v.ToArray().AsSerializable()));
- }
-
- protected override TValue GetInternal(TKey key)
- {
- return db.Get(options, prefix, key);
- }
-
- protected override TValue TryGetInternal(TKey key)
- {
- return db.TryGet(options, prefix, key);
- }
-
- protected override void UpdateInternal(TKey key, TValue value)
- {
- batch?.Put(prefix, key, value);
- }
- }
-}
diff --git a/src/neo/Persistence/LevelDB/DbMetaDataCache.cs b/src/neo/Persistence/LevelDB/DbMetaDataCache.cs
deleted file mode 100644
index 0163d84e39..0000000000
--- a/src/neo/Persistence/LevelDB/DbMetaDataCache.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using Neo.IO;
-using Neo.IO.Caching;
-using Neo.IO.Data.LevelDB;
-using System;
-
-namespace Neo.Persistence.LevelDB
-{
- internal class DbMetaDataCache : MetaDataCache
- where T : class, ICloneable, ISerializable, new()
- {
- private readonly DB db;
- private readonly ReadOptions options;
- private readonly WriteBatch batch;
- private readonly byte prefix;
-
- public DbMetaDataCache(DB db, ReadOptions options, WriteBatch batch, byte prefix, Func factory = null)
- : base(factory)
- {
- this.db = db;
- this.options = options ?? ReadOptions.Default;
- this.batch = batch;
- this.prefix = prefix;
- }
-
- protected override void AddInternal(T item)
- {
- batch?.Put(prefix, item.ToArray());
- }
-
- protected override T TryGetInternal()
- {
- if (!db.TryGet(options, prefix, out Slice slice))
- return null;
- return slice.ToArray().AsSerializable();
- }
-
- protected override void UpdateInternal(T item)
- {
- batch?.Put(prefix, item.ToArray());
- }
- }
-}
diff --git a/src/neo/Persistence/LevelDB/DbSnapshot.cs b/src/neo/Persistence/LevelDB/DbSnapshot.cs
deleted file mode 100644
index 365584fa7c..0000000000
--- a/src/neo/Persistence/LevelDB/DbSnapshot.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using Neo.IO.Caching;
-using Neo.IO.Data.LevelDB;
-using Neo.IO.Wrappers;
-using Neo.Ledger;
-using LSnapshot = Neo.IO.Data.LevelDB.Snapshot;
-
-namespace Neo.Persistence.LevelDB
-{
- internal class DbSnapshot : Snapshot
- {
- private readonly DB db;
- private readonly LSnapshot snapshot;
- private readonly WriteBatch batch;
-
- public override DataCache Blocks { get; }
- public override DataCache Transactions { get; }
- public override DataCache Contracts { get; }
- public override DataCache Storages { get; }
- public override DataCache HeaderHashList { get; }
- public override MetaDataCache BlockHashIndex { get; }
- public override MetaDataCache HeaderHashIndex { get; }
-
- public DbSnapshot(DB db)
- {
- this.db = db;
- this.snapshot = db.GetSnapshot();
- this.batch = new WriteBatch();
- ReadOptions options = new ReadOptions { FillCache = false, Snapshot = snapshot };
- Blocks = new DbCache(db, options, batch, Prefixes.DATA_Block);
- Transactions = new DbCache(db, options, batch, Prefixes.DATA_Transaction);
- Contracts = new DbCache(db, options, batch, Prefixes.ST_Contract);
- Storages = new DbCache(db, options, batch, Prefixes.ST_Storage);
- HeaderHashList = new DbCache(db, options, batch, Prefixes.IX_HeaderHashList);
- BlockHashIndex = new DbMetaDataCache(db, options, batch, Prefixes.IX_CurrentBlock);
- HeaderHashIndex = new DbMetaDataCache(db, options, batch, Prefixes.IX_CurrentHeader);
- }
-
- public override void Commit()
- {
- base.Commit();
- db.Write(WriteOptions.Default, batch);
- }
-
- public override void Dispose()
- {
- snapshot.Dispose();
- }
- }
-}
diff --git a/src/neo/Persistence/LevelDB/LevelDBStore.cs b/src/neo/Persistence/LevelDB/LevelDBStore.cs
deleted file mode 100644
index 805c1fe915..0000000000
--- a/src/neo/Persistence/LevelDB/LevelDBStore.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-using Neo.IO.Caching;
-using Neo.IO.Data.LevelDB;
-using Neo.IO.Wrappers;
-using Neo.Ledger;
-using System;
-using System.Reflection;
-
-namespace Neo.Persistence.LevelDB
-{
- public class LevelDBStore : Store, IDisposable
- {
- private readonly DB db;
-
- public LevelDBStore(string path)
- {
- this.db = DB.Open(path, new Options { CreateIfMissing = true });
- if (db.TryGet(ReadOptions.Default, SliceBuilder.Begin(Prefixes.SYS_Version), out Slice value) && Version.TryParse(value.ToString(), out Version version) && version >= Version.Parse("2.9.1"))
- return;
- WriteBatch batch = new WriteBatch();
- ReadOptions options = new ReadOptions { FillCache = false };
- using (Iterator it = db.NewIterator(options))
- {
- for (it.SeekToFirst(); it.Valid(); it.Next())
- {
- batch.Delete(it.Key());
- }
- }
- db.Put(WriteOptions.Default, SliceBuilder.Begin(Prefixes.SYS_Version), Assembly.GetExecutingAssembly().GetName().Version.ToString());
- db.Write(WriteOptions.Default, batch);
- }
-
- public void Dispose()
- {
- db.Dispose();
- }
-
- public override byte[] Get(byte[] key)
- {
- if (!db.TryGet(ReadOptions.Default, key, out Slice slice))
- return null;
- return slice.ToArray();
- }
-
- public override DataCache GetBlocks()
- {
- return new DbCache(db, null, null, Prefixes.DATA_Block);
- }
-
- public override DataCache GetContracts()
- {
- return new DbCache(db, null, null, Prefixes.ST_Contract);
- }
-
- public override Snapshot GetSnapshot()
- {
- return new DbSnapshot(db);
- }
-
- public override DataCache GetStorages()
- {
- return new DbCache(db, null, null, Prefixes.ST_Storage);
- }
-
- public override DataCache GetTransactions()
- {
- return new DbCache(db, null, null, Prefixes.DATA_Transaction);
- }
-
- public override DataCache GetHeaderHashList()
- {
- return new DbCache(db, null, null, Prefixes.IX_HeaderHashList);
- }
-
- public override MetaDataCache GetBlockHashIndex()
- {
- return new DbMetaDataCache(db, null, null, Prefixes.IX_CurrentBlock);
- }
-
- public override MetaDataCache GetHeaderHashIndex()
- {
- return new DbMetaDataCache(db, null, null, Prefixes.IX_CurrentHeader);
- }
-
- public override void Put(byte[] key, byte[] value)
- {
- db.Put(WriteOptions.Default, key, value);
- }
-
- public override void PutSync(byte[] key, byte[] value)
- {
- db.Put(new WriteOptions { Sync = true }, key, value);
- }
- }
-}
diff --git a/src/neo/Persistence/LevelDB/Snapshot.cs b/src/neo/Persistence/LevelDB/Snapshot.cs
new file mode 100644
index 0000000000..dbf5cbe278
--- /dev/null
+++ b/src/neo/Persistence/LevelDB/Snapshot.cs
@@ -0,0 +1,55 @@
+using Neo.IO.Data.LevelDB;
+using System.Collections.Generic;
+using System.Linq;
+using LSnapshot = Neo.IO.Data.LevelDB.Snapshot;
+
+namespace Neo.Persistence.LevelDB
+{
+ internal class Snapshot : ISnapshot
+ {
+ private readonly DB db;
+ private readonly LSnapshot snapshot;
+ private readonly ReadOptions options;
+ private readonly WriteBatch batch;
+
+ public Snapshot(DB db)
+ {
+ this.db = db;
+ this.snapshot = db.GetSnapshot();
+ this.options = new ReadOptions { FillCache = false, Snapshot = snapshot };
+ this.batch = new WriteBatch();
+ }
+
+ public void Commit()
+ {
+ db.Write(WriteOptions.Default, batch);
+ }
+
+ public void Delete(byte table, byte[] key)
+ {
+ batch.Delete(SliceBuilder.Begin(table).Add(key));
+ }
+
+ public void Dispose()
+ {
+ snapshot.Dispose();
+ }
+
+ public IEnumerable<(byte[] Key, byte[] Value)> Find(byte table, byte[] prefix)
+ {
+ return db.Find(options, SliceBuilder.Begin(table).Add(prefix), (k, v) => (k.ToArray().Skip(1).ToArray(), v.ToArray()));
+ }
+
+ public void Put(byte table, byte[] key, byte[] value)
+ {
+ batch.Put(SliceBuilder.Begin(table).Add(key), value);
+ }
+
+ public byte[] TryGet(byte table, byte[] key)
+ {
+ if (!db.TryGet(options, SliceBuilder.Begin(table).Add(key), out Slice slice))
+ return null;
+ return slice.ToArray();
+ }
+ }
+}
diff --git a/src/neo/Persistence/LevelDB/Store.cs b/src/neo/Persistence/LevelDB/Store.cs
new file mode 100644
index 0000000000..fbded76391
--- /dev/null
+++ b/src/neo/Persistence/LevelDB/Store.cs
@@ -0,0 +1,69 @@
+using Neo.IO.Data.LevelDB;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+namespace Neo.Persistence.LevelDB
+{
+ public class Store : IStore
+ {
+ private const byte SYS_Version = 0xf0;
+ private readonly DB db;
+
+ public Store(string path)
+ {
+ this.db = DB.Open(path, new Options { CreateIfMissing = true });
+ if (db.TryGet(ReadOptions.Default, SliceBuilder.Begin(SYS_Version), out Slice value) && Version.TryParse(value.ToString(), out Version version) && version >= Version.Parse("2.9.1"))
+ return;
+ WriteBatch batch = new WriteBatch();
+ ReadOptions options = new ReadOptions { FillCache = false };
+ using (Iterator it = db.NewIterator(options))
+ {
+ for (it.SeekToFirst(); it.Valid(); it.Next())
+ {
+ batch.Delete(it.Key());
+ }
+ }
+ db.Put(WriteOptions.Default, SliceBuilder.Begin(SYS_Version), Assembly.GetExecutingAssembly().GetName().Version.ToString());
+ db.Write(WriteOptions.Default, batch);
+ }
+
+ public void Delete(byte table, byte[] key)
+ {
+ db.Delete(WriteOptions.Default, SliceBuilder.Begin(table).Add(key));
+ }
+
+ public void Dispose()
+ {
+ db.Dispose();
+ }
+
+ public IEnumerable<(byte[], byte[])> Find(byte table, byte[] prefix)
+ {
+ return db.Find(ReadOptions.Default, SliceBuilder.Begin(table).Add(prefix), (k, v) => (k.ToArray().Skip(1).ToArray(), v.ToArray()));
+ }
+
+ public ISnapshot GetSnapshot()
+ {
+ return new Snapshot(db);
+ }
+
+ public void Put(byte table, byte[] key, byte[] value)
+ {
+ db.Put(WriteOptions.Default, SliceBuilder.Begin(table).Add(key), value);
+ }
+
+ public void PutSync(byte table, byte[] key, byte[] value)
+ {
+ db.Put(new WriteOptions { Sync = true }, SliceBuilder.Begin(table).Add(key), value);
+ }
+
+ public byte[] TryGet(byte table, byte[] key)
+ {
+ if (!db.TryGet(ReadOptions.Default, SliceBuilder.Begin(table).Add(key), out Slice slice))
+ return null;
+ return slice.ToArray();
+ }
+ }
+}
diff --git a/src/neo/Persistence/Memory/ByteArrayEqualityComparer.cs b/src/neo/Persistence/Memory/ByteArrayEqualityComparer.cs
new file mode 100644
index 0000000000..97096498aa
--- /dev/null
+++ b/src/neo/Persistence/Memory/ByteArrayEqualityComparer.cs
@@ -0,0 +1,47 @@
+using System.Collections.Generic;
+
+namespace Neo.Persistence.Memory
+{
+ internal class ByteArrayEqualityComparer : IEqualityComparer
+ {
+ public static readonly ByteArrayEqualityComparer Default = new ByteArrayEqualityComparer();
+
+ public unsafe bool Equals(byte[] x, byte[] y)
+ {
+ if (ReferenceEquals(x, y)) return true;
+ if (x is null || y is null) return false;
+ int len = x.Length;
+ if (len != y.Length) return false;
+ if (len == 0) return true;
+ fixed (byte* xp = x, yp = y)
+ {
+ long* xlp = (long*)xp, ylp = (long*)yp;
+ for (; len >= 8; len -= 8)
+ {
+ if (*xlp != *ylp) return false;
+ xlp++;
+ ylp++;
+ }
+ byte* xbp = (byte*)xlp, ybp = (byte*)ylp;
+ for (; len > 0; len--)
+ {
+ if (*xbp != *ybp) return false;
+ xbp++;
+ ybp++;
+ }
+ }
+ return true;
+ }
+
+ public int GetHashCode(byte[] obj)
+ {
+ unchecked
+ {
+ int hash = 17;
+ foreach (byte element in obj)
+ hash = hash * 31 + element;
+ return hash;
+ }
+ }
+ }
+}
diff --git a/src/neo/Persistence/Memory/Helper.cs b/src/neo/Persistence/Memory/Helper.cs
new file mode 100644
index 0000000000..c3535d897d
--- /dev/null
+++ b/src/neo/Persistence/Memory/Helper.cs
@@ -0,0 +1,12 @@
+namespace Neo.Persistence.Memory
+{
+ internal static class Helper
+ {
+ private static readonly byte[] EmptyBytes = new byte[0];
+
+ public static byte[] EnsureNotNull(this byte[] source)
+ {
+ return source ?? EmptyBytes;
+ }
+ }
+}
diff --git a/src/neo/Persistence/Memory/Snapshot.cs b/src/neo/Persistence/Memory/Snapshot.cs
new file mode 100644
index 0000000000..82455ddea8
--- /dev/null
+++ b/src/neo/Persistence/Memory/Snapshot.cs
@@ -0,0 +1,63 @@
+using Neo.IO;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+
+namespace Neo.Persistence.Memory
+{
+ internal class Snapshot : ISnapshot
+ {
+ private readonly ConcurrentDictionary[] innerData;
+ private readonly ImmutableDictionary[] immutableData;
+ private readonly ConcurrentDictionary[] writeBatch;
+
+ public Snapshot(ConcurrentDictionary[] innerData)
+ {
+ this.innerData = innerData;
+ this.immutableData = innerData.Select(p => p.ToImmutableDictionary(ByteArrayEqualityComparer.Default)).ToArray();
+ this.writeBatch = new ConcurrentDictionary[innerData.Length];
+ for (int i = 0; i < writeBatch.Length; i++)
+ writeBatch[i] = new ConcurrentDictionary(ByteArrayEqualityComparer.Default);
+ }
+
+ public void Commit()
+ {
+ for (int i = 0; i < writeBatch.Length; i++)
+ foreach (var pair in writeBatch[i])
+ if (pair.Value is null)
+ innerData[i].TryRemove(pair.Key, out _);
+ else
+ innerData[i][pair.Key] = pair.Value;
+ }
+
+ public void Delete(byte table, byte[] key)
+ {
+ writeBatch[table][key.EnsureNotNull()] = null;
+ }
+
+ public void Dispose()
+ {
+ }
+
+ public IEnumerable<(byte[] Key, byte[] Value)> Find(byte table, byte[] prefix)
+ {
+ IEnumerable> records = immutableData[table];
+ if (prefix?.Length > 0)
+ records = records.Where(p => p.Key.Length >= prefix.Length && p.Key.Take(prefix.Length).SequenceEqual(prefix));
+ records = records.OrderBy(p => p.Key, ByteArrayComparer.Default);
+ return records.Select(p => (p.Key, p.Value));
+ }
+
+ public void Put(byte table, byte[] key, byte[] value)
+ {
+ writeBatch[table][key.EnsureNotNull()] = value;
+ }
+
+ public byte[] TryGet(byte table, byte[] key)
+ {
+ immutableData[table].TryGetValue(key.EnsureNotNull(), out byte[] value);
+ return value;
+ }
+ }
+}
diff --git a/src/neo/Persistence/Memory/Store.cs b/src/neo/Persistence/Memory/Store.cs
new file mode 100644
index 0000000000..5e2d11eeb9
--- /dev/null
+++ b/src/neo/Persistence/Memory/Store.cs
@@ -0,0 +1,60 @@
+using Neo.IO;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Neo.Persistence.Memory
+{
+ public class Store : IStore
+ {
+ private readonly ConcurrentDictionary[] innerData;
+
+ public Store()
+ {
+ innerData = new ConcurrentDictionary[256];
+ for (int i = 0; i < innerData.Length; i++)
+ innerData[i] = new ConcurrentDictionary(ByteArrayEqualityComparer.Default);
+ }
+
+ public void Delete(byte table, byte[] key)
+ {
+ innerData[table].TryRemove(key.EnsureNotNull(), out _);
+ }
+
+ public void Dispose()
+ {
+ }
+
+ public IEnumerable<(byte[] Key, byte[] Value)> Find(byte table, byte[] prefix)
+ {
+ IEnumerable> records = innerData[table];
+ if (prefix?.Length > 0)
+ records = records.Where(p => p.Key.Length >= prefix.Length && p.Key.Take(prefix.Length).SequenceEqual(prefix));
+ records = records.OrderBy(p => p.Key, ByteArrayComparer.Default);
+ foreach (var pair in records)
+ yield return (pair.Key, pair.Value);
+ }
+
+ public ISnapshot GetSnapshot()
+ {
+ return new Snapshot(innerData);
+ }
+
+ public void Put(byte table, byte[] key, byte[] value)
+ {
+ PutSync(table, key, value);
+ }
+
+ public void PutSync(byte table, byte[] key, byte[] value)
+ {
+ innerData[table][key.EnsureNotNull()] = value;
+ }
+
+ public byte[] TryGet(byte table, byte[] key)
+ {
+ innerData[table].TryGetValue(key.EnsureNotNull(), out byte[] value);
+ return value;
+ }
+ }
+}
diff --git a/src/neo/Persistence/LevelDB/Prefixes.cs b/src/neo/Persistence/Prefixes.cs
similarity index 76%
rename from src/neo/Persistence/LevelDB/Prefixes.cs
rename to src/neo/Persistence/Prefixes.cs
index f40359a55a..dad8540787 100644
--- a/src/neo/Persistence/LevelDB/Prefixes.cs
+++ b/src/neo/Persistence/Prefixes.cs
@@ -1,4 +1,4 @@
-namespace Neo.Persistence.LevelDB
+namespace Neo.Persistence
{
internal static class Prefixes
{
@@ -12,9 +12,7 @@ internal static class Prefixes
public const byte IX_CurrentBlock = 0xc0;
public const byte IX_CurrentHeader = 0xc1;
- public const byte SYS_Version = 0xf0;
-
- /* Prefixes 0xf1 to 0xff are reserved for external use.
+ /* Prefixes 0xf0 to 0xff are reserved for external use.
*
* Note: The saved consensus state uses the Prefix 0xf4
*/
diff --git a/src/neo/Persistence/ReadOnlyView.cs b/src/neo/Persistence/ReadOnlyView.cs
new file mode 100644
index 0000000000..f138b616c1
--- /dev/null
+++ b/src/neo/Persistence/ReadOnlyView.cs
@@ -0,0 +1,33 @@
+using Neo.IO.Caching;
+using Neo.IO.Wrappers;
+using Neo.Ledger;
+using System;
+
+namespace Neo.Persistence
+{
+ ///
+ /// Provide a read-only for accessing directly from database instead of from snapshot.
+ ///
+ public class ReadOnlyView : StoreView
+ {
+ private readonly IReadOnlyStore store;
+
+ public override DataCache Blocks => new StoreDataCache(store, Prefixes.DATA_Block);
+ public override DataCache Transactions => new StoreDataCache(store, Prefixes.DATA_Transaction);
+ public override DataCache Contracts => new StoreDataCache(store, Prefixes.ST_Contract);
+ public override DataCache Storages => new StoreDataCache(store, Prefixes.ST_Storage);
+ public override DataCache HeaderHashList => new StoreDataCache(store, Prefixes.IX_HeaderHashList);
+ public override MetaDataCache BlockHashIndex => new StoreMetaDataCache(store, Prefixes.IX_CurrentBlock);
+ public override MetaDataCache HeaderHashIndex => new StoreMetaDataCache(store, Prefixes.IX_CurrentHeader);
+
+ public ReadOnlyView(IReadOnlyStore store)
+ {
+ this.store = store;
+ }
+
+ public override void Commit()
+ {
+ throw new NotSupportedException();
+ }
+ }
+}
diff --git a/src/neo/Persistence/SnapshotView.cs b/src/neo/Persistence/SnapshotView.cs
new file mode 100644
index 0000000000..5eb9071fe3
--- /dev/null
+++ b/src/neo/Persistence/SnapshotView.cs
@@ -0,0 +1,46 @@
+using Neo.IO.Caching;
+using Neo.IO.Wrappers;
+using Neo.Ledger;
+using System;
+
+namespace Neo.Persistence
+{
+ ///
+ /// Provide a for accessing snapshots.
+ ///
+ public class SnapshotView : StoreView, IDisposable
+ {
+ private readonly ISnapshot snapshot;
+
+ public override DataCache Blocks { get; }
+ public override DataCache Transactions { get; }
+ public override DataCache Contracts { get; }
+ public override DataCache Storages { get; }
+ public override DataCache HeaderHashList { get; }
+ public override MetaDataCache BlockHashIndex { get; }
+ public override MetaDataCache HeaderHashIndex { get; }
+
+ public SnapshotView(IStore store)
+ {
+ this.snapshot = store.GetSnapshot();
+ Blocks = new StoreDataCache(snapshot, Prefixes.DATA_Block);
+ Transactions = new StoreDataCache(snapshot, Prefixes.DATA_Transaction);
+ Contracts = new StoreDataCache(snapshot, Prefixes.ST_Contract);
+ Storages = new StoreDataCache(snapshot, Prefixes.ST_Storage);
+ HeaderHashList = new StoreDataCache(snapshot, Prefixes.IX_HeaderHashList);
+ BlockHashIndex = new StoreMetaDataCache(snapshot, Prefixes.IX_CurrentBlock);
+ HeaderHashIndex = new StoreMetaDataCache(snapshot, Prefixes.IX_CurrentHeader);
+ }
+
+ public override void Commit()
+ {
+ base.Commit();
+ snapshot.Commit();
+ }
+
+ public void Dispose()
+ {
+ snapshot.Dispose();
+ }
+ }
+}
diff --git a/src/neo/Persistence/Store.cs b/src/neo/Persistence/Store.cs
deleted file mode 100644
index eab5c182b9..0000000000
--- a/src/neo/Persistence/Store.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using Neo.IO.Caching;
-using Neo.IO.Wrappers;
-using Neo.Ledger;
-
-namespace Neo.Persistence
-{
- public abstract class Store : IPersistence
- {
- DataCache IPersistence.Blocks => GetBlocks();
- DataCache IPersistence.Transactions => GetTransactions();
- DataCache IPersistence.Contracts => GetContracts();
- DataCache IPersistence.Storages => GetStorages();
- DataCache IPersistence.HeaderHashList => GetHeaderHashList();
- MetaDataCache IPersistence.BlockHashIndex => GetBlockHashIndex();
- MetaDataCache IPersistence.HeaderHashIndex => GetHeaderHashIndex();
-
- public abstract byte[] Get(byte[] key);
- public abstract DataCache GetBlocks();
- public abstract DataCache GetTransactions();
- public abstract DataCache GetContracts();
- public abstract DataCache GetStorages();
- public abstract DataCache GetHeaderHashList();
- public abstract MetaDataCache GetBlockHashIndex();
- public abstract MetaDataCache GetHeaderHashIndex();
- public abstract void Put(byte[] key, byte[] value);
- public abstract void PutSync(byte[] key, byte[] value);
-
- public abstract Snapshot GetSnapshot();
- }
-}
diff --git a/src/neo/Persistence/StoreDataCache.cs b/src/neo/Persistence/StoreDataCache.cs
new file mode 100644
index 0000000000..995a34290f
--- /dev/null
+++ b/src/neo/Persistence/StoreDataCache.cs
@@ -0,0 +1,54 @@
+using Neo.IO;
+using Neo.IO.Caching;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Neo.Persistence
+{
+ internal class StoreDataCache : DataCache
+ where TKey : IEquatable, ISerializable, new()
+ where TValue : class, ICloneable, ISerializable, new()
+ {
+ private readonly IReadOnlyStore store;
+ private readonly ISnapshot snapshot;
+ private readonly byte prefix;
+
+ public StoreDataCache(IReadOnlyStore store, byte prefix)
+ {
+ this.store = store;
+ this.snapshot = store as ISnapshot;
+ this.prefix = prefix;
+ }
+
+ protected override void AddInternal(TKey key, TValue value)
+ {
+ snapshot?.Put(prefix, key.ToArray(), value.ToArray());
+ }
+
+ protected override void DeleteInternal(TKey key)
+ {
+ snapshot?.Delete(prefix, key.ToArray());
+ }
+
+ protected override IEnumerable<(TKey, TValue)> FindInternal(byte[] key_prefix)
+ {
+ return store.Find(prefix, key_prefix).Select(p => (p.Key.AsSerializable(), p.Value.AsSerializable()));
+ }
+
+ protected override TValue GetInternal(TKey key)
+ {
+ return store.TryGet(prefix, key.ToArray()).AsSerializable();
+ }
+
+ protected override TValue TryGetInternal(TKey key)
+ {
+ return store.TryGet(prefix, key.ToArray())?.AsSerializable();
+ }
+
+ protected override void UpdateInternal(TKey key, TValue value)
+ {
+ snapshot?.Put(prefix, key.ToArray(), value.ToArray());
+ }
+ }
+}
diff --git a/src/neo/Persistence/StoreMetaDataCache.cs b/src/neo/Persistence/StoreMetaDataCache.cs
new file mode 100644
index 0000000000..152a315e03
--- /dev/null
+++ b/src/neo/Persistence/StoreMetaDataCache.cs
@@ -0,0 +1,37 @@
+using Neo.IO;
+using Neo.IO.Caching;
+using System;
+
+namespace Neo.Persistence
+{
+ internal class StoreMetaDataCache : MetaDataCache
+ where T : class, ICloneable, ISerializable, new()
+ {
+ private readonly IReadOnlyStore store;
+ private readonly ISnapshot snapshot;
+ private readonly byte prefix;
+
+ public StoreMetaDataCache(IReadOnlyStore store, byte prefix, Func factory = null)
+ : base(factory)
+ {
+ this.store = store;
+ this.snapshot = store as ISnapshot;
+ this.prefix = prefix;
+ }
+
+ protected override void AddInternal(T item)
+ {
+ snapshot?.Put(prefix, null, item.ToArray());
+ }
+
+ protected override T TryGetInternal()
+ {
+ return store.TryGet(prefix, null)?.AsSerializable();
+ }
+
+ protected override void UpdateInternal(T item)
+ {
+ snapshot?.Put(prefix, null, item.ToArray());
+ }
+ }
+}
diff --git a/src/neo/Persistence/Snapshot.cs b/src/neo/Persistence/StoreView.cs
similarity index 53%
rename from src/neo/Persistence/Snapshot.cs
rename to src/neo/Persistence/StoreView.cs
index 1e900800b0..c23e000ff2 100644
--- a/src/neo/Persistence/Snapshot.cs
+++ b/src/neo/Persistence/StoreView.cs
@@ -2,11 +2,13 @@
using Neo.IO.Wrappers;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
-using System;
namespace Neo.Persistence
{
- public abstract class Snapshot : IDisposable, IPersistence
+ ///
+ /// It provides a set of properties and methods for reading formatted data from the underlying storage. Such as and .
+ ///
+ public abstract class StoreView
{
public Block PersistingBlock { get; internal set; }
public abstract DataCache Blocks { get; }
@@ -22,9 +24,9 @@ public abstract class Snapshot : IDisposable, IPersistence
public UInt256 CurrentBlockHash => BlockHashIndex.Get().Hash;
public UInt256 CurrentHeaderHash => HeaderHashIndex.Get().Hash;
- public Snapshot Clone()
+ public StoreView Clone()
{
- return new CloneSnapshot(this);
+ return new ClonedView(this);
}
public virtual void Commit()
@@ -38,8 +40,35 @@ public virtual void Commit()
HeaderHashIndex.Commit();
}
- public virtual void Dispose()
+ public bool ContainsBlock(UInt256 hash)
{
+ TrimmedBlock state = Blocks.TryGet(hash);
+ if (state == null) return false;
+ return state.IsBlock;
+ }
+
+ public bool ContainsTransaction(UInt256 hash)
+ {
+ TransactionState state = Transactions.TryGet(hash);
+ return state != null;
+ }
+
+ public Block GetBlock(UInt256 hash)
+ {
+ TrimmedBlock state = Blocks.TryGet(hash);
+ if (state == null) return null;
+ if (!state.IsBlock) return null;
+ return state.GetBlock(Transactions);
+ }
+
+ public Header GetHeader(UInt256 hash)
+ {
+ return Blocks.TryGet(hash)?.Header;
+ }
+
+ public Transaction GetTransaction(UInt256 hash)
+ {
+ return Transactions.TryGet(hash)?.Transaction;
}
}
}
diff --git a/src/neo/Plugins/IPersistencePlugin.cs b/src/neo/Plugins/IPersistencePlugin.cs
index 0f06ae51eb..14a3316115 100644
--- a/src/neo/Plugins/IPersistencePlugin.cs
+++ b/src/neo/Plugins/IPersistencePlugin.cs
@@ -7,8 +7,8 @@ namespace Neo.Plugins
{
public interface IPersistencePlugin
{
- void OnPersist(Snapshot snapshot, IReadOnlyList applicationExecutedList);
- void OnCommit(Snapshot snapshot);
+ void OnPersist(StoreView snapshot, IReadOnlyList applicationExecutedList);
+ void OnCommit(StoreView snapshot);
bool ShouldThrowExceptionFromCommit(Exception ex);
}
}
diff --git a/src/neo/SmartContract/ApplicationEngine.cs b/src/neo/SmartContract/ApplicationEngine.cs
index 41c17aebeb..eb4eb5e7c2 100644
--- a/src/neo/SmartContract/ApplicationEngine.cs
+++ b/src/neo/SmartContract/ApplicationEngine.cs
@@ -21,7 +21,7 @@ public partial class ApplicationEngine : ExecutionEngine
public TriggerType Trigger { get; }
public IVerifiable ScriptContainer { get; }
- public Snapshot Snapshot { get; }
+ public StoreView Snapshot { get; }
public long GasConsumed { get; private set; } = 0;
public UInt160 CurrentScriptHash => CurrentContext?.GetState().ScriptHash;
public UInt160 CallingScriptHash => InvocationStack.Count > 1 ? InvocationStack.Peek(1).GetState().ScriptHash : null;
@@ -29,7 +29,7 @@ public partial class ApplicationEngine : ExecutionEngine
public IReadOnlyList Notifications => notifications;
internal Dictionary InvocationCounter { get; } = new Dictionary();
- public ApplicationEngine(TriggerType trigger, IVerifiable container, Snapshot snapshot, long gas, bool testMode = false)
+ public ApplicationEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false)
{
this.gas_amount = GasFree + gas;
this.testMode = testMode;
@@ -84,7 +84,7 @@ protected override bool PreExecuteInstruction()
return AddGas(OpCodePrices[CurrentContext.CurrentInstruction.OpCode]);
}
- private static Block CreateDummyBlock(Snapshot snapshot)
+ private static Block CreateDummyBlock(StoreView snapshot)
{
var currentBlock = snapshot.Blocks[snapshot.CurrentBlockHash];
return new Block
@@ -105,7 +105,7 @@ private static Block CreateDummyBlock(Snapshot snapshot)
};
}
- public static ApplicationEngine Run(byte[] script, Snapshot snapshot,
+ public static ApplicationEngine Run(byte[] script, StoreView snapshot,
IVerifiable container = null, Block persistingBlock = null, bool testMode = false, long extraGAS = default)
{
snapshot.PersistingBlock = persistingBlock ?? snapshot.PersistingBlock ?? CreateDummyBlock(snapshot);
@@ -117,7 +117,7 @@ private static Block CreateDummyBlock(Snapshot snapshot)
public static ApplicationEngine Run(byte[] script, IVerifiable container = null, Block persistingBlock = null, bool testMode = false, long extraGAS = default)
{
- using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot())
+ using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
{
return Run(script, snapshot, container, persistingBlock, testMode, extraGAS);
}
diff --git a/src/neo/SmartContract/ContractParametersContext.cs b/src/neo/SmartContract/ContractParametersContext.cs
index 327c8b1ef8..4465e7831e 100644
--- a/src/neo/SmartContract/ContractParametersContext.cs
+++ b/src/neo/SmartContract/ContractParametersContext.cs
@@ -94,7 +94,7 @@ public IReadOnlyList ScriptHashes
return _ScriptHashes;
}
- using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot())
+ using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
{
_ScriptHashes = Verifiable.GetScriptHashesForVerifying(snapshot);
}
diff --git a/src/neo/SmartContract/Helper.cs b/src/neo/SmartContract/Helper.cs
index 03e543a5b4..4ddaf5fca5 100644
--- a/src/neo/SmartContract/Helper.cs
+++ b/src/neo/SmartContract/Helper.cs
@@ -254,7 +254,7 @@ public static UInt160 ToScriptHash(this byte[] script)
return new UInt160(Crypto.Default.Hash160(script));
}
- internal static bool VerifyWitnesses(this IVerifiable verifiable, Snapshot snapshot, long gas)
+ internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snapshot, long gas)
{
if (gas < 0) return false;
diff --git a/src/neo/SmartContract/Iterators/StorageIterator.cs b/src/neo/SmartContract/Iterators/StorageIterator.cs
index f35d70d890..a42875e1aa 100644
--- a/src/neo/SmartContract/Iterators/StorageIterator.cs
+++ b/src/neo/SmartContract/Iterators/StorageIterator.cs
@@ -6,9 +6,9 @@ namespace Neo.SmartContract.Iterators
{
internal class StorageIterator : IIterator
{
- private readonly IEnumerator> enumerator;
+ private readonly IEnumerator<(StorageKey Key, StorageItem Value)> enumerator;
- public StorageIterator(IEnumerator> enumerator)
+ public StorageIterator(IEnumerator<(StorageKey, StorageItem)> enumerator)
{
this.enumerator = enumerator;
}
diff --git a/src/neo/SmartContract/Native/PolicyContract.cs b/src/neo/SmartContract/Native/PolicyContract.cs
index 797104924e..3726cf49fb 100644
--- a/src/neo/SmartContract/Native/PolicyContract.cs
+++ b/src/neo/SmartContract/Native/PolicyContract.cs
@@ -29,7 +29,7 @@ public PolicyContract()
Manifest.Features = ContractFeatures.HasStorage;
}
- internal bool CheckPolicy(Transaction tx, Snapshot snapshot)
+ internal bool CheckPolicy(Transaction tx, StoreView snapshot)
{
UInt160[] blockedAccounts = GetBlockedAccounts(snapshot);
if (blockedAccounts.Intersect(tx.GetScriptHashesForVerifying(snapshot)).Any())
@@ -72,7 +72,7 @@ private StackItem GetMaxTransactionsPerBlock(ApplicationEngine engine, VMArray a
return GetMaxTransactionsPerBlock(engine.Snapshot);
}
- public uint GetMaxTransactionsPerBlock(Snapshot snapshot)
+ public uint GetMaxTransactionsPerBlock(StoreView snapshot)
{
return BitConverter.ToUInt32(snapshot.Storages[CreateStorageKey(Prefix_MaxTransactionsPerBlock)].Value, 0);
}
@@ -83,7 +83,7 @@ private StackItem GetMaxBlockSize(ApplicationEngine engine, VMArray args)
return GetMaxBlockSize(engine.Snapshot);
}
- public uint GetMaxBlockSize(Snapshot snapshot)
+ public uint GetMaxBlockSize(StoreView snapshot)
{
return BitConverter.ToUInt32(snapshot.Storages[CreateStorageKey(Prefix_MaxBlockSize)].Value, 0);
}
@@ -94,7 +94,7 @@ private StackItem GetFeePerByte(ApplicationEngine engine, VMArray args)
return GetFeePerByte(engine.Snapshot);
}
- public long GetFeePerByte(Snapshot snapshot)
+ public long GetFeePerByte(StoreView snapshot)
{
return BitConverter.ToInt64(snapshot.Storages[CreateStorageKey(Prefix_FeePerByte)].Value, 0);
}
@@ -105,7 +105,7 @@ private StackItem GetBlockedAccounts(ApplicationEngine engine, VMArray args)
return GetBlockedAccounts(engine.Snapshot).Select(p => (StackItem)p.ToArray()).ToList();
}
- public UInt160[] GetBlockedAccounts(Snapshot snapshot)
+ public UInt160[] GetBlockedAccounts(StoreView snapshot)
{
return snapshot.Storages[CreateStorageKey(Prefix_BlockedAccounts)].Value.AsSerializableArray();
}
diff --git a/src/neo/SmartContract/Native/Tokens/GasToken.cs b/src/neo/SmartContract/Native/Tokens/GasToken.cs
index 4266494a4f..be46335940 100644
--- a/src/neo/SmartContract/Native/Tokens/GasToken.cs
+++ b/src/neo/SmartContract/Native/Tokens/GasToken.cs
@@ -60,7 +60,7 @@ private StackItem GetSysFeeAmount(ApplicationEngine engine, VMArray args)
return GetSysFeeAmount(engine.Snapshot, index);
}
- public BigInteger GetSysFeeAmount(Snapshot snapshot, uint index)
+ public BigInteger GetSysFeeAmount(StoreView snapshot, uint index)
{
if (index == 0) return Blockchain.GenesisBlock.Transactions.Sum(p => p.SystemFee);
StorageKey key = CreateStorageKey(Prefix_SystemFeeAmount, BitConverter.GetBytes(index));
diff --git a/src/neo/SmartContract/Native/Tokens/NeoToken.cs b/src/neo/SmartContract/Native/Tokens/NeoToken.cs
index ba059aff4d..e0023b3841 100644
--- a/src/neo/SmartContract/Native/Tokens/NeoToken.cs
+++ b/src/neo/SmartContract/Native/Tokens/NeoToken.cs
@@ -33,7 +33,7 @@ internal NeoToken()
this.TotalAmount = 100000000 * Factor;
}
- public override BigInteger TotalSupply(Snapshot snapshot)
+ public override BigInteger TotalSupply(StoreView snapshot)
{
return TotalAmount;
}
@@ -64,7 +64,7 @@ private void DistributeGas(ApplicationEngine engine, UInt160 account, AccountSta
engine.Snapshot.Storages.GetAndChange(CreateAccountKey(account)).Value = state.ToByteArray();
}
- private BigInteger CalculateBonus(Snapshot snapshot, BigInteger value, uint start, uint end)
+ private BigInteger CalculateBonus(StoreView snapshot, BigInteger value, uint start, uint end)
{
if (value.IsZero || start >= end) return BigInteger.Zero;
if (value.Sign < 0) throw new ArgumentOutOfRangeException(nameof(value));
@@ -124,7 +124,7 @@ private StackItem UnclaimedGas(ApplicationEngine engine, VMArray args)
return UnclaimedGas(engine.Snapshot, account, end);
}
- public BigInteger UnclaimedGas(Snapshot snapshot, UInt160 account, uint end)
+ public BigInteger UnclaimedGas(StoreView snapshot, UInt160 account, uint end)
{
StorageItem storage = snapshot.Storages.TryGet(CreateAccountKey(account));
if (storage is null) return BigInteger.Zero;
@@ -139,7 +139,7 @@ private StackItem RegisterValidator(ApplicationEngine engine, VMArray args)
return RegisterValidator(engine.Snapshot, pubkey);
}
- private bool RegisterValidator(Snapshot snapshot, ECPoint pubkey)
+ private bool RegisterValidator(StoreView snapshot, ECPoint pubkey)
{
StorageKey key = CreateStorageKey(Prefix_Validator, pubkey);
if (snapshot.Storages.TryGet(key) != null) return false;
@@ -199,7 +199,7 @@ private StackItem GetRegisteredValidators(ApplicationEngine engine, VMArray args
return GetRegisteredValidators(engine.Snapshot).Select(p => new Struct(new StackItem[] { p.PublicKey.ToArray(), p.Votes })).ToArray();
}
- public IEnumerable<(ECPoint PublicKey, BigInteger Votes)> GetRegisteredValidators(Snapshot snapshot)
+ public IEnumerable<(ECPoint PublicKey, BigInteger Votes)> GetRegisteredValidators(StoreView snapshot)
{
byte[] prefix_key = StorageKey.CreateSearchPrefix(Hash, new[] { Prefix_Validator });
return snapshot.Storages.Find(prefix_key).Select(p =>
@@ -215,7 +215,7 @@ private StackItem GetValidators(ApplicationEngine engine, VMArray args)
return GetValidators(engine.Snapshot).Select(p => (StackItem)p.ToArray()).ToList();
}
- public ECPoint[] GetValidators(Snapshot snapshot)
+ public ECPoint[] GetValidators(StoreView snapshot)
{
StorageItem storage_count = snapshot.Storages.TryGet(CreateStorageKey(Prefix_ValidatorsCount));
if (storage_count is null) return Blockchain.StandbyValidators;
@@ -240,7 +240,7 @@ private StackItem GetNextBlockValidators(ApplicationEngine engine, VMArray args)
return GetNextBlockValidators(engine.Snapshot).Select(p => (StackItem)p.ToArray()).ToList();
}
- public ECPoint[] GetNextBlockValidators(Snapshot snapshot)
+ public ECPoint[] GetNextBlockValidators(StoreView snapshot)
{
StorageItem storage = snapshot.Storages.TryGet(CreateStorageKey(Prefix_NextValidators));
if (storage is null) return Blockchain.StandbyValidators;
diff --git a/src/neo/SmartContract/Native/Tokens/Nep5Token.cs b/src/neo/SmartContract/Native/Tokens/Nep5Token.cs
index 6d35d00410..5728c2d8be 100644
--- a/src/neo/SmartContract/Native/Tokens/Nep5Token.cs
+++ b/src/neo/SmartContract/Native/Tokens/Nep5Token.cs
@@ -138,7 +138,7 @@ protected StackItem TotalSupply(ApplicationEngine engine, VMArray args)
return TotalSupply(engine.Snapshot);
}
- public virtual BigInteger TotalSupply(Snapshot snapshot)
+ public virtual BigInteger TotalSupply(StoreView snapshot)
{
StorageItem storage = snapshot.Storages.TryGet(CreateStorageKey(Prefix_TotalSupply));
if (storage is null) return BigInteger.Zero;
@@ -151,7 +151,7 @@ protected StackItem BalanceOf(ApplicationEngine engine, VMArray args)
return BalanceOf(engine.Snapshot, new UInt160(args[0].GetSpan().ToArray()));
}
- public virtual BigInteger BalanceOf(Snapshot snapshot, UInt160 account)
+ public virtual BigInteger BalanceOf(StoreView snapshot, UInt160 account)
{
StorageItem storage = snapshot.Storages.TryGet(CreateAccountKey(account));
if (storage is null) return BigInteger.Zero;
diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs
index bc52b9b368..f2cf92e7b2 100644
--- a/src/neo/Wallets/Wallet.cs
+++ b/src/neo/Wallets/Wallet.cs
@@ -221,7 +221,7 @@ public Transaction MakeTransaction(TransferOutput[] outputs, UInt160 from = null
throw new ArgumentException($"The address {from.ToString()} was not found in the wallet");
accounts = new[] { from };
}
- using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot())
+ using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot())
{
HashSet cosignerList = new HashSet();
byte[] script;
@@ -290,14 +290,14 @@ public Transaction MakeTransaction(byte[] script, UInt160 sender = null, Transac
throw new ArgumentException($"The address {sender.ToString()} was not found in the wallet");
accounts = new[] { sender };
}
- using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot())
+ 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], cosigners ?? new Cosigner[0], balances_gas);
}
}
- private Transaction MakeTransaction(Snapshot snapshot, byte[] script, TransactionAttribute[] attributes, Cosigner[] cosigners, List<(UInt160 Account, BigInteger Value)> balances_gas)
+ private Transaction MakeTransaction(StoreView snapshot, byte[] script, TransactionAttribute[] attributes, Cosigner[] cosigners, List<(UInt160 Account, BigInteger Value)> balances_gas)
{
Random rand = new Random();
foreach (var (account, value) in balances_gas)
diff --git a/tests/neo.UnitTests/Consensus/UT_Consensus.cs b/tests/neo.UnitTests/Consensus/UT_Consensus.cs
index c10e6c94e3..bc4c2277a0 100644
--- a/tests/neo.UnitTests/Consensus/UT_Consensus.cs
+++ b/tests/neo.UnitTests/Consensus/UT_Consensus.cs
@@ -41,7 +41,7 @@ public void ConsensusService_Primary_Sends_PrepareRequest_After_OnStart()
TestProbe subscriber = CreateTestProbe();
var mockWallet = new Mock();
mockWallet.Setup(p => p.GetAccount(It.IsAny())).Returns(p => new TestWalletAccount(p));
- ConsensusContext context = new ConsensusContext(mockWallet.Object, TestBlockchain.GetStore());
+ ConsensusContext context = new ConsensusContext(mockWallet.Object, TestBlockchain.Store);
int timeIndex = 0;
var timeValues = new[] {
diff --git a/tests/neo.UnitTests/Consensus/UT_ConsensusContext.cs b/tests/neo.UnitTests/Consensus/UT_ConsensusContext.cs
index 821b6f8da5..ee5eb5f9d1 100644
--- a/tests/neo.UnitTests/Consensus/UT_ConsensusContext.cs
+++ b/tests/neo.UnitTests/Consensus/UT_ConsensusContext.cs
@@ -38,7 +38,7 @@ public void TestSetup()
_validatorKeys[x] = new KeyPair(pk);
}
- _context = new ConsensusContext(mockWallet.Object, TestBlockchain.GetStore())
+ _context = new ConsensusContext(mockWallet.Object, TestBlockchain.Store)
{
Validators = _validatorKeys.Select(u => u.PublicKey).ToArray()
};
diff --git a/tests/neo.UnitTests/Extensions/NativeContractExtensions.cs b/tests/neo.UnitTests/Extensions/NativeContractExtensions.cs
index 9847bddd48..cbf4a109d9 100644
--- a/tests/neo.UnitTests/Extensions/NativeContractExtensions.cs
+++ b/tests/neo.UnitTests/Extensions/NativeContractExtensions.cs
@@ -1,4 +1,5 @@
using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
@@ -9,12 +10,12 @@ namespace Neo.UnitTests.Extensions
{
public static class NativeContractExtensions
{
- public static StackItem Call(this NativeContract contract, Neo.Persistence.Snapshot snapshot, string method, params ContractParameter[] args)
+ public static StackItem Call(this NativeContract contract, StoreView snapshot, string method, params ContractParameter[] args)
{
return Call(contract, snapshot, null, method, args);
}
- public static StackItem Call(this NativeContract contract, Neo.Persistence.Snapshot snapshot, IVerifiable container, string method, params ContractParameter[] args)
+ 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);
diff --git a/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs b/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs
index f06a7eb201..4a04d97c84 100644
--- a/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs
+++ b/tests/neo.UnitTests/Extensions/Nep5NativeContractExtensions.cs
@@ -1,5 +1,6 @@
using FluentAssertions;
using Neo.Network.P2P.Payloads;
+using Neo.Persistence;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
@@ -33,14 +34,14 @@ public ManualWitness(params UInt160[] hashForVerify)
public void DeserializeUnsigned(BinaryReader reader) { }
- public UInt160[] GetScriptHashesForVerifying(Persistence.Snapshot snapshot) => _hashForVerify;
+ public UInt160[] GetScriptHashesForVerifying(StoreView snapshot) => _hashForVerify;
public void Serialize(BinaryWriter writer) { }
public void SerializeUnsigned(BinaryWriter writer) { }
}
- public static bool Transfer(this NativeContract contract, Persistence.Snapshot snapshot, byte[] from, byte[] to, BigInteger amount, bool signFrom)
+ public static bool Transfer(this NativeContract contract, StoreView snapshot, byte[] from, byte[] to, BigInteger amount, bool signFrom)
{
var engine = new ApplicationEngine(TriggerType.Application,
new ManualWitness(signFrom ? new UInt160(from) : null), snapshot, 0, true);
@@ -89,7 +90,7 @@ public static string[] SupportedStandards(this NativeContract contract)
.ToArray();
}
- public static BigInteger TotalSupply(this NativeContract contract, Persistence.Snapshot snapshot)
+ public static BigInteger TotalSupply(this NativeContract contract, StoreView snapshot)
{
var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
@@ -109,7 +110,7 @@ public static BigInteger TotalSupply(this NativeContract contract, Persistence.S
return (result as VM.Types.Integer).GetBigInteger();
}
- public static BigInteger BalanceOf(this NativeContract contract, Persistence.Snapshot snapshot, byte[] account)
+ public static BigInteger BalanceOf(this NativeContract contract, StoreView snapshot, byte[] account)
{
var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
diff --git a/tests/neo.UnitTests/IO/Caching/UT_DataCache.cs b/tests/neo.UnitTests/IO/Caching/UT_DataCache.cs
index 437f2b92f1..cd9752c819 100644
--- a/tests/neo.UnitTests/IO/Caching/UT_DataCache.cs
+++ b/tests/neo.UnitTests/IO/Caching/UT_DataCache.cs
@@ -105,7 +105,7 @@ class MyDataCache : DataCache
{
public Dictionary InnerDict = new Dictionary();
- public override void DeleteInternal(TKey key)
+ protected override void DeleteInternal(TKey key)
{
InnerDict.Remove(key);
}
@@ -115,9 +115,9 @@ protected override void AddInternal(TKey key, TValue value)
InnerDict.Add(key, value);
}
- protected override IEnumerable> FindInternal(byte[] key_prefix)
+ protected override IEnumerable<(TKey, TValue)> FindInternal(byte[] key_prefix)
{
- return InnerDict.Where(kvp => kvp.Key.ToArray().Take(key_prefix.Length).SequenceEqual(key_prefix));
+ return InnerDict.Where(kvp => kvp.Key.ToArray().Take(key_prefix.Length).SequenceEqual(key_prefix)).Select(p => (p.Key, p.Value));
}
protected override TValue GetInternal(TKey key)
diff --git a/tests/neo.UnitTests/Ledger/UT_Blockchain.cs b/tests/neo.UnitTests/Ledger/UT_Blockchain.cs
index af0ec69a79..27dd15b6aa 100644
--- a/tests/neo.UnitTests/Ledger/UT_Blockchain.cs
+++ b/tests/neo.UnitTests/Ledger/UT_Blockchain.cs
@@ -9,7 +9,7 @@ namespace Neo.UnitTests.Ledger
{
internal class TestBlock : Block
{
- public override bool Verify(Snapshot snapshot)
+ public override bool Verify(StoreView snapshot)
{
return true;
}
@@ -22,7 +22,7 @@ public static TestBlock Cast(Block input)
internal class TestHeader : Header
{
- public override bool Verify(Snapshot snapshot)
+ public override bool Verify(StoreView snapshot)
{
return true;
}
@@ -37,14 +37,14 @@ public static TestHeader Cast(Header input)
public class UT_Blockchain
{
private NeoSystem system;
- private Store store;
+ private IStore store;
Transaction txSample = Blockchain.GenesisBlock.Transactions[0];
[TestInitialize]
public void Initialize()
{
- system = TestBlockchain.InitializeMockNeoSystem();
- store = TestBlockchain.GetStore();
+ system = TestBlockchain.TheNeoSystem;
+ store = TestBlockchain.Store;
Blockchain.Singleton.MemPool.TryAdd(txSample.Hash, txSample);
}
diff --git a/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs b/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs
index 631ae06dbc..c68504f4c6 100644
--- a/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs
+++ b/tests/neo.UnitTests/Ledger/UT_MemoryPool.cs
@@ -3,7 +3,6 @@
using Moq;
using Neo.Cryptography;
using Neo.IO;
-using Neo.IO.Caching;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.Persistence;
@@ -40,11 +39,11 @@ public void TestSetup()
// protect against external changes on TimeProvider
TimeProvider.ResetToDefault();
- NeoSystem TheNeoSystem = TestBlockchain.InitializeMockNeoSystem();
+ TestBlockchain.InitializeMockNeoSystem();
// Create a MemoryPool with capacity of 100
- _unit = new MemoryPool(TheNeoSystem, 100);
- _unit.LoadPolicy(TestBlockchain.GetStore().GetSnapshot());
+ _unit = new MemoryPool(TestBlockchain.TheNeoSystem, 100);
+ _unit.LoadPolicy(Blockchain.Singleton.GetSnapshot());
// Verify capacity equals the amount specified
_unit.Capacity.Should().Be(100);
@@ -52,7 +51,7 @@ public void TestSetup()
_unit.VerifiedCount.Should().Be(0);
_unit.UnVerifiedCount.Should().Be(0);
_unit.Count.Should().Be(0);
- _unit2 = new MemoryPool(TheNeoSystem, 0);
+ _unit2 = new MemoryPool(TestBlockchain.TheNeoSystem, 0);
plugin = new TestIMemoryPoolTxObserverPlugin();
}
@@ -75,8 +74,8 @@ private Transaction CreateTransactionWithFee(long fee)
var randomBytes = new byte[16];
random.NextBytes(randomBytes);
Mock mock = new Mock();
- mock.Setup(p => p.Reverify(It.IsAny(), It.IsAny())).Returns(true);
- mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(true);
+ mock.Setup(p => p.Reverify(It.IsAny(), It.IsAny())).Returns(true);
+ mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(true);
mock.Object.Script = randomBytes;
mock.Object.Sender = UInt160.Zero;
mock.Object.NetworkFee = fee;
@@ -100,8 +99,8 @@ private Transaction CreateTransactionWithFeeAndBalanceVerify(long fee)
random.NextBytes(randomBytes);
Mock mock = new Mock();
UInt160 sender = UInt160.Zero;
- mock.Setup(p => p.Reverify(It.IsAny(), It.IsAny())).Returns(((Snapshot snapshot, BigInteger amount) => NativeContract.GAS.BalanceOf(snapshot, sender) >= amount + fee));
- mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(true);
+ mock.Setup(p => p.Reverify(It.IsAny(), It.IsAny())).Returns(((StoreView snapshot, BigInteger amount) => NativeContract.GAS.BalanceOf(snapshot, sender) >= amount + fee));
+ mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(true);
mock.Object.Script = randomBytes;
mock.Object.Sender = sender;
mock.Object.NetworkFee = fee;
@@ -223,7 +222,7 @@ public void BlockPersistAndReverificationWillAbandonTxAsBalanceTransfered()
// Simulate the transfer process in tx by burning the balance
UInt160 sender = block.Transactions[0].Sender;
- Snapshot snapshot = Blockchain.Singleton.GetSnapshot();
+ SnapshotView snapshot = Blockchain.Singleton.GetSnapshot();
BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, sender);
ApplicationEngine applicationEngine = new ApplicationEngine(TriggerType.All, block, snapshot, (long)balance);
@@ -412,10 +411,8 @@ public void TestGetVerifiedTransactions()
[TestMethod]
public void TestReVerifyTopUnverifiedTransactionsIfNeeded()
{
- NeoSystem TheNeoSystem = TestBlockchain.InitializeMockNeoSystem();
- var s = Blockchain.Singleton.Height;
- _unit = new MemoryPool(TheNeoSystem, 600);
- _unit.LoadPolicy(TestBlockchain.GetStore().GetSnapshot());
+ _unit = new MemoryPool(TestBlockchain.TheNeoSystem, 600);
+ _unit.LoadPolicy(Blockchain.Singleton.GetSnapshot());
AddTransaction(CreateTransaction(100000001));
AddTransaction(CreateTransaction(100000001));
AddTransaction(CreateTransaction(100000001));
@@ -475,7 +472,7 @@ public void TestTryGetValue()
[TestMethod]
public void TestUpdatePoolForBlockPersisted()
{
- var mockSnapshot = new Mock();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
byte[] transactionsPerBlock = { 0x18, 0x00, 0x00, 0x00 }; // 24
byte[] feePerByte = { 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 1048576
StorageItem item1 = new StorageItem
@@ -486,14 +483,12 @@ public void TestUpdatePoolForBlockPersisted()
{
Value = feePerByte
};
- var myDataCache = new MyDataCache();
var key1 = CreateStorageKey(Prefix_MaxTransactionsPerBlock);
var key2 = CreateStorageKey(Prefix_FeePerByte);
key1.ScriptHash = NativeContract.Policy.Hash;
key2.ScriptHash = NativeContract.Policy.Hash;
- myDataCache.Add(key1, item1);
- myDataCache.Add(key2, item2);
- mockSnapshot.SetupGet(p => p.Storages).Returns(myDataCache);
+ snapshot.Storages.Add(key1, item1);
+ snapshot.Storages.Add(key2, item2);
var tx1 = CreateTransaction();
var tx2 = CreateTransaction();
@@ -505,7 +500,7 @@ public void TestUpdatePoolForBlockPersisted()
_unit.UnVerifiedCount.Should().Be(0);
_unit.VerifiedCount.Should().Be(1);
- _unit.UpdatePoolForBlockPersisted(block, mockSnapshot.Object);
+ _unit.UpdatePoolForBlockPersisted(block, snapshot);
_unit.UnVerifiedCount.Should().Be(0);
_unit.VerifiedCount.Should().Be(0);
@@ -524,48 +519,4 @@ public StorageKey CreateStorageKey(byte prefix, byte[] key = null)
return storageKey;
}
}
-
- public class MyDataCache : DataCache
- where TKey : IEquatable, ISerializable
- where TValue : class, ICloneable, ISerializable, new()
- {
- private readonly TValue _defaultValue;
-
- public MyDataCache()
- {
- _defaultValue = null;
- }
-
- public MyDataCache(TValue defaultValue)
- {
- this._defaultValue = defaultValue;
- }
- public override void DeleteInternal(TKey key)
- {
- }
-
- protected override void AddInternal(TKey key, TValue value)
- {
- Add(key, value);
- }
-
- protected override IEnumerable> FindInternal(byte[] key_prefix)
- {
- return Enumerable.Empty>();
- }
-
- protected override TValue GetInternal(TKey key)
- {
- return TryGet(key);
- }
-
- protected override TValue TryGetInternal(TKey key)
- {
- return _defaultValue;
- }
-
- protected override void UpdateInternal(TKey key, TValue value)
- {
- }
- }
}
diff --git a/tests/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs b/tests/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs
index 81fb0d9354..ac5cf57b7c 100644
--- a/tests/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs
+++ b/tests/neo.UnitTests/Ledger/UT_SendersFeeMonitor.cs
@@ -18,8 +18,8 @@ private Transaction CreateTransactionWithFee(long networkFee, long systemFee)
var randomBytes = new byte[16];
random.NextBytes(randomBytes);
Mock mock = new Mock();
- mock.Setup(p => p.Reverify(It.IsAny(), It.IsAny())).Returns(true);
- mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(true);
+ mock.Setup(p => p.Reverify(It.IsAny(), It.IsAny())).Returns(true);
+ mock.Setup(p => p.Verify(It.IsAny(), It.IsAny())).Returns(true);
mock.Object.Script = randomBytes;
mock.Object.Sender = UInt160.Zero;
mock.Object.NetworkFee = networkFee;
diff --git a/tests/neo.UnitTests/Ledger/UT_TrimmedBlock.cs b/tests/neo.UnitTests/Ledger/UT_TrimmedBlock.cs
index 3704279701..482297f7ab 100644
--- a/tests/neo.UnitTests/Ledger/UT_TrimmedBlock.cs
+++ b/tests/neo.UnitTests/Ledger/UT_TrimmedBlock.cs
@@ -1,4 +1,4 @@
-using FluentAssertions;
+using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.IO;
using Neo.Ledger;
@@ -42,7 +42,7 @@ public void TestGetIsBlock()
[TestMethod]
public void TestGetBlock()
{
- var cache = new TestDataCache();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var tx1 = TestUtils.GetTransaction();
tx1.Script = new byte[] { 0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,
@@ -63,12 +63,12 @@ public void TestGetBlock()
Transaction = tx2,
BlockIndex = 1
};
- cache.Add(tx1.Hash, state1);
- cache.Add(tx2.Hash, state2);
+ snapshot.Transactions.Add(tx1.Hash, state1);
+ snapshot.Transactions.Add(tx2.Hash, state2);
TrimmedBlock tblock = GetTrimmedBlockWithNoTransaction();
tblock.Hashes = new UInt256[] { tx1.Hash, tx2.Hash };
- Block block = tblock.GetBlock(cache);
+ Block block = tblock.GetBlock(snapshot.Transactions);
block.Index.Should().Be(1);
block.MerkleRoot.Should().Be(UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff02"));
diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
index cf5f4504fe..af12fe148e 100644
--- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
+++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
@@ -5,7 +5,6 @@
using Neo.IO.Json;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
-using Neo.Persistence;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.SmartContract.Native.Tokens;
@@ -20,13 +19,12 @@ namespace Neo.UnitTests.Network.P2P.Payloads
public class UT_Transaction
{
Transaction uut;
- Store store;
[TestInitialize]
public void TestSetup()
{
+ TestBlockchain.InitializeMockNeoSystem();
uut = new Transaction();
- store = TestBlockchain.GetStore();
}
[TestMethod]
@@ -86,10 +84,9 @@ public void Size_Get()
[TestMethod]
public void FeeIsMultiSigContract()
{
- var store = TestBlockchain.GetStore();
var walletA = TestUtils.GenerateTestWallet();
var walletB = TestUtils.GenerateTestWallet();
- var snapshot = store.GetSnapshot();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
using (var unlockA = walletA.Unlock("123"))
using (var unlockB = walletB.Unlock("123"))
@@ -121,6 +118,8 @@ public void FeeIsMultiSigContract()
}
.ToByteArray();
+ snapshot.Commit();
+
// Make transaction
var tx = walletA.MakeTransaction(new TransferOutput[]
@@ -175,7 +174,7 @@ public void FeeIsMultiSigContract()
public void FeeIsSignatureContractDetailed()
{
var wallet = TestUtils.GenerateTestWallet();
- var snapshot = store.GetSnapshot();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
using (var unlock = wallet.Unlock("123"))
{
@@ -196,6 +195,8 @@ public void FeeIsSignatureContractDetailed()
}
.ToByteArray();
+ snapshot.Commit();
+
// Make transaction
// self-transfer of 1e-8 GAS
@@ -290,7 +291,7 @@ public void FeeIsSignatureContractDetailed()
public void FeeIsSignatureContract_TestScope_Global()
{
var wallet = TestUtils.GenerateTestWallet();
- var snapshot = store.GetSnapshot();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
// no password on this wallet
using (var unlock = wallet.Unlock(""))
@@ -312,6 +313,8 @@ public void FeeIsSignatureContract_TestScope_Global()
}
.ToByteArray();
+ snapshot.Commit();
+
// Make transaction
// Manually creating script
@@ -381,7 +384,7 @@ public void FeeIsSignatureContract_TestScope_Global()
public void FeeIsSignatureContract_TestScope_CurrentHash_GAS()
{
var wallet = TestUtils.GenerateTestWallet();
- var snapshot = store.GetSnapshot();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
// no password on this wallet
using (var unlock = wallet.Unlock(""))
@@ -403,6 +406,8 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS()
}
.ToByteArray();
+ snapshot.Commit();
+
// Make transaction
// Manually creating script
@@ -473,7 +478,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS()
public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS()
{
var wallet = TestUtils.GenerateTestWallet();
- var snapshot = store.GetSnapshot();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
// no password on this wallet
using (var unlock = wallet.Unlock(""))
@@ -495,6 +500,8 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS()
}
.ToByteArray();
+ snapshot.Commit();
+
// Make transaction
// Manually creating script
@@ -568,7 +575,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS()
public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_FAULT()
{
var wallet = TestUtils.GenerateTestWallet();
- var snapshot = store.GetSnapshot();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
// no password on this wallet
using (var unlock = wallet.Unlock(""))
@@ -626,7 +633,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_FAULT()
public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS()
{
var wallet = TestUtils.GenerateTestWallet();
- var snapshot = store.GetSnapshot();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
// no password on this wallet
using (var unlock = wallet.Unlock(""))
@@ -648,6 +655,8 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS()
}
.ToByteArray();
+ snapshot.Commit();
+
// Make transaction
// Manually creating script
@@ -723,7 +732,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS()
public void FeeIsSignatureContract_TestScope_NoScopeFAULT()
{
var wallet = TestUtils.GenerateTestWallet();
- var snapshot = store.GetSnapshot();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
// no password on this wallet
using (var unlock = wallet.Unlock(""))
@@ -775,7 +784,7 @@ public void FeeIsSignatureContract_TestScope_NoScopeFAULT()
[TestMethod]
public void Transaction_Reverify_Hashes_Length_Unequal_To_Witnesses_Length()
{
- var snapshot = store.GetSnapshot();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
Transaction txSimple = new Transaction
{
Version = 0x00,
@@ -981,7 +990,7 @@ public void FeeIsSignatureContract_TestScope_Global_Default()
cosigner.Scopes.Should().Be(WitnessScope.Global);
var wallet = TestUtils.GenerateTestWallet();
- var snapshot = store.GetSnapshot();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
// no password on this wallet
using (var unlock = wallet.Unlock(""))
@@ -1003,6 +1012,8 @@ public void FeeIsSignatureContract_TestScope_Global_Default()
}
.ToByteArray();
+ snapshot.Commit();
+
// Make transaction
// Manually creating script
diff --git a/tests/neo.UnitTests/Network/P2P/UT_ProtocolHandler.cs b/tests/neo.UnitTests/Network/P2P/UT_ProtocolHandler.cs
index f8b932c4f2..1f62a77580 100644
--- a/tests/neo.UnitTests/Network/P2P/UT_ProtocolHandler.cs
+++ b/tests/neo.UnitTests/Network/P2P/UT_ProtocolHandler.cs
@@ -9,26 +9,18 @@ namespace Neo.UnitTests.Network.P2P
[TestClass]
public class UT_ProtocolHandler : TestKit
{
- private NeoSystem testBlockchain;
-
[TestCleanup]
public void Cleanup()
{
Shutdown();
}
- [TestInitialize]
- public void TestSetup()
- {
- testBlockchain = TestBlockchain.InitializeMockNeoSystem();
- }
-
[TestMethod]
public void ProtocolHandler_Test_SendVersion_TellParent()
{
var senderProbe = CreateTestProbe();
var parent = CreateTestProbe();
- var protocolActor = ActorOfAsTestActorRef(() => new ProtocolHandler(testBlockchain), parent);
+ var protocolActor = ActorOfAsTestActorRef(() => new ProtocolHandler(TestBlockchain.TheNeoSystem), parent);
var payload = new VersionPayload()
{
diff --git a/tests/neo.UnitTests/Network/P2P/UT_RemoteNode.cs b/tests/neo.UnitTests/Network/P2P/UT_RemoteNode.cs
index 570cc904da..a700902f6c 100644
--- a/tests/neo.UnitTests/Network/P2P/UT_RemoteNode.cs
+++ b/tests/neo.UnitTests/Network/P2P/UT_RemoteNode.cs
@@ -23,7 +23,7 @@ public UT_RemoteNode()
[ClassInitialize]
public static void TestSetup(TestContext ctx)
{
- testBlockchain = TestBlockchain.InitializeMockNeoSystem();
+ testBlockchain = TestBlockchain.TheNeoSystem;
}
[TestMethod]
diff --git a/tests/neo.UnitTests/Network/RPC/UT_RpcServer.cs b/tests/neo.UnitTests/Network/RPC/UT_RpcServer.cs
index fae945a21a..cfdfe7fbd8 100644
--- a/tests/neo.UnitTests/Network/RPC/UT_RpcServer.cs
+++ b/tests/neo.UnitTests/Network/RPC/UT_RpcServer.cs
@@ -14,8 +14,7 @@ public class UT_RpcServer
[TestInitialize]
public void Setup()
{
- var system = TestBlockchain.InitializeMockNeoSystem();
- server = new RpcServer(system);
+ server = new RpcServer(TestBlockchain.TheNeoSystem);
}
[TestCleanup]
diff --git a/tests/neo.UnitTests/Network/RPC/UT_TransactionManager.cs b/tests/neo.UnitTests/Network/RPC/UT_TransactionManager.cs
index e1cce967cd..e11c551a9a 100644
--- a/tests/neo.UnitTests/Network/RPC/UT_TransactionManager.cs
+++ b/tests/neo.UnitTests/Network/RPC/UT_TransactionManager.cs
@@ -3,6 +3,7 @@
using Neo.Cryptography;
using Neo.IO;
using Neo.IO.Json;
+using Neo.Ledger;
using Neo.Network.P2P;
using Neo.Network.P2P.Payloads;
using Neo.Network.RPC;
@@ -156,8 +157,7 @@ public void TestSignMulti()
.AddSignature(keyPair1)
.Sign();
- var store = TestBlockchain.GetStore();
- var snapshot = store.GetSnapshot();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var tx = txManager.Tx;
Assert.IsTrue(tx.VerifyWitnesses(snapshot, tx.NetworkFee));
diff --git a/tests/neo.UnitTests/Plugins/UT_Plugin.cs b/tests/neo.UnitTests/Plugins/UT_Plugin.cs
index 3c6098e47a..7c3224c82a 100644
--- a/tests/neo.UnitTests/Plugins/UT_Plugin.cs
+++ b/tests/neo.UnitTests/Plugins/UT_Plugin.cs
@@ -65,8 +65,7 @@ public void TestNotifyPluginsLoadedAfterSystemConstructed()
[TestMethod]
public void TestResumeNodeStartupAndSuspendNodeStartup()
{
- var system = TestBlockchain.InitializeMockNeoSystem();
- TestLogPlugin.TestLoadPlugins(system);
+ TestLogPlugin.TestLoadPlugins(TestBlockchain.TheNeoSystem);
TestLogPlugin.TestSuspendNodeStartup();
TestLogPlugin.TestSuspendNodeStartup();
TestLogPlugin.TestResumeNodeStartup().Should().BeFalse();
diff --git a/tests/neo.UnitTests/SmartContract/Iterators/UT_StorageIterator.cs b/tests/neo.UnitTests/SmartContract/Iterators/UT_StorageIterator.cs
index aad833b04e..a0126b3b03 100644
--- a/tests/neo.UnitTests/SmartContract/Iterators/UT_StorageIterator.cs
+++ b/tests/neo.UnitTests/SmartContract/Iterators/UT_StorageIterator.cs
@@ -14,7 +14,7 @@ public class UT_StorageIterator
[TestMethod]
public void TestGeneratorAndDispose()
{
- StorageIterator storageIterator = new StorageIterator(new List>().GetEnumerator());
+ StorageIterator storageIterator = new StorageIterator(new List<(StorageKey, StorageItem)>().GetEnumerator());
Assert.IsNotNull(storageIterator);
Action action = () => storageIterator.Dispose();
action.Should().NotThrow();
@@ -23,12 +23,12 @@ public void TestGeneratorAndDispose()
[TestMethod]
public void TestKeyAndValueAndNext()
{
- List> list = new List>();
+ List<(StorageKey, StorageItem)> list = new List<(StorageKey, StorageItem)>();
StorageKey storageKey = new StorageKey();
storageKey.Key = new byte[1];
StorageItem storageItem = new StorageItem();
storageItem.Value = new byte[1];
- list.Add(new KeyValuePair(storageKey, storageItem));
+ list.Add((storageKey, storageItem));
StorageIterator storageIterator = new StorageIterator(list.GetEnumerator());
storageIterator.Next();
Assert.AreEqual(new ByteArray(new byte[1]), storageIterator.Key());
diff --git a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs
index 7e811d3eda..96beff3cbd 100644
--- a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs
+++ b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_GasToken.cs
@@ -2,7 +2,6 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
-using Neo.Persistence;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.UnitTests.Extensions;
@@ -17,13 +16,10 @@ namespace Neo.UnitTests.SmartContract.Native.Tokens
[TestClass]
public class UT_GasToken
{
- Store Store;
-
[TestInitialize]
public void TestSetup()
{
TestBlockchain.InitializeMockNeoSystem();
- Store = TestBlockchain.GetStore();
}
[TestMethod]
@@ -41,7 +37,7 @@ public void TestSetup()
[TestMethod]
public void Check_BalanceOfTransferAndBurn()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
snapshot.PersistingBlock = new Block() { Index = 1000 };
byte[] from = Contract.CreateMultiSigRedeemScript(Blockchain.StandbyValidators.Length / 2 + 1,
@@ -133,7 +129,7 @@ public void Check_BalanceOfTransferAndBurn()
[TestMethod]
public void Check_BadScript()
{
- var engine = new ApplicationEngine(TriggerType.Application, null, Store.GetSnapshot(), 0);
+ var engine = new ApplicationEngine(TriggerType.Application, null, Blockchain.Singleton.GetSnapshot(), 0);
var script = new ScriptBuilder();
script.Emit(OpCode.NOP);
@@ -160,7 +156,7 @@ public void TestGetSysFeeAmount1()
[TestMethod]
public void TestGetSysFeeAmount2()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
NativeContract.GAS.GetSysFeeAmount(snapshot, 0).Should().Be(new BigInteger(0));
NativeContract.GAS.GetSysFeeAmount(snapshot, 1).Should().Be(new BigInteger(0));
diff --git a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs
index 19f7ad2f6a..8ae4516cab 100644
--- a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs
+++ b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs
@@ -21,13 +21,10 @@ namespace Neo.UnitTests.SmartContract.Native.Tokens
[TestClass]
public class UT_NeoToken
{
- private Store Store;
-
[TestInitialize]
public void TestSetup()
{
TestBlockchain.InitializeMockNeoSystem();
- Store = TestBlockchain.GetStore();
}
[TestMethod]
@@ -45,7 +42,7 @@ public void TestSetup()
[TestMethod]
public void Check_Vote()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
snapshot.PersistingBlock = new Block() { Index = 1000 };
byte[] from = Contract.CreateMultiSigRedeemScript(Blockchain.StandbyValidators.Length / 2 + 1,
@@ -85,7 +82,7 @@ public void Check_Vote()
[TestMethod]
public void Check_UnclaimedGas()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
snapshot.PersistingBlock = new Block() { Index = 1000 };
byte[] from = Contract.CreateMultiSigRedeemScript(Blockchain.StandbyValidators.Length / 2 + 1,
@@ -103,7 +100,7 @@ public void Check_UnclaimedGas()
[TestMethod]
public void Check_RegisterValidator()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var ret = Check_RegisterValidator(snapshot, new byte[0]);
ret.State.Should().BeFalse();
@@ -148,7 +145,7 @@ public void Check_RegisterValidator()
[TestMethod]
public void Check_Transfer()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
snapshot.PersistingBlock = new Block() { Index = 1000 };
byte[] from = Contract.CreateMultiSigRedeemScript(Blockchain.StandbyValidators.Length / 2 + 1,
@@ -201,7 +198,7 @@ public void Check_Transfer()
[TestMethod]
public void Check_BalanceOf()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
byte[] account = Contract.CreateMultiSigRedeemScript(Blockchain.StandbyValidators.Length / 2 + 1,
Blockchain.StandbyValidators).ToScriptHash().ToArray();
@@ -215,7 +212,7 @@ public void Check_BalanceOf()
[TestMethod]
public void Check_Initialize()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
// StandbyValidators
@@ -240,7 +237,7 @@ public void Check_Initialize()
[TestMethod]
public void Check_BadScript()
{
- var engine = new ApplicationEngine(TriggerType.Application, null, Store.GetSnapshot(), 0);
+ var engine = new ApplicationEngine(TriggerType.Application, null, Blockchain.Singleton.GetSnapshot(), 0);
var script = new ScriptBuilder();
script.Emit(OpCode.NOP);
@@ -252,7 +249,7 @@ public void Check_BadScript()
[TestMethod]
public void TestCalculateBonus()
{
- Snapshot snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
StorageKey key = CreateStorageKey(20, UInt160.Zero.ToArray());
snapshot.Storages.Add(key, new StorageItem
{
@@ -295,7 +292,7 @@ public void TestGetNextBlockValidators1()
[TestMethod]
public void TestGetNextBlockValidators2()
{
- Snapshot snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var result = NativeContract.NEO.GetNextBlockValidators(snapshot);
result.Length.Should().Be(7);
result[0].ToArray().ToHexString().Should().Be("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c");
@@ -343,7 +340,7 @@ public void TestGetRegisteredValidators1()
[TestMethod]
public void TestGetRegisteredValidators2()
{
- Snapshot snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var result = NativeContract.NEO.GetRegisteredValidators(snapshot).ToArray();
result.Length.Should().Be(7);
result[0].PublicKey.ToArray().ToHexString().Should().Be("02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70");
@@ -390,7 +387,7 @@ public void TestGetValidators1()
[TestMethod]
public void TestGetValidators2()
{
- Snapshot snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var result = NativeContract.NEO.GetValidators(snapshot);
result[0].ToArray().ToHexString().Should().Be("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c");
result[1].ToArray().ToHexString().Should().Be("02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093");
@@ -416,7 +413,7 @@ public void TestGetValidators2()
[TestMethod]
public void TestInitialize()
{
- Snapshot snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var engine = new ApplicationEngine(TriggerType.System, null, snapshot, 0, true);
Action action = () => NativeContract.NEO.Initialize(engine);
action.Should().Throw();
@@ -425,6 +422,7 @@ public void TestInitialize()
NativeContract.NEO.Initialize(engine).Should().BeFalse();
snapshot.Storages.Delete(CreateStorageKey(11));
+ snapshot.PersistingBlock = Blockchain.GenesisBlock;
engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
NativeContract.NEO.Initialize(engine).Should().BeTrue();
}
@@ -448,14 +446,14 @@ public void TestOnBalanceChanging()
[TestMethod]
public void TestTotalSupply()
{
- Snapshot snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
NativeContract.NEO.TotalSupply(snapshot).Should().Be(new BigInteger(100000000));
}
[TestMethod]
public void TestUnclaimedGas()
{
- Snapshot snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
NativeContract.NEO.UnclaimedGas(snapshot, UInt160.Zero, 10).Should().Be(new BigInteger(0));
snapshot.Storages.Add(CreateStorageKey(20, UInt160.Zero.ToArray()), new StorageItem
{
@@ -467,7 +465,7 @@ public void TestUnclaimedGas()
[TestMethod]
public void TestVote()
{
- Snapshot snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
UInt160 account = UInt160.Parse("01ff00ff00ff00ff00ff00ff00ff00ff00ff00a4");
StorageKey keyAccount = CreateStorageKey(20, account.ToArray());
StorageKey keyValidator = CreateStorageKey(33, ECCurve.Secp256r1.G.ToArray());
@@ -529,7 +527,8 @@ public void TestValidatorState_ToByteArray()
internal (bool State, bool Result) Transfer4TesingOnBalanceChanging(BigInteger amount, bool addVotes)
{
- Snapshot snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
+ snapshot.PersistingBlock = Blockchain.GenesisBlock;
var engine = new ApplicationEngine(TriggerType.Application, Blockchain.GenesisBlock, snapshot, 0, true);
ScriptBuilder sb = new ScriptBuilder();
var tmp = engine.ScriptContainer.GetScriptHashesForVerifying(engine.Snapshot);
@@ -578,7 +577,7 @@ public void TestValidatorState_ToByteArray()
return (true, result.ToBoolean());
}
- internal static (bool State, bool Result) Check_Vote(Snapshot snapshot, byte[] account, byte[][] pubkeys, bool signAccount)
+ internal static (bool State, bool Result) Check_Vote(StoreView snapshot, byte[] account, byte[][] pubkeys, bool signAccount)
{
var engine = new ApplicationEngine(TriggerType.Application,
new Nep5NativeContractExtensions.ManualWitness(signAccount ? new UInt160(account) : UInt160.Zero), snapshot, 0, true);
@@ -608,7 +607,7 @@ internal static (bool State, bool Result) Check_Vote(Snapshot snapshot, byte[] a
return (true, result.ToBoolean());
}
- internal static (bool State, bool Result) Check_RegisterValidator(Snapshot snapshot, byte[] pubkey)
+ internal static (bool State, bool Result) Check_RegisterValidator(StoreView snapshot, byte[] pubkey)
{
var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
@@ -632,7 +631,7 @@ internal static (bool State, bool Result) Check_RegisterValidator(Snapshot snaps
return (true, result.ToBoolean());
}
- internal static ECPoint[] Check_GetValidators(Snapshot snapshot)
+ internal static ECPoint[] Check_GetValidators(StoreView snapshot)
{
var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
@@ -652,7 +651,7 @@ internal static ECPoint[] Check_GetValidators(Snapshot snapshot)
return (result as VM.Types.Array).Select(u => u.GetSpan().AsSerializable()).ToArray();
}
- internal static (BigInteger Value, bool State) Check_UnclaimedGas(Snapshot snapshot, byte[] address)
+ internal static (BigInteger Value, bool State) Check_UnclaimedGas(StoreView snapshot, byte[] address)
{
var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
diff --git a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs
index a34c7a109f..a3bc7fa531 100644
--- a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs
+++ b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_Nep5Token.cs
@@ -1,8 +1,6 @@
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Moq;
using Neo.Ledger;
-using Neo.Persistence;
using Neo.SmartContract;
using Neo.SmartContract.Native.Tokens;
using Neo.VM;
@@ -20,8 +18,7 @@ public class UT_Nep5Token
[TestMethod]
public void TestTotalSupply()
{
- var mockSnapshot = new Mock();
- var myDataCache = new TestDataCache();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
StorageItem item = new StorageItem
{
Value = new byte[] { 0x01 }
@@ -38,10 +35,9 @@ public void TestTotalSupply()
var Hash = script.ToScriptHash();
key.ScriptHash = Hash;
- myDataCache.Add(key, item);
- mockSnapshot.SetupGet(p => p.Storages).Returns(myDataCache);
+ snapshot.Storages.Add(key, item);
TestNep5Token test = new TestNep5Token();
- ApplicationEngine ae = new ApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0);
+ ApplicationEngine ae = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
StackItem stackItem = test.TotalSupply(ae, null);
stackItem.GetBigInteger().Should().Be(1);
}
@@ -49,8 +45,7 @@ public void TestTotalSupply()
[TestMethod]
public void TestTotalSupplyDecimal()
{
- var mockSnapshot = new Mock();
- var myDataCache = new TestDataCache();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
TestNep5Token test = new TestNep5Token();
BigInteger totalSupply = 100_000_000;
@@ -73,10 +68,9 @@ public void TestTotalSupplyDecimal()
var Hash = script.ToScriptHash();
key.ScriptHash = Hash;
- myDataCache.Add(key, item);
- mockSnapshot.SetupGet(p => p.Storages).Returns(myDataCache);
+ snapshot.Storages.Add(key, item);
- ApplicationEngine ae = new ApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0);
+ ApplicationEngine ae = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
StackItem stackItem = test.TotalSupply(ae, null);
stackItem.GetBigInteger().Should().Be(10_000_000_000_000_000);
}
diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs
index 61e93de6ad..71cfd3c093 100644
--- a/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs
+++ b/tests/neo.UnitTests/SmartContract/Native/UT_NativeContract.cs
@@ -1,6 +1,6 @@
-using FluentAssertions;
+using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Persistence;
+using Neo.Ledger;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
@@ -13,13 +13,10 @@ namespace Neo.UnitTests.SmartContract.Native
[TestClass]
public class UT_NativeContract
{
- Store Store;
-
[TestInitialize]
public void TestSetup()
{
TestBlockchain.InitializeMockNeoSystem();
- Store = TestBlockchain.GetStore();
}
[TestMethod]
@@ -37,7 +34,7 @@ public void TestInitialize()
[TestMethod]
public void TestInvoke()
{
- ApplicationEngine engine1 = new ApplicationEngine(TriggerType.Application, null, Store.GetSnapshot(), 0);
+ ApplicationEngine engine1 = new ApplicationEngine(TriggerType.Application, null, Blockchain.Singleton.GetSnapshot(), 0);
TestNativeContract testNativeContract = new TestNativeContract();
ScriptBuilder sb1 = new ScriptBuilder();
@@ -46,7 +43,7 @@ public void TestInvoke()
engine1.LoadScript(sb1.ToArray());
testNativeContract.Invoke(engine1).Should().BeFalse();
- ApplicationEngine engine2 = new ApplicationEngine(TriggerType.Application, null, Store.GetSnapshot(), 0);
+ ApplicationEngine engine2 = new ApplicationEngine(TriggerType.Application, null, Blockchain.Singleton.GetSnapshot(), 0);
ScriptBuilder sb2 = new ScriptBuilder();
sb2.EmitSysCall("test".ToInteropMethodHash());
@@ -68,14 +65,14 @@ public void TestInvoke()
[TestMethod]
public void TestOnPersistWithArgs()
{
- ApplicationEngine engine1 = new ApplicationEngine(TriggerType.Application, null, Store.GetSnapshot(), 0);
+ ApplicationEngine engine1 = new ApplicationEngine(TriggerType.Application, null, Blockchain.Singleton.GetSnapshot(), 0);
TestNativeContract testNativeContract = new TestNativeContract();
VMArray args = new VMArray();
VM.Types.Boolean result1 = new VM.Types.Boolean(false);
testNativeContract.TestOnPersist(engine1, args).Should().Be(result1);
- ApplicationEngine engine2 = new ApplicationEngine(TriggerType.System, null, Store.GetSnapshot(), 0);
+ ApplicationEngine engine2 = new ApplicationEngine(TriggerType.System, null, Blockchain.Singleton.GetSnapshot(), 0);
VM.Types.Boolean result2 = new VM.Types.Boolean(true);
testNativeContract.TestOnPersist(engine2, args).Should().Be(result2);
}
diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs
index b75141459f..0b15d0732d 100644
--- a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs
+++ b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs
@@ -15,13 +15,10 @@ namespace Neo.UnitTests.SmartContract.Native
[TestClass]
public class UT_PolicyContract
{
- Store Store;
-
[TestInitialize]
public void TestSetup()
{
TestBlockchain.InitializeMockNeoSystem();
- Store = TestBlockchain.GetStore();
}
[TestMethod]
@@ -30,7 +27,7 @@ public void TestSetup()
[TestMethod]
public void Check_Initialize()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var keyCount = snapshot.Storages.GetChangeSet().Count();
NativeContract.Policy.Initialize(new ApplicationEngine(TriggerType.Application, null, snapshot, 0)).Should().BeTrue();
@@ -57,7 +54,7 @@ public void Check_Initialize()
[TestMethod]
public void Check_SetMaxBlockSize()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
// Fake blockchain
@@ -103,7 +100,7 @@ public void Check_SetMaxBlockSize()
[TestMethod]
public void Check_SetMaxTransactionsPerBlock()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
// Fake blockchain
@@ -138,7 +135,7 @@ public void Check_SetMaxTransactionsPerBlock()
[TestMethod]
public void Check_SetFeePerByte()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
// Fake blockchain
@@ -173,7 +170,7 @@ public void Check_SetFeePerByte()
[TestMethod]
public void Check_Block_UnblockAccount()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
// Fake blockchain
@@ -233,7 +230,7 @@ public void Check_Block_UnblockAccount()
public void TestCheckPolicy()
{
Transaction tx = Blockchain.GenesisBlock.Transactions[0];
- Snapshot snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
StorageKey storageKey = new StorageKey
{
@@ -248,7 +245,7 @@ public void TestCheckPolicy()
NativeContract.Policy.CheckPolicy(tx, snapshot).Should().BeFalse();
- snapshot = Store.GetSnapshot().Clone();
+ 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 d8bdd8a857..3790aaf094 100644
--- a/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs
+++ b/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs
@@ -17,19 +17,17 @@ public class UT_ApplicationEngine
{
private string message = null;
private StackItem item = null;
- private Store Store;
[TestInitialize]
public void TestSetup()
{
TestBlockchain.InitializeMockNeoSystem();
- Store = TestBlockchain.GetStore();
}
[TestMethod]
public void TestLog()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
ApplicationEngine.Log += Test_Log1;
string logMessage = "TestMessage";
@@ -54,7 +52,7 @@ public void TestLog()
[TestMethod]
public void TestNotify()
{
- var snapshot = Store.GetSnapshot().Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
ApplicationEngine.Notify += Test_Notify1;
StackItem notifyItem = "TestItem";
@@ -79,10 +77,10 @@ public void TestNotify()
[TestMethod]
public void TestDisposable()
{
- var snapshot = Store.GetSnapshot().Clone();
- var replica = snapshot.Clone();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
+ var m = new Mock();
var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
- engine.AddDisposable(replica).Should().Be(replica);
+ engine.AddDisposable(m.Object).Should().Be(m.Object);
Action action = () => engine.Dispose();
action.Should().NotThrow();
}
@@ -110,19 +108,12 @@ private void Test_Notify2(object sender, NotifyEventArgs e)
[TestMethod]
public void TestCreateDummyBlock()
{
- var mockSnapshot = new Mock();
- UInt256 currentBlockHash = UInt256.Parse("0x0000000000000000000000000000000000000000000000000000000000000000");
- TrimmedBlock block = new TrimmedBlock();
- var cache = new TestDataCache();
- cache.Add(currentBlockHash, block);
- mockSnapshot.SetupGet(p => p.Blocks).Returns(cache);
- TestMetaDataCache testCache = new TestMetaDataCache();
- mockSnapshot.SetupGet(p => p.BlockHashIndex).Returns(testCache);
+ var snapshot = Blockchain.Singleton.GetSnapshot();
byte[] SyscallSystemRuntimeCheckWitnessHash = new byte[] { 0x68, 0xf8, 0x27, 0xec, 0x8c };
- ApplicationEngine.Run(SyscallSystemRuntimeCheckWitnessHash, mockSnapshot.Object);
- mockSnapshot.Object.PersistingBlock.Version.Should().Be(0);
- mockSnapshot.Object.PersistingBlock.PrevHash.Should().Be(currentBlockHash);
- mockSnapshot.Object.PersistingBlock.MerkleRoot.Should().Be(new UInt256());
+ ApplicationEngine.Run(SyscallSystemRuntimeCheckWitnessHash, snapshot);
+ snapshot.PersistingBlock.Version.Should().Be(0);
+ snapshot.PersistingBlock.PrevHash.Should().Be(Blockchain.GenesisBlock.Hash);
+ snapshot.PersistingBlock.MerkleRoot.Should().Be(new UInt256());
}
[TestMethod]
@@ -134,10 +125,8 @@ public void TestOnSysCall()
engine.LoadScript(SyscallSystemRuntimeCheckWitnessHash);
engine.GetOnSysCall(descriptor.Hash).Should().BeFalse();
- var mockSnapshot = new Mock();
- TestMetaDataCache testCache = new TestMetaDataCache();
- mockSnapshot.SetupGet(p => p.BlockHashIndex).Returns(testCache);
- engine = new TestApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0, true);
+ var snapshot = Blockchain.Singleton.GetSnapshot();
+ engine = new TestApplicationEngine(TriggerType.Application, null, snapshot, 0, true);
engine.LoadScript(SyscallSystemRuntimeCheckWitnessHash);
engine.GetOnSysCall(descriptor.Hash).Should().BeTrue();
}
@@ -151,7 +140,7 @@ private static bool Blockchain_GetHeight(ApplicationEngine engine)
public class TestApplicationEngine : ApplicationEngine
{
- public TestApplicationEngine(TriggerType trigger, IVerifiable container, Snapshot snapshot, long gas, bool testMode = false) : base(trigger, container, snapshot, gas, testMode)
+ public TestApplicationEngine(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_InteropService.NEO.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs
index 3e60b91591..351f885f11 100644
--- a/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs
+++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.NEO.cs
@@ -1,12 +1,10 @@
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Moq;
using Neo.Cryptography;
using Neo.Cryptography.ECC;
using Neo.Ledger;
using Neo.Network.P2P;
using Neo.Network.P2P.Payloads;
-using Neo.Persistence;
using Neo.SmartContract;
using Neo.SmartContract.Enumerators;
using Neo.SmartContract.Iterators;
@@ -142,10 +140,10 @@ public void TestAccount_IsStandard()
InteropService.Invoke(engine, InteropService.Neo_Account_IsStandard).Should().BeTrue();
engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().BeTrue();
- var mockSnapshot = new Mock();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var state = TestUtils.GetContract();
- mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache(state.ScriptHash, state));
- engine = new ApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0);
+ snapshot.Contracts.Add(state.ScriptHash, state);
+ engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
engine.LoadScript(new byte[] { 0x01 });
engine.CurrentContext.EvaluationStack.Push(state.ScriptHash.ToArray());
InteropService.Invoke(engine, InteropService.Neo_Account_IsStandard).Should().BeTrue();
@@ -176,10 +174,10 @@ public void TestContract_Create()
engine.CurrentContext.EvaluationStack.Push(script);
InteropService.Invoke(engine, InteropService.Neo_Contract_Create).Should().BeTrue();
- var mockSnapshot = new Mock();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var state = TestUtils.GetContract();
- mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache(state.ScriptHash, state));
- engine = new ApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0);
+ snapshot.Contracts.Add(state.ScriptHash, state);
+ engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
engine.LoadScript(new byte[] { 0x01 });
engine.CurrentContext.EvaluationStack.Push(manifest.ToString());
engine.CurrentContext.EvaluationStack.Push(state.Script);
@@ -219,7 +217,7 @@ public void TestContract_Update()
Signature = signature
}
};
- var mockSnapshot = new Mock();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var state = TestUtils.GetContract();
state.Manifest.Features = ContractFeatures.HasStorage;
var storageItem = new StorageItem
@@ -233,9 +231,9 @@ public void TestContract_Update()
ScriptHash = state.ScriptHash,
Key = new byte[] { 0x01 }
};
- mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache(state.ScriptHash, state));
- mockSnapshot.SetupGet(p => p.Storages).Returns(new TestDataCache(storageKey, storageItem));
- engine = new ApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0);
+ snapshot.Contracts.Add(state.ScriptHash, state);
+ snapshot.Storages.Add(storageKey, storageItem);
+ engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
engine.LoadScript(state.Script);
engine.CurrentContext.EvaluationStack.Push(manifest.ToString());
engine.CurrentContext.EvaluationStack.Push(script);
@@ -244,10 +242,10 @@ public void TestContract_Update()
// Remove Storage flag with something stored
state.Manifest.Features = ContractFeatures.NoProperty;
- mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache(state.ScriptHash, state));
- mockSnapshot.SetupGet(p => p.Storages).Returns(new TestDataCache(storageKey, storageItem));
+ snapshot.Contracts.Add(state.ScriptHash, state);
+ snapshot.Storages.Add(storageKey, storageItem);
- engine = new ApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0);
+ engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
engine.LoadScript(state.Script);
engine.CurrentContext.EvaluationStack.Push(manifest.ToString());
engine.CurrentContext.EvaluationStack.Push(script);
@@ -257,7 +255,7 @@ public void TestContract_Update()
[TestMethod]
public void TestStorage_Find()
{
- var mockSnapshot = new Mock();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var state = TestUtils.GetContract();
state.Manifest.Features = ContractFeatures.HasStorage;
@@ -271,9 +269,9 @@ public void TestStorage_Find()
ScriptHash = state.ScriptHash,
Key = new byte[] { 0x01 }
};
- mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache(state.ScriptHash, state));
- mockSnapshot.SetupGet(p => p.Storages).Returns(new TestDataCache(storageKey, storageItem));
- var engine = new ApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0);
+ snapshot.Contracts.Add(state.ScriptHash, state);
+ snapshot.Storages.Add(storageKey, storageItem);
+ var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
engine.LoadScript(new byte[] { 0x01 });
engine.CurrentContext.EvaluationStack.Push(new byte[] { 0x01 });
diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs
index 83f4a1485b..f04d6f5b6c 100644
--- a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs
+++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs
@@ -1,12 +1,10 @@
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Moq;
using Neo.Cryptography;
using Neo.Cryptography.ECC;
using Neo.Ledger;
using Neo.Network.P2P;
using Neo.Network.P2P.Payloads;
-using Neo.Persistence;
using Neo.SmartContract;
using Neo.SmartContract.Manifest;
using Neo.VM;
@@ -31,7 +29,7 @@ public void TestSetup()
public void Runtime_GetNotifications_Test()
{
UInt160 scriptHash2;
- var snapshot = TestBlockchain.GetStore().GetSnapshot();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
using (var script = new ScriptBuilder())
{
@@ -445,10 +443,10 @@ public void TestBlockchain_GetContract()
InteropService.Invoke(engine, InteropService.System_Blockchain_GetContract).Should().BeTrue();
engine.CurrentContext.EvaluationStack.Pop().Should().Be(StackItem.Null);
- var mockSnapshot = new Mock();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var state = TestUtils.GetContract();
- mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache(state.ScriptHash, state));
- engine = new ApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0);
+ snapshot.Contracts.Add(state.ScriptHash, state);
+ engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
engine.LoadScript(new byte[] { 0x01 });
engine.CurrentContext.EvaluationStack.Push(state.ScriptHash.ToArray());
InteropService.Invoke(engine, InteropService.System_Blockchain_GetContract).Should().BeTrue();
@@ -483,7 +481,7 @@ public void TestStorage_GetReadOnlyContext()
[TestMethod]
public void TestStorage_Get()
{
- var mockSnapshot = new Mock();
+ var snapshot = Blockchain.Singleton.GetSnapshot();
var state = TestUtils.GetContract();
state.Manifest.Features = ContractFeatures.HasStorage;
@@ -498,9 +496,9 @@ public void TestStorage_Get()
Value = new byte[] { 0x01, 0x02, 0x03, 0x04 },
IsConstant = true
};
- mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache(state.ScriptHash, state));
- mockSnapshot.SetupGet(p => p.Storages).Returns(new TestDataCache(storageKey, storageItem));
- var engine = new ApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0);
+ snapshot.Contracts.Add(state.ScriptHash, state);
+ snapshot.Storages.Add(storageKey, storageItem);
+ var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
engine.LoadScript(new byte[] { 0x01 });
engine.CurrentContext.EvaluationStack.Push(new byte[] { 0x01 });
@@ -512,8 +510,8 @@ public void TestStorage_Get()
InteropService.Invoke(engine, InteropService.System_Storage_Get).Should().BeTrue();
engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToHexString().Should().Be(storageItem.Value.ToHexString());
- mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache