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); }); }
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 }); }