public void ConsensusManager_Connect_New_Block_Failed() { using (NodeBuilder builder = NodeBuilder.Create(this)) { var syncerNetwork = new StratisOverrideRegTest(); var minerA = builder.CreateStratisPosNode(this.posNetwork); var syncer = builder.CreateStratisPosNode(syncerNetwork); builder.StartAll(); minerA.NotInIBD().WithWallet(); syncer.NotInIBD(); // Miner A mines to height 11. TestHelper.MineBlocks(minerA, 11); // Inject a rule that will fail at block 11 of the new chain ConsensusRuleEngine engine = syncer.FullNode.NodeService <IConsensusRuleEngine>() as ConsensusRuleEngine; syncerNetwork.Consensus.FullValidationRules.Insert(1, new FailValidation(11)); engine.Register(); // Connect syncer to Miner A, reorg should fail. TestHelper.Connect(syncer, minerA); // Syncer should disconnect from miner A after the failed block. TestHelper.WaitLoop(() => !TestHelper.IsNodeConnectedTo(syncer, minerA)); // Make sure syncer rolled back Assert.True(syncer.FullNode.ConsensusManager().Tip.Height == 10); } }
public SmartContractCoinViewRuleLogic(ConsensusRuleEngine parent) { this.refundCounter = 1; this.Parent = parent; this.blockTxsProcessed = new List <Transaction>(); this.receipts = new List <Receipt>(); this.ContractCoinviewRule = (ISmartContractCoinviewRule)this.Parent; }
public void ConsensusManager_Reorgs_Then_Try_To_Connect_Longer_Chain__With__No_Connected_Blocks_And_Fail_Then_Revert_Back() { using (NodeBuilder builder = NodeBuilder.Create(this)) { var syncerNetwork = new BitcoinOverrideRegTest(); var minerA = builder.CreateStratisPowNode(this.powNetwork); var minerB = builder.CreateStratisPowNode(this.powNetwork); var syncer = builder.CreateStratisPowNode(syncerNetwork); builder.StartAll(); minerA.NotInIBD().WithWallet(); minerB.NotInIBD().WithWallet(); syncer.NotInIBD(); // MinerA mines to height 10. TestHelper.MineBlocks(minerA, 10); // Sync the network to height 10. TestHelper.ConnectAndSync(syncer, minerA, minerB); // Disable syncer from sending blocks to miner B TestHelper.DisableBlockPropagation(syncer, minerB); // Miner A and syncer continues to mine to height 20. TestHelper.MineBlocks(minerA, 10); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(syncer, minerA)); // Inject a rule that will fail at block 11 of the new chain ConsensusRuleEngine engine = syncer.FullNode.NodeService <IConsensusRuleEngine>() as ConsensusRuleEngine; syncerNetwork.Consensus.FullValidationRules.Insert(1, new FailValidation(11)); engine.Register(); // Miner B continues to mine to height 30 on a new and longer chain. TestHelper.MineBlocks(minerB, 20); // check miner B at height 30. Assert.True(minerB.FullNode.ConsensusManager().Tip.Height == 30); // Miner B should become disconnected. TestHelper.WaitLoop(() => !TestHelper.IsNodeConnectedTo(syncer, minerB)); // Make sure syncer rolled back Assert.True(syncer.FullNode.ConsensusManager().Tip.Height == 20); // Check syncer is still synced with Miner A TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(syncer, minerA)); } }
public T RegisterRule <T>(ConsensusRuleEngine ruleEngine) where T : ConsensusRuleBase, new() { var rule = new T(); if (rule is IHeaderValidationConsensusRule validationConsensusRule) { ruleEngine.Network.Consensus.HeaderValidationRules = new List <IHeaderValidationConsensusRule>() { validationConsensusRule } } ; else if (rule is IIntegrityValidationConsensusRule consensusRule) { ruleEngine.Network.Consensus.IntegrityValidationRules = new List <IIntegrityValidationConsensusRule>() { consensusRule } } ; else if (rule is IPartialValidationConsensusRule partialValidationConsensusRule) { ruleEngine.Network.Consensus.PartialValidationRules = new List <IPartialValidationConsensusRule>() { partialValidationConsensusRule } } ; else if (rule is IFullValidationConsensusRule fullValidationConsensusRule) { ruleEngine.Network.Consensus.FullValidationRules = new List <IFullValidationConsensusRule>() { fullValidationConsensusRule } } ; else { throw new Exception("Rule type wasn't recognized."); } ruleEngine.Register(); return(rule); }
public IActionResult DeploymentFlags() { try { ConsensusRuleEngine ruleEngine = this.ConsensusManager.ConsensusRules as ConsensusRuleEngine; // Ensure threshold conditions cached. ThresholdState[] thresholdStates = ruleEngine.NodeDeployments.BIP9.GetStates(this.ChainState.ConsensusTip.Previous); List <ThresholdStateModel> metrics = ruleEngine.NodeDeployments.BIP9.GetThresholdStateMetrics(this.ChainState.ConsensusTip.Previous, thresholdStates); return(this.Json(metrics)); } catch (Exception e) { this.logger.LogError("Exception occurred: {0}", e.ToString()); return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString())); } }
public async Task InitializeAsync() { this.blockinfo = new List <Blockinfo>(); List <long> 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 = KnownNetworks.RegTest; byte[] hex = Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"); this.scriptPubKey = new Script(new[] { Op.GetPushOp(hex), OpcodeType.OP_CHECKSIG }); this.entry = new TestMemPoolEntryHelper(); this.ChainIndexer = new ChainIndexer(this.network); this.network.Consensus.Options = new ConsensusOptions(); IDateTimeProvider dateTimeProvider = DateTimeProvider.Default; var loggerFactory = ExtendedLoggerFactory.Create(); var nodeSettings = new NodeSettings(this.network, args: new string[] { "-checkpoints" }); var consensusSettings = new ConsensusSettings(nodeSettings); var inMemoryCoinView = new InMemoryCoinView(new HashHeightPair(this.ChainIndexer.Tip)); var nodeStats = new NodeStats(dateTimeProvider, loggerFactory); this.cachedCoinView = new CachedCoinView(this.network, new Checkpoints(), inMemoryCoinView, dateTimeProvider, new LoggerFactory(), nodeStats, consensusSettings); var signals = new Signals.Signals(loggerFactory, null); var asyncProvider = new AsyncProvider(loggerFactory, signals, new NodeLifetime()); var deployments = new NodeDeployments(this.network, this.ChainIndexer); var genesis = this.network.GetGenesis(); var chainState = new ChainState() { BlockStoreTip = new ChainedHeader(genesis.Header, genesis.GetHash(), 0) }; var consensusRulesContainer = new ConsensusRulesContainer(); foreach (var ruleType in this.network.Consensus.ConsensusRules.HeaderValidationRules) { consensusRulesContainer.HeaderValidationRules.Add(Activator.CreateInstance(ruleType) as HeaderValidationConsensusRule); } foreach (var ruleType in this.network.Consensus.ConsensusRules.FullValidationRules) { FullValidationConsensusRule rule = null; if (ruleType == typeof(FlushUtxosetRule)) { rule = new FlushUtxosetRule(new Mock <IInitialBlockDownloadState>().Object); } else { rule = Activator.CreateInstance(ruleType) as FullValidationConsensusRule; } consensusRulesContainer.FullValidationRules.Add(rule); } this.ConsensusRules = new PowConsensusRuleEngine(this.network, loggerFactory, dateTimeProvider, this.ChainIndexer, deployments, consensusSettings, new Checkpoints(), this.cachedCoinView, chainState, new InvalidBlockHashStore(dateTimeProvider), nodeStats, asyncProvider, consensusRulesContainer).SetupRulesEngineParent(); this.consensus = ConsensusManagerHelper.CreateConsensusManager(this.network, chainState: chainState, inMemoryCoinView: inMemoryCoinView, chainIndexer: this.ChainIndexer, consensusRules: this.ConsensusRules); await this.consensus.InitializeAsync(chainState.BlockStoreTip); this.entry.Fee(11); this.entry.Height(11); var dateTimeProviderSet = new DateTimeProviderSet { time = dateTimeProvider.GetTime(), timeutc = dateTimeProvider.GetUtcNow() }; this.DateTimeProvider = dateTimeProviderSet; this.mempool = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings), loggerFactory, nodeSettings); this.mempoolLock = new MempoolSchedulerLock(); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) this.baseheight = 0; var blocks = new List <Block>(); this.txFirst = new List <Transaction>(); this.nonce = 0; for (int i = 0; i < this.blockinfo.Count; ++i) { Block block = this.network.CreateBlock(); block.Header.HashPrevBlock = this.consensus.Tip.HashBlock; block.Header.Version = 1; block.Header.Time = Utils.DateTimeToUnixTime(this.ChainIndexer.Tip.GetMedianTimePast()) + 1; Transaction txCoinbase = this.network.CreateTransaction(); txCoinbase.Version = 1; txCoinbase.AddInput(new TxIn(new Script(new[] { Op.GetPushOp(this.blockinfo[i].extranonce), Op.GetPushOp(this.ChainIndexer.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())); block.AddTransaction(txCoinbase); if (this.txFirst.Count == 0) { this.baseheight = this.ChainIndexer.Height; } if (this.txFirst.Count < 4) { this.txFirst.Add(block.Transactions[0]); } block.Header.Bits = block.Header.GetWorkRequired(this.network, this.ChainIndexer.Tip); block.UpdateMerkleRoot(); while (!block.CheckProofOfWork()) { block.Header.Nonce = ++this.nonce; } // Serialization sets the BlockSize property. block = Block.Load(block.ToBytes(), this.network.Consensus.ConsensusFactory); var res = await this.consensus.BlockMinedAsync(block); if (res == null) { throw new InvalidOperationException(); } blocks.Add(block); } // Just to make sure we can still make simple blocks this.newBlock = AssemblerForTest(this).Build(this.ChainIndexer.Tip, this.scriptPubKey); Assert.NotNull(this.newBlock); }
public BlockchainInfoModel GetBlockchainInfo() { var blockchainInfo = new BlockchainInfoModel { Chain = this.Network?.Name, Blocks = (uint)(this.ChainState?.ConsensusTip?.Height ?? 0), Headers = (uint)(this.ChainIndexer?.Height ?? 0), BestBlockHash = this.ChainState?.ConsensusTip?.HashBlock, Difficulty = this.GetNetworkDifficulty()?.Difficulty ?? 0.0, MedianTime = this.ChainState?.ConsensusTip?.GetMedianTimePast().ToUnixTimeSeconds() ?? 0, VerificationProgress = 0.0, IsInitialBlockDownload = this.ibdState?.IsInitialBlockDownload() ?? true, Chainwork = this.ChainState?.ConsensusTip?.ChainWork, IsPruned = false }; if (blockchainInfo.Headers > 0) { blockchainInfo.VerificationProgress = (double)blockchainInfo.Blocks / blockchainInfo.Headers; } // softfork deployments blockchainInfo.SoftForks = new List <SoftForks>(); foreach (var consensusBuriedDeployment in Enum.GetValues(typeof(BuriedDeployments))) { bool active = this.ChainIndexer.Height >= this.Network.Consensus.BuriedDeployments[(BuriedDeployments)consensusBuriedDeployment]; blockchainInfo.SoftForks.Add(new SoftForks { Id = consensusBuriedDeployment.ToString().ToLower(), Version = (int)consensusBuriedDeployment + 2, // hack to get the deployment number similar to bitcoin core without changing the enums Status = new SoftForksStatus { Status = active } }); } // softforkbip9 deployments blockchainInfo.SoftForksBip9 = new Dictionary <string, SoftForksBip9>(); ConsensusRuleEngine ruleEngine = (ConsensusRuleEngine)this.ConsensusManager.ConsensusRules; ThresholdState[] thresholdStates = ruleEngine.NodeDeployments.BIP9.GetStates(this.ChainIndexer.Tip.Previous); List <ThresholdStateModel> metrics = ruleEngine.NodeDeployments.BIP9.GetThresholdStateMetrics(this.ChainIndexer.Tip.Previous, thresholdStates); foreach (ThresholdStateModel metric in metrics.Where(m => !m.DeploymentName.ToLower().Contains("test"))) // to remove the test dummy { // TODO: Deployment timeout may not be implemented yet // Deployments with timeout value of 0 are hidden. // A timeout value of 0 guarantees a softfork will never be activated. // This is used when softfork codes are merged without specifying the deployment schedule. if (metric.TimeTimeOut?.Ticks > 0) { blockchainInfo.SoftForksBip9.Add(metric.DeploymentName, this.CreateSoftForksBip9(metric, thresholdStates[metric.DeploymentIndex])); } } // TODO: Implement blockchainInfo.warnings return(blockchainInfo); }
public RuleRegistrationHelper(ConsensusRuleEngine ruleEngine, ConsensusRulesContainer consensusRulesContainer) { this.ruleEngine = ruleEngine; this.consensusRulesContainer = consensusRulesContainer; }
public static ConsensusManager CreateConsensusManager( Network network, string dataDir = null, ChainState chainState = null, InMemoryCoinView inMemoryCoinView = null, ConcurrentChain chain = null, IRuleRegistration ruleRegistration = null, ConsensusRuleEngine consensusRules = null) { string[] param = dataDir == null ? new string[] {} : new string[] { $"-datadir={dataDir}" }; var nodeSettings = new NodeSettings(network, args: param); ILoggerFactory loggerFactory = nodeSettings.LoggerFactory; IDateTimeProvider dateTimeProvider = DateTimeProvider.Default; network.Consensus.Options = new ConsensusOptions(); if (ruleRegistration == null) { ruleRegistration = new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration(); } ruleRegistration.RegisterRules(network.Consensus); // Dont check PoW of a header in this test. network.Consensus.HeaderValidationRules.RemoveAll(x => x.GetType() == typeof(CheckDifficultyPowRule)); var consensusSettings = new ConsensusSettings(nodeSettings); if (chain == null) { chain = new ConcurrentChain(network); } if (inMemoryCoinView == null) { inMemoryCoinView = new InMemoryCoinView(chain.Tip.HashBlock); } var networkPeerFactory = new NetworkPeerFactory(network, dateTimeProvider, loggerFactory, new PayloadProvider().DiscoverPayloads(), new SelfEndpointTracker(loggerFactory), new Mock <IInitialBlockDownloadState>().Object, new ConnectionManagerSettings()); var peerAddressManager = new PeerAddressManager(DateTimeProvider.Default, nodeSettings.DataFolder, loggerFactory, new SelfEndpointTracker(loggerFactory)); var peerDiscovery = new PeerDiscovery(new AsyncLoopFactory(loggerFactory), loggerFactory, network, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager); var connectionSettings = new ConnectionManagerSettings(nodeSettings); var selfEndpointTracker = new SelfEndpointTracker(loggerFactory); var connectionManager = new ConnectionManager(dateTimeProvider, loggerFactory, network, networkPeerFactory, nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { }, peerDiscovery, selfEndpointTracker, connectionSettings, new VersionProvider(), new Mock <INodeStats>().Object); if (chainState == null) { chainState = new ChainState(); } var peerBanning = new PeerBanning(connectionManager, loggerFactory, dateTimeProvider, peerAddressManager); var deployments = new NodeDeployments(network, chain); if (consensusRules == null) { consensusRules = new PowConsensusRuleEngine(network, loggerFactory, dateTimeProvider, chain, deployments, consensusSettings, new Checkpoints(), inMemoryCoinView, chainState, new InvalidBlockHashStore(dateTimeProvider), new NodeStats(dateTimeProvider)).Register(); } consensusRules.Register(); var tree = new ChainedHeaderTree(network, loggerFactory, new HeaderValidator(consensusRules, loggerFactory), new Checkpoints(), new ChainState(), new Mock <IFinalizedBlockInfoRepository>().Object, consensusSettings, new InvalidBlockHashStore(new DateTimeProvider())); var consensus = new ConsensusManager(tree, network, loggerFactory, chainState, new IntegrityValidator(consensusRules, loggerFactory), new PartialValidator(consensusRules, loggerFactory), new FullValidator(consensusRules, loggerFactory), consensusRules, new Mock <IFinalizedBlockInfoRepository>().Object, new Signals.Signals(), peerBanning, new Mock <IInitialBlockDownloadState>().Object, chain, new Mock <IBlockPuller>().Object, new Mock <IBlockStore>().Object, new Mock <IConnectionManager>().Object, new Mock <INodeStats>().Object, new NodeLifetime()); return(consensus); }
public async Task InitializeAsync() { this.blockinfo = new List <Blockinfo>(); List <long> 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 = KnownNetworks.RegTest; byte[] hex = Encoders.Hex.DecodeData("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"); this.scriptPubKey = new Script(new[] { Op.GetPushOp(hex), OpcodeType.OP_CHECKSIG }); this.entry = new TestMemPoolEntryHelper(); this.chain = new ConcurrentChain(this.network); this.network.Consensus.Options = new ConsensusOptions(); new FullNodeBuilderConsensusExtension.PowConsensusRulesRegistration().RegisterRules(this.network.Consensus); IDateTimeProvider dateTimeProvider = DateTimeProvider.Default; this.cachedCoinView = new CachedCoinView(new InMemoryCoinView(this.chain.Tip.HashBlock), dateTimeProvider, new LoggerFactory()); var loggerFactory = new ExtendedLoggerFactory(); loggerFactory.AddConsoleWithFilters(); var nodeSettings = new NodeSettings(args: new string[] { "-checkpoints" }); var consensusSettings = new ConsensusSettings(nodeSettings); var networkPeerFactory = new NetworkPeerFactory(this.network, dateTimeProvider, loggerFactory, new PayloadProvider().DiscoverPayloads(), new SelfEndpointTracker(loggerFactory), new Mock <IInitialBlockDownloadState>().Object, new ConnectionManagerSettings()); var peerAddressManager = new PeerAddressManager(DateTimeProvider.Default, nodeSettings.DataFolder, loggerFactory, new SelfEndpointTracker(loggerFactory)); var peerDiscovery = new PeerDiscovery(new AsyncLoopFactory(loggerFactory), loggerFactory, this.network, networkPeerFactory, new NodeLifetime(), nodeSettings, peerAddressManager); var connectionSettings = new ConnectionManagerSettings(nodeSettings); var selfEndpointTracker = new SelfEndpointTracker(loggerFactory); var connectionManager = new ConnectionManager(dateTimeProvider, loggerFactory, this.network, networkPeerFactory, nodeSettings, new NodeLifetime(), new NetworkPeerConnectionParameters(), peerAddressManager, new IPeerConnector[] { }, peerDiscovery, selfEndpointTracker, connectionSettings, new VersionProvider(), new Mock <INodeStats>().Object); var peerBanning = new PeerBanning(connectionManager, loggerFactory, dateTimeProvider, peerAddressManager); var deployments = new NodeDeployments(this.network, this.chain); var genesis = this.network.GetGenesis(); var chainState = new ChainState() { BlockStoreTip = new ChainedHeader(genesis.Header, genesis.GetHash(), 0) }; this.ConsensusRules = new PowConsensusRuleEngine(this.network, loggerFactory, dateTimeProvider, this.chain, deployments, consensusSettings, new Checkpoints(), this.cachedCoinView, chainState, new InvalidBlockHashStore(dateTimeProvider)).Register(); this.consensus = ConsensusManagerHelper.CreateConsensusManager(this.network); await this.consensus.InitializeAsync(chainState.BlockStoreTip); this.entry.Fee(11); this.entry.Height(11); var dateTimeProviderSet = new MemoryPoolTests.DateTimeProviderSet { time = dateTimeProvider.GetTime(), timeutc = dateTimeProvider.GetUtcNow() }; this.DateTimeProvider = dateTimeProviderSet; this.mempool = new TxMempool(dateTimeProvider, new BlockPolicyEstimator(new MempoolSettings(nodeSettings), loggerFactory, nodeSettings), loggerFactory, nodeSettings); this.mempoolLock = new MempoolSchedulerLock(); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) this.baseheight = 0; var blocks = new List <Block>(); this.txFirst = new List <Transaction>(); this.nonce = 0; for (int i = 0; i < this.blockinfo.Count; ++i) { Block block = this.network.CreateBlock(); block.Header.HashPrevBlock = this.chain.Tip.HashBlock; block.Header.Version = 1; block.Header.Time = Utils.DateTimeToUnixTime(this.chain.Tip.GetMedianTimePast()) + 1; Transaction txCoinbase = this.network.CreateTransaction(); 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())); block.AddTransaction(txCoinbase); if (this.txFirst.Count == 0) { this.baseheight = this.chain.Height; } if (this.txFirst.Count < 4) { this.txFirst.Add(block.Transactions[0]); } block.Header.Bits = block.Header.GetWorkRequired(this.network, this.chain.Tip); block.UpdateMerkleRoot(); while (!block.CheckProofOfWork()) { block.Header.Nonce = ++this.nonce; } // Serialization sets the BlockSize property. block = Block.Load(block.ToBytes(), this.network); await this.consensus.BlockMinedAsync(block); blocks.Add(block); } // Just to make sure we can still make simple blocks this.newBlock = AssemblerForTest(this).Build(this.chain.Tip, this.scriptPubKey); Assert.NotNull(this.newBlock); }