Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using NSubstitute.Core;
using Stratis.Bitcoin;
using Stratis.Bitcoin.AsyncWork;
using Stratis.Bitcoin.Base.Deployments;
using Stratis.Bitcoin.Configuration;
using Stratis.Bitcoin.Connection;
using Stratis.Bitcoin.Consensus;
Expand Down Expand Up @@ -73,12 +74,14 @@ public FederationGatewayControllerTests()

private FederationGatewayController CreateController(IFederatedPegSettings federatedPegSettings)
{
var retrievalTypeConfirmations = new RetrievalTypeConfirmations(this.network, new NodeDeployments(this.network, new ChainIndexer(this.network)), federatedPegSettings);

var controller = new FederationGatewayController(
Substitute.For<IAsyncProvider>(),
new ChainIndexer(),
Substitute.For<IConnectionManager>(),
this.crossChainTransferStore,
this.GetMaturedBlocksProvider(federatedPegSettings),
this.GetMaturedBlocksProvider(retrievalTypeConfirmations),
this.network,
this.federatedPegSettings,
this.federationWalletManager,
Expand All @@ -89,7 +92,7 @@ private FederationGatewayController CreateController(IFederatedPegSettings feder
return controller;
}

private MaturedBlocksProvider GetMaturedBlocksProvider(IFederatedPegSettings federatedPegSettings)
private MaturedBlocksProvider GetMaturedBlocksProvider(IRetrievalTypeConfirmations retrievalTypeConfirmations)
{
IBlockRepository blockRepository = Substitute.For<IBlockRepository>();

Expand All @@ -108,7 +111,7 @@ private MaturedBlocksProvider GetMaturedBlocksProvider(IFederatedPegSettings fed

IExternalApiPoller externalApiPoller = Substitute.For<IExternalApiPoller>();

return new MaturedBlocksProvider(this.consensusManager, this.depositExtractor, federatedPegSettings);
return new MaturedBlocksProvider(this.consensusManager, this.depositExtractor, retrievalTypeConfirmations);
}

[Fact]
Expand Down Expand Up @@ -154,8 +157,8 @@ public async Task GetMaturedBlockDeposits_Gets_All_Matured_Block_DepositsAsync()
ChainedHeader earlierBlock = tip.GetAncestor(minConfirmations);

int depositExtractorCallCount = 0;
this.depositExtractor.ExtractDepositsFromBlock(Arg.Any<Block>(), Arg.Any<int>(), Arg.Any<Dictionary<DepositRetrievalType, int>>()).Returns(new List<IDeposit>());
this.depositExtractor.When(x => x.ExtractDepositsFromBlock(Arg.Any<Block>(), Arg.Any<int>(), Arg.Any<Dictionary<DepositRetrievalType, int>>())).Do(info =>
this.depositExtractor.ExtractDepositsFromBlock(Arg.Any<Block>(), Arg.Any<int>(), Arg.Any<IRetrievalTypeConfirmations>()).Returns(new List<IDeposit>());
this.depositExtractor.When(x => x.ExtractDepositsFromBlock(Arg.Any<Block>(), Arg.Any<int>(), Arg.Any<IRetrievalTypeConfirmations>())).Do(info =>
{
depositExtractorCallCount++;
});
Expand Down Expand Up @@ -207,12 +210,14 @@ public void Call_Sidechain_Gateway_Get_Info()

var federatedPegSettings = new FederatedPegSettings(nodeSettings, new CounterChainNetworkWrapper(KnownNetworks.StraxRegTest));

var retrievalTypeConfirmations = new RetrievalTypeConfirmations(this.network, new NodeDeployments(this.network, new ChainIndexer(this.network)), federatedPegSettings);

var controller = new FederationGatewayController(
Substitute.For<IAsyncProvider>(),
new ChainIndexer(),
Substitute.For<IConnectionManager>(),
this.crossChainTransferStore,
this.GetMaturedBlocksProvider(federatedPegSettings),
this.GetMaturedBlocksProvider(retrievalTypeConfirmations),
this.network,
federatedPegSettings,
this.federationWalletManager,
Expand Down Expand Up @@ -299,13 +304,14 @@ public void Call_Mainchain_Gateway_Get_Info()
this.federationWalletManager.IsFederationWalletActive().Returns(true);

var settings = new FederatedPegSettings(nodeSettings, new CounterChainNetworkWrapper(KnownNetworks.StraxRegTest));
var retrievalTypeConfirmations = new RetrievalTypeConfirmations(this.network, new NodeDeployments(this.network, new ChainIndexer(this.network)), settings);

var controller = new FederationGatewayController(
Substitute.For<IAsyncProvider>(),
new ChainIndexer(),
Substitute.For<IConnectionManager>(),
this.crossChainTransferStore,
this.GetMaturedBlocksProvider(settings),
this.GetMaturedBlocksProvider(retrievalTypeConfirmations),
this.network,
settings,
this.federationWalletManager,
Expand Down
15 changes: 4 additions & 11 deletions src/Stratis.Features.FederatedPeg.Tests/DepositExtractorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using Moq;
using NBitcoin;
using NSubstitute;
using Stratis.Bitcoin;
using Stratis.Bitcoin.Base.Deployments;
using Stratis.Bitcoin.Features.ExternalApi;
using Stratis.Bitcoin.Features.Wallet;
using Stratis.Bitcoin.Networks;
Expand All @@ -29,7 +31,7 @@ public class DepositExtractorTests
private readonly Network network;
private readonly MultisigAddressHelper addressHelper;
private readonly TestTransactionBuilder transactionBuilder;
private readonly Dictionary<DepositRetrievalType, int> retrievalTypeConfirmations;
private readonly RetrievalTypeConfirmations retrievalTypeConfirmations;

public DepositExtractorTests()
{
Expand All @@ -53,16 +55,7 @@ public DepositExtractorTests()
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
};
this.retrievalTypeConfirmations = new RetrievalTypeConfirmations(this.network, new NodeDeployments(this.network, new ChainIndexer(this.network)), this.federationSettings);
}

// Normal Deposits
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using NSubstitute;
using NSubstitute.Core;
using Stratis.Bitcoin;
using Stratis.Bitcoin.Base.Deployments;
using Stratis.Bitcoin.Consensus;
using Stratis.Bitcoin.Features.Wallet;
using Stratis.Bitcoin.Networks;
Expand Down Expand Up @@ -39,7 +40,7 @@ public sealed class MaturedBlocksProviderTests
private readonly byte[] opReturnBytes;
private readonly BitcoinPubKeyAddress targetAddress;
private List<ChainedHeaderBlock> blocks;
private Dictionary<DepositRetrievalType, int> retrievalTypeConfirmations;
private IRetrievalTypeConfirmations retrievalTypeConfirmations;

public MaturedBlocksProviderTests()
{
Expand Down Expand Up @@ -79,17 +80,7 @@ public MaturedBlocksProviderTests()
return this.blocks.SkipWhile(x => x.ChainedHeader.Height <= chainedHeader.Height).Where(x => x.ChainedHeader.Height <= this.consensusManager.Tip.Height).ToArray();
});

this.retrievalTypeConfirmations = new Dictionary<DepositRetrievalType, int>
{
[DepositRetrievalType.Small] = this.federatedPegSettings.MinimumConfirmationsSmallDeposits,
[DepositRetrievalType.Normal] = this.federatedPegSettings.MinimumConfirmationsNormalDeposits,
[DepositRetrievalType.Large] = this.federatedPegSettings.MinimumConfirmationsLargeDeposits,
};

this.retrievalTypeConfirmations[DepositRetrievalType.Distribution] = this.federatedPegSettings.MinimumConfirmationsDistributionDeposits;
this.retrievalTypeConfirmations[DepositRetrievalType.ConversionSmall] = this.federatedPegSettings.MinimumConfirmationsSmallDeposits;
this.retrievalTypeConfirmations[DepositRetrievalType.ConversionNormal] = this.federatedPegSettings.MinimumConfirmationsNormalDeposits;
this.retrievalTypeConfirmations[DepositRetrievalType.ConversionLarge] = this.federatedPegSettings.MinimumConfirmationsLargeDeposits;
this.retrievalTypeConfirmations = new RetrievalTypeConfirmations(this.network, new NodeDeployments(this.network, new ChainIndexer(this.network)), this.federatedPegSettings);
}

[Fact]
Expand All @@ -110,7 +101,7 @@ public async Task GetMaturedBlocksReturnsDepositsAsync()
this.consensusManager.Tip.Returns(tip);

// Makes every block a matured block.
var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, federatedPegSettings);
var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.retrievalTypeConfirmations);

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

Expand Down Expand Up @@ -158,7 +149,7 @@ public async Task RetrieveDeposits_ReturnsDataToAdvanceNextMaturedBlockHeightAsy
});

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

