Commit 00b2e5bd authored by Sergei Zubov's avatar Sergei Zubov

Modify processing of genesis block

Coins are emitted in genesis block. To make them spendable, they are
added to CoinView. WalletManager changed to include them in wallet's
balance.
parent 4e170a53
using System;
using System.Linq;
using System.Threading.Tasks;
using System.IO;
using Microsoft.CodeAnalysis.CSharp;
using DeStream.Stratis.Bitcoin.Configuration;
using NBitcoin;
using NBitcoin.Protocol;
using Stratis.Bitcoin;
using Stratis.Bitcoin.Builder;
using Stratis.Bitcoin.Configuration;
using Stratis.Bitcoin.Features.Api;
using Stratis.Bitcoin.Features.BlockStore;
using Stratis.Bitcoin.Features.Consensus;
......@@ -15,11 +14,6 @@ using Stratis.Bitcoin.Features.Miner;
using Stratis.Bitcoin.Features.RPC;
using Stratis.Bitcoin.Features.Wallet;
using Stratis.Bitcoin.Utilities;
using Stratis.Bitcoin.Utilities.Extensions;
using DeStream.Stratis.Bitcoin.Configuration;
using NBitcoin.Networks;
namespace DeStream.DeStreamD
{
......@@ -34,27 +28,20 @@ namespace DeStream.DeStreamD
{
try
{
Network network = null;
Network network = args.Contains("-testnet") ? Network.DeStreamTest : Network.DeStreamMain;
if (args.Contains("-testnet"))
{
network = Network.DeStreamTest;
}
else
{
network = Network.DeStreamMain;
}
DeStreamNodeSettings nodeSettings = new DeStreamNodeSettings(network, ProtocolVersion.ALT_PROTOCOL_VERSION, args: args, loadConfiguration: false);
var nodeSettings = new DeStreamNodeSettings(network, ProtocolVersion.ALT_PROTOCOL_VERSION, args: args,
loadConfiguration: false);
Console.WriteLine($"current network: {network.Name}");
// NOTES: running BTC and STRAT side by side is not possible yet as the flags for serialization are static
var node = new FullNodeBuilder()
IFullNode node = new FullNodeBuilder()
.UseNodeSettings(nodeSettings)
.UseBlockStore()
.UsePosConsensus()
.UseDeStreamPosConsensus()
.UseMempool()
.UseWallet()
.UseDeStreamWallet()
.AddPowPosMining()
.UseApi()
.AddRPC()
......
......@@ -22,13 +22,13 @@ namespace Stratis.Bitcoin.Features.Consensus.CoinViews
private static readonly byte[] blockHashKey = new byte[0];
/// <summary>Instance logger.</summary>
private readonly ILogger logger;
protected readonly ILogger logger;
/// <summary>Access to DBreeze database.</summary>
private readonly DBreezeEngine dbreeze;
protected readonly DBreezeEngine dbreeze;
/// <summary>Specification of the network the node runs on - regtest/testnet/mainnet.</summary>
private readonly Network network;
protected readonly Network network;
/// <summary>Hash of the block which is currently the tip of the coinview.</summary>
private uint256 blockHash;
......@@ -82,7 +82,7 @@ namespace Stratis.Bitcoin.Features.Consensus.CoinViews
/// <summary>
/// Initializes the database tables used by the coinview.
/// </summary>
public Task InitializeAsync()
public virtual Task InitializeAsync()
{
this.logger.LogTrace("()");
......@@ -156,7 +156,7 @@ namespace Stratis.Bitcoin.Features.Consensus.CoinViews
/// </summary>
/// <param name="transaction">Open DBreeze transaction.</param>
/// <returns>Block header hash of the coinview's current tip.</returns>
private uint256 GetCurrentHash(DBreeze.Transactions.Transaction transaction)
protected uint256 GetCurrentHash(DBreeze.Transactions.Transaction transaction)
{
if (this.blockHash == null)
{
......@@ -173,7 +173,7 @@ namespace Stratis.Bitcoin.Features.Consensus.CoinViews
/// </summary>
/// <param name="transaction">Open DBreeze transaction.</param>
/// <param name="nextBlockHash">Hash of the block to become the new tip.</param>
private void SetBlockHash(DBreeze.Transactions.Transaction transaction, uint256 nextBlockHash)
protected void SetBlockHash(DBreeze.Transactions.Transaction transaction, uint256 nextBlockHash)
{
this.logger.LogTrace("({0}:'{1}')", nameof(nextBlockHash), nextBlockHash);
......
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using NBitcoin;
using Stratis.Bitcoin.Configuration;
using Stratis.Bitcoin.Utilities;
using Transaction = DBreeze.Transactions.Transaction;
namespace Stratis.Bitcoin.Features.Consensus.CoinViews
{
/// <inheritdoc cref="DBreezeCoinView" />
public class DeStreamDBreezeCoinView : DBreezeCoinView, IDisposable
{
public DeStreamDBreezeCoinView(Network network, DataFolder dataFolder, IDateTimeProvider dateTimeProvider,
ILoggerFactory loggerFactory) : base(network, dataFolder, dateTimeProvider, loggerFactory)
{
}
public DeStreamDBreezeCoinView(Network network, string folder, IDateTimeProvider dateTimeProvider,
ILoggerFactory loggerFactory) : base(network, folder, dateTimeProvider, loggerFactory)
{
}
/// <inheritdoc />
public override Task InitializeAsync()
{
this.logger.LogTrace("()");
Block genesis = this.network.GetGenesis();
int insertedEntities = 0;
Task task = Task.Run(() =>
{
this.logger.LogTrace("()");
using (Transaction transaction = this.dbreeze.GetTransaction())
{
transaction.ValuesLazyLoadingIsOn = false;
transaction.SynchronizeTables("BlockHash");
if (this.GetCurrentHash(transaction) == null)
{
this.SetBlockHash(transaction, genesis.GetHash());
// Genesis coin is spendable and added to the database.
foreach (UnspentOutputs unspentOutput in
genesis.Transactions.Select(p => new UnspentOutputs(0, p)))
{
transaction.Insert("Coins", unspentOutput.TransactionId.ToBytes(false),
unspentOutput.ToCoins());
}
insertedEntities += genesis.Transactions.Count;
transaction.Commit();
}
}
this.logger.LogTrace("(-)");
});
this.PerformanceCounter.AddInsertedEntities(insertedEntities);
this.logger.LogTrace("(-)");
return task;
}
}
}
\ No newline at end of file
using Microsoft.Extensions.DependencyInjection;
using Stratis.Bitcoin.BlockPulling;
using Stratis.Bitcoin.Builder;
using Stratis.Bitcoin.Configuration.Logging;
using Stratis.Bitcoin.Configuration.Settings;
using Stratis.Bitcoin.Consensus;
using Stratis.Bitcoin.Consensus.Rules;
using Stratis.Bitcoin.Features.Consensus.CoinViews;
using Stratis.Bitcoin.Features.Consensus.Interfaces;
using Stratis.Bitcoin.Features.Consensus.Rules;
using Stratis.Bitcoin.Interfaces;
namespace Stratis.Bitcoin.Features.Consensus
{
/// <summary>
/// A class providing extension methods for <see cref="IFullNodeBuilder" />.
/// </summary>
public static class DeStreamFullNodeBuilderConsensusExtension
{
public static IFullNodeBuilder UseDeStreamPowConsensus(this IFullNodeBuilder fullNodeBuilder)
{
LoggingConfiguration.RegisterFeatureNamespace<ConsensusFeature>("consensus");
LoggingConfiguration.RegisterFeatureClass<ConsensusStats>("bench");
fullNodeBuilder.ConfigureFeature(features =>
{
features
.AddFeature<ConsensusFeature>()
.FeatureServices(services =>
{
// TODO: this should be set on the network build
fullNodeBuilder.Network.Consensus.Options = new PowConsensusOptions();
services.AddSingleton<ICheckpoints, Checkpoints>();
services.AddSingleton<NBitcoin.Consensus.ConsensusOptions, PowConsensusOptions>();
services.AddSingleton<DBreezeCoinView, DeStreamDBreezeCoinView>();
services.AddSingleton<CoinView, CachedCoinView>();
services.AddSingleton<LookaheadBlockPuller>()
.AddSingleton<ILookaheadBlockPuller, LookaheadBlockPuller>(provider =>
provider.GetService<LookaheadBlockPuller>());
;
services.AddSingleton<IConsensusLoop, ConsensusLoop>()
.AddSingleton<INetworkDifficulty, ConsensusLoop>(provider =>
provider.GetService<IConsensusLoop>() as ConsensusLoop)
.AddSingleton<IGetUnspentTransaction, ConsensusLoop>(provider =>
provider.GetService<IConsensusLoop>() as ConsensusLoop);
services.AddSingleton<IInitialBlockDownloadState, InitialBlockDownloadState>();
services.AddSingleton<ConsensusController>();
services.AddSingleton<ConsensusStats>();
services.AddSingleton<ConsensusSettings>();
services.AddSingleton<IConsensusRules, PowConsensusRules>();
services
.AddSingleton<IRuleRegistration,
FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration>();
});
});
return fullNodeBuilder;
}
public static IFullNodeBuilder UseDeStreamPosConsensus(this IFullNodeBuilder fullNodeBuilder)
{
LoggingConfiguration.RegisterFeatureNamespace<ConsensusFeature>("consensus");
LoggingConfiguration.RegisterFeatureClass<ConsensusStats>("bench");
fullNodeBuilder.ConfigureFeature(features =>
{
features
.AddFeature<ConsensusFeature>()
.FeatureServices(services =>
{
fullNodeBuilder.Network.Consensus.Options = new PosConsensusOptions();
services.AddSingleton<ICheckpoints, Checkpoints>();
services.AddSingleton<DBreezeCoinView, DeStreamDBreezeCoinView>();
services.AddSingleton<CoinView, CachedCoinView>();
services.AddSingleton<LookaheadBlockPuller>()
.AddSingleton<ILookaheadBlockPuller, LookaheadBlockPuller>(provider =>
provider.GetService<LookaheadBlockPuller>());
;
services.AddSingleton<IConsensusLoop, ConsensusLoop>()
.AddSingleton<INetworkDifficulty, ConsensusLoop>(provider =>
provider.GetService<IConsensusLoop>() as ConsensusLoop)
.AddSingleton<IGetUnspentTransaction, ConsensusLoop>(provider =>
provider.GetService<IConsensusLoop>() as ConsensusLoop);
services.AddSingleton<StakeChainStore>()
.AddSingleton<IStakeChain, StakeChainStore>(provider =>
provider.GetService<StakeChainStore>());
services.AddSingleton<IStakeValidator, StakeValidator>();
services.AddSingleton<IInitialBlockDownloadState, InitialBlockDownloadState>();
services.AddSingleton<ConsensusController>();
services.AddSingleton<ConsensusStats>();
services.AddSingleton<ConsensusSettings>();
services.AddSingleton<IConsensusRules, PosConsensusRules>();
services
.AddSingleton<IRuleRegistration,
FullNodeBuilderConsensusExtension.PosConsensusRulesRegistration>();
});
});
return fullNodeBuilder;
}
}
}
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Stratis Bitcoin Features Consensus</Description>
<AssemblyTitle>Stratis.Bitcoin.Features.Consensus</AssemblyTitle>
......@@ -17,7 +16,6 @@
<Version>1.1.12-beta</Version>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Deployments\**" />
<EmbeddedResource Remove="Deployments\**" />
......@@ -26,23 +24,19 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NBitcoin\NBitcoin.csproj" />
<ProjectReference Include="..\Stratis.Bitcoin\Stratis.Bitcoin.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="CoinViews\" />
</ItemGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<DefineConstants>$(DefineConstants);NETCORE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<NoWarn>1701;1702;1705;IDE0008;</NoWarn>
<DocumentationFile></DocumentationFile>
<DocumentationFile>
</DocumentationFile>
</PropertyGroup>
</Project>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Stratis.Bitcoin.Builder;
using Stratis.Bitcoin.Configuration.Logging;
using Stratis.Bitcoin.Features.BlockStore;
using Stratis.Bitcoin.Features.MemoryPool;
using Stratis.Bitcoin.Features.RPC;
using Stratis.Bitcoin.Features.Wallet.Broadcasting;
using Stratis.Bitcoin.Features.Wallet.Controllers;
using Stratis.Bitcoin.Features.Wallet.Interfaces;
using Stratis.Bitcoin.Configuration.Logging;
namespace Stratis.Bitcoin.Features.Wallet
{
/// <summary>
/// A class providing extension methods for <see cref="IFullNodeBuilder" />.
/// </summary>
public static class DeStreamFullNodeBuilderWalletExtension
{
public static IFullNodeBuilder DeStreamUseWallet(this IFullNodeBuilder fullNodeBuilder)
public static IFullNodeBuilder UseDeStreamWallet(this IFullNodeBuilder fullNodeBuilder)
{
LoggingConfiguration.RegisterFeatureNamespace<WalletFeature>("wallet");
......@@ -31,7 +30,7 @@ namespace Stratis.Bitcoin.Features.Wallet
{
services.AddSingleton<IWalletSyncManager, WalletSyncManager>();
services.AddSingleton<IWalletTransactionHandler, WalletTransactionHandler>();
services.AddSingleton<IWalletManager, WalletManager>();
services.AddSingleton<IWalletManager, DeStreamWalletManager>();
services.AddSingleton<IWalletFeePolicy, WalletFeePolicy>();
services.AddSingleton<WalletController>();
services.AddSingleton<WalletRPCController>();
......@@ -43,6 +42,5 @@ namespace Stratis.Bitcoin.Features.Wallet
return fullNodeBuilder;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Microsoft.Extensions.Logging;
using NBitcoin;
using Stratis.Bitcoin.Configuration;
......@@ -9,14 +8,64 @@ using Stratis.Bitcoin.Utilities;
namespace Stratis.Bitcoin.Features.Wallet
{
/// <inheritdoc />
public class DeStreamWalletManager : WalletManager
{
public DeStreamWalletManager(ILoggerFactory loggerFactory, Network network, ConcurrentChain chain, NodeSettings settings, WalletSettings walletSettings,
DataFolder dataFolder, IWalletFeePolicy walletFeePolicy, IAsyncLoopFactory asyncLoopFactory, INodeLifetime nodeLifetime, IDateTimeProvider dateTimeProvider,
public DeStreamWalletManager(ILoggerFactory loggerFactory, Network network, ConcurrentChain chain,
NodeSettings settings, WalletSettings walletSettings,
DataFolder dataFolder, IWalletFeePolicy walletFeePolicy, IAsyncLoopFactory asyncLoopFactory,
INodeLifetime nodeLifetime, IDateTimeProvider dateTimeProvider,
IBroadcasterManager broadcasterManager = null) :
base(loggerFactory, network, chain, settings, walletSettings, dataFolder, walletFeePolicy, asyncLoopFactory, nodeLifetime, dateTimeProvider, broadcasterManager)
{ }
base(loggerFactory, network, chain, settings, walletSettings, dataFolder, walletFeePolicy, asyncLoopFactory,
nodeLifetime, dateTimeProvider, broadcasterManager)
{
}
public ConcurrentChain chain { get; set; }
/// <inheritdoc />
public override void Start()
{
base.Start();
this.ProcessGenesisBlock();
}
/// <inheritdoc />
public override Wallet LoadWallet(string password, string name)
{
Wallet result = base.LoadWallet(password, name);
this.LoadKeysLookupLock();
this.ProcessGenesisBlock();
return result;
}
/// <inheritdoc />
public override Wallet RecoverWallet(string password, string name, string mnemonic, DateTime creationTime,
string passphrase = null)
{
Wallet result = base.RecoverWallet(password, name, mnemonic, creationTime, passphrase);
this.ProcessGenesisBlock();
return result;
}
/// <summary>
/// Processes genesis block
/// </summary>
private void ProcessGenesisBlock()
{
foreach (var transactionWithOutput in this.network.GetGenesis().Transactions.SelectMany(p =>
p.Outputs.Select(q => new { Transaction = p, Output = q }).Where(q =>
this.keysLookup.TryGetValue(q.Output.ScriptPubKey, out HdAddress _))))
{
this.AddTransactionToWallet(transactionWithOutput.Transaction, transactionWithOutput.Output, 0,
this.network.GetGenesis());
}
}
}
}
\ No newline at end of file
using System;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
......@@ -52,7 +52,7 @@ namespace Stratis.Bitcoin.Features.Wallet
private readonly CoinType coinType;
/// <summary>Specification of the network the node runs on - regtest/testnet/mainnet.</summary>
private readonly Network network;
protected readonly Network network;
/// <summary>The chain of headers.</summary>
private readonly ConcurrentChain chain;
......@@ -149,7 +149,7 @@ namespace Stratis.Bitcoin.Features.Wallet
this.logger.LogTrace("(-)");
}
public void Start()
public virtual void Start()
{
this.logger.LogTrace("()");
......@@ -256,7 +256,7 @@ namespace Stratis.Bitcoin.Features.Wallet
}
/// <inheritdoc />
public Wallet LoadWallet(string password, string name)
public virtual Wallet LoadWallet(string password, string name)
{
Guard.NotEmpty(password, nameof(password));
Guard.NotEmpty(name, nameof(name));
......@@ -284,7 +284,7 @@ namespace Stratis.Bitcoin.Features.Wallet
}
/// <inheritdoc />
public Wallet RecoverWallet(string password, string name, string mnemonic, DateTime creationTime, string passphrase = null)
public virtual Wallet RecoverWallet(string password, string name, string mnemonic, DateTime creationTime, string passphrase = null)
{
Guard.NotEmpty(password, nameof(password));
Guard.NotEmpty(name, nameof(name));
......@@ -901,7 +901,7 @@ namespace Stratis.Bitcoin.Features.Wallet
/// <param name="blockHeight">Height of the block.</param>
/// <param name="block">The block containing the transaction to add.</param>
/// <param name="isPropagated">Propagation state of the transaction.</param>
private void AddTransactionToWallet(Transaction transaction, TxOut utxo, int? blockHeight = null, Block block = null, bool isPropagated = true)
protected void AddTransactionToWallet(Transaction transaction, TxOut utxo, int? blockHeight = null, Block block = null, bool isPropagated = true)
{
Guard.NotNull(transaction, nameof(transaction));
Guard.NotNull(utxo, nameof(utxo));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment