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

Contract Guid by counter #1405

Merged
merged 24 commits into from
Jan 17, 2020
Merged
Show file tree
Hide file tree
Changes from 22 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
40 changes: 40 additions & 0 deletions src/neo/Ledger/ContractIdState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Neo.IO;
using System.IO;

namespace Neo.Ledger
{
public class ContractIdState : ICloneable<ContractIdState>, ISerializable
{
public int Id;

int ISerializable.Size => sizeof(int);

ContractIdState ICloneable<ContractIdState>.Clone()
{
return new ContractIdState
{
Id = Id
};
}

void ISerializable.Deserialize(BinaryReader reader)
{
Id = reader.ReadInt32();
}

void ICloneable<ContractIdState>.FromReplica(ContractIdState replica)
{
Id = replica.Id;
}

void ISerializable.Serialize(BinaryWriter writer)
{
writer.Write(Id);
}

internal void Set(int value)
{
Id = value;
}
}
}
13 changes: 7 additions & 6 deletions src/neo/Ledger/ContractState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Neo.Ledger
{
public class ContractState : ICloneable<ContractState>, ISerializable, IInteroperable
{
public Guid Guid;
public int Id;
public byte[] Script;
public ContractManifest Manifest;

Expand All @@ -32,42 +32,43 @@ public UInt160 ScriptHash
}
}

int ISerializable.Size => 16 + Script.GetVarSize() + Manifest.ToJson().ToString().GetVarSize();
int ISerializable.Size => sizeof(uint) + Script.GetVarSize() + Manifest.ToJson().ToString().GetVarSize();

ContractState ICloneable<ContractState>.Clone()
{
return new ContractState
{
Guid = Guid,
Id = Id,
Script = Script,
Manifest = Manifest.Clone()
};
}

void ISerializable.Deserialize(BinaryReader reader)
{
Guid = new Guid(reader.ReadBytes(16));
Id = reader.ReadInt32();
Script = reader.ReadVarBytes();
Manifest = reader.ReadSerializable<ContractManifest>();
}

void ICloneable<ContractState>.FromReplica(ContractState replica)
{
Guid = replica.Guid;
Id = replica.Id;
Script = replica.Script;
Manifest = replica.Manifest.Clone();
}

void ISerializable.Serialize(BinaryWriter writer)
{
writer.Write(Guid.ToByteArray());
writer.Write(Id);
writer.WriteVarBytes(Script);
writer.Write(Manifest);
}