int nextMaturedBlockHeight = 1;
for (int i = 1; i < this.blocks.Count; i++)
Expand Down Expand Up @@ -219,7 +210,7 @@ public async Task RetrieveDeposits_ReturnsSmallAndNormalDeposits_Scenario2_Async
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);
var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.retrievalTypeConfirmations);

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

Expand Down Expand Up @@ -273,7 +264,7 @@ public async Task RetrieveDeposits_ReturnsSmallAndNormalDeposits_Scenario3_Async
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);
var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.retrievalTypeConfirmations);

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

Expand Down Expand Up @@ -329,7 +320,7 @@ public async Task RetrieveDeposits_ReturnsSmallAndNormalDeposits_Scenario4_Async
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);
var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.retrievalTypeConfirmations);

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

Expand Down Expand Up @@ -386,7 +377,7 @@ public async Task RetrieveDeposits_ReturnsSmallAndNormalDeposits_Scenario5_Async
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);
var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.retrievalTypeConfirmations);

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

Expand Down Expand Up @@ -442,7 +433,7 @@ public async Task RetrieveDeposits_ReturnsLargeDeposits_Scenario6_Async()

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);
var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.retrievalTypeConfirmations);

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

Expand Down Expand Up @@ -504,7 +495,7 @@ public async Task RetrieveDeposits_ReturnsLargeDeposits_Scenario7_Async()
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);
var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.retrievalTypeConfirmations);

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

