public DepositExtractorTests()
        {
            this.network             = CirrusNetwork.NetworksSelector.Regtest();
            this.counterChainNetwork = Networks.Stratis.Regtest();

            this.loggerFactory      = Substitute.For <ILoggerFactory>();
            this.settings           = Substitute.For <IFederatedPegSettings>();
            this.opReturnDataReader = Substitute.For <IOpReturnDataReader>();

            this.addressHelper = new MultisigAddressHelper(this.network, this.counterChainNetwork);

            this.settings.MultiSigRedeemScript.Returns(this.addressHelper.PayToMultiSig);

            this.settings.GetWithdrawalTransactionFee(Arg.Any <int>()).ReturnsForAnyArgs((x) =>
            {
                int numInputs = x.ArgAt <int>(0);

                return(FederatedPegSettings.BaseTransactionFee + FederatedPegSettings.InputTransactionFee * numInputs);
            });

            this.opReturnDataReader.TryGetTargetAddress(null, out string address).Returns(callInfo => { callInfo[1] = null; return(false); });

            this.transactionBuilder = new TestTransactionBuilder();

            this.depositExtractor = new DepositExtractor(
                this.loggerFactory,
                this.settings,
                this.opReturnDataReader);
        }
예제 #2
0
        public void RetrieveDeposits_ReturnsSmallAndNormalDeposits_Scenario5()
        {
            // Create a "chain" of 20 blocks.
            this.blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(20, true, this.mainChainNetwork);

            // Add 4 small deposits to blocks 5 through to 8 (the amounts are less than 10).
            for (int i = 5; i <= 8; i++)
            {
                this.blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins(i), this.opReturnBytes);
            }

            // Add 6 normal deposits to block 11 through to 16.
            for (int i = 11; i <= 16; i++)
            {
                this.blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins(i), this.opReturnBytes);
            }

            this.consensusManager.GetBlockData(Arg.Any <List <uint256> >()).Returns(delegate(CallInfo info)
            {
                var hashes = (List <uint256>)info[0];
                return(hashes.Select((hash) => this.blocks.Single(x => x.ChainedHeader.HashBlock == hash)).ToArray());
            });
            this.consensusManager.Tip.Returns(this.blocks.Last().ChainedHeader);

            var depositExtractor = new DepositExtractor(this.federatedPegSettings, this.network, this.opReturnDataReader);

            var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.federatedPegSettings);

            SerializableResult <List <MaturedBlockDepositsModel> > depositsResult = maturedBlocksProvider.RetrieveDeposits(10);

            // Total deposits
            Assert.Equal(4, depositsResult.Value.SelectMany(b => b.Deposits).Count());
        }
