Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Improve]: use IReadOnlyStoreView instead. #3683

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Neo/SmartContract/ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ protected override void PostExecuteInstruction(Instruction instruction)
Diagnostic?.PostExecuteInstruction(instruction);
}

private static Block CreateDummyBlock(DataCache snapshot, ProtocolSettings settings)
private static Block CreateDummyBlock(IReadOnlyStoreView snapshot, ProtocolSettings settings)
{
UInt256 hash = NativeContract.Ledger.CurrentHash(snapshot);
Block currentBlock = NativeContract.Ledger.GetBlock(snapshot, hash);
Expand Down
17 changes: 8 additions & 9 deletions src/Neo/SmartContract/Native/ContractManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ internal override async ContractTask OnPersistAsync(ApplicationEngine engine)
}

[ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)]
private long GetMinimumDeploymentFee(DataCache snapshot)
private long GetMinimumDeploymentFee(IReadOnlyStoreView snapshot)
{
// In the unit of datoshi, 1 datoshi = 1e-8 GAS
return (long)(BigInteger)snapshot[CreateStorageKey(Prefix_MinimumDeploymentFee)];
Expand All @@ -137,9 +137,10 @@ private void SetMinimumDeploymentFee(ApplicationEngine engine, BigInteger value/
/// <param name="hash">The hash of the deployed contract.</param>
/// <returns>The deployed contract.</returns>
[ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)]
public ContractState GetContract(DataCache snapshot, UInt160 hash)
public ContractState GetContract(IReadOnlyStoreView snapshot, UInt160 hash)
{
return snapshot.TryGet(CreateStorageKey(Prefix_Contract).Add(hash))?.GetInteroperable<ContractState>(false);
var key = CreateStorageKey(Prefix_Contract).Add(hash);
return snapshot.TryGet(key, out var item) ? item.GetInteroperable<ContractState>(false) : null;
}

/// <summary>
Expand All @@ -149,12 +150,10 @@ public ContractState GetContract(DataCache snapshot, UInt160 hash)
/// <param name="id">Contract ID.</param>
/// <returns>The deployed contract.</returns>
[ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)]
public ContractState GetContractById(DataCache snapshot, int id)
public ContractState GetContractById(IReadOnlyStoreView snapshot, int id)
{
StorageItem item = snapshot.TryGet(CreateStorageKey(Prefix_ContractHash).AddBigEndian(id));
if (item is null) return null;
var hash = new UInt160(item.Value.Span);
return GetContract(snapshot, hash);
var key = CreateStorageKey(Prefix_ContractHash).AddBigEndian(id);
return snapshot.TryGet(key, out var item) ? GetContract(snapshot, new UInt160(item.Value.Span)) : null;
}

