public async Task DoubleSpendCheckCleanUp()
        {
            //arrange
            cleanUpTxService.Pause();
            var cleanUpTxTriggeredSubscription = EventBus.Subscribe <CleanUpTxTriggeredEvent>();

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

            (_, _, var firstBlockHash) = await InsertDoubleSpend();

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

            var doubleSpends = (await TxRepositoryPostgres.GetTxsToSendBlockDSNotificationsAsync()).ToList();

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

            foreach (var txDoubleSpend in doubleSpends)
            {
                await TxRepositoryPostgres.SetBlockDoubleSpendSendDateAsync(txDoubleSpend.TxInternalId, txDoubleSpend.BlockInternalId, txDoubleSpend.DoubleSpendTxId, MockedClock.UtcNow);
            }

            doubleSpends = (await TxRepositoryPostgres.GetTxsToSendBlockDSNotificationsAsync()).ToList();
            Assert.AreEqual(0, doubleSpends.Count);

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

                // check if everything in db was cleared
                await CheckBlockNotPresentInDb(firstBlockHash);
                await CheckTxListNotPresentInDbAsync(txList);
            }
        }
Exemplo n.º 2
0
        public async Task TestFeeQuotesForSimilarIdentities()
        {
            // arrange
            var entryPostWithIdentity = GetItemToCreateWithIdentity();
            var testIdentity          = GetMockedIdentity;

            testIdentity.Identity          = "test ";
            entryPostWithIdentity.Identity = testIdentity.Identity;
            await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entryPostWithIdentity, HttpStatusCode.Created);

            var entryPostWithIdentity2 = GetItemToCreateWithIdentity();

            entryPostWithIdentity2.Identity = "test _ underline";
            await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entryPostWithIdentity2, HttpStatusCode.Created);

            // test if we properly check for keys in cache
            using (MockedClock.NowIs(DateTime.UtcNow.AddMinutes(1)))
            {
                testIdentity.IdentityProvider = null;
                var getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client,
                                                                          UrlForValidFeeQuotesKey(testIdentity), HttpStatusCode.OK);

                Assert.AreEqual(1, getEntries.Length); // must be only one
                CheckWasCreatedFrom(entryPostWithIdentity, getEntries[0]);
            }
        }
Exemplo n.º 3
0
        public async Task TestPost_2x_GetCurrentFeeQuote()
        {
            var entryPost = GetItemToCreate();

            var(entryResponsePost, _) = await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entryPost, HttpStatusCode.Created);

            var(entryResponsePost2, _) = await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entryPost, HttpStatusCode.Created);

            Assert.IsTrue(entryResponsePost.CreatedAt < entryResponsePost2.CreatedAt);

            using (MockedClock.NowIs(entryResponsePost.CreatedAt.AddMinutes(-1)))
            {
                var getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForCurrentFeeQuoteKey(null, anonymous : true), HttpStatusCode.OK);

                Assert.AreEqual(0, getEntries.Count());
            }

            using (MockedClock.NowIs(entryResponsePost.CreatedAt.AddMinutes(1)))
            {
                // current feeQuote should return newer
                var getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForCurrentFeeQuoteKey(null, anonymous : true), HttpStatusCode.OK);

                Assert.AreEqual(entryResponsePost2.Id, getEntries.Single().Id);
            }
        }
