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

Add initial values for native contracts #2265

Merged
merged 5 commits into from
Jan 26, 2021
Merged
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
4 changes: 2 additions & 2 deletions src/neo/SmartContract/ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ protected ApplicationEngine(TriggerType trigger, IVerifiable container, DataCach
this.Snapshot = snapshot;
this.PersistingBlock = persistingBlock;
this.gas_amount = gas;
this.exec_fee_factor = snapshot is null ? PolicyContract.DefaultExecFeeFactor : NativeContract.Policy.GetExecFeeFactor(Snapshot);
this.StoragePrice = snapshot is null ? PolicyContract.DefaultStoragePrice : NativeContract.Policy.GetStoragePrice(Snapshot);
this.exec_fee_factor = snapshot is null || persistingBlock?.Index == 0 ? PolicyContract.DefaultExecFeeFactor : NativeContract.Policy.GetExecFeeFactor(Snapshot);
this.StoragePrice = snapshot is null || persistingBlock?.Index == 0 ? PolicyContract.DefaultStoragePrice : NativeContract.Policy.GetStoragePrice(Snapshot);
}

protected internal void AddGas(long gas)
Expand Down
3 changes: 2 additions & 1 deletion src/neo/SmartContract/Native/ContractManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ internal ContractManagement()

private int GetNextAvailableId(DataCache snapshot)
{
StorageItem item = snapshot.GetAndChange(CreateStorageKey(Prefix_NextAvailableId), () => new StorageItem(1));
StorageItem item = snapshot.GetAndChange(CreateStorageKey(Prefix_NextAvailableId));
int value = (int)(BigInteger)item;
item.Add(1);
return value;
Expand All @@ -74,6 +74,7 @@ private int GetNextAvailableId(DataCache snapshot)
internal override void Initialize(ApplicationEngine engine)
{
engine.Snapshot.Add(CreateStorageKey(Prefix_MinimumDeploymentFee), new StorageItem(10_00000000));
engine.Snapshot.Add(CreateStorageKey(Prefix_NextAvailableId), new StorageItem(0));
}

internal override void OnPersist(ApplicationEngine engine)
Expand Down
14 changes: 8 additions & 6 deletions src/neo/SmartContract/Native/NameService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ internal NameService()

internal override void Initialize(ApplicationEngine engine)
{
base.Initialize(engine);
engine.Snapshot.Add(CreateStorageKey(Prefix_Roots), new StorageItem(new StringList()));
engine.Snapshot.Add(CreateStorageKey(Prefix_DomainPrice), new StorageItem(10_00000000));
}

Expand Down Expand Up @@ -68,15 +70,15 @@ private void AddRoot(ApplicationEngine engine, string root)
{
if (!rootRegex.IsMatch(root)) throw new ArgumentException(null, nameof(root));
if (!CheckCommittee(engine)) throw new InvalidOperationException();
StringList roots = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Roots), () => new StorageItem(new StringList())).GetInteroperable<StringList>();
StringList roots = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Roots)).GetInteroperable<StringList>();
int index = roots.BinarySearch(root);
if (index >= 0) throw new InvalidOperationException("The name already exists.");
roots.Insert(~index, root);
}

public IEnumerable<string> GetRoots(DataCache snapshot)
{
return snapshot.TryGet(CreateStorageKey(Prefix_Roots))?.GetInteroperable<StringList>() ?? Enumerable.Empty<string>();
return snapshot[CreateStorageKey(Prefix_Roots)].GetInteroperable<StringList>();
}

[ContractMethod(0_03000000, CallFlags.WriteStates)]
Expand All @@ -101,8 +103,8 @@ public bool IsAvailable(DataCache snapshot, string name)
if (names.Length != 2) throw new ArgumentException(null, nameof(name));
byte[] hash = GetKey(Utility.StrictUTF8.GetBytes(name));
if (snapshot.TryGet(CreateStorageKey(Prefix_Token).Add(hash)) is not null) return false;
StringList roots = snapshot.TryGet(CreateStorageKey(Prefix_Roots))?.GetInteroperable<StringList>();
if (roots is null || roots.BinarySearch(names[1]) < 0) throw new InvalidOperationException();
StringList roots = snapshot[CreateStorageKey(Prefix_Roots)].GetInteroperable<StringList>();
if (roots.BinarySearch(names[1]) < 0) throw new InvalidOperationException();
return true;
}

