Esempio n. 1
0
        public void Node_issues_while_building_transfer_amount_transaction()
        {
            //ARRANGE
            var client = PrepareClient <AppSettings>((options) =>
            {
                var aggregator = CreateMocksAndSetupFactories(options);

                options.IntegrationName = $"{nameof(TransactionExecutorClientTests)}+{nameof(Node_issues_while_building_transfer_amount_transaction)}";
                aggregator.HealthProvider.Setup(x => x.GetDiseaseAsync()).ReturnsAsync(Disease);
                aggregator.TransferAmountTransactionBuilder.Setup(x => x.BuildTransferAmountAsync(It.IsAny <BuildTransferAmountTransactionRequest>()))
                .ThrowsAsync(
                    new TransactionBuildingException(
                        TransactionBuildingError.RetryLater,
                        "Node is too busy"));
            });

            //ACT && ASSERT

            Assert.ThrowsAsync <TransactionBuildingWebApiException>(async() =>
            {
                var transfers = new[]
                {
                    new Transfer(
                        new Asset("asset"),
                        UMoney.Create(1000000000, 4),
                        new Address("x1"),
                        new Address("x2")),
                };
                var request = new BuildTransferAmountTransactionRequest(transfers, Array.Empty <Fee>());
                await client.BuildTransferAmountTransactionAsync(request);
            });
        }
Esempio n. 2
0
        private static async Task <object> BuildInvalidTransactionAsync(ITransactionsExecutorApi client)
        {
            Console.WriteLine("Building the invalid transaction...");

            return(await client.BuildTransferAmountTransactionAsync
                   (
                       new BuildTransferAmountTransactionRequest
                       (
                           new[]
            {
                new Transfer
                (
                    new Asset("STEEM"),
                    UMoney.Create(100, 3),
                    "Test:c021d892538b4a7a8520ae46f368c00f",
                    "Test:0662c0c7b9954373a5803fab41d97774"
                ),
                new Transfer
                (
                    new Asset("STEEM"),
                    UMoney.Create(50, 3),
                    "Test:c021d892538b4a7a8520ae46f368c00f",
                    "Test:0662c0c7b9954373a5803fab41d97774"
                )
            },
                           new []
            {
                new Fee(new Asset("STEEM"), UMoney.Create(0.001m, 3))
            }
                       )
                   ));
        }
Esempio n. 3
0
        public void Bad_request_while_estimating_transfer_amount_transaction()
        {
            //ARRANGE
            var client = PrepareClient <AppSettings>((options) =>
            {
                var aggregator = CreateMocksAndSetupFactories(options);

                options.IntegrationName = $"{nameof(TransactionExecutorClientTests)}+{nameof(Bad_request_while_estimating_transfer_amount_transaction)}";
                aggregator.HealthProvider.Setup(x => x.GetDiseaseAsync()).ReturnsAsync(Disease);
                aggregator.TransactionEstimator.Setup(x => x.EstimateTransferAmountAsync(It.IsAny <EstimateTransferAmountTransactionRequest>()))
                .ThrowsAsync(new RequestValidationException("Not VALID"));
            });

            //ACT && ASSERT
            Assert.ThrowsAsync <BadRequestWebApiException>(async() =>
            {
                var transfers = new[]
                {
                    new Transfer(
                        new Asset("asset"),
                        UMoney.Create(1000000000, 4),
                        new Address("x1"),
                        new Address("x2")),
                };
                var request = new EstimateTransferAmountTransactionRequest(transfers);
                await client.EstimateTransferAmountTransactionAsync(request);
            });
        }
Esempio n. 4
0
 public void Money_Should_Be_Serializable_To_Json()
 {
     JsonConvert
     .SerializeObject(UMoney.Create(10, 5))
     .Should()
     .Be("\"10.00000\"");
 }
