public void CanSignRawTransaction() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(); builder.StartAll(); node.Generate(101); var tx = new Transaction(); tx.Outputs.Add(new TxOut(Money.Coins(1.0m), new Key())); var funded = node.CreateRPCClient().FundRawTransaction(tx); var signed = node.CreateRPCClient().SignRawTransaction(funded.Transaction); node.CreateRPCClient().SendRawTransaction(signed); } }
public void CanGetPeersInfo() { using (var builder = NodeBuilderEx.Create()) { var nodeA = builder.CreateNode(); builder.StartAll(); var rpc = nodeA.CreateRPCClient(); using (var node = nodeA.CreateNodeClient()) { node.VersionHandshake(); var peers = rpc.GetPeersInfo(); Assert.NotEmpty(peers); } } }
public void CanGetMemPool() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(); var rpc = node.CreateRPCClient(); builder.StartAll(); node.Generate(101); var txid = rpc.SendToAddress(new Key().PubKey.GetAddress(rpc.Network), Money.Coins(1.0m), "hello", "world"); var memPoolInfo = rpc.GetMemPool(); Assert.NotNull(memPoolInfo); Assert.Equal(1, memPoolInfo.Size); } }
public void CanSendCommand() { using (var builder = NodeBuilderEx.Create()) { var rpc = builder.CreateNode().CreateRPCClient(); builder.StartAll(); var response = rpc.SendCommand(RPCOperations.getblockchaininfo); Assert.NotNull(response.Result); var copy = RPCCredentialString.Parse(rpc.CredentialString.ToString()); copy.Server = rpc.Address.AbsoluteUri; rpc = new RPCClient(copy, null as string, builder.Network); response = rpc.SendCommand(RPCOperations.getblockchaininfo); Assert.NotNull(response.Result); } }
public void CanDownloadBlock() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(true).CreateNodeClient(); node.VersionHandshake(); node.SendMessageAsync(new GetDataPayload(new InventoryVector() { Hash = Network.RegTest.GenesisHash, Type = InventoryType.MSG_BLOCK })); var block = node.ReceiveMessage <BlockPayload>(); Assert.True(block.Object.CheckMerkleRoot()); } }
public void CanParseBlock() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(); builder.StartAll(); var rpc = node.CreateRPCClient(); rpc.Generate(10); var hash = rpc.GetBestBlockHash(); var b = rpc.GetBlock(hash); Assert.NotNull(b); Assert.Equal(hash, b.GetHash()); new ConcurrentChain(builder.Network); } }
public void CanDownloadHeaders() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(true).CreateNodeClient(); builder.Nodes[0].Generate(50); node.VersionHandshake(); var begin = node.Counter.Snapshot(); var result = node.GetChain(); var end = node.Counter.Snapshot(); var diff = end - begin; Assert.True(node.PeerVersion.StartHeight <= result.Height); var subChain = node.GetChain(result.GetBlock(10).HashBlock); Assert.Equal(10, subChain.Height); } }
public void CanGetTransactionsFromMemPool() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(); node.ConfigParameters.Add("whitelist", "127.0.0.1"); node.Start(); var rpc = node.CreateRPCClient(); rpc.Generate(101); rpc.SendToAddress(new Key().PubKey.GetAddress(ScriptPubKeyType.Legacy, Network.RegTest), Money.Coins(1.0m)); var client = node.CreateNodeClient(); client.VersionHandshake(); var transactions = client.GetMempoolTransactions(); Assert.True(transactions.Length == 1); } }
public void CanDownloadBlocks() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(true).CreateNodeClient(); builder.Nodes[0].Generate(50); var chain = node.GetChain(); chain.SetTip(chain.GetBlock(9)); var blocks = node.GetBlocks(chain.ToEnumerable(true).Select(c => c.HashBlock)).ToList(); foreach (var block in blocks) { Assert.True(block.CheckMerkleRoot()); } Assert.Equal(10, blocks.Count); } }
public void CanSignUsingTaproot() { using (var nodeBuilder = NodeBuilderEx.Create()) { var rpc = nodeBuilder.CreateNode().CreateRPCClient(); nodeBuilder.StartAll(); rpc.Generate(102); var key = new Key(); var addr = key.PubKey.GetTaprootFullPubKey().GetAddress(nodeBuilder.Network); foreach (var anyoneCanPay in new[] { false, true }) { rpc.Generate(1); foreach (var hashType in new[] { TaprootSigHash.All, TaprootSigHash.Default, TaprootSigHash.None, TaprootSigHash.Single }) { if (hashType == TaprootSigHash.Default && anyoneCanPay) { continue; // Not supported by btc } var txid = rpc.SendToAddress(addr, Money.Coins(1.0m)); var tx = rpc.GetRawTransaction(txid); var spentOutput = tx.Outputs.AsIndexedOutputs().First(o => o.TxOut.ScriptPubKey == addr.ScriptPubKey); var spender = nodeBuilder.Network.CreateTransaction(); spender.Inputs.Add(new OutPoint(tx, spentOutput.N)); var dest = rpc.GetNewAddress(); spender.Outputs.Add(Money.Coins(0.7m), dest); spender.Outputs.Add(Money.Coins(0.2999000m), addr); var sighash = hashType | (anyoneCanPay ? TaprootSigHash.AnyoneCanPay : 0); var hash = spender.GetSignatureHashTaproot(new[] { spentOutput.TxOut }, new TaprootExecutionData(0) { SigHash = sighash }); var sig = key.SignTaprootKeySpend(hash, sighash); Assert.True(addr.PubKey.VerifySignature(hash, sig.SchnorrSignature)); spender.Inputs[0].WitScript = new WitScript(Op.GetPushOp(sig.ToBytes())); rpc.SendRawTransaction(spender); } } } }
public void CanCalculateChainWork() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(); var client = node.CreateRESTClient(); var rpc = node.CreateRPCClient(); builder.StartAll(); var info = client.GetChainInfoAsync().Result; Assert.Equal("regtest", info.Chain); Assert.Equal(new ChainedBlock(Network.RegTest.GetGenesis().Header, 0).GetChainWork(false), info.ChainWork); rpc.Generate(10); var chain = node.CreateNodeClient().GetChain(); info = client.GetChainInfoAsync().Result; Assert.Equal(info.ChainWork, chain.Tip.GetChainWork(false)); } }
public async Task CanGetBlockchainInfo() { using (var builder = NodeBuilderEx.Create()) { var rpc = builder.CreateNode().CreateRPCClient(); builder.StartAll(); var response = await rpc.GetBlockchainInfoAsync(); Assert.Equal(builder.Network, response.Chain); Assert.Equal(builder.Network.GetGenesis().GetHash(), response.BestBlockHash); Assert.Contains(response.Bip9SoftForks, x => x.Name == "segwit"); Assert.Contains(response.Bip9SoftForks, x => x.Name == "csv"); Assert.Contains(response.SoftForks, x => x.Bip == "bip34"); Assert.Contains(response.SoftForks, x => x.Bip == "bip65"); Assert.Contains(response.SoftForks, x => x.Bip == "bip66"); } }
public void CanSyncWithoutPoW() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(); builder.StartAll(); node.Generate(100); var nodeClient = node.CreateNodeClient(); nodeClient.VersionHandshake(); ConcurrentChain chain = new ConcurrentChain(builder.Network); nodeClient.SynchronizeChain(chain, new Protocol.SynchronizeChainOptions() { SkipPoWCheck = true }); Assert.Equal(100, chain.Height); } }
public void CanGetBlockHeader() { using (var builder = NodeBuilderEx.Create()) { var client = builder.CreateNode().CreateRESTClient(); var rpc = builder.Nodes[0].CreateRPCClient(); builder.StartAll(); rpc.Generate(2); var result = client.GetBlockHeadersAsync(RegNetGenesisBlock.GetHash(), 3).Result; var headers = result.ToArray(); var last = headers.Last(); Assert.Equal(3, headers.Length); Assert.Equal(rpc.GetBestBlockHash(), last.GetHash()); Assert.Equal(headers[1].GetHash(), last.HashPrevBlock); Assert.Equal(RegNetGenesisBlock.GetHash(), headers[1].HashPrevBlock); } }
public void HasCorrectGenesisBlock() { using (var builder = NodeBuilderEx.Create()) { var rpc = builder.CreateNode().CreateRPCClient(); builder.StartAll(); var genesis = rpc.GetBlock(0); if (builder.Network == Altcoins.Liquid.Instance.Regtest) { Assert.Contains(genesis.Transactions.SelectMany(t => t.Outputs).OfType <ElementsTxOut>(), o => o.IsPeggedAsset == true && o.ConfidentialValue.Amount != null && o.ConfidentialValue.Amount != Money.Zero); } var actual = genesis.GetHash(); var calculatedGenesis = builder.Network.GetGenesis().GetHash(); Assert.Equal(calculatedGenesis, actual); Assert.Equal(rpc.GetBlockHash(0), calculatedGenesis); } }
public void ThrowsRestApiClientException() { using (var builder = NodeBuilderEx.Create()) { var client = builder.CreateNode().CreateRESTClient(); builder.StartAll(); var unexistingBlockId = uint256.Parse("100000006c02c8ea6e4ff69651f7fcde348fb9d557a06e6957b65552002a7820"); Assert.Throws <RestApiException>(() => client.GetBlock(unexistingBlockId)); var txId = uint256.Parse("7569ce92f93f9afd51ffae243e04076be4e5088cf69501aab6de9ede5c331402"); Assert.Throws <RestApiException>(() => client.GetTransaction(txId)); var result = client.GetBlockHeaders(unexistingBlockId, 3); var headers = result.ToArray(); Assert.Empty(headers); } }
public void CanGetMemPool() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(); var rpc = node.CreateRPCClient(); node.ConfigParameters.Add("whitelist", "127.0.0.1"); node.Start(); rpc.Generate(102); for (int i = 0; i < 2; i++) { node.CreateRPCClient().SendToAddress(new Key().PubKey.GetAddress(ScriptPubKeyType.Legacy, Network.RegTest), Money.Coins(1.0m)); } var client = node.CreateNodeClient(); var txIds = client.GetMempool(); Assert.True(txIds.Length == 2); } }
public void CanGetPrivateKeysFromAccount() { using (var builder = NodeBuilderEx.Create()) { var rpc = builder.CreateNode().CreateRPCClient(); builder.StartAll(); Key key = new Key(); rpc.ImportAddress(key.PubKey.GetAddress(builder.Network), TestAccount, false); BitcoinAddress address = rpc.GetAccountAddress(TestAccount); BitcoinSecret secret = rpc.DumpPrivKey(address); BitcoinSecret secret2 = rpc.GetAccountSecret(TestAccount); Assert.Equal(secret.ToString(), secret2.ToString()); var p2pkh = secret.GetAddress().ToString(); var wit = secret.PubKey.WitHash.GetAddress(builder.Network).ToString(); var p2shwit = secret.PubKey.WitHash.ScriptPubKey.GetScriptAddress(builder.Network).ToString(); Assert.True(address.ToString() == p2pkh || address.ToString() == wit || address.ToString() == p2shwit); } }
public void CanGetChainsConcurrenty() { using (var builder = NodeBuilderEx.Create()) { bool generating = true; var node = builder.CreateNode(true); var rpc = node.CreateRPCClient(); Task.Run(() => { rpc.Generate(600); generating = false; }); var nodeClient = node.CreateNodeClient(); nodeClient.PollHeaderDelay = TimeSpan.FromSeconds(2); nodeClient.VersionHandshake(); Random rand = new Random(); Thread.Sleep(1000); var chains = Enumerable.Range(0, 5) .Select(_ => Task.Factory.StartNew(() => { Thread.Sleep(rand.Next(0, 1000)); return(nodeClient.GetChain()); })) .Select(t => t.Result) .ToArray(); while (generating) { SyncAll(nodeClient, rand, chains); } SyncAll(nodeClient, rand, chains); foreach (var c in chains) { Assert.Equal(600, c.Height); } var chainNoHeader = nodeClient.GetChain(new SynchronizeChainOptions() { SkipPoWCheck = true, StripHeaders = true }); Assert.False(chainNoHeader.Tip.HasHeader); } }
public void CanGetBlocksWithProtocol() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(true); var rpc = node.CreateRPCClient(); rpc.Generate(50); var client = node.CreateNodeClient(); var chain = client.GetChain(); var blocks = client.GetBlocks(chain.GetBlock(20).HashBlock).ToArray(); Assert.Equal(20, blocks.Length); Assert.Equal(chain.GetBlock(20).HashBlock, blocks.Last().Header.GetHash()); blocks = client.GetBlocksFromFork(chain.GetBlock(45)).ToArray(); Assert.Equal(5, blocks.Length); Assert.Equal(chain.GetBlock(50).HashBlock, blocks.Last().Header.GetHash()); Assert.Equal(chain.GetBlock(46).HashBlock, blocks.First().Header.GetHash()); } }
public void SynchronizeChainSurviveReorg() { using (var builder = NodeBuilderEx.Create()) { ConcurrentChain chain = new ConcurrentChain(Network.RegTest); var node1 = builder.CreateNode(true); node1.Generate(10); node1.CreateNodeClient().SynchronizeChain(chain); Assert.Equal(10, chain.Height); var node2 = builder.CreateNode(true); node2.Generate(12); var node2c = node2.CreateNodeClient(); node2c.PollHeaderDelay = TimeSpan.FromSeconds(2); node2c.SynchronizeChain(chain); Assert.Equal(12, chain.Height); } }
public void CanCancelConnection() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(true); CancellationTokenSource cts = new CancellationTokenSource(); cts.Cancel(); try { var client = Node.Connect(Network.RegTest, "127.0.0.1:" + node.ProtocolPort.ToString(), new NodeConnectionParameters() { ConnectCancellation = cts.Token }); Assert.False(true, "Should have thrown"); } catch (OperationCanceledException) { } } }
public void InvalidateBlockToRPC() { using (var builder = NodeBuilderEx.Create()) { var rpc = builder.CreateNode().CreateRPCClient(); builder.StartAll(); var generatedBlockHashes = rpc.Generate(2); var tip = rpc.GetBestBlockHash(); var bestBlockHash = generatedBlockHashes.Last(); Assert.Equal(tip, bestBlockHash); rpc.InvalidateBlock(bestBlockHash); tip = rpc.GetBestBlockHash(); Assert.NotEqual(tip, bestBlockHash); bestBlockHash = generatedBlockHashes.First(); Assert.Equal(tip, bestBlockHash); } }
public void CanAuthWithCookieFile() { #if NOFILEIO Assert.Throws <NotSupportedException>(() => new RPCClient(Network.Main)); #else using (var builder = NodeBuilderEx.Create()) { //Sanity check that it does not throw #pragma warning disable CS0618 new RPCClient(new NetworkCredential("toto", "tata:blah"), "localhost:10393", Network.Main); var node = builder.CreateNode(); node.CookieAuth = true; node.Start(); var rpc = node.CreateRPCClient(); rpc.GetBlockCount(); node.Restart(); rpc.GetBlockCount(); new RPCClient("cookiefile=data/tx_valid.json", new Uri("http://localhost/"), Network.RegTest); new RPCClient("cookiefile=data/efpwwie.json", new Uri("http://localhost/"), Network.RegTest); rpc = new RPCClient("bla:bla", null as Uri, Network.RegTest); Assert.Equal("http://127.0.0.1:" + Network.RegTest.RPCPort + "/", rpc.Address.AbsoluteUri); rpc = node.CreateRPCClient(); rpc = rpc.PrepareBatch(); var blockCountAsync = rpc.GetBlockCountAsync(); rpc.SendBatch(); var blockCount = blockCountAsync.GetAwaiter().GetResult(); node.Restart(); rpc = rpc.PrepareBatch(); blockCountAsync = rpc.GetBlockCountAsync(); rpc.SendBatch(); blockCount = blockCountAsync.GetAwaiter().GetResult(); rpc = new RPCClient("bla:bla", "http://toto/", Network.RegTest); } #endif }
public void RPCSendRPCException() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(); builder.StartAll(); var rpcClient = node.CreateRPCClient(); try { rpcClient.SendCommand("whatever"); Assert.False(true, "Should have thrown"); } catch (RPCException ex) { if (ex.RPCCode != RPCErrorCode.RPC_METHOD_NOT_FOUND) { Assert.False(true, "Should have thrown RPC_METHOD_NOT_FOUND"); } } } }
public void CanRBFTransaction() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(); var rpc = node.CreateRPCClient(); builder.StartAll(); node.Generate(101); var key = new Key(); var address = key.PubKey.GetAddress(rpc.Network); var txid = rpc.SendToAddress(address, Money.Coins(2), null, null, false, true); var txbumpid = rpc.BumpFee(txid); var blocks = rpc.Generate(1); var block = rpc.GetBlock(blocks.First()); Assert.DoesNotContain(block.Transactions, x => x.GetHash() == txid); Assert.Contains(block.Transactions, x => x.GetHash() == txbumpid.TransactionId); } }
public void CanScanTxoutSet() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(); var rpc = node.CreateRPCClient(); builder.StartAll(); node.Generate(101); var key = new Key(); var dest = key.PubKey.Hash.GetAddress(builder.Network); var txid = rpc.SendToAddress(dest, Money.Coins(1.0m)); var funding = rpc.GetRawTransaction(txid); var coin = funding.Outputs.AsCoins().Single(o => o.ScriptPubKey == dest.ScriptPubKey); var result = rpc.StartScanTxoutSet(new ScanTxoutSetObject(ScanTxoutDescriptor.Addr(dest))); Assert.Equal(101, result.SearchedItems); Assert.True(result.Success); Assert.Empty(result.Outputs); Assert.Equal(Money.Zero, result.TotalAmount); Assert.False(rpc.AbortScanTxoutSet()); Assert.Null(rpc.GetStatusScanTxoutSet()); rpc.Generate(1); result = rpc.StartScanTxoutSet(new ScanTxoutSetObject(ScanTxoutDescriptor.Addr(dest))); Assert.True(result.SearchedItems > 100); Assert.True(result.Success); Assert.Single(result.Outputs); Assert.Equal(102, result.Outputs[0].Height); Assert.Equal(Money.Coins(1.0m), result.TotalAmount); Assert.False(rpc.AbortScanTxoutSet()); Assert.Null(rpc.GetStatusScanTxoutSet()); } }
public void DoesRPCCapabilitiesWellAdvertised() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(); builder.StartAll(); node.Generate(builder.Network.Consensus.CoinbaseMaturity + 1); var rpc = node.CreateRPCClient(); rpc.ScanRPCCapabilities(); Assert.NotNull(rpc.Capabilities); CheckCapabilities(rpc, "getnetworkinfo", rpc.Capabilities.SupportGetNetworkInfo); CheckCapabilities(rpc, "scantxoutset", rpc.Capabilities.SupportScanUTXOSet); CheckCapabilities(rpc, "signrawtransactionwithkey", rpc.Capabilities.SupportSignRawTransactionWith); CheckCapabilities(rpc, "estimatesmartfee", rpc.Capabilities.SupportEstimateSmartFee); try { var address = rpc.GetNewAddress(new GetNewAddressRequest() { AddressType = AddressType.Bech32 }); // If this fail, rpc support segwit bug you said it does not Assert.Equal(rpc.Capabilities.SupportSegwit, address.ScriptPubKey.IsWitness); if (rpc.Capabilities.SupportSegwit) { Assert.True(builder.Network.Consensus.SupportSegwit, "The node RPC support segwit, but Network.Consensus.SupportSegwit is set to false"); rpc.SendToAddress(address, Money.Coins(1.0m)); } else { Assert.False(builder.Network.Consensus.SupportSegwit, "The node RPC does not support segwit, but Network.Consensus.SupportSegwit is set to true (This error can be normal if you are using a old node version)"); } } catch (RPCException) when(!rpc.Capabilities.SupportSegwit) { } } }
public async Task CanMaskExceptionThrownByMessageReceivers() { using (var builder = NodeBuilderEx.Create()) { var node = builder.CreateNode(); var rpc = node.CreateRPCClient(); node.Start(); var nodeClient = node.CreateNodeClient(); TaskCompletionSource <bool> ok = new TaskCompletionSource <bool>(); nodeClient.VersionHandshake(); nodeClient.UncaughtException += (s, m) => { ok.TrySetResult(m.GetType() == typeof(Exception) && m.Message == "test"); }; nodeClient.MessageReceived += (s, m) => { throw new Exception("test"); }; nodeClient.SendMessage(new PingPayload()); Assert.True(await ok.Task); } }
public void CanCalculateTransactionHash() { using (var builder = NodeBuilderEx.Create()) { var rpc = builder.CreateNode().CreateRPCClient(); builder.StartAll(); var blockHash = rpc.Generate(1)[0]; var block = rpc.GetBlock(blockHash); Transaction walletTx = null; try { walletTx = rpc.GetRawTransaction(block.Transactions[0].GetHash(), block.GetHash()); } // Some nodes does not support the blockid catch { walletTx = rpc.GetRawTransaction(block.Transactions[0].GetHash()); } Assert.Equal(walletTx.ToHex(), block.Transactions[0].ToHex()); } }