Exemplo n.º 4
0
        public async Task TestFeeQuotesCurrentAndValidDifferentCreatedAt()
        {
            // arrange
            var validFrom = new DateTime(2020, 9, 16, 6, (int)FeeQuoteRepositoryMock.quoteExpiryMinutes, 0);

            using (MockedClock.NowIs(new DateTime(2020, 9, 16, 6, 0, 0)))
            {
                var entryPost = GetItemToCreate();
                entryPost.Id        = 1;
                entryPost.ValidFrom = validFrom;
                await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entryPost, HttpStatusCode.Created);
            }
            using (MockedClock.NowIs(new DateTime(2020, 9, 16, 6, (int)(FeeQuoteRepositoryMock.quoteExpiryMinutes * 0.8), 0)))
            {
                var entryPost = GetItemToCreate();
                entryPost.Id        = 2;
                entryPost.ValidFrom = validFrom;
                await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entryPost, HttpStatusCode.Created);
            }

            // act
            using (MockedClock.NowIs(new DateTime(2020, 9, 16, 6, (int)(FeeQuoteRepositoryMock.quoteExpiryMinutes * 0.5), 0)))
            {
                // check GET for anonymous
                var getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForValidFeeQuotesKey(null) + $"&anonymous=true", HttpStatusCode.OK);

                Assert.AreEqual(0, getEntries.Count());

                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForCurrentFeeQuoteKey(null, anonymous : true), HttpStatusCode.OK);

                Assert.AreEqual(0, getEntries.Count());
            }

            using (MockedClock.NowIs(new DateTime(2020, 9, 16, 6, (int)(FeeQuoteRepositoryMock.quoteExpiryMinutes * 1.2), 0)))
            {
                // check GET for anonymous
                var getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForValidFeeQuotesKey(null) + $"&anonymous=true", HttpStatusCode.OK);

                Assert.AreEqual(1, getEntries.Count());

                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForCurrentFeeQuoteKey(null, anonymous : true), HttpStatusCode.OK);

                Assert.AreEqual(2, getEntries.Single().Id);
            }

            using (MockedClock.NowIs(new DateTime(2020, 9, 16, 6, (int)(FeeQuoteRepositoryMock.quoteExpiryMinutes * 2.1), 0)))
            {
                // check GET for anonymous
                var getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForValidFeeQuotesKey(null) + $"&anonymous=true", HttpStatusCode.OK);

                Assert.AreEqual(1, getEntries.Count());

                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForCurrentFeeQuoteKey(null, anonymous : true), HttpStatusCode.OK);

                Assert.AreEqual(2, getEntries.Single().Id);
            }
        }
Exemplo n.º 5
0
        public async Task TestFeeQuotesValidGetParameters()
        {
            // arrange
            var entryPostWithIdentity = GetItemToCreateWithIdentity();

            var(entryResponsePostIdentity, _) = await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entryPostWithIdentity, HttpStatusCode.Created);

            CheckWasCreatedFrom(entryPostWithIdentity, entryResponsePostIdentity);

            var entryPost = GetItemToCreate();

            entryPost.Id = 2;
            await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entryPost, HttpStatusCode.Created);

            entryPost.Id = 3;
            var(entryResponsePost, _) = await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entryPost, HttpStatusCode.Created);

            // act
            using (MockedClock.NowIs(entryResponsePost.CreatedAt.AddSeconds(10)))
            {
                // check GET for identity
                var getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForValidFeeQuotesKey(GetMockedIdentity), HttpStatusCode.OK);

                CheckWasCreatedFrom(entryPostWithIdentity, getEntries.Single());

                // check GET for identityProvider
                var tIdentity = GetMockedIdentity;
                tIdentity.Identity = null;
                getEntries         = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForValidFeeQuotesKey(tIdentity), HttpStatusCode.OK);

                CheckWasCreatedFrom(entryPostWithIdentity, getEntries.Single());

                // check GET for identity
                tIdentity = GetMockedIdentity;
                tIdentity.IdentityProvider = null;
                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForValidFeeQuotesKey(tIdentity), HttpStatusCode.OK);

                CheckWasCreatedFrom(entryPostWithIdentity, getEntries.Single());

                // check GET for anonymous
                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForValidFeeQuotesKey(null) + $"&anonymous=true", HttpStatusCode.OK);

                Assert.AreEqual(2, getEntries.Count());

                // check GET for identity+anonymous
                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForValidFeeQuotesKey(GetMockedIdentity) + $"&anonymous=true", HttpStatusCode.OK);

                Assert.AreEqual(3, getEntries.Count());

                // check GET all
                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlForValidFeeQuotesKey(null), HttpStatusCode.OK);

                Assert.AreEqual(3, getEntries.Count());
            }
        }