Esempio n. 5
0
        public async Task Build_transfer_amount_transaction()
        {
            //ARRANGE
            string transactionResponse = "transactionResponse";

            var client = PrepareClient <AppSettings>((options) =>
            {
                var aggregator = CreateMocksAndSetupFactories(options);

                options.IntegrationName = $"{nameof(TransactionExecutorClientTests)}+{nameof(Build_transfer_amount_transaction)}";
                aggregator.HealthProvider.Setup(x => x.GetDiseaseAsync()).ReturnsAsync(Disease);
                aggregator.TransferAmountTransactionBuilder.Setup(x => x.BuildTransferAmountAsync(It.IsAny <BuildTransferAmountTransactionRequest>()))
                .ReturnsAsync(new BuildTransactionResponse(Base64String.Encode(transactionResponse)));
            });

            //ACT
            var transfers = new[]
            {
                new Transfer(
                    new Asset("asset"),
                    UMoney.Create(1000000000, 4),
                    new Address("x1"),
                    new Address("x2")),
            };
            var request = new BuildTransferAmountTransactionRequest(transfers, Array.Empty <Fee>());
            var result  = await client.BuildTransferAmountTransactionAsync(request);

            //ASSERT

            Assert.True(result != null);
            Assert.True(result.TransactionContext.DecodeToString() == transactionResponse);
        }
Esempio n. 6
0
 public void Money_Should_Be_Deserializable_From_Json()
 {
     JsonConvert
     .DeserializeObject <UMoney>("\"10.00000\"")
     .Should()
     .Be(UMoney.Create(10, 5));
 }
Esempio n. 7
0
        public void Test_that_coins_to_receive_should_be_numbers_in_a_row_starting_from_zero(string coinsToReceiveNumbers, bool shouldThrow)
        {
            var coinToSpend = new CoinToSpend
                              (
                new CoinId("1", 1),
                new Asset("KIN"),
                UMoney.Create(100, 3),
                "A"
                              );
            var coinsToReceive = coinsToReceiveNumbers
                                 .Split(',')
                                 .Select(x => new CoinToReceive
                                         (
                                             int.Parse(x),
                                             new Asset("KIN"),
                                             UMoney.Create(1, 3),
                                             "B"
                                         ))
                                 .ToArray();

            if (shouldThrow)
            {
                Assert.Throws <RequestValidationException>(() => TransactionCoinsValidator.Validate(new[] { coinToSpend }, coinsToReceive));
            }
            else
            {
                Assert.DoesNotThrow(() => TransactionCoinsValidator.Validate(new[] { coinToSpend }, coinsToReceive));
            }
        }
Esempio n. 8
0
        private static IEnumerable <UMoney> Values()
        {
            yield return(UMoney.Create(10.0000m));

            yield return(UMoney.Create(13.00m));

            yield return(UMoney.Create(10.300000m));
        }
Esempio n. 9
0
        public async Task Estimate_transfer_coins_transaction()
        {
            //ARRANGE
            var fees = new[]
            {
                new Fee(new Asset("asset"), UMoney.Create(1000, 4))
            };

            var client = PrepareClient <AppSettings>((options) =>
            {
                var aggregator = CreateMocksAndSetupFactories(options);

                options.IntegrationName = $"{nameof(TransactionExecutorClientTests)}+{nameof(Estimate_transfer_coins_transaction)}";
                aggregator.HealthProvider.Setup(x => x.GetDiseaseAsync()).ReturnsAsync(Disease);
                aggregator.TransferCoinsTransactionsEstimator
                .Setup(x => x.EstimateTransferCoinsAsync(It.IsAny <EstimateTransferCoinsTransactionRequest>()))
                .ReturnsAsync(new EstimateTransactionResponse(fees));
            });

            //ACT
            var coinsToSpend = new[]
            {
                new CoinToSpend(new CoinId("tx1", 0),
                                new Asset("assetId"),
                                UMoney.Create(1000, 4),
                                new Address("0x1"),
                                Base64String.Encode("context"),
                                1),
            };
            var coinsToReceive = new[]
            {
                new CoinToReceive(0,
                                  new Asset("assetId"),
                                  UMoney.Create(1000, 4),
                                  new Address("0x2"),
                                  new AddressTag("tag"),
                                  AddressTagType.Text
                                  ),
            };

            var request = new EstimateTransferCoinsTransactionRequest(coinsToSpend, coinsToReceive);
            var result  = await client.EstimateTransferCoinsTransactionAsync(request);

            //ASSERT
            Assert.NotNull(result);

            var estimation = result.EstimatedFees.SingleOrDefault();

            Assert.NotNull(estimation);
            Assert.AreEqual(new Asset("asset"), estimation.Asset);
            Assert.AreEqual(UMoney.Create(1000, 4), estimation.Amount);
        }
