Skip to content

Commit

Permalink
Neo.VM.3.0.0-CI00190 (#1357)
Browse files Browse the repository at this point in the history
  • Loading branch information
erikzhang authored Dec 14, 2019
1 parent a7d40b4 commit 91e9898
Show file tree
Hide file tree
Showing 28 changed files with 380 additions and 372 deletions.
6 changes: 3 additions & 3 deletions src/neo/Ledger/Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private class ParallelVerified { public Transaction Transaction; public bool Sho
Witness = new Witness
{
InvocationScript = Array.Empty<byte>(),
VerificationScript = new[] { (byte)OpCode.PUSHT }
VerificationScript = new[] { (byte)OpCode.PUSH1 }
},
ConsensusData = new ConsensusData
{
Expand Down Expand Up @@ -164,7 +164,7 @@ private static Transaction DeployNativeContracts()
{
Version = 0,
Script = script,
Sender = (new[] { (byte)OpCode.PUSHT }).ToScriptHash(),
Sender = (new[] { (byte)OpCode.PUSH1 }).ToScriptHash(),
SystemFee = 0,
Attributes = new TransactionAttribute[0],
Cosigners = new Cosigner[0],
Expand All @@ -173,7 +173,7 @@ private static Transaction DeployNativeContracts()
new Witness
{
InvocationScript = Array.Empty<byte>(),
VerificationScript = new[] { (byte)OpCode.PUSHT }
VerificationScript = new[] { (byte)OpCode.PUSH1 }
}
}
};
Expand Down
4 changes: 2 additions & 2 deletions src/neo/Network/P2P/Payloads/Witness.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ void ISerializable.Deserialize(BinaryReader reader)
{
// This is designed to allow a MultiSig 10/10 (around 1003 bytes) ~1024 bytes
// Invocation = 10 * 64 + 10 = 650 ~ 664 (exact is 653)
InvocationScript = reader.ReadVarBytes(664);
InvocationScript = reader.ReadVarBytes(663);
// Verification = 10 * 33 + 10 = 340 ~ 360 (exact is 351)
VerificationScript = reader.ReadVarBytes(360);
VerificationScript = reader.ReadVarBytes(361);
}

void ISerializable.Serialize(BinaryWriter writer)
Expand Down
134 changes: 43 additions & 91 deletions src/neo/SmartContract/ApplicationEngine.OpCodePrices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,87 +7,19 @@ partial class ApplicationEngine
{
public static readonly IReadOnlyDictionary<OpCode, long> OpCodePrices = new Dictionary<OpCode, long>
{
[OpCode.PUSH0] = 30,
[OpCode.PUSHBYTES1] = 120,
[OpCode.PUSHBYTES2] = 120,
[OpCode.PUSHBYTES3] = 120,
[OpCode.PUSHBYTES4] = 120,
[OpCode.PUSHBYTES5] = 120,
[OpCode.PUSHBYTES6] = 120,
[OpCode.PUSHBYTES7] = 120,
[OpCode.PUSHBYTES8] = 120,
[OpCode.PUSHBYTES9] = 120,
[OpCode.PUSHBYTES10] = 120,
[OpCode.PUSHBYTES11] = 120,
[OpCode.PUSHBYTES12] = 120,
[OpCode.PUSHBYTES13] = 120,
[OpCode.PUSHBYTES14] = 120,
[OpCode.PUSHBYTES15] = 120,
[OpCode.PUSHBYTES16] = 120,
[OpCode.PUSHBYTES17] = 120,
[OpCode.PUSHBYTES18] = 120,
[OpCode.PUSHBYTES19] = 120,
[OpCode.PUSHBYTES20] = 120,
[OpCode.PUSHBYTES21] = 120,
[OpCode.PUSHBYTES22] = 120,
[OpCode.PUSHBYTES23] = 120,
[OpCode.PUSHBYTES24] = 120,
[OpCode.PUSHBYTES25] = 120,
[OpCode.PUSHBYTES26] = 120,
[OpCode.PUSHBYTES27] = 120,
[OpCode.PUSHBYTES28] = 120,
[OpCode.PUSHBYTES29] = 120,
[OpCode.PUSHBYTES30] = 120,
[OpCode.PUSHBYTES31] = 120,
[OpCode.PUSHBYTES32] = 120,
[OpCode.PUSHBYTES33] = 120,
[OpCode.PUSHBYTES34] = 120,
[OpCode.PUSHBYTES35] = 120,
[OpCode.PUSHBYTES36] = 120,
[OpCode.PUSHBYTES37] = 120,
[OpCode.PUSHBYTES38] = 120,
[OpCode.PUSHBYTES39] = 120,
[OpCode.PUSHBYTES40] = 120,
[OpCode.PUSHBYTES41] = 120,
[OpCode.PUSHBYTES42] = 120,
[OpCode.PUSHBYTES43] = 120,
[OpCode.PUSHBYTES44] = 120,
[OpCode.PUSHBYTES45] = 120,
[OpCode.PUSHBYTES46] = 120,
[OpCode.PUSHBYTES47] = 120,
[OpCode.PUSHBYTES48] = 120,
[OpCode.PUSHBYTES49] = 120,
[OpCode.PUSHBYTES50] = 120,
[OpCode.PUSHBYTES51] = 120,
[OpCode.PUSHBYTES52] = 120,
[OpCode.PUSHBYTES53] = 120,
[OpCode.PUSHBYTES54] = 120,
[OpCode.PUSHBYTES55] = 120,
[OpCode.PUSHBYTES56] = 120,
[OpCode.PUSHBYTES57] = 120,
[OpCode.PUSHBYTES58] = 120,
[OpCode.PUSHBYTES59] = 120,
[OpCode.PUSHBYTES60] = 120,
[OpCode.PUSHBYTES61] = 120,
[OpCode.PUSHBYTES62] = 120,
[OpCode.PUSHBYTES63] = 120,
[OpCode.PUSHBYTES64] = 120,
[OpCode.PUSHBYTES65] = 120,
[OpCode.PUSHBYTES66] = 120,
[OpCode.PUSHBYTES67] = 120,
[OpCode.PUSHBYTES68] = 120,
[OpCode.PUSHBYTES69] = 120,
[OpCode.PUSHBYTES70] = 120,
[OpCode.PUSHBYTES71] = 120,
[OpCode.PUSHBYTES72] = 120,
[OpCode.PUSHBYTES73] = 120,
[OpCode.PUSHBYTES74] = 120,
[OpCode.PUSHBYTES75] = 120,
[OpCode.PUSHINT8] = 30,
[OpCode.PUSHINT16] = 30,
[OpCode.PUSHINT32] = 30,
[OpCode.PUSHINT64] = 30,
[OpCode.PUSHINT128] = 120,
[OpCode.PUSHINT256] = 120,
[OpCode.PUSHA] = 120,
[OpCode.PUSHNULL] = 30,
[OpCode.PUSHDATA1] = 180,
[OpCode.PUSHDATA2] = 13000,
[OpCode.PUSHDATA4] = 110000,
[OpCode.PUSHM1] = 30,
[OpCode.PUSHNULL] = 30,
[OpCode.PUSH0] = 30,
[OpCode.PUSH1] = 30,
[OpCode.PUSH2] = 30,
[OpCode.PUSH3] = 30,
Expand All @@ -106,29 +38,51 @@ partial class ApplicationEngine
[OpCode.PUSH16] = 30,
[OpCode.NOP] = 30,
[OpCode.JMP] = 70,
[OpCode.JMP_L] = 70,
[OpCode.JMPIF] = 70,
[OpCode.JMPIF_L] = 70,
[OpCode.JMPIFNOT] = 70,
[OpCode.JMPIFNOT_L] = 70,
[OpCode.JMPEQ] = 70,
[OpCode.JMPEQ_L] = 70,
[OpCode.JMPNE] = 70,
[OpCode.JMPNE_L] = 70,
[OpCode.JMPGT] = 70,
[OpCode.JMPGT_L] = 70,
[OpCode.JMPGE] = 70,
[OpCode.JMPGE_L] = 70,
[OpCode.JMPLT] = 70,
[OpCode.JMPLT_L] = 70,
[OpCode.JMPLE] = 70,
[OpCode.JMPLE_L] = 70,
[OpCode.CALL] = 22000,
[OpCode.CALL_L] = 22000,
[OpCode.CALLA] = 22000,
[OpCode.THROW] = 30,
[OpCode.THROWIF] = 30,
[OpCode.THROWIFNOT] = 30,
[OpCode.RET] = 40,
[OpCode.SYSCALL] = 0,
[OpCode.DUPFROMALTSTACKBOTTOM] = 60,
[OpCode.DUPFROMALTSTACK] = 60,
[OpCode.TOALTSTACK] = 60,
[OpCode.FROMALTSTACK] = 60,
[OpCode.ISNULL] = 60,
[OpCode.XDROP] = 400,
[OpCode.XSWAP] = 60,
[OpCode.XTUCK] = 400,
[OpCode.DEPTH] = 60,
[OpCode.DROP] = 60,
[OpCode.DUP] = 60,
[OpCode.NIP] = 60,
[OpCode.XDROP] = 400,
[OpCode.CLEAR] = 400,
[OpCode.DUP] = 60,
[OpCode.OVER] = 60,
[OpCode.PICK] = 60,
[OpCode.ROLL] = 400,
[OpCode.ROT] = 60,
[OpCode.SWAP] = 60,
[OpCode.TUCK] = 60,
[OpCode.SWAP] = 60,
[OpCode.ROT] = 60,
[OpCode.ROLL] = 400,
[OpCode.REVERSE3] = 60,
[OpCode.REVERSE4] = 60,
[OpCode.REVERSEN] = 400,
[OpCode.TOALTSTACK] = 60,
[OpCode.FROMALTSTACK] = 60,
[OpCode.DUPFROMALTSTACK] = 60,
[OpCode.DUPFROMALTSTACKBOTTOM] = 60,
[OpCode.ISNULL] = 60,
[OpCode.CAT] = 80000,
[OpCode.SUBSTR] = 80000,
[OpCode.LEFT] = 80000,
Expand Down Expand Up @@ -178,8 +132,6 @@ partial class ApplicationEngine
[OpCode.HASKEY] = 270000,
[OpCode.KEYS] = 500,
[OpCode.VALUES] = 7000,
[OpCode.THROW] = 30,
[OpCode.THROWIFNOT] = 30
};
}
}
7 changes: 2 additions & 5 deletions src/neo/SmartContract/ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public partial class ApplicationEngine : ExecutionEngine
public StoreView Snapshot { get; }
public long GasConsumed { get; private set; } = 0;
public UInt160 CurrentScriptHash => CurrentContext?.GetState<ExecutionContextState>().ScriptHash;
public UInt160 CallingScriptHash => InvocationStack.Count > 1 ? InvocationStack.Peek(1).GetState<ExecutionContextState>().ScriptHash : null;
public UInt160 CallingScriptHash => CurrentContext?.GetState<ExecutionContextState>().CallingScriptHash;
public UInt160 EntryScriptHash => EntryContext?.GetState<ExecutionContextState>().ScriptHash;
public IReadOnlyList<NotifyEventArgs> Notifications => notifications;
internal Dictionary<UInt160, int> InvocationCounter { get; } = new Dictionary<UInt160, int>();
Expand Down Expand Up @@ -55,10 +55,7 @@ protected override void LoadContext(ExecutionContext context)
{
// Set default execution context state

context.SetState(new ExecutionContextState()
{
ScriptHash = ((byte[])context.Script).ToScriptHash()
});
context.GetState<ExecutionContextState>().ScriptHash ??= ((byte[])context.Script).ToScriptHash();

base.LoadContext(context);
}
Expand Down
8 changes: 4 additions & 4 deletions src/neo/SmartContract/ContractParametersContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,16 +144,16 @@ public bool AddSignature(Contract contract, ECPoint pubkey, byte[] signature)
int i = 0;
switch (contract.Script[i++])
{
case 1:
case (byte)OpCode.PUSHINT8:
++i;
break;
case 2:
case (byte)OpCode.PUSHINT16:
i += 2;
break;
}
while (contract.Script[i++] == 33)
while (contract.Script[i++] == (byte)OpCode.PUSHDATA1)
{
points.Add(ECPoint.DecodePoint(contract.Script.AsSpan(i, 33), ECCurve.Secp256r1));
points.Add(ECPoint.DecodePoint(contract.Script.AsSpan(++i, 33), ECCurve.Secp256r1));
i += 33;
}
}
Expand Down
7 changes: 6 additions & 1 deletion src/neo/SmartContract/ExecutionContextState.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
namespace Neo.SmartContract
{
public class ExecutionContextState
internal class ExecutionContextState
{
/// <summary>
/// Script hash
/// </summary>
public UInt160 ScriptHash { get; set; }

/// <summary>
/// Calling script hash
/// </summary>
public UInt160 CallingScriptHash { get; set; }
}
}
42 changes: 24 additions & 18 deletions src/neo/SmartContract/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,49 @@ public static bool IsMultiSigContract(this byte[] script, out int m, out int n)
{
m = 0; n = 0;
int i = 0;
if (script.Length < 42) return false;
if (script[i] > (byte)OpCode.PUSH16) return false;
if (script[i] < (byte)OpCode.PUSH1 && script[i] != 1 && script[i] != 2) return false;
if (script.Length < 43) return false;
switch (script[i])
{
case 1:
case (byte)OpCode.PUSHINT8:
m = script[++i];
++i;
break;
case 2:
case (byte)OpCode.PUSHINT16:
m = BinaryPrimitives.ReadUInt16LittleEndian(script.AsSpan(++i));
i += 2;
break;
default:
m = script[i++] - 80;
case byte b when b >= (byte)OpCode.PUSH1 && b <= (byte)OpCode.PUSH16:
m = b - (byte)OpCode.PUSH0;
++i;
break;
default:
return false;
}
if (m < 1 || m > 1024) return false;
while (script[i] == 33)
while (script[i] == (byte)OpCode.PUSHDATA1)
{
if (script.Length <= i + 35) return false;
if (script[++i] != 33) return false;
i += 34;
if (script.Length <= i) return false;
++n;
}
if (n < m || n > 1024) return false;
switch (script[i])
{
case 1:
case (byte)OpCode.PUSHINT8:
if (n != script[++i]) return false;
++i;
break;
case 2:
case (byte)OpCode.PUSHINT16:
if (script.Length < i + 3 || n != BinaryPrimitives.ReadUInt16LittleEndian(script.AsSpan(++i))) return false;
i += 2;
break;
default:
if (n != script[i++] - 80) return false;
case byte b when b >= (byte)OpCode.PUSH1 && b <= (byte)OpCode.PUSH16:
if (n != b - (byte)OpCode.PUSH0) return false;
++i;
break;
default:
return false;
}
if (script[i++] != (byte)OpCode.PUSHNULL) return false;
if (script[i++] != (byte)OpCode.SYSCALL) return false;
Expand All @@ -64,11 +69,12 @@ public static bool IsMultiSigContract(this byte[] script, out int m, out int n)

public static bool IsSignatureContract(this byte[] script)
{
if (script.Length != 40) return false;
if (script[0] != (byte)OpCode.PUSHBYTES33
|| script[34] != (byte)OpCode.PUSHNULL
|| script[35] != (byte)OpCode.SYSCALL
|| BitConverter.ToUInt32(script, 36) != InteropService.Neo_Crypto_ECDsaVerify)
if (script.Length != 41) return false;
if (script[0] != (byte)OpCode.PUSHDATA1
|| script[1] != 33
|| script[35] != (byte)OpCode.PUSHNULL
|| script[36] != (byte)OpCode.SYSCALL
|| BitConverter.ToUInt32(script, 37) != InteropService.Neo_Crypto_ECDsaVerify)
return false;
return true;
}
Expand Down
2 changes: 2 additions & 0 deletions src/neo/SmartContract/InteropService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,9 @@ private static bool Contract_Call(ApplicationEngine engine)
engine.InvocationCounter[contract.ScriptHash] = 1;
}