/// <summary>
Expand Down Expand Up @@ -184,7 +183,7 @@ private IIterator GetContractHashes(DataCache snapshot)
/// <param name="pcount">The number of parameters</param>
/// <returns>True if the method exists.</returns>
[ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)]
public bool HasMethod(DataCache snapshot, UInt160 hash, string method, int pcount)
public bool HasMethod(IReadOnlyStoreView snapshot, UInt160 hash, string method, int pcount)
{
var contract = GetContract(snapshot, hash);
if (contract is null) return false;
Expand Down
1 change: 1 addition & 0 deletions src/Neo/SmartContract/Native/ContractMethodMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public ContractMethodMetadata(MemberInfo member, ContractMethodAttribute attribu
if (parameterInfos.Length > 0)
{
NeedApplicationEngine = parameterInfos[0].ParameterType.IsAssignableFrom(typeof(ApplicationEngine));
// snapshot is a DataCache instance, and DataCache implements IReadOnlyStoreView
NeedSnapshot = parameterInfos[0].ParameterType.IsAssignableFrom(typeof(DataCache));
shargon marked this conversation as resolved.
Show resolved Hide resolved
}
if (NeedApplicationEngine || NeedSnapshot)
Expand Down
16 changes: 8 additions & 8 deletions src/Neo/SmartContract/Native/FungibleToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,10 @@ internal async ContractTask Burn(ApplicationEngine engine, UInt160 account, BigI
/// <param name="snapshot">The snapshot used to read data.</param>
/// <returns>The total supply of the token.</returns>
[ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)]
public virtual BigInteger TotalSupply(DataCache snapshot)
public virtual BigInteger TotalSupply(IReadOnlyStoreView snapshot)
{
StorageItem storage = snapshot.TryGet(CreateStorageKey(Prefix_TotalSupply));
if (storage is null) return BigInteger.Zero;
return storage;
var key = CreateStorageKey(Prefix_TotalSupply);
return snapshot.TryGet(key, out var item) ? item : BigInteger.Zero;
}

/// <summary>
Expand All @@ -121,11 +120,12 @@ public virtual BigInteger TotalSupply(DataCache snapshot)
/// <param name="account">The owner of the account.</param>
/// <returns>The balance of the account. Or 0 if the account doesn't exist.</returns>
[ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)]
public virtual BigInteger BalanceOf(DataCache snapshot, UInt160 account)
public virtual BigInteger BalanceOf(IReadOnlyStoreView snapshot, UInt160 account)
{
StorageItem storage = snapshot.TryGet(CreateStorageKey(Prefix_Account).Add(account));
if (storage is null) return BigInteger.Zero;
return storage.GetInteroperable<TState>().Balance;
var key = CreateStorageKey(Prefix_Account).Add(account);
if (snapshot.TryGet(key, out var item))
return item.GetInteroperable<TState>().Balance;
return BigInteger.Zero;
}

[ContractMethod(CpuFee = 1 << 17, StorageFee = 50, RequiredCallFlags = CallFlags.States | CallFlags.AllowCall | CallFlags.AllowNotify)]
Expand Down
66 changes: 38 additions & 28 deletions src/Neo/SmartContract/Native/LedgerContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ internal override ContractTask OnPersistAsync(ApplicationEngine engine)
}
}
}

engine.SetState(transactions);
return ContractTask.CompletedTask;
}
Expand All @@ -87,7 +88,7 @@ internal bool Initialized(DataCache snapshot)
return snapshot.Find(CreateStorageKey(Prefix_Block).ToArray()).Any();
}

