Beispiel #1
0
        public async Task BlockPersistAndReverificationWillAbandonTxAsBalanceTransfered()
        {
            var               snapshot = GetSnapshot();
            BigInteger        balance  = NativeContract.GAS.BalanceOf(snapshot, senderAccount);
            ApplicationEngine engine   = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: long.MaxValue);
            await NativeContract.GAS.Burn(engine, UInt160.Zero, balance);

            _ = NativeContract.GAS.Mint(engine, UInt160.Zero, 70, true);

            long txFee = 1;

            AddTransactionsWithBalanceVerify(70, txFee, snapshot);

            _unit.SortedTxCount.Should().Be(70);

            var block = new Block
            {
                Header       = new Header(),
                Transactions = _unit.GetSortedVerifiedTransactions().Take(10).ToArray()
            };

            // Simulate the transfer process in tx by burning the balance
            UInt160 sender = block.Transactions[0].Sender;

            ApplicationEngine applicationEngine = ApplicationEngine.Create(TriggerType.All, block, snapshot, block, settings: TestBlockchain.TheNeoSystem.Settings, gas: (long)balance);
            await NativeContract.GAS.Burn(applicationEngine, sender, NativeContract.GAS.BalanceOf(snapshot, sender));

            _ = NativeContract.GAS.Mint(applicationEngine, sender, txFee * 30, true); // Set the balance to meet 30 txs only

            // Persist block and reverify all the txs in mempool, but half of the txs will be discarded
            _unit.UpdatePoolForBlockPersisted(block, snapshot);
            _unit.SortedTxCount.Should().Be(30);
            _unit.UnverifiedSortedTxCount.Should().Be(0);

            // Revert the balance
            await NativeContract.GAS.Burn(applicationEngine, sender, txFee * 30);

            _ = NativeContract.GAS.Mint(applicationEngine, sender, balance, true);
        }
        public static BigInteger BalanceOf(this NativeContract contract, StoreView snapshot, byte[] account)
        {
            var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);

            engine.LoadScript(contract.Script, CallFlags.All, contract.Hash);

            var script = new ScriptBuilder();

            script.EmitPush(account);
            script.EmitPush(1);
            script.Emit(OpCode.PACK);
            script.EmitPush("balanceOf");
            engine.LoadScript(script.ToArray());

            engine.Execute().Should().Be(VMState.HALT);

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Integer));

            return(result.GetInteger());
        }
Beispiel #3
0
        public async Task TestTransactionSenderFee()
        {
            var snapshot              = TestBlockchain.GetTestSnapshot();
            ApplicationEngine engine  = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings, gas: long.MaxValue);
            BigInteger        balance = NativeContract.GAS.BalanceOf(snapshot, UInt160.Zero);
            await NativeContract.GAS.Burn(engine, UInt160.Zero, balance);

            _ = NativeContract.GAS.Mint(engine, UInt160.Zero, 8, true);

            TransactionVerificationContext verificationContext = new();
            var tx = CreateTransactionWithFee(1, 2);

            verificationContext.CheckTransaction(tx, snapshot).Should().BeTrue();
            verificationContext.AddTransaction(tx);
            verificationContext.CheckTransaction(tx, snapshot).Should().BeTrue();
            verificationContext.AddTransaction(tx);
            verificationContext.CheckTransaction(tx, snapshot).Should().BeFalse();
            verificationContext.RemoveTransaction(tx);
            verificationContext.CheckTransaction(tx, snapshot).Should().BeTrue();
            verificationContext.AddTransaction(tx);
            verificationContext.CheckTransaction(tx, snapshot).Should().BeFalse();
        }
Beispiel #4
0
        public void TestSignatureRedeemScriptFee()
        {
            byte[] privateKey         = new byte[32];
            RandomNumberGenerator rng = RandomNumberGenerator.Create();

            rng.GetBytes(privateKey);
            KeyPair key = new KeyPair(privateKey);

            byte[] verification = Contract.CreateSignatureRedeemScript(key.PublicKey);
            byte[] invocation   = new ScriptBuilder().EmitPush(UInt160.Zero).ToArray();

            var fee = PolicyContract.DefaultExecFeeFactor * (ApplicationEngine.OpCodePrices[OpCode.PUSHDATA1] * 2 + ApplicationEngine.OpCodePrices[OpCode.PUSHNULL] + ApplicationEngine.OpCodePrices[OpCode.SYSCALL] + ApplicationEngine.ECDsaVerifyPrice);

            using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, new Transaction {
                Signers = Array.Empty <Signer>(), Attributes = Array.Empty <TransactionAttribute>()
            }, null))
            {
                engine.LoadScript(invocation.Concat(verification).ToArray(), configureState: p => p.CallFlags = CallFlags.None);
                engine.Execute();
                engine.GasConsumed.Should().Be(fee);
            }
        }
Beispiel #5
0
        public void TestTransactionSenderFee()
        {
            var snapshot              = Blockchain.Singleton.GetSnapshot();
            ApplicationEngine engine  = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, long.MaxValue);
            BigInteger        balance = NativeContract.GAS.BalanceOf(snapshot, UInt160.Zero);

            NativeContract.GAS.Burn(engine, UInt160.Zero, balance);
            NativeContract.GAS.Mint(engine, UInt160.Zero, 8, true);

            TransactionVerificationContext verificationContext = new TransactionVerificationContext();
            var tx = CreateTransactionWithFee(1, 2);

            verificationContext.CheckTransaction(tx, snapshot).Should().BeTrue();
            verificationContext.AddTransaction(tx);
            verificationContext.CheckTransaction(tx, snapshot).Should().BeTrue();
            verificationContext.AddTransaction(tx);
            verificationContext.CheckTransaction(tx, snapshot).Should().BeFalse();
            verificationContext.RemoveTransaction(tx);
            verificationContext.CheckTransaction(tx, snapshot).Should().BeTrue();
            verificationContext.AddTransaction(tx);
            verificationContext.CheckTransaction(tx, snapshot).Should().BeFalse();
        }
Beispiel #6
0
        public void TestContract_Destroy()
        {
            var engine = GetEngine(false, true);

            engine.DestroyContract();

            var snapshot = Blockchain.Singleton.GetSnapshot();
            var state    = TestUtils.GetContract();

            state.Manifest.Features = ContractFeatures.HasStorage;
            var scriptHash  = UInt160.Parse("0xcb9f3b7c6fb1cf2c13a40637c189bdd066a272b4");
            var storageItem = new StorageItem
            {
                Value      = new byte[] { 0x01, 0x02, 0x03, 0x04 },
                IsConstant = false
            };

            var storageKey = new StorageKey
            {
                Id  = 0x43000000,
                Key = new byte[] { 0x01 }
            };

            snapshot.Contracts.Add(scriptHash, state);
            snapshot.Storages.Add(storageKey, storageItem);
            engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);
            engine.LoadScript(new byte[0]);
            engine.DestroyContract();
            engine.Snapshot.Storages.Find(BitConverter.GetBytes(0x43000000)).Any().Should().BeFalse();

            //storages are removed
            snapshot = Blockchain.Singleton.GetSnapshot();
            state    = TestUtils.GetContract();
            snapshot.Contracts.Add(scriptHash, state);
            engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);
            engine.LoadScript(new byte[0]);
            engine.DestroyContract();
            engine.Snapshot.Storages.Find(BitConverter.GetBytes(0x43000000)).Any().Should().BeFalse();
        }
        public static StackItem Call(this NativeContract contract, StoreView snapshot, IVerifiable container, Block persistingBlock, string method, params ContractParameter[] args)
        {
            var engine        = ApplicationEngine.Create(TriggerType.Application, container, snapshot, persistingBlock);
            var contractState = NativeContract.ContractManagement.GetContract(snapshot, contract.Hash);

            if (contractState == null)
            {
                throw new InvalidOperationException();
            }
            var md = contract.Manifest.Abi.GetMethod(method, args.Length);

            var script = new ScriptBuilder();

            for (var i = args.Length - 1; i >= 0; i--)
            {
                script.EmitPush(args[i]);
            }

            script.EmitPush(method);
            engine.LoadContract(contractState, md, CallFlags.All);
            engine.LoadScript(script.ToArray());

            if (engine.Execute() != VMState.HALT)
            {
                Exception exception = engine.FaultException;
                while (exception?.InnerException != null)
                {
                    exception = exception.InnerException;
                }
                throw exception ?? new InvalidOperationException();
            }

            if (0 < engine.ResultStack.Count)
            {
                return(engine.ResultStack.Pop());
            }
            return(null);
        }
Beispiel #8
0
        public void CreateCallbackTest()
        {
            using var script = new ScriptBuilder();

            script.EmitPush(5); // Callback argument
            script.EmitPush(1); // ParamCount
            script.Emit(OpCode.PUSHA, BitConverter.GetBytes(0));
            script.EmitSysCall(ApplicationEngine.System_Callback_Create);

            // Execute

            var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 100_000_000);

            engine.LoadScript(script.ToArray());
            Assert.AreEqual(engine.Execute(), VMState.HALT);

            // Check the results

            Assert.AreEqual(2, engine.ResultStack.Count);
            var callback = engine.ResultStack.Pop <InteropInterface>().GetInterface <PointerCallback>();

            Assert.AreEqual(1, callback.ParametersCount);
        }
Beispiel #9
0
        internal static (bool State, bool Result) Check_SetPrice(DataCache snapshot, byte[] pubkey, long price, Block persistingBlock)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application,
                                                        new Nep17NativeContractExtensions.ManualWitness(Contract.CreateSignatureRedeemScript(ECPoint.DecodePoint(pubkey, ECCurve.Secp256r1)).ToScriptHash()), snapshot, persistingBlock);

            engine.LoadScript(NativeContract.NameService.Script, configureState: p => p.ScriptHash = NativeContract.NameService.Hash);

            using var script = new ScriptBuilder();
            script.EmitPush(price);
            script.EmitPush("setPrice");
            engine.LoadScript(script.ToArray());

            if (engine.Execute() == VMState.FAULT)
            {
                return(false, false);
            }

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Boolean));

            return(true, result.GetBoolean());
        }
