Example #1
0
        public void CommitTransaction()
        {
            if (!inTransaction)
            {
                throw new InvalidOperationException();
            }

            unconfirmedTxesStorage.CommitTransaction(
                chainTip,
                unconfirmedTxCount,
                unconfirmedTxes,
                unconfirmedTxesByPrevTxOutputKey);

            chainTip           = null;
            unconfirmedTxCount = null;
            unconfirmedTxes    = null;
            unconfirmedTxesByPrevTxOutputKey = null;

            inTransaction = false;

            if (!readOnly)
            {
                unconfirmedTxesStorage.WriteTxLock.Release();
            }
        }
Example #2
0
        public void RollbackTransaction()
        {
            if (!inTransaction)
            {
                throw new InvalidOperationException();
            }

            chainTip            = null;
            unspentTxCount      = null;
            unspentOutputCount  = null;
            totalTxCount        = null;
            totalInputCount     = null;
            totalOutputCount    = null;
            headers             = null;
            unspentTransactions = null;
            unspentTxOutputs    = null;
            blockSpentTxes      = null;
            blockUnmintedTxes   = null;

            inTransaction = false;

            if (!readOnly)
            {
                chainStateStorage.WriteTxLock.Release();
            }
        }
Example #3
0
 public void BeginTransaction(
     out UncommittedRecord <ChainedHeader> chainTip,
     out UncommittedRecord <int> unspentTxCount,
     out UncommittedRecord <int> unspentOutputCount,
     out UncommittedRecord <int> totalTxCount,
     out UncommittedRecord <int> totalInputCount,
     out UncommittedRecord <int> totalOutputCount,
     out UncommittedRecord <ImmutableSortedDictionary <UInt256, ChainedHeader> .Builder> headers,
     out UncommittedRecord <ImmutableSortedDictionary <UInt256, UnspentTx> .Builder> unspentTransactions,
     out UncommittedRecord <ImmutableSortedDictionary <TxOutputKey, TxOutput> .Builder> unspentTxOutputs,
     out UncommittedRecord <ImmutableDictionary <int, BlockSpentTxes> .Builder> blockSpentTxes,
     out UncommittedRecord <ImmutableDictionary <UInt256, IImmutableList <UnmintedTx> > .Builder> blockUnmintedTxes)
 {
     lock (this.lockObject)
     {
         chainTip            = this.chainTip.AsUncommitted();
         unspentTxCount      = this.unspentTxCount.AsUncommitted();
         unspentOutputCount  = this.unspentOutputCount.AsUncommitted();
         totalTxCount        = this.totalTxCount.AsUncommitted();
         totalInputCount     = this.totalInputCount.AsUncommitted();
         totalOutputCount    = this.totalOutputCount.AsUncommitted();
         headers             = this.headers.AsUncommitted(x => x.ToImmutable().ToBuilder());
         unspentTransactions = this.unspentTransactions.AsUncommitted(x => x.ToImmutable().ToBuilder());
         unspentTxOutputs    = this.unspentTxOutputs.AsUncommitted(x => x.ToImmutable().ToBuilder());
         blockSpentTxes      = this.blockSpentTxes.AsUncommitted(x => x.ToImmutable().ToBuilder());
         blockUnmintedTxes   = this.blockUnmintedTxes.AsUncommitted(x => x.ToImmutable().ToBuilder());
     }
 }
Example #4
0
 public void Committ <U>(UncommittedRecord <U> uncommittedRecord, Func <U, T> transformFunc)
 {
     if (uncommittedRecord.ValueModified)
     {
         Value = transformFunc(uncommittedRecord.Value);
         ValueVersion++;
     }
 }
