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()); }
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(); }
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); } }
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(); }
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); }
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); }
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()); }
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); }
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); }
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()); }
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()); }
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(); }
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); } }
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"); } } }
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); }
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); }
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); }
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()); } }
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); }
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 } }
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()); }
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()); }
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)); }
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); } }
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(); }
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); }