Expand Down Expand Up @@ -567,7 +558,7 @@ public async Task RetrieveDeposits_ReturnsLargeDeposits_Scenario8_Async()
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);
var maturedBlocksProvider = new MaturedBlocksProvider(this.consensusManager, depositExtractor, this.retrievalTypeConfirmations);

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

Expand Down
1 change: 1 addition & 0 deletions src/Stratis.Features.FederatedPeg/FederatedPegFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ public static IFullNodeBuilder AddFederatedPeg(this IFullNodeBuilder fullNodeBui
.FeatureServices(services =>
{
services.AddSingleton<IMaturedBlocksProvider, MaturedBlocksProvider>();
services.AddSingleton<IRetrievalTypeConfirmations, RetrievalTypeConfirmations>();
services.AddSingleton<IFederatedPegSettings, FederatedPegSettings>();
services.AddSingleton<IOpReturnDataReader>(provider => new OpReturnDataReader(provider.GetService<CounterChainNetworkWrapper>().CounterChainNetwork));
services.AddSingleton<IDepositExtractor, DepositExtractor>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public interface IDepositExtractor
/// <param name="blockHeight">The height of the block containing the transactions.</param>
/// <param name="depositRetrievalTypes">The types of retrieval to perform. The type will determine the value of the deposit to be processed.</param>
/// <returns>The extracted deposit (if any), otherwise returns an empty list.</returns>
Task<IReadOnlyList<IDeposit>> ExtractDepositsFromBlock(Block block, int blockHeight, Dictionary<DepositRetrievalType, int> depositRetrievalTypes);
Task<IReadOnlyList<IDeposit>> ExtractDepositsFromBlock(Block block, int blockHeight, IRetrievalTypeConfirmations depositRetrievalTypes);

/// <summary>
/// Extracts a deposit from a transaction (if any).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public DepositExtractor(IConversionRequestRepository conversionRequestRepository
};

/// <inheritdoc />
public async Task<IReadOnlyList<IDeposit>> ExtractDepositsFromBlock(Block block, int blockHeight, Dictionary<DepositRetrievalType, int> confirmationsByRetrievalType)
public async Task<IReadOnlyList<IDeposit>> ExtractDepositsFromBlock(Block block, int blockHeight, IRetrievalTypeConfirmations confirmationsByRetrievalType)
{
List<IDeposit> deposits;

Expand All @@ -82,7 +82,7 @@ public async Task<IReadOnlyList<IDeposit>> ExtractDepositsFromBlock(Block block,
((Deposit)deposit).BlockHash = block.GetHash();
}

DepositRetrievalType[] retrievalTypes = confirmationsByRetrievalType.Keys.ToArray();
DepositRetrievalType[] retrievalTypes = confirmationsByRetrievalType.GetRetrievalTypes();

// If it's an empty block (i.e. only the coinbase transaction is present), there's no deposits inside.
if (block.Transactions.Count > 1)
Expand Down Expand Up @@ -110,7 +110,7 @@ public async Task<IReadOnlyList<IDeposit>> ExtractDepositsFromBlock(Block block,
/// <param name="deposits">Add burn requests to this list of deposits.</param>
/// <param name="inspectForDepositsAtHeight">The block height to inspect.</param>
/// <param name="confirmationsByRetrievalType">The various retrieval types and their required confirmations.</param>
private void ProcessInterFluxBurnRequests(List<IDeposit> deposits, int inspectForDepositsAtHeight, Dictionary<DepositRetrievalType, int> confirmationsByRetrievalType)
private void ProcessInterFluxBurnRequests(List<IDeposit> deposits, int inspectForDepositsAtHeight, IRetrievalTypeConfirmations confirmationsByRetrievalType)
{
List<ConversionRequest> burnRequests = this.conversionRequestRepository.GetAllBurn(true);

Expand Down Expand Up @@ -141,7 +141,7 @@ private void ProcessInterFluxBurnRequests(List<IDeposit> deposits, int inspectFo
if (inspectForDepositsAtHeight > burnRequest.BlockHeight)
{
DepositRetrievalType retrievalType = DetermineDepositRetrievalType(burnRequest.Amount.GetLow64());
var requiredConfirmations = confirmationsByRetrievalType[retrievalType];
var requiredConfirmations = confirmationsByRetrievalType.GetDepositConfirmations(burnRequest.BlockHeight, retrievalType);

// If the inspection height is now equal to the burn request's processing height plus
// the required confirmations, set it to processed.
Expand Down
Loading