Example #5
0
        public void Committ(UncommittedRecord <T> uncommittedRecord)
        {
            if (ConflictsWith(uncommittedRecord))
            {
                throw new InvalidOperationException();
            }

            if (uncommittedRecord.ValueModified)
            {
                Value = uncommittedRecord.Value;
                ValueVersion++;
            }
        }
 public void BeginTransaction(
     out UncommittedRecord <ChainedHeader> chainTip,
     out UncommittedRecord <int> unconfirmedTxCount,
     out UncommittedRecord <ImmutableDictionary <UInt256, UnconfirmedTx> .Builder> unconfirmedTxes,
     out UncommittedRecord <ImmutableDictionary <TxOutputKey, ImmutableDictionary <UInt256, UnconfirmedTx> .Builder> .Builder> unconfirmedTxesByPrevTxOutputKey)
 {
     lock (this.lockObject)
     {
         chainTip           = this.chainTip.AsUncommitted();
         unconfirmedTxCount = this.unconfirmedTxCount.AsUncommitted();
         unconfirmedTxes    = this.unconfirmedTxes.AsUncommitted(x => x.ToImmutable().ToBuilder());
         unconfirmedTxesByPrevTxOutputKey = this.unconfirmedTxesByPrevTxOutputKey.AsUncommitted(x => x.ToImmutable().ToBuilder());
     }
 }
