private bool CursorContains <TKey, TValue>(TKey key, WorkQueueDictionary <TKey, TValue> dict, Func <TKey, byte[]> encodeKey) { CheckTransaction(); if (dict != null) { return(dict.ContainsKey(key)); } else { var keySlice = encodeKey(key); Slice valueSlice; return(db.TryGet(txReadOptions, keySlice, out valueSlice)); } }
public async Task CommitTransactionAsync() { if (!inTransaction) { throw new InvalidOperationException(); } if (!readOnly) { unspentTxes.WorkQueue.Complete(); unspentTxOutputs.WorkQueue.Complete(); globals.WorkQueue.Complete(); headers.WorkQueue.Complete(); spentTxes.WorkQueue.Complete(); unmintedTxes.WorkQueue.Complete(); await unspentTxesApplier.Completion; await unspentTxOutputsApplier.Completion; await globalsApplier.Completion; await headersApplier.Completion; await spentTxesApplier.Completion; await unmintedTxesApplier.Completion; db.Write(new WriteOptions(), txWriteBatch); txWriteBatch.Dispose(); } txSnapshot.Dispose(); txSnapshot = null; txReadOptions = null; txWriteBatch = null; unspentTxes = null; unspentTxOutputs = null; globals = null; headers = null; spentTxes = null; unmintedTxes = null; unspentTxesApplier = null; unspentTxOutputsApplier = null; globalsApplier = null; headersApplier = null; spentTxesApplier = null; unmintedTxesApplier = null; inTransaction = false; }
public void BeginTransaction(bool readOnly) { if (inTransaction) { throw new InvalidOperationException(); } txSnapshot = db.GetSnapshot(); txReadOptions = new ReadOptions { Snapshot = txSnapshot }; if (!readOnly) { txWriteBatch = new WriteBatch(); } else { txWriteBatch = null; } if (!readOnly || isDeferred) { InitWorkQueueDictionaries(); } else { unspentTxes = null; unspentTxOutputs = null; globals = null; headers = null; spentTxes = null; unmintedTxes = null; unspentTxOutputsApplier = null; unspentTxesApplier = null; globalsApplier = null; headersApplier = null; spentTxesApplier = null; unmintedTxesApplier = null; } inTransaction = true; this.readOnly = readOnly; }
public void RollbackTransaction() { if (!inTransaction) { throw new InvalidOperationException(); } if (!readOnly || isDeferred) { unspentTxes.WorkQueue.Complete(); unspentTxOutputs.WorkQueue.Complete(); globals.WorkQueue.Complete(); headers.WorkQueue.Complete(); spentTxes.WorkQueue.Complete(); unmintedTxes.WorkQueue.Complete(); unspentTxesApplier.Complete(); unspentTxOutputsApplier.Complete(); globalsApplier.Complete(); headersApplier.Complete(); spentTxesApplier.Complete(); unmintedTxesApplier.Complete(); } txSnapshot.Dispose(); txWriteBatch?.Dispose(); txSnapshot = null; txReadOptions = null; txWriteBatch = null; unspentTxes = null; unspentTxOutputs = null; globals = null; headers = null; spentTxes = null; unmintedTxes = null; unspentTxesApplier = null; unspentTxOutputsApplier = null; globalsApplier = null; headersApplier = null; spentTxesApplier = null; unmintedTxesApplier = null; inTransaction = false; }
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); }); }
private void InitWorkQueueDictionaries() { unspentTxes = CreateWorkQueueDictionary <UInt256, UnspentTx>(MakeUnspentTxKey, x => DataDecoder.DecodeUnspentTx(x)); unspentTxesApplier = CreateApplier <UInt256, UnspentTx>(MakeUnspentTxKey, x => DataEncoder.EncodeUnspentTx(x)); unspentTxes.WorkQueue.LinkTo(unspentTxesApplier, new DataflowLinkOptions { PropagateCompletion = true }); unspentTxOutputs = CreateWorkQueueDictionary <TxOutputKey, TxOutput>(MakeUnspentTxOutputKey, x => DataDecoder.DecodeTxOutput(x)); unspentTxOutputsApplier = CreateApplier <TxOutputKey, TxOutput>(MakeUnspentTxOutputKey, x => DataEncoder.EncodeTxOutput(x)); unspentTxOutputs.WorkQueue.LinkTo(unspentTxOutputsApplier, new DataflowLinkOptions { PropagateCompletion = true }); globals = CreateWorkQueueDictionary <GlobalValue, Slice>(MakeGlobalKey, x => x); globalsApplier = CreateApplier <GlobalValue, Slice>(MakeGlobalKey, x => x.ToArray()); globals.WorkQueue.LinkTo(globalsApplier, new DataflowLinkOptions { PropagateCompletion = true }); headers = CreateWorkQueueDictionary <UInt256, ChainedHeader>(MakeHeaderKey, x => DataDecoder.DecodeChainedHeader(x)); headersApplier = CreateApplier <UInt256, ChainedHeader>(MakeHeaderKey, x => DataEncoder.EncodeChainedHeader(x)); headers.WorkQueue.LinkTo(headersApplier, new DataflowLinkOptions { PropagateCompletion = true }); spentTxes = CreateWorkQueueDictionary <int, BlockSpentTxes>(MakeSpentTxesKey, x => DataDecoder.DecodeBlockSpentTxes(x)); spentTxesApplier = CreateApplier <int, BlockSpentTxes>(MakeSpentTxesKey, x => DataEncoder.EncodeBlockSpentTxes(x)); spentTxes.WorkQueue.LinkTo(spentTxesApplier, new DataflowLinkOptions { PropagateCompletion = true }); unmintedTxes = CreateWorkQueueDictionary <UInt256, IImmutableList <UnmintedTx> >(MakeUnmintedTxesKey, x => DataDecoder.DecodeUnmintedTxList(x)); unmintedTxesApplier = CreateApplier <UInt256, IImmutableList <UnmintedTx> >(MakeUnmintedTxesKey, x => DataEncoder.EncodeUnmintedTxList(x)); unmintedTxes.WorkQueue.LinkTo(unmintedTxesApplier, new DataflowLinkOptions { PropagateCompletion = true }); }
private bool CursorTryGet <TKey, TValue>(TKey key, out TValue value, WorkQueueDictionary <TKey, TValue> dict, Func <TKey, byte[]> encodeKey, Func <byte[], TValue> decodeValue) { CheckTransaction(); if (dict != null) { return(dict.TryGetValue(key, out value)); } else { var keySlice = encodeKey(key); Slice valueSlice; if (db.TryGet(txReadOptions, keySlice, out valueSlice)) { value = decodeValue(valueSlice.ToArray()); return(true); } else { value = default(TValue); return(false); } } }
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 }); }