Beispiel #10
0
        internal static (bool State, bool Result) Check_IsAvailable(DataCache snapshot, UInt160 account, string name, Block persistingBlock)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application, new Nep17NativeContractExtensions.ManualWitness(account), snapshot, persistingBlock);

            engine.LoadScript(NativeContract.NameService.Script, configureState: p => p.ScriptHash = NativeContract.NameService.Hash);

            var script = new ScriptBuilder();

            script.EmitPush(name);
            script.EmitPush("isAvailable");
            engine.LoadScript(script.ToArray());

            if (engine.Execute() == VMState.FAULT)
            {
                return(false, false);
            }

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Boolean));

            return(((VM.Types.Boolean)result).GetBoolean(), true);
        }
Beispiel #11
0
        internal static bool Check_SetAdmin(DataCache snapshot, string name, UInt160 admin, UInt160 signedBy, Block persistingBlock)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application, new Nep17NativeContractExtensions.ManualWitness(admin, signedBy), snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings);
            using var script = new ScriptBuilder();
            script.EmitDynamicCall(NativeContract.NameService.Hash, "setAdmin", new ContractParameter[] {
                new ContractParameter(ContractParameterType.String)
                {
                    Value = name
                },
                new ContractParameter(ContractParameterType.Hash160)
                {
                    Value = admin
                }
            });
            engine.LoadScript(script.ToArray());

            if (engine.Execute() == VMState.FAULT)
            {
                return(false);
            }

            return(true);
        }
Beispiel #12
0
        internal static BigInteger Check_Renew(DataCache snapshot, string name, UInt160 signedBy, Block persistingBlock)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application, new Nep17NativeContractExtensions.ManualWitness(signedBy), snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings);
            using var script = new ScriptBuilder();
            script.EmitDynamicCall(NativeContract.NameService.Hash, "renew", new ContractParameter[] {
                new ContractParameter(ContractParameterType.String)
                {
                    Value = name
                }
            });
            engine.LoadScript(script.ToArray());

            if (engine.Execute() == VMState.FAULT)
            {
                return(-1);
            }

            var result = engine.ResultStack.Pop();

            Assert.IsInstanceOfType(result, typeof(VM.Types.Integer));

            return(result.GetInteger());
        }
Beispiel #13
0
        internal static bool Check_DeleteRecord(DataCache snapshot, string name, RecordType type, UInt160 signedBy, Block persistingBlock)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application, new Nep17NativeContractExtensions.ManualWitness(signedBy), snapshot, persistingBlock);
            using var script = new ScriptBuilder();
            script.EmitDynamicCall(NativeContract.NameService.Hash, "deleteRecord", new ContractParameter[] {
                new ContractParameter(ContractParameterType.String)
                {
                    Value = name
                },
                new ContractParameter(ContractParameterType.Integer)
                {
                    Value = (int)type
                }
            });
            engine.LoadScript(script.ToArray());

            if (engine.Execute() == VMState.FAULT)
            {
                return(false);
            }

            return(true);
        }
        public void TestCreateStandardMultisigAccount()
        {
            var settings = ProtocolSettings.Default;

            using var engine = ApplicationEngine.Create(TriggerType.Application, null, null, settings: TestBlockchain.TheNeoSystem.Settings, gas: 1100_00000000);

            using var script = new ScriptBuilder();
            script.EmitSysCall(ApplicationEngine.System_Contract_CreateMultisigAccount, new object[]
            {
                2,
                3,
                settings.StandbyCommittee[0].EncodePoint(true),
                settings.StandbyCommittee[1].EncodePoint(true),
                settings.StandbyCommittee[2].EncodePoint(true)
            });
            engine.LoadScript(script.ToArray());

            Assert.AreEqual(VMState.HALT, engine.Execute());

            var result = engine.ResultStack.Pop();

            new UInt160(result.GetSpan()).Should().Be(Contract.CreateMultiSigRedeemScript(2, settings.StandbyCommittee.Take(3).ToArray()).ToScriptHash());
        }
