Example #1
0
        public static ISourceBlock<ValidatableTx> ReplayRollbackUtxo(ICoreStorage coreStorage, IChainState chainState, ChainedHeader replayBlock, CancellationToken cancelToken = default(CancellationToken))
        {
            // replaying rollback of an on-chain block, use the chainstate tx index for replay, same as replaying forward
            if (chainState.Chain.BlocksByHash.ContainsKey(replayBlock.Hash))
            {
                return ReplayFromTxIndex(coreStorage, chainState, replayBlock, replayForward: false, cancelToken: cancelToken);
            }
            // replaying rollback of an off-chain (re-org) block, use the unminted information for replay
            else
            {
                IImmutableList<UnmintedTx> unmintedTxesList;
                if (!chainState.TryGetBlockUnmintedTxes(replayBlock.Hash, out unmintedTxesList))
                {
                    //TODO if a wallet/monitor were to see a chainstate block that wasn't flushed to disk yet,
                    //TODO and if bitsharp crashed, and if the block was orphaned: then the orphaned block would
                    //TODO not be present in the chainstate, and it would not get rolled back to generate unminted information.
                    //TODO DeferredChainStateCursor should be used in order to re-org the chainstate in memory and calculate the unminted information
                    throw new MissingDataException(replayBlock.Hash);
                }

                var unmintedTxes = ImmutableDictionary.CreateRange(
                    unmintedTxesList.Select(x => new KeyValuePair<UInt256, UnmintedTx>(x.TxHash, x)));

                var lookupLoadingTx = new TransformBlock<DecodedBlockTx, ValidatableTx>(
                    blockTx =>
                    {
                        var tx = blockTx.Transaction;
                        var txIndex = blockTx.Index;
                        var prevTxOutputs = ImmutableArray.CreateBuilder<PrevTxOutput>(!blockTx.IsCoinbase ? tx.Inputs.Length : 0);

                        if (!blockTx.IsCoinbase)
                        {
                            UnmintedTx unmintedTx;
                            if (!unmintedTxes.TryGetValue(tx.Hash, out unmintedTx))
                                throw new MissingDataException(replayBlock.Hash);

                            prevTxOutputs.AddRange(unmintedTx.PrevTxOutputs);
                        }

                        return new ValidatableTx(blockTx, replayBlock, prevTxOutputs.MoveToImmutable());
                    });

                IEnumerator<BlockTx> blockTxes;
                if (!coreStorage.TryReadBlockTransactions(replayBlock.Hash, out blockTxes))
                {
                    throw new MissingDataException(replayBlock.Hash);
                }

                var blockTxesBuffer = new BufferBlock<DecodedBlockTx>();
                blockTxesBuffer.LinkTo(lookupLoadingTx, new DataflowLinkOptions { PropagateCompletion = true });

                blockTxesBuffer.SendAndCompleteAsync(blockTxes.UsingAsEnumerable().Select(x => x.Decode()).Reverse(), cancelToken).Forget();

                return lookupLoadingTx;
            }
        }
        public BlockStoreController(Network network,
                                    ILoggerFactory loggerFactory,
                                    IBlockStore blockStore,
                                    IChainState chainState)
        {
            Guard.NotNull(network, nameof(network));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(chainState, nameof(chainState));

            this.network    = network;
            this.blockStore = blockStore;
            this.chainState = chainState;
            this.logger     = loggerFactory.CreateLogger(this.GetType().FullName);
        }
        /// <summary>
        /// Initializes an instanse of the object.
        /// </summary>
        /// <param name="chain">Thread safe chain of block headers from genesis.</param>
        /// <param name="chainState">Information about node's chain.</param>
        /// <param name="loggerFactory">Factory for creating loggers.</param>
        /// <param name="initialBlockDownloadState">Provider of IBD state.</param>
        public ChainHeadersBehavior(ConcurrentChain chain, IChainState chainState, IInitialBlockDownloadState initialBlockDownloadState, ILoggerFactory loggerFactory)
        {
            Guard.NotNull(chain, nameof(chain));

            this.chainState                = chainState;
            this.chain                     = chain;
            this.loggerFactory             = loggerFactory;
            this.initialBlockDownloadState = initialBlockDownloadState;
            this.logger                    = loggerFactory.CreateLogger(this.GetType().FullName, $"[{this.GetHashCode():x}] ");

            this.AutoSync = true;
            this.CanSync  = true;
            this.CanRespondToGetHeaders = true;
        }
 public DataFeederProcessor(ILogger <DataFeederProcessor> logger,
                            IEventBus eventBus,
                            IDateTimeProvider dateTimeProvider,
                            IPeerBehaviorManager peerBehaviorManager,
                            IInitialBlockDownloadTracker ibdState,
                            IChainState chainState,
                            IOptions <BitcoinSettings> options)
     : base(logger, eventBus, peerBehaviorManager, isHandshakeAware: true, receiveMessagesOnlyIfHandshaked: true)
 {
     _dateTimeProvider = dateTimeProvider;
     _ibdState         = ibdState;
     _chainState       = chainState;
     _settings         = options.Value;
 }