Exemplo n.º 6
0
        public async Task TestFeeQuotesGetParameters()
        {
            // arrange
            var entryPostWithIdentity = GetItemToCreateWithIdentity();

            var(entryResponsePostIdentity, _) = await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entryPostWithIdentity, HttpStatusCode.Created);

            CheckWasCreatedFrom(entryPostWithIdentity, entryResponsePostIdentity);

            var entryPost = GetItemToCreate();

            entryPost.Id = 2;
            var(entryResponsePost, _) = await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entryPost, HttpStatusCode.Created);

            // act
            using (MockedClock.NowIs(entryResponsePost.CreatedAt.AddMinutes(-FeeQuoteRepositoryMock.quoteExpiryMinutes)))
            {
                // check GET for identity & identityProvider
                var getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlWithIdentity(GetBaseUrl(), GetMockedIdentity), HttpStatusCode.OK);

                CheckWasCreatedFrom(entryPostWithIdentity, getEntries.Single());

                // check GET for identityProvider
                var tIdentity = GetMockedIdentity;
                tIdentity.Identity = null;
                getEntries         = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlWithIdentity(GetBaseUrl(), tIdentity), HttpStatusCode.OK);

                CheckWasCreatedFrom(entryPostWithIdentity, getEntries.Single());

                // check GET for identity
                tIdentity = GetMockedIdentity;
                tIdentity.IdentityProvider = null;
                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlWithIdentity(GetBaseUrl(), tIdentity), HttpStatusCode.OK);

                CheckWasCreatedFrom(entryPostWithIdentity, getEntries.Single());

                // check GET for anonymous
                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlWithIdentity(GetBaseUrl(), null) + $"?anonymous=true", HttpStatusCode.OK);

                CheckWasCreatedFrom(entryPost, getEntries.Single());

                // check GET for identity+anonymous
                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlWithIdentity(GetBaseUrl(), GetMockedIdentity) + $"&anonymous=true", HttpStatusCode.OK);

                Assert.AreEqual(2, getEntries.Count());

                // check GET all
                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client, UrlWithIdentity(GetBaseUrl(), null), HttpStatusCode.OK);

                Assert.AreEqual(2, getEntries.Count());
            }
        }
Exemplo n.º 7
0
        public async Task TestGetValidFeeQuotes()
        {
            DateTime tNow    = DateTime.UtcNow;
            var      entries = GetItemsToCreate();


            entries.Last().ValidFrom = entries.First().ValidFrom.Value.AddMinutes(FeeQuoteRepositoryMock.quoteExpiryMinutes / 2);
            foreach (var entry in entries)
            {
                // Create new one using POST
                await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entry, HttpStatusCode.Created);
            }

            using (MockedClock.NowIs(tNow.AddMinutes(-FeeQuoteRepositoryMock.quoteExpiryMinutes)))
            {
                // Should return no results - no feeQuote is yet valid
                var getEntriesInPast = await Get <FeeQuoteConfigViewModelGet[]>(client,
                                                                                UrlForValidFeeQuotesKey(null), HttpStatusCode.OK);

                Assert.AreEqual(0, getEntriesInPast.Length);
            }

            using (MockedClock.NowIs(tNow.AddMinutes(1)))
            {
                // We should be able to retrieve first:
                var getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client,
                                                                          UrlForValidFeeQuotesKey(null), HttpStatusCode.OK);

                Assert.AreEqual(1, getEntries.Length);
                CheckWasCreatedFrom(entries[0], getEntries[0]);
            }

            using (MockedClock.NowIs(tNow.AddMinutes((FeeQuoteRepositoryMock.quoteExpiryMinutes / 2) + 1)))
            {
                // We should be able to retrieve both:
                var getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client,
                                                                          UrlForValidFeeQuotesKey(null), HttpStatusCode.OK);

                Assert.AreEqual(2, getEntries.Length);
            }

            using (MockedClock.NowIs(entries.Last().ValidFrom.Value.AddMinutes(FeeQuoteRepositoryMock.quoteExpiryMinutes * 2)))
            {
                // We should be able to retrieve second:
                var getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client,
                                                                          UrlForValidFeeQuotesKey(null), HttpStatusCode.OK);

                Assert.AreEqual(1, getEntries.Length);
                CheckWasCreatedFrom(entries[1], getEntries[0]);
            }
        }