Beispiel #15
0
        public void TestAccount_IsStandard()
        {
            var engine = GetEngine(false, true);
            var hash   = new byte[] { 0x01, 0x01, 0x01, 0x01, 0x01,
                                      0x01, 0x01, 0x01, 0x01, 0x01,
                                      0x01, 0x01, 0x01, 0x01, 0x01,
                                      0x01, 0x01, 0x01, 0x01, 0x01 };

            engine.IsStandardContract(new UInt160(hash)).Should().BeFalse();

            var snapshot = Blockchain.Singleton.GetSnapshot();
            var state    = TestUtils.GetContract();

            snapshot.AddContract(state.Hash, state);
            engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);
            engine.LoadScript(new byte[] { 0x01 });
            engine.IsStandardContract(state.Hash).Should().BeFalse();

            state.Nef.Script = Contract.CreateSignatureRedeemScript(Blockchain.StandbyValidators[0]);
            engine           = ApplicationEngine.Create(TriggerType.Application, null, snapshot);
            engine.LoadScript(new byte[] { 0x01 });
            engine.IsStandardContract(state.Hash).Should().BeTrue();
        }
Beispiel #16
0
        public void Check_CommitteeBonus()
        {
            var snapshot = Blockchain.Singleton.GetSnapshot();

            snapshot.PersistingBlock = new Block {
                Index = 1
            };

            using (ScriptBuilder sb = new ScriptBuilder())
            {
                sb.EmitAppCall(NativeContract.NEO.Hash, "postPersist");
                sb.Emit(OpCode.RET);
                ApplicationEngine engine = ApplicationEngine.Create(TriggerType.System, null, snapshot, (long)(20 * NativeContract.GAS.Factor));
                engine.LoadScript(sb.ToArray());
                engine.Execute();
                engine.State.Should().Be(VM.VMState.HALT);

                var committee = Blockchain.StandbyCommittee.OrderBy(p => p).ToArray();
                NativeContract.GAS.BalanceOf(snapshot, Contract.CreateSignatureContract(committee[0]).ScriptHash.ToArray()).Should().Be(25000000);
                NativeContract.GAS.BalanceOf(snapshot, Contract.CreateSignatureContract(committee[1]).ScriptHash.ToArray()).Should().Be(25000000);
                NativeContract.GAS.BalanceOf(snapshot, Contract.CreateSignatureContract(committee[2]).ScriptHash.ToArray()).Should().Be(0);
            }
        }
Beispiel #17
0
        public void TestRuntime_Deserialize()
        {
            var snapshot = TestBlockchain.GetTestSnapshot();

            // Good

            using (var script = new ScriptBuilder())
            {
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "deserialize", "280474657374".HexToBytes());
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "deserialize", "210164".HexToBytes());

                using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings))
                {
                    engine.LoadScript(script.ToArray());

                    Assert.AreEqual(engine.Execute(), VMState.HALT);
                    Assert.AreEqual(2, engine.ResultStack.Count);

                    Assert.AreEqual(engine.ResultStack.Pop <Integer>().GetInteger(), 100);
                    Assert.AreEqual(engine.ResultStack.Pop <ByteString>().GetString(), "test");
                }
            }
        }
Beispiel #18
0
        public void TestNotify()
        {
            using var snapshot        = Blockchain.Singleton.GetSnapshot();
            using var engine          = ApplicationEngine.Create(TriggerType.Application, null, snapshot);
            ApplicationEngine.Notify += Test_Notify1;
            const string notifyEvent = "TestEvent";

            engine.SendNotification(UInt160.Zero, notifyEvent, new Array());
            eventName.Should().Be(notifyEvent);

            ApplicationEngine.Notify += Test_Notify2;
            engine.SendNotification(UInt160.Zero, notifyEvent, new Array());
            eventName.Should().Be(null);

            eventName = notifyEvent;
            ApplicationEngine.Notify -= Test_Notify1;
            engine.SendNotification(UInt160.Zero, notifyEvent, new Array());
            eventName.Should().Be(null);

            ApplicationEngine.Notify -= Test_Notify2;
            engine.SendNotification(UInt160.Zero, notifyEvent, new Array());
            eventName.Should().Be(null);
        }
Beispiel #19
0
        public static StackItem Call(this NativeContract contract, DataCache snapshot, IVerifiable container, Block persistingBlock, string method, params ContractParameter[] args)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application, container, snapshot, persistingBlock, settings: TestBlockchain.TheNeoSystem.Settings);
            using var script = new ScriptBuilder();
            script.EmitDynamicCall(contract.Hash, method, args);
            engine.LoadScript(script.ToArray());

            if (engine.Execute() != VMState.HALT)
            {
                Exception exception = engine.FaultException;
                while (exception?.InnerException != null)
                {
                    exception = exception.InnerException;
                }
                throw exception ?? new InvalidOperationException();
            }

            if (0 < engine.ResultStack.Count)
            {
                return(engine.ResultStack.Pop());
            }
            return(null);
        }