Example #5
0
        public NodeController(
            ChainIndexer chainIndexer,
            IChainState chainState,
            IConnectionManager connectionManager,
            IDateTimeProvider dateTimeProvider,
            IFullNode fullNode,
            ILoggerFactory loggerFactory,
            NodeSettings nodeSettings,
            Network network,
            IAsyncProvider asyncProvider,
            ISelfEndpointTracker selfEndpointTracker,
            IBlockStore blockStore = null,
            IGetUnspentTransaction getUnspentTransaction             = null,
            INetworkDifficulty networkDifficulty                     = null,
            IPooledGetUnspentTransaction pooledGetUnspentTransaction = null,
            IPooledTransaction pooledTransaction                     = null,
            IConsensusManager consensusManager  = null,
            IInitialBlockDownloadState ibdState = null)
        {
            Guard.NotNull(fullNode, nameof(fullNode));
            Guard.NotNull(network, nameof(network));
            Guard.NotNull(chainIndexer, nameof(chainIndexer));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(nodeSettings, nameof(nodeSettings));
            Guard.NotNull(chainState, nameof(chainState));
            Guard.NotNull(connectionManager, nameof(connectionManager));
            Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider));
            Guard.NotNull(asyncProvider, nameof(asyncProvider));
            Guard.NotNull(selfEndpointTracker, nameof(selfEndpointTracker));
            Guard.NotNull(consensusManager, nameof(consensusManager));

            this.chainIndexer        = chainIndexer;
            this.chainState          = chainState;
            this.connectionManager   = connectionManager;
            this.dateTimeProvider    = dateTimeProvider;
            this.fullNode            = fullNode;
            this.logger              = loggerFactory.CreateLogger(this.GetType().FullName);
            this.network             = network;
            this.nodeSettings        = nodeSettings;
            this.asyncProvider       = asyncProvider;
            this.selfEndpointTracker = selfEndpointTracker;

            this.blockStore                  = blockStore;
            this.getUnspentTransaction       = getUnspentTransaction;
            this.networkDifficulty           = networkDifficulty;
            this.pooledGetUnspentTransaction = pooledGetUnspentTransaction;
            this.pooledTransaction           = pooledTransaction;
            this.consensusManager            = consensusManager;
            this.ibdState = ibdState;
        }
Example #6
0
 public ProvenHeadersBlockStoreSignaled(
     Network network,
     IBlockStoreQueue blockStoreQueue,
     StoreSettings storeSettings,
     IChainState chainState,
     IConnectionManager connection,
     INodeLifetime nodeLifetime,
     ILoggerFactory loggerFactory,
     IInitialBlockDownloadState initialBlockDownloadState,
     IProvenBlockHeaderStore provenBlockHeaderStore)
     : base(blockStoreQueue, storeSettings, chainState, connection, nodeLifetime, loggerFactory, initialBlockDownloadState)
 {
     this.network = Guard.NotNull(network, nameof(network));
     this.provenBlockHeaderStore = Guard.NotNull(provenBlockHeaderStore, nameof(provenBlockHeaderStore));
 }
 public PosConsensusRuleEngine(Network network, ILoggerFactory loggerFactory, IDateTimeProvider dateTimeProvider,
                               ChainIndexer chainIndexer, NodeDeployments nodeDeployments,
                               ConsensusSettings consensusSettings, ICheckpoints checkpoints, ICoinView utxoSet, IStakeChain stakeChain,
                               IStakeValidator stakeValidator, IChainState chainState,
                               IInvalidBlockHashStore invalidBlockHashStore, INodeStats nodeStats,
                               IRewindDataIndexCache rewindDataIndexCache, IAsyncProvider asyncProvider,
                               ConsensusRulesContainer consensusRulesContainer)
     : base(network, loggerFactory, dateTimeProvider, chainIndexer, nodeDeployments, consensusSettings,
            checkpoints, utxoSet, chainState, invalidBlockHashStore, nodeStats, asyncProvider,
            consensusRulesContainer)
 {
     this.StakeChain           = stakeChain;
     this.StakeValidator       = stakeValidator;
     this.RewindDataIndexCache = rewindDataIndexCache;
 }
Example #8
0
        public InitialBlockDownloadState(IChainState chainState, Network network, ConsensusSettings consensusSettings, ICheckpoints checkpoints, ILoggerFactory loggerFactory, IDateTimeProvider dateTimeProvider)
        {
            Guard.NotNull(chainState, nameof(chainState));

            this.network           = network;
            this.consensusSettings = consensusSettings;
            this.chainState        = chainState;
            this.checkpoints       = checkpoints;
            this.dateTimeProvider  = dateTimeProvider;

            this.lastCheckpointHeight = this.checkpoints.GetLastCheckpointHeight();
            this.minimumChainWork     = this.network.Consensus.MinimumChainWork ?? uint256.Zero;

            this.logger = loggerFactory.CreateLogger(this.GetType().FullName);
        }
Example #9
0
        public static ISourceBlock<ValidatableTx> ReplayBlock(ICoreStorage coreStorage, IChainState chainState, UInt256 blockHash, bool replayForward, CancellationToken cancelToken = default(CancellationToken))
        {
            ChainedHeader replayBlock;
            if (!coreStorage.TryGetChainedHeader(blockHash, out replayBlock))
                throw new MissingDataException(blockHash);

            // replay the validatable txes for this block, in reverse order for a rollback
            ISourceBlock<ValidatableTx> validatableTxes;
            if (replayForward)
                validatableTxes = UtxoReplayer.ReplayCalculateUtxo(coreStorage, chainState, replayBlock, cancelToken);
            else
                validatableTxes = UtxoReplayer.ReplayRollbackUtxo(coreStorage, chainState, replayBlock, cancelToken);

            return validatableTxes;
        }
Example #10
0
        /// <inheritdoc />
        public override void Initialize()
        {
            base.Initialize();

            PoAConsensusRuleEngine engine = this.Parent as PoAConsensusRuleEngine;

            this.slotsManager      = engine.SlotsManager;
            this.validator         = engine.PoaHeaderValidator;
            this.votingManager     = engine.VotingManager;
            this.federationManager = engine.FederationManager;
            this.chainState        = engine.ChainState;

            this.maxReorg      = this.Parent.Network.Consensus.MaxReorgLength;
            this.votingEnabled = ((PoAConsensusOptions)this.Parent.Network.Consensus.Options).VotingEnabled;
        }
 public BlockNotificationFeature(
     IBlockNotification blockNotification,
     IConnectionManager connectionManager,
     IConsensusManager consensusManager,
     IChainState chainState,
     ConcurrentChain chain,
     ILoggerFactory loggerFactory)
 {
     this.blockNotification = blockNotification;
     this.connectionManager = connectionManager;
     this.consensusManager  = consensusManager;
     this.chainState        = chainState;
     this.chain             = chain;
     this.loggerFactory     = loggerFactory;
 }
        /// <inheritdoc />
        public override void Initialize()
        {
            base.Initialize();

            var engine = this.Parent as PoAConsensusRuleEngine;

            // TODO: Consider adding these via a constructor on this rule.
            this.slotsManager      = engine.SlotsManager;
            this.federationHistory = engine.FederationHistory;
            this.validator         = engine.PoaHeaderValidator;
            this.chainState        = engine.ChainState;
            this.network           = this.Parent.Network;

            this.maxReorg = this.network.Consensus.MaxReorgLength;
        }
 public FeatureController(
     IFullNode fullNode        = null,
     NodeSettings nodeSettings = null,
     Network network           = null,
     ConcurrentChain chain     = null,
     IChainState chainState    = null,
     Connection.IConnectionManager connectionManager = null)
 {
     this.FullNode          = fullNode;
     this.Settings          = nodeSettings;
     this.Network           = network;
     this.Chain             = chain;
     this.ChainState        = chainState;
     this.ConnectionManager = connectionManager;
 }
