public static async Task ValidateBlockAsync(ICoreStorage coreStorage, ICoreRules rules, Chain newChain, ISourceBlock<ValidatableTx> validatableTxes, CancellationToken cancelToken = default(CancellationToken)) { // tally transactions object finalTally = null; var txTallier = new TransformBlock<ValidatableTx, ValidatableTx>( validatableTx => { var runningTally = finalTally; rules.TallyTransaction(newChain, validatableTx, ref runningTally); finalTally = runningTally; return validatableTx; }); validatableTxes.LinkTo(txTallier, new DataflowLinkOptions { PropagateCompletion = true }); // validate transactions var txValidator = InitTxValidator(rules, newChain, cancelToken); // begin feeding the tx validator txTallier.LinkTo(txValidator, new DataflowLinkOptions { PropagateCompletion = true }); // validate scripts var scriptValidator = InitScriptValidator(rules, newChain, cancelToken); // begin feeding the script validator txValidator.LinkTo(scriptValidator, new DataflowLinkOptions { PropagateCompletion = true }); //TODO await PipelineCompletion.Create( new Task[] { }, new IDataflowBlock[] { validatableTxes, txTallier, txValidator, scriptValidator }); // validate overall block rules.PostValidateBlock(newChain, finalTally); }
public ChainStateBuilder(ICoreRules rules, ICoreStorage coreStorage, IStorageManager storageManager) { this.rules = rules; this.coreStorage = coreStorage; this.storageManager = storageManager; this.chain = new Lazy <Chain>(() => LoadChain()); this.stats = new ChainStateBuilderStats(); this.utxoBuilder = new UtxoBuilder(); }
public CoreDaemon(ICoreRules rules, IStorageManager storageManager) { this.rules = rules; this.storageManager = storageManager; coreStorage = new CoreStorage(storageManager); // create chain state builder chainStateBuilder = new ChainStateBuilder(this.rules, coreStorage, this.storageManager); // create unconfirmed txes builder unconfirmedTxesBuilder = new UnconfirmedTxesBuilder(this, coreStorage, this.storageManager); // create workers targetChainWorker = new TargetChainWorker( new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMilliseconds(0), maxIdleTime: TimeSpan.FromSeconds(30)), ChainParams, coreStorage); chainStateWorker = new ChainStateWorker( new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMilliseconds(0), maxIdleTime: TimeSpan.FromSeconds(5)), targetChainWorker, chainStateBuilder, this.rules, coreStorage); unconfirmedTxesWorker = new UnconfirmedTxesWorker( new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMilliseconds(0), maxIdleTime: TimeSpan.FromSeconds(5)), chainStateWorker, unconfirmedTxesBuilder, coreStorage); pruningWorker = new PruningWorker( new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromSeconds(0), maxIdleTime: TimeSpan.FromMinutes(5)), this, this.storageManager, chainStateWorker); defragWorker = new DefragWorker( new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMinutes(5), maxIdleTime: TimeSpan.FromMinutes(5)), this.storageManager); gcWorker = new WorkerMethod("GC Worker", GcWorker, initialNotify: true, minIdleTime: TimeSpan.FromMinutes(5), maxIdleTime: TimeSpan.FromMinutes(5)); utxoScanWorker = new WorkerMethod("UTXO Scan Worker", UtxoScanWorker, initialNotify: true, minIdleTime: TimeSpan.FromSeconds(60), maxIdleTime: TimeSpan.FromSeconds(60)); statsWorker = new StatsWorker( new WorkerConfig(initialNotify: true, minIdleTime: TimeSpan.FromMinutes(0), maxIdleTime: TimeSpan.MaxValue), this); // wire events chainStateWorker.BlockMissed += HandleBlockMissed; targetChainWorker.OnTargetChainChanged += HandleTargetChainChanged; chainStateWorker.OnChainStateChanged += HandleChainStateChanged; pruningWorker.OnWorkFinished += defragWorker.NotifyWork; unconfirmedTxesBuilder.UnconfirmedTxAdded += RaiseUnconfirmedTxAdded; unconfirmedTxesBuilder.TxesConfirmed += RaiseTxesConfirmed; unconfirmedTxesBuilder.TxesUnconfirmed += RaiseTxesUnconfirmed; }
private static ActionBlock<Tuple<ValidatableTx, int>> InitScriptValidator(ICoreRules rules, Chain newChain, CancellationToken cancelToken) { return new ActionBlock<Tuple<ValidatableTx, int>>( tuple => { var validatableTx = tuple.Item1; var inputIndex = tuple.Item2; var tx = validatableTx.Transaction; var txInput = tx.Inputs[inputIndex]; var prevTxOutputs = validatableTx.PrevTxOutputs[inputIndex]; rules.ValidationTransactionScript(newChain, validatableTx.BlockTx, txInput, inputIndex, prevTxOutputs); }, new ExecutionDataflowBlockOptions { CancellationToken = cancelToken, MaxDegreeOfParallelism = Environment.ProcessorCount }); }
private static ActionBlock <Tuple <ValidatableTx, int> > InitScriptValidator(ICoreRules rules, Chain newChain, CancellationToken cancelToken) { return(new ActionBlock <Tuple <ValidatableTx, int> >( tuple => { var validatableTx = tuple.Item1; var inputIndex = tuple.Item2; var tx = validatableTx.Transaction; var txInput = tx.Inputs[inputIndex]; var prevTxOutputs = validatableTx.PrevTxOutputs[inputIndex]; rules.ValidationTransactionScript(newChain, validatableTx.BlockTx, txInput, inputIndex, prevTxOutputs); }, new ExecutionDataflowBlockOptions { CancellationToken = cancelToken, MaxDegreeOfParallelism = Environment.ProcessorCount })); }
public static async Task ValidateBlockAsync(ICoreStorage coreStorage, ICoreRules rules, Chain newChain, ISourceBlock <ValidatableTx> validatableTxes, CancellationToken cancelToken = default(CancellationToken)) { // tally transactions object finalTally = null; var txTallier = new TransformBlock <ValidatableTx, ValidatableTx>( validatableTx => { var runningTally = finalTally; rules.TallyTransaction(newChain, validatableTx, ref runningTally); finalTally = runningTally; return(validatableTx); }); validatableTxes.LinkTo(txTallier, new DataflowLinkOptions { PropagateCompletion = true }); // validate transactions var txValidator = InitTxValidator(rules, newChain, cancelToken); // begin feeding the tx validator txTallier.LinkTo(txValidator, new DataflowLinkOptions { PropagateCompletion = true }); // validate scripts var scriptValidator = InitScriptValidator(rules, newChain, cancelToken); // begin feeding the script validator txValidator.LinkTo(scriptValidator, new DataflowLinkOptions { PropagateCompletion = true }); //TODO await PipelineCompletion.Create( new Task[] { }, new IDataflowBlock[] { validatableTxes, txTallier, txValidator, scriptValidator }); // validate overall block rules.PostValidateBlock(newChain, finalTally); }
public ChainStateWorker(WorkerConfig workerConfig, TargetChainWorker targetChainWorker, ChainStateBuilder chainStateBuilder, ICoreRules rules, CoreStorage coreStorage) : base("ChainStateWorker", workerConfig.initialNotify, workerConfig.minIdleTime, workerConfig.maxIdleTime) { this.rules = rules; this.coreStorage = coreStorage; this.blockProcessingDurationMeasure = new DurationMeasure(sampleCutoff: TimeSpan.FromMinutes(5)); this.blockMissCountMeasure = new CountMeasure(TimeSpan.FromSeconds(30)); this.targetChainWorker = targetChainWorker; this.chainStateBuilder = chainStateBuilder; this.currentChain = new Lazy <Chain>(() => this.chainStateBuilder.Chain); this.coreStorage.BlockInvalidated += HandleChanged; this.coreStorage.BlockTxesAdded += HandleChanged; this.coreStorage.BlockTxesRemoved += HandleChanged; this.coreStorage.ChainedHeaderAdded += HandleChanged; this.coreStorage.ChainedHeaderRemoved += HandleChanged; this.targetChainWorker.OnTargetChainChanged += HandleChanged; }
public ChainStateWorker(WorkerConfig workerConfig, TargetChainWorker targetChainWorker, ChainStateBuilder chainStateBuilder, ICoreRules rules, CoreStorage coreStorage) : base("ChainStateWorker", workerConfig.initialNotify, workerConfig.minIdleTime, workerConfig.maxIdleTime) { this.rules = rules; this.coreStorage = coreStorage; this.blockProcessingDurationMeasure = new DurationMeasure(sampleCutoff: TimeSpan.FromMinutes(5)); this.blockMissCountMeasure = new CountMeasure(TimeSpan.FromSeconds(30)); this.targetChainWorker = targetChainWorker; this.chainStateBuilder = chainStateBuilder; this.currentChain = new Lazy<Chain>(() => this.chainStateBuilder.Chain); this.coreStorage.BlockInvalidated += HandleChanged; this.coreStorage.BlockTxesAdded += HandleChanged; this.coreStorage.BlockTxesRemoved += HandleChanged; this.coreStorage.ChainedHeaderAdded += HandleChanged; this.coreStorage.ChainedHeaderRemoved += HandleChanged; this.targetChainWorker.OnTargetChainChanged += HandleChanged; }
private static TransformManyBlock<ValidatableTx, Tuple<ValidatableTx, int>> InitTxValidator(ICoreRules rules, Chain newChain, CancellationToken cancelToken) { return new TransformManyBlock<ValidatableTx, Tuple<ValidatableTx, int>>( validatableTx => { rules.ValidateTransaction(newChain, validatableTx); if (!rules.IgnoreScripts && !validatableTx.IsCoinbase) { var tx = validatableTx.Transaction; var scripts = new Tuple<ValidatableTx, int>[tx.Inputs.Length]; for (var i = 0; i < tx.Inputs.Length; i++) scripts[i] = Tuple.Create(validatableTx, i); return scripts; } else return new Tuple<ValidatableTx, int>[0]; }, new ExecutionDataflowBlockOptions { CancellationToken = cancelToken, MaxDegreeOfParallelism = Environment.ProcessorCount }); }
private static TransformManyBlock <ValidatableTx, Tuple <ValidatableTx, int> > InitTxValidator(ICoreRules rules, Chain newChain, CancellationToken cancelToken) { return(new TransformManyBlock <ValidatableTx, Tuple <ValidatableTx, int> >( validatableTx => { rules.ValidateTransaction(newChain, validatableTx); if (!rules.IgnoreScripts && !validatableTx.IsCoinbase) { var tx = validatableTx.Transaction; var scripts = new Tuple <ValidatableTx, int> [tx.Inputs.Length]; for (var i = 0; i < tx.Inputs.Length; i++) { scripts[i] = Tuple.Create(validatableTx, i); } return scripts; } else { return new Tuple <ValidatableTx, int> [0]; } }, new ExecutionDataflowBlockOptions { CancellationToken = cancelToken, MaxDegreeOfParallelism = Environment.ProcessorCount })); }