Beispiel #20
0
        public void TestSignatureContractCost()
        {
            var contract = Contract.CreateSignatureContract(_key.PublicKey);

            var tx = TestUtils.CreateRandomHashTransaction();

            tx.Signers[0].Account = contract.ScriptHash;

            using ScriptBuilder invocationScript = new();
            invocationScript.EmitPush(Neo.Wallets.Helper.Sign(tx, _key, ProtocolSettings.Default.Magic));
            tx.Witnesses = new Witness[] { new Witness()
                                           {
                                               InvocationScript = invocationScript.ToArray(), VerificationScript = contract.Script
                                           } };

            using var engine = ApplicationEngine.Create(TriggerType.Verification, tx, null, null, ProtocolSettings.Default);
            engine.LoadScript(contract.Script);
            engine.LoadScript(new Script(invocationScript.ToArray(), true), configureState: p => p.CallFlags = CallFlags.None);
            Assert.AreEqual(VMState.HALT, engine.Execute());
            Assert.IsTrue(engine.ResultStack.Pop().GetBoolean());

            Assert.AreEqual(Neo.SmartContract.Helper.SignatureContractCost() * PolicyContract.DefaultExecFeeFactor, engine.GasConsumed);
        }
Beispiel #21
0
        public void MemoryCompare()
        {
            var snapshot = TestBlockchain.GetTestSnapshot();

            using (var script = new ScriptBuilder())
            {
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "memoryCompare", "abc", "c");
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "memoryCompare", "abc", "d");
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "memoryCompare", "abc", "abc");
                script.EmitDynamicCall(NativeContract.StdLib.Hash, "memoryCompare", "abc", "abcd");

                using var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, settings: TestBlockchain.TheNeoSystem.Settings);
                engine.LoadScript(script.ToArray());

                Assert.AreEqual(engine.Execute(), VMState.HALT);
                Assert.AreEqual(4, engine.ResultStack.Count);

                Assert.AreEqual(-1, engine.ResultStack.Pop <Integer>().GetInteger());
                Assert.AreEqual(0, engine.ResultStack.Pop <Integer>().GetInteger());
                Assert.AreEqual(-1, engine.ResultStack.Pop <Integer>().GetInteger());
                Assert.AreEqual(-1, engine.ResultStack.Pop <Integer>().GetInteger());
            }
        }
Beispiel #22
0
        public void TestEmitArray()
        {
            var expected = new BigInteger[] { 1, 2, 3 };
            var sb       = new ScriptBuilder();

            sb.CreateArray(expected);

            using var engine = ApplicationEngine.Create(TriggerType.Application, null, null);
            engine.LoadScript(sb.ToArray());
            Assert.AreEqual(VMState.HALT, engine.Execute());

            CollectionAssert.AreEqual(expected, engine.ResultStack.Pop <VM.Types.Array>().Select(u => u.GetInteger()).ToArray());

            expected = new BigInteger[] { };
            sb       = new ScriptBuilder();
            sb.CreateArray(expected);

            using var engine2 = ApplicationEngine.Create(TriggerType.Application, null, null);
            engine2.LoadScript(sb.ToArray());
            Assert.AreEqual(VMState.HALT, engine2.Execute());

            Assert.AreEqual(0, engine2.ResultStack.Pop <VM.Types.Array>().Count);
        }
        internal static (BigInteger Value, bool State) Check_GetGasPerBlock(StoreView snapshot)
        {
            var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);

            engine.LoadScript(NativeContract.NEO.Script);

            var script = new ScriptBuilder();

            script.EmitPush(0);
            script.Emit(OpCode.PACK);
            script.EmitPush("getGasPerBlock");
            engine.LoadScript(script.ToArray());

            if (engine.Execute() == VMState.FAULT)
            {
                return(BigInteger.Zero, false);
            }

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(VM.Types.Integer));

            return(((VM.Types.Integer)result).GetInteger(), true);
        }
Beispiel #24
0
        public void ApplicationEngineReusedStorage_PartialReuseTwice()
        {
            var key      = new byte[] { (byte)OpCode.PUSH1 };
            var oldValue = new byte[] { (byte)OpCode.PUSH1 };
            var value    = new byte[] { (byte)OpCode.PUSH1, (byte)OpCode.PUSH1 };

            byte[] script = CreateMultiplePutScript(key, value);

            ContractState contractState = TestUtils.GetContract(script);

            contractState.Manifest.Features = ContractFeatures.HasStorage;

            StorageKey  skey  = TestUtils.GetStorageKey(contractState.Id, key);
            StorageItem sItem = TestUtils.GetStorageItem(oldValue);

            var snapshot = Blockchain.Singleton.GetSnapshot();

            snapshot.Storages.Add(skey, sItem);
            snapshot.Contracts.Add(script.ToScriptHash(), contractState);

            using (ApplicationEngine ae = ApplicationEngine.Create(TriggerType.Application, null, snapshot))
            {
                Debugger debugger = new Debugger(ae);
                ae.LoadScript(script);
                debugger.StepInto();                                                           //push value
                debugger.StepInto();                                                           //push key
                debugger.StepInto();                                                           //syscall Storage.GetContext
                debugger.StepInto();                                                           //syscall Storage.Put
                debugger.StepInto();                                                           //push value
                debugger.StepInto();                                                           //push key
                debugger.StepInto();                                                           //syscall Storage.GetContext
                var setupPrice = ae.GasConsumed;
                debugger.StepInto();                                                           //syscall Storage.Put
                (ae.GasConsumed - setupPrice).Should().Be(1 * ApplicationEngine.StoragePrice); // = PUT basic fee
            }
        }
