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 @@ -7,6 +7,7 @@
using NBitcoin;
using NBitcoin.Policy;
using Stratis.Bitcoin.Builder.Feature;
using Stratis.Bitcoin.Configuration;
using Stratis.Bitcoin.Connection;
using Stratis.Bitcoin.Consensus;
using Stratis.Bitcoin.Features.BlockStore;
Expand All @@ -21,9 +22,16 @@ namespace Stratis.Bitcoin.Features.ColdStaking
/// <summary>
/// Contains modified implementations of the <see cref="IWalletService"/> methods suitable for cold staking.
/// </summary>
public class ColdStakingWalletService : WalletService
public sealed class ColdStakingWalletService : WalletService
{
public ColdStakingWalletService(ILoggerFactory loggerFactory, IWalletManager walletManager, IConsensusManager consensusManager, IWalletTransactionHandler walletTransactionHandler, IWalletSyncManager walletSyncManager, IConnectionManager connectionManager, Network network, ChainIndexer chainIndexer, IBroadcasterManager broadcasterManager, IDateTimeProvider dateTimeProvider, IUtxoIndexer utxoIndexer, IWalletFeePolicy walletFeePolicy) : base(loggerFactory, walletManager, consensusManager, walletTransactionHandler, walletSyncManager, connectionManager, network, chainIndexer, broadcasterManager, dateTimeProvider, utxoIndexer, walletFeePolicy)
public ColdStakingWalletService(
ILoggerFactory loggerFactory, IWalletManager walletManager,
IConsensusManager consensusManager, IWalletTransactionHandler walletTransactionHandler,
IWalletSyncManager walletSyncManager, IConnectionManager connectionManager,
Network network, ChainIndexer chainIndexer, IBroadcasterManager broadcasterManager,
IDateTimeProvider dateTimeProvider, IUtxoIndexer utxoIndexer,
IWalletFeePolicy walletFeePolicy, NodeSettings nodeSettings)
: base(loggerFactory, walletManager, consensusManager, walletTransactionHandler, walletSyncManager, connectionManager, network, chainIndexer, broadcasterManager, dateTimeProvider, utxoIndexer, walletFeePolicy, nodeSettings)
{
}

Expand Down Expand Up @@ -77,7 +85,7 @@ public override async Task<WalletBuildTransactionModel> OfflineSignRequest(Offli
var coldAccountAddresses = coldAccount.GetCombinedAddresses();
hdAddress = coldAccountAddresses.FirstOrDefault(a => a.Address == address || a.Bech32Address == address);
}

// It is possible that the address is outside the gap limit. So if it is not found we optimistically presume the address descriptors will fill in the missing information later.
if (hdAddress != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.Extensions.Logging;
using NBitcoin;
using Stratis.Bitcoin.AsyncWork;
using Stratis.Bitcoin.Configuration;
using Stratis.Bitcoin.Connection;
using Stratis.Bitcoin.Consensus;
using Stratis.Bitcoin.Consensus.Validators;
Expand Down Expand Up @@ -42,8 +43,10 @@ public TestPoAMiner(
VotingManager votingManager,
PoASettings poAMinerSettings,
IAsyncProvider asyncProvider,
IIdleFederationMembersKicker idleFederationMembersKicker) : base(consensusManager, dateTimeProvider, network, nodeLifetime, loggerFactory, ibdState, blockDefinition, slotsManager,
connectionManager, poaHeaderValidator, federationManager, integrityValidator, walletManager, nodeStats, votingManager, poAMinerSettings, asyncProvider, idleFederationMembersKicker)
IIdleFederationMembersKicker idleFederationMembersKicker,
NodeSettings nodeSettings)
: base(consensusManager, dateTimeProvider, network, nodeLifetime, loggerFactory, ibdState, blockDefinition, slotsManager,
connectionManager, poaHeaderValidator, federationManager, integrityValidator, walletManager, nodeStats, votingManager, poAMinerSettings, asyncProvider, idleFederationMembersKicker, nodeSettings)
{
this.timeProvider = dateTimeProvider as EditableTimeProvider;

Expand Down
2 changes: 1 addition & 1 deletion src/Stratis.Bitcoin.Features.PoA.Tests/PoATestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public static (IFederationManager federationManager, IFederationHistory federati

var counterChainSettings = new CounterChainSettings(nodeSettings, new CounterChainNetworkWrapper(new StraxRegTest()));

var federationManager = new FederationManager(fullNode.Object, network, nodeSettings, signals, new PoASettings(nodeSettings), counterChainSettings);
var federationManager = new FederationManager(fullNode.Object, network, nodeSettings, signals, counterChainSettings);
var asyncProvider = new AsyncProvider(loggerFactory, signals);
var finalizedBlockRepo = new FinalizedBlockInfoRepository(new LevelDbKeyValueRepository(nodeSettings.DataFolder, dbreezeSerializer), asyncProvider);
finalizedBlockRepo.LoadFinalizedBlockInfoAsync(network).GetAwaiter().GetResult();
Expand Down
5 changes: 1 addition & 4 deletions src/Stratis.Bitcoin.Features.PoA/FederationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ public sealed class FederationManager : IFederationManager
private readonly ILogger logger;
private readonly PoANetwork network;
private readonly NodeSettings nodeSettings;
private readonly PoASettings poaSettings;
private readonly ISignals signals;

private int? multisigMinersApplicabilityHeight;
Expand All @@ -91,14 +90,12 @@ public FederationManager(
Network network,
NodeSettings nodeSettings,
ISignals signals,
PoASettings poaSettings,
ICounterChainSettings counterChainSettings = null)
{
this.counterChainSettings = counterChainSettings;
this.fullNode = fullNode;
this.network = Guard.NotNull(network as PoANetwork, nameof(network));
this.nodeSettings = Guard.NotNull(nodeSettings, nameof(nodeSettings));
this.poaSettings = poaSettings;
this.signals = Guard.NotNull(signals, nameof(signals));

this.logger = LogManager.GetCurrentClassLogger();
Expand Down Expand Up @@ -142,7 +139,7 @@ public void Initialize()

private bool InitializeFederationMemberKey()
{
if (!this.poaSettings.DevMode)
if (!this.nodeSettings.DevMode)
{
// Load key.
Key key = new KeyTool(this.nodeSettings.DataFolder).LoadPrivateKey();
Expand Down
23 changes: 14 additions & 9 deletions src/Stratis.Bitcoin.Features.PoA/PoAMiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.Extensions.Logging;
using NBitcoin;
using Stratis.Bitcoin.AsyncWork;
using Stratis.Bitcoin.Configuration;
using Stratis.Bitcoin.Configuration.Logging;
using Stratis.Bitcoin.Connection;
using Stratis.Bitcoin.Consensus;
Expand Down Expand Up @@ -70,13 +71,15 @@ public class PoAMiner : IPoAMiner

private readonly IIdleFederationMembersKicker idleFederationMembersKicker;

private readonly NodeSettings nodeSettings;

private readonly IWalletManager walletManager;

protected readonly VotingManager votingManager;

private readonly VotingDataEncoder votingDataEncoder;

private readonly PoASettings settings;
private readonly PoASettings poaSettings;

private readonly IAsyncProvider asyncProvider;

Expand All @@ -102,7 +105,8 @@ public PoAMiner(
VotingManager votingManager,
PoASettings poAMinerSettings,
IAsyncProvider asyncProvider,
IIdleFederationMembersKicker idleFederationMembersKicker)
IIdleFederationMembersKicker idleFederationMembersKicker,
NodeSettings nodeSettings)
{
this.consensusManager = consensusManager;
this.dateTimeProvider = dateTimeProvider;
Expand All @@ -116,13 +120,14 @@ public PoAMiner(
this.integrityValidator = integrityValidator;
this.walletManager = walletManager;
this.votingManager = votingManager;
this.settings = poAMinerSettings;
this.poaSettings = poAMinerSettings;
this.asyncProvider = asyncProvider;
this.idleFederationMembersKicker = idleFederationMembersKicker;

this.logger = loggerFactory.CreateLogger(this.GetType().FullName);
this.cancellation = CancellationTokenSource.CreateLinkedTokenSource(new[] { nodeLifetime.ApplicationStopping });
this.votingDataEncoder = new VotingDataEncoder(loggerFactory);
this.nodeSettings = nodeSettings;

nodeStats.RegisterStats(this.AddComponentStats, StatsType.Component, this.GetType().Name);
}
Expand All @@ -144,11 +149,11 @@ private async Task CreateBlocksAsync()
try
{
this.logger.LogDebug("IsInitialBlockDownload={0}, AnyConnectedPeers={1}, BootstrappingMode={2}, IsFederationMember={3}",
this.ibdState.IsInitialBlockDownload(), this.connectionManager.ConnectedPeers.Any(), this.settings.BootstrappingMode, this.federationManager.IsFederationMember);
this.ibdState.IsInitialBlockDownload(), this.connectionManager.ConnectedPeers.Any(), this.poaSettings.BootstrappingMode, this.federationManager.IsFederationMember);

// Don't mine in IBD or if we aren't connected to any node (unless bootstrapping mode is enabled).
// Don't try to mine if we aren't a federation member.
bool cantMineAtAll = (this.ibdState.IsInitialBlockDownload() || !this.connectionManager.ConnectedPeers.Any()) && !this.settings.BootstrappingMode;
bool cantMineAtAll = (this.ibdState.IsInitialBlockDownload() || !this.connectionManager.ConnectedPeers.Any()) && !this.poaSettings.BootstrappingMode;
if (cantMineAtAll || !this.federationManager.IsFederationMember)
{
if (!cantMineAtAll)
Expand Down Expand Up @@ -193,10 +198,10 @@ private async Task CreateBlocksAsync()
// There is therefore no point keeping this mode enabled once this node has mined successfully.
// Additionally, keeping it enabled may result in network splits if this node becomes disconnected from its peers for a prolonged period.
// If DevMode is enabled the miner will conitnue it's bootstrapped mining, i.e. without any connections.
if (this.settings.BootstrappingMode && !this.settings.DevMode)
if (this.poaSettings.BootstrappingMode && !this.nodeSettings.DevMode)
{
this.logger.LogInformation("Disabling bootstrap mode as a block has been successfully mined.");
this.settings.DisableBootstrap();
this.poaSettings.DisableBootstrap();
}
}
catch (OperationCanceledException)
Expand Down Expand Up @@ -281,9 +286,9 @@ protected async Task<ChainedHeader> MineBlockAtTimestampAsync(uint timestamp)
// If an address is specified for mining then preferentially use that.
// The private key for this address is not used for block signing, so it can be any valid address.
// Since it is known which miner mines in each block already it does not change the privacy level that every block mines to the same address.
if (!string.IsNullOrWhiteSpace(this.settings.MineAddress))
if (!string.IsNullOrWhiteSpace(this.poaSettings.MineAddress))
{
this.walletScriptPubKey = BitcoinAddress.Create(this.settings.MineAddress, this.network).ScriptPubKey;
this.walletScriptPubKey = BitcoinAddress.Create(this.poaSettings.MineAddress, this.network).ScriptPubKey;
}
else
{
Expand Down
13 changes: 1 addition & 12 deletions src/Stratis.Bitcoin.Features.PoA/PoASettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,13 @@

namespace Stratis.Bitcoin.Features.PoA
{
public class PoASettings
public sealed class PoASettings
{
/// <summary>
/// String value that defines the devmode flag in config.
/// </summary>
public const string DevModeParam = "devmode";

/// <summary>
/// Allows mining in case node is in IBD and not connected to anyone.
/// </summary>
public bool BootstrappingMode { get; private set; }

/// <summary>
/// A flag that allows the miner to continue its bootstrapped mining, whilst having no connections.
/// </summary>
public bool DevMode { get; private set; }

/// <summary>
/// An address to use when mining, if not specified an address from the wallet will be used.
/// </summary>
Expand All @@ -32,7 +22,6 @@ public PoASettings(NodeSettings nodeSettings)
TextFileConfiguration config = nodeSettings.ConfigReader;

this.BootstrappingMode = config.GetOrDefault("bootstrap", false);
this.DevMode = config.GetOrDefault(DevModeParam, false);
this.MineAddress = config.GetOrDefault<string>("mineaddress", null);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
using Microsoft.Extensions.Logging;
using NBitcoin;
using Newtonsoft.Json;
using Stratis.Bitcoin.Configuration;
using Stratis.Bitcoin.Connection;
using Stratis.Bitcoin.Controllers;
using Stratis.Bitcoin.Features.PoA;
using Stratis.Bitcoin.Features.SmartContracts.Models;
using Stratis.Bitcoin.Features.SmartContracts.Wallet;
using Stratis.Bitcoin.Features.Wallet;
Expand Down Expand Up @@ -56,7 +56,7 @@ public class SmartContractsController : FeatureController
private readonly ILocalExecutor localExecutor;
private readonly ISmartContractTransactionService smartContractTransactionService;
private readonly IConnectionManager connectionManager;
private readonly PoASettings poaSettings;
private readonly NodeSettings nodeSettings;

public SmartContractsController(IBroadcasterManager broadcasterManager,
IBlockStore blockStore,
Expand All @@ -72,7 +72,7 @@ public SmartContractsController(IBroadcasterManager broadcasterManager,
ILocalExecutor localExecutor,
ISmartContractTransactionService smartContractTransactionService,
IConnectionManager connectionManager,
PoASettings poASettings = null)
NodeSettings nodeSettings)
{
this.stateRoot = stateRoot;
this.contractDecompiler = contractDecompiler;
Expand All @@ -88,7 +88,7 @@ public SmartContractsController(IBroadcasterManager broadcasterManager,
this.localExecutor = localExecutor;
this.smartContractTransactionService = smartContractTransactionService;
this.connectionManager = connectionManager;
this.poaSettings = poASettings;
this.nodeSettings = nodeSettings;
}

/// <summary>
Expand Down Expand Up @@ -517,7 +517,7 @@ public async Task<IActionResult> BuildAndSendCreateSmartContractTransactionAsync
return ModelStateErrors.BuildErrorResponse(this.ModelState);

// Ignore this check if the node is running dev mode.
if ((this.poaSettings != null && !this.poaSettings.DevMode) && !this.connectionManager.ConnectedPeers.Any())
if (!this.nodeSettings.DevMode && !this.connectionManager.ConnectedPeers.Any())
{
this.logger.LogTrace("(-)[NO_CONNECTED_PEERS]");
return ErrorHelpers.BuildErrorResponse(HttpStatusCode.Forbidden, "Can't send transaction as the node requires at least one connection.", string.Empty);
Expand Down Expand Up @@ -570,7 +570,7 @@ public async Task<IActionResult> BuildAndSendCallSmartContractTransactionAsync([
return ModelStateErrors.BuildErrorResponse(this.ModelState);

// Ignore this check if the node is running dev mode.
if ((this.poaSettings != null && !this.poaSettings.DevMode) && !this.connectionManager.ConnectedPeers.Any())
if (!this.nodeSettings.DevMode && !this.connectionManager.ConnectedPeers.Any())
{
this.logger.LogTrace("(-)[NO_CONNECTED_PEERS]");
return ErrorHelpers.BuildErrorResponse(HttpStatusCode.Forbidden, "Can't send transaction as the node requires at least one connection.", string.Empty);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Moq;
using Moq.AutoMock;
using NBitcoin;
using Stratis.Bitcoin.Configuration;
using Stratis.Bitcoin.Connection;
using Stratis.Bitcoin.Consensus;
using Stratis.Bitcoin.Features.Wallet.Broadcasting;
Expand Down Expand Up @@ -1954,7 +1955,7 @@ public async Task SendTransactionSuccessfulReturnsWalletSendTransactionModelResp
}

[Fact]
public async Task SendTransactionFailedBecauseNoNodesConnected()
public async Task SendTransactionFailedBecauseNoNodesConnectedAsync()
{
var mockBroadcasterManager = this.ConfigureMock<IBroadcasterManager>();

Expand All @@ -1964,17 +1965,15 @@ public async Task SendTransactionFailedBecauseNoNodesConnected()

var controller = this.GetWalletController();

IActionResult result =
await controller.SendTransaction(new SendTransactionRequest(new uint256(15555).ToString()));
IActionResult result = await controller.SendTransaction(new SendTransactionRequest(new uint256(15555).ToString()));

var errorResult = Assert.IsType<ErrorResult>(result);
var errorResponse = Assert.IsType<ErrorResponse>(errorResult.Value);
Assert.Single(errorResponse.Errors);

ErrorModel error = errorResponse.Errors[0];
Assert.Equal(403, error.Status);
Assert.Equal("Can't send transaction: sending transaction requires at least one connection!",
error.Message);
Assert.Equal("Can't send transaction: sending transaction requires at least one connection.", error.Message);
}

[Fact]
Expand Down Expand Up @@ -2638,6 +2637,7 @@ private WalletController GetWalletController()
mocker.Use(typeof(IConsensusManager), this.GetMock<IConsensusManager>(true));
mocker.Use(typeof(IDateTimeProvider), this.GetMock<IDateTimeProvider>() ?? DateTimeProvider.Default);
mocker.Use(typeof(IConnectionManager), this.GetMock<IConnectionManager>(true));
mocker.Use(typeof(NodeSettings), NodeSettings.Default(this.Network));
mocker.Use(typeof(IWalletService), this.GetMock<WalletService>() ?? mocker.CreateInstance<WalletService>());

return mocker.CreateInstance<WalletController>();
Expand Down
Loading