public void Create_WithFunds_Via_Controller() { using (NodeBuilder builder = NodeBuilder.Create(this)) { CoreNode scSender = builder.CreateSmartContractPowNode(); CoreNode scReceiver = builder.CreateSmartContractPowNode(); builder.StartAll(); scSender.NotInIBD(); scReceiver.NotInIBD(); scSender.FullNode.Network.Consensus.CoinbaseMaturity = 1L; scReceiver.FullNode.Network.Consensus.CoinbaseMaturity = 1L; int maturity = (int)scReceiver.FullNode.Network.Consensus.CoinbaseMaturity; scSender.FullNode.WalletManager().CreateWallet(Password, WalletName, Passphrase); scReceiver.FullNode.WalletManager().CreateWallet(Password, WalletName, Passphrase); HdAddress addr = scSender.FullNode.WalletManager().GetUnusedAddress(new WalletAccountReference(WalletName, AccountName)); Features.Wallet.Wallet wallet = scSender.FullNode.WalletManager().GetWalletByName(WalletName); Key key = wallet.GetExtendedPrivateKeyForAddress(Password, addr).PrivateKey; scSender.SetDummyMinerSecret(new BitcoinSecret(key, scSender.FullNode.Network)); scReceiver.SetDummyMinerSecret(new BitcoinSecret(key, scReceiver.FullNode.Network)); scSender.GenerateStratisWithMiner(2); TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(scSender)); var total = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount); Assert.Equal(Money.COIN * (maturity + 1) * 50, total); SmartContractsController senderSmartContractsController = scSender.FullNode.NodeService <SmartContractsController>(); SmartContractWalletController senderWalletController = scSender.FullNode.NodeService <SmartContractWalletController>(); SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/StorageDemo.cs"); Assert.True(compilationResult.Success); var buildRequest = new BuildCreateContractTransactionRequest { AccountName = AccountName, Amount = "30", GasLimit = "10000", GasPrice = "1", ContractCode = compilationResult.Compilation.ToHexString(), FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; JsonResult result = (JsonResult)senderSmartContractsController.BuildCreateSmartContractTransaction(buildRequest); var response = (BuildCreateContractTransactionResponse)result.Value; scSender.CreateRPCClient().AddNode(scReceiver.Endpoint, true); SmartContractSharedSteps.SendTransactionAndMine(scSender, scReceiver, senderWalletController, response.Hex); ContractStateRepositoryRoot senderState = scSender.FullNode.NodeService <ContractStateRepositoryRoot>(); Assert.Equal((ulong)30 * 100_000_000, senderState.GetCurrentBalance(new Address(response.NewContractAddress).ToUint160(new SmartContractsRegTest()))); } }
public void ReceivedType_Is_MiningReward() { var transactionData = new TransactionData(); transactionData.IsCoinBase = true; transactionData.Index = 0; Assert.Equal(ContractTransactionItemType.Staked, SmartContractWalletController.ReceivedTransactionType(transactionData)); }
public void ReceivedType_Is_GasRefund() { var transactionData = new TransactionData(); transactionData.IsCoinBase = true; transactionData.Index = 1; Assert.Equal(ContractTransactionItemType.GasRefund, SmartContractWalletController.ReceivedTransactionType(transactionData)); }
public static void SendTransaction(CoreNode scSender, CoreNode scReceiver, SmartContractWalletController senderWalletController, string responseHex) { senderWalletController.SendTransaction(new SendTransactionRequest { Hex = responseHex }); TestHelper.WaitLoop(() => scReceiver.CreateRPCClient().GetRawMempool().Length > 0); }
/// <summary> /// Creates a new DynamicContractController instance. /// </summary> /// <param name="smartContractWalletController"></param> /// <param name="localCallController"></param> /// <param name="stateRoot"></param> /// <param name="loader"></param> /// <param name="network"></param> public DynamicContractController( SmartContractWalletController smartContractWalletController, SmartContractsController localCallController, IStateRepositoryRoot stateRoot, ILoader loader, Network network) { this.smartContractWalletController = smartContractWalletController; this.localCallController = localCallController; this.stateRoot = stateRoot; this.loader = loader; this.network = network; }
public void ReceivedType_Is_Receive_Null_Coinbase() { var transactionData = new TransactionData(); transactionData.IsCoinBase = null; // Should be true for all indexes for (var i = 0; i < 10; i++) { transactionData.Index = i; Assert.Equal(ContractTransactionItemType.Received, SmartContractWalletController.ReceivedTransactionType(transactionData)); } }
public void SmartContractsController_Builds_Transaction_With_Minimum_Inputs() { using (NodeBuilder builder = NodeBuilder.Create(this)) { CoreNode scSender = builder.CreateSmartContractPowNode(); builder.StartAll(); scSender.NotInIBD(); var maturity = (int)scSender.FullNode.Network.Consensus.CoinbaseMaturity; scSender.FullNode.WalletManager().CreateWallet(Password, WalletName, Passphrase); HdAddress addr = scSender.FullNode.WalletManager().GetUnusedAddress(new WalletAccountReference(WalletName, AccountName)); Features.Wallet.Wallet wallet = scSender.FullNode.WalletManager().GetWalletByName(WalletName); Key key = wallet.GetExtendedPrivateKeyForAddress(Password, addr).PrivateKey; scSender.SetDummyMinerSecret(new BitcoinSecret(key, scSender.FullNode.Network)); scSender.GenerateStratisWithMiner(maturity + 5); TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(scSender)); int spendableBlocks = GetSpendableBlocks(maturity + 5, maturity); var total = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount); Assert.Equal(Money.COIN * spendableBlocks * 50, total); SmartContractsController senderSmartContractsController = scSender.FullNode.NodeService <SmartContractsController>(); SmartContractWalletController senderWalletController = scSender.FullNode.NodeService <SmartContractWalletController>(); SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/StorageDemo.cs"); Assert.True(compilationResult.Success); var buildRequest = new BuildCreateContractTransactionRequest { AccountName = AccountName, GasLimit = "10000", GasPrice = "1", ContractCode = compilationResult.Compilation.ToHexString(), FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; JsonResult result = (JsonResult)senderSmartContractsController.BuildCreateSmartContractTransaction(buildRequest); var response = (BuildCreateContractTransactionResponse)result.Value; var transaction = scSender.FullNode.Network.CreateTransaction(response.Hex); Assert.Single(transaction.Inputs); } }
public Node(CoreNode coreNode, Chain chain) { this.CoreNode = coreNode; this.chain = chain; // Set up address and mining this.CoreNode.FullNode.WalletManager().CreateWallet(this.Password, this.WalletName, this.Passphrase); this.MinerAddress = this.CoreNode.FullNode.WalletManager().GetUnusedAddress(new WalletAccountReference(this.WalletName, this.AccountName)); Wallet wallet = this.CoreNode.FullNode.WalletManager().GetWalletByName(this.WalletName); Key key = wallet.GetExtendedPrivateKeyForAddress(this.Password, this.MinerAddress).PrivateKey; this.CoreNode.SetDummyMinerSecret(new BitcoinSecret(key, this.CoreNode.FullNode.Network)); // Set up services for later this.smartContractWalletController = this.CoreNode.FullNode.NodeService <SmartContractWalletController>(); this.smartContractsController = this.CoreNode.FullNode.NodeService <SmartContractsController>(); this.stateRoot = this.CoreNode.FullNode.NodeService <IStateRepositoryRoot>(); this.blockStore = this.CoreNode.FullNode.NodeService <IBlockStore>(); }
public MockChainNode(CoreNode coreNode, IMockChain chain, Mnemonic mnemonic = null) { this.CoreNode = coreNode; this.chain = chain; // Set up address and mining (Wallet wallet, _) = this.CoreNode.FullNode.WalletManager().CreateWallet(this.Password, this.WalletName, this.Passphrase, mnemonic); HdAccount account = wallet.GetAccount(this.AccountName); this.MinerAddress = account.GetFirstUnusedReceivingAddress(); Key key = wallet.GetExtendedPrivateKeyForAddress(this.Password, this.MinerAddress).PrivateKey; this.CoreNode.SetMinerSecret(new BitcoinSecret(key, this.CoreNode.FullNode.Network)); // Set up services for later this.smartContractWalletController = this.CoreNode.FullNode.NodeController <SmartContractWalletController>(); this.smartContractsController = this.CoreNode.FullNode.NodeController <SmartContractsController>(); this.stateRoot = this.CoreNode.FullNode.NodeService <IStateRepositoryRoot>(); this.blockStore = this.CoreNode.FullNode.NodeService <IBlockStore>(); }
public void SmartContractsController_Builds_Transaction_With_Minimum_Inputs() { using (SmartContractNodeBuilder builder = SmartContractNodeBuilder.Create(this)) { CoreNode scSender = builder.CreateSmartContractPowNode().WithWallet().Start(); var maturity = (int)scSender.FullNode.Network.Consensus.CoinbaseMaturity; HdAddress addr = TestHelper.MineBlocks(scSender, maturity + 5).AddressUsed; int spendableBlocks = GetSpendableBlocks(maturity + 5, maturity); var total = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount); Assert.Equal(Money.COIN * spendableBlocks * 50, total); SmartContractsController senderSmartContractsController = scSender.FullNode.NodeService <SmartContractsController>(); SmartContractWalletController senderWalletController = scSender.FullNode.NodeService <SmartContractWalletController>(); ContractCompilationResult compilationResult = ContractCompiler.CompileFile("SmartContracts/StorageDemo.cs"); Assert.True(compilationResult.Success); var buildRequest = new BuildCreateContractTransactionRequest { AccountName = AccountName, GasLimit = 10_000, GasPrice = 1, ContractCode = compilationResult.Compilation.ToHexString(), FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; JsonResult result = (JsonResult)senderSmartContractsController.BuildCreateSmartContractTransaction(buildRequest); var response = (BuildCreateContractTransactionResponse)result.Value; var transaction = scSender.FullNode.Network.CreateTransaction(response.Hex); Assert.Single(transaction.Inputs); } }
public void SendAndReceiveSmartContractTransactionsUsingController() { using (NodeBuilder builder = NodeBuilder.Create(this)) { CoreNode scSender = builder.CreateSmartContractPowNode(); CoreNode scReceiver = builder.CreateSmartContractPowNode(); builder.StartAll(); scSender.NotInIBD(); scReceiver.NotInIBD(); scSender.FullNode.WalletManager().CreateWallet(Password, WalletName); scReceiver.FullNode.WalletManager().CreateWallet(Password, WalletName); HdAddress addr = scSender.FullNode.WalletManager().GetUnusedAddress(new WalletAccountReference(WalletName, AccountName)); Features.Wallet.Wallet wallet = scSender.FullNode.WalletManager().GetWalletByName(WalletName); Key key = wallet.GetExtendedPrivateKeyForAddress(Password, addr).PrivateKey; scSender.SetDummyMinerSecret(new BitcoinSecret(key, scSender.FullNode.Network)); scReceiver.SetDummyMinerSecret(new BitcoinSecret(key, scReceiver.FullNode.Network)); var maturity = (int)scSender.FullNode.Network.Consensus.CoinbaseMaturity; scSender.GenerateStratisWithMiner(maturity + 5); TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(scSender)); var total = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount); Assert.Equal(Money.COIN * (maturity + 5) * 50, total); SmartContractsController senderSmartContractsController = scSender.FullNode.NodeService <SmartContractsController>(); SmartContractWalletController senderWalletController = scSender.FullNode.NodeService <SmartContractWalletController>(); SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/StorageDemo.cs"); Assert.True(compilationResult.Success); var buildRequest = new BuildCreateContractTransactionRequest { AccountName = AccountName, GasLimit = "10000", GasPrice = "1", ContractCode = compilationResult.Compilation.ToHexString(), FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; JsonResult result = (JsonResult)senderSmartContractsController.BuildCreateSmartContractTransaction(buildRequest); var response = (BuildCreateContractTransactionResponse)result.Value; scSender.CreateRPCClient().AddNode(scReceiver.Endpoint, true); SmartContractSharedSteps.SendTransactionAndMine(scSender, scReceiver, senderWalletController, response.Hex); var receiptStorage = scReceiver.FullNode.NodeService <ISmartContractReceiptStorage>(); Assert.NotNull(receiptStorage.GetReceipt(response.TransactionId)); // Check wallet history is updating correctly result = (JsonResult)senderWalletController.GetHistory(new WalletHistoryRequest { AccountName = AccountName, WalletName = WalletName }); var walletHistoryModel = (WalletHistoryModel)result.Value; Assert.Single(walletHistoryModel.AccountsHistoryModel.First().TransactionsHistory.Where(x => x.Type == TransactionItemType.Send)); string storageRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "TestSave", DataType = SmartContractDataType.String })).Value; Assert.Equal("Hello, smart contract world!", storageRequestResult); string ownerRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "Owner", DataType = SmartContractDataType.Address })).Value; Assert.NotEmpty(ownerRequestResult); string counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "Counter", DataType = SmartContractDataType.Int })).Value; Assert.Equal("12345", counterRequestResult); var callRequest = new BuildCallContractTransactionRequest { AccountName = AccountName, GasLimit = "10000", GasPrice = "1", Amount = "0", MethodName = "Increment", ContractAddress = response.NewContractAddress, FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; result = (JsonResult)senderSmartContractsController.BuildCallSmartContractTransaction(callRequest); var callResponse = (BuildCallContractTransactionResponse)result.Value; SmartContractSharedSteps.SendTransactionAndMine(scSender, scReceiver, senderWalletController, callResponse.Hex); counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "Counter", DataType = SmartContractDataType.Int })).Value; Assert.Equal("12346", counterRequestResult); // Check wallet history again result = (JsonResult)senderWalletController.GetHistory(new WalletHistoryRequest { AccountName = AccountName, WalletName = WalletName }); walletHistoryModel = (WalletHistoryModel)result.Value; Assert.Equal(2, walletHistoryModel.AccountsHistoryModel.First().TransactionsHistory.Where(x => x.Type == TransactionItemType.Send).Count()); // Check receipts var receiptResponse = (JsonResult)senderSmartContractsController.GetReceipt(callResponse.TransactionId.ToString()); var receiptModel = (ReceiptModel)receiptResponse.Value; Assert.True(receiptModel.Successful); } }
public void GetHistoryWithValidModelWithoutTransactionSpendingDetailsReturnsWalletHistoryModel() { ulong gasPrice = SmartContractMempoolValidator.MinGasPrice; int vmVersion = 1; Gas gasLimit = (Gas)(SmartContractFormatRule.GasLimitMaximum / 2); var contractTxData = new ContractTxData(vmVersion, gasPrice, gasLimit, new byte[] { 0, 1, 2, 3 }); var callDataSerializer = new CallDataSerializer(new ContractPrimitiveSerializer(new SmartContractsRegTest())); var contractCreateScript = new Script(callDataSerializer.Serialize(contractTxData)); string walletName = "myWallet"; HdAddress address = WalletTestsHelpers.CreateAddress(); TransactionData normalTransaction = WalletTestsHelpers.CreateTransaction(new uint256(1), new Money(500000), 1); TransactionData createTransaction = WalletTestsHelpers.CreateTransaction(new uint256(1), new Money(500000), 1); createTransaction.SpendingDetails = new SpendingDetails { BlockHeight = 100, CreationTime = DateTimeOffset.Now, TransactionId = uint256.One, Payments = new List <PaymentDetails> { new PaymentDetails { Amount = new Money(100000), DestinationScriptPubKey = contractCreateScript } } }; address.Transactions.Add(normalTransaction); address.Transactions.Add(createTransaction); var addresses = new List <HdAddress> { address }; Features.Wallet.Wallet wallet = WalletTestsHelpers.CreateWallet(walletName); var account = new HdAccount { ExternalAddresses = addresses }; wallet.AccountsRoot.Add(new AccountRoot() { Accounts = new List <HdAccount> { account } }); List <FlatHistory> flat = addresses.SelectMany(s => s.Transactions.Select(t => new FlatHistory { Address = s, Transaction = t })).ToList(); var accountsHistory = new List <AccountHistory> { new AccountHistory { History = flat, Account = account } }; this.walletManager.Setup(w => w.GetHistory(walletName, It.IsAny <string>())).Returns(accountsHistory); this.walletManager.Setup(w => w.GetWalletByName(walletName)).Returns(wallet); this.walletManager.Setup(w => w.GetAccounts(walletName)).Returns(new List <HdAccount> { account }); this.receiptRepository.Setup(x => x.Retrieve(It.IsAny <uint256>())) .Returns(new Receipt(null, 0, new Log[0], null, null, null, uint160.Zero, true, null)); this.callDataSerializer.Setup(x => x.Deserialize(It.IsAny <byte[]>())) .Returns(Result.Ok(new ContractTxData(0, 0, (Gas)0, new uint160(0), null, null))); var controller = new SmartContractWalletController( this.broadcasterManager.Object, this.callDataSerializer.Object, this.connectionManager.Object, this.loggerFactory.Object, this.network, this.receiptRepository.Object, this.walletManager.Object); IActionResult result = controller.GetHistory(walletName, address.Address); var viewResult = Assert.IsType <JsonResult>(result); var model = viewResult.Value as IEnumerable <ContractTransactionItem>; Assert.NotNull(model); Assert.Equal(3, model.Count()); ContractTransactionItem resultingTransaction = model.ElementAt(2); ContractTransactionItem resultingCreate = model.ElementAt(0); Assert.Equal(ContractTransactionItemType.ContractCreate, resultingCreate.Type); Assert.Equal(createTransaction.SpendingDetails.TransactionId, resultingCreate.Hash); Assert.Equal(createTransaction.SpendingDetails.Payments.First().Amount.ToUnit(MoneyUnit.BTC), resultingCreate.Amount); Assert.Equal(uint160.Zero.ToBase58Address(this.network), resultingCreate.To); Assert.Equal((uint)createTransaction.SpendingDetails.BlockHeight, resultingCreate.BlockHeight); Assert.Equal(ContractTransactionItemType.Received, resultingTransaction.Type); Assert.Equal(address.Address, resultingTransaction.To); Assert.Equal(normalTransaction.Id, resultingTransaction.Hash); Assert.Equal(normalTransaction.Amount.ToUnit(MoneyUnit.BTC), resultingTransaction.Amount); Assert.Equal((uint)1, resultingTransaction.BlockHeight); }
public void GetHistoryWithValidModelWithSkipAndTakeReturnsWalletHistoryModel() { ulong gasPrice = SmartContractMempoolValidator.MinGasPrice; int vmVersion = 1; var gasLimit = (Stratis.SmartContracts.RuntimeObserver.Gas)(SmartContractFormatLogic.GasLimitMaximum / 2); var contractTxData = new ContractTxData(vmVersion, gasPrice, gasLimit, new byte[] { 0, 1, 2, 3 }); var callDataSerializer = new CallDataSerializer(new ContractPrimitiveSerializer(new SmartContractsRegTest())); var contractCreateScript = new Script(callDataSerializer.Serialize(contractTxData)); string walletName = "myWallet"; HdAddress address = WalletTestsHelpers.CreateAddress(); const int totalHistoryLength = 100; const int toSkip = 10; const int toTake = 10; for (int i = 0; i < totalHistoryLength; i++) { TransactionData createTransaction = WalletTestsHelpers.CreateTransaction(new uint256((ulong)i), new Money(500000), 100 + i); createTransaction.SpendingDetails = new SpendingDetails { BlockHeight = 100 + i, CreationTime = DateTimeOffset.Now, TransactionId = new uint256((ulong)i), Payments = new List <PaymentDetails> { new PaymentDetails { Amount = new Money(100000), DestinationScriptPubKey = contractCreateScript } } }; address.Transactions.Add(createTransaction); } var addresses = new List <HdAddress> { address }; Features.Wallet.Wallet wallet = WalletTestsHelpers.CreateWallet(walletName); var account = new HdAccount { ExternalAddresses = addresses }; wallet.AccountsRoot.Add(new AccountRoot() { Accounts = new List <HdAccount> { account } }); List <FlatHistory> flat = addresses.SelectMany(s => s.Transactions.Select(t => new FlatHistory { Address = s, Transaction = t })).ToList(); var accountsHistory = new List <AccountHistory> { new AccountHistory { History = flat, Account = account } }; this.walletManager.Setup(w => w.GetHistory(walletName, It.IsAny <string>())).Returns(accountsHistory); this.walletManager.Setup(w => w.GetWalletByName(walletName)).Returns(wallet); this.walletManager.Setup(w => w.GetAccounts(walletName)).Returns(new List <HdAccount> { account }); var receipt = new Receipt(null, 12345, new Log[0], null, null, null, uint160.Zero, true, null, null, 2, 100000); var receiptList = new List <Receipt>(); for (int i = 0; i < totalHistoryLength; i++) { receiptList.Add(receipt); } this.receiptRepository.Setup(x => x.RetrieveMany(It.IsAny <IList <uint256> >())) .Returns(receiptList); this.callDataSerializer.Setup(x => x.Deserialize(It.IsAny <byte[]>())) .Returns(Result.Ok(new ContractTxData(0, 0, (Stratis.SmartContracts.RuntimeObserver.Gas) 0, new uint160(0), null, null))); var controller = new SmartContractWalletController( this.broadcasterManager.Object, this.callDataSerializer.Object, this.connectionManager.Object, this.loggerFactory.Object, this.network, this.receiptRepository.Object, this.walletManager.Object, this.smartContractTransactionService.Object); var request = new GetHistoryRequest { Address = address.Address, WalletName = walletName, Skip = toSkip, Take = toTake }; IActionResult result = controller.GetHistory(request); JsonResult viewResult = Assert.IsType <JsonResult>(result); var model = viewResult.Value as IEnumerable <ContractTransactionItem>; Assert.NotNull(model); Assert.Equal(toTake, model.Count()); Assert.Equal(new uint256(toSkip), model.ElementAt(toTake - 1).Hash); Assert.Equal(new uint256(toSkip + toTake - 1), model.ElementAt(0).Hash); }
public void SendAndReceiveSmartContractTransactionsUsingController() { using (NodeBuilder builder = NodeBuilder.Create(this)) { CoreNode scSender = builder.CreateSmartContractPowNode(); CoreNode scReceiver = builder.CreateSmartContractPowNode(); builder.StartAll(); scSender.NotInIBD(); scReceiver.NotInIBD(); int maturity = (int)scReceiver.FullNode.Network.Consensus.CoinbaseMaturity; scSender.FullNode.WalletManager().CreateWallet(Password, WalletName, Passphrase); scReceiver.FullNode.WalletManager().CreateWallet(Password, WalletName, Passphrase); HdAddress addr = TestHelper.MineBlocks(scSender, WalletName, Password, AccountName, maturity + 5).AddressUsed; TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(scSender)); int spendable = GetSpendableBlocks(maturity + 5, maturity); var total = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount); Assert.Equal(Money.COIN * spendable * 50, total); SmartContractsController senderSmartContractsController = scSender.FullNode.NodeService <SmartContractsController>(); SmartContractWalletController senderWalletController = scSender.FullNode.NodeService <SmartContractWalletController>(); SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/StorageDemo.cs"); Assert.True(compilationResult.Success); var buildRequest = new BuildCreateContractTransactionRequest { AccountName = AccountName, GasLimit = "10000", GasPrice = "1", ContractCode = compilationResult.Compilation.ToHexString(), FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; JsonResult result = (JsonResult)senderSmartContractsController.BuildCreateSmartContractTransaction(buildRequest); var response = (BuildCreateContractTransactionResponse)result.Value; scSender.CreateRPCClient().AddNode(scReceiver.Endpoint, true); SmartContractSharedSteps.SendTransaction(scSender, scReceiver, senderWalletController, response.Hex); TestHelper.MineBlocks(scReceiver, WalletName, Password, AccountName, 2); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender)); // Check wallet history is updating correctly. result = (JsonResult)senderWalletController.GetHistory(new WalletHistoryRequest { AccountName = AccountName, WalletName = WalletName }); var walletHistoryModel = (WalletHistoryModel)result.Value; Assert.Single(walletHistoryModel.AccountsHistoryModel.First().TransactionsHistory.Where(x => x.Type == TransactionItemType.Send)); // Check receipt was stored and can be retrieved. var receiptResponse = (ReceiptResponse)((JsonResult)senderSmartContractsController.GetReceipt(response.TransactionId.ToString())).Value; Assert.True(receiptResponse.Success); Assert.Equal(response.NewContractAddress, receiptResponse.NewContractAddress); Assert.Null(receiptResponse.To); Assert.Equal(addr.Address, receiptResponse.From); string storageRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "TestSave", DataType = SmartContractDataType.String })).Value; Assert.Equal("Hello, smart contract world!", storageRequestResult); string ownerRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "Owner", DataType = SmartContractDataType.Address })).Value; Assert.NotEmpty(ownerRequestResult); string counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "Counter", DataType = SmartContractDataType.Int })).Value; Assert.Equal("12345", counterRequestResult); var callRequest = new BuildCallContractTransactionRequest { AccountName = AccountName, GasLimit = "10000", GasPrice = "1", Amount = "0", MethodName = "Increment", ContractAddress = response.NewContractAddress, FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; result = (JsonResult)senderSmartContractsController.BuildCallSmartContractTransaction(callRequest); var callResponse = (BuildCallContractTransactionResponse)result.Value; SmartContractSharedSteps.SendTransaction(scSender, scReceiver, senderWalletController, callResponse.Hex); TestHelper.MineBlocks(scReceiver, WalletName, Password, AccountName, 2); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender)); counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "Counter", DataType = SmartContractDataType.Int })).Value; Assert.Equal("12346", counterRequestResult); // Check receipt was stored and can be retrieved. receiptResponse = (ReceiptResponse)((JsonResult)senderSmartContractsController.GetReceipt(callResponse.TransactionId.ToString())).Value; Assert.True(receiptResponse.Success); Assert.Null(receiptResponse.NewContractAddress); Assert.Equal(response.NewContractAddress, receiptResponse.To); Assert.Equal(addr.Address, receiptResponse.From); // Check wallet history again result = (JsonResult)senderWalletController.GetHistory(new WalletHistoryRequest { AccountName = AccountName, WalletName = WalletName }); walletHistoryModel = (WalletHistoryModel)result.Value; Assert.Equal(2, walletHistoryModel.AccountsHistoryModel.First().TransactionsHistory.Where(x => x.Type == TransactionItemType.Send).Count()); // Test serialization // TODO: When refactoring integration tests, move this to the one place and test all types, from method param to storage to serialization. var serializationRequest = new BuildCallContractTransactionRequest { AccountName = AccountName, GasLimit = "10000", GasPrice = "1", Amount = "0", MethodName = "TestSerializer", ContractAddress = response.NewContractAddress, FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; result = (JsonResult)senderSmartContractsController.BuildCallSmartContractTransaction(serializationRequest); var serializationResponse = (BuildCallContractTransactionResponse)result.Value; SmartContractSharedSteps.SendTransaction(scSender, scReceiver, senderWalletController, serializationResponse.Hex); TestHelper.MineBlocks(scReceiver, WalletName, Password, AccountName, 2); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender)); // Would have only saved if execution completed successfully counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "Int32", DataType = SmartContractDataType.Int })).Value; Assert.Equal("12345", counterRequestResult); } }
public static void SendTransactionAndMine(CoreNode scSender, CoreNode scReceiver, SmartContractWalletController senderWalletController, string responseHex) { senderWalletController.SendTransaction(new SendTransactionRequest { Hex = responseHex }); TestHelper.WaitLoop(() => scReceiver.CreateRPCClient().GetRawMempool().Length > 0); scReceiver.GenerateStratisWithMiner(2); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender)); }
public void SendAndReceiveSmartContractTransactionsUsingController() { using (SmartContractNodeBuilder builder = SmartContractNodeBuilder.Create(this)) { CoreNode scSender = builder.CreateSmartContractPowNode().WithWallet().Start(); CoreNode scReceiver = builder.CreateSmartContractPowNode().WithWallet().Start(); int maturity = (int)scReceiver.FullNode.Network.Consensus.CoinbaseMaturity; HdAddress addr = TestHelper.MineBlocks(scSender, maturity + 5).AddressUsed; int spendable = GetSpendableBlocks(maturity + 5, maturity); var total = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount); Assert.Equal(Money.COIN * spendable * 50, total); SmartContractsController senderSmartContractsController = scSender.FullNode.NodeService <SmartContractsController>(); SmartContractWalletController senderWalletController = scSender.FullNode.NodeService <SmartContractWalletController>(); ContractCompilationResult compilationResult = ContractCompiler.CompileFile("SmartContracts/StorageDemo.cs"); Assert.True(compilationResult.Success); Gas gasLimit = (Gas)(SmartContractFormatRule.GasLimitMaximum / 2); var buildRequest = new BuildCreateContractTransactionRequest { AccountName = AccountName, GasLimit = gasLimit, GasPrice = SmartContractMempoolValidator.MinGasPrice, ContractCode = compilationResult.Compilation.ToHexString(), FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; JsonResult result = (JsonResult)senderSmartContractsController.BuildCreateSmartContractTransaction(buildRequest); var response = (BuildCreateContractTransactionResponse)result.Value; TestHelper.Connect(scSender, scReceiver); SmartContractSharedSteps.SendTransaction(scSender, scReceiver, senderWalletController, response.Hex); TestHelper.MineBlocks(scReceiver, 2); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender)); // Check receipt was stored and can be retrieved. var receiptResponse = (ReceiptResponse)((JsonResult)senderSmartContractsController.GetReceipt(response.TransactionId.ToString())).Value; Assert.True(receiptResponse.Success); Assert.Equal(response.NewContractAddress, receiptResponse.NewContractAddress); Assert.Null(receiptResponse.To); Assert.Equal(addr.Address, receiptResponse.From); string storageRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "TestSave", DataType = MethodParameterDataType.String })).Value; Assert.Equal("Hello, smart contract world!", storageRequestResult); string ownerRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "Owner", DataType = MethodParameterDataType.Address })).Value; Assert.NotEmpty(ownerRequestResult); string counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "Counter", DataType = MethodParameterDataType.Int })).Value; Assert.Equal("12345", counterRequestResult); var callRequest = new BuildCallContractTransactionRequest { AccountName = AccountName, GasLimit = gasLimit, GasPrice = SmartContractMempoolValidator.MinGasPrice, Amount = "0", MethodName = "Increment", ContractAddress = response.NewContractAddress, FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; result = (JsonResult)senderSmartContractsController.BuildCallSmartContractTransaction(callRequest); var callResponse = (BuildCallContractTransactionResponse)result.Value; SmartContractSharedSteps.SendTransaction(scSender, scReceiver, senderWalletController, callResponse.Hex); TestHelper.MineBlocks(scReceiver, 2); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender)); counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "Counter", DataType = MethodParameterDataType.Int })).Value; Assert.Equal("12346", counterRequestResult); // Check receipt was stored and can be retrieved. receiptResponse = (ReceiptResponse)((JsonResult)senderSmartContractsController.GetReceipt(callResponse.TransactionId.ToString())).Value; Assert.True(receiptResponse.Success); Assert.Null(receiptResponse.NewContractAddress); Assert.Equal(response.NewContractAddress, receiptResponse.To); Assert.Equal(addr.Address, receiptResponse.From); // Test serialization // TODO: When refactoring integration tests, move this to the one place and test all types, from method param to storage to serialization. var serializationRequest = new BuildCallContractTransactionRequest { AccountName = AccountName, GasLimit = gasLimit, GasPrice = SmartContractMempoolValidator.MinGasPrice, Amount = "0", MethodName = "TestSerializer", ContractAddress = response.NewContractAddress, FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; result = (JsonResult)senderSmartContractsController.BuildCallSmartContractTransaction(serializationRequest); var serializationResponse = (BuildCallContractTransactionResponse)result.Value; SmartContractSharedSteps.SendTransaction(scSender, scReceiver, senderWalletController, serializationResponse.Hex); TestHelper.MineBlocks(scReceiver, 2); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender)); // Would have only saved if execution completed successfully counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress.ToString(), StorageKey = "Int32", DataType = MethodParameterDataType.Int })).Value; Assert.Equal("12345", counterRequestResult); } }
public void SendAndReceiveLocalSmartContractPropertyCallTransactionsUsingController() { using (SmartContractNodeBuilder builder = SmartContractNodeBuilder.Create(this)) { CoreNode scSender = builder.CreateSmartContractPowNode().WithWallet().Start(); CoreNode scReceiver = builder.CreateSmartContractPowNode().WithWallet().Start(); int maturity = (int)scReceiver.FullNode.Network.Consensus.CoinbaseMaturity; HdAddress addr = TestHelper.MineBlocks(scSender, maturity + 5).AddressUsed; int spendable = GetSpendableBlocks(maturity + 5, maturity); var total = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount); Assert.Equal(Money.COIN * spendable * 50, total); SmartContractsController senderSmartContractsController = scSender.FullNode.NodeService <SmartContractsController>(); SmartContractWalletController senderWalletController = scSender.FullNode.NodeService <SmartContractWalletController>(); ContractCompilationResult compilationResult = ContractCompiler.CompileFile("SmartContracts/StorageDemo.cs"); Assert.True(compilationResult.Success); Gas gasLimit = (Gas)(SmartContractFormatRule.GasLimitMaximum / 2); var buildRequest = new BuildCreateContractTransactionRequest { AccountName = AccountName, GasLimit = gasLimit, GasPrice = SmartContractMempoolValidator.MinGasPrice, ContractCode = compilationResult.Compilation.ToHexString(), FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; JsonResult result = (JsonResult)senderSmartContractsController.BuildCreateSmartContractTransaction(buildRequest); var response = (BuildCreateContractTransactionResponse)result.Value; TestHelper.Connect(scSender, scReceiver); SmartContractSharedSteps.SendTransaction(scSender, scReceiver, senderWalletController, response.Hex); TestHelper.MineBlocks(scReceiver, 2); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender)); // Make a call request where the MethodName is the name of a property var callRequest = new BuildCallContractTransactionRequest { AccountName = AccountName, GasLimit = gasLimit, GasPrice = SmartContractMempoolValidator.MinGasPrice, Amount = "0", MethodName = "Counter", ContractAddress = response.NewContractAddress, FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; result = (JsonResult)senderSmartContractsController.LocalCallSmartContractTransaction(callRequest); var callResponse = (ILocalExecutionResult)result.Value; // Check that the locally executed transaction returns the correct results Assert.Equal(12345, callResponse.Return); Assert.False(callResponse.Revert); Assert.True(callResponse.GasConsumed > 0); Assert.Null(callResponse.ErrorMessage); Assert.NotNull(callResponse.InternalTransfers); TestHelper.MineBlocks(scReceiver, 2); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender)); } }
public void SendAndReceiveLocalSmartContractTransactionsUsingController() { using (SmartContractNodeBuilder builder = SmartContractNodeBuilder.Create(this)) { CoreNode scSender = builder.CreateSmartContractPowNode().WithWallet().Start(); CoreNode scReceiver = builder.CreateSmartContractPowNode().WithWallet().Start(); int maturity = (int)scReceiver.FullNode.Network.Consensus.CoinbaseMaturity; HdAddress addr = TestHelper.MineBlocks(scSender, maturity + 5).AddressUsed; int spendable = GetSpendableBlocks(maturity + 5, maturity); var total = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount); Assert.Equal(Money.COIN * spendable * 50, total); SmartContractsController senderSmartContractsController = scSender.FullNode.NodeService <SmartContractsController>(); SmartContractWalletController senderWalletController = scSender.FullNode.NodeService <SmartContractWalletController>(); ContractCompilationResult compilationResult = ContractCompiler.CompileFile("SmartContracts/StorageDemo.cs"); Assert.True(compilationResult.Success); Gas gasLimit = (Gas)(SmartContractFormatRule.GasLimitMaximum / 2); var buildRequest = new BuildCreateContractTransactionRequest { AccountName = AccountName, GasLimit = gasLimit.ToString(), GasPrice = SmartContractMempoolValidator.MinGasPrice.ToString(), ContractCode = compilationResult.Compilation.ToHexString(), FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; JsonResult result = (JsonResult)senderSmartContractsController.BuildCreateSmartContractTransaction(buildRequest); var response = (BuildCreateContractTransactionResponse)result.Value; TestHelper.Connect(scSender, scReceiver); SmartContractSharedSteps.SendTransaction(scSender, scReceiver, senderWalletController, response.Hex); TestHelper.MineBlocks(scReceiver, 2); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender)); // Check wallet history is updating correctly. result = (JsonResult)senderWalletController.GetHistory(new WalletHistoryRequest { AccountName = AccountName, WalletName = WalletName }); var walletHistoryModel = (WalletHistoryModel)result.Value; Assert.Single(walletHistoryModel.AccountsHistoryModel.First().TransactionsHistory.Where(x => x.Type == TransactionItemType.Send)); string counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress, StorageKey = "Counter", DataType = MethodParameterDataType.Int })).Value; Assert.Equal("12345", counterRequestResult); var callRequest = new BuildCallContractTransactionRequest { AccountName = AccountName, GasLimit = gasLimit.ToString(), GasPrice = SmartContractMempoolValidator.MinGasPrice.ToString(), Amount = "0", MethodName = "Increment", ContractAddress = response.NewContractAddress, FeeAmount = "0.001", Password = Password, WalletName = WalletName, Sender = addr.Address }; result = (JsonResult)senderSmartContractsController.LocalCallSmartContractTransaction(callRequest); var callResponse = (ILocalExecutionResult)result.Value; // Check that the locally executed transaction returns the correct results Assert.Equal(12346, callResponse.Return); Assert.False(callResponse.Revert); Assert.True(callResponse.GasConsumed > 0); Assert.Null(callResponse.ErrorMessage); Assert.NotNull(callResponse.InternalTransfers); TestHelper.MineBlocks(scReceiver, 2); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender)); // Check that the on-chain storage has not changed after mining counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest { ContractAddress = response.NewContractAddress, StorageKey = "Counter", DataType = MethodParameterDataType.Int })).Value; Assert.Equal("12345", counterRequestResult); // Check wallet history again to make sure nothing has changed result = (JsonResult)senderWalletController.GetHistory(new WalletHistoryRequest { AccountName = AccountName, WalletName = WalletName }); walletHistoryModel = (WalletHistoryModel)result.Value; Assert.Single(walletHistoryModel.AccountsHistoryModel.First().TransactionsHistory.Where(x => x.Type == TransactionItemType.Send)); } }