public JObject ToJson()
{
JObject json = new JObject();
json["id"] = Id;
json["hash"] = ScriptHash.ToString();
json["script"] = Convert.ToBase64String(Script);
json["manifest"] = Manifest.ToJson();
Expand Down
16 changes: 8 additions & 8 deletions src/neo/Ledger/StorageKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ namespace Neo.Ledger
{
public class StorageKey : IEquatable<StorageKey>, ISerializable
{
public Guid Guid;
public int Id;
public byte[] Key;

int ISerializable.Size => 16 + (Key.Length / 16 + 1) * 17;
int ISerializable.Size => sizeof(int) + (Key.Length / 16 + 1) * 17;

internal static byte[] CreateSearchPrefix(Guid guid, byte[] prefix)
internal static byte[] CreateSearchPrefix(int id, byte[] prefix)
{
using (MemoryStream ms = new MemoryStream())
{
Expand All @@ -27,13 +27,13 @@ internal static byte[] CreateSearchPrefix(Guid guid, byte[] prefix)
}
if (remain > 0)
ms.Write(prefix, index, remain);
return Helper.Concat(guid.ToByteArray(), ms.ToArray());
return Helper.Concat(BitConverter.GetBytes(id), ms.ToArray());
}
}

void ISerializable.Deserialize(BinaryReader reader)
{
Guid = new Guid(reader.ReadBytes(16));
Id = reader.ReadInt32();
Key = reader.ReadBytesWithGrouping();
}

Expand All @@ -43,7 +43,7 @@ public bool Equals(StorageKey other)
return false;
if (ReferenceEquals(this, other))
return true;
return Guid.Equals(other.Guid) && MemoryExtensions.SequenceEqual<byte>(Key, other.Key);
return Id == other.Id && MemoryExtensions.SequenceEqual<byte>(Key, other.Key);
}

public override bool Equals(object obj)
Expand All @@ -54,12 +54,12 @@ public override bool Equals(object obj)

public override int GetHashCode()
{
return Guid.GetHashCode() + (int)Key.Murmur32(0);
return Id.GetHashCode() + (int)Key.Murmur32(0);
}

void ISerializable.Serialize(BinaryWriter writer)
{
writer.Write(Guid.ToByteArray());
writer.Write(Id);
writer.WriteBytesWithGrouping(Key);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/neo/Persistence/ClonedView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ internal class ClonedView : StoreView
public override DataCache<SerializableWrapper<uint>, HeaderHashList> HeaderHashList { get; }
public override MetaDataCache<HashIndexState> BlockHashIndex { get; }
public override MetaDataCache<HashIndexState> HeaderHashIndex { get; }
public override MetaDataCache<ContractIdState> ContractId { get; }

public ClonedView(StoreView view)
{
Expand All @@ -24,6 +25,7 @@ public ClonedView(StoreView view)
this.HeaderHashList = view.HeaderHashList.CreateSnapshot();
this.BlockHashIndex = view.BlockHashIndex.CreateSnapshot();
this.HeaderHashIndex = view.HeaderHashIndex.CreateSnapshot();
this.ContractId = view.ContractId.CreateSnapshot();
}
}
}
1 change: 1 addition & 0 deletions src/neo/Persistence/Prefixes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ internal static class Prefixes
public const byte IX_HeaderHashList = 0x80;
public const byte IX_CurrentBlock = 0xc0;
public const byte IX_CurrentHeader = 0xc1;
public const byte IX_CurrentContractId = 0xc2;