Expand All @@ -115,8 +117,8 @@ private bool Register(ApplicationEngine engine, string name, UInt160 owner)
if (!engine.CheckWitnessInternal(owner)) throw new InvalidOperationException();
byte[] hash = GetKey(Utility.StrictUTF8.GetBytes(name));
if (engine.Snapshot.TryGet(CreateStorageKey(Prefix_Token).Add(hash)) is not null) return false;
StringList roots = engine.Snapshot.TryGet(CreateStorageKey(Prefix_Roots))?.GetInteroperable<StringList>();
if (roots is null || roots.BinarySearch(names[1]) < 0) throw new InvalidOperationException();
StringList roots = engine.Snapshot[CreateStorageKey(Prefix_Roots)].GetInteroperable<StringList>();
if (roots.BinarySearch(names[1]) < 0) throw new InvalidOperationException();
engine.AddGas(GetPrice(engine.Snapshot));
NameState state = new NameState
{
Expand Down
10 changes: 7 additions & 3 deletions src/neo/SmartContract/Native/NonfungibleToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,17 @@ protected NonfungibleToken()

protected virtual byte[] GetKey(byte[] tokenId) => tokenId;

internal override void Initialize(ApplicationEngine engine)
{
engine.Snapshot.Add(CreateStorageKey(Prefix_TotalSupply), new StorageItem(BigInteger.Zero));
}

protected void Mint(ApplicationEngine engine, TokenState token)
{
engine.Snapshot.Add(CreateStorageKey(Prefix_Token).Add(GetKey(token.Id)), new StorageItem(token));
NFTAccountState account = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_Account).Add(token.Owner), () => new StorageItem(new NFTAccountState())).GetInteroperable<NFTAccountState>();
account.Add(token.Id);
engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_TotalSupply), () => new StorageItem(BigInteger.Zero)).Add(1);
engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_TotalSupply)).Add(1);
PostTransfer(engine, null, token.Owner, token.Id);
}

Expand All @@ -93,8 +98,7 @@ private protected void Burn(ApplicationEngine engine, StorageKey key)
[ContractMethod(0_01000000, CallFlags.ReadStates)]
public BigInteger TotalSupply(DataCache snapshot)
{
StorageItem storage = snapshot.TryGet(CreateStorageKey(Prefix_TotalSupply));
return storage ?? BigInteger.Zero;
return snapshot[CreateStorageKey(Prefix_TotalSupply)];
}

[ContractMethod(0_01000000, CallFlags.ReadStates)]
Expand Down
17 changes: 9 additions & 8 deletions src/neo/SmartContract/Native/OracleContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Neo.VM;
using Neo.VM.Types;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
Expand Down Expand Up @@ -104,20 +105,20 @@ private UInt256 GetOriginalTxid(ApplicationEngine engine)

public OracleRequest GetRequest(DataCache snapshot, ulong id)
{
return snapshot.TryGet(CreateStorageKey(Prefix_Request).Add(id))?.GetInteroperable<OracleRequest>();
return snapshot.TryGet(CreateStorageKey(Prefix_Request).AddBigEndian(id))?.GetInteroperable<OracleRequest>();
}

public IEnumerable<(ulong, OracleRequest)> GetRequests(DataCache snapshot)
{
return snapshot.Find(new KeyBuilder(Id, Prefix_Request).ToArray()).Select(p => (BitConverter.ToUInt64(p.Key.Key, 1), p.Value.GetInteroperable<OracleRequest>()));
return snapshot.Find(CreateStorageKey(Prefix_Request).ToArray()).Select(p => (BinaryPrimitives.ReadUInt64BigEndian(p.Key.Key.AsSpan(1)), p.Value.GetInteroperable<OracleRequest>()));
}

public IEnumerable<(ulong, OracleRequest)> GetRequestsByUrl(DataCache snapshot, string url)
{
IdList list = snapshot.TryGet(CreateStorageKey(Prefix_IdList).Add(GetUrlHash(url)))?.GetInteroperable<IdList>();
if (list is null) yield break;
foreach (ulong id in list)
yield return (id, snapshot[CreateStorageKey(Prefix_Request).Add(id)].GetInteroperable<OracleRequest>());
yield return (id, snapshot[CreateStorageKey(Prefix_Request).AddBigEndian(id)].GetInteroperable<OracleRequest>());
}

private static byte[] GetUrlHash(string url)
Expand All @@ -127,7 +128,7 @@ private static byte[] GetUrlHash(string url)

internal override void Initialize(ApplicationEngine engine)
{
engine.Snapshot.Add(CreateStorageKey(Prefix_RequestId), new StorageItem(BitConverter.GetBytes(0ul)));
engine.Snapshot.Add(CreateStorageKey(Prefix_RequestId), new StorageItem(BigInteger.Zero));
}

internal override void PostPersist(ApplicationEngine engine)
Expand All @@ -140,7 +141,7 @@ internal override void PostPersist(ApplicationEngine engine)
if (response is null) continue;

