public static ISourceBlock<BlockTx> LookAhead(ISourceBlock<BlockTx> blockTxes, IDeferredChainStateCursor deferredChainStateCursor, CancellationToken cancelToken = default(CancellationToken)) { // capture the original block txes order var orderedBlockTxes = OrderingBlock.CaptureOrder<BlockTx, BlockTx, int>( blockTxes, blockTx => blockTx.Index, cancelToken); // queue each utxo entry to be warmed up: each input's previous transaction, and each new transaction var queueUnspentTxLookup = InitQueueUnspentTxLookup(cancelToken); orderedBlockTxes.LinkTo(queueUnspentTxLookup, new DataflowLinkOptions { PropagateCompletion = true }); // warm up each uxto entry var warmupUtxo = InitWarmupUtxo(deferredChainStateCursor, cancelToken); queueUnspentTxLookup.LinkTo(warmupUtxo, new DataflowLinkOptions { PropagateCompletion = true }); // return the block txes with warmed utxo entries in original order return orderedBlockTxes.ApplyOrder(warmupUtxo, blockTx => blockTx.Index, cancelToken); }
private static TransformManyBlock<Tuple<UInt256, CompletionCount, BlockTx>, BlockTx> InitWarmupUtxo(IDeferredChainStateCursor deferredChainStateCursor, CancellationToken cancelToken) { return new TransformManyBlock<Tuple<UInt256, CompletionCount, BlockTx>, BlockTx>( tuple => { var txHash = tuple.Item1; var completionCount = tuple.Item2; var blockTx = tuple.Item3; deferredChainStateCursor.WarmUnspentTx(txHash); if (completionCount.TryComplete()) return new[] { blockTx }; else return new BlockTx[0]; }, new ExecutionDataflowBlockOptions { CancellationToken = cancelToken, MaxDegreeOfParallelism = Math.Min(Environment.ProcessorCount, deferredChainStateCursor.CursorCount) }); }
private static TransformManyBlock<Tuple<TxOutputKey, CompletionCount, DecodedBlockTx>, DecodedBlockTx> InitWarmupUtxo(IDeferredChainStateCursor deferredChainStateCursor, CancellationToken cancelToken) { return new TransformManyBlock<Tuple<TxOutputKey, CompletionCount, DecodedBlockTx>, DecodedBlockTx>( tuple => { var txOutputKey = tuple.Item1; var completionCount = tuple.Item2; var blockTx = tuple.Item3; if (txOutputKey.TxOutputIndex == uint.MaxValue) deferredChainStateCursor.WarmUnspentTx(txOutputKey.TxHash); else deferredChainStateCursor.WarmUnspentTxOutput(txOutputKey); if (completionCount.TryComplete()) return new[] { blockTx }; else return new DecodedBlockTx[0]; }, new ExecutionDataflowBlockOptions { CancellationToken = cancelToken, MaxDegreeOfParallelism = Math.Min(Environment.ProcessorCount, deferredChainStateCursor.CursorCount) }); }
private static TransformManyBlock <Tuple <TxOutputKey, CompletionCount, DecodedBlockTx>, DecodedBlockTx> InitWarmupUtxo(IDeferredChainStateCursor deferredChainStateCursor, CancellationToken cancelToken) { return(new TransformManyBlock <Tuple <TxOutputKey, CompletionCount, DecodedBlockTx>, DecodedBlockTx>( tuple => { var txOutputKey = tuple.Item1; var completionCount = tuple.Item2; var blockTx = tuple.Item3; if (txOutputKey.TxOutputIndex == uint.MaxValue) { deferredChainStateCursor.WarmUnspentTx(txOutputKey.TxHash); } else { deferredChainStateCursor.WarmUnspentTxOutput(txOutputKey); } if (completionCount.TryComplete()) { return new[] { blockTx } } ; else { return new DecodedBlockTx[0]; } }, new ExecutionDataflowBlockOptions { CancellationToken = cancelToken, MaxDegreeOfParallelism = Math.Min(Environment.ProcessorCount, deferredChainStateCursor.CursorCount) })); }
public static ISourceBlock <DecodedBlockTx> LookAhead(ISourceBlock <DecodedBlockTx> blockTxes, IDeferredChainStateCursor deferredChainStateCursor, CancellationToken cancelToken = default(CancellationToken)) { // capture the original block txes order var orderedBlockTxes = OrderingBlock.CaptureOrder <DecodedBlockTx, DecodedBlockTx, int>( blockTxes, blockTx => blockTx.Index, cancelToken); // queue each utxo entry to be warmed up: each input's previous transaction, and each new transaction var queueUnspentTxLookup = InitQueueUnspentTxLookup(cancelToken); orderedBlockTxes.LinkTo(queueUnspentTxLookup, new DataflowLinkOptions { PropagateCompletion = true }); // warm up each uxto entry var warmupUtxo = InitWarmupUtxo(deferredChainStateCursor, cancelToken); queueUnspentTxLookup.LinkTo(warmupUtxo, new DataflowLinkOptions { PropagateCompletion = true }); // return the block txes with warmed utxo entries in original order return(orderedBlockTxes.ApplyOrder(warmupUtxo, blockTx => blockTx.Index, cancelToken)); }