Esempio n. 10
0
 public void Test_that_single_transfer_is_allowed()
 {
     TransactionTransfersValidator.Validate(new List <Transfer>
     {
         new Transfer
         (
             new Asset("STEEM"),
             UMoney.Create(100, 3),
             "A",
             "B"
         )
     });
 }
Esempio n. 11
0
        public async Task Build_transfer_coins_transaction()
        {
            //ARRANGE
            string transactionResponse = "transactionResponse";

            var client = PrepareClient <AppSettings>((options) =>
            {
                var aggregator = CreateMocksAndSetupFactories(options);

                options.IntegrationName = $"{nameof(TransactionExecutorClientTests)}+{nameof(Build_transfer_coins_transaction)}";
                aggregator.HealthProvider.Setup(x => x.GetDiseaseAsync()).ReturnsAsync(Disease);
                aggregator.TransferCoinsTransactionsBuilder
                .Setup(x => x.BuildTransferCoinsAsync(It.IsAny <BuildTransferCoinsTransactionRequest>()))
                .ReturnsAsync(new BuildTransactionResponse(Base64String.Encode(transactionResponse)));
            });

            //ACT
            var coinsToSpend = new[]
            {
                new CoinToSpend(new CoinId("tx1", 0),
                                new Asset("assetId"),
                                UMoney.Create(1000, 4),
                                new Address("0x1"),
                                Base64String.Encode("context"),
                                1),
            };
            var coinsToReceive = new[]
            {
                new CoinToReceive(0,
                                  new Asset("assetId"),
                                  UMoney.Create(1000, 4),
                                  new Address("0x2"),
                                  new AddressTag("tag"),
                                  AddressTagType.Text
                                  ),
            };
            var expirationOptions = new ExpirationOptions(DateTime.Now + TimeSpan.FromDays(1));

            var request = new BuildTransferCoinsTransactionRequest(coinsToSpend, coinsToReceive, expirationOptions);
            var result  = await client.BuildTransferCoinsTransactionAsync(request);

            //ASSERT

            Assert.True(result != null);
            Assert.True(result.TransactionContext.DecodeToString() == transactionResponse);
        }
Esempio n. 12
0
        public void Bad_request_transfer_coins_transaction()
        {
            //ARRANGE

            var client = PrepareClient <AppSettings>((options) =>
            {
                var aggregator = CreateMocksAndSetupFactories(options);

                options.IntegrationName = $"{nameof(TransactionExecutorClientTests)}+{nameof(Bad_request_transfer_coins_transaction)}";
                aggregator.HealthProvider.Setup(x => x.GetDiseaseAsync()).ReturnsAsync(Disease);
                aggregator.TransferCoinsTransactionsBuilder
                .Setup(x => x.BuildTransferCoinsAsync(It.IsAny <BuildTransferCoinsTransactionRequest>()))
                .ThrowsAsync(new TransactionBuildingException(TransactionBuildingError.RetryLater, "some error"));
            });

            //ACT && ASSERT
            var coinsToSpend = new[]
            {
                new CoinToSpend(new CoinId("tx1", 0),
                                new Asset("assetId"),
                                UMoney.Create(1000, 4),
                                new Address("0x1"),
                                Base64String.Encode("context"),
                                1),
            };
            var coinsToReceive = new[]
            {
                new CoinToReceive(0,
                                  new Asset("assetId"),
                                  UMoney.Create(1000, 4),
                                  new Address("0x2"),
                                  new AddressTag("tag"),
                                  AddressTagType.Text
                                  ),
            };
            var expirationOptions = new ExpirationOptions(DateTime.Now + TimeSpan.FromDays(1));

            Assert.ThrowsAsync <TransactionBuildingWebApiException>(async() =>
            {
                var request = new BuildTransferCoinsTransactionRequest(coinsToSpend, coinsToReceive, expirationOptions);
                await client.BuildTransferCoinsTransactionAsync(request);
            });
        }