Exemplo n.º 8
0
        public async Task DoubleSpendMempoolCheckCleanUp()
        {
            //arrange
            cleanUpTxService.Pause();
            var cleanUpTxTriggeredSubscription = eventBus.Subscribe <CleanUpTxTriggeredEvent>();

            (List <Tx> txList, uint256 firstBlockHash) = await CreateAndInsertTxWithMempoolAsync(dsCheckMempool : true);

            WaitUntilEventBusIsIdle();

            var           doubleSpendTx = Transaction.Parse(Tx2Hex, Network.Main);
            List <byte[]> dsTxId        = new List <byte[]>
            {
                doubleSpendTx.GetHash().ToBytes()
            };
            var txsWithDSCheck = (await TxRepositoryPostgres.GetTxsForDSCheckAsync(dsTxId, true)).ToArray();

            var txPayload = HelperTools.HexStringToByteArray(tx2Hex);

            foreach (var dsTx in txsWithDSCheck)
            {
                await TxRepositoryPostgres.InsertMempoolDoubleSpendAsync(
                    dsTx.TxInternalId,
                    dsTx.TxExternalIdBytes,
                    txPayload);
            }
            WaitUntilEventBusIsIdle();
            var doubleSpends = (await TxRepositoryPostgres.GetTxsToSendMempoolDSNotificationsAsync()).ToList();

            Assert.AreEqual(1, doubleSpends.Count());

            foreach (var txDoubleSpend in doubleSpends)
            {
                await TxRepositoryPostgres.SetNotificationSendDateAsync(CallbackReason.DoubleSpendAttempt, txDoubleSpend.TxInternalId, -1, txDoubleSpend.DoubleSpendTxId, MockedClock.UtcNow);
            }

            doubleSpends = (await TxRepositoryPostgres.GetTxsToSendMempoolDSNotificationsAsync()).ToList();
            Assert.AreEqual(0, doubleSpends.Count());

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

                // check if everything in db was cleared
                await CheckBlockNotPresentInDb(firstBlockHash);
                await CheckTxListNotPresentInDbAsync(txList);
            }
        }
Exemplo n.º 9
0
        public async Task TxWithoutBlockCheckCleanUp()
        {
            //arrange
            cleanUpTxService.Pause();
            var cleanUpTxTriggeredSubscription = eventBus.Subscribe <CleanUpTxTriggeredEvent>();

            (List <Tx> txList, _) = await CreateAndInsertTxWithMempoolAsync(addBlocks : false);

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

                // check if everything in db was cleared
                await CheckTxListNotPresentInDbAsync(txList);
            }
        }
Exemplo n.º 10
0
        protected void SetPoliciesForCurrentFeeQuote(string policiesJsonString, UserAndIssuer userAndIssuer = null)
        {
            var feeQuote = FeeQuoteRepository.GetCurrentFeeQuoteByIdentity(userAndIssuer);

            FeeQuoteRepositoryPostgres.EmptyRepository(DbConnectionStringDDL);

            feeQuote.Policies = policiesJsonString;

            using (MockedClock.NowIs(DateTime.UtcNow.AddMinutes(-1)))
            {
                if (FeeQuoteRepository.InsertFeeQuoteAsync(feeQuote).Result == null)
                {
                    throw new Exception("Can not insert test fee quote with policies.");
                }
            }
        }