private bool IsTraceableBlock(DataCache snapshot, uint index, uint maxTraceableBlocks)
private bool IsTraceableBlock(IReadOnlyStoreView snapshot, uint index, uint maxTraceableBlocks)
{
uint currentIndex = CurrentIndex(snapshot);
if (index > currentIndex) return false;
Expand All @@ -100,14 +101,13 @@ private bool IsTraceableBlock(DataCache snapshot, uint index, uint maxTraceableB
/// <param name="snapshot">The snapshot used to read data.</param>
/// <param name="index">The index of the block.</param>
/// <returns>The hash of the block.</returns>
public UInt256 GetBlockHash(DataCache snapshot, uint index)
public UInt256 GetBlockHash(IReadOnlyStoreView snapshot, uint index)
{
if (snapshot is null)
throw new ArgumentNullException(nameof(snapshot));

StorageItem item = snapshot.TryGet(CreateStorageKey(Prefix_BlockHash).AddBigEndian(index));
if (item is null) return null;
return new UInt256(item.Value.Span);
var key = CreateStorageKey(Prefix_BlockHash).AddBigEndian(index);
return snapshot.TryGet(key, out var item) ? new UInt256(item.Value.Span) : null;
}

/// <summary>
Expand All @@ -116,7 +116,7 @@ public UInt256 GetBlockHash(DataCache snapshot, uint index)
/// <param name="snapshot">The snapshot used to read data.</param>
/// <returns>The hash of the current block.</returns>
[ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)]
public UInt256 CurrentHash(DataCache snapshot)
public UInt256 CurrentHash(IReadOnlyStoreView snapshot)
{
if (snapshot is null)
throw new ArgumentNullException(nameof(snapshot));
Expand All @@ -130,7 +130,7 @@ public UInt256 CurrentHash(DataCache snapshot)
/// <param name="snapshot">The snapshot used to read data.</param>
/// <returns>The index of the current block.</returns>
[ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)]
public uint CurrentIndex(DataCache snapshot)
public uint CurrentIndex(IReadOnlyStoreView snapshot)
{
if (snapshot is null)
throw new ArgumentNullException(nameof(snapshot));
Expand All @@ -143,8 +143,10 @@ public uint CurrentIndex(DataCache snapshot)
/// </summary>
/// <param name="snapshot">The snapshot used to read data.</param>
/// <param name="hash">The hash of the block.</param>
/// <returns><see langword="true"/> if the blockchain contains the block; otherwise, <see langword="false"/>.</returns>
public bool ContainsBlock(DataCache snapshot, UInt256 hash)
/// <returns>
/// <see langword="true"/> if the blockchain contains the block; otherwise, <see langword="false"/>.
/// </returns>
public bool ContainsBlock(IReadOnlyStoreView snapshot, UInt256 hash)
{
if (snapshot is null)
throw new ArgumentNullException(nameof(snapshot));
Expand All @@ -157,8 +159,10 @@ public bool ContainsBlock(DataCache snapshot, UInt256 hash)
/// </summary>
/// <param name="snapshot">The snapshot used to read data.</param>
/// <param name="hash">The hash of the transaction.</param>
/// <returns><see langword="true"/> if the blockchain contains the transaction; otherwise, <see langword="false"/>.</returns>
public bool ContainsTransaction(DataCache snapshot, UInt256 hash)
/// <returns>
/// <see langword="true"/> if the blockchain contains the transaction; otherwise, <see langword="false"/>.
/// </returns>
public bool ContainsTransaction(IReadOnlyStoreView snapshot, UInt256 hash)
{
var txState = GetTransactionState(snapshot, hash);
return txState != null;
Expand All @@ -172,8 +176,11 @@ public bool ContainsTransaction(DataCache snapshot, UInt256 hash)
/// <param name="hash">The hash of the conflicting transaction.</param>
/// <param name="signers">The list of signer accounts of the conflicting transaction.</param>
/// <param name="maxTraceableBlocks">MaxTraceableBlocks protocol setting.</param>
/// <returns><see langword="true"/> if the blockchain contains the hash of the conflicting transaction; otherwise, <see langword="false"/>.</returns>
public bool ContainsConflictHash(DataCache snapshot, UInt256 hash, IEnumerable<UInt160> signers, uint maxTraceableBlocks)
/// <returns>
/// <see langword="true"/> if the blockchain contains the hash of the conflicting transaction;
/// otherwise, <see langword="false"/>.
/// </returns>
public bool ContainsConflictHash(IReadOnlyStoreView snapshot, UInt256 hash, IEnumerable<UInt160> signers, uint maxTraceableBlocks)
{
if (snapshot is null)
throw new ArgumentNullException(nameof(snapshot));
Expand All @@ -182,14 +189,16 @@ public bool ContainsConflictHash(DataCache snapshot, UInt256 hash, IEnumerable<U
throw new ArgumentNullException(nameof(signers));

// Check the dummy stub firstly to define whether there's exist at least one conflict record.
var stub = snapshot.TryGet(CreateStorageKey(Prefix_Transaction).Add(hash))?.GetInteroperable<TransactionState>();
var key = CreateStorageKey(Prefix_Transaction).Add(hash);
var stub = snapshot.TryGet(key, out var item) ? item.GetInteroperable<TransactionState>() : null;
if (stub is null || stub.Transaction is not null || !IsTraceableBlock(snapshot, stub.BlockIndex, maxTraceableBlocks))
return false;

// At least one conflict record is found, then need to check signers intersection.
foreach (var signer in signers)
{
var state = snapshot.TryGet(CreateStorageKey(Prefix_Transaction).Add(hash).Add(signer))?.GetInteroperable<TransactionState>();
key = CreateStorageKey(Prefix_Transaction).Add(hash).Add(signer);
var state = snapshot.TryGet(key, out var tx) ? tx.GetInteroperable<TransactionState>() : null;
if (state is not null && IsTraceableBlock(snapshot, state.BlockIndex, maxTraceableBlocks))
return true;
}
Expand All @@ -203,14 +212,15 @@ public bool ContainsConflictHash(DataCache snapshot, UInt256 hash, IEnumerable<U
/// <param name="snapshot">The snapshot used to read data.</param>
/// <param name="hash">The hash of the block.</param>
/// <returns>The trimmed block.</returns>
public TrimmedBlock GetTrimmedBlock(DataCache snapshot, UInt256 hash)
public TrimmedBlock GetTrimmedBlock(IReadOnlyStoreView snapshot, UInt256 hash)
{
if (snapshot is null)
throw new ArgumentNullException(nameof(snapshot));

StorageItem item = snapshot.TryGet(CreateStorageKey(Prefix_Block).Add(hash));
if (item is null) return null;
return item.Value.AsSerializable<TrimmedBlock>();
var key = CreateStorageKey(Prefix_Block).Add(hash);
if (snapshot.TryGet(key, out var item))
return item.Value.AsSerializable<TrimmedBlock>();
return null;
}

[ContractMethod(CpuFee = 1 << 15, RequiredCallFlags = CallFlags.ReadStates)]
Expand All @@ -235,7 +245,7 @@ private TrimmedBlock GetBlock(ApplicationEngine engine, byte[] indexOrHash)
/// <param name="snapshot">The snapshot used to read data.</param>
/// <param name="hash">The hash of the block.</param>
/// <returns>The block with the specified hash.</returns>
public Block GetBlock(DataCache snapshot, UInt256 hash)
public Block GetBlock(IReadOnlyStoreView snapshot, UInt256 hash)
{
TrimmedBlock state = GetTrimmedBlock(snapshot, hash);
if (state is null) return null;
Expand All @@ -252,7 +262,7 @@ public Block GetBlock(DataCache snapshot, UInt256 hash)
/// <param name="snapshot">The snapshot used to read data.</param>
/// <param name="index">The index of the block.</param>
/// <returns>The block with the specified index.</returns>
public Block GetBlock(DataCache snapshot, uint index)
public Block GetBlock(IReadOnlyStoreView snapshot, uint index)
{
UInt256 hash = GetBlockHash(snapshot, index);
if (hash is null) return null;
Expand All @@ -265,7 +275,7 @@ public Block GetBlock(DataCache snapshot, uint index)
/// <param name="snapshot">The snapshot used to read data.</param>
/// <param name="hash">The hash of the block.</param>
/// <returns>The block header with the specified hash.</returns>
public Header GetHeader(DataCache snapshot, UInt256 hash)
public Header GetHeader(IReadOnlyStoreView snapshot, UInt256 hash)
{
return GetTrimmedBlock(snapshot, hash)?.Header;
}
Expand All @@ -276,7 +286,7 @@ public Header GetHeader(DataCache snapshot, UInt256 hash)
/// <param name="snapshot">The snapshot used to read data.</param>
/// <param name="index">The index of the block.</param>
/// <returns>The block header with the specified index.</returns>
public Header GetHeader(DataCache snapshot, uint index)
public Header GetHeader(IReadOnlyStoreView snapshot, uint index)
{
UInt256 hash = GetBlockHash(snapshot, index);
if (hash is null) return null;
Expand All @@ -289,14 +299,14 @@ public Header GetHeader(DataCache snapshot, uint index)
/// <param name="snapshot">The snapshot used to read data.</param>
/// <param name="hash">The hash of the transaction.</param>
/// <returns>The <see cref="TransactionState"/> with the specified hash.</returns>
public TransactionState GetTransactionState(DataCache snapshot, UInt256 hash)
public TransactionState GetTransactionState(IReadOnlyStoreView snapshot, UInt256 hash)
{
if (snapshot is null)
throw new ArgumentNullException(nameof(snapshot));

var state = snapshot.TryGet(CreateStorageKey(Prefix_Transaction).Add(hash))?.GetInteroperable<TransactionState>();
if (state?.Transaction is null) return null;
return state;
var key = CreateStorageKey(Prefix_Transaction).Add(hash);
var state = snapshot.TryGet(key, out var item) ? item.GetInteroperable<TransactionState>() : null;
return state?.Transaction is null ? null : state;
}

/// <summary>
Expand All @@ -305,7 +315,7 @@ public TransactionState GetTransactionState(DataCache snapshot, UInt256 hash)
/// <param name="snapshot">The snapshot used to read data.</param>
/// <param name="hash">The hash of the transaction.</param>
/// <returns>The transaction with the specified hash.</returns>
public Transaction GetTransaction(DataCache snapshot, UInt256 hash)
public Transaction GetTransaction(IReadOnlyStoreView snapshot, UInt256 hash)
{
return GetTransactionState(snapshot, hash)?.Transaction;
}
Expand Down
Loading
Loading