//Remove the request from storage
StorageKey key = CreateStorageKey(Prefix_Request).Add(response.Id);
StorageKey key = CreateStorageKey(Prefix_Request).AddBigEndian(response.Id);
OracleRequest request = engine.Snapshot.TryGet(key)?.GetInteroperable<OracleRequest>();
if (request == null) continue;
engine.Snapshot.Delete(key);
Expand Down Expand Up @@ -184,13 +185,13 @@ private void Request(ApplicationEngine engine, string url, string filter, string

//Increase the request id
StorageItem item_id = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_RequestId));
ulong id = BitConverter.ToUInt64(item_id.Value) + 1;
item_id.Value = BitConverter.GetBytes(id);
ulong id = (ulong)(BigInteger)item_id;
item_id.Add(1);

//Put the request to storage
if (ContractManagement.GetContract(engine.Snapshot, engine.CallingScriptHash) is null)
throw new InvalidOperationException();
engine.Snapshot.Add(CreateStorageKey(Prefix_Request).Add(item_id.Value), new StorageItem(new OracleRequest
engine.Snapshot.Add(CreateStorageKey(Prefix_Request).AddBigEndian(id), new StorageItem(new OracleRequest
{
OriginalTxid = GetOriginalTxid(engine),
GasForResponse = gasForResponse,
Expand Down
54 changes: 23 additions & 31 deletions src/neo/SmartContract/Native/PolicyContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,52 +27,50 @@ internal PolicyContract()
{
}

internal override void Initialize(ApplicationEngine engine)
{
engine.Snapshot.Add(CreateStorageKey(Prefix_MaxTransactionsPerBlock), new StorageItem(512));
engine.Snapshot.Add(CreateStorageKey(Prefix_FeePerByte), new StorageItem(1000));
engine.Snapshot.Add(CreateStorageKey(Prefix_MaxBlockSize), new StorageItem(1024 * 256));
engine.Snapshot.Add(CreateStorageKey(Prefix_MaxBlockSystemFee), new StorageItem(9000 * GAS.Factor)); // For the transfer method of NEP5, the maximum persisting time is about three seconds.
engine.Snapshot.Add(CreateStorageKey(Prefix_ExecFeeFactor), new StorageItem(DefaultExecFeeFactor));
engine.Snapshot.Add(CreateStorageKey(Prefix_StoragePrice), new StorageItem(DefaultStoragePrice));
}

[ContractMethod(0_01000000, CallFlags.ReadStates)]
public uint GetMaxTransactionsPerBlock(DataCache snapshot)
{
StorageItem item = snapshot.TryGet(CreateStorageKey(Prefix_MaxTransactionsPerBlock));
if (item is null) return 512;
return (uint)(BigInteger)item;
return (uint)(BigInteger)snapshot[CreateStorageKey(Prefix_MaxTransactionsPerBlock)];
}

[ContractMethod(0_01000000, CallFlags.ReadStates)]
public uint GetMaxBlockSize(DataCache snapshot)
{
StorageItem item = snapshot.TryGet(CreateStorageKey(Prefix_MaxBlockSize));
if (item is null) return 1024 * 256;
return (uint)(BigInteger)item;
return (uint)(BigInteger)snapshot[CreateStorageKey(Prefix_MaxBlockSize)];
}

[ContractMethod(0_01000000, CallFlags.ReadStates)]
public long GetMaxBlockSystemFee(DataCache snapshot)
{
StorageItem item = snapshot.TryGet(CreateStorageKey(Prefix_MaxBlockSystemFee));
if (item is null) return 9000 * (long)GAS.Factor; // For the transfer method of NEP5, the maximum persisting time is about three seconds.
return (long)(BigInteger)item;
return (long)(BigInteger)snapshot[CreateStorageKey(Prefix_MaxBlockSystemFee)];
}

[ContractMethod(0_01000000, CallFlags.ReadStates)]
public long GetFeePerByte(DataCache snapshot)
{
StorageItem item = snapshot.TryGet(CreateStorageKey(Prefix_FeePerByte));
if (item is null) return 1000;
return (long)(BigInteger)item;
return (long)(BigInteger)snapshot[CreateStorageKey(Prefix_FeePerByte)];
}

[ContractMethod(0_01000000, CallFlags.ReadStates)]
public uint GetExecFeeFactor(DataCache snapshot)
{
StorageItem item = snapshot.TryGet(CreateStorageKey(Prefix_ExecFeeFactor));
if (item is null) return DefaultExecFeeFactor;
return (uint)(BigInteger)item;
return (uint)(BigInteger)snapshot[CreateStorageKey(Prefix_ExecFeeFactor)];
}

[ContractMethod(0_01000000, CallFlags.ReadStates)]
public uint GetStoragePrice(DataCache snapshot)
{
StorageItem item = snapshot.TryGet(CreateStorageKey(Prefix_StoragePrice));
if (item is null) return DefaultStoragePrice;
return (uint)(BigInteger)item;
return (uint)(BigInteger)snapshot[CreateStorageKey(Prefix_StoragePrice)];
}

[ContractMethod(0_01000000, CallFlags.ReadStates)]
Expand All @@ -86,53 +84,47 @@ private void SetMaxBlockSize(ApplicationEngine engine, uint value)
{
if (value > Message.PayloadMaxSize) throw new ArgumentOutOfRangeException(nameof(value));
if (!CheckCommittee(engine)) throw new InvalidOperationException();
StorageItem storage = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_MaxBlockSize), () => new StorageItem());
storage.Set(value);
engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_MaxBlockSize)).Set(value);
}

[ContractMethod(0_03000000, CallFlags.WriteStates)]
private void SetMaxTransactionsPerBlock(ApplicationEngine engine, uint value)
{
if (value > Block.MaxTransactionsPerBlock) throw new ArgumentOutOfRangeException(nameof(value));
if (!CheckCommittee(engine)) throw new InvalidOperationException();
StorageItem storage = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_MaxTransactionsPerBlock), () => new StorageItem());
storage.Set(value);
engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_MaxTransactionsPerBlock)).Set(value);
}