Example #14
0
        public ConsensusManager(
            Network network,
            ILoggerFactory loggerFactory,
            IChainState chainState,
            IHeaderValidator headerValidator,
            IIntegrityValidator integrityValidator,
            IPartialValidation partialValidation,
            ICheckpoints checkpoints,
            ConsensusSettings consensusSettings,
            IConsensusRules consensusRules,
            IFinalizedBlockHeight finalizedBlockHeight,
            Signals.Signals signals,
            IPeerBanning peerBanning,
            NodeSettings nodeSettings,
            IDateTimeProvider dateTimeProvider,
            IInitialBlockDownloadState ibdState,
            ConcurrentChain chain,
            IBlockStore blockStore = null)
        {
            this.network              = network;
            this.chainState           = chainState;
            this.partialValidation    = partialValidation;
            this.consensusSettings    = consensusSettings;
            this.consensusRules       = consensusRules;
            this.signals              = signals;
            this.peerBanning          = peerBanning;
            this.blockStore           = blockStore;
            this.finalizedBlockHeight = finalizedBlockHeight;
            this.chain  = chain;
            this.logger = loggerFactory.CreateLogger(this.GetType().FullName);

            this.chainedHeaderTree = new ChainedHeaderTree(network, loggerFactory, headerValidator, integrityValidator, checkpoints, chainState, finalizedBlockHeight, consensusSettings, signals);

            this.peerLock               = new object();
            this.reorgLock              = new AsyncLock();
            this.blockRequestedLock     = new object();
            this.expectedBlockDataBytes = 0;
            this.expectedBlockSizes     = new Dictionary <uint256, long>();

            this.callbacksByBlocksRequestedHash = new Dictionary <uint256, List <OnBlockDownloadedCallback> >();
            this.peersByPeerId   = new Dictionary <int, INetworkPeer>();
            this.toDownloadQueue = new Queue <BlockDownloadRequest>();
            this.ibdState        = ibdState;

            ProtocolVersion protocolVersion = nodeSettings.ProtocolVersion;

            this.blockPuller = new BlockPuller(this.BlockDownloaded, this.chainState, protocolVersion, dateTimeProvider, loggerFactory);
        }
Example #15
0
        public UnreliablePeerBehavior(Network network, IChainState chainState, ILoggerFactory loggerFactory, IPeerBanning peerBanning, NodeSettings nodeSettings)
        {
            Guard.NotNull(network, nameof(network));
            Guard.NotNull(chainState, nameof(chainState));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(peerBanning, nameof(nodeSettings));
            Guard.NotNull(nodeSettings, nameof(nodeSettings));

            this.network       = network;
            this.chainState    = chainState;
            this.loggerFactory = loggerFactory;
            this.peerBanning   = peerBanning;
            this.nodeSettings  = nodeSettings;

            this.logger = loggerFactory.CreateLogger(this.GetType().FullName);
        }
Example #16
0
        public BlockStoreController(Network network,
                                    ILoggerFactory loggerFactory,
                                    IBlockStore blockStore,
                                    IChainState chainState,
                                    ChainIndexer chainIndexer)
        {
            Guard.NotNull(network, nameof(network));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(chainState, nameof(chainState));

            this.network      = network;
            this.blockStore   = blockStore;
            this.chainState   = chainState;
            this.chainIndexer = chainIndexer;
            this.logger       = loggerFactory.CreateLogger("Impleum.Bitcoin.FullNode");
        }
Example #17
0
        public ConsensusFeature(
            Network network,
            IChainState chainState,
            IConnectionManager connectionManager,
            ISignals signals,
            IConsensusManager consensusManager,
            NodeDeployments nodeDeployments)
        {
            this.chainState        = chainState;
            this.connectionManager = connectionManager;
            this.signals           = signals;
            this.consensusManager  = consensusManager;
            this.nodeDeployments   = nodeDeployments;

            this.chainState.MaxReorgLength = network.Consensus.MaxReorgLength;
        }
Example #18
0
        public static UInt256 ComputeHash(IChainState chainState)
        {
            using (var sha256 = new SHA256Managed())
            {
                // add each unspent tx to hash
                foreach (var unspentTx in chainState.ReadUnspentTransactions())
                {
                    var unspentTxBytes = DataEncoder.EncodeUnspentTx(unspentTx);
                    sha256.TransformBlock(unspentTxBytes, 0, unspentTxBytes.Length, unspentTxBytes, 0);
                }
                // finalize hash
                sha256.TransformFinalBlock(new byte[0], 0, 0);

                // hash again to return double-hashed utxo committment
                return new UInt256(SHA256Static.ComputeHash(sha256.Hash));
            }
        }
Example #19
0
 public PruneBlockStoreService(
     IAsyncLoopFactory asyncLoopFactory,
     IBlockRepository blockRepository,
     IPrunedBlockRepository prunedBlockRepository,
     IChainState chainState,
     ILoggerFactory loggerFactory,
     INodeLifetime nodeLifetime,
     StoreSettings storeSettings)
 {
     this.asyncLoopFactory      = asyncLoopFactory;
     this.blockRepository       = blockRepository;
     this.prunedBlockRepository = prunedBlockRepository;
     this.chainState            = chainState;
     this.logger        = loggerFactory.CreateLogger("Impleum.Bitcoin.FullNode");
     this.nodeLifetime  = nodeLifetime;
     this.storeSettings = storeSettings;
 }
