public async Task NodesDifferAsync() { using var services1 = new HostedServices(); using var services2 = new HostedServices(); var coreNodes = await Task.WhenAll(TestNodeBuilder.CreateAsync(services1, additionalFolder: "0"), TestNodeBuilder.CreateAsync(services2, additionalFolder: "1")); await services1.StartAllAsync(CancellationToken.None); await services2.StartAllAsync(CancellationToken.None); CoreNode node1 = coreNodes[0]; CoreNode node2 = coreNodes[1]; try { Assert.NotEqual(node1.DataDir, node2.DataDir); Assert.NotEqual(node1.P2pEndPoint, node2.P2pEndPoint); Assert.NotEqual(node1.RpcEndPoint, node2.RpcEndPoint); } finally { await services1.StopAllAsync(CancellationToken.None); await services2.StopAllAsync(CancellationToken.None); await Task.WhenAll(node1.TryStopAsync(), node2.TryStopAsync()); } }
public async Task AllFeeEstimateAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); try { var rpc = coreNode.RpcClient; var estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Conservative, simulateIfRegTest : true, tolerateBitcoinCoreBrainfuck : true); Assert.Equal(WalletWasabi.Helpers.Constants.OneDayConfirmationTarget, estimations.Estimations.Count); Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key); Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value); Assert.Equal(EstimateSmartFeeMode.Conservative, estimations.Type); estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Economical, simulateIfRegTest : true, tolerateBitcoinCoreBrainfuck : true); Assert.Equal(145, estimations.Estimations.Count); Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key); Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value); Assert.Equal(EstimateSmartFeeMode.Economical, estimations.Type); estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Economical, simulateIfRegTest : true, tolerateBitcoinCoreBrainfuck : false); Assert.Equal(145, estimations.Estimations.Count); Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key); Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value); Assert.Equal(EstimateSmartFeeMode.Economical, estimations.Type); } finally { await coreNode.StopAsync(); } }
public async Task AllFeeEstimateAsync() { using var services = new HostedServices(); var coreNode = await TestNodeBuilder.CreateAsync(services); await services.StartAllAsync(CancellationToken.None); try { var rpc = coreNode.RpcClient; var estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Conservative, simulateIfRegTest : true); Assert.Equal(WalletWasabi.Helpers.Constants.OneDayConfirmationTarget, estimations.Estimations.Count); Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key); Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value); Assert.Equal(EstimateSmartFeeMode.Conservative, estimations.Type); estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Economical, simulateIfRegTest : true); Assert.Equal(145, estimations.Estimations.Count); Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key); Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value); Assert.Equal(EstimateSmartFeeMode.Economical, estimations.Type); } finally { await services.StopAllAsync(CancellationToken.None); await coreNode.TryStopAsync(); } }
public async Task MempoolNotifiesAsync() { using var services = new HostedServices(); var coreNode = await TestNodeBuilder.CreateAsync(services); await services.StartAllAsync(CancellationToken.None); using var node = await coreNode.CreateNewP2pNodeAsync(); try { var network = coreNode.Network; var rpc = coreNode.RpcClient; var dir = Path.Combine(Global.Instance.DataDir, EnvironmentHelpers.GetCallerFileName(), EnvironmentHelpers.GetMethodName()); var indexStore = new IndexStore(Path.Combine(dir, "indexStore"), network, new SmartHeaderChain()); var transactionStore = new AllTransactionStore(Path.Combine(dir, "transactionStore"), network); var mempoolService = new MempoolService(); var blocks = new FileSystemBlockRepository(Path.Combine(dir, "blocks"), network); var bitcoinStore = new BitcoinStore(indexStore, transactionStore, mempoolService, blocks); await bitcoinStore.InitializeAsync(); await rpc.GenerateAsync(101); node.Behaviors.Add(bitcoinStore.CreateUntrustedP2pBehavior()); node.VersionHandshake(); var addr = new Key().PubKey.GetSegwitAddress(network); var txNum = 10; var eventAwaiter = new EventsAwaiter <SmartTransaction>( h => bitcoinStore.MempoolService.TransactionReceived += h, h => bitcoinStore.MempoolService.TransactionReceived -= h, txNum); var txTasks = new List <Task <uint256> >(); var batch = rpc.PrepareBatch(); for (int i = 0; i < txNum; i++) { txTasks.Add(batch.SendToAddressAsync(addr, Money.Coins(1))); } var batchTask = batch.SendBatchAsync(); var stxs = await eventAwaiter.WaitAsync(TimeSpan.FromSeconds(21)); await batchTask; var hashes = await Task.WhenAll(txTasks); foreach (var stx in stxs) { Assert.Contains(stx.GetHash(), hashes); } } finally { await services.StopAllAsync(CancellationToken.None); node.Disconnect(); await coreNode.TryStopAsync(); } }
private volatile bool _disposedValue = false; // To detect redundant calls public RegTestFixture() { RuntimeParams.SetDataDir(Path.Combine(Common.DataDir, "RegTests", "Backend")); RuntimeParams.LoadAsync().GetAwaiter().GetResult(); var hostedServices = new HostedServices(); BackendRegTestNode = TestNodeBuilder.CreateAsync(hostedServices, callerFilePath: "RegTests", callerMemberName: "BitcoinCoreData").GetAwaiter().GetResult(); var testnetBackendDir = EnvironmentHelpers.GetDataDir(Path.Combine("WalletWasabi", "Tests", "RegTests", "Backend")); IoHelpers.TryDeleteDirectoryAsync(testnetBackendDir).GetAwaiter().GetResult(); Thread.Sleep(100); Directory.CreateDirectory(testnetBackendDir); Thread.Sleep(100); var config = new Config( BackendRegTestNode.RpcClient.Network, BackendRegTestNode.RpcClient.CredentialString.ToString(), new IPEndPoint(IPAddress.Loopback, Network.Main.DefaultPort), new IPEndPoint(IPAddress.Loopback, Network.TestNet.DefaultPort), BackendRegTestNode.P2pEndPoint, new IPEndPoint(IPAddress.Loopback, Network.Main.RPCPort), new IPEndPoint(IPAddress.Loopback, Network.TestNet.RPCPort), BackendRegTestNode.RpcEndPoint); var configFilePath = Path.Combine(testnetBackendDir, "Config.json"); config.SetFilePath(configFilePath); config.ToFile(); var roundConfig = CreateRoundConfig(Money.Coins(0.1m), Constants.OneDayConfirmationTarget, 0.7, 0.1m, 100, 120, 60, 60, 60, 1, 24, true, 11); var roundConfigFilePath = Path.Combine(testnetBackendDir, "CcjRoundConfig.json"); roundConfig.SetFilePath(roundConfigFilePath); roundConfig.ToFile(); var conf = new ConfigurationBuilder() .AddInMemoryCollection(new[] { new KeyValuePair <string, string>("datadir", testnetBackendDir) }) .Build(); BackendEndPoint = $"http://localhost:{CryptoHelpers.RandomInt(37130, 37999)}/"; BackendEndPointUri = new Uri(BackendEndPoint); BackendEndPointApiUri = new Uri(BackendEndPointUri, $"/api/v{Constants.BackendMajorVersion}/"); BackendHost = Host.CreateDefaultBuilder() .ConfigureWebHostDefaults(webBuilder => webBuilder .UseStartup <Startup>() .UseConfiguration(conf) .UseWebRoot("../../../../WalletWasabi.Backend/wwwroot") .UseUrls(BackendEndPoint)) .Build(); Global = (Global)BackendHost.Services.GetService(typeof(Global)); Global.HostedServices = hostedServices; var hostInitializationTask = BackendHost.RunWithTasksAsync(); Logger.LogInfo($"Started Backend webhost: {BackendEndPoint}"); var delayTask = Task.Delay(3000); Task.WaitAny(delayTask, hostInitializationTask); // Wait for server to initialize (Without this OSX CI will fail) }
public async Task AllFeeEstimateAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); try { var rpc = coreNode.RpcClient; var estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Conservative, simulateIfRegTest : true); Assert.Equal(7, estimations.Estimations.Count); Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key); Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value); Assert.Equal(EstimateSmartFeeMode.Conservative, estimations.Type); estimations = await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Economical, simulateIfRegTest : true); Assert.Equal(7, estimations.Estimations.Count); Assert.True(estimations.Estimations.First().Key < estimations.Estimations.Last().Key); Assert.True(estimations.Estimations.First().Value > estimations.Estimations.Last().Value); Assert.Equal(EstimateSmartFeeMode.Economical, estimations.Type); } finally { await coreNode.TryStopAsync(); } }
public async Task TrustedNotifierNotifiesTxAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); try { var rpc = coreNode.RpcClient; await rpc.GenerateAsync(101); var network = rpc.Network; var dir = Path.Combine(Global.Instance.DataDir, EnvironmentHelpers.GetMethodName()); var addr = new Key().PubKey.GetSegwitAddress(network); var notifier = coreNode.TrustedNodeNotifyingBehavior; var txNum = 10; var txInvEventAwaiter = new EventsAwaiter <uint256>( h => notifier.TransactionInv += h, h => notifier.TransactionInv -= h, txNum); var txEventAwaiter = new EventsAwaiter <SmartTransaction>( h => notifier.Transaction += h, h => notifier.Transaction -= h, txNum); var txTasks = new List <Task <uint256> >(); var batch = rpc.PrepareBatch(); for (int i = 0; i < txNum; i++) { txTasks.Add(batch.SendToAddressAsync(addr, Money.Coins(1))); } var batchTask = batch.SendBatchAsync(); var aht = txInvEventAwaiter.WaitAsync(TimeSpan.FromSeconds(21)); var arrivedTxs = await txEventAwaiter.WaitAsync(TimeSpan.FromSeconds(21)); var arrivedHashes = await aht; await batchTask; var hashes = await Task.WhenAll(txTasks); foreach (var hash in arrivedHashes) { Assert.Contains(hash, hashes); } foreach (var hash in arrivedTxs.Select(x => x.GetHash())) { Assert.Contains(hash, hashes); } } finally { await coreNode.TryStopAsync(); } }
public async Task CanHandleConfirmationAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); using HostedServices services = new(); services.Register <MempoolMirror>(() => new MempoolMirror(TimeSpan.FromSeconds(2), coreNode.RpcClient, coreNode.P2pNode), "Mempool Mirror"); try { var rpc = coreNode.RpcClient; var network = rpc.Network; await services.StartAllAsync(); var mempoolInstance = services.Get <MempoolMirror>(); var walletName = "RandomWalletName"; await rpc.CreateWalletAsync(walletName); var spendAmount = new Money(0.0004m, MoneyUnit.BTC); await rpc.GenerateAsync(101); var rpcMempoolBeforeSend = await rpc.GetRawMempoolAsync(); var localMempoolBeforeSend = mempoolInstance.GetMempoolHashes(); Assert.Equal(rpcMempoolBeforeSend.Length, localMempoolBeforeSend.Count); await rpc.SendToAddressAsync(BitcoinFactory.CreateBitcoinAddress(network), spendAmount); while (!(await rpc.GetRawMempoolAsync()).Any()) { await Task.Delay(50); } await mempoolInstance.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7)); var localMempoolAfterSend = mempoolInstance.GetMempoolHashes(); Assert.Equal(1, localMempoolAfterSend.Count); Assert.Single(localMempoolAfterSend); await rpc.GenerateAsync(1); while ((await rpc.GetRawMempoolAsync()).Any()) { await Task.Delay(50); } await mempoolInstance.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7)); var localMempoolAfterBlockMined = mempoolInstance.GetMempoolHashes(); Assert.Empty(localMempoolAfterBlockMined); } finally { await services.StopAllAsync(); await coreNode.TryStopAsync(); } }
public async Task CanHandleTheSameTxSentManyTimesAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); using HostedServices services = new(); services.Register <MempoolMirror>(() => new MempoolMirror(TimeSpan.FromSeconds(2), coreNode.RpcClient, coreNode.P2pNode), "Mempool Mirror"); try { var rpc = coreNode.RpcClient; var network = rpc.Network; await services.StartAllAsync(); var mempoolInstance = services.Get <MempoolMirror>(); var walletName = "RandomWalletName"; await rpc.CreateWalletAsync(walletName); using var k1 = new Key(); var blockIds = await rpc.GenerateToAddressAsync(1, k1.PubKey.WitHash.GetAddress(network)); var block = await rpc.GetBlockAsync(blockIds[0]); var coinBaseTx = block.Transactions[0]; var tx = Transaction.Create(network); tx.Inputs.Add(coinBaseTx, 0); tx.Outputs.Add(Money.Coins(49.9999m), BitcoinFactory.CreateBitcoinAddress(network)); tx.Sign(k1.GetBitcoinSecret(network), coinBaseTx.Outputs.AsCoins().First()); var valid = tx.Check(); await rpc.GenerateAsync(101); for (int i = 0; i < 5; i++) { await rpc.SendRawTransactionAsync(tx); } while (!(await rpc.GetRawMempoolAsync()).Any()) { await Task.Delay(50); } await mempoolInstance.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7)); var localMempoolHashes = mempoolInstance.GetMempoolHashes(); Assert.Single(localMempoolHashes); Assert.Contains(tx.GetHash(), localMempoolHashes); } finally { await services.StopAllAsync(); await coreNode.TryStopAsync(); } }
public async Task CanBuildCoreNodeAsync() { using var services = new HostedServices(); var coreNode = await TestNodeBuilder.CreateAsync(services); await services.StartAllAsync(CancellationToken.None); await coreNode.TryStopAsync(); await services.StopAllAsync(CancellationToken.None); }
public async Task TrustedNotifierNotifiesTxAsync() { using HostedServices services = new(); var coreNode = await TestNodeBuilder.CreateAsync(services); await services.StartAllAsync(); try { var rpc = coreNode.RpcClient; var walletName = "wallet.dat"; await rpc.CreateWalletAsync(walletName); await rpc.GenerateAsync(101); var network = rpc.Network; var dir = Common.GetWorkDir(); using Key k = new(); var addr = k.PubKey.GetSegwitAddress(network); var notifier = coreNode.MempoolService; var txNum = 10; EventsAwaiter <SmartTransaction> txEventAwaiter = new( h => notifier.TransactionReceived += h, h => notifier.TransactionReceived -= h, txNum); List <Task <uint256> > txTasks = new(); var batch = rpc.PrepareBatch(); for (int i = 0; i < txNum; i++) { txTasks.Add(batch.SendToAddressAsync(addr, Money.Coins(1))); } var batchTask = batch.SendBatchAsync(); var arrivedTxs = await txEventAwaiter.WaitAsync(TimeSpan.FromSeconds(21)); await batchTask; var hashes = await Task.WhenAll(txTasks); foreach (var hash in arrivedTxs.Select(x => x.GetHash())) { Assert.Contains(hash, hashes); } } finally { await services.StopAllAsync(); await coreNode.TryStopAsync(); } }
public async Task MempoolNotifiesAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); using var node = await coreNode.CreateP2pNodeAsync(); try { var rpc = coreNode.RpcClient; await rpc.GenerateAsync(101); var network = rpc.Network; var bitcoinStore = new BitcoinStore(); var dir = Path.Combine(Global.Instance.DataDir, EnvironmentHelpers.GetMethodName()); await bitcoinStore.InitializeAsync(dir, network); node.Behaviors.Add(bitcoinStore.CreateMempoolBehavior()); node.VersionHandshake(); var addr = new Key().PubKey.GetSegwitAddress(network); var txNum = 10; var eventAwaiter = new EventsAwaiter <SmartTransaction>( h => bitcoinStore.MempoolService.TransactionReceived += h, h => bitcoinStore.MempoolService.TransactionReceived -= h, txNum); var txTasks = new List <Task <uint256> >(); var batch = rpc.PrepareBatch(); for (int i = 0; i < txNum; i++) { txTasks.Add(batch.SendToAddressAsync(addr, Money.Coins(1))); } var batchTask = batch.SendBatchAsync(); var stxs = await eventAwaiter.WaitAsync(TimeSpan.FromSeconds(21)); await batchTask; var hashes = await Task.WhenAll(txTasks); foreach (var stx in stxs) { Assert.Contains(stx.GetHash(), hashes); } } finally { node.Disconnect(); await coreNode.StopAsync(); } }
public async Task CanBuildCoreNodeAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); try { Assert.False(coreNode.Process.HasExited); } finally { await coreNode.StopAsync(); } }
public async Task GetRawTransactionsAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); try { var rpc = coreNode.RpcClient; var txs = await rpc.GetRawTransactionsAsync(new[] { BitcoinFactory.CreateUint256(), BitcoinFactory.CreateUint256() }, CancellationToken.None); Assert.Empty(txs); await rpc.CreateWalletAsync("wallet"); await rpc.GenerateAsync(101); var txid = await rpc.SendToAddressAsync(BitcoinFactory.CreateScript().GetDestinationAddress(Network.RegTest), Money.Coins(1)); txs = await rpc.GetRawTransactionsAsync(new[] { txid }, CancellationToken.None); Assert.Single(txs); List <uint256> txids = new(); for (int i = 0; i < 2; i++) { var txid2 = await rpc.SendToAddressAsync(BitcoinFactory.CreateScript().GetDestinationAddress(Network.RegTest), Money.Coins(1)); txids.Add(txid2); } txs = await rpc.GetRawTransactionsAsync(txids, CancellationToken.None); Assert.Equal(2, txs.Count()); txids = new(); for (int i = 0; i < 20; i++) { var txid2 = await rpc.SendToAddressAsync(BitcoinFactory.CreateScript().GetDestinationAddress(Network.RegTest), Money.Coins(1)); txids.Add(txid2); } txs = await rpc.GetRawTransactionsAsync(txids, CancellationToken.None); Assert.Equal(20, txs.Count()); } finally { await coreNode.TryStopAsync(); } }
public async Task CanHandleManyTxsAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); using HostedServices services = new(); services.Register <MempoolMirror>(() => new MempoolMirror(TimeSpan.FromSeconds(2), coreNode.RpcClient, coreNode.P2pNode), "Mempool Mirror"); try { var rpc = coreNode.RpcClient; var network = rpc.Network; await services.StartAllAsync(); var mempoolInstance = services.Get <MempoolMirror>(); var walletName = "RandomWalletName"; await rpc.CreateWalletAsync(walletName); using var k1 = new Key(); var blockIds = await rpc.GenerateToAddressAsync(1, k1.PubKey.WitHash.GetAddress(network)); var block = await rpc.GetBlockAsync(blockIds[0]); var coinBaseTx = block.Transactions[0]; await rpc.GenerateAsync(101); for (int i = 0; i < 5; i++) { await rpc.SendToAddressAsync(BitcoinFactory.CreateBitcoinAddress(network), new Money(0.0004m, MoneyUnit.BTC)); } while ((await rpc.GetRawMempoolAsync()).Length != 5) { await Task.Delay(50); } await mempoolInstance.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7)); var localMempoolHashes = mempoolInstance.GetMempoolHashes(); Assert.Equal(5, localMempoolHashes.Count); } finally { await services.StopAllAsync(); await coreNode.TryStopAsync(); } }
public async Task CantDoubleSpendAsync() { using var services = new HostedServices(); var coreNode = await TestNodeBuilder.CreateAsync(services); await services.StartAllAsync(CancellationToken.None); try { var rpc = coreNode.RpcClient; var network = rpc.Network; var walletName = "wallet.dat"; await rpc.CreateWalletAsync(walletName); using var k1 = new Key(); var blockId = await rpc.GenerateToAddressAsync(1, k1.PubKey.WitHash.GetAddress(network)); var block = await rpc.GetBlockAsync(blockId[0]); var coinBaseTx = block.Transactions[0]; var tx = Transaction.Create(network); tx.Inputs.Add(coinBaseTx, 0); using var k2 = new Key(); tx.Outputs.Add(Money.Coins(49.9999m), k2.PubKey.WitHash.GetAddress(network)); tx.Sign(k1.GetBitcoinSecret(network), coinBaseTx.Outputs.AsCoins().First()); var valid = tx.Check(); var doubleSpend = Transaction.Create(network); doubleSpend.Inputs.Add(coinBaseTx, 0); using var k3 = new Key(); doubleSpend.Outputs.Add(Money.Coins(49.998m), k3.PubKey.WitHash.GetAddress(network)); doubleSpend.Sign(k1.GetBitcoinSecret(network), coinBaseTx.Outputs.AsCoins().First()); valid = doubleSpend.Check(); await rpc.GenerateAsync(101); var txId = await rpc.SendRawTransactionAsync(tx); await Assert.ThrowsAsync <RPCException>(async() => await rpc.SendRawTransactionAsync(doubleSpend)); } finally { await services.StopAllAsync(CancellationToken.None); await coreNode.TryStopAsync(); } }
public async Task RpcWorksAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); try { var blockCount = await coreNode.RpcClient.GetBlockCountAsync(); Assert.Equal(0, blockCount); } finally { await coreNode.TryStopAsync(); } }
public async Task FeeEstimationCanCancelAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); try { var rpc = coreNode.RpcClient; using CancellationTokenSource cts = new(TimeSpan.Zero); await Assert.ThrowsAsync <TaskCanceledException>(async() => await rpc.EstimateAllFeeAsync(EstimateSmartFeeMode.Conservative, true, cts.Token)); } finally { await coreNode.TryStopAsync(); } }
public async Task VerboseBlockInfoAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); try { var rpc = coreNode.RpcClient; var blockInfo = await rpc.GetVerboseBlockAsync(coreNode.Network.GenesisHash); Assert.NotNull(blockInfo.Transactions.ElementAt(0).Inputs.ElementAt(0).Coinbase); } finally { await coreNode.TryStopAsync(); } }
public async Task P2pWorksAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); using var node = await coreNode.CreateNewP2pNodeAsync(); try { var blocks = node.GetBlocks(new[] { Network.RegTest.GenesisHash }); var genesis = Assert.Single(blocks); Assert.Equal(genesis.GetHash(), Network.RegTest.GenesisHash); } finally { node.Disconnect(); await coreNode.TryStopAsync(); } }
public async Task NodesDifferAsync() { var coreNodes = await Task.WhenAll(TestNodeBuilder.CreateAsync(additionalFolder: "0"), TestNodeBuilder.CreateAsync(additionalFolder: "1")); CoreNode node1 = coreNodes[0]; CoreNode node2 = coreNodes[1]; try { Assert.NotEqual(node1.DataDir, node2.DataDir); Assert.NotEqual(node1.P2pEndPoint, node2.P2pEndPoint); Assert.NotEqual(node1.RpcEndPoint, node2.RpcEndPoint); } finally { await Task.WhenAll(node1.TryStopAsync(), node2.TryStopAsync()); } }
public async Task CanCopyMempoolFromRpcAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); using HostedServices services = new(); services.Register <MempoolMirror>(() => new MempoolMirror(TimeSpan.FromSeconds(2), coreNode.RpcClient, coreNode.P2pNode), "Mempool Mirror"); try { var rpc = coreNode.RpcClient; var network = rpc.Network; var mempoolInstance = services.Get <MempoolMirror>(); var walletName = "RandomWalletName"; await rpc.CreateWalletAsync(walletName); var spendAmount = new Money(0.0004m, MoneyUnit.BTC); var spendAmount2 = new Money(0.0004m, MoneyUnit.BTC); await rpc.GenerateAsync(101); var txid = await rpc.SendToAddressAsync(BitcoinFactory.CreateBitcoinAddress(network), spendAmount); var txid2 = await rpc.SendToAddressAsync(BitcoinFactory.CreateBitcoinAddress(network), spendAmount2); while ((await rpc.GetRawMempoolAsync()).Length != 2) { await Task.Delay(50); } await services.StartAllAsync(); await mempoolInstance.TriggerAndWaitRoundAsync(TimeSpan.FromSeconds(7)); var localMempoolHashes = mempoolInstance.GetMempoolHashes(); Assert.Equal(2, localMempoolHashes.Count); Assert.Contains(txid, localMempoolHashes); Assert.Contains(txid2, localMempoolHashes); } finally { await services.StopAllAsync(); await coreNode.TryStopAsync(); } }
public async Task RpcWorksAsync() { using var services = new HostedServices(); var coreNode = await TestNodeBuilder.CreateAsync(services); await services.StartAllAsync(CancellationToken.None); try { var blockCount = await coreNode.RpcClient.GetBlockCountAsync(); Assert.Equal(0, blockCount); } finally { await services.StopAllAsync(CancellationToken.None); await coreNode.TryStopAsync(); } }
public async Task VerboseBlockInfoAsync() { using var services = new HostedServices(); var coreNode = await TestNodeBuilder.CreateAsync(services); await services.StartAllAsync(CancellationToken.None); try { var rpc = coreNode.RpcClient; var blockInfo = await rpc.GetVerboseBlockAsync(coreNode.Network.GenesisHash); Assert.NotNull(blockInfo.Transactions.ElementAt(0).Inputs.ElementAt(0).Coinbase); } finally { await services.StopAllAsync(CancellationToken.None); await coreNode.TryStopAsync(); } }
public async Task P2pWorksAsync() { using var services = new HostedServices(); var coreNode = await TestNodeBuilder.CreateAsync(services); await services.StartAllAsync(CancellationToken.None); using var node = await coreNode.CreateNewP2pNodeAsync(); try { var blocks = node.GetBlocks(new[] { Network.RegTest.GenesisHash }); var genesis = Assert.Single(blocks); Assert.Equal(genesis.GetHash(), Network.RegTest.GenesisHash); } finally { await services.StopAllAsync(CancellationToken.None); node.Disconnect(); await coreNode.TryStopAsync(); } }
public async Task MempoolNotifiesAsync() { using HostedServices services = new(); CoreNode coreNode = await TestNodeBuilder.CreateAsync(services); await services.StartAllAsync(); using var node = await coreNode.CreateNewP2pNodeAsync(); try { string dir = Common.GetWorkDir(); var network = coreNode.Network; var rpc = coreNode.RpcClient; var walletName = "wallet.dat"; await rpc.CreateWalletAsync(walletName); await using IndexStore indexStore = new(Path.Combine(dir, "indexStore"), network, new SmartHeaderChain()); await using AllTransactionStore transactionStore = new(Path.Combine(dir, "transactionStore"), network); MempoolService mempoolService = new(); FileSystemBlockRepository blocks = new(Path.Combine(dir, "blocks"), network); // Construct BitcoinStore. await using BitcoinStore bitcoinStore = new(indexStore, transactionStore, mempoolService, blocks); await bitcoinStore.InitializeAsync(); await rpc.GenerateAsync(blockCount : 101); node.Behaviors.Add(bitcoinStore.CreateUntrustedP2pBehavior()); node.VersionHandshake(); using Key k = new(); BitcoinWitPubKeyAddress address = k.PubKey.GetSegwitAddress(network); // Number of transactions to send. const int TransactionsCount = 10; EventsAwaiter <SmartTransaction> eventAwaiter = new( subscribe : h => mempoolService.TransactionReceived += h, unsubscribe : h => mempoolService.TransactionReceived -= h, count : TransactionsCount); List <Task <uint256> > txHashesList = new(); IRPCClient rpcBatch = rpc.PrepareBatch(); // Add to the batch 10 RPC commands: Send 1 coin to the same address. for (int i = 0; i < TransactionsCount; i++) { txHashesList.Add(rpcBatch.SendToAddressAsync(address, Money.Coins(1))); } // Publish the RPC batch. Task rpcBatchTask = rpcBatch.SendBatchAsync(); // Wait until the mempool service receives all the sent transactions. IEnumerable <SmartTransaction> mempoolSmartTxs = await eventAwaiter.WaitAsync(TimeSpan.FromMinutes(2)); await rpcBatchTask; // Collect all the transaction hashes of the sent transactions. uint256[] hashes = await Task.WhenAll(txHashesList); // Check that all the received transaction hashes are in the set of sent transaction hashes. foreach (SmartTransaction tx in mempoolSmartTxs) { Assert.Contains(tx.GetHash(), hashes); } } finally { await services.StopAllAsync(); node.Disconnect(); await coreNode.TryStopAsync(); } }
public async Task BlockNotifierTestsAsync() { using HostedServices services = new(); var coreNode = await TestNodeBuilder.CreateAsync(services); await services.StartAllAsync(); try { var rpc = coreNode.RpcClient; var walletName = "wallet.dat"; await rpc.CreateWalletAsync(walletName); BlockNotifier notifier = services.FirstOrDefault <BlockNotifier>(); // Make sure we get notification for one block. EventAwaiter <Block> blockEventAwaiter = new(h => notifier.OnBlock += h, h => notifier.OnBlock -= h); var hash = (await rpc.GenerateAsync(1)).First(); var block = await blockEventAwaiter.WaitAsync(TimeSpan.FromSeconds(21)); Assert.Equal(hash, block.GetHash()); // Make sure we get notifications about 10 blocks created at the same time. var blockNum = 10; EventsAwaiter <Block> blockEventsAwaiter = new(h => notifier.OnBlock += h, h => notifier.OnBlock -= h, blockNum); var hashes = (await rpc.GenerateAsync(blockNum)).ToArray(); var arrivedBlocks = (await blockEventsAwaiter.WaitAsync(TimeSpan.FromSeconds(21))).ToArray(); for (int i = 0; i < hashes.Length; i++) { var expected = hashes[i]; var actual = arrivedBlocks[i].GetHash(); Assert.Equal(expected, actual); } // Make sure we get reorg notifications. var reorgNum = 3; var newBlockNum = reorgNum + 1; EventsAwaiter <uint256> reorgEventsAwaiter = new(h => notifier.OnReorg += h, h => notifier.OnReorg -= h, reorgNum); blockEventsAwaiter = new( h => notifier.OnBlock += h, h => notifier.OnBlock -= h, newBlockNum); var reorgedHashes = hashes.TakeLast(reorgNum).ToArray(); await rpc.InvalidateBlockAsync(reorgedHashes[0]); var newHashes = (await rpc.GenerateAsync(newBlockNum)).ToArray(); var reorgedHeaders = (await reorgEventsAwaiter.WaitAsync(TimeSpan.FromSeconds(21))).ToArray(); var newBlocks = (await blockEventsAwaiter.WaitAsync(TimeSpan.FromSeconds(21))).ToArray(); reorgedHashes = reorgedHashes.Reverse().ToArray(); for (int i = 0; i < reorgedHashes.Length; i++) { var expected = reorgedHashes[i]; var actual = reorgedHeaders[i]; Assert.Equal(expected, actual); } for (int i = 0; i < newHashes.Length; i++) { var expected = newHashes[i]; var actual = newBlocks[i].GetHash(); Assert.Equal(expected, actual); } } finally { await services.StopAllAsync(); await coreNode.TryStopAsync(); } }
public async Task CanBuildCoreNodeAsync() { var coreNode = await TestNodeBuilder.CreateAsync(); await coreNode.TryStopAsync(); }