UInt160 callingScriptHash = engine.CurrentScriptHash;
ExecutionContext context_new = engine.LoadScript(contract.Script, 1);
context_new.GetState<ExecutionContextState>().CallingScriptHash = callingScriptHash;
context_new.EvaluationStack.Push(args);
context_new.EvaluationStack.Push(method);
return true;
Expand Down
2 changes: 1 addition & 1 deletion src/neo/SmartContract/StackItemSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ private static StackItem Deserialize(BinaryReader reader, uint maxItemSize, Refe
deserialized.Push(new Boolean(reader.ReadBoolean()));
break;
case StackItemType.Integer:
deserialized.Push(new Integer(new BigInteger(reader.ReadVarBytes(ExecutionEngine.MaxSizeForBigInteger))));
deserialized.Push(new Integer(new BigInteger(reader.ReadVarBytes(Integer.MaxSize))));
break;
case StackItemType.Array:
case StackItemType.Struct:
Expand Down
5 changes: 4 additions & 1 deletion src/neo/VM/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,10 @@ private static StackItem ToStackItem(ContractParameter parameter, List<(StackIte
(stackItem, _) = context.FirstOrDefault(p => ReferenceEquals(p.Item2, parameter));
if (stackItem is null)
{
stackItem = new Map(((IList<KeyValuePair<ContractParameter, ContractParameter>>)parameter.Value).ToDictionary(p => (PrimitiveType)ToStackItem(p.Key, context), p => ToStackItem(p.Value, context)));
Map map = new Map();
foreach (var pair in (IList<KeyValuePair<ContractParameter, ContractParameter>>)parameter.Value)
map[(PrimitiveType)ToStackItem(pair.Key, context)] = ToStackItem(pair.Value, context);
stackItem = map;
context.Add((stackItem, parameter));
}
break;
Expand Down
Loading

0 comments on commit 91e9898

Please sign in to comment.