Example #20
0
        public static UInt256 ComputeHash(IChainState chainState)
        {
            using (var sha256 = new SHA256Managed())
            {
                // add each unspent tx to hash
                foreach (var unspentTx in chainState.ReadUnspentTransactions())
                {
                    var unspentTxBytes = DataEncoder.EncodeUnspentTx(unspentTx);
                    sha256.TransformBlock(unspentTxBytes, 0, unspentTxBytes.Length, unspentTxBytes, 0);
                }
                // finalize hash
                sha256.TransformFinalBlock(new byte[0], 0, 0);

                // hash again to return double-hashed utxo committment
                return(new UInt256(SHA256Static.ComputeHash(sha256.Hash)));
            }
        }
Example #21
0
 public PruneBlockStoreService(
     IAsyncProvider asyncProvider,
     IBlockRepository blockRepository,
     IPrunedBlockRepository prunedBlockRepository,
     IChainState chainState,
     ILoggerFactory loggerFactory,
     INodeLifetime nodeLifetime,
     StoreSettings storeSettings)
 {
     this.asyncProvider         = asyncProvider;
     this.blockRepository       = blockRepository;
     this.prunedBlockRepository = prunedBlockRepository;
     this.chainState            = chainState;
     this.logger        = loggerFactory.CreateLogger(this.GetType().FullName);
     this.nodeLifetime  = nodeLifetime;
     this.storeSettings = storeSettings;
 }
Example #22
0
 public FeatureController(
     IFullNode fullNode                   = null,
     Network network                      = null,
     NodeSettings nodeSettings            = null,
     ChainIndexer chainIndexer            = null,
     IChainState chainState               = null,
     IConnectionManager connectionManager = null,
     IConsensusManager consensusManager   = null)
 {
     this.FullNode          = fullNode;
     this.Settings          = nodeSettings;
     this.Network           = network;
     this.ChainIndexer      = chainIndexer;
     this.ChainState        = chainState;
     this.ConnectionManager = connectionManager;
     this.ConsensusManager  = consensusManager;
 }
        protected ConsensusRuleEngine(
            Network network,
            ILoggerFactory loggerFactory,
            IDateTimeProvider dateTimeProvider,
            ChainIndexer chainIndexer,
            NodeDeployments nodeDeployments,
            ConsensusSettings consensusSettings,
            ICheckpoints checkpoints,
            IChainState chainState,
            IInvalidBlockHashStore invalidBlockHashStore,
            INodeStats nodeStats)
        {
            Guard.NotNull(network, nameof(network));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider));
            Guard.NotNull(chainIndexer, nameof(chainIndexer));
            Guard.NotNull(nodeDeployments, nameof(nodeDeployments));
            Guard.NotNull(consensusSettings, nameof(consensusSettings));
            Guard.NotNull(checkpoints, nameof(checkpoints));
            Guard.NotNull(chainState, nameof(chainState));
            Guard.NotNull(invalidBlockHashStore, nameof(invalidBlockHashStore));
            Guard.NotNull(nodeStats, nameof(nodeStats));

            this.Network               = network;
            this.ChainIndexer          = chainIndexer;
            this.ChainState            = chainState;
            this.NodeDeployments       = nodeDeployments;
            this.LoggerFactory         = loggerFactory;
            this.ConsensusSettings     = consensusSettings;
            this.Checkpoints           = checkpoints;
            this.ConsensusParams       = this.Network.Consensus;
            this.ConsensusSettings     = consensusSettings;
            this.DateTimeProvider      = dateTimeProvider;
            this.invalidBlockHashStore = invalidBlockHashStore;
            this.LoggerFactory         = loggerFactory;
            this.logger          = loggerFactory.CreateLogger("Impleum.Bitcoin.Fullnode");
            this.NodeDeployments = nodeDeployments;

            this.headerValidationRules    = new List <HeaderValidationConsensusRule>();
            this.integrityValidationRules = new List <IntegrityValidationConsensusRule>();
            this.partialValidationRules   = new List <PartialValidationConsensusRule>();
            this.fullValidationRules      = new List <FullValidationConsensusRule>();

            nodeStats.RegisterStats(this.AddBenchStats, StatsType.Benchmark, 500);
        }
