Skip to content

Commit

Permalink
[neox] Merge master (#1789)
Browse files Browse the repository at this point in the history
* Allow call from native contract (#1700)

* Fix MethodCallback (#1723)

* Fix #1714 (#1715)

* Add base64 SYSCALLs (#1717)

* Neo.VM.3.0.0-CI00230 (#1725)

* Allow to iterate buffer (#1726)

* Buffer iterator

* Rename

* Remove using

Co-authored-by: Erik Zhang <[email protected]>

* Update StorageContext.cs (#1728)

StorageContext needs to be public so it can be accessed by Neo Debugger

Co-authored-by: Erik Zhang <[email protected]>

* Fix return value check (#1730)

Co-authored-by: Shargon <[email protected]>

* Fix ContractEventDescriptor (#1733)

* fix enumerator (#1744)

Co-authored-by: Tommo-L <[email protected]>

* Change json fields to all lower case for consistency (#1736)

* Replace DataCache.Find by DataCache.Seek (#1740)

* replace DataCache.Find by DataCache.Seek

* fix order

* optimize

* Update ByteArrayComparer.cs

* Update ByteArrayComparer.cs

* Update DataCache.cs

* fix comments

* fix comments

* fix comments

* Update DataCache.cs

* Update DataCache.cs

* Reorder methods

Co-authored-by: Tommo-L <[email protected]>
Co-authored-by: erikzhang <[email protected]>
Co-authored-by: Shargon <[email protected]>

* Add MaxVerificationGas (#1745)

Co-authored-by: Shargon <[email protected]>

* Create KeyBuilder (#1748)

* Speed up the initialization of ApplicationEngine. (#1749)

* Change nef checksum to double SHA256 (#1751)

* Change to double SHA256

* Clean code

* Revert change

* Clean code

* Fix checksum

* Update NefFile.cs

* Fix compile

* Clean code

Clean code
Fix checksum
Update NefFile.cs
Fix compile

* Optimize

* Optimize

* Fix

Co-authored-by: erikzhang <[email protected]>

* Check witnesses on isStandard (#1754)

* Check witness on isStandard

* Add IsDeployed

* Add IsPayable

* Fix UT

* format

* Add coverage

* Remove IsPayable, IsDeployed

* Move NEP10 to manifest (#1729)

* NEP10 abi

* To lower case

* Move to Manifest

* Clean code

* Update ContractManifest.cs

* Update ContractManifest.cs

* Fix native contracts

Co-authored-by: Erik Zhang <[email protected]>

* Capture fault Exception (#1761)

* Capture faultException

* Update Wallet error

* Remove flag check

* Clean code

* Sender from signers (#1752)

* Sender from signers

* Remove co-

* Move signers outside attributes

* Fix UT and remove Signers class

* Fix UT

* Add FeeOnly scope

* Remove orderBy

* Remove _signersCache

* Fix Signers

* Fix WitnessScope

* Fix Sender

* Update TransactionAttributeType.cs

* Update Wallet.cs

* Fix Wallet

* Rename

* Update Wallet.cs

* Update Wallet.cs

* Partial UT fix

* More UT fixes

* Fix Sender's WitnessScope

* Fix Wallet

* Fix UT

* Explicit FeeOnly for DeployNativeContracts

* Same order as serialization

* Test FeeOnly

* dotnet format

* format

Co-authored-by: Erik Zhang <[email protected]>

* IApplicationEngineProvider (#1758)

* Remove the lock from SendersFeeMonitor and rename it to TransactionVerificationContext (#1756)

* Add EffectiveVoterTurnout (#1762)

* Remove AllowedTriggers from SYSCALLs (#1755)

* fix validatorscount (#1770)

Co-authored-by: Tommo-L <[email protected]>

* workflows: use checkout action v2 (#1775)

* Update git workflow

* Update .github/workflows/main.yml

Co-authored-by: Erik Zhang <[email protected]>

Co-authored-by: Erik Zhang <[email protected]>

* Add cache to native contract executions V2 (#1766)

* cache v2

* More optimizations

* Policy contract optimization

* Remove interporable variable

* Two more

* Add Set

* Optimizations

* Optimize

Co-authored-by: erikzhang <[email protected]>

* Optimize attributes (#1774)

* Add length before compression data (#1768)

* Add length before compression

* Optimize

* Fix UT

* Add UT

* Add UT

Co-authored-by: erikzhang <[email protected]>

* Fix VerifyWitnesses (#1776)

* Ensure non predictable peers (#1739)

* Plugins from List to array

* Move false to init

* Fix UT

* Refactor

* Add Exception Message For CreateContract (#1787)

* Add Exception Message When Create Contract

* Add Exception Message

* Code optimization

* add UT

Co-authored-by: Shargon <[email protected]>
Co-authored-by: Qiao Jin <[email protected]>

Co-authored-by: Erik Zhang <[email protected]>
Co-authored-by: Shargon <[email protected]>
Co-authored-by: Harry Pierson <[email protected]>
Co-authored-by: Luchuan <[email protected]>
Co-authored-by: Tommo-L <[email protected]>
Co-authored-by: joeqian <[email protected]>
Co-authored-by: cloud8little <[email protected]>
Co-authored-by: Qiao Jin <[email protected]>
  • Loading branch information
9 people authored Jul 23, 2020
1 parent 3a0a732 commit 857bfec
Show file tree
Hide file tree
Showing 12 changed files with 164 additions and 78 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
Expand All @@ -39,7 +39,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
Expand All @@ -61,7 +61,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
Expand All @@ -79,7 +79,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v2
- name: Get version
id: get_version
run: |
Expand Down
14 changes: 7 additions & 7 deletions src/neo/IO/Helper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using K4os.Compression.LZ4;
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -69,20 +70,19 @@ public static byte[] CompressLz4(this byte[] data)
int maxLength = LZ4Codec.MaximumOutputSize(data.Length);
using var buffer = MemoryPool<byte>.Shared.Rent(maxLength);
int length = LZ4Codec.Encode(data, buffer.Memory.Span);
byte[] result = new byte[length];
buffer.Memory[..length].CopyTo(result);
byte[] result = new byte[sizeof(uint) + length];
BinaryPrimitives.WriteInt32LittleEndian(result, data.Length);
buffer.Memory[..length].CopyTo(result.AsMemory(4));
return result;
}

public static byte[] DecompressLz4(this byte[] data, int maxOutput)
{
var maxDecompressDataLength = data.Length * 255;
if (maxDecompressDataLength > 0) maxOutput = Math.Min(maxOutput, maxDecompressDataLength);
using var buffer = MemoryPool<byte>.Shared.Rent(maxOutput);
int length = LZ4Codec.Decode(data, buffer.Memory.Span);
int length = BinaryPrimitives.ReadInt32LittleEndian(data);
if (length < 0 || length > maxOutput) throw new FormatException();
byte[] result = new byte[length];
buffer.Memory[..length].CopyTo(result);
if (LZ4Codec.Decode(data.AsSpan(4), result) != length)
throw new FormatException();
return result;
}

Expand Down
61 changes: 49 additions & 12 deletions src/neo/Ledger/StorageItem.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
using Neo.IO;
using Neo.SmartContract;
using System;
using System.Collections.Generic;
using System.IO;
using System.Numerics;

namespace Neo.Ledger
{
public class StorageItem : ICloneable<StorageItem>, ISerializable
{
private byte[] value;
private IInteroperable interoperable;
private object cache;
public bool IsConstant;

public int Size => Value.GetVarSize() + sizeof(bool);
Expand All @@ -16,33 +19,47 @@ public byte[] Value
{
get
{
if (value is null && interoperable != null)
value = BinarySerializer.Serialize(interoperable.ToStackItem(null), 4096);
return value;
return value ??= cache switch
{
BigInteger bi => bi.ToByteArrayStandard(),
IInteroperable interoperable => BinarySerializer.Serialize(interoperable.ToStackItem(null), 4096),
IReadOnlyCollection<ISerializable> list => list.ToByteArray(),
null => null,
_ => throw new InvalidCastException()
};
}
set
{
interoperable = null;
this.value = value;
cache = null;
}
}

public StorageItem()
{
}
public StorageItem() { }

public StorageItem(byte[] value, bool isConstant = false)
{
this.value = value;
this.IsConstant = isConstant;
}

public StorageItem(BigInteger value, bool isConstant = false)
{
this.cache = value;
this.IsConstant = isConstant;
}

public StorageItem(IInteroperable interoperable, bool isConstant = false)
{
this.interoperable = interoperable;
this.cache = interoperable;
this.IsConstant = isConstant;
}

public void Add(BigInteger integer)
{
Set(this + integer);
}

StorageItem ICloneable<StorageItem>.Clone()
{
return new StorageItem
Expand All @@ -66,19 +83,39 @@ void ICloneable<StorageItem>.FromReplica(StorageItem replica)

public T GetInteroperable<T>() where T : IInteroperable, new()
{
if (interoperable is null)
if (cache is null)
{
interoperable = new T();
var interoperable = new T();
interoperable.FromStackItem(BinarySerializer.Deserialize(value, 16, 34));
cache = interoperable;
}
value = null;
return (T)interoperable;
return (T)cache;
}

public List<T> GetSerializableList<T>() where T : ISerializable, new()
{
cache ??= new List<T>(value.AsSerializableArray<T>());
value = null;
return (List<T>)cache;
}

public void Serialize(BinaryWriter writer)
{
writer.WriteVarBytes(Value);
writer.Write(IsConstant);
}

public void Set(BigInteger integer)
{
cache = integer;
value = null;
}

public static implicit operator BigInteger(StorageItem item)
{
item.cache ??= new BigInteger(item.value);
return (BigInteger)item.cache;
}
}
}
15 changes: 14 additions & 1 deletion src/neo/Network/P2P/Payloads/Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ public class Transaction : IEquatable<Transaction>, IInventory, IInteroperable
sizeof(long) + //NetworkFee
sizeof(uint); //ValidUntilBlock

private Dictionary<Type, TransactionAttribute[]> _attributesCache;
public TransactionAttribute[] Attributes
{
get => attributes;
set { attributes = value; _hash = null; _size = 0; }
set { attributes = value; _attributesCache = null; _hash = null; _size = 0; }
}

/// <summary>
Expand Down Expand Up @@ -219,6 +220,18 @@ void IInteroperable.FromStackItem(StackItem stackItem)
throw new NotSupportedException();
}

public T GetAttribute<T>() where T : TransactionAttribute
{
return GetAttributes<T>()?.First();
}

public T[] GetAttributes<T>() where T : TransactionAttribute
{
_attributesCache ??= attributes.GroupBy(p => p.GetType()).ToDictionary(p => p.Key, p => (TransactionAttribute[])p.OfType<T>().ToArray());
_attributesCache.TryGetValue(typeof(T), out var result);
return (T[])result;
}

public override int GetHashCode()
{
return Hash.GetHashCode();
Expand Down
4 changes: 3 additions & 1 deletion src/neo/Network/P2P/Peer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,9 @@ private void OnTimer()
// If there aren't available UnconnectedPeers, it triggers an abstract implementation of NeedMorePeers
if (UnconnectedPeers.Count == 0)
NeedMorePeers(MinDesiredConnections - ConnectedPeers.Count);
IPEndPoint[] endpoints = UnconnectedPeers.Take(MinDesiredConnections - ConnectedPeers.Count).ToArray();

Random rand = new Random();
IPEndPoint[] endpoints = UnconnectedPeers.OrderBy(u => rand.Next()).Take(MinDesiredConnections - ConnectedPeers.Count).ToArray();
ImmutableInterlocked.Update(ref UnconnectedPeers, p => p.Except(endpoints));
foreach (IPEndPoint endpoint in endpoints)
{
Expand Down
32 changes: 17 additions & 15 deletions src/neo/SmartContract/ApplicationEngine.Contract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,24 @@ partial class ApplicationEngine

internal ContractState CreateContract(byte[] script, byte[] manifest)
{
if (script.Length == 0 || script.Length > MaxContractLength || manifest.Length == 0 || manifest.Length > ContractManifest.MaxLength)
throw new ArgumentException();
if (script.Length == 0 || script.Length > MaxContractLength)
throw new ArgumentException($"Invalid Script Length: {script.Length}");
if (manifest.Length == 0 || manifest.Length > ContractManifest.MaxLength)
throw new ArgumentException($"Invalid Manifest Length: {manifest.Length}");

AddGas(StoragePrice * (script.Length + manifest.Length));

UInt160 hash = script.ToScriptHash();
ContractState contract = Snapshot.Contracts.TryGet(hash);
if (contract != null) throw new InvalidOperationException();
if (contract != null) throw new InvalidOperationException($"Contract Already Exists: {hash}");
contract = new ContractState
{
Id = Snapshot.ContractId.GetAndChange().NextId++,
Script = script.ToArray(),
Manifest = ContractManifest.Parse(manifest)
};

if (!contract.Manifest.IsValid(hash)) throw new InvalidOperationException();
if (!contract.Manifest.IsValid(hash)) throw new InvalidOperationException($"Invalid Manifest Hash: {hash}");

Snapshot.Contracts.Add(hash, contract);
return contract;
Expand All @@ -56,15 +58,15 @@ internal void UpdateContract(byte[] script, byte[] manifest)
AddGas(StoragePrice * (script?.Length ?? 0 + manifest?.Length ?? 0));

var contract = Snapshot.Contracts.TryGet(CurrentScriptHash);
if (contract is null) throw new InvalidOperationException();
if (contract is null) throw new InvalidOperationException($"Updating Contract Does Not Exist: {CurrentScriptHash}");

if (script != null)
{
if (script.Length == 0 || script.Length > MaxContractLength)
throw new ArgumentException();
throw new ArgumentException($"Invalid Script Length: {script.Length}");
UInt160 hash_new = script.ToScriptHash();
if (hash_new.Equals(CurrentScriptHash) || Snapshot.Contracts.TryGet(hash_new) != null)
throw new InvalidOperationException();
throw new InvalidOperationException($"Adding Contract Hash Already Exist: {hash_new}");
contract = new ContractState
{
Id = contract.Id,
Expand All @@ -78,13 +80,13 @@ internal void UpdateContract(byte[] script, byte[] manifest)
if (manifest != null)
{
if (manifest.Length == 0 || manifest.Length > ContractManifest.MaxLength)
throw new ArgumentException();
throw new ArgumentException($"Invalid Manifest Length: {manifest.Length}");
contract = Snapshot.Contracts.GetAndChange(contract.ScriptHash);
contract.Manifest = ContractManifest.Parse(manifest);
if (!contract.Manifest.IsValid(contract.ScriptHash))
throw new InvalidOperationException();
throw new InvalidOperationException($"Invalid Manifest Hash: {contract.ScriptHash}");
if (!contract.HasStorage && Snapshot.Storages.Find(BitConverter.GetBytes(contract.Id)).Any())
throw new InvalidOperationException();
throw new InvalidOperationException($"Contract Does Not Support Storage But Uses Storage");
}
}

Expand Down Expand Up @@ -113,15 +115,15 @@ internal void CallContractEx(UInt160 contractHash, string method, Array args, Ca

private void CallContractInternal(UInt160 contractHash, string method, Array args, CallFlags flags)
{
if (method.StartsWith('_')) throw new ArgumentException();
if (method.StartsWith('_')) throw new ArgumentException($"Invalid Method Name: {method}");

ContractState contract = Snapshot.Contracts.TryGet(contractHash);
if (contract is null) throw new InvalidOperationException();
if (contract is null) throw new InvalidOperationException($"Called Contract Does Not Exist: {contractHash}");

ContractManifest currentManifest = Snapshot.Contracts.TryGet(CurrentScriptHash)?.Manifest;

if (currentManifest != null && !currentManifest.CanCall(contract.Manifest, method))
throw new InvalidOperationException();
throw new InvalidOperationException($"Cannot Call Method {method} Of Contract {contractHash} From Contract {CurrentScriptHash}");

if (invocationCounter.TryGetValue(contract.ScriptHash, out var counter))
{
Expand All @@ -139,8 +141,8 @@ private void CallContractInternal(UInt160 contractHash, string method, Array arg
CallFlags callingFlags = state.CallFlags;

ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(method);
if (md is null) throw new InvalidOperationException();
if (args.Count != md.Parameters.Length) throw new InvalidOperationException();
if (md is null) throw new InvalidOperationException($"Method {method} Does Not Exist In Contract {contractHash}");
if (args.Count != md.Parameters.Length) throw new InvalidOperationException($"Method {method} Expects {md.Parameters.Length} Arguments But Receives {args.Count} Arguments");
ExecutionContext context_new = LoadScript(contract.Script);
state = context_new.GetState<ExecutionContextState>();
state.CallingScriptHash = callingScriptHash;
Expand Down
2 changes: 1 addition & 1 deletion src/neo/SmartContract/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ internal static bool VerifyWitnesses(this IVerifiable verifiable, StoreView snap
}
using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, verifiable, snapshot.Clone(), gas))
{
engine.LoadScript(verification, CallFlags.ReadOnly).InstructionPointer = offset;
engine.LoadScript(verification, CallFlags.None).InstructionPointer = offset;
engine.LoadScript(verifiable.Witnesses[i].InvocationScript, CallFlags.None);
if (engine.Execute() == VMState.FAULT) return false;
if (engine.ResultStack.Count != 1 || !engine.ResultStack.Pop().GetBoolean()) return false;
Expand Down
Loading

0 comments on commit 857bfec

Please sign in to comment.