예제 #1
0
        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);
 }
예제 #3
0
 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;
 }
예제 #4
0
 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);
        }
예제 #7
0
 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));
            }
        }
예제 #10
0
        /// <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));
        }
예제 #11
0
 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>()
            };
        }
예제 #14
0
 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);
 }
예제 #15
0
 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;
 }
예제 #18
0
        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>()
            };
        }
예제 #19
0
            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);
            }
예제 #20
0
        /// <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
            });
        }
예제 #21
0
        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();
        }
예제 #22
0
        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();
                }
            }
        }
예제 #23
0
        /// <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
            });
        }
예제 #24
0
            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)
 {
 }
예제 #26
0
        /// <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
            });
        }
예제 #27
0
 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);
 }