Example #24
0
        private async Task ScanBlock(ICoreStorage coreStorage, IChainState chainState, ChainedHeader scanBlock, bool forward, CancellationToken cancelToken = default(CancellationToken))
        {
            var replayTxes = BlockReplayer.ReplayBlock(coreStorage, chainState, scanBlock.Hash, forward, cancelToken);

            var txScanner = new ActionBlock <ValidatableTx>(
                validatableTx =>
            {
                var tx      = validatableTx.Transaction;
                var txIndex = validatableTx.Index;

                if (!validatableTx.IsCoinbase)
                {
                    for (var inputIndex = 0; inputIndex < tx.Inputs.Length; inputIndex++)
                    {
                        var input                = tx.Inputs[inputIndex];
                        var prevOutput           = validatableTx.PrevTxOutputs[inputIndex];
                        var prevOutputScriptHash = new UInt256(SHA256Static.ComputeHash(prevOutput.ScriptPublicKey));

                        var chainPosition = ChainPosition.Fake();
                        var entryType     = forward ? EnumWalletEntryType.Spend : EnumWalletEntryType.UnSpend;

                        ScanForEntry(chainPosition, entryType, (TxOutput)prevOutput, prevOutputScriptHash);
                    }
                }

                for (var outputIndex = 0; outputIndex < tx.Outputs.Length; outputIndex++)
                {
                    var output           = tx.Outputs[outputIndex];
                    var outputScriptHash = new UInt256(SHA256Static.ComputeHash(output.ScriptPublicKey));

                    var chainPosition = ChainPosition.Fake();
                    var entryType     =
                        validatableTx.IsCoinbase ?
                        (forward ? EnumWalletEntryType.Mine : EnumWalletEntryType.UnMine)
                                : (forward ? EnumWalletEntryType.Receive : EnumWalletEntryType.UnReceieve);

                    ScanForEntry(chainPosition, entryType, output, outputScriptHash);
                }
            });

            replayTxes.LinkTo(txScanner, new DataflowLinkOptions {
                PropagateCompletion = true
            });
            await txScanner.Completion;
        }
        protected ConsensusRuleEngine(
            Network network,
            ILoggerFactory loggerFactory,
            IDateTimeProvider dateTimeProvider,
            ChainIndexer chainIndexer,
            NodeDeployments nodeDeployments,
            ConsensusSettings consensusSettings,
            ICheckpoints checkpoints,
            IChainState chainState,
            IInvalidBlockHashStore invalidBlockHashStore,
            INodeStats nodeStats,
            ConsensusRulesContainer consensusRules)
        {
            Guard.NotNull(network, nameof(network));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider));
            Guard.NotNull(chainIndexer, nameof(chainIndexer));
            Guard.NotNull(nodeDeployments, nameof(nodeDeployments));
            Guard.NotNull(consensusSettings, nameof(consensusSettings));
            Guard.NotNull(checkpoints, nameof(checkpoints));
            Guard.NotNull(chainState, nameof(chainState));
            Guard.NotNull(invalidBlockHashStore, nameof(invalidBlockHashStore));
            Guard.NotNull(nodeStats, nameof(nodeStats));

            this.Network               = network;
            this.ChainIndexer          = chainIndexer;
            this.ChainState            = chainState;
            this.NodeDeployments       = nodeDeployments;
            this.LoggerFactory         = loggerFactory;
            this.ConsensusSettings     = consensusSettings;
            this.Checkpoints           = checkpoints;
            this.ConsensusParams       = this.Network.Consensus;
            this.ConsensusSettings     = consensusSettings;
            this.DateTimeProvider      = dateTimeProvider;
            this.invalidBlockHashStore = invalidBlockHashStore;
            this.consensusRules        = consensusRules;
            this.LoggerFactory         = loggerFactory;
            this.logger          = loggerFactory.CreateLogger(this.GetType().FullName);
            this.NodeDeployments = nodeDeployments;

            if (nodeStats.DisplayBenchStats)
            {
                nodeStats.RegisterStats(this.AddBenchStats, StatsType.Benchmark, this.GetType().Name, 500);
            }
        }
Example #26
0
        public BlockStoreBehavior(ConcurrentChain chain, IChainState chainState, ILoggerFactory loggerFactory, IConsensusManager consensusManager)
        {
            Guard.NotNull(chain, nameof(chain));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(consensusManager, nameof(consensusManager));

            this.chain            = chain;
            this.chainState       = chainState;
            this.logger           = loggerFactory.CreateLogger(this.GetType().FullName);
            this.loggerFactory    = loggerFactory;
            this.consensusManager = consensusManager;

            this.CanRespondToGetBlocksPayload = true;
            this.CanRespondToGetDataPayload   = true;

            this.PreferHeaders      = false;
            this.preferHeaderAndIDs = false;
        }
 public ProvenHeadersConsensusManagerBehavior(
     ConcurrentChain chain,
     IInitialBlockDownloadState initialBlockDownloadState,
     IConsensusManager consensusManager,
     IPeerBanning peerBanning,
     ILoggerFactory loggerFactory,
     Network network,
     IChainState chainState) : base(chain, initialBlockDownloadState, consensusManager, peerBanning, loggerFactory)
 {
     this.chain = chain;
     this.initialBlockDownloadState = initialBlockDownloadState;
     this.consensusManager          = consensusManager;
     this.peerBanning   = peerBanning;
     this.network       = network;
     this.loggerFactory = loggerFactory;
     this.logger        = loggerFactory.CreateLogger(this.GetType().FullName, $"[{this.GetHashCode():x}] ");
     this.chainState    = chainState;
 }
Example #28
0
        public UnreliablePeerBehavior(Network network, IChainState chainState, ILoggerFactory loggerFactory, IPeerBanning peerBanning, NodeSettings nodeSettings, ICheckpoints checkpoints)
        {
            Guard.NotNull(network, nameof(network));
            Guard.NotNull(chainState, nameof(chainState));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(peerBanning, nameof(nodeSettings));
            Guard.NotNull(nodeSettings, nameof(nodeSettings));
            Guard.NotNull(checkpoints, nameof(checkpoints));

            this.network       = network;
            this.chainState    = chainState;
            this.loggerFactory = loggerFactory;
            this.peerBanning   = peerBanning;
            this.nodeSettings  = nodeSettings;
            this.checkpoints   = checkpoints;

            this.logger = loggerFactory.CreateLogger("Impleum.Bitcoin.Fullnode");
        }
Example #29
0
 public FullNodeController(
     ILoggerFactory loggerFactory,
     IFullNode fullNode        = null,
     NodeSettings nodeSettings = null,
     Network network           = null,
     ConcurrentChain chain     = null,
     IChainState chainState    = null,
     Connection.IConnectionManager connectionManager = null)
     : base(
         fullNode: fullNode,
         nodeSettings: nodeSettings,
         network: network,
         chain: chain,
         chainState: chainState,
         connectionManager: connectionManager)
 {
     this.logger = loggerFactory.CreateLogger(this.GetType().FullName);
 }
        public ChainedHeaderTree(
            Network network,
            ILoggerFactory loggerFactory,
            IChainedHeaderValidator chainedHeaderValidator,
            ICheckpoints checkpoints,
            IChainState chainState,
            ConsensusSettings consensusSettings)
        {
            this.network = network;
            this.chainedHeaderValidator = chainedHeaderValidator;
            this.checkpoints            = checkpoints;
            this.chainState             = chainState;
            this.consensusSettings      = consensusSettings;
            this.logger = loggerFactory.CreateLogger(this.GetType().FullName);

            this.peerTipsByPeerId     = new Dictionary <int, uint256>();
            this.peerIdsByTipHash     = new Dictionary <uint256, HashSet <int> >();
            this.chainedHeadersByHash = new Dictionary <uint256, ChainedHeader>();
        }