예제 #3
0
        public DepositExtractorTests()
        {
            this.network = new CirrusRegTest();

            ILoggerFactory loggerFactory = Substitute.For <ILoggerFactory>();

            this.addressHelper = new MultisigAddressHelper(this.network, new StraxRegTest());

            this.federationSettings = Substitute.For <IFederatedPegSettings>();
            this.federationSettings.SmallDepositThresholdAmount.Returns(Money.Coins(10));
            this.federationSettings.NormalDepositThresholdAmount.Returns(Money.Coins(20));

            this.federationSettings.MultiSigRedeemScript.Returns(this.addressHelper.PayToMultiSig);
            this.federationSettings.GetWithdrawalTransactionFee(Arg.Any <int>()).ReturnsForAnyArgs((x) =>
            {
                int numInputs = x.ArgAt <int>(0);
                return(FederatedPegSettings.BaseTransactionFee + FederatedPegSettings.InputTransactionFee * numInputs);
            });

            this.opReturnDataReader = Substitute.For <IOpReturnDataReader>();
            this.opReturnDataReader.TryGetTargetAddress(null, out string address).Returns(callInfo => { callInfo[1] = null; return(false); });

            this.depositExtractor   = new DepositExtractor(loggerFactory, this.federationSettings, this.opReturnDataReader);
            this.transactionBuilder = new TestTransactionBuilder();
        }
        public DepositExtractorTests()
        {
            this.network = new CirrusRegTest();

            this.addressHelper = new MultisigAddressHelper(this.network, new StraxRegTest());

            this.conversionRequestRepository = Substitute.For <IConversionRequestRepository>();

            this.federationSettings = Substitute.For <IFederatedPegSettings>();
            this.federationSettings.IsMainChain.Returns(true);
            this.federationSettings.SmallDepositThresholdAmount.Returns(Money.Coins(10));
            this.federationSettings.NormalDepositThresholdAmount.Returns(Money.Coins(20));
            this.federationSettings.MultiSigRedeemScript.Returns(this.addressHelper.PayToMultiSig);

            this.opReturnDataReader = Substitute.For <IOpReturnDataReader>();
            this.opReturnDataReader.TryGetTargetAddress(null, out string address).Returns(callInfo => { callInfo[1] = null; return(false); });

            IExternalApiClient externalClient = Substitute.For <IExternalApiClient>();

            externalClient.EstimateConversionTransactionFeeAsync().Returns("1.0");
            this.depositExtractor   = new DepositExtractor(this.conversionRequestRepository, this.federationSettings, this.network, this.opReturnDataReader);
            this.transactionBuilder = new TestTransactionBuilder();

            this.retrievalTypeConfirmations = new Dictionary <DepositRetrievalType, int>
            {
                [DepositRetrievalType.Small]            = this.federationSettings.MinimumConfirmationsSmallDeposits,
                [DepositRetrievalType.Normal]           = this.federationSettings.MinimumConfirmationsNormalDeposits,
                [DepositRetrievalType.Large]            = this.federationSettings.MinimumConfirmationsLargeDeposits,
                [DepositRetrievalType.Distribution]     = this.federationSettings.MinimumConfirmationsDistributionDeposits,
                [DepositRetrievalType.ConversionSmall]  = this.federationSettings.MinimumConfirmationsSmallDeposits,
                [DepositRetrievalType.ConversionNormal] = this.federationSettings.MinimumConfirmationsNormalDeposits,
                [DepositRetrievalType.ConversionLarge]  = this.federationSettings.MinimumConfirmationsLargeDeposits
            };
        }
        public async Task RetrieveDeposits_ReturnsLargeDeposits_Scenario6_Async()
        {
            // Create a "chain" of 20 blocks.
            this.blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(20, true, this.mainChainNetwork);

            // Add 4 small deposits to blocks 5 through to 8 (the amounts are less than 10).
            for (int i = 5; i <= 8; i++)
            {
                this.blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins(i), this.opReturnBytes);
            }

            // Add 6 normal deposits to block 11 through to 16.
            for (int i = 11; i <= 16; i++)
            {
                this.blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins(i), this.opReturnBytes);
            }

            // Add 6 large deposits to block 11 through to 16.
            for (int i = 11; i <= 16; i++)
            {
                this.blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins((long)this.federatedPegSettings.NormalDepositThresholdAmount + 1), this.opReturnBytes);
            }

            this.consensusManager.Tip.Returns(this.blocks.Last().ChainedHeader);
            var depositExtractor      = new DepositExtractor(this.conversionRequestRepository, this.federatedPegSettings, this.network, this.opReturnDataReader);
            var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.federatedPegSettings);

            SerializableResult <List <MaturedBlockDepositsModel> > depositsResult = await maturedBlocksProvider.RetrieveDepositsAsync(10);

            // Total deposits
            Assert.Equal(4, depositsResult.Value.SelectMany(b => b.Deposits).Count());
        }
        public async Task RetrieveDeposits_ReturnsSmallAndNormalDeposits_Scenario3_Async()
        {
            // Create a "chain" of 30 blocks.
            this.blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(30, true, this.mainChainNetwork);

            // Add 6 small deposits to blocks 8 through to 13 (the amounts are less than 10).
            for (int i = 8; i <= 13; i++)
            {
                this.blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins(8), this.opReturnBytes);
            }

            // Add 5 normal deposits to block 11 through to 15.
            for (int i = 11; i <= 15; i++)
            {
                this.blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins(i), this.opReturnBytes);
            }

            this.consensusManager.Tip.Returns(this.blocks.Last().ChainedHeader);
            var depositExtractor = new DepositExtractor(this.conversionRequestRepository, this.federatedPegSettings, this.network, this.opReturnDataReader);

            var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.federatedPegSettings);

            SerializableResult <List <MaturedBlockDepositsModel> > depositsResult = await maturedBlocksProvider.RetrieveDepositsAsync(5);

            // Total deposits
            Assert.Equal(11, depositsResult.Value.SelectMany(b => b.Deposits).Count());

            // Small Deposits
            Assert.Equal(6, depositsResult.Value.SelectMany(b => b.Deposits).Where(d => d.RetrievalType == DepositRetrievalType.Small).Count());

            // Normal Deposits
            Assert.Equal(5, depositsResult.Value.SelectMany(b => b.Deposits).Where(d => d.RetrievalType == DepositRetrievalType.Normal).Count());
        }
        public void RetrieveDeposits_ReturnsLargeDeposits_Scenario7()
        {
            // Create a "chain" of 40 blocks.
            List <ChainedHeaderBlock> blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(40, null, true);

            // Add 4 small deposits to blocks 5 through to 8 (the amounts are less than 10).
            for (int i = 5; i <= 8; i++)
            {
                blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, blocks[i].Block, Money.Coins(i), this.opReturnBytes);
            }

            // Add 6 normal deposits to block 11 through to 16.
            for (int i = 11; i <= 16; i++)
            {
                blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, blocks[i].Block, Money.Coins(i), this.opReturnBytes);
            }

            // Add 6 large deposits to block 11 through to 16.
            for (int i = 11; i <= 16; i++)
            {
                blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, blocks[i].Block, Money.Coins((long)this.federatedPegSettings.NormalDepositThresholdAmount + 1), this.opReturnBytes);
            }

            this.consensusManager.GetBlockData(Arg.Any <List <uint256> >()).Returns(delegate(CallInfo info)
            {
                var hashes = (List <uint256>)info[0];
                return(hashes.Select((hash) => blocks.Single(x => x.ChainedHeader.HashBlock == hash)).ToArray());
            });
            this.consensusManager.Tip.Returns(blocks.Last().ChainedHeader);

            var depositExtractor = new DepositExtractor(this.loggerFactory, this.federatedPegSettings, this.opReturnDataReader);

            var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.federatedPegSettings, this.loggerFactory);

            SerializableResult <List <MaturedBlockDepositsModel> > depositsResult = maturedBlocksProvider.RetrieveDeposits(10);

            // Total deposits
            Assert.Equal(12, depositsResult.Value.SelectMany(b => b.Deposits).Count());

            // Small Deposits
            Assert.Empty(depositsResult.Value.SelectMany(b => b.Deposits).Where(d => d.RetrievalType == DepositRetrievalType.Small));

            // Normal Deposits
            Assert.Equal(6, depositsResult.Value.SelectMany(b => b.Deposits).Where(d => d.RetrievalType == DepositRetrievalType.Normal).Count());

            // Large Deposits
            Assert.Equal(6, depositsResult.Value.SelectMany(b => b.Deposits).Where(d => d.RetrievalType == DepositRetrievalType.Large).Count());
        }