Esempio n. 13
0
        public void Internal_server_error_estimate_transfer_coins_transaction()
        {
            //ARRANGE
            var client = PrepareClient <AppSettings>((options) =>
            {
                var aggregator = CreateMocksAndSetupFactories(options);

                options.IntegrationName =
                    $"{nameof(TransactionExecutorClientTests)}+{nameof(Internal_server_error_estimate_transfer_coins_transaction)}";
                aggregator.HealthProvider.Setup(x => x.GetDiseaseAsync()).ReturnsAsync(Disease);
                aggregator.TransferCoinsTransactionsEstimator
                .Setup(x => x.EstimateTransferCoinsAsync(It.IsAny <EstimateTransferCoinsTransactionRequest>()))
                .ThrowsAsync(new Exception("some error"));
            });

            //ACT && ASSERT
            var coinsToSpend = new[]
            {
                new CoinToSpend(new CoinId("tx1", 0),
                                new Asset("assetId"),
                                UMoney.Create(1000, 4),
                                new Address("0x1"),
                                Base64String.Encode("context"),
                                1),
            };
            var coinsToReceive = new[]
            {
                new CoinToReceive(0,
                                  new Asset("assetId"),
                                  UMoney.Create(1000, 4),
                                  new Address("0x2"),
                                  new AddressTag("tag"),
                                  AddressTagType.Text
                                  ),
            };

            Assert.ThrowsAsync <InternalServerErrorWebApiException>(async() =>
            {
                var request = new EstimateTransferCoinsTransactionRequest(coinsToSpend, coinsToReceive);
                await client.EstimateTransferCoinsTransactionAsync(request);
            });
        }
Esempio n. 14
0
        public async Task ReadBlockAsync(long blockNumber, IBlockListener listener)
        {
            var blockId         = Guid.NewGuid().ToString("N");
            var previousBlockId = Guid.NewGuid().ToString("N");

            listener.HandleRawBlock("raw-block".ToBase64(), blockId);

            var transactionsListener = listener.StartBlockTransactionsHandling
                                       (
                new BlockHeaderReadEvent
                (
                    blockNumber,
                    blockId,
                    DateTime.UtcNow,
                    100,
                    1,
                    previousBlockId
                )
                                       );

            var transactionId = new TransactionId(Guid.NewGuid().ToString("N"));

            await transactionsListener.HandleRawTransactionAsync("raw-transaction".ToBase64(), transactionId);

            transactionsListener.HandleExecutedTransaction
            (
                new TransferAmountExecutedTransaction
                (
                    transactionNumber: 1,
                    transactionId: transactionId,
                    balanceChanges: new[]
            {
                new BalanceChange("1", new Asset("STEEM"), Money.Create(123, 4), "abc")
            },
                    fees: new[]
            {
                new Fee(new Asset("STEEM"), UMoney.Create(0.0001m, 4)),
            },
                    isIrreversible: true
                )
            );
        }
Esempio n. 15
0
        public void Nullable_Money_Should_Be_Serializable_To_Json()
        {
            // ReSharper disable once JoinDeclarationAndInitializer
            UMoney?value;

            value = UMoney.Create(10, 5);

            JsonConvert
            .SerializeObject(value)
            .Should()
            .Be("\"10.00000\"");

            value = null;

            JsonConvert
            // ReSharper disable once ExpressionIsAlwaysNull
            .SerializeObject(value)
            .Should()
            .Be("null");
        }