Example #31
0
        /// <inheritdoc />
        public override void Initialize()
        {
            base.Initialize();

            var engine = this.Parent as PoAConsensusRuleEngine;

            // TODO: Consider adding these via a constructor on this rule.
            this.slotsManager      = engine.SlotsManager;
            this.federationHistory = engine.FederationHistory;
            this.validator         = engine.PoaHeaderValidator;
            this.chainState        = engine.ChainState;
            this.network           = this.Parent.Network;

            this.maxReorg = this.network.Consensus.MaxReorgLength;

            KeyValuePair <int, CheckpointInfo> lastCheckPoint = engine.Network.Checkpoints.LastOrDefault();

            this.lastCheckPoint = (lastCheckPoint.Value != null) ? new HashHeightPair(lastCheckPoint.Value.Hash, lastCheckPoint.Key) : null;
        }
        public BlockStoreBehavior(ChainIndexer chainIndexer, IChainState chainState, ILoggerFactory loggerFactory, IConsensusManager consensusManager, IBlockStoreQueue blockStoreQueue)
        {
            Guard.NotNull(chainIndexer, nameof(chainIndexer));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(consensusManager, nameof(consensusManager));
            Guard.NotNull(blockStoreQueue, nameof(blockStoreQueue));

            this.ChainIndexer     = chainIndexer;
            this.chainState       = chainState;
            this.logger           = loggerFactory.CreateLogger(this.GetType().FullName);
            this.loggerFactory    = loggerFactory;
            this.consensusManager = consensusManager;
            this.blockStoreQueue  = blockStoreQueue;

            this.CanRespondToGetDataPayload = true;

            this.PreferHeaders      = false;
            this.preferHeaderAndIDs = false;
        }
        public BlockExplorerController(
            Network network,
            ILoggerFactory loggerFactory,
            IBlockStore blockStoreCache,
            IStakeChain stakeChain,
            ChainIndexer chain,
            IChainState chainState)
        {
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(blockStoreCache, nameof(blockStoreCache));
            Guard.NotNull(chainState, nameof(chainState));

            this.network         = network;
            this.blockStoreCache = blockStoreCache;
            this.stakeChain      = stakeChain;
            this.chain           = chain;
            this.chainState      = chainState;
            this.logger          = loggerFactory.CreateLogger(this.GetType().FullName);
        }
        public DeferredChainStateCursor(IChainState chainState, IStorageManager storageManager)
        {
            this.chainState = chainState;
            this.storageManager = storageManager;

            UnspentOutputCount = chainState.UnspentOutputCount;
            UnspentTxCount = chainState.UnspentTxCount;
            TotalTxCount = chainState.TotalTxCount;
            TotalInputCount = chainState.TotalInputCount;
            TotalOutputCount = chainState.TotalOutputCount;

            headers = new DeferredDictionary<UInt256, ChainedHeader>(
                blockHash =>
                {
                    ChainedHeader header;
                    return Tuple.Create(chainState.TryGetHeader(blockHash, out header), header);
                });

            unspentTxes = new WorkQueueDictionary<UInt256, UnspentTx>(
                txHash =>
                {
                    UnspentTx unspentTx;
                    return Tuple.Create(chainState.TryGetUnspentTx(txHash, out unspentTx), unspentTx);
                });

            blockSpentTxes = new DeferredDictionary<int, BlockSpentTxes>(
                blockHeight =>
                {
                    BlockSpentTxes spentTxes;
                    return Tuple.Create(chainState.TryGetBlockSpentTxes(blockHeight, out spentTxes), spentTxes);
                });

            blockUnmintedTxes = new DeferredDictionary<UInt256, IImmutableList<UnmintedTx>>(
                blockHash =>
                {
                    IImmutableList<UnmintedTx> unmintedTxes;
                    return Tuple.Create(chainState.TryGetBlockUnmintedTxes(blockHash, out unmintedTxes), unmintedTxes);
                });
        }
Example #35
0
        public static ISourceBlock<LoadedTx> ReplayBlock(ICoreStorage coreStorage, IChainState chainState, UInt256 blockHash, bool replayForward, CancellationToken cancelToken = default(CancellationToken))
        {
            ChainedHeader replayBlock;
            if (!coreStorage.TryGetChainedHeader(blockHash, out replayBlock))
                throw new MissingDataException(blockHash);

            // replay the loading txes for this block, in reverse order for a rollback
            ISourceBlock<LoadingTx> loadingTxes;
            if (replayForward)
                loadingTxes = UtxoReplayer.ReplayCalculateUtxo(coreStorage, chainState, replayBlock, cancelToken);
            else
                loadingTxes = UtxoReplayer.ReplayRollbackUtxo(coreStorage, chainState, replayBlock, cancelToken);

            // capture the original loading txes order
            var orderedLoadingTxes = OrderingBlock.CaptureOrder<LoadingTx, LoadedTx, UInt256>(
                loadingTxes, loadingTx => loadingTx.Transaction.Hash, cancelToken);

            // begin loading txes
            var loadedTxes = TxLoader.LoadTxes(coreStorage, orderedLoadingTxes, cancelToken);

            // return the loaded txes in original order
            return orderedLoadingTxes.ApplyOrder(loadedTxes, loadedTx => loadedTx.Transaction.Hash, cancelToken);
        }
Example #36
0
        private static ISourceBlock<ValidatableTx> ReplayFromTxIndex(ICoreStorage coreStorage, IChainState chainState, ChainedHeader replayBlock, bool replayForward, CancellationToken cancelToken = default(CancellationToken))
        {
            //TODO use replayForward to retrieve blocks in reverse order
            //TODO also check that the block hasn't been pruned (that information isn't stored yet)

            IEnumerator<BlockTx> blockTxes;
            if (!coreStorage.TryReadBlockTransactions(replayBlock.Hash, out blockTxes))
            {
                throw new MissingDataException(replayBlock.Hash);
            }

            var blockTxesBuffer = new BufferBlock<DecodedBlockTx>();
            if (replayForward)
                blockTxesBuffer.SendAndCompleteAsync(blockTxes.UsingAsEnumerable().Select(x => x.Decode()), cancelToken).Forget();
            else
                blockTxesBuffer.SendAndCompleteAsync(blockTxes.UsingAsEnumerable().Select(x => x.Decode()).Reverse(), cancelToken).Forget();

            // begin looking up txes
            var lookupValidatableTx = InitLookupValidatableTx(chainState, replayBlock, cancelToken);
            blockTxesBuffer.LinkTo(lookupValidatableTx, new DataflowLinkOptions { PropagateCompletion = true });

            return lookupValidatableTx;
        }
