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 void ConfigureRabbitMq(IServiceCollection services, ServiceProvider loggerServicesProvier) { var config = new RabbitMqConfig(); Configuration.GetSection("RabbitMq").Bind(config); var factory = RabbitMqFactory.Create(config); var cardsConsumer = factory.CreateConsumer(Queues.Cards); var awaiter = new EventsAwaiter("Cards", loggerServicesProvier.GetService <ILogger <EventsAwaiter> >()); awaiter.BindConsumer(cardsConsumer); services.AddSingleton(awaiter); var publishers = new Dictionary <string, IPublisher>(); publishers.Add(Queues.APIGateway, factory.CreatePublisher(Queues.APIGateway)); publishers.Add(Queues.Accounts, factory.CreatePublisher(Queues.Accounts)); publishers.Add(Queues.Transactions, factory.CreatePublisher(Queues.Transactions)); var publishingRouter = new PublishingRouter(publishers); services.AddSingleton(publishingRouter); var servicesProvider = services.BuildServiceProvider(); var cardsService = servicesProvider.GetService <CardsService>(); var consumingRouter = ConsumingRouter <CardsService> .Create(cardsService, publishingRouter, "Cards", loggerServicesProvier.GetService <ILogger <IConsumer> >()); consumingRouter.LinkConsumer(cardsConsumer); services.AddSingleton(consumingRouter); }
public CardsService(CardsRepository cardsRepository, ILogger <CardsService> logger, PublishingRouter publishingRouter, EventsAwaiter eventsAwaiter) { this.cardsRepository = cardsRepository; this.logger = logger; this.publishingRouter = publishingRouter; this.eventsAwaiter = eventsAwaiter; }
public CardController(ILogger <CardController> logger, Mapper mapper, PublishingRouter publishingRouter, EventsAwaiter eventsAwaiter) { this.logger = logger; this.mapper = mapper; this.publishingRouter = publishingRouter; this.eventsAwaiter = eventsAwaiter; }
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(); } }
private void AddAwaiter(IServiceCollection services, RabbitMqFactory factory, ServiceProvider loggerServicesProvier) { var awaiter = new EventsAwaiter("APIGateway", loggerServicesProvier.GetService <ILogger <EventsAwaiter> >()); var consumer = factory.CreateConsumer(Queues.APIGateway); awaiter.BindConsumer(consumer); services.AddSingleton(awaiter); }
public async Task LongChainReorgAsync() { var chain = new ConcurrentChain(Network.RegTest); using var notifier = CreateNotifier(chain); var blockAwaiter = new EventsAwaiter <Block>( h => notifier.OnBlock += h, h => notifier.OnBlock -= h, 11); var reorgAwaiter = new EventsAwaiter <uint256>( h => notifier.OnReorg += h, h => notifier.OnReorg -= h, 3); await notifier.StartAsync(CancellationToken.None); await AddBlockAsync(chain); var forkPoint = chain.Tip; var firstReorgedChain = new[] { await AddBlockAsync(chain, wait : false), await AddBlockAsync(chain) }; chain.SetTip(forkPoint); var secondReorgedChain = new[] { await AddBlockAsync(chain, wait : false), await AddBlockAsync(chain, wait : false), await AddBlockAsync(chain) }; chain.SetTip(secondReorgedChain[1]); await AddBlockAsync(chain, wait : false); await AddBlockAsync(chain, wait : false); await AddBlockAsync(chain, wait : false); await AddBlockAsync(chain, wait : false); await AddBlockAsync(chain); // Three blocks notifications await blockAwaiter.WaitAsync(TimeSpan.FromSeconds(2)); // No reorg notifications var reorgedkBlock = await reorgAwaiter.WaitAsync(TimeSpan.FromSeconds(1)); var expectedReorgedBlocks = firstReorgedChain.ToList().Concat(new[] { secondReorgedChain[2] }); Assert.Subset(reorgedkBlock.ToHashSet(), expectedReorgedBlocks.Select(x => x.Header.GetHash()).ToHashSet()); Assert.Equal(chain.Tip.HashBlock, notifier.BestBlockHash); await notifier.StopAsync(CancellationToken.None); }
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 TrustedNotifierNotifiesTxAsync() { using var services = new HostedServices(); var coreNode = await TestNodeBuilder.CreateAsync(services); await services.StartAllAsync(); try { var rpc = coreNode.RpcClient; await rpc.GenerateAsync(101); var network = rpc.Network; var dir = Common.GetWorkDir(); var addr = new Key().PubKey.GetSegwitAddress(network); var notifier = coreNode.MempoolService; var txNum = 10; var txEventAwaiter = new EventsAwaiter <SmartTransaction>( h => notifier.TransactionReceived += h, h => notifier.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 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 SuperFastNodeValidationAsync() { var chain = new ConcurrentChain(Network.RegTest); using var notifier = CreateNotifier(chain); var blockAwaiter = new EventsAwaiter <Block>( h => notifier.OnBlock += h, h => notifier.OnBlock -= h, 144); await notifier.StartAsync(CancellationToken.None); var lastKnownBlock = await AddBlockAsync(chain); foreach (var i in Enumerable.Range(0, 200)) { await AddBlockAsync(chain, wait : false); } await AddBlockAsync(chain, wait : true); notifier.TriggerRound(); Assert.Equal(chain.Tip.HashBlock, notifier.BestBlockHash); var nofifiedBlocks = (await blockAwaiter.WaitAsync(TimeSpan.FromSeconds(1))).ToArray(); var tip = chain.Tip; var pos = nofifiedBlocks.Length - 1; while (tip.HashBlock != nofifiedBlocks[pos].GetHash()) { tip = tip.Previous; } while (pos >= 0) { Assert.Equal(tip.HashBlock, nofifiedBlocks[pos].GetHash()); tip = tip.Previous; pos--; } await notifier.StopAsync(CancellationToken.None); }
public async Task SimpleReorgAsync() { var chain = new ConcurrentChain(Network.RegTest); using var notifier = CreateNotifier(chain); var blockAwaiter = new EventsAwaiter <Block>( h => notifier.OnBlock += h, h => notifier.OnBlock -= h, 5); var reorgAwaiter = new EventAwaiter <BlockHeader>( h => notifier.OnReorg += h, h => notifier.OnReorg -= h); await notifier.StartAsync(CancellationToken.None); await AddBlockAsync(chain); var forkPoint = chain.Tip; var blockToBeReorged = await AddBlockAsync(chain); chain.SetTip(forkPoint); await AddBlockAsync(chain, wait : false); await AddBlockAsync(chain, wait : false); await AddBlockAsync(chain); notifier.TriggerRound(); // Three blocks notifications await blockAwaiter.WaitAsync(TimeSpan.FromSeconds(2)); // No reorg notifications var reorgedkBlock = await reorgAwaiter.WaitAsync(TimeSpan.FromSeconds(1)); Assert.Equal(forkPoint.HashBlock, reorgedkBlock.HashPrevBlock); Assert.Equal(blockToBeReorged.HashBlock, reorgedkBlock.GetHash()); Assert.Equal(chain.Tip.HashBlock, notifier.BestBlockHash); await notifier.StopAsync(CancellationToken.None); }
public async Task BlockNotifierTestsAsync() { using var services = new HostedServices(); var coreNode = await TestNodeBuilder.CreateAsync(services); await services.StartAllAsync(CancellationToken.None); try { var rpc = coreNode.RpcClient; BlockNotifier notifier = services.FirstOrDefault <BlockNotifier>(); // Make sure we get notification for one block. var blockEventAwaiter = new EventAwaiter <Block>( 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; var blockEventsAwaiter = new EventsAwaiter <Block>( 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; var reorgEventsAwaiter = new EventsAwaiter <uint256>( h => notifier.OnReorg += h, h => notifier.OnReorg -= h, reorgNum); blockEventsAwaiter = new EventsAwaiter <Block>( 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(CancellationToken.None); await coreNode.TryStopAsync(); } }
public async Task TestServicesAsync(string networkString) { await RuntimeParams.LoadAsync(); var network = Network.GetNetwork(networkString); var blocksToDownload = new List <uint256>(); if (network == Network.Main) { blocksToDownload.Add(new uint256("00000000000000000037c2de35bd85f3e57f14ddd741ce6cee5b28e51473d5d0")); blocksToDownload.Add(new uint256("000000000000000000115315a43cb0cdfc4ea54a0e92bed127f4e395e718d8f9")); blocksToDownload.Add(new uint256("00000000000000000011b5b042ad0522b69aae36f7de796f563c895714bbd629")); } else if (network == Network.TestNet) { blocksToDownload.Add(new uint256("0000000097a664c4084b49faa6fd4417055cb8e5aac480abc31ddc57a8208524")); blocksToDownload.Add(new uint256("000000009ed5b82259ecd2aa4cd1f119db8da7a70e7ea78d9c9f603e01f93bcc")); blocksToDownload.Add(new uint256("00000000e6da8c2da304e9f5ad99c079df2c3803b49efded3061ecaf206ddc66")); } else { throw new NotSupportedNetworkException(network); } var dataDir = Path.Combine(Global.Instance.DataDir, EnvironmentHelpers.GetCallerFileName()); BitcoinStore bitcoinStore = new BitcoinStore(); await bitcoinStore.InitializeAsync(Path.Combine(dataDir, EnvironmentHelpers.GetMethodName()), network); var addressManagerFolderPath = Path.Combine(dataDir, "AddressManager"); var addressManagerFilePath = Path.Combine(addressManagerFolderPath, $"AddressManager{network}.dat"); var blocksFolderPath = Path.Combine(dataDir, "Blocks", network.ToString()); var connectionParameters = new NodeConnectionParameters(); AddressManager addressManager = null; try { addressManager = await NBitcoinHelpers.LoadAddressManagerFromPeerFileAsync(addressManagerFilePath); Logger.LogInfo($"Loaded {nameof(AddressManager)} from `{addressManagerFilePath}`."); } catch (DirectoryNotFoundException) { addressManager = new AddressManager(); } catch (FileNotFoundException) { addressManager = new AddressManager(); } catch (OverflowException) { File.Delete(addressManagerFilePath); addressManager = new AddressManager(); } catch (FormatException) { File.Delete(addressManagerFilePath); addressManager = new AddressManager(); } connectionParameters.TemplateBehaviors.Add(new AddressManagerBehavior(addressManager)); connectionParameters.TemplateBehaviors.Add(bitcoinStore.CreateUntrustedP2pBehavior()); using var nodes = new NodesGroup(network, connectionParameters, requirements: Constants.NodeRequirements); KeyManager keyManager = KeyManager.CreateNew(out _, "password"); WasabiSynchronizer syncer = new WasabiSynchronizer(network, bitcoinStore, new Uri("http://localhost:12345"), Global.Instance.TorSocks5Endpoint); ServiceConfiguration serviceConfig = new ServiceConfiguration(50, 2, 21, 50, new IPEndPoint(IPAddress.Loopback, network.DefaultPort), Money.Coins(Constants.DefaultDustThreshold)); CachedBlockProvider blockProvider = new CachedBlockProvider( new P2pBlockProvider(nodes, null, syncer, serviceConfig, network), new FileSystemBlockRepository(blocksFolderPath, network)); using Wallet wallet = Wallet.CreateAndRegisterServices( network, bitcoinStore, keyManager, syncer, nodes, dataDir, new ServiceConfiguration(50, 2, 21, 50, new IPEndPoint(IPAddress.Loopback, network.DefaultPort), Money.Coins(Constants.DefaultDustThreshold)), syncer, blockProvider); Assert.True(Directory.Exists(blocksFolderPath)); try { var mempoolTransactionAwaiter = new EventsAwaiter <SmartTransaction>( h => bitcoinStore.MempoolService.TransactionReceived += h, h => bitcoinStore.MempoolService.TransactionReceived -= h, 3); var nodeConnectionAwaiter = new EventsAwaiter <NodeEventArgs>( h => nodes.ConnectedNodes.Added += h, h => nodes.ConnectedNodes.Added -= h, 3); nodes.Connect(); var downloadTasks = new List <Task <Block> >(); using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(4)); foreach (var hash in blocksToDownload) { downloadTasks.Add(blockProvider.GetBlockAsync(hash, cts.Token)); } await nodeConnectionAwaiter.WaitAsync(TimeSpan.FromMinutes(3)); var i = 0; var hashArray = blocksToDownload.ToArray(); foreach (var block in await Task.WhenAll(downloadTasks)) { Assert.True(File.Exists(Path.Combine(blocksFolderPath, hashArray[i].ToString()))); i++; } await mempoolTransactionAwaiter.WaitAsync(TimeSpan.FromMinutes(1)); } finally { // So next test will download the block. foreach (var hash in blocksToDownload) { await blockProvider.BlockRepository.RemoveAsync(hash, CancellationToken.None); } if (wallet is { })
public ReportsDataFetcher(PublishingRouter publishingRouter, EventsAwaiter eventsAwaiter) { this.publishingRouter = publishingRouter; this.eventsAwaiter = eventsAwaiter; }
public async Task MempoolNotifiesAsync() { using var services = new HostedServices(); CoreNode coreNode = await TestNodeBuilder.CreateAsync(services); await services.StartAllAsync(); BitcoinStore?bitcoinStore = null; using var node = await coreNode.CreateNewP2pNodeAsync(); try { string dir = Common.GetWorkDir(); var network = coreNode.Network; var rpc = coreNode.RpcClient; 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); // Construct BitcoinStore. bitcoinStore = new BitcoinStore(indexStore, transactionStore, mempoolService, blocks); await bitcoinStore.InitializeAsync(); await rpc.GenerateAsync(blockCount : 101); node.Behaviors.Add(bitcoinStore.CreateUntrustedP2pBehavior()); node.VersionHandshake(); BitcoinWitPubKeyAddress address = new Key().PubKey.GetSegwitAddress(network); // Number of transactions to send. const int TransactionsCount = 10; var eventAwaiter = new EventsAwaiter <SmartTransaction>( subscribe: h => mempoolService.TransactionReceived += h, unsubscribe: h => mempoolService.TransactionReceived -= h, count: TransactionsCount); var txHashesList = new List <Task <uint256> >(); 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.FromSeconds(30)); 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 { if (bitcoinStore is { } store) { await store.DisposeAsync(); } await services.StopAllAsync(); node.Disconnect(); await coreNode.TryStopAsync(); } }
public async Task ReorgTestAsync() { (string password, IRPCClient rpc, Network network, _, _, BitcoinStore bitcoinStore, Backend.Global global) = await Common.InitializeTestEnvironmentAsync(RegTestFixture, 1); var keyManager = KeyManager.CreateNew(out _, password, network); // Mine some coins, make a few bech32 transactions then make it confirm. await rpc.GenerateAsync(1); var key = keyManager.GenerateNewKey(SmartLabel.Empty, KeyState.Clean, isInternal: false); var tx2 = await rpc.SendToAddressAsync(key.GetP2wpkhAddress(network), Money.Coins(0.1m)); key = keyManager.GenerateNewKey(SmartLabel.Empty, KeyState.Clean, isInternal: false); var tx3 = await rpc.SendToAddressAsync(key.GetP2wpkhAddress(network), Money.Coins(0.1m)); var tx4 = await rpc.SendToAddressAsync(key.GetP2pkhAddress(network), Money.Coins(0.1m)); var tx5 = await rpc.SendToAddressAsync(key.GetP2shOverP2wpkhAddress(network), Money.Coins(0.1m)); var tx1 = await rpc.SendToAddressAsync(key.GetP2wpkhAddress(network), Money.Coins(0.1m), replaceable : true); await rpc.GenerateAsync(2); // Generate two, so we can test for two reorg var node = RegTestFixture.BackendRegTestNode; using HttpClientFactory httpClientFactory = new(torEndPoint : null, backendUriGetter : () => new Uri(RegTestFixture.BackendEndPoint)); WasabiSynchronizer synchronizer = new(bitcoinStore, httpClientFactory); try { synchronizer.Start(requestInterval: TimeSpan.FromSeconds(3), 1000); var reorgAwaiter = new EventsAwaiter <FilterModel>( h => bitcoinStore.IndexStore.Reorged += h, h => bitcoinStore.IndexStore.Reorged -= h, 2); // Test initial synchronization. await WaitForIndexesToSyncAsync(global, TimeSpan.FromSeconds(90), bitcoinStore); var tip = await rpc.GetBestBlockHashAsync(); Assert.Equal(tip, bitcoinStore.SmartHeaderChain.TipHash); var tipBlock = await rpc.GetBlockHeaderAsync(tip); Assert.Equal(tipBlock.HashPrevBlock, bitcoinStore.SmartHeaderChain.GetChain().Select(x => x.header.BlockHash).ToArray()[bitcoinStore.SmartHeaderChain.HashCount - 2]); // Test synchronization after fork. await rpc.InvalidateBlockAsync(tip); // Reorg 1 tip = await rpc.GetBestBlockHashAsync(); await rpc.InvalidateBlockAsync(tip); // Reorg 2 var tx1bumpRes = await rpc.BumpFeeAsync(tx1); // RBF it await rpc.GenerateAsync(5); await WaitForIndexesToSyncAsync(global, TimeSpan.FromSeconds(90), bitcoinStore); var hashes = bitcoinStore.SmartHeaderChain.GetChain().Select(x => x.header.BlockHash).ToArray(); Assert.DoesNotContain(tip, hashes); Assert.DoesNotContain(tipBlock.HashPrevBlock, hashes); tip = await rpc.GetBestBlockHashAsync(); Assert.Equal(tip, bitcoinStore.SmartHeaderChain.TipHash); var filterList = new List <FilterModel>(); await bitcoinStore.IndexStore.ForeachFiltersAsync(async x => { filterList.Add(x); await Task.CompletedTask; }, new Height(0)); var filterTip = filterList.Last(); Assert.Equal(tip, filterTip.Header.BlockHash); // Test filter block hashes are correct after fork. var blockCountIncludingGenesis = await rpc.GetBlockCountAsync() + 1; filterList.Clear(); await bitcoinStore.IndexStore.ForeachFiltersAsync(async x => { filterList.Add(x); await Task.CompletedTask; }, new Height(0)); FilterModel[] filters = filterList.ToArray(); for (int i = 0; i < blockCountIncludingGenesis; i++) { var expectedHash = await rpc.GetBlockHashAsync(i); var filter = filters[i]; Assert.Equal(i, (int)filter.Header.Height); Assert.Equal(expectedHash, filter.Header.BlockHash); if (i < 101) // Later other tests may fill the filter. { Assert.Equal(IndexBuilderService.CreateDummyEmptyFilter(expectedHash).ToString(), filter.Filter.ToString()); } } // Test the serialization, too. tip = await rpc.GetBestBlockHashAsync(); var blockHash = tip; for (var i = 0; i < hashes.Length; i++) { var block = await rpc.GetBlockHeaderAsync(blockHash); Assert.Equal(blockHash, hashes[hashes.Length - i - 1]); blockHash = block.HashPrevBlock; } // Assert reorg happened exactly as many times as we reorged. await reorgAwaiter.WaitAsync(TimeSpan.FromSeconds(10)); } finally { await synchronizer.StopAsync(); } }
public ReportController(ILogger <ReportController> logger, EventsAwaiter eventsAwaiter, PublishingRouter publishingRouter) { this.logger = logger; this.eventsAwaiter = eventsAwaiter; this.publishingRouter = publishingRouter; }