Esempio n. 16
0
        public void Test_that_empty_collections_are_not_allowed()
        {
            // Arrange

            var coinToSpend = new CoinToSpend
                              (
                new CoinId("1", 1),
                new Asset("KIN"),
                UMoney.Create(100, 3),
                "A"
                              );
            var coinToReceive = new CoinToReceive
                                (
                0,
                new Asset("KIN"),
                UMoney.Create(100, 3),
                "A"
                                );

            // Act, Throw

            Assert.Throws <RequestValidationException>
            (
                () => TransactionCoinsValidator.Validate(null, new[] { coinToReceive })
            );

            Assert.Throws <RequestValidationException>
            (
                () => TransactionCoinsValidator.Validate(Array.Empty <CoinToSpend>(), new[] { coinToReceive })
            );

            Assert.Throws <RequestValidationException>
            (
                () => TransactionCoinsValidator.Validate(new[] { coinToSpend }, null)
            );

            Assert.Throws <RequestValidationException>
            (
                () => TransactionCoinsValidator.Validate(new[] { coinToSpend }, Array.Empty <CoinToReceive>())
            );
        }
Esempio n. 17
0
        public void Test_that_duplicated_transfers_are_not_allowed()
        {
            var transfers = new List <Transfer>
            {
                new Transfer
                (
                    new Asset("XRP"),
                    UMoney.Create(100, 3),
                    "A",
                    "B"
                ),
                new Transfer
                (
                    new Asset("XRP"),
                    UMoney.Create(80, 5),
                    "A",
                    "B"
                )
            };

            Assert.Throws <RequestValidationException>(() => TransactionTransfersValidator.Validate(transfers));
        }
Esempio n. 18
0
        public async Task Estimate_transfer_amount_transaction()
        {
            //ARRANGE
            var fees = new[]
            {
                new Fee(new Asset("asset"), UMoney.Create(1000, 4))
            };

            var client = PrepareClient <AppSettings>((options) =>
            {
                var aggregator = CreateMocksAndSetupFactories(options);

                options.IntegrationName = $"{nameof(TransactionExecutorClientTests)}+{nameof(Estimate_transfer_amount_transaction)}";
                aggregator.HealthProvider.Setup(x => x.GetDiseaseAsync()).ReturnsAsync(Disease);
                aggregator.TransactionEstimator.Setup(x => x.EstimateTransferAmountAsync(It.IsAny <EstimateTransferAmountTransactionRequest>()))
                .ReturnsAsync(new EstimateTransactionResponse(fees));
            });

            //ACT
            var transfers = new[]
            {
                new Transfer(
                    new Asset("asset"),
                    UMoney.Create(1000000000, 4),
                    new Address("x1"),
                    new Address("x2")),
            };
            var request = new EstimateTransferAmountTransactionRequest(transfers);
            var result  = await client.EstimateTransferAmountTransactionAsync(request);

            //ASSERT
            Assert.NotNull(result);

            var estimation = result.EstimatedFees.SingleOrDefault();

            Assert.NotNull(estimation);
            Assert.AreEqual(new Asset("asset"), estimation.Asset);
            Assert.AreEqual(UMoney.Create(1000, 4), estimation.Amount);
        }
Esempio n. 19
0
        public void Test_that_sum_of_coins_to_send_equal_or_greater_than_sum_to_receive_for_each_assets(string assetsToSpend, string assetsToReceive, bool shouldThrow)
        {
            // Arrange

            var coinsToSpend = assetsToSpend
                               .Split(',')
                               .Select(x => x.Split(':'))
                               .Select(x => new CoinToSpend
                                       (
                                           new CoinId("1", 1),
                                           new Asset(x[0]),
                                           UMoney.Create(int.Parse(x[1]), 3),
                                           "A"
                                       ))
                               .ToArray();
            var coinsToReceive = assetsToReceive
                                 .Split(',')
                                 .Select(x => x.Split(':'))
                                 .Select((x, i) => new CoinToReceive
                                         (
                                             i,
                                             new Asset(x[0]),
                                             UMoney.Create(int.Parse(x[1]), 3),
                                             "A"
                                         ))
                                 .ToArray();

            // Act, Throw

            if (shouldThrow)
            {
                Assert.Throws <RequestValidationException>(() => TransactionCoinsValidator.Validate(coinsToSpend, coinsToReceive));
            }
            else
            {
                Assert.DoesNotThrow(() => TransactionCoinsValidator.Validate(coinsToSpend, coinsToReceive));
            }
        }
