public PosMinting(ConsensusLoop consensusLoop, ConcurrentChain chain, Network network, ConnectionManager connection, IDateTimeProvider dateTimeProvider, AssemblerFactory blockAssemblerFactory, BlockRepository blockRepository, BlockStore.ChainBehavior.ChainState chainState, Signals signals, FullNode.CancellationProvider cancellationProvider, NodeSettings settings, CoinView coinView, StakeChain stakeChain) { this.consensusLoop = consensusLoop; this.chain = chain; this.network = network; this.connection = connection; this.dateTimeProvider = dateTimeProvider; this.blockAssemblerFactory = blockAssemblerFactory; this.blockRepository = blockRepository; this.chainState = chainState; this.signals = signals; this.cancellationProvider = cancellationProvider; this.settings = settings; this.coinView = coinView; this.stakeChain = stakeChain; this.minerSleep = 500; // GetArg("-minersleep", 500); this.lastCoinStakeSearchTime = Utils.DateTimeToUnixTime(this.dateTimeProvider.GetTimeOffset()); // startup timestamp this.reserveBalance = 0; // TOOD:settings.ReserveBalance this.minimumInputValue = 0; this.posConsensusValidator = consensusLoop.Validator as PosConsensusValidator; }
public PowMining( ConsensusLoop consensusLoop, ConcurrentChain chain, Network network, IDateTimeProvider dateTimeProvider, AssemblerFactory blockAssemblerFactory, IBlockRepository blockRepository, ChainState chainState, Signals.Signals signals, INodeLifetime nodeLifetime, IAsyncLoopFactory asyncLoopFactory, ILoggerFactory loggerFactory) { this.consensusLoop = consensusLoop; this.chain = chain; this.network = network; this.dateTimeProvider = dateTimeProvider; this.blockAssemblerFactory = blockAssemblerFactory; this.blockRepository = blockRepository; this.chainState = chainState; this.signals = signals; this.nodeLifetime = nodeLifetime; this.asyncLoopFactory = asyncLoopFactory; this.logger = loggerFactory.CreateLogger(this.GetType().FullName); }
public PosBlockAssembler(ConsensusLoop consensusLoop, Network network, ConcurrentChain chain, MempoolScheduler mempoolScheduler, TxMempool mempool, IDateTimeProvider dateTimeProvider, StakeChain stakeChain, AssemblerOptions options = null) : base(consensusLoop, network, chain, mempoolScheduler, mempool, dateTimeProvider, options) { this.stakeChain = stakeChain; }
public Mining(FullNode fullNode, ConsensusLoop consensusLoop, ConcurrentChain chain, Network network, IDateTimeProvider dateTimeProvider, BlockAssemblerFactory blockAssemblerFactory) { this.fullNode = fullNode; this.consensusLoop = consensusLoop; this.chain = chain; this.network = network; this.dateTimeProvider = dateTimeProvider; this.blockAssemblerFactory = blockAssemblerFactory; }
public BlockAssemblerFactory(ConsensusLoop consensusLoop, Network network, ConcurrentChain chain, MempoolScheduler mempoolScheduler, TxMempool mempool, IDateTimeProvider dateTimeProvider) { this.consensusLoop = consensusLoop; this.network = network; this.chain = chain; this.mempoolScheduler = mempoolScheduler; this.mempool = mempool; this.dateTimeProvider = dateTimeProvider; }
/// <summary> /// Creates a proof of work block assembler. /// </summary> /// <param name="network">Network running on.</param> /// <param name="consensus">Consensus loop.</param> /// <param name="chain">Block chain.</param> /// <param name="mempoolLock">Async lock for memory pool.</param> /// <param name="mempool">Memory pool for transactions.</param> /// <param name="date">Date and time provider.</param> /// <returns>Proof of work block assembler.</returns> private static PowBlockAssembler CreatePowBlockAssembler(Network network, ConsensusLoop consensus, ConcurrentChain chain, MempoolSchedulerLock mempoolLock, TxMempool mempool, IDateTimeProvider date, LoggerFactory loggerFactory) { AssemblerOptions options = new AssemblerOptions(); options.BlockMaxWeight = network.Consensus.Option<PowConsensusOptions>().MaxBlockWeight; options.BlockMaxSize = network.Consensus.Option<PowConsensusOptions>().MaxBlockSerializedSize; FeeRate blockMinFeeRate = new FeeRate(PowMining.DefaultBlockMinTxFee); options.BlockMinFeeRate = blockMinFeeRate; return new PowBlockAssembler(consensus, network, mempoolLock, mempool, date, chain.Tip, loggerFactory, options); }
public PowMining(ConsensusLoop consensusLoop, ConcurrentChain chain, Network network, IDateTimeProvider dateTimeProvider, AssemblerFactory blockAssemblerFactory, BlockRepository blockRepository, BlockStore.ChainBehavior.ChainState chainState, Signals signals, FullNode.CancellationProvider cancellationProvider) { this.consensusLoop = consensusLoop; this.chain = chain; this.network = network; this.dateTimeProvider = dateTimeProvider; this.blockAssemblerFactory = blockAssemblerFactory; this.blockRepository = blockRepository; this.chainState = chainState; this.signals = signals; this.cancellationProvider = cancellationProvider; }
public PosBlockAssembler( ConsensusLoop consensusLoop, Network network, ConcurrentChain chain, MempoolAsyncLock mempoolLock, TxMempool mempool, IDateTimeProvider dateTimeProvider, StakeChain stakeChain, ILogger logger, AssemblerOptions options = null) : base(consensusLoop, network, chain, mempoolLock, mempool, dateTimeProvider, logger, options) { this.stakeChain = stakeChain; }
public void TestSegwitActivation() { using (NodeBuilder builder = NodeBuilder.Create(version: "0.15.1")) { CoreNode coreNode = builder.CreateNode(false); coreNode.ConfigParameters.AddOrReplace("debug", "1"); coreNode.ConfigParameters.AddOrReplace("printtoconsole", "0"); coreNode.Start(); CoreNode node1 = builder.CreateStratisPowNode(true, fullNodeBuilder => { fullNodeBuilder .UseConsensus() .UseBlockStore() .UseMempool() .UseBlockNotification() .UseTransactionNotification() .AddMining() .UseWallet() .UseApi() .AddRPC(); }); WalletManager wm1 = node1.FullNode.NodeService <IWalletManager>() as WalletManager; wm1.CreateWallet("Test1", "alice1"); RPCClient rpc1 = node1.CreateRPCClient(); RPCClient coreRpc = coreNode.CreateRPCClient(); coreRpc.AddNode(node1.Endpoint, false); rpc1.AddNode(coreNode.Endpoint, false); coreRpc.Generate(450); BIP9DeploymentsArray bip9Constants = node1.FullNode.Network.Consensus.BIP9Deployments; ConsensusLoop consensusLoop = node1.FullNode.NodeService <ConsensusLoop>(); ThresholdState[] bip9State = consensusLoop.NodeDeployments.BIP9.GetStates(node1.FullNode.Chain.Tip.Previous); Money amount = new Money(5.0m, MoneyUnit.BTC); HdAddress destination1 = wm1.GetUnusedAddress(new WalletAccountReference("alice1", "account 0")); coreRpc.SendToAddress(BitcoinAddress.Create(destination1.Address, Network.RegTest), amount); coreRpc.Generate(1); Assert.Equal(ThresholdState.Active, bip9State.GetValue((int)BIP9Deployments.Segwit)); } }
/// <summary> /// Creates a proof of work block assembler. /// </summary> /// <param name="network">Network running on.</param> /// <param name="consensus">Consensus loop.</param> /// <param name="chain">Block chain.</param> /// <param name="mempoolLock">Async lock for memory pool.</param> /// <param name="mempool">Memory pool for transactions.</param> /// <param name="date">Date and time provider.</param> /// <returns>Proof of work block assembler.</returns> private static PowBlockAssembler CreatePowBlockAssembler(Network network, ConsensusLoop consensus, ConcurrentChain chain, MempoolAsyncLock mempoolLock, TxMempool mempool, IDateTimeProvider date) { AssemblerOptions options = new AssemblerOptions(); options.BlockMaxWeight = network.Consensus.Option <PowConsensusOptions>().MAX_BLOCK_WEIGHT; options.BlockMaxSize = network.Consensus.Option <PowConsensusOptions>().MAX_BLOCK_SERIALIZED_SIZE; FeeRate blockMinFeeRate = new FeeRate(PowMining.DefaultBlockMinTxFee); options.BlockMinFeeRate = blockMinFeeRate; Mock <ILogger> logger = new Mock <ILogger>(); return(new PowBlockAssembler(consensus, network, chain, mempoolLock, mempool, date, logger.Object, options)); }
public PosBlockAssembler( ConsensusLoop consensusLoop, Network network, MempoolSchedulerLock mempoolLock, TxMempool mempool, IDateTimeProvider dateTimeProvider, StakeChain stakeChain, ChainedBlock chainTip, ILoggerFactory loggerFactory, AssemblerOptions options = null) : base(consensusLoop, network, mempoolLock, mempool, dateTimeProvider, chainTip, loggerFactory, options) { this.logger = loggerFactory.CreateLogger(this.GetType().FullName); this.stakeChain = stakeChain; }
public PowMining(ConsensusLoop consensusLoop, ConcurrentChain chain, Network network, IDateTimeProvider dateTimeProvider, AssemblerFactory blockAssemblerFactory, BlockRepository blockRepository, BlockStore.ChainBehavior.ChainState chainState, Signals signals, INodeLifetime nodeLifetime, IAsyncLoopFactory asyncLoopFactory) { this.consensusLoop = consensusLoop; this.chain = chain; this.network = network; this.dateTimeProvider = dateTimeProvider; this.blockAssemblerFactory = blockAssemblerFactory; this.blockRepository = blockRepository; this.chainState = chainState; this.signals = signals; this.nodeLifetime = nodeLifetime; this.asyncLoopFactory = asyncLoopFactory; }
public PowBlockAssembler( ConsensusLoop consensusLoop, Network network, MempoolAsyncLock mempoolLock, TxMempool mempool, IDateTimeProvider dateTimeProvider, ChainedBlock chainTip, ILoggerFactory loggerFactory, AssemblerOptions options = null) { this.logger = loggerFactory.CreateLogger(this.GetType().FullName); options = options ?? new AssemblerOptions(); this.blockMinFeeRate = options.BlockMinFeeRate; // Limit weight to between 4K and MAX_BLOCK_WEIGHT-4K for sanity. this.blockMaxWeight = (uint)Math.Max(4000, Math.Min(PowMining.DefaultBlockMaxWeight - 4000, options.BlockMaxWeight)); // Limit size to between 1K and MAX_BLOCK_SERIALIZED_SIZE-1K for sanity. this.blockMaxSize = (uint)Math.Max(1000, Math.Min(network.Consensus.Option <PowConsensusOptions>().MaxBlockSerializedSize - 1000, options.BlockMaxSize)); // Whether we need to account for byte usage (in addition to weight usage). this.needSizeAccounting = (this.blockMaxSize < network.Consensus.Option <PowConsensusOptions>().MaxBlockSerializedSize - 1000); this.consensusLoop = consensusLoop; this.mempoolLock = mempoolLock; this.mempool = mempool; this.dateTimeProvider = dateTimeProvider; this.options = options; this.network = network; this.inBlock = new TxMempool.SetEntries(); // Reserve space for coinbase tx. this.blockSize = 1000; this.blockWeight = 4000; this.blockSigOpsCost = 400; this.fIncludeWitness = false; // These counters do not include coinbase tx. this.blockTx = 0; this.fees = 0; this.ChainTip = chainTip; this.pblocktemplate = new BlockTemplate { Block = new Block(), VTxFees = new List <Money>() }; }
public PowMining( ConsensusLoop consensusLoop, ConcurrentChain chain, Network network, AssemblerFactory blockAssemblerFactory, INodeLifetime nodeLifetime, IAsyncLoopFactory asyncLoopFactory, ILoggerFactory loggerFactory) { this.consensusLoop = consensusLoop; this.chain = chain; this.network = network; this.blockAssemblerFactory = blockAssemblerFactory; this.nodeLifetime = nodeLifetime; this.asyncLoopFactory = asyncLoopFactory; this.logger = loggerFactory.CreateLogger(this.GetType().FullName); }
public PosAssemblerFactory( ConsensusLoop consensusLoop, Network network, MempoolAsyncLock mempoolScheduler, TxMempool mempool, IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory, StakeChain stakeChain = null) { this.consensusLoop = consensusLoop; this.network = network; this.mempoolScheduler = mempoolScheduler; this.mempool = mempool; this.dateTimeProvider = dateTimeProvider; this.stakeChain = stakeChain; this.loggerFactory = loggerFactory; this.logger = loggerFactory.CreateLogger(this.GetType().FullName); }
public PosMinting( ConsensusLoop consensusLoop, ConcurrentChain chain, Network network, IConnectionManager connection, IDateTimeProvider dateTimeProvider, AssemblerFactory blockAssemblerFactory, BlockRepository blockRepository, ChainState chainState, Signals.Signals signals, INodeLifetime nodeLifetime, NodeSettings settings, CoinView coinView, StakeChain stakeChain, IWalletManager wallet, IAsyncLoopFactory asyncLoopFactory, ILoggerFactory loggerFactory) { this.consensusLoop = consensusLoop; this.chain = chain; this.network = network; this.connection = connection; this.dateTimeProvider = dateTimeProvider; this.blockAssemblerFactory = blockAssemblerFactory; this.blockRepository = blockRepository; this.chainState = chainState; this.signals = signals; this.nodeLifetime = nodeLifetime; this.settings = settings; this.coinView = coinView; this.stakeChain = stakeChain; this.asyncLoopFactory = asyncLoopFactory; this.wallet = wallet as WalletManager; this.logger = loggerFactory.CreateLogger(this.GetType().FullName); this.minerSleep = 500; // GetArg("-minersleep", 500); this.lastCoinStakeSearchTime = Utils.DateTimeToUnixTime(this.dateTimeProvider.GetTimeOffset()); // startup timestamp this.reserveBalance = 0; // TOOD:settings.ReserveBalance this.minimumInputValue = 0; this.posConsensusValidator = consensusLoop.Validator as PosConsensusValidator; }
public BaseRPCController( IFullNode fullNode = null, NodeSettings nodeSettings = null, Network network = null, PowConsensusValidator consensusValidator = null, ConsensusLoop consensusLoop = null, ConcurrentChain chain = null, ChainState chainState = null, BlockStoreManager blockManager = null, MempoolManager mempoolManager = null, Connection.IConnectionManager connectionManager = null) { this.FullNode = fullNode; this.Settings = nodeSettings; this.Network = network; this.ConsensusValidator = consensusValidator; this.ConsensusLoop = consensusLoop; this.Chain = chain; this.ChainState = chainState; this.BlockManager = blockManager; this.MempoolManager = mempoolManager; this.ConnectionManager = connectionManager; }
public PowBlockAssembler(ConsensusLoop consensusLoop, Network network, ConcurrentChain chain, MempoolScheduler mempoolScheduler, TxMempool mempool, IDateTimeProvider dateTimeProvider, AssemblerOptions options = null) { options = options ?? new AssemblerOptions(); this.blockMinFeeRate = options.BlockMinFeeRate; // Limit weight to between 4K and MAX_BLOCK_WEIGHT-4K for sanity: this.blockMaxWeight = (uint)Math.Max(4000, Math.Min(PowMining.DefaultBlockMaxWeight - 4000, options.BlockMaxWeight)); // Limit size to between 1K and MAX_BLOCK_SERIALIZED_SIZE-1K for sanity: this.blockMaxSize = (uint)Math.Max(1000, Math.Min(network.Consensus.Option <PowConsensusOptions>().MAX_BLOCK_SERIALIZED_SIZE - 1000, options.BlockMaxSize)); // Whether we need to account for byte usage (in addition to weight usage) this.needSizeAccounting = (blockMaxSize < network.Consensus.Option <PowConsensusOptions>().MAX_BLOCK_SERIALIZED_SIZE - 1000); this.consensusLoop = consensusLoop; this.chain = chain; this.mempoolScheduler = mempoolScheduler; this.mempool = mempool; this.dateTimeProvider = dateTimeProvider; this.options = options; this.network = network; this.inBlock = new TxMempool.SetEntries(); // Reserve space for coinbase tx this.blockSize = 1000; this.blockWeight = 4000; this.blockSigOpsCost = 400; this.fIncludeWitness = false; // These counters do not include coinbase tx this.blockTx = 0; this.fees = 0; this.pblocktemplate = new BlockTemplate { Block = new Block(), VTxFees = new List <Money>() }; }
public async Task InitializeAsync() { this.blockinfo = new List <Blockinfo>(); var lst = blockinfoarr.Cast <long>().ToList(); for (int i = 0; i < lst.Count; i += 2) { this.blockinfo.Add(new Blockinfo { extranonce = (int)lst[i], nonce = (uint)lst[i + 1] }); } // Note that by default, these tests run with size accounting enabled. this.network = Network.Main; var hex = Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"); this.scriptPubKey = new Script(new[] { Op.GetPushOp(hex), OpcodeType.OP_CHECKSIG }); this.newBlock = new BlockTemplate(this.network); this.entry = new TestMemPoolEntryHelper(); this.chain = new ConcurrentChain(this.network); this.network.Consensus.Options = new PowConsensusOptions(); IDateTimeProvider dateTimeProvider = DateTimeProvider.Default; this.cachedCoinView = new CachedCoinView(new InMemoryCoinView(this.chain.Tip.HashBlock), dateTimeProvider, new LoggerFactory()); var loggerFactory = new ExtendedLoggerFactory(); loggerFactory.AddConsoleWithFilters(); NodeSettings nodeSettings = new NodeSettings(args: new string[] { "-checkpoints" }); var consensusSettings = new ConsensusSettings().Load(nodeSettings); PowConsensusValidator consensusValidator = new PowConsensusValidator(this.network, new Checkpoints(), dateTimeProvider, loggerFactory); NetworkPeerFactory networkPeerFactory = new NetworkPeerFactory(this.network, dateTimeProvider, loggerFactory, new PayloadProvider().DiscoverPayloads(), new SelfEndpointTracker()); var peerAddressManager = new PeerAddressManager(DateTimeProvider.Default, nodeSettings.DataFolder, loggerFactory, new SelfEndpointTracker()); var peerDiscovery = new PeerDiscovery(new AsyncLoopFactory(loggerFactory), loggerFactory, Network.Main, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager); var connectionSettings = new ConnectionManagerSettings(); connectionSettings.Load(nodeSettings); var connectionManager = new ConnectionManager(dateTimeProvider, loggerFactory, this.network, networkPeerFactory, nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { }, peerDiscovery, connectionSettings); LookaheadBlockPuller blockPuller = new LookaheadBlockPuller(this.chain, connectionManager, new LoggerFactory()); PeerBanning peerBanning = new PeerBanning(connectionManager, loggerFactory, dateTimeProvider, peerAddressManager); NodeDeployments deployments = new NodeDeployments(this.network, this.chain); ConsensusRules consensusRules = new PowConsensusRules(this.network, loggerFactory, dateTimeProvider, this.chain, deployments, consensusSettings, new Checkpoints(), this.cachedCoinView, blockPuller).Register(new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration()); this.consensus = new ConsensusLoop(new AsyncLoopFactory(loggerFactory), consensusValidator, new NodeLifetime(), this.chain, this.cachedCoinView, blockPuller, new NodeDeployments(this.network, this.chain), loggerFactory, new ChainState(new InvalidBlockHashStore(dateTimeProvider)), connectionManager, dateTimeProvider, new Signals.Signals(), consensusSettings, nodeSettings, peerBanning, consensusRules); await this.consensus.StartAsync(); this.entry.Fee(11); this.entry.Height(11); var date1 = new MemoryPoolTests.DateTimeProviderSet(); date1.time = dateTimeProvider.GetTime(); date1.timeutc = dateTimeProvider.GetUtcNow(); this.DateTimeProvider = date1; this.mempool = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(new MempoolSettings(nodeSettings), new LoggerFactory(), nodeSettings), new LoggerFactory(), nodeSettings); this.mempoolLock = new MempoolSchedulerLock(); // Simple block creation, nothing special yet: this.newBlock = AssemblerForTest(this).Build(this.chain.Tip, this.scriptPubKey); this.chain.SetTip(this.newBlock.Block.Header); await this.consensus.ValidateAndExecuteBlockAsync(new RuleContext(new BlockValidationContext { Block = this.newBlock.Block }, this.network.Consensus, this.consensus.Tip) { CheckPow = false, CheckMerkleRoot = false }); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) this.baseheight = 0; List <Block> blocks = new List <Block>(); this.txFirst = new List <Transaction>(); for (int i = 0; i < this.blockinfo.Count; ++i) { var pblock = this.newBlock.Block.Clone(); // pointer for convenience pblock.Header.HashPrevBlock = this.chain.Tip.HashBlock; pblock.Header.Version = 1; pblock.Header.Time = Utils.DateTimeToUnixTime(this.chain.Tip.GetMedianTimePast()) + 1; Transaction txCoinbase = pblock.Transactions[0].Clone(); txCoinbase.Inputs.Clear(); txCoinbase.Version = 1; txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(this.blockinfo[i].extranonce), Op.GetPushOp(this.chain.Height) }))); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this) txCoinbase.AddOutput(new TxOut(Money.Zero, new Script())); pblock.Transactions[0] = txCoinbase; if (this.txFirst.Count == 0) { this.baseheight = this.chain.Height; } if (this.txFirst.Count < 4) { this.txFirst.Add(pblock.Transactions[0]); } pblock.UpdateMerkleRoot(); pblock.Header.Nonce = this.blockinfo[i].nonce; this.chain.SetTip(pblock.Header); await this.consensus.ValidateAndExecuteBlockAsync(new RuleContext(new BlockValidationContext { Block = pblock }, this.network.Consensus, this.consensus.Tip) { CheckPow = false, CheckMerkleRoot = false }); blocks.Add(pblock); } // Just to make sure we can still make simple blocks this.newBlock = AssemblerForTest(this).Build(this.chain.Tip, this.scriptPubKey); Assert.NotNull(this.newBlock); }
/// <summary> /// Creates the test chain with some default blocks and txs. /// </summary> /// <param name="network">Network to create the chain on.</param> /// <param name="scriptPubKey">Public key to create blocks/txs with.</param> /// <returns>Context object representing the test chain.</returns> public static async Task <ITestChainContext> CreateAsync(Network network, Script scriptPubKey, string dataDir) { var nodeSettings = new NodeSettings(network, args: new string[] { $"-datadir={dataDir}" }); ILoggerFactory loggerFactory = nodeSettings.LoggerFactory; IDateTimeProvider dateTimeProvider = DateTimeProvider.Default; network.Consensus.Options = new ConsensusOptions(); network.Consensus.Rules = new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration().GetRules(); var consensusSettings = new ConsensusSettings(nodeSettings); var chain = new ConcurrentChain(network); InMemoryCoinView inMemoryCoinView = new InMemoryCoinView(chain.Tip.HashBlock); var cachedCoinView = new CachedCoinView(inMemoryCoinView, DateTimeProvider.Default, loggerFactory); var networkPeerFactory = new NetworkPeerFactory(network, dateTimeProvider, loggerFactory, new PayloadProvider().DiscoverPayloads(), new SelfEndpointTracker()); var peerAddressManager = new PeerAddressManager(DateTimeProvider.Default, nodeSettings.DataFolder, loggerFactory, new SelfEndpointTracker()); var peerDiscovery = new PeerDiscovery(new AsyncLoopFactory(loggerFactory), loggerFactory, network, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager); var connectionSettings = new ConnectionManagerSettings(nodeSettings); var connectionManager = new ConnectionManager(dateTimeProvider, loggerFactory, network, networkPeerFactory, nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { }, peerDiscovery, connectionSettings, new VersionProvider()); var blockPuller = new LookaheadBlockPuller(chain, connectionManager, new LoggerFactory()); var peerBanning = new PeerBanning(connectionManager, loggerFactory, dateTimeProvider, peerAddressManager); var deployments = new NodeDeployments(network, chain); ConsensusRules consensusRules = new PowConsensusRules(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints(), inMemoryCoinView, new Mock <ILookaheadBlockPuller>().Object).Register(); var consensusLoop = new ConsensusLoop(new AsyncLoopFactory(loggerFactory), new NodeLifetime(), chain, cachedCoinView, blockPuller, deployments, loggerFactory, new ChainState(new InvalidBlockHashStore(dateTimeProvider)), connectionManager, dateTimeProvider, new Signals.Signals(), consensusSettings, nodeSettings, peerBanning, consensusRules); await consensusLoop.StartAsync(); var blockPolicyEstimator = new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings); var mempool = new TxMempool(dateTimeProvider, blockPolicyEstimator, loggerFactory, nodeSettings); var mempoolLock = new MempoolSchedulerLock(); var minerSettings = new MinerSettings(nodeSettings); // Simple block creation, nothing special yet: PowBlockDefinition blockDefinition = new PowBlockDefinition(consensusLoop, dateTimeProvider, loggerFactory, mempool, mempoolLock, minerSettings, network, consensusRules); BlockTemplate newBlock = blockDefinition.Build(chain.Tip, scriptPubKey); chain.SetTip(newBlock.Block.Header); RuleContext ruleContext = consensusRules.CreateRuleContext(new ValidationContext { Block = newBlock.Block }, consensusLoop.Tip); ruleContext.MinedBlock = true; await consensusLoop.ValidateAndExecuteBlockAsync(ruleContext); List <BlockInfo> blockinfo = CreateBlockInfoList(); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) int baseheight = 0; var blocks = new List <Block>(); var srcTxs = new List <Transaction>(); for (int i = 0; i < blockinfo.Count; ++i) { Block currentBlock = Block.Load(newBlock.Block.ToBytes(network.Consensus.ConsensusFactory), network); currentBlock.Header.HashPrevBlock = chain.Tip.HashBlock; currentBlock.Header.Version = 1; currentBlock.Header.Time = Utils.DateTimeToUnixTime(chain.Tip.GetMedianTimePast()) + 1; Transaction txCoinbase = network.CreateTransaction(currentBlock.Transactions[0].ToBytes()); txCoinbase.Inputs.Clear(); txCoinbase.Version = 1; txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(blockinfo[i].extraNonce), Op.GetPushOp(chain.Height) }))); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this) txCoinbase.AddOutput(new TxOut(Money.Zero, new Script())); currentBlock.Transactions[0] = txCoinbase; if (srcTxs.Count == 0) { baseheight = chain.Height; } if (srcTxs.Count < 4) { srcTxs.Add(currentBlock.Transactions[0]); } currentBlock.UpdateMerkleRoot(); currentBlock.Header.Nonce = blockinfo[i].nonce; chain.SetTip(currentBlock.Header); RuleContext ruleContextForBlock = consensusRules.CreateRuleContext(new ValidationContext { Block = currentBlock }, consensusLoop.Tip); ruleContextForBlock.MinedBlock = true; await consensusLoop.ValidateAndExecuteBlockAsync(ruleContextForBlock); blocks.Add(currentBlock); } // Just to make sure we can still make simple blocks blockDefinition = new PowBlockDefinition(consensusLoop, dateTimeProvider, loggerFactory, mempool, mempoolLock, minerSettings, network, consensusRules); newBlock = blockDefinition.Build(chain.Tip, scriptPubKey); var mempoolValidator = new MempoolValidator(mempool, mempoolLock, dateTimeProvider, new MempoolSettings(nodeSettings), chain, cachedCoinView, loggerFactory, nodeSettings, consensusRules); return(new TestChainContext { MempoolValidator = mempoolValidator, SrcTxs = srcTxs }); }
public void Start() { if (IsDisposed) { throw new ObjectDisposedException("FullNode"); } _IsStarted.Reset(); // start all the features defined this.StartFeatures(); // == RPC == // todo: add an RPC feature if (_Settings.RPC != null) { RPCHost = new WebHostBuilder() .UseKestrel() .ForFullNode(this) .UseUrls(_Settings.RPC.GetUrls()) .UseIISIntegration() .UseStartup <RPC.Startup>() .Build(); RPCHost.Start(); _Resources.Add(RPCHost); Logs.RPC.LogInformation("RPC Server listening on: " + Environment.NewLine + String.Join(Environment.NewLine, _Settings.RPC.GetUrls())); } // === Consensus === var coinviewdb = this.Services.ServiceProvider.GetService <DBreezeCoinView>(); // DBreezeCoinView will be in the constructor of a feature coinviewdb.Initialize(this.Network.GetGenesis()).GetAwaiter().GetResult(); var blockPuller = new LookaheadBlockPuller(Chain, ConnectionManager.ConnectedNodes); ConnectionManager.Parameters.TemplateBehaviors.Add(new BlockPuller.BlockPullerBehavior(blockPuller)); var consensusValidator = this.Services.ServiceProvider.GetService <ConsensusValidator>(); // new ConsensusValidator(Network.Consensus); ConsensusLoop = new ConsensusLoop(consensusValidator, Chain, CoinView, blockPuller); this._ChainBehaviorState.HighestValidatedPoW = ConsensusLoop.Tip; // === Miner === this.Miner = new Mining(this, this.DateTimeProvider); var flags = ConsensusLoop.GetFlags(); if (flags.ScriptFlags.HasFlag(ScriptVerify.Witness)) { ConnectionManager.AddDiscoveredNodesRequirement(NodeServices.NODE_WITNESS); } // add disposables (TODO: move this to the consensus feature) this.Resources.Add(coinviewdb); _ChainBehaviorState.HighestValidatedPoW = ConsensusLoop.Tip; ConnectionManager.Start(); new Thread(RunLoop) { Name = "Consensus Loop" }.Start(); _IsStarted.Set(); this.StartPeriodicLog(); }
void RunLoop() { try { var stack = new CoinViewStack(CoinView); var cache = stack.Find <CachedCoinView>(); var stats = new ConsensusStats(this, stack); var cancellationToken = this.GlobalCancellation.Cancellation.Token; ChainedBlock lastTip = ConsensusLoop.Tip; foreach (var block in ConsensusLoop.Execute(cancellationToken)) { bool reorg = false; if (ConsensusLoop.Tip.FindFork(lastTip) != lastTip) { reorg = true; Logs.FullNode.LogInformation("Reorg detected, rewinding from " + lastTip.Height + " (" + lastTip.HashBlock + ") to " + ConsensusLoop.Tip.Height + " (" + ConsensusLoop.Tip.HashBlock + ")"); } lastTip = ConsensusLoop.Tip; cancellationToken.ThrowIfCancellationRequested(); if (block.Error != null) { Logs.FullNode.LogError("Block rejected: " + block.Error.Message); //Pull again ConsensusLoop.Puller.SetLocation(ConsensusLoop.Tip); if (block.Error == ConsensusErrors.BadWitnessNonceSize) { Logs.FullNode.LogInformation("You probably need witness information, activating witness requirement for peers."); ConnectionManager.AddDiscoveredNodesRequirement(NodeServices.NODE_WITNESS); ConsensusLoop.Puller.RequestOptions(TransactionOptions.Witness); continue; } //Set the PoW chain back to ConsensusLoop.Tip Chain.SetTip(ConsensusLoop.Tip); //Since ChainBehavior check PoW, MarkBlockInvalid can't be spammed Logs.FullNode.LogError("Marking block as invalid"); _ChainBehaviorState.MarkBlockInvalid(block.ChainedBlock.HashBlock); } if (!reorg && block.Error == null) { _ChainBehaviorState.HighestValidatedPoW = ConsensusLoop.Tip; if (Chain.Tip.HashBlock == block.ChainedBlock?.HashBlock) { var unused = cache.FlushAsync(); } this.Signals.Blocks.Broadcast(block.Block); } // TODO: replace this with a signalling object if (stats.CanLog) { stats.Log(); } } } catch (Exception ex) //TODO: Barbaric clean exit { if (ex is OperationCanceledException) { if (this.GlobalCancellation.Cancellation.IsCancellationRequested) { return; } } if (!IsDisposed) { Logs.FullNode.LogCritical(new EventId(0), ex, "Consensus loop unhandled exception (Tip:" + ConsensusLoop.Tip?.Height + ")"); _UncatchedException = ex; Dispose(); } } }
/// <summary> /// Creates the test chain with some default blocks and txs. /// </summary> /// <param name="network">Network to create the chain on.</param> /// <param name="scriptPubKey">Public key to create blocks/txs with.</param> /// <returns>Context object representing the test chain.</returns> public static async Task <ITestChainContext> CreateAsync(Network network, Script scriptPubKey, string dataDir) { NodeSettings nodeSettings = new NodeSettings(network.Name, network).LoadArguments(new string[] { $"-datadir={dataDir}" }); if (dataDir != null) { nodeSettings.DataDir = dataDir; } var loggerFactory = new ExtendedLoggerFactory(); IDateTimeProvider dateTimeProvider = DateTimeProvider.Default; network.Consensus.Options = new PowConsensusOptions(); ConsensusSettings consensusSettings = new ConsensusSettings(nodeSettings, loggerFactory); PowConsensusValidator consensusValidator = new PowConsensusValidator(network, new Checkpoints(), dateTimeProvider, loggerFactory); ConcurrentChain chain = new ConcurrentChain(network); CachedCoinView cachedCoinView = new CachedCoinView(new InMemoryCoinView(chain.Tip.HashBlock), DateTimeProvider.Default, loggerFactory); NetworkPeerFactory networkPeerFactory = new NetworkPeerFactory(network, dateTimeProvider, loggerFactory); var peerAddressManager = new PeerAddressManager(nodeSettings.DataFolder, loggerFactory); var peerDiscovery = new PeerDiscovery(new AsyncLoopFactory(loggerFactory), loggerFactory, Network.PurpleMain, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager); var connectionManager = new ConnectionManager(dateTimeProvider, loggerFactory, network, networkPeerFactory, nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { }, peerDiscovery); LookaheadBlockPuller blockPuller = new LookaheadBlockPuller(chain, connectionManager, new LoggerFactory()); PeerBanning peerBanning = new PeerBanning(connectionManager, loggerFactory, dateTimeProvider, nodeSettings); NodeDeployments deployments = new NodeDeployments(network, chain); ConsensusRules consensusRules = new ConsensusRules(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints()).Register(new FullNodeBuilderConsensusExtension.CoreConsensusRules()); ConsensusLoop consensus = new ConsensusLoop(new AsyncLoopFactory(loggerFactory), consensusValidator, new NodeLifetime(), chain, cachedCoinView, blockPuller, deployments, loggerFactory, new ChainState(new InvalidBlockHashStore(dateTimeProvider)), connectionManager, dateTimeProvider, new Signals.Signals(), consensusSettings, nodeSettings, peerBanning, consensusRules); await consensus.StartAsync(); BlockPolicyEstimator blockPolicyEstimator = new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings); TxMempool mempool = new TxMempool(dateTimeProvider, blockPolicyEstimator, loggerFactory, nodeSettings); MempoolSchedulerLock mempoolLock = new MempoolSchedulerLock(); // Simple block creation, nothing special yet: PowBlockAssembler blockAssembler = CreatePowBlockAssembler(network, consensus, chain, mempoolLock, mempool, dateTimeProvider, loggerFactory); BlockTemplate newBlock = blockAssembler.CreateNewBlock(scriptPubKey); chain.SetTip(newBlock.Block.Header); await consensus.ValidateAndExecuteBlockAsync(new RuleContext(new BlockValidationContext { Block = newBlock.Block }, network.Consensus, consensus.Tip) { CheckPow = false, CheckMerkleRoot = false }); List <BlockInfo> blockinfo = CreateBlockInfoList(); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) int baseheight = 0; List <Block> blocks = new List <Block>(); List <Transaction> srcTxs = new List <Transaction>(); for (int i = 0; i < blockinfo.Count; ++i) { Block currentBlock = newBlock.Block.Clone(); // pointer for convenience currentBlock.Header.HashPrevBlock = chain.Tip.HashBlock; currentBlock.Header.Version = 1; currentBlock.Header.Time = Utils.DateTimeToUnixTime(chain.Tip.GetMedianTimePast()) + 1; Transaction txCoinbase = currentBlock.Transactions[0].Clone(); txCoinbase.Inputs.Clear(); txCoinbase.Version = 1; txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(blockinfo[i].extraNonce), Op.GetPushOp(chain.Height) }))); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this) txCoinbase.AddOutput(new TxOut(Money.Zero, new Script())); currentBlock.Transactions[0] = txCoinbase; if (srcTxs.Count == 0) { baseheight = chain.Height; } if (srcTxs.Count < 4) { srcTxs.Add(currentBlock.Transactions[0]); } currentBlock.UpdateMerkleRoot(); currentBlock.Header.Nonce = blockinfo[i].nonce; chain.SetTip(currentBlock.Header); await consensus.ValidateAndExecuteBlockAsync(new RuleContext(new BlockValidationContext { Block = currentBlock }, network.Consensus, consensus.Tip) { CheckPow = false, CheckMerkleRoot = false }); blocks.Add(currentBlock); } // Just to make sure we can still make simple blocks blockAssembler = CreatePowBlockAssembler(network, consensus, chain, mempoolLock, mempool, dateTimeProvider, loggerFactory); newBlock = blockAssembler.CreateNewBlock(scriptPubKey); MempoolValidator mempoolValidator = new MempoolValidator(mempool, mempoolLock, consensusValidator, dateTimeProvider, new MempoolSettings(nodeSettings), chain, cachedCoinView, loggerFactory, nodeSettings); return(new TestChainContext { MempoolValidator = mempoolValidator, SrcTxs = srcTxs }); }
public TestContext() { this.blockinfo = new List <Blockinfo>(); var lst = blockinfoarr.Cast <long>().ToList(); for (int i = 0; i < lst.Count; i += 2) { this.blockinfo.Add(new Blockinfo() { extranonce = (int)lst[i], nonce = (uint)lst[i + 1] }); } // Note that by default, these tests run with size accounting enabled. this.network = Network.Main; var hex = Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"); this.scriptPubKey = new Script(new[] { Op.GetPushOp(hex), OpcodeType.OP_CHECKSIG }); this.newBlock = new BlockTemplate(); this.entry = new TestMemPoolEntryHelper(); this.chain = new ConcurrentChain(this.network); this.network.Consensus.Options = new PowConsensusOptions(); this.cachedCoinView = new CachedCoinView(new InMemoryCoinView(this.chain.Tip.HashBlock), new LoggerFactory()); this.consensus = new ConsensusLoop(new PowConsensusValidator(this.network), this.chain, this.cachedCoinView, new LookaheadBlockPuller(this.chain, new ConnectionManager(this.network, new NodeConnectionParameters(), new NodeSettings(), new LoggerFactory(), new NodeLifetime()), new LoggerFactory()), new NodeDeployments(this.network)); this.consensus.Initialize(); this.entry.Fee(11); this.entry.Height(11); var date1 = new MemoryPoolTests.DateTimeProviderSet(); date1.time = DateTimeProvider.Default.GetTime(); date1.timeutc = DateTimeProvider.Default.GetUtcNow(); this.date = date1; this.mempool = new TxMempool(new FeeRate(1000), DateTimeProvider.Default, new BlockPolicyEstimator(new FeeRate(1000), NodeSettings.Default(), new LoggerFactory()), new LoggerFactory());; this.mempoolLock = new MempoolAsyncLock(); // Simple block creation, nothing special yet: this.newBlock = AssemblerForTest(this).CreateNewBlock(this.scriptPubKey); this.chain.SetTip(this.newBlock.Block.Header); this.consensus.AcceptBlock(new ContextInformation(new BlockResult { Block = this.newBlock.Block }, this.network.Consensus) { CheckPow = false, CheckMerkleRoot = false }); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) this.baseheight = 0; List <Block> blocks = new List <Block>(); this.txFirst = new List <Transaction>(); for (int i = 0; i < this.blockinfo.Count; ++i) { var pblock = this.newBlock.Block.Clone(); // pointer for convenience pblock.Header.HashPrevBlock = this.chain.Tip.HashBlock; pblock.Header.Version = 1; pblock.Header.Time = Utils.DateTimeToUnixTime(this.chain.Tip.GetMedianTimePast()) + 1; Transaction txCoinbase = pblock.Transactions[0].Clone(); txCoinbase.Inputs.Clear(); txCoinbase.Version = 1; txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(this.blockinfo[i].extranonce), Op.GetPushOp(this.chain.Height) }))); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this) txCoinbase.AddOutput(new TxOut(Money.Zero, new Script())); pblock.Transactions[0] = txCoinbase; if (this.txFirst.Count == 0) { this.baseheight = this.chain.Height; } if (this.txFirst.Count < 4) { this.txFirst.Add(pblock.Transactions[0]); } pblock.UpdateMerkleRoot(); pblock.Header.Nonce = this.blockinfo[i].nonce; this.chain.SetTip(pblock.Header); this.consensus.AcceptBlock(new ContextInformation(new BlockResult { Block = pblock }, this.network.Consensus) { CheckPow = false, CheckMerkleRoot = false }); blocks.Add(pblock); } // Just to make sure we can still make simple blocks this.newBlock = AssemblerForTest(this).CreateNewBlock(this.scriptPubKey); Assert.NotNull(this.newBlock); }
public ConsensusController(ChainBehavior.ChainState chainState = null, ConsensusLoop consensusLoop = null, ConcurrentChain chain = null) : base(chainState: chainState, consensusLoop: consensusLoop, chain: chain) { }
/// <summary> /// Creates the test chain with some default blocks and txs. /// </summary> /// <param name="network">Network to create the chain on.</param> /// <param name="scriptPubKey">Public key to create blocks/txs with.</param> /// <returns>Context object representing the test chain.</returns> public static ITestChainContext Create(Network network, Script scriptPubKey) { NodeSettings nodeSettings = NodeSettings.Default(); LoggerFactory loggerFactory = new LoggerFactory(); IDateTimeProvider dateTimeProvider = DateTimeProvider.Default; network.Consensus.Options = new PowConsensusOptions(); PowConsensusValidator consensusValidator = new PowConsensusValidator(network); ConcurrentChain chain = new ConcurrentChain(network); CachedCoinView cachedCoinView = new CachedCoinView(new InMemoryCoinView(chain.Tip.HashBlock), loggerFactory); ConnectionManager connectionManager = new ConnectionManager(network, new NodeConnectionParameters(), nodeSettings, loggerFactory, new NodeLifetime()); LookaheadBlockPuller blockPuller = new LookaheadBlockPuller(chain, connectionManager, new LoggerFactory()); ConsensusLoop consensus = new ConsensusLoop(consensusValidator, chain, cachedCoinView, blockPuller, new NodeDeployments(network)); consensus.Initialize(); BlockPolicyEstimator blockPolicyEstimator = new BlockPolicyEstimator(new FeeRate(1000), nodeSettings, loggerFactory); TxMempool mempool = new TxMempool(new FeeRate(1000), dateTimeProvider, blockPolicyEstimator, loggerFactory); MempoolAsyncLock mempoolLock = new MempoolAsyncLock(); // Simple block creation, nothing special yet: PowBlockAssembler blockAssembler = CreatePowBlockAssembler(network, consensus, chain, mempoolLock, mempool, dateTimeProvider); BlockTemplate newBlock = blockAssembler.CreateNewBlock(scriptPubKey); chain.SetTip(newBlock.Block.Header); consensus.AcceptBlock(new ContextInformation(new BlockResult { Block = newBlock.Block }, network.Consensus) { CheckPow = false, CheckMerkleRoot = false }); List <BlockInfo> blockinfo = CreateBlockInfoList(); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) int baseheight = 0; List <Block> blocks = new List <Block>(); List <Transaction> srcTxs = new List <Transaction>(); for (int i = 0; i < blockinfo.Count; ++i) { Block currentBlock = newBlock.Block.Clone(); // pointer for convenience currentBlock.Header.HashPrevBlock = chain.Tip.HashBlock; currentBlock.Header.Version = 1; currentBlock.Header.Time = Utils.DateTimeToUnixTime(chain.Tip.GetMedianTimePast()) + 1; Transaction txCoinbase = currentBlock.Transactions[0].Clone(); txCoinbase.Inputs.Clear(); txCoinbase.Version = 1; txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(blockinfo[i].extraNonce), Op.GetPushOp(chain.Height) }))); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this) txCoinbase.AddOutput(new TxOut(Money.Zero, new Script())); currentBlock.Transactions[0] = txCoinbase; if (srcTxs.Count == 0) { baseheight = chain.Height; } if (srcTxs.Count < 4) { srcTxs.Add(currentBlock.Transactions[0]); } currentBlock.UpdateMerkleRoot(); currentBlock.Header.Nonce = blockinfo[i].nonce; chain.SetTip(currentBlock.Header); consensus.AcceptBlock(new ContextInformation(new BlockResult { Block = currentBlock }, network.Consensus) { CheckPow = false, CheckMerkleRoot = false }); blocks.Add(currentBlock); } // Just to make sure we can still make simple blocks blockAssembler = CreatePowBlockAssembler(network, consensus, chain, mempoolLock, mempool, dateTimeProvider); newBlock = blockAssembler.CreateNewBlock(scriptPubKey); MempoolValidator mempoolValidator = new MempoolValidator(mempool, mempoolLock, consensusValidator, dateTimeProvider, nodeSettings, chain, cachedCoinView, loggerFactory); return(new TestChainContext { MempoolValidator = mempoolValidator, SrcTxs = srcTxs }); }
public ConsensusController(ILoggerFactory loggerFactory, ChainState chainState = null, ConsensusLoop consensusLoop = null, ConcurrentChain chain = null) : base(chainState: chainState, consensusLoop: consensusLoop, chain: chain) { this.logger = loggerFactory.CreateLogger(this.GetType().FullName); }