public void EstimateFeeRateReturnsCorrectValues() { RPCClient rpc = this.rpcTestFixture.RpcClient; Assert.Throws<NoEstimationException>(() => rpc.EstimateFeeRate(1)); Assert.Equal(Money.Coins(50m), rpc.GetBalance(1, false)); Assert.Equal(Money.Coins(50m), rpc.GetBalance()); }
public void EnsureIsSetup(bool forceRenew = false) { if (forceRenew || RPCClient == null) { RPCClient = _Args.ConfigureRPCClient(Information.Network); try { RPCClient.EstimateFeeRate(2); } catch (Exception) { if (!this.Information.IsTest) { throw new ConfigException("Fee unavaialble, wait for your fullnode to have more fee information and retry again"); } } } }
private void DumpCoins(BitcoinAddress destination, IEnumerable <Coin> coins, IEnumerable <Key> keys) { var total = coins.Select(u => u.Amount).Sum(); var fee = Money.Zero; FeeRate feeRate = null; try { feeRate = RPCClient.EstimateFeeRate(6); //BCC having few fees, this will confirm fast } catch { if (RPCClient.Network == Network.RegTest) { feeRate = new FeeRate(Money.Satoshis(30), 1); } else { Logs.Main.LogWarning("Fee estimation unavailable, you need to wait Bitcoin Core to properly sync and retry to dump"); return; } } TransactionBuilder builder = new TransactionBuilder(); builder.AddCoins(coins); builder.Send(destination, total); try { builder.SendEstimatedFees(feeRate); builder.BuildTransaction(false); } catch (NotEnoughFundsException ex) { fee = (Money)ex.Missing; } builder = new TransactionBuilder(); builder.AddKeys(keys.ToArray()); builder.AddCoins(coins); builder.Send(destination, total - fee); builder.SendFees(fee); var dumpTransaction = builder.BuildTransaction(true, SigHash.ForkId | SigHash.All); Logs.Main.LogInformation("Dump transaction created " + dumpTransaction.ToHex()); Logs.Main.LogInformation("Dump transaction ID " + dumpTransaction.GetHash()); //repository.lock(coins.select(c => c.outpoint).toarray(), dumptransaction.gethash()); Thread.Sleep(1000); while (true) { Console.WriteLine("Are you sure to dump " + coins.Select(c => c.Amount).Sum().ToString() + " BCash coin to " + destination.ToString() + " ? (type `yes` to continue)"); var response = Console.ReadLine(); if (response.Equals("yes", StringComparison.OrdinalIgnoreCase)) { break; } } Logs.Main.LogInformation("Connecting to a BCC node..."); AddressManagerBehavior addrman = new AddressManagerBehavior(new AddressManager()); addrman.PeersToDiscover = 10; addrman.Mode = AddressManagerBehaviorMode.Discover; NodesGroup group = new NodesGroup(RPCClient.Network, new NodeConnectionParameters() { IsRelay = false, Services = NodeServices.Nothing | NodeServices.NODE_BITCOIN_CASH, TemplateBehaviors = { addrman }, UserAgent = "BCCSpliter", Advertize = false }, new NodeRequirement() { RequiredServices = NodeServices.NODE_BITCOIN_CASH }); group.MaximumNodeConnection = 1; if (Configuration.BCCEndpoint != null) { addrman.PeersToDiscover = 1; addrman.Mode = AddressManagerBehaviorMode.None; addrman.AddressManager.Add(new NetworkAddress(Configuration.BCCEndpoint), IPAddress.Parse("127.0.0.1")); group.CustomGroupSelector = WellKnownGroupSelectors.ByEndpoint; group.AllowSameGroup = true; } group.ConnectedNodes.Added += (s, e) => { Logs.Main.LogInformation("Connected to " + e.Node.RemoteSocketEndpoint); Logs.Main.LogInformation("Broadcasting..."); e.Node.SendMessageAsync(new InvPayload(new InventoryVector(InventoryType.MSG_TX, dumpTransaction.GetHash()))); e.Node.SendMessageAsync(new TxPayload(dumpTransaction)); CancellationTokenSource cts = new CancellationTokenSource(); cts.CancelAfter(10000); try { e.Node.PingPong(cts.Token); } catch (Exception ex) { Logs.Main.LogWarning("Error while broadcasting transaction, retrying with another node..."); e.Node.Disconnect("Error while broadcasting transaction", ex); return; } Logs.Main.LogInformation("Broadcasted " + dumpTransaction.GetHash()); group.Disconnect(); group.Dispose(); }; group.Connect(); }
private void Dump(DumpOptions o) { if (o.Address == null) { throw new FormatException(); } var destination = BitcoinAddress.Create(o.Address); if (destination is BitcoinWitScriptAddress || destination is BitcoinWitPubKeyAddress) { throw new FormatException("BCC disabled segwit, segwit address unsupported"); } UTXO[] utxos = GetDumpingUTXOs(); if (utxos.Length == 0) { Logs.Main.LogWarning("No UTXO selected to dump, use `select` command to select UTXOs to select for dump"); return; } Logs.Main.LogInformation("Dumping " + utxos.Length + " UTXOs"); FeeRate feeRate = null; try { feeRate = RPCClient.EstimateFeeRate(6); //BCC having few fees, this will confirm fast } catch { if (RPCClient.Network == Network.RegTest) { feeRate = new FeeRate(Money.Satoshis(30), 1); } else { Logs.Main.LogWarning("Fee estimation unavailable, you need to wait Bitcoin Core to properly sync and retry to dump"); return; } } var total = utxos.Select(u => u.Amount).Sum(); var fee = Money.Zero; var coins = utxos.Select(u => u.AsCoin()); TransactionBuilder builder = new TransactionBuilder(); builder.AddCoins(coins); builder.Send(destination, total); try { builder.SendEstimatedFees(feeRate); builder.BuildTransaction(false); } catch (NotEnoughFundsException ex) { fee = (Money)ex.Missing; } builder = new TransactionBuilder(); builder.AddKeys(FetchKeys(coins).ToArray()); builder.AddCoins(coins); builder.Send(destination, total - fee); builder.SendFees(fee); var dumpTransaction = builder.BuildTransaction(true, SigHash.ForkId | SigHash.All); Logs.Main.LogInformation("Dump transaction created " + dumpTransaction.ToHex()); Logs.Main.LogInformation("Dump transaction ID " + dumpTransaction.GetHash()); Repository.Lock(coins.Select(c => c.Outpoint).ToArray(), dumpTransaction.GetHash()); Logs.Main.LogInformation("Connecting to a BCC node..."); AddressManagerBehavior addrman = new AddressManagerBehavior(new AddressManager()); addrman.PeersToDiscover = 10; addrman.Mode = AddressManagerBehaviorMode.Discover; NodesGroup group = new NodesGroup(RPCClient.Network, new NodeConnectionParameters() { IsRelay = false, Services = NodeServices.Nothing | NodeServices.NODE_BITCOIN_CASH, TemplateBehaviors = { addrman }, UserAgent = "BCCSpliter", Advertize = false }, new NodeRequirement() { RequiredServices = NodeServices.NODE_BITCOIN_CASH }); group.MaximumNodeConnection = 1; if (Configuration.BCCEndpoint != null) { addrman.PeersToDiscover = 1; addrman.Mode = AddressManagerBehaviorMode.None; addrman.AddressManager.Add(new NetworkAddress(Configuration.BCCEndpoint), IPAddress.Parse("127.0.0.1")); group.CustomGroupSelector = WellKnownGroupSelectors.ByEndpoint; group.AllowSameGroup = true; } group.ConnectedNodes.Added += (s, e) => { Logs.Main.LogInformation("Connected to " + e.Node.RemoteSocketEndpoint); Logs.Main.LogInformation("Broadcasting..."); e.Node.SendMessageAsync(new InvPayload(new InventoryVector(InventoryType.MSG_TX, dumpTransaction.GetHash()))); e.Node.SendMessageAsync(new TxPayload(dumpTransaction)); CancellationTokenSource cts = new CancellationTokenSource(); cts.CancelAfter(10000); try { e.Node.PingPong(cts.Token); } catch (Exception ex) { Logs.Main.LogWarning("Error while broadcasting transaction, retrying with another node..."); e.Node.Disconnect("Error while broadcasting transaction", ex); return; } Logs.Main.LogInformation("Broadcasted " + dumpTransaction.GetHash() + ", when this transaction is confirmed, unlock your Bitcoins again with `confirm " + dumpTransaction.GetHash() + "`"); group.Disconnect(); group.Dispose(); }; group.Connect(); }