Beispiel #25
0
        internal static (bool State, string Result) Check_GetRecord(DataCache snapshot, string name, RecordType type, Block persistingBlock)
        {
            using var engine = ApplicationEngine.Create(TriggerType.Application,
                                                        new Nep17NativeContractExtensions.ManualWitness(UInt160.Zero), snapshot, persistingBlock);

            engine.LoadScript(NativeContract.NameService.Script, configureState: p => p.ScriptHash = NativeContract.NameService.Hash);

            using var script = new ScriptBuilder();
            script.EmitPush(type);
            script.EmitPush(name);
            script.EmitPush("getRecord");
            engine.LoadScript(script.ToArray());

            if (engine.Execute() == VMState.FAULT)
            {
                return(false, null);
            }

            var result = engine.ResultStack.Pop();

            result.Should().BeOfType(typeof(Neo.VM.Types.ByteString));

            return(true, result.ToString());
        }
Beispiel #26
0
        public void InvokeCallbackTest()
        {
            using var script = new ScriptBuilder();

            script.EmitPush(5);                                    // Callback argument 1
            script.EmitPush(1);                                    // Callback argument 2
            script.EmitPush(2);                                    // ParamCount
            script.Emit(OpCode.PACK);
            script.EmitPush(2);                                    // ParamCount
            script.Emit(OpCode.PUSHA, BitConverter.GetBytes(200)); // -> Nop area
            script.EmitSysCall(ApplicationEngine.System_Callback_Create);
            script.EmitSysCall(ApplicationEngine.System_Callback_Invoke);
            script.Emit(OpCode.RET);

            for (int x = 0; x < 250; x++)
            {
                script.Emit(OpCode.NOP);
            }

            script.Emit(OpCode.SUB); // Should return 5-1
            script.Emit(OpCode.RET);

            // Execute

            var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 100_000_000);

            engine.LoadScript(script.ToArray());
            Assert.AreEqual(engine.Execute(), VMState.HALT);

            // Check the results

            Assert.AreEqual(1, engine.ResultStack.Count);
            var item = engine.ResultStack.Pop <PrimitiveType>();

            Assert.AreEqual(4, item.GetInteger());
        }
Beispiel #27
0
        public void TestStorage_Delete()
        {
            var engine   = GetEngine(false, true);
            var snapshot = Blockchain.Singleton.GetSnapshot();
            var state    = TestUtils.GetContract();

            state.Manifest.Features = ContractFeatures.HasStorage;
            var storageKey = new StorageKey
            {
                Id  = 0x42000000,
                Key = new byte[] { 0x01 }
            };
            var storageItem = new StorageItem
            {
                Value      = new byte[] { 0x01, 0x02, 0x03, 0x04 },
                IsConstant = false
            };

            snapshot.Contracts.Add(state.ScriptHash, state);
            snapshot.Storages.Add(storageKey, storageItem);
            engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);
            engine.LoadScript(new byte[] { 0x01 });
            state.Manifest.Features = ContractFeatures.HasStorage;
            var key            = new byte[] { 0x01 };
            var storageContext = new StorageContext
            {
                Id         = state.Id,
                IsReadOnly = false
            };

            engine.Delete(storageContext, key);

            //context is readonly
            storageContext.IsReadOnly = true;
            Assert.ThrowsException <ArgumentException>(() => engine.Delete(storageContext, key));
        }
Beispiel #28
0
        public void System_Blockchain_GetBlock()
        {
            var tx = new Transaction()
            {
                Script          = new byte[] { 0x01 },
                Attributes      = Array.Empty <TransactionAttribute>(),
                Signers         = Array.Empty <Signer>(),
                NetworkFee      = 0x02,
                SystemFee       = 0x03,
                Nonce           = 0x04,
                ValidUntilBlock = 0x05,
                Version         = 0x06,
                Witnesses       = new Witness[] { new Witness()
                                                  {
                                                      VerificationScript = new byte[] { 0x07 }
                                                  } },
            };

            var block = new Block()
            {
                Index     = 0,
                Timestamp = 2,
                Version   = 3,
                Witness   = new Witness()
                {
                    InvocationScript   = new byte[0],
                    VerificationScript = new byte[0]
                },
                PrevHash      = UInt256.Zero,
                MerkleRoot    = UInt256.Zero,
                NextConsensus = UInt160.Zero,
                ConsensusData = new ConsensusData()
                {
                    Nonce = 1, PrimaryIndex = 1
                },
                Transactions = new Transaction[] { tx }
            };

            var snapshot = Blockchain.Singleton.GetSnapshot();

            using (var script = new ScriptBuilder())
            {
                script.EmitPush(block.Hash.ToArray());
                script.EmitSysCall(ApplicationEngine.System_Blockchain_GetBlock);

                // Without block

                var engine = ApplicationEngine.Create(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);

                // Not traceable block

                var height = snapshot.BlockHashIndex.GetAndChange();
                height.Index = block.Index + Transaction.MaxValidUntilBlockIncrement;

                var blocks = snapshot.Blocks;
                var txs    = snapshot.Transactions;
                blocks.Add(block.Hash, block.Trim());
                txs.Add(tx.Hash, new TransactionState()
                {
                    Transaction = tx, BlockIndex = block.Index, VMState = VMState.HALT
                });

                engine = ApplicationEngine.Create(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 block

                height.Index = block.Index;

                engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0, true);
                engine.LoadScript(script.ToArray());

                Assert.AreEqual(engine.Execute(), VMState.HALT);
                Assert.AreEqual(1, engine.ResultStack.Count);

                var array = engine.ResultStack.Pop <VM.Types.Array>();
                Assert.AreEqual(block.Hash, new UInt256(array[0].GetSpan()));

                // Clean

                blocks.Delete(block.Hash);
                txs.Delete(tx.Hash);
            }
        }