Exemplo n.º 11
0
 protected void InsertFeeQuote(UserAndIssuer userAndIssuer = null)
 {
     using (MockedClock.NowIs(DateTime.UtcNow.AddMinutes(-1)))
     {
         var feeQuote = new FeeQuote
         {
             Id               = 1,
             CreatedAt        = MockedClock.UtcNow,
             ValidFrom        = MockedClock.UtcNow,
             Identity         = userAndIssuer?.Identity,
             IdentityProvider = userAndIssuer?.IdentityProvider,
             Fees             = new[] {
                 new Fee {
                     FeeType   = Const.FeeType.Standard,
                     MiningFee = new FeeAmount {
                         Satoshis      = 500,
                         Bytes         = 1000,
                         FeeAmountType = Const.AmountType.MiningFee
                     },
                     RelayFee = new FeeAmount {
                         Satoshis      = 250,
                         Bytes         = 1000,
                         FeeAmountType = Const.AmountType.RelayFee
                     },
                 },
                 new Fee {
                     FeeType   = Const.FeeType.Data,
                     MiningFee = new FeeAmount {
                         Satoshis      = 500,
                         Bytes         = 1000,
                         FeeAmountType = Const.AmountType.MiningFee
                     },
                     RelayFee = new FeeAmount {
                         Satoshis      = 250,
                         Bytes         = 1000,
                         FeeAmountType = Const.AmountType.RelayFee
                     },
                 },
             }
         };
         if (FeeQuoteRepository.InsertFeeQuoteAsync(feeQuote).Result == null)
         {
             throw new Exception("Can not insert test fee quote");
         }
     }
 }
        public async Task TestFeeQuotesValidOverExpiryGetParameters()
        {
            // arrange
            var entryPostWithIdentity = GetItemToCreateWithIdentity();

            var(entryResponsePostIdentity, _) = await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(Client, entryPostWithIdentity, HttpStatusCode.Created);

            CheckWasCreatedFrom(entryPostWithIdentity, entryResponsePostIdentity);

            var entryPost = GetItemToCreate();

            entryPost.Id = 2;
            await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(Client, entryPost, HttpStatusCode.Created);

            entryPost.Id = 3;
            var(entryResponsePost, _) = await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(Client, entryPost, HttpStatusCode.Created);

            // act
            using (MockedClock.NowIs(entryResponsePost.CreatedAt.AddMinutes(FeeQuoteRepositoryMock.quoteExpiryMinutes * 2)))
            {
                // check GET for identity
                var getEntries = await Get <FeeQuoteConfigViewModelGet[]>(Client, UrlForValidFeeQuotesKey(MockedIdentity), HttpStatusCode.OK);

                CheckWasCreatedFrom(entryPostWithIdentity, getEntries.Single());

                // check GET for anonymous
                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(Client, UrlForValidFeeQuotesKey(null) + $"&anonymous=true", HttpStatusCode.OK);

                Assert.AreEqual(1, getEntries.Length);
                Assert.AreEqual(entryPost.Id, getEntries.Single().Id);

                // check GET for identity+anonymous
                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(Client, UrlForValidFeeQuotesKey(MockedIdentity) + $"&anonymous=true", HttpStatusCode.OK);

                Assert.AreEqual(2, getEntries.Length);

                // check GET all
                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(Client, UrlForValidFeeQuotesKey(null), HttpStatusCode.OK);

                Assert.AreEqual(2, getEntries.Length);
            }
        }
Exemplo n.º 13
0
        public async Task TestFeeQuotesForSimilarIdentitiesAndProviders()
        {
            // arrange
            var entryPostWithIdentity = GetItemToCreateWithIdentity();

            entryPostWithIdentity.Identity         = "test_";
            entryPostWithIdentity.IdentityProvider = "underline";
            await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entryPostWithIdentity, HttpStatusCode.Created);

            var entryPostWithIdentity2 = GetItemToCreateWithIdentity();

            entryPostWithIdentity2.Id               = 2;
            entryPostWithIdentity2.Identity         = "test";
            entryPostWithIdentity2.IdentityProvider = "_underline";
            await Post <FeeQuoteViewModelCreate, FeeQuoteConfigViewModelGet>(client, entryPostWithIdentity2, HttpStatusCode.Created);

            // test if we properly check for keys in cache
            using (MockedClock.NowIs(DateTime.UtcNow.AddMinutes(1)))
            {
                var getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client,
                                                                          UrlForCurrentFeeQuoteKey(new UserAndIssuer()
                {
                    Identity = entryPostWithIdentity.Identity,
                    IdentityProvider = entryPostWithIdentity.IdentityProvider
                }), HttpStatusCode.OK);

                CheckWasCreatedFrom(entryPostWithIdentity, getEntries.Single());

                getEntries = await Get <FeeQuoteConfigViewModelGet[]>(client,
                                                                      UrlForCurrentFeeQuoteKey(new UserAndIssuer()
                {
                    Identity = entryPostWithIdentity2.Identity,
                    IdentityProvider = entryPostWithIdentity2.IdentityProvider
                }), HttpStatusCode.OK);

                CheckWasCreatedFrom(entryPostWithIdentity2, getEntries.Single());
            }
        }
Exemplo n.º 14
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);
            }
        }