예제 #1
0
 public void EstimateSmartFee()
 {
     using (var builder = NodeBuilderEx.Create())
     {
         var node = builder.CreateNode();
         node.Start();
         node.Generate(101);
         var rpc = node.CreateRPCClient();
         Assert.Throws <NoEstimationException>(() => rpc.EstimateSmartFee(1));
         Assert.Equal(Money.Coins(50m), rpc.GetBalance(1, false));
         Assert.Equal(Money.Coins(50m), rpc.GetBalance());
     }
 }
예제 #2
0
 public void CanHandshake()
 {
     using (var builder = NodeBuilderEx.Create())
     {
         var seed = builder.CreateNode(true).CreateNodeClient();
         Assert.True(seed.State == NodeState.Connected);
         seed.VersionHandshake();
         Assert.True(seed.State == NodeState.HandShaked);
         seed.Disconnect();
         Assert.True(seed.State == NodeState.Offline);
         Assert.NotNull(seed.TimeOffset);
     }
 }
예제 #3
0
 public void CorrectCoinMaturity()
 {
     using (var builder = NodeBuilderEx.Create())
     {
         var node = builder.CreateNode();
         builder.StartAll();
         node.Generate(builder.Network.Consensus.CoinbaseMaturity);
         var rpc = node.CreateRPCClient();
         Assert.Equal(Money.Zero, rpc.GetBalance());
         node.Generate(1);
         Assert.NotEqual(Money.Zero, rpc.GetBalance());
     }
 }
예제 #4
0
        public void CanGetBlockFromRPC()
        {
            using (var builder = NodeBuilderEx.Create())
            {
                var rpc = builder.CreateNode().CreateRPCClient();
                builder.StartAll();
                var response = rpc.GetBlockHeader(0);
                AssertEx.CollectionEquals(Network.RegTest.GetGenesis().Header.ToBytes(), response.ToBytes());

                response = rpc.GetBlockHeader(0);
                Assert.Equal(Network.RegTest.GenesisHash, response.GetHash());
            }
        }
예제 #5
0
 public void CanGetRawMemPool()
 {
     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 ids  = rpc.GetRawMempool();
         Assert.Single(ids);
         Assert.Equal(txid, ids[0]);
     }
 }
예제 #6
0
 public void CanGetUTXOs()
 {
     using (var builder = NodeBuilderEx.Create())
     {
         var client = builder.CreateNode().CreateRESTClient();
         builder.StartAll();
         var txId     = uint256.Parse("3a3422dfd155f1d2ffc3e46cf978a9c5698c17c187f04cfa1b93358699c4ed3f");
         var outPoint = new OutPoint(txId, 0);
         var utxos    = client.GetUnspentOutputsAsync(new[] { outPoint }, false).Result;
         Assert.True(utxos.Bitmap[0]);
         Assert.False(utxos.Bitmap[1]);
         Assert.Empty(utxos.Outputs);
     }
 }
예제 #7
0
 public void CanGetTransaction()
 {
     using (var builder = NodeBuilderEx.Create())
     {
         var client = builder.CreateNode().CreateRESTClient();
         builder.StartAll();
         builder.Nodes[0].Generate(1);
         var block = builder.Nodes[0].CreateRPCClient().GetBestBlockHash();
         var txId  = builder.Nodes[0].CreateRPCClient().GetBlock(block).Transactions[0].GetHash();
         var tx    = client.GetTransactionAsync(txId).Result;
         Assert.True(tx.IsCoinBase);
         Assert.Equal(Money.Coins(50), tx.TotalOut);
     }
 }
예제 #8
0
        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);
            }
        }
예제 #9
0
 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);
     }
 }
예제 #10
0
 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);
         }
     }
 }
예제 #11
0
        public void CanParseAddress()
        {
            using (var builder = NodeBuilderEx.Create())
            {
                var node = builder.CreateNode();
                builder.StartAll();
                var addr  = node.CreateRPCClient().SendCommand(RPC.RPCOperations.getnewaddress).Result.ToString();
                var addr2 = BitcoinAddress.Create(addr, builder.Network).ToString();
                Assert.Equal(addr, addr2);

                var address = new Key().PubKey.GetAddress(builder.Network);
                var isValid = ((JObject)node.CreateRPCClient().SendCommand("validateaddress", address.ToString()).Result)["isvalid"].Value <bool>();
                Assert.True(isValid);
            }
        }
예제 #12
0
        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);
            }
        }
예제 #13
0
 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);
     }
 }
예제 #14
0
        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);
            }
        }
예제 #15
0
        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());
            }
        }
예제 #16
0
 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);
     }
 }
예제 #17
0
 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);
     }
 }
예제 #18
0
        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);
                    }
                }
            }
        }
예제 #19
0
 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);
     }
 }
예제 #20
0
 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));
     }
 }
예제 #21
0
        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");
            }
        }
예제 #22
0
        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);
            }
        }
예제 #23
0
 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);
     }
 }
예제 #24
0
 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);
     }
 }
예제 #25
0
 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);
     }
 }
예제 #26
0
        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);
            }
        }
예제 #27
0
        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());
            }
        }
예제 #28
0
        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);
            }
        }
예제 #29
0
        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);
            }
        }
예제 #30
0
 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)
         {
         }
     }
 }