Example #7
0
        public bool TryRemoveTransaction(UInt256 txHash)
        {
            CheckWriteTransaction();

            UnconfirmedTx unconfirmedTx;

            if (unconfirmedTxes.Value.TryGetValue(txHash, out unconfirmedTx) &&
                unconfirmedTxes.TryModify(x => x.Remove(txHash)))
            {
                // update index of txes spending each input's prev tx
                for (var inputIndex = 0; inputIndex < unconfirmedTx.Transaction.Inputs.Length; inputIndex++)
                {
                    var input = unconfirmedTx.Transaction.Inputs[inputIndex];

                    unconfirmedTxesByPrevTxOutputKey.Modify(_ => { });
                    ImmutableDictionary <UInt256, UnconfirmedTx> .Builder unconfirmedTxes;
                    if (unconfirmedTxesByPrevTxOutputKey.Value.TryGetValue(input.PrevTxOutputKey, out unconfirmedTxes))
                    {
                        // ensure a copy of the builder is modified or underlying storage will see uncomitted state
                        unconfirmedTxes = unconfirmedTxes.ToImmutable().ToBuilder();
                    }
                    else
                    {
                        unconfirmedTxes = ImmutableDictionary.CreateBuilder <UInt256, UnconfirmedTx>();
                    }

                    unconfirmedTxes.Remove(unconfirmedTx.Hash);
                    if (unconfirmedTxes.Count > 0)
                    {
                        unconfirmedTxesByPrevTxOutputKey.Value[input.PrevTxOutputKey] = unconfirmedTxes;
                    }
                    else
                    {
                        unconfirmedTxesByPrevTxOutputKey.Value.Remove(input.PrevTxOutputKey);
                    }
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
Example #8
0
        public void CommitTransaction(
            UncommittedRecord <ChainedHeader> chainTip,
            UncommittedRecord <int> unspentTxCount,
            UncommittedRecord <int> unspentOutputCount,
            UncommittedRecord <int> totalTxCount,
            UncommittedRecord <int> totalInputCount,
            UncommittedRecord <int> totalOutputCount,
            UncommittedRecord <ImmutableSortedDictionary <UInt256, ChainedHeader> .Builder> headers,
            UncommittedRecord <ImmutableSortedDictionary <UInt256, UnspentTx> .Builder> unspentTransactions,
            UncommittedRecord <ImmutableSortedDictionary <TxOutputKey, TxOutput> .Builder> unspentTxOutputs,
            UncommittedRecord <ImmutableDictionary <int, BlockSpentTxes> .Builder> blockSpentTxes,
            UncommittedRecord <ImmutableDictionary <UInt256, IImmutableList <UnmintedTx> > .Builder> blockUnmintedTxes)
        {
            lock (this.lockObject)
            {
                if (this.chainTip.ConflictsWith(chainTip) ||
                    this.unspentTxCount.ConflictsWith(unspentTxCount) ||
                    this.unspentOutputCount.ConflictsWith(unspentOutputCount) ||
                    this.totalTxCount.ConflictsWith(totalTxCount) ||
                    this.totalInputCount.ConflictsWith(totalInputCount) ||
                    this.totalOutputCount.ConflictsWith(totalOutputCount) ||
                    this.headers.ConflictsWith(headers) ||
                    this.unspentTransactions.ConflictsWith(unspentTransactions) ||
                    this.unspentTxOutputs.ConflictsWith(unspentTxOutputs) ||
                    this.blockSpentTxes.ConflictsWith(blockSpentTxes) ||
                    this.blockUnmintedTxes.ConflictsWith(blockUnmintedTxes))
                {
                    throw new InvalidOperationException();
                }

                this.chainTip.Committ(chainTip);
                this.unspentTxCount.Committ(unspentTxCount);
                this.unspentOutputCount.Committ(unspentOutputCount);
                this.totalTxCount.Committ(totalTxCount);
                this.totalInputCount.Committ(totalInputCount);
                this.totalOutputCount.Committ(totalOutputCount);
                this.headers.Committ(headers, x => x.ToImmutable().ToBuilder());
                this.unspentTransactions.Committ(unspentTransactions, x => x.ToImmutable().ToBuilder());
                this.unspentTxOutputs.Committ(unspentTxOutputs, x => x.ToImmutable().ToBuilder());
                this.blockSpentTxes.Committ(blockSpentTxes, x => x.ToImmutable().ToBuilder());
                this.blockUnmintedTxes.Committ(blockUnmintedTxes, x => x.ToImmutable().ToBuilder());
            }
        }
        public void CommitTransaction(
            UncommittedRecord <ChainedHeader> chainTip,
            UncommittedRecord <int> unconfirmedTxCount,
            UncommittedRecord <ImmutableDictionary <UInt256, UnconfirmedTx> .Builder> unconfirmedTxes,
            UncommittedRecord <ImmutableDictionary <TxOutputKey, ImmutableDictionary <UInt256, UnconfirmedTx> .Builder> .Builder> unconfirmedTxesByPrevTxOutputKey)
        {
            lock (this.lockObject)
            {
                if (this.chainTip.ConflictsWith(chainTip) ||
                    this.unconfirmedTxCount.ConflictsWith(unconfirmedTxCount) ||
                    this.unconfirmedTxes.ConflictsWith(unconfirmedTxes) ||
                    this.unconfirmedTxesByPrevTxOutputKey.ConflictsWith(unconfirmedTxesByPrevTxOutputKey))
                {
                    throw new InvalidOperationException();
                }

                this.chainTip.Committ(chainTip);
                this.unconfirmedTxCount.Committ(unconfirmedTxCount);
                this.unconfirmedTxes.Committ(unconfirmedTxes, x => x.ToImmutable().ToBuilder());
                this.unconfirmedTxesByPrevTxOutputKey.Committ(unconfirmedTxesByPrevTxOutputKey, x => x.ToImmutable().ToBuilder());
            }
        }
Example #10
0
        public bool TryAddTransaction(UnconfirmedTx unconfirmedTx)
        {
            CheckWriteTransaction();

            try
            {
                unconfirmedTxes.Modify(x => x.Add(unconfirmedTx.Hash, unconfirmedTx));

                // update index of txes spending each input's prev tx
                for (var inputIndex = 0; inputIndex < unconfirmedTx.Transaction.Inputs.Length; inputIndex++)
                {
                    var input = unconfirmedTx.Transaction.Inputs[inputIndex];

                    unconfirmedTxesByPrevTxOutputKey.Modify(_ => { });
                    ImmutableDictionary <UInt256, UnconfirmedTx> .Builder unconfirmedTxes;
                    if (unconfirmedTxesByPrevTxOutputKey.Value.TryGetValue(input.PrevTxOutputKey, out unconfirmedTxes))
                    {
                        // ensure a copy of the builder is modified or underlying storage will see uncomitted state
                        unconfirmedTxes = unconfirmedTxes.ToImmutable().ToBuilder();
                    }
                    else
                    {
                        unconfirmedTxes = ImmutableDictionary.CreateBuilder <UInt256, UnconfirmedTx>();
                    }

                    unconfirmedTxes.Add(unconfirmedTx.Hash, unconfirmedTx);
                    unconfirmedTxesByPrevTxOutputKey.Value[input.PrevTxOutputKey] = unconfirmedTxes;
                }

                return(true);
            }
            catch (ArgumentException)
            {
                return(false);
            }
        }
Example #11
0
 public bool ConflictsWith <U>(UncommittedRecord <U> uncommittedRecord)
 {
     return(uncommittedRecord.ValueModified && uncommittedRecord.ValueVersion != ValueVersion);
 }