/// <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, args: new string[] { $"-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(DateTimeProvider.Default, nodeSettings.DataFolder, loggerFactory); 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, network, networkPeerFactory, nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { }, peerDiscovery, connectionSettings); 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 PowConsensusRules(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints()).Register(new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration()); 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 }); }
/// <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, string dataDir) { NodeSettings nodeSettings = NodeSettings.FromArguments(new string[] { $"-datadir={dataDir}" }, network.Name, network); if (dataDir != null) { nodeSettings.DataDir = dataDir; } LoggerFactory loggerFactory = new LoggerFactory(); IDateTimeProvider dateTimeProvider = DateTimeProvider.Default; network.Consensus.Options = new PowConsensusOptions(); PowConsensusValidator consensusValidator = new PowConsensusValidator(network, new Checkpoints(network), loggerFactory); 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), loggerFactory); consensus.Initialize(); BlockPolicyEstimator blockPolicyEstimator = new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings); TxMempool mempool = new TxMempool(dateTimeProvider, blockPolicyEstimator, loggerFactory, nodeSettings); MempoolAsyncLock mempoolLock = new MempoolAsyncLock(); // 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); 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, 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 }); }
private PowMining CreateProofOfWorkMiner(PowBlockAssembler blockBuilder) { return(new PowMining(this.asyncLoopFactory.Object, blockBuilder, this.consensusLoop.Object, this.chain, DateTimeProvider.Default, this.mempool.Object, this.mempoolLock, this.network, this.nodeLifetime.Object, this.LoggerFactory.Object)); }