예제 #8
0
        public void RewardClaimer_RetrieveDeposits_Scenario1()
        {
            // Create a "chain" of 30 blocks.
            this.blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(30, true, network: this.network, chainIndexer: this.chainIndexer, withCoinbaseAndCoinStake: true, createCirrusReward: true);
            var rewardClaimer = new RewardClaimer(this.broadCasterManager, this.chainIndexer, this.consensusManager, this.loggerFactory, this.network, this.signals, this.initialBlockDownloadState);

            var depositExtractor = new DepositExtractor(this.federatedPegSettings, this.network, this.opReturnDataReader);

            // Add 5 distribution deposits from block 11 through to 15.
            for (int i = 11; i <= 15; i++)
            {
                Transaction rewardTransaction = rewardClaimer.BuildRewardTransaction();
                IDeposit    deposit           = depositExtractor.ExtractDepositFromTransaction(rewardTransaction, i, this.blocks[i].Block.GetHash());
                Assert.NotNull(deposit);
            }
        }
        public DepositExtractorTests()
        {
            this.network = new CirrusRegTest();

            this.addressHelper = new MultisigAddressHelper(this.network, new StraxRegTest());

            this.federationSettings = Substitute.For <IFederatedPegSettings>();
            this.federationSettings.SmallDepositThresholdAmount.Returns(Money.Coins(10));
            this.federationSettings.NormalDepositThresholdAmount.Returns(Money.Coins(20));
            this.federationSettings.MultiSigRedeemScript.Returns(this.addressHelper.PayToMultiSig);

            this.opReturnDataReader = Substitute.For <IOpReturnDataReader>();
            this.opReturnDataReader.TryGetTargetAddress(null, out string address).Returns(callInfo => { callInfo[1] = null; return(false); });

            this.depositExtractor   = new DepositExtractor(this.federationSettings, this.network, this.opReturnDataReader);
            this.transactionBuilder = new TestTransactionBuilder();
        }
예제 #10
0
        public void RetrieveDeposits_ReturnsDataToAdvanceNextMaturedBlockHeight()
        {
            // Create a "chain" of 20 blocks.
            this.blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(20, true, this.mainChainNetwork);

            // Add 6 normal deposits to block 11 through to 16.
            for (int i = 11; i < 17; i++)
            {
                this.blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins(i), this.opReturnBytes);
            }

            // Add 4 faster deposits to blocks 5 through to 9 (the amounts are less than 10).
            for (int i = 5; i < 9; i++)
            {
                this.blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins(i), this.opReturnBytes);
            }

            this.consensusManager.GetBlockData(Arg.Any <List <uint256> >()).Returns(delegate(CallInfo info)
            {
                var hashes = (List <uint256>)info[0];
                return(hashes.Select((hash) => this.blocks.Single(x => x.ChainedHeader.HashBlock == hash && x.ChainedHeader.Height <= this.consensusManager.Tip.Height)).ToArray());
            });

            var depositExtractor = new DepositExtractor(this.federatedPegSettings, this.network, this.opReturnDataReader);

            var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.federatedPegSettings);

            int nextMaturedBlockHeight = 1;

            for (int i = 1; i < this.blocks.Count; i++)
            {
                this.consensusManager.Tip.Returns(this.blocks[i].ChainedHeader);

                SerializableResult <List <MaturedBlockDepositsModel> > depositsResult = maturedBlocksProvider.RetrieveDeposits(nextMaturedBlockHeight);

                if (depositsResult?.Value != null && nextMaturedBlockHeight == depositsResult.Value.Min(b => b.BlockInfo.BlockHeight))
                {
                    nextMaturedBlockHeight = depositsResult.Value.Max(b => b.BlockInfo.BlockHeight) + 1;
                }
            }

            // Test whether the returned data is able to advance the NextMaturedBlockHeight.
            Assert.Equal(21, nextMaturedBlockHeight);
        }