[ContractMethod(0_03000000, CallFlags.WriteStates)]
private void SetMaxBlockSystemFee(ApplicationEngine engine, long value)
{
if (value <= 4007600) throw new ArgumentOutOfRangeException(nameof(value));
if (!CheckCommittee(engine)) throw new InvalidOperationException();
StorageItem storage = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_MaxBlockSystemFee), () => new StorageItem());
storage.Set(value);
engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_MaxBlockSystemFee)).Set(value);
}

[ContractMethod(0_03000000, CallFlags.WriteStates)]
private void SetFeePerByte(ApplicationEngine engine, long value)
{
if (value < 0 || value > 1_00000000) throw new ArgumentOutOfRangeException(nameof(value));
if (!CheckCommittee(engine)) throw new InvalidOperationException();
StorageItem storage = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_FeePerByte), () => new StorageItem());
storage.Set(value);
engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_FeePerByte)).Set(value);
}

[ContractMethod(0_03000000, CallFlags.WriteStates)]
private void SetExecFeeFactor(ApplicationEngine engine, uint value)
{
if (value == 0 || value > MaxExecFeeFactor) throw new ArgumentOutOfRangeException(nameof(value));
if (!CheckCommittee(engine)) throw new InvalidOperationException();
StorageItem storage = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_ExecFeeFactor), () => new StorageItem());
storage.Set(value);
engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_ExecFeeFactor)).Set(value);
}

[ContractMethod(0_03000000, CallFlags.WriteStates)]
private void SetStoragePrice(ApplicationEngine engine, uint value)
{
if (value == 0 || value > MaxStoragePrice) throw new ArgumentOutOfRangeException(nameof(value));
if (!CheckCommittee(engine)) throw new InvalidOperationException();
StorageItem storage = engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_StoragePrice), () => new StorageItem());
storage.Set(value);
engine.Snapshot.GetAndChange(CreateStorageKey(Prefix_StoragePrice)).Set(value);
}

[ContractMethod(0_03000000, CallFlags.WriteStates)]
Expand All @@ -143,7 +135,7 @@ private bool BlockAccount(ApplicationEngine engine, UInt160 account)
var key = CreateStorageKey(Prefix_BlockedAccount).Add(account);
if (engine.Snapshot.Contains(key)) return false;

engine.Snapshot.Add(key, new StorageItem(new byte[] { 0x01 }));
engine.Snapshot.Add(key, new StorageItem(Array.Empty<byte>()));
return true;
}

Expand Down
7 changes: 2 additions & 5 deletions tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.UnitTests.Extensions;
using Neo.UnitTests.IO.Caching;
using System;
using System.Linq;

Expand Down Expand Up @@ -207,12 +206,11 @@ public void Check_SetFeePerByte()
[TestMethod]
public void Check_SetBaseExecFee()
{
var snapshot = Blockchain.Singleton.GetSnapshot();
var snapshot = _snapshot.CreateSnapshot();

// Fake blockchain

Block block = new Block() { Index = 1000, PrevHash = UInt256.Zero };
NativeContract.Policy.Initialize(ApplicationEngine.Create(TriggerType.Application, null, snapshot, block, 0));

// Without signature

Expand Down Expand Up @@ -251,12 +249,11 @@ public void Check_SetBaseExecFee()
[TestMethod]
public void Check_SetStoragePrice()
{
var snapshot = Blockchain.Singleton.GetSnapshot();
var snapshot = _snapshot.CreateSnapshot();

// Fake blockchain

Block block = new Block() { Index = 1000, PrevHash = UInt256.Zero };
NativeContract.Policy.Initialize(ApplicationEngine.Create(TriggerType.Application, null, snapshot, block, 0));

// Without signature

Expand Down