Example #37
0
        //TODO this should lookup in parallel and then get sorted, like TxLoader, etc.
        private static TransformBlock<DecodedBlockTx, ValidatableTx> InitLookupValidatableTx(IChainState chainState, ChainedHeader replayBlock, CancellationToken cancelToken)
        {
            return new TransformBlock<DecodedBlockTx, ValidatableTx>(
                blockTx =>
                {
                    var tx = blockTx.Transaction;
                    var txIndex = blockTx.Index;

                    var prevTxOutputs = ImmutableArray.CreateBuilder<PrevTxOutput>(!blockTx.IsCoinbase ? tx.Inputs.Length : 0);

                    if (!blockTx.IsCoinbase)
                    {
                        for (var inputIndex = 0; inputIndex < tx.Inputs.Length; inputIndex++)
                        {
                            var input = tx.Inputs[inputIndex];

                            UnspentTx unspentTx;
                            if (!chainState.TryGetUnspentTx(input.PrevTxOutputKey.TxHash, out unspentTx))
                                throw new MissingDataException(replayBlock.Hash);

                            TxOutput txOutput;
                            if (!chainState.TryGetUnspentTxOutput(input.PrevTxOutputKey, out txOutput))
                                throw new MissingDataException(replayBlock.Hash);

                            prevTxOutputs.Add(new PrevTxOutput(txOutput, unspentTx));
                        }
                    }

                    return new ValidatableTx(blockTx, replayBlock, prevTxOutputs.MoveToImmutable());
                },
                new ExecutionDataflowBlockOptions { CancellationToken = cancelToken, MaxDegreeOfParallelism = Math.Min(Environment.ProcessorCount, chainState.CursorCount) });
        }
        public DeferredChainStateCursor(IChainState chainState, IStorageManager storageManager)
        {
            this.chainState = chainState;
            this.storageManager = storageManager;

            headers = new DeferredDictionary<UInt256, ChainedHeader>(
                blockHash =>
                {
                    ChainedHeader header;
                    return Tuple.Create(chainState.TryGetHeader(blockHash, out header), header);
                });

            unspentTxes = new WorkQueueDictionary<UInt256, UnspentTx>(
                txHash =>
                {
                    UnspentTx unspentTx;
                    return Tuple.Create(chainState.TryGetUnspentTx(txHash, out unspentTx), unspentTx);
                });

            unspentTxOutputs = new WorkQueueDictionary<TxOutputKey, TxOutput>(
                txOutputKey =>
                {
                    TxOutput txOutput;
                    return Tuple.Create(chainState.TryGetUnspentTxOutput(txOutputKey, out txOutput), txOutput);
                });

            blockSpentTxes = new DeferredDictionary<int, BlockSpentTxes>(
                blockHeight =>
                {
                    BlockSpentTxes spentTxes;
                    return Tuple.Create(chainState.TryGetBlockSpentTxes(blockHeight, out spentTxes), spentTxes);
                });

            blockUnmintedTxes = new DeferredDictionary<UInt256, IImmutableList<UnmintedTx>>(
                blockHash =>
                {
                    IImmutableList<UnmintedTx> unmintedTxes;
                    return Tuple.Create(chainState.TryGetBlockUnmintedTxes(blockHash, out unmintedTxes), unmintedTxes);
                });

            utxoApplier = new ActionBlock<WorkQueueDictionary<UInt256, UnspentTx>.WorkItem>(
                workItem =>
                {
                    workItem.Consume(
                        (operation, unspentTxHash, unspentTx) =>
                        {
                            lock (parentCursor)
                                switch (operation)
                                {
                                    case WorkQueueOperation.Nothing:
                                        break;

                                    case WorkQueueOperation.Add:
                                        if (!parentCursor.TryAddUnspentTx(unspentTx))
                                            throw new InvalidOperationException();
                                        break;

                                    case WorkQueueOperation.Update:
                                        if (!parentCursor.TryUpdateUnspentTx(unspentTx))
                                            throw new InvalidOperationException();
                                        break;

                                    case WorkQueueOperation.Remove:
                                        if (!parentCursor.TryRemoveUnspentTx(unspentTxHash))
                                            throw new InvalidOperationException();
                                        break;

                                    default:
                                        throw new InvalidOperationException();
                                }
                        });
                });

            unspentTxes.WorkQueue.LinkTo(utxoApplier, new DataflowLinkOptions { PropagateCompletion = true });

            utxoApplier2 = new ActionBlock<WorkQueueDictionary<TxOutputKey, TxOutput>.WorkItem>(
                workItem =>
                {
                    workItem.Consume(
                        (operation, txOutputKey, txOutput) =>
                        {
                            lock (parentCursor)
                                switch (operation)
                                {
                                    case WorkQueueOperation.Nothing:
                                        break;

                                    case WorkQueueOperation.Add:
                                        if (!parentCursor.TryAddUnspentTxOutput(txOutputKey, txOutput))
                                            throw new InvalidOperationException();
                                        break;

                                    case WorkQueueOperation.Update:
                                        throw new InvalidOperationException();

                                    case WorkQueueOperation.Remove:
                                        if (!parentCursor.TryRemoveUnspentTxOutput(txOutputKey))
                                            throw new InvalidOperationException();
                                        break;

                                    default:
                                        throw new InvalidOperationException();
                                }
                        });
                });

            unspentTxOutputs.WorkQueue.LinkTo(utxoApplier2, new DataflowLinkOptions { PropagateCompletion = true });
        }