예제 #11
0
        public void DoTest()
        {
            var transactionRequest = new BuildTransactionRequest()
            {
                FeeAmount = "0.01",
                // Change this to the address that should receive the funds.
                OpReturnData     = "PLv2NAsyn22cNbk5veopWCkypaN6DBR27L",
                AccountName      = "account 0",
                AllowUnconfirmed = true,
                Recipients       = new List <RecipientModel> {
                    new RecipientModel {
                        DestinationAddress = "2MyKFLbvhSouDYeAHhxsj9a5A4oV71j7SPR",
                        Amount             = "1.1"
                    }
                },
                Password   = "******",
                WalletName = "test"
            };

            WalletBuildTransactionModel model = Post <BuildTransactionRequest, WalletBuildTransactionModel>(
                "http://127.0.0.1:38221/api/wallet/build-transaction", transactionRequest);

            var transaction = new PosTransaction(model.Hex);

            var      reader    = new OpReturnDataReader(this.loggerFactory, Networks.Stratis.Testnet());
            var      extractor = new DepositExtractor(this.loggerFactory, this.federationGatewaySettings, reader, this.fullNode);
            IDeposit deposit   = extractor.ExtractDepositFromTransaction(transaction, 2, 1);

            Assert.NotNull(deposit);
            Assert.Equal(transaction.GetHash(), deposit.Id);
            Assert.Equal(transactionRequest.OpReturnData, deposit.TargetAddress);
            Assert.Equal(Money.Parse(transactionRequest.Recipients[0].Amount), deposit.Amount);
            Assert.Equal((uint256)1, deposit.BlockHash);
            Assert.Equal(2, deposit.BlockNumber);

            // Post the transaction
            var sendRequest = new SendTransactionRequest()
            {
                Hex = model.Hex
            };

            WalletSendTransactionModel model2 = Post <SendTransactionRequest, WalletSendTransactionModel>(
                "http://127.0.0.1:38221/api/wallet/send-transaction", sendRequest);
        }
        public async Task RetrieveDeposits_ReturnsLargeDeposits_Scenario8_Async()
        {
            // Create a "chain" of 40 blocks.
            this.blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(40, true, this.mainChainNetwork);

            // Add 6 normal deposits to block 11 through to 16.
            for (int i = 11; i <= 16; i++)
            {
                this.blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins(i), this.opReturnBytes);
            }

            // Add 10 large deposits to block 14 through to 23.
            for (int i = 14; i <= 23; i++)
            {
                this.blocks[i].Block.AddTransaction(new Transaction());
                CreateDepositTransaction(this.targetAddress, this.blocks[i].Block, Money.Coins((long)this.federatedPegSettings.NormalDepositThresholdAmount + 1), this.opReturnBytes);
            }

            this.consensusManager.GetBlockData(Arg.Any <List <uint256> >()).Returns(delegate(CallInfo info)
            {
                var hashes = (List <uint256>)info[0];
                return(hashes.Select((hash) => this.blocks.Single(x => x.ChainedHeader.HashBlock == hash)).ToArray());
            });
            this.consensusManager.Tip.Returns(this.blocks.Last().ChainedHeader);

            var depositExtractor      = new DepositExtractor(this.conversionRequestRepository, this.federatedPegSettings, this.network, this.opReturnDataReader);
            var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.federatedPegSettings);

            SerializableResult <List <MaturedBlockDepositsModel> > depositsResult = await maturedBlocksProvider.RetrieveDepositsAsync(10);

            // Total deposits
            Assert.Equal(13, depositsResult.Value.SelectMany(b => b.Deposits).Count());

            // Small Deposits
            Assert.Empty(depositsResult.Value.SelectMany(b => b.Deposits).Where(d => d.RetrievalType == DepositRetrievalType.Small));

            // Normal Deposits
            Assert.Equal(6, depositsResult.Value.SelectMany(b => b.Deposits).Where(d => d.RetrievalType == DepositRetrievalType.Normal).Count());

            // Large Deposits
            Assert.Equal(7, depositsResult.Value.SelectMany(b => b.Deposits).Where(d => d.RetrievalType == DepositRetrievalType.Large).Count());
        }
        public void RewardClaimer_RetrieveSingleDeposits()
        {
            DataFolder dataFolder         = TestBase.CreateDataFolder(this);
            var        keyValueRepository = new LevelDbKeyValueRepository(dataFolder, this.dbreezeSerializer);

            // Create a "chain" of 30 blocks.
            this.blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(30, true, network: this.network, chainIndexer: this.chainIndexer, withCoinbaseAndCoinStake: true, createCirrusReward: true);
            using (var rewardClaimer = new RewardClaimer(this.broadCasterManager, this.chainIndexer, this.consensusManager, this.initialBlockDownloadState, keyValueRepository, this.network, this.signals))
            {
                var depositExtractor = new DepositExtractor(this.federatedPegSettings, this.network, this.opReturnDataReader);

                // Add 5 distribution deposits from block 11 through to 15.
                for (int i = 11; i <= 15; i++)
                {
                    Transaction rewardTransaction = rewardClaimer.BuildRewardTransaction(false);
                    IDeposit    deposit           = depositExtractor.ExtractDepositFromTransaction(rewardTransaction, i, this.blocks[i].Block.GetHash());
                    Assert.NotNull(deposit);
                }
            }
        }
        public DepositExtractorTests()
        {
            this.network = FederatedPegNetwork.NetworksSelector.Regtest();

            this.loggerFactory      = Substitute.For <ILoggerFactory>();
            this.settings           = Substitute.For <IFederationGatewaySettings>();
            this.opReturnDataReader = Substitute.For <IOpReturnDataReader>();

            this.addressHelper = new MultisigAddressHelper(this.network);

            this.settings.MultiSigRedeemScript.Returns(this.addressHelper.PayToMultiSig);
            this.opReturnDataReader.TryGetTargetAddress(null, out string address).Returns(callInfo => { callInfo[1] = null; return(false); });

            this.transactionBuilder = new TestTransactionBuilder();

            this.depositExtractor = new DepositExtractor(
                this.loggerFactory,
                this.settings,
                this.opReturnDataReader);
        }
        public void RewardClaimer_RetrieveBatchedDeposits()
        {
            DataFolder dataFolder         = TestBase.CreateDataFolder(this);
            var        keyValueRepository = new LevelDbKeyValueRepository(dataFolder, this.dbreezeSerializer);

            // Create a "chain" of 30 blocks.
            this.blocks = ChainedHeadersHelper.CreateConsecutiveHeadersAndBlocks(30, true, network: this.network, chainIndexer: this.chainIndexer, withCoinbaseAndCoinStake: true, createCirrusReward: true);

            // The reward claimer should look at block 10 to 20.
            using (var rewardClaimer = new RewardClaimer(this.broadCasterManager, this.chainIndexer, this.consensusManager, this.initialBlockDownloadState, keyValueRepository, this.network, this.signals))
            {
                Transaction rewardTransaction = rewardClaimer.BuildRewardTransaction(true);

                Assert.Equal(10, rewardTransaction.Inputs.Count);
                Assert.Equal(2, rewardTransaction.Outputs.Count);
                Assert.Equal(Money.Coins(90), rewardTransaction.TotalOut);

                var      depositExtractor = new DepositExtractor(this.federatedPegSettings, this.network, this.opReturnDataReader);
                IDeposit deposit          = depositExtractor.ExtractDepositFromTransaction(rewardTransaction, 30, this.blocks[30].Block.GetHash());
                Assert.Equal(Money.Coins(90), deposit.Amount);
            }
        }
        public DepositExtractorTests()
        {
            this.network = FederatedPegNetwork.NetworksSelector.Regtest();

            this.loggerFactory      = Substitute.For <ILoggerFactory>();
            this.settings           = Substitute.For <IFederationGatewaySettings>();
            this.opReturnDataReader = Substitute.For <IOpReturnDataReader>();
            this.fullNode           = Substitute.For <IFullNode>();
            this.fullNode.NodeService <ConcurrentChain>().Returns(this.chain);

            this.addressHelper = new MultisigAddressHelper(this.network);

            this.settings.MultiSigRedeemScript.Returns(this.addressHelper.PayToMultiSig);
            this.opReturnDataReader.TryGetTargetAddress(null).ReturnsForAnyArgs((string)null);

            this.transactionBuilder = new TestTransactionBuilder();

            this.depositExtractor = new DepositExtractor(
                this.loggerFactory,
                this.settings,
                this.opReturnDataReader,
                this.fullNode);
        }