Esempio n. 1
0
        public async Task MerkleProofCheckCleanUp()
        {
            //arrange
            cleanUpTxService.Pause();
            var cleanUpTxTriggeredSubscription = eventBus.Subscribe <CleanUpTxTriggeredEvent>();

            List <Tx> txList = await CreateAndInsertTxAsync(true, false);

            uint256 firstBlockHash = await InsertMerkleProof();

            WaitUntilEventBusIsIdle();

            await CheckTxListPresentInDbAsync(txList, true);
            await CheckBlockPresentInDbAsync(firstBlockHash);

            var merkleProofTxs = (await TxRepositoryPostgres.GetTxsToSendMerkleProofNotificationsAsync(0, 10000)).ToList();

            Assert.AreEqual(5, merkleProofTxs.Count());
            Assert.IsTrue(merkleProofTxs.Any(x => new uint256(x.TxExternalId) == new uint256(Tx2Hash)));

            foreach (var txWithMerkle in merkleProofTxs)
            {
                await TxRepositoryPostgres.SetNotificationSendDateAsync(CallbackReason.MerkleProof, txWithMerkle.TxInternalId, txWithMerkle.BlockInternalId, null, MockedClock.UtcNow);
            }

            merkleProofTxs = (await TxRepositoryPostgres.GetTxsToSendMerkleProofNotificationsAsync(0, 10000)).ToList();
            Assert.AreEqual(0, merkleProofTxs.Count());

            using (MockedClock.NowIs(DateTime.UtcNow.AddDays(cleanUpTxAfterDays)))
            {
                await ResumeAndWaitForCleanup(cleanUpTxTriggeredSubscription);

                // check if everything in db was cleared
                await CheckBlockNotPresentInDb(firstBlockHash);
                await CheckTxListNotPresentInDbAsync(txList);
            }
        }
        public virtual async Task DoubleMerkleProofCheck()
        {
            _ = await CreateAndInsertTxAsync(true, true, 2);

            var node      = NodeRepository.GetNodes().First();
            var rpcClient = rpcClientFactoryMock.Create(node.Host, node.Port, node.Username, node.Password);

            var(blockCount, _) = await CreateAndPublishNewBlock(rpcClient, null, null);

            NBitcoin.Block forkBlock = null;
            var            nextBlock = NBitcoin.Block.Load(await rpcClient.GetBlockByHeightAsBytesAsync(0), Network.Main);
            var            pubKey    = nextBlock.Transactions.First().Outputs.First().ScriptPubKey.GetDestinationPublicKeys().First();
            // tx1 will be mined in block 1 and the notification has to be sent only once (1 insert into txBlock)
            var tx1 = Transaction.Parse(Tx1Hex, Network.Main);
            // tx2 will be mined in block 15 in chain 1 and in the block 20 in longer chain 2 and the notification
            // has to be sent twice (2 inserts into txBlock)
            var tx2 = Transaction.Parse(Tx2Hex, Network.Main);

            // Setup first chain, 20 blocks long
            do
            {
                var prevBlockHash = nextBlock.GetHash();
                nextBlock = nextBlock.CreateNextBlockWithCoinbase(pubKey, new Money(50, MoneyUnit.MilliBTC), new ConsensusFactory());
                nextBlock.Header.HashPrevBlock = prevBlockHash;
                if (blockCount == 1)
                {
                    nextBlock.AddTransaction(tx1);
                }
                if (blockCount == 9)
                {
                    forkBlock = nextBlock;
                }
                if (blockCount == 15)
                {
                    nextBlock.AddTransaction(tx2);
                }
                nextBlock.Check();
                rpcClientFactoryMock.AddKnownBlock(blockCount++, nextBlock.ToBytes());
            }while (blockCount < 20);
            PublishBlockHashToEventBus(await rpcClient.GetBestBlockHashAsync());

            nextBlock  = forkBlock;
            blockCount = 10;
            // Setup second chain
            do
            {
                var prevBlockHash = nextBlock.GetHash();
                nextBlock = nextBlock.CreateNextBlockWithCoinbase(pubKey, new Money(50, MoneyUnit.MilliBTC), new ConsensusFactory());
                nextBlock.Header.HashPrevBlock = prevBlockHash;
                if (blockCount == 20)
                {
                    nextBlock.AddTransaction(tx2);
                }
                nextBlock.Check();
                rpcClientFactoryMock.AddKnownBlock(blockCount++, nextBlock.ToBytes());
            }while (blockCount < 21);
            PublishBlockHashToEventBus(await rpcClient.GetBestBlockHashAsync());

            var merkleProofs = (await TxRepositoryPostgres.GetTxsToSendMerkleProofNotificationsAsync(0, 100)).ToArray();

            Assert.AreEqual(3, merkleProofs.Length);
            Assert.IsTrue(merkleProofs.Count(x => new uint256(x.TxExternalId).ToString() == Tx1Hash) == 1);
            // Tx2 must have 2 requests for merkle proof notification (blocks 15 and 20)
            Assert.IsTrue(merkleProofs.Count(x => new uint256(x.TxExternalId).ToString() == Tx2Hash) == 2);
            Assert.IsTrue(merkleProofs.Any(x => new uint256(x.TxExternalId).ToString() == Tx2Hash && x.BlockHeight == 15));
            Assert.IsTrue(merkleProofs.Any(x => new uint256(x.TxExternalId).ToString() == Tx2Hash && x.BlockHeight == 20));
        }