From 8985184efc6b6598dc61a8e1e73480c2a6381bf8 Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 30 Jan 2020 18:31:51 +0100 Subject: [PATCH 1/4] Allow to get the current tx --- .../InteropService.Blockchain.cs | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/neo/SmartContract/InteropService.Blockchain.cs b/src/neo/SmartContract/InteropService.Blockchain.cs index b31aba4a32..60e6e1906d 100644 --- a/src/neo/SmartContract/InteropService.Blockchain.cs +++ b/src/neo/SmartContract/InteropService.Blockchain.cs @@ -45,8 +45,25 @@ private static bool Blockchain_GetBlock(ApplicationEngine engine) private static bool Blockchain_GetTransaction(ApplicationEngine engine) { - ReadOnlySpan hash = engine.CurrentContext.EvaluationStack.Pop().GetSpan(); - Transaction tx = engine.Snapshot.GetTransaction(new UInt256(hash)); + Transaction tx; + StackItem item = engine.CurrentContext.EvaluationStack.Pop(); + + if (item.IsNull) + { + if (engine.ScriptContainer is Transaction senderTx) + { + tx = senderTx; + } + else + { + return false; + } + } + else + { + tx = engine.Snapshot.GetTransaction(new UInt256(item.GetSpan())); + } + if (tx == null) engine.CurrentContext.EvaluationStack.Push(StackItem.Null); else From 36b3221d733322cf0c8e863f8a26bbd566711863 Mon Sep 17 00:00:00 2001 From: Shargon Date: Sun, 2 Feb 2020 10:33:14 +0100 Subject: [PATCH 2/4] Change to a new syscall --- .../InteropService.Blockchain.cs | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/neo/SmartContract/InteropService.Blockchain.cs b/src/neo/SmartContract/InteropService.Blockchain.cs index 60e6e1906d..c97f42be60 100644 --- a/src/neo/SmartContract/InteropService.Blockchain.cs +++ b/src/neo/SmartContract/InteropService.Blockchain.cs @@ -14,6 +14,7 @@ public static class Blockchain public static readonly InteropDescriptor GetHeight = Register("System.Blockchain.GetHeight", Blockchain_GetHeight, 0_00000400, TriggerType.Application, CallFlags.None); public static readonly InteropDescriptor GetBlock = Register("System.Blockchain.GetBlock", Blockchain_GetBlock, 0_02500000, TriggerType.Application, CallFlags.None); public static readonly InteropDescriptor GetTransaction = Register("System.Blockchain.GetTransaction", Blockchain_GetTransaction, 0_01000000, TriggerType.Application, CallFlags.None); + public static readonly InteropDescriptor GetCurrentTransaction = Register("System.Blockchain.GetCurrentTransaction", Blockchain_GetCurrentTransaction, 0_01000000, TriggerType.Application, CallFlags.None); public static readonly InteropDescriptor GetTransactionHeight = Register("System.Blockchain.GetTransactionHeight", Blockchain_GetTransactionHeight, 0_01000000, TriggerType.Application, CallFlags.None); public static readonly InteropDescriptor GetTransactionFromBlock = Register("System.Blockchain.GetTransactionFromBlock", Blockchain_GetTransactionFromBlock, 0_01000000, TriggerType.Application, CallFlags.None); public static readonly InteropDescriptor GetContract = Register("System.Blockchain.GetContract", Blockchain_GetContract, 0_01000000, TriggerType.Application, CallFlags.None); @@ -43,27 +44,21 @@ private static bool Blockchain_GetBlock(ApplicationEngine engine) return true; } - private static bool Blockchain_GetTransaction(ApplicationEngine engine) + private static bool Blockchain_GetCurrentTransaction(ApplicationEngine engine) { - Transaction tx; - StackItem item = engine.CurrentContext.EvaluationStack.Pop(); + Transaction tx = !(engine.ScriptContainer is Transaction) ? null : (Transaction)engine.ScriptContainer; - if (item.IsNull) - { - if (engine.ScriptContainer is Transaction senderTx) - { - tx = senderTx; - } - else - { - return false; - } - } + if (tx == null) + engine.CurrentContext.EvaluationStack.Push(StackItem.Null); else - { - tx = engine.Snapshot.GetTransaction(new UInt256(item.GetSpan())); - } + engine.CurrentContext.EvaluationStack.Push(tx.ToStackItem(engine.ReferenceCounter)); + return true; + } + private static bool Blockchain_GetTransaction(ApplicationEngine engine) + { + ReadOnlySpan hash = engine.CurrentContext.EvaluationStack.Pop().GetSpan(); + Transaction tx = engine.Snapshot.GetTransaction(new UInt256(hash)); if (tx == null) engine.CurrentContext.EvaluationStack.Push(StackItem.Null); else From fe3848d5c300bd6f65829383a529b999d09eb96d Mon Sep 17 00:00:00 2001 From: Shargon Date: Sun, 2 Feb 2020 10:34:10 +0100 Subject: [PATCH 3/4] Clean code --- src/neo/SmartContract/InteropService.Blockchain.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/neo/SmartContract/InteropService.Blockchain.cs b/src/neo/SmartContract/InteropService.Blockchain.cs index c97f42be60..345499125d 100644 --- a/src/neo/SmartContract/InteropService.Blockchain.cs +++ b/src/neo/SmartContract/InteropService.Blockchain.cs @@ -46,12 +46,10 @@ private static bool Blockchain_GetBlock(ApplicationEngine engine) private static bool Blockchain_GetCurrentTransaction(ApplicationEngine engine) { - Transaction tx = !(engine.ScriptContainer is Transaction) ? null : (Transaction)engine.ScriptContainer; - - if (tx == null) - engine.CurrentContext.EvaluationStack.Push(StackItem.Null); - else + if (engine.ScriptContainer is Transaction tx) engine.CurrentContext.EvaluationStack.Push(tx.ToStackItem(engine.ReferenceCounter)); + else + engine.CurrentContext.EvaluationStack.Push(StackItem.Null); return true; } From 610619e9f7a87f0353d1841daf4a5056e1313dae Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 3 Feb 2020 09:35:26 +0100 Subject: [PATCH 4/4] Add UT --- .../SmartContract/UT_Syscalls.cs | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs index 04f60db7ff..6fb6fb80e5 100644 --- a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs +++ b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs @@ -92,6 +92,53 @@ public void System_Blockchain_GetBlock() } } + [TestMethod] + public void System_Blockchain_GetCurrentTransaction() + { + var tx = new Transaction() + { + Script = new byte[] { 0x01 }, + Attributes = new TransactionAttribute[0], + Cosigners = new Cosigner[0], + NetworkFee = 0x02, + SystemFee = 0x03, + Nonce = 0x04, + ValidUntilBlock = 0x05, + Version = 0x06, + Witnesses = new Witness[] { new Witness() { VerificationScript = new byte[] { 0x07 } } }, + Sender = UInt160.Parse("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + }; + + var snapshot = Blockchain.Singleton.GetSnapshot(); + + using (var script = new ScriptBuilder()) + { + script.EmitSysCall(InteropService.Blockchain.GetCurrentTransaction); + + // Without tx + + var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true); + engine.LoadScript(script.ToArray()); + + Assert.AreEqual(engine.Execute(), VMState.HALT); + Assert.AreEqual(1, engine.ResultStack.Count); + Assert.IsTrue(engine.ResultStack.Peek().IsNull); + + // With tx + + script.EmitSysCall(InteropService.Json.Serialize); + engine = new ApplicationEngine(TriggerType.Application, tx, snapshot, 0, true); + engine.LoadScript(script.ToArray()); + + Assert.AreEqual(engine.Execute(), VMState.HALT); + Assert.AreEqual(1, engine.ResultStack.Count); + Assert.IsInstanceOfType(engine.ResultStack.Peek(), typeof(ByteArray)); + Assert.AreEqual(engine.ResultStack.Pop().GetSpan().ToHexString(), + "5b225c75303032426b53415959527a4c4b69685a676464414b50596f754655737a63544d7867445a6572584a3172784c37303d222c362c342c222f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f383d222c332c322c352c2241513d3d225d"); + Assert.AreEqual(0, engine.ResultStack.Count); + } + } + [TestMethod] public void Json_Deserialize() {