/* Prefixes 0xf0 to 0xff are reserved for external use.
*
Expand Down
1 change: 1 addition & 0 deletions src/neo/Persistence/ReadOnlyView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class ReadOnlyView : StoreView
public override DataCache<SerializableWrapper<uint>, HeaderHashList> HeaderHashList => new StoreDataCache<SerializableWrapper<uint>, HeaderHashList>(store, Prefixes.IX_HeaderHashList);
public override MetaDataCache<HashIndexState> BlockHashIndex => new StoreMetaDataCache<HashIndexState>(store, Prefixes.IX_CurrentBlock);
public override MetaDataCache<HashIndexState> HeaderHashIndex => new StoreMetaDataCache<HashIndexState>(store, Prefixes.IX_CurrentHeader);
public override MetaDataCache<ContractIdState> ContractId => new StoreMetaDataCache<ContractIdState>(store, Prefixes.IX_CurrentContractId);

public ReadOnlyView(IReadOnlyStore store)
{
Expand Down
2 changes: 2 additions & 0 deletions src/neo/Persistence/SnapshotView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class SnapshotView : StoreView, IDisposable
public override DataCache<SerializableWrapper<uint>, HeaderHashList> HeaderHashList { get; }
public override MetaDataCache<HashIndexState> BlockHashIndex { get; }
public override MetaDataCache<HashIndexState> HeaderHashIndex { get; }
public override MetaDataCache<ContractIdState> ContractId { get; }

public SnapshotView(IStore store)
{
Expand All @@ -30,6 +31,7 @@ public SnapshotView(IStore store)
HeaderHashList = new StoreDataCache<SerializableWrapper<uint>, HeaderHashList>(snapshot, Prefixes.IX_HeaderHashList);
BlockHashIndex = new StoreMetaDataCache<HashIndexState>(snapshot, Prefixes.IX_CurrentBlock);
HeaderHashIndex = new StoreMetaDataCache<HashIndexState>(snapshot, Prefixes.IX_CurrentHeader);
ContractId = new StoreMetaDataCache<ContractIdState>(snapshot, Prefixes.IX_CurrentContractId);
}

public override void Commit()
Expand Down
3 changes: 3 additions & 0 deletions src/neo/Persistence/StoreView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ public abstract class StoreView
public abstract DataCache<SerializableWrapper<uint>, HeaderHashList> HeaderHashList { get; }
public abstract MetaDataCache<HashIndexState> BlockHashIndex { get; }
public abstract MetaDataCache<HashIndexState> HeaderHashIndex { get; }
public abstract MetaDataCache<ContractIdState> ContractId { get; }

public uint Height => BlockHashIndex.Get().Index;
public uint HeaderHeight => HeaderHashIndex.Get().Index;
public UInt256 CurrentBlockHash => BlockHashIndex.Get().Hash;
public UInt256 CurrentHeaderHash => HeaderHashIndex.Get().Hash;
public int CurrentContractId => ContractId.Get().Id;

public StoreView Clone()
{
Expand All @@ -38,6 +40,7 @@ public virtual void Commit()
HeaderHashList.Commit();
BlockHashIndex.Commit();
HeaderHashIndex.Commit();
ContractId.Commit();
}

public bool ContainsBlock(UInt256 hash)
Expand Down
2 changes: 0 additions & 2 deletions src/neo/SmartContract/ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ public partial class ApplicationEngine : ExecutionEngine
public UInt160 EntryScriptHash => EntryContext?.GetState<ExecutionContextState>().ScriptHash;
public IReadOnlyList<NotifyEventArgs> Notifications => notifications;
internal Dictionary<UInt160, int> InvocationCounter { get; } = new Dictionary<UInt160, int>();
internal uint SyscallCounter { get; private set; }

public ApplicationEngine(TriggerType trigger, IVerifiable container, StoreView snapshot, long gas, bool testMode = false)
{
Expand Down Expand Up @@ -81,7 +80,6 @@ protected override bool OnSysCall(uint method)
{
if (!AddGas(InteropService.GetPrice(method, CurrentContext.EvaluationStack)))
return false;
SyscallCounter++;
return InteropService.Invoke(this, method);
}

Expand Down
9 changes: 2 additions & 7 deletions src/neo/SmartContract/InteropService.Contract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ private static long GetDeploymentPrice(EvaluationStack stack)
return Storage.GasPerByte * size;
}

internal static Guid GetDeterministicGuid(Transaction tx, uint nonce)
{
return new Guid(Concat(tx.Hash.ToArray(), BitConverter.GetBytes(nonce)).Sha256().AsSpan(0, 16));
}

private static bool Contract_Create(ApplicationEngine engine)
{
byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray();
Expand All @@ -46,7 +41,7 @@ private static bool Contract_Create(ApplicationEngine engine)
if (contract != null) return false;
contract = new ContractState
{
Guid = GetDeterministicGuid((Transaction)engine.ScriptContainer, engine.SyscallCounter),
Id = ++engine.Snapshot.ContractId.GetAndChange().Id,
doubiliu marked this conversation as resolved.
Show resolved Hide resolved
Script = script,
Manifest = ContractManifest.Parse(manifest)
};
Expand Down Expand Up @@ -75,7 +70,7 @@ private static bool Contract_Update(ApplicationEngine engine)
if (engine.Snapshot.Contracts.TryGet(hash_new) != null) return false;
contract = new ContractState
{
Guid = contract.Guid,
Id = contract.Id,
Script = script,
Manifest = contract.Manifest
};
Expand Down
2 changes: 1 addition & 1 deletion src/neo/SmartContract/InteropService.Native.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ private static bool Native_Deploy(ApplicationEngine engine)
{
engine.Snapshot.Contracts.Add(contract.Hash, new ContractState
{
Guid = contract.Guid,
Id = contract.Id,
Script = contract.Script,
Manifest = contract.Manifest
});
Expand Down
14 changes: 7 additions & 7 deletions src/neo/SmartContract/InteropService.Storage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ private static bool PutExInternal(ApplicationEngine engine, StorageContext conte

StorageKey skey = new StorageKey
{
Guid = context.Guid,
Id = context.Id,
Key = key
};

Expand All @@ -64,7 +64,7 @@ private static bool Storage_GetContext(ApplicationEngine engine)
if (!contract.HasStorage) return false;
engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(new StorageContext
{
Guid = contract.Guid,
Id = contract.Id,
IsReadOnly = false
}));
return true;
Expand All @@ -77,7 +77,7 @@ private static bool Storage_GetReadOnlyContext(ApplicationEngine engine)
if (!contract.HasStorage) return false;
engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(new StorageContext
{
Guid = contract.Guid,
Id = contract.Id,
IsReadOnly = true
}));
return true;
Expand All @@ -91,7 +91,7 @@ private static bool Storage_AsReadOnly(ApplicationEngine engine)
if (!context.IsReadOnly)
context = new StorageContext
{
Guid = context.Guid,
Id = context.Id,
IsReadOnly = true
};
engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(context));
Expand All @@ -108,7 +108,7 @@ private static bool Storage_Get(ApplicationEngine engine)
byte[] key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray();
StorageItem item = engine.Snapshot.Storages.TryGet(new StorageKey
{
Guid = context.Guid,
Id = context.Id,
Key = key
});
engine.CurrentContext.EvaluationStack.Push(item?.Value ?? StackItem.Null);
Expand All @@ -123,7 +123,7 @@ private static bool Storage_Find(ApplicationEngine engine)
{
StorageContext context = _interface.GetInterface<StorageContext>();
byte[] prefix = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray();
byte[] prefix_key = StorageKey.CreateSearchPrefix(context.Guid, prefix);
byte[] prefix_key = StorageKey.CreateSearchPrefix(context.Id, prefix);
StorageIterator iterator = engine.AddDisposable(new StorageIterator(engine.Snapshot.Storages.Find(prefix_key).Where(p => p.Key.Key.AsSpan().StartsWith(prefix)).GetEnumerator()));
engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(iterator));
return true;
Expand Down Expand Up @@ -160,7 +160,7 @@ private static bool Storage_Delete(ApplicationEngine engine)
if (context.IsReadOnly) return false;
StorageKey key = new StorageKey
{
Guid = context.Guid,
Id = context.Id,
Key = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray()
};
if (engine.Snapshot.Storages.TryGet(key)?.IsConstant == true) return false;
Expand Down
5 changes: 2 additions & 3 deletions src/neo/SmartContract/Native/NativeContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public abstract class NativeContract
public uint ServiceHash { get; }
public byte[] Script { get; }
public UInt160 Hash { get; }
public Guid Guid { get; }
public abstract int Id { get; }
public ContractManifest Manifest { get; }
public virtual string[] SupportedStandards { get; } = { "NEP-10" };

Expand All @@ -41,7 +41,6 @@ protected NativeContract()
this.Script = sb.ToArray();
}
this.Hash = Script.ToScriptHash();
this.Guid = InteropService.Contract.GetDeterministicGuid(Blockchain.GenesisBlock.Transactions[0], ServiceHash);
this.Manifest = ContractManifest.CreateDefault(this.Hash);
List<ContractMethodDescriptor> descriptors = new List<ContractMethodDescriptor>();
List<string> safeMethods = new List<string>();
Expand Down Expand Up @@ -73,7 +72,7 @@ protected StorageKey CreateStorageKey(byte prefix, byte[] key = null)
{
StorageKey storageKey = new StorageKey
{
Guid = Guid,
Id = Id,
Key = new byte[sizeof(byte) + (key?.Length ?? 0)]
};
storageKey.Key[0] = prefix;
Expand Down
1 change: 1 addition & 0 deletions src/neo/SmartContract/Native/PolicyContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public sealed class PolicyContract : NativeContract
private const byte Prefix_FeePerByte = 10;
private const byte Prefix_BlockedAccounts = 15;
private const byte Prefix_MaxBlockSize = 16;
public override int Id => -1;

public PolicyContract()
{
Expand Down
2 changes: 2 additions & 0 deletions src/neo/SmartContract/Native/Tokens/GasToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public sealed class GasToken : Nep5Token<Nep5AccountState>
public override string Symbol => "gas";
public override byte Decimals => 8;

public override int Id => -3;

private const byte Prefix_SystemFeeAmount = 15;

internal GasToken()
Expand Down
Loading