Esempio n. 20
0
        public void Test_that_sets_of_assets_should_match(string assetsToSpend, string assetsToReceive, bool shouldThrow)
        {
            // Arrange

            var coinsToSpend = assetsToSpend
                               .Split(',')
                               .Select(asset => new CoinToSpend
                                       (
                                           new CoinId("1", 1),
                                           new Asset(asset),
                                           UMoney.Create(100, 3),
                                           "A"
                                       ))
                               .ToArray();
            var coinsToReceive = assetsToReceive
                                 .Split(',')
                                 .Select((asset, i) => new CoinToReceive
                                         (
                                             i,
                                             new Asset(asset),
                                             UMoney.Create(100, 3),
                                             "A"
                                         ))
                                 .ToArray();

            // Act, Throw

            if (shouldThrow)
            {
                Assert.Throws <RequestValidationException>(() => TransactionCoinsValidator.Validate(coinsToSpend, coinsToReceive));
            }
            else
            {
                Assert.DoesNotThrow(() => TransactionCoinsValidator.Validate(coinsToSpend, coinsToReceive));
            }
        }
Esempio n. 21
0
 public void Test_that_multiple_transfers_are_allowed(
     string asset1,
     string asset2,
     string asset3,
     string source1,
     string source2,
     string source3,
     string destination1,
     string destination2,
     string destination3)
 {
     TransactionTransfersValidator.Validate(new List <Transfer>
     {
         new Transfer
         (
             new Asset(asset1),
             UMoney.Create(100, 3),
             source1,
             destination1
         ),
         new Transfer
         (
             new Asset(asset2),
             UMoney.Create(80, 5),
             source2,
             destination2
         ),
         new Transfer
         (
             new Asset(asset3),
             UMoney.Create(80, 5),
             source3,
             destination3
         )
     });
 }
        public async Task Block_listener_test()
        {
            //ARRANGE
            Mock <IRawObjectWriteOnlyRepository> rawObjectsRepository = null;
            var typeWaitHandles = new Dictionary <Type, ManualResetEventSlim>()
            {
                { typeof(BlockHeaderReadEvent), new ManualResetEventSlim() },
                { typeof(BlockNotFoundEvent), new ManualResetEventSlim() },
                { typeof(TransferAmountTransactionsBatchEvent), new ManualResetEventSlim() },
            };
            var blockEventsHandlerMock = BlockEventsHandlerCreateMock((intName, evt, headers, messagePublisher) =>
            {
                if (typeWaitHandles.TryGetValue(evt.GetType(), out var eventWaitHandle))
                {
                    eventWaitHandle.Set();
                }
            });

            var(client, apiFactory, testServer) = PrepareClient <AppSettings>(
                serverOptions =>
            {
                CreateMocks(
                    out var blockReader,
                    out var blockProvider);
                rawObjectsRepository = new Mock <IRawObjectWriteOnlyRepository>();
                rawObjectsRepository
                .Setup(x => x.SaveAsync(RawObjectType.Transaction, It.IsNotNull <string>(), It.IsNotNull <Base64String>()))
                .Returns(Task.CompletedTask)
                .Verifiable();

                async void CallBack(long blockNumber, IBlockListener blockListener)
                {
                    if (blockNumber == 2)
                    {
                        blockListener.HandleNotFoundBlock(new BlockNotFoundEvent(blockNumber));
                        return;
                    }

                    var asset = new Asset("assetId");

                    blockListener.HandleRawBlock(Base64String.Encode("raw-block"), "1");

                    var transactionsListener = blockListener.StartBlockTransactionsHandling
                                               (
                        new BlockHeaderReadEvent
                        (
                            1,
                            "1",
                            DateTime.UtcNow,
                            256,
                            5
                        )
                                               );

                    await transactionsListener.HandleRawTransactionAsync(Base64String.Encode("transaction.raw"), "tr1");

                    transactionsListener.HandleExecutedTransaction
                    (
                        new TransferAmountExecutedTransaction
                        (
                            1,
                            "tr1",
                            new[]
                    {
                        new BalanceChange
                        (
                            "1",
                            asset,
                            Money.Create(1000, 4),
                            new Address("0x2"),
                            new AddressTag("tag"),
                            AddressTagType.Text,
                            1)
                    },
                            new[]
                    {
                        new Fee(asset, UMoney.Create(10, 4))
                    },
                            true
                        )
                    );

                    await transactionsListener.HandleRawTransactionAsync(Base64String.Encode("transaction.raw"), "tr2");

                    transactionsListener.HandleExecutedTransaction
                    (
                        new TransferAmountExecutedTransaction
                        (
                            2,
                            "tr2",
                            new[]
                    {
                        new BalanceChange
                        (
                            "1",
                            asset,
                            Money.Create(100, 4),
                            new Address("0x3"),
                            new AddressTag("tag"),
                            AddressTagType.Text,
                            2)
                    },
                            new[]
                    {
                        new Fee(asset, UMoney.Create(10, 4))
                    },
                            true
                        )
                    );

                    await transactionsListener.HandleRawTransactionAsync(Base64String.Encode("transaction.raw"), "tr3");

                    transactionsListener.HandleExecutedTransaction
                    (
                        new TransferAmountExecutedTransaction
                        (
                            3,
                            "tr3",
                            new[]
                    {
                        new BalanceChange
                        (
                            "1",
                            asset,
                            Money.Create(500, 4),
                            new Address("0x4"),
                            new AddressTag("tag"),
                            AddressTagType.Text,
                            3)
                    },
                            new[]
                    {
                        new Fee(asset, UMoney.Create(10, 4))
                    },
                            true
                        )
                    );

                    await transactionsListener.HandleRawTransactionAsync(Base64String.Encode("transaction.raw"), "tr4");

                    transactionsListener.HandleFailedTransaction
                    (
                        new FailedTransaction
                        (
                            4,
                            "tr4",
                            TransactionBroadcastingError.TransientFailure,
                            "some error message",
                            new[]
                    {
                        new Fee(asset, UMoney.Create(10, 4))
                    }
                        )
                    );

                    await transactionsListener.HandleRawTransactionAsync(Base64String.Encode("transaction.raw"), "tr5");

                    transactionsListener.HandleFailedTransaction
                    (
                        new FailedTransaction
                        (
                            5,
                            "tr5",
                            TransactionBroadcastingError.TransientFailure,
                            "some error message",
                            new[]
                    {
                        new Fee(asset, UMoney.Create(10, 4))
                    }
                        )
                    );
                }

                serverOptions.IntegrationName = _integrationName;
                serverOptions.UseTransferAmountTransactionsModel();

                blockReader
                .Setup(x => x.ReadBlockAsync(It.IsAny <long>(), It.IsAny <IBlockListener>()))
                .Returns(Task.CompletedTask)
                .Callback((Action <long, IBlockListener>)CallBack);

                serverOptions.UseSettings = (services, set) =>
                {
                    services.AddSingleton(rawObjectsRepository.Object);
                };
                ConfigureFactories(serverOptions,
                                   blockReader,
                                   blockProvider,
                                   false);//pushing is set here
            },
                clientOptions =>
            {
                clientOptions.BlockEventsHandlerFactory = context => blockEventsHandlerMock.Object;
                clientOptions.RabbitVhost        = _rabbitMqSettings.Vhost;
                clientOptions.RabbitMqConnString = _rabbitMqSettings.GetConnectionString();
                clientOptions.AddIntegration(_integrationName);
            });

            var block1CorrelationId = "correlation-id-1";
            var block2CorrelationId = "correlation-id-2";

            //ACT
            using (testServer)
                using (client)
                {
                    client.Initialize();
                    client.StartListening();

                    var apiBlocksReader = apiFactory.Create(_integrationName);
                    await apiBlocksReader.SendAsync(new ReadBlockCommand(1), block1CorrelationId);

                    await apiBlocksReader.SendAsync(new ReadBlockCommand(2), block2CorrelationId);

                    foreach (var manualResetEventSlim in typeWaitHandles)
                    {
                        if (!manualResetEventSlim.Value.Wait(Waiting.Timeout))
                        {
                            Console.WriteLine($"Event {manualResetEventSlim.Key} has been missed!");
                        }
                    }
                }

            //ASSERT
            rawObjectsRepository
            .Verify(x => x.SaveAsync(RawObjectType.Transaction, It.IsNotNull <string>(), It.IsNotNull <Base64String>()), Times.AtLeast(3));

            rawObjectsRepository
            .Verify(x => x.SaveAsync(RawObjectType.Block, It.IsNotNull <string>(), It.IsNotNull <Base64String>()), Times.AtLeast(1));

            blockEventsHandlerMock
            .Verify(x =>
                    x.HandleAsync(
                        _integrationName,
                        It.Is <BlockHeaderReadEvent>(b => b.BlockId == "1"),
                        It.Is <MessageHeaders>(h => h.CorrelationId == block1CorrelationId),
                        It.IsNotNull <IMessagePublisher>()),
                    Times.AtLeastOnce);
            blockEventsHandlerMock
            .Verify(x =>
                    x.HandleAsync(
                        _integrationName,
                        It.Is <BlockHeaderReadEvent>(b => b.BlockId != "1"),
                        It.IsNotNull <MessageHeaders>(),
                        It.IsNotNull <IMessagePublisher>()),
                    Times.Never);

            blockEventsHandlerMock
            .Verify(x =>
                    x.HandleAsync(
                        _integrationName,
                        It.Is <BlockNotFoundEvent>(b => b.BlockNumber == 2),
                        It.Is <MessageHeaders>(h => h.CorrelationId == block2CorrelationId),
                        It.IsNotNull <IMessagePublisher>()),
                    Times.AtLeastOnce);
            blockEventsHandlerMock
            .Verify(x =>
                    x.HandleAsync(
                        _integrationName,
                        It.Is <BlockNotFoundEvent>(b => b.BlockNumber != 2),
                        It.IsNotNull <MessageHeaders>(),
                        It.IsNotNull <IMessagePublisher>()),
                    Times.Never);

            // Batch 1

            blockEventsHandlerMock
            .Verify(x => x.HandleAsync(
                        _integrationName,
                        It.Is <TransferAmountTransactionsBatchEvent>(b => b.BlockId == "1" &&
                                                                     b.FailedTransactions.Count == 0 &&
                                                                     b.TransferAmountExecutedTransactions.Count == 2),
                        It.Is <MessageHeaders>(h => h.CorrelationId == block1CorrelationId),
                        It.IsNotNull <IMessagePublisher>()),
                    Times.AtLeastOnce);

            // Batch 2

            blockEventsHandlerMock
            .Verify(x => x.HandleAsync(
                        _integrationName,
                        It.Is <TransferAmountTransactionsBatchEvent>(b => b.BlockId == "1" &&
                                                                     b.FailedTransactions.Count == 1 &&
                                                                     b.TransferAmountExecutedTransactions.Count == 1),
                        It.Is <MessageHeaders>(h => h.CorrelationId == block1CorrelationId),
                        It.IsNotNull <IMessagePublisher>()),
                    Times.AtLeastOnce);

            // Batch 3

            blockEventsHandlerMock
            .Verify(x => x.HandleAsync(
                        _integrationName,
                        It.Is <TransferAmountTransactionsBatchEvent>(b => b.BlockId == "1" &&
                                                                     b.FailedTransactions.Count == 1 &&
                                                                     b.TransferAmountExecutedTransactions.Count == 0),
                        It.Is <MessageHeaders>(h => h.CorrelationId == block1CorrelationId),
                        It.IsNotNull <IMessagePublisher>()),
                    Times.AtLeastOnce);
        }