Example #39
0
        private async Task ScanBlock(ICoreStorage coreStorage, IChainState chainState, ChainedHeader scanBlock, bool forward, CancellationToken cancelToken = default(CancellationToken))
        {
            var replayTxes = BlockReplayer.ReplayBlock(coreStorage, chainState, scanBlock.Hash, forward, cancelToken);

            var txScanner = new ActionBlock<ValidatableTx>(
                validatableTx =>
                {
                    var tx = validatableTx.Transaction;
                    var txIndex = validatableTx.Index;

                    if (!validatableTx.IsCoinbase)
                    {
                        for (var inputIndex = 0; inputIndex < tx.Inputs.Length; inputIndex++)
                        {
                            var input = tx.Inputs[inputIndex];
                            var prevOutput = validatableTx.PrevTxOutputs[inputIndex];
                            var prevOutputScriptHash = new UInt256(SHA256Static.ComputeHash(prevOutput.ScriptPublicKey));

                            var chainPosition = ChainPosition.Fake();
                            var entryType = forward ? EnumWalletEntryType.Spend : EnumWalletEntryType.UnSpend;

                            ScanForEntry(chainPosition, entryType, (TxOutput)prevOutput, prevOutputScriptHash);
                        }
                    }

                    for (var outputIndex = 0; outputIndex < tx.Outputs.Length; outputIndex++)
                    {
                        var output = tx.Outputs[outputIndex];
                        var outputScriptHash = new UInt256(SHA256Static.ComputeHash(output.ScriptPublicKey));

                        var chainPosition = ChainPosition.Fake();
                        var entryType =
                            validatableTx.IsCoinbase ?
                                (forward ? EnumWalletEntryType.Mine : EnumWalletEntryType.UnMine)
                                : (forward ? EnumWalletEntryType.Receive : EnumWalletEntryType.UnReceieve);

                        ScanForEntry(chainPosition, entryType, output, outputScriptHash);
                    }
                });

            replayTxes.LinkTo(txScanner, new DataflowLinkOptions { PropagateCompletion = true });
            await txScanner.Completion;
        }
 public DisposeHandle<IDeferredChainStateCursor> OpenDeferredChainStateCursor(IChainState chainState)
 {
     return chainStateManager.Value.OpenDeferredChainStateCursor();
 }
Example #41
0
 public DisposeHandle<IDeferredChainStateCursor> OpenDeferredChainStateCursor(IChainState chainState)
 {
     var cursor = new DeferredChainStateCursor(chainState, this);
     return new DisposeHandle<IDeferredChainStateCursor>(
         _ => cursor.Dispose(), cursor);
 }
Example #42
0
        //TODO this should lookup in parallel and then get sorted, like TxLoader, etc.
        private static TransformBlock<BlockTx, LoadingTx> InitLookupLoadingTx(IChainState chainState, ChainedHeader replayBlock, CancellationToken cancelToken)
        {
            return new TransformBlock<BlockTx, LoadingTx>(
                blockTx =>
                {
                    var tx = blockTx.Transaction;
                    var txIndex = blockTx.Index;

                    var prevOutputTxKeys = ImmutableArray.CreateBuilder<TxLookupKey>(!blockTx.IsCoinbase ? tx.Inputs.Length : 0);

                    if (!blockTx.IsCoinbase)
                    {
                        for (var inputIndex = 0; inputIndex < tx.Inputs.Length; inputIndex++)
                        {
                            var input = tx.Inputs[inputIndex];

                            UnspentTx unspentTx;
                            if (!chainState.TryGetUnspentTx(input.PreviousTxOutputKey.TxHash, out unspentTx))
                                throw new MissingDataException(replayBlock.Hash);

                            var prevOutputBlockHash = chainState.Chain.Blocks[unspentTx.BlockIndex].Hash;
                            var prevOutputTxIndex = unspentTx.TxIndex;

                            prevOutputTxKeys.Add(new TxLookupKey(prevOutputBlockHash, prevOutputTxIndex));
                        }
                    }

                    return new LoadingTx(txIndex, tx, replayBlock, prevOutputTxKeys.MoveToImmutable());
                },
                new ExecutionDataflowBlockOptions { CancellationToken = cancelToken, MaxDegreeOfParallelism = Math.Min(Environment.ProcessorCount, chainState.CursorCount) });
        }
Example #43
0
 public static ISourceBlock<ValidatableTx> ReplayCalculateUtxo(ICoreStorage coreStorage, IChainState chainState, ChainedHeader replayBlock, CancellationToken cancelToken = default(CancellationToken))
 {
     return ReplayFromTxIndex(coreStorage, chainState, replayBlock, replayForward: true, cancelToken: cancelToken);
 }
Example #44
0
        private static ISourceBlock<LoadingTx> ReplayFromTxIndex(ICoreStorage coreStorage, IChainState chainState, ChainedHeader replayBlock, bool replayForward, CancellationToken cancelToken = default(CancellationToken))
        {
            //TODO use replayForward to retrieve blocks in reverse order
            //TODO also check that the block hasn't been pruned (that information isn't stored yet)

            IEnumerator<BlockTx> blockTxes;
            if (!coreStorage.TryReadBlockTransactions(replayBlock.Hash, /*requireTransaction:*/true, out blockTxes))
            {
                throw new MissingDataException(replayBlock.Hash);
            }

            var blockTxesBuffer = new BufferBlock<BlockTx>();
            if (replayForward)
                blockTxesBuffer.SendAndCompleteAsync(blockTxes.UsingAsEnumerable(), cancelToken).Forget();
            else
                blockTxesBuffer.SendAndCompleteAsync(blockTxes.UsingAsEnumerable().Reverse(), cancelToken).Forget();

            // capture the original block txes order
            var orderedBlockTxes = OrderingBlock.CaptureOrder<BlockTx, LoadingTx, UInt256>(
                blockTxesBuffer, blockTx => blockTx.Transaction.Hash, cancelToken);

            // begin looking up txes
            var lookupLoadingTx = InitLookupLoadingTx(chainState, replayBlock, cancelToken);
            orderedBlockTxes.LinkTo(lookupLoadingTx, new DataflowLinkOptions { PropagateCompletion = true });

            // return the loading txes in original order
            return orderedBlockTxes.ApplyOrder(lookupLoadingTx, loadingTx => loadingTx.Transaction.Hash, cancelToken); ;
        }