Beispiel #29
0
        public void Check_BalanceOfTransferAndBurn()
        {
            var snapshot = Blockchain.Singleton.GetSnapshot();

            snapshot.PersistingBlock = new Block()
            {
                Index = 1000
            };

            byte[] from = Blockchain.GetConsensusAddress(Blockchain.StandbyValidators).ToArray();

            byte[] to = new byte[20];

            var keyCount = snapshot.Storages.GetChangeSet().Count();

            var supply = NativeContract.GAS.TotalSupply(snapshot);

            supply.Should().Be(3000000050000000); // 3000000000000000 + 50000000 (neo holder reward)

            // Check unclaim

            var unclaim = UT_NeoToken.Check_UnclaimedGas(snapshot, from);

            unclaim.Value.Should().Be(new BigInteger(0.5 * 1000 * 100000000L));
            unclaim.State.Should().BeTrue();

            // Transfer

            NativeContract.NEO.Transfer(snapshot, from, to, BigInteger.Zero, true).Should().BeTrue();
            NativeContract.NEO.BalanceOf(snapshot, from).Should().Be(100000000);
            NativeContract.NEO.BalanceOf(snapshot, to).Should().Be(0);

            NativeContract.GAS.BalanceOf(snapshot, from).Should().Be(30000500_00000000);
            NativeContract.GAS.BalanceOf(snapshot, to).Should().Be(0);

            // Check unclaim

            unclaim = UT_NeoToken.Check_UnclaimedGas(snapshot, from);
            unclaim.Value.Should().Be(new BigInteger(0));
            unclaim.State.Should().BeTrue();

            supply = NativeContract.GAS.TotalSupply(snapshot);
            supply.Should().Be(3000050050000000);

            snapshot.Storages.GetChangeSet().Count().Should().Be(keyCount + 3); // Gas

            // Transfer

            keyCount = snapshot.Storages.GetChangeSet().Count();

            NativeContract.GAS.Transfer(snapshot, from, to, 30000500_00000000, false).Should().BeFalse(); // Not signed
            NativeContract.GAS.Transfer(snapshot, from, to, 30000500_00000001, true).Should().BeFalse();  // More than balance
            NativeContract.GAS.Transfer(snapshot, from, to, 30000500_00000000, true).Should().BeTrue();   // All balance

            // Balance of

            NativeContract.GAS.BalanceOf(snapshot, to).Should().Be(30000500_00000000);
            NativeContract.GAS.BalanceOf(snapshot, from).Should().Be(0);

            snapshot.Storages.GetChangeSet().Count().Should().Be(keyCount + 1); // All

            // Burn

            var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0);

            keyCount = snapshot.Storages.GetChangeSet().Count();

            Assert.ThrowsException <ArgumentOutOfRangeException>(() =>
                                                                 NativeContract.GAS.Burn(engine, new UInt160(to), BigInteger.MinusOne));

            // Burn more than expected

            Assert.ThrowsException <InvalidOperationException>(() =>
                                                               NativeContract.GAS.Burn(engine, new UInt160(to), new BigInteger(30000500_00000001)));

            // Real burn

            NativeContract.GAS.Burn(engine, new UInt160(to), new BigInteger(1));

            NativeContract.GAS.BalanceOf(snapshot, to).Should().Be(3000049999999999);

            keyCount.Should().Be(snapshot.Storages.GetChangeSet().Count());

            // Burn all

            NativeContract.GAS.Burn(engine, new UInt160(to), new BigInteger(3000049999999999));

            (keyCount - 1).Should().Be(snapshot.Storages.GetChangeSet().Count());

            // Bad inputs

            NativeContract.GAS.Transfer(snapshot, from, to, BigInteger.MinusOne, true).Should().BeFalse();
            NativeContract.GAS.Transfer(snapshot, new byte[19], to, BigInteger.One, false).Should().BeFalse();
            NativeContract.GAS.Transfer(snapshot, from, new byte[19], BigInteger.One, false).Should().BeFalse();
        }
Beispiel #30
0
        public void Runtime_GetNotifications_Test()
        {
            UInt160 scriptHash2;
            var     snapshot = TestBlockchain.GetTestSnapshot();

            using (var script = new ScriptBuilder())
            {
                // Notify method

                script.Emit(OpCode.SWAP, OpCode.NEWARRAY, OpCode.SWAP);
                script.EmitSysCall(ApplicationEngine.System_Runtime_Notify);

                // Add return

                script.EmitPush(true);
                script.Emit(OpCode.RET);

                // Mock contract

                scriptHash2 = script.ToArray().ToScriptHash();

                snapshot.DeleteContract(scriptHash2);
                snapshot.AddContract(scriptHash2, new ContractState()
                {
                    Nef = new NefFile {
                        Script = script.ToArray()
                    },
                    Hash     = script.ToArray().ToScriptHash(),
                    Manifest = TestUtils.CreateManifest("test", ContractParameterType.Any, ContractParameterType.Integer, ContractParameterType.Integer),
                });
            }

            // Wrong length

            using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot))
                using (var script = new ScriptBuilder())
                {
                    // Retrive

                    script.EmitPush(1);
                    script.EmitSysCall(ApplicationEngine.System_Runtime_GetNotifications);

                    // Execute

                    engine.LoadScript(script.ToArray());

                    Assert.AreEqual(VMState.FAULT, engine.Execute());
                }

            // All test

            using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot))
                using (var script = new ScriptBuilder())
                {
                    // Notification

                    script.EmitPush(0);
                    script.Emit(OpCode.NEWARRAY);
                    script.EmitPush("testEvent1");
                    script.EmitSysCall(ApplicationEngine.System_Runtime_Notify);

                    // Call script

                    script.EmitDynamicCall(scriptHash2, "test", "testEvent2", 1);

                    // Drop return

                    script.Emit(OpCode.DROP);

                    // Receive all notifications

                    script.Emit(OpCode.PUSHNULL);
                    script.EmitSysCall(ApplicationEngine.System_Runtime_GetNotifications);

                    // Execute

                    engine.LoadScript(script.ToArray());
                    var currentScriptHash = engine.EntryScriptHash;

                    Assert.AreEqual(VMState.HALT, engine.Execute());
                    Assert.AreEqual(1, engine.ResultStack.Count);
                    Assert.AreEqual(2, engine.Notifications.Count);

                    Assert.IsInstanceOfType(engine.ResultStack.Peek(), typeof(VM.Types.Array));

                    var array = (VM.Types.Array)engine.ResultStack.Pop();

                    // Check syscall result

                    AssertNotification(array[1], scriptHash2, "testEvent2");
                    AssertNotification(array[0], currentScriptHash, "testEvent1");

                    // Check notifications

                    Assert.AreEqual(scriptHash2, engine.Notifications[1].ScriptHash);
                    Assert.AreEqual("testEvent2", engine.Notifications[1].EventName);

                    Assert.AreEqual(currentScriptHash, engine.Notifications[0].ScriptHash);
                    Assert.AreEqual("testEvent1", engine.Notifications[0].EventName);
                }

            // Script notifications

            using (var engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot))
                using (var script = new ScriptBuilder())
                {
                    // Notification

                    script.EmitPush(0);
                    script.Emit(OpCode.NEWARRAY);
                    script.EmitPush("testEvent1");
                    script.EmitSysCall(ApplicationEngine.System_Runtime_Notify);

                    // Call script

                    script.EmitDynamicCall(scriptHash2, "test", "testEvent2", 1);

                    // Drop return

                    script.Emit(OpCode.DROP);

                    // Receive all notifications

                    script.EmitPush(scriptHash2.ToArray());
                    script.EmitSysCall(ApplicationEngine.System_Runtime_GetNotifications);

                    // Execute

                    engine.LoadScript(script.ToArray());
                    var currentScriptHash = engine.EntryScriptHash;

                    Assert.AreEqual(VMState.HALT, engine.Execute());
                    Assert.AreEqual(1, engine.ResultStack.Count);
                    Assert.AreEqual(2, engine.Notifications.Count);

                    Assert.IsInstanceOfType(engine.ResultStack.Peek(), typeof(VM.Types.Array));

                    var array = (VM.Types.Array)engine.ResultStack.Pop();

                    // Check syscall result

                    AssertNotification(array[0], scriptHash2, "testEvent2");

                    // Check notifications

                    Assert.AreEqual(scriptHash2, engine.Notifications[1].ScriptHash);
                    Assert.AreEqual("testEvent2", engine.Notifications[1].EventName);

                    Assert.AreEqual(currentScriptHash, engine.Notifications[0].ScriptHash);
                    Assert.AreEqual("testEvent1", engine.Notifications[0].EventName);
                }

            // Clean storage

            snapshot.DeleteContract(scriptHash2);
        }