Esempio n. 1
0
        public static UTXOStateResult CreateStates(
            Func <Script[], bool[]> matchScript,
            HashSet <Bookmark> knownUnconfBookmarks, IEnumerable <Transaction> unconfirmed,
            HashSet <Bookmark> knownConfBookmarks, IEnumerable <Transaction> confirmed)
        {
            var utxoState = new UTXOState();

            utxoState.MatchScript = matchScript;

            var knownConf = knownConfBookmarks.Contains(Bookmark.Start) ? new UTXOState() : null;

            foreach (var tx in confirmed)
            {
                if (utxoState.Apply(tx) == ApplyTransactionResult.Conflict)
                {
                    throw new InvalidOperationException("Conflict in UTXOStateResult.CreateStates should never happen");
                }
                if (knownConfBookmarks.Contains(utxoState.CurrentBookmark))
                {
                    knownConf = utxoState.Snapshot();
                }
            }


            var actualConf = utxoState.Snapshot();

            utxoState.ResetEvents();

            var knownUnconf = knownUnconfBookmarks.Contains(Bookmark.Start) ? utxoState.Snapshot() : null;

            foreach (var tx in unconfirmed)
            {
                var txid = tx.GetHash();
                if (utxoState.Apply(tx) == ApplyTransactionResult.Conflict)
                {
                    throw new InvalidOperationException("Conflict in UTXOStateResult.CreateStates should never happen");
                }

                if (knownUnconfBookmarks.Contains(utxoState.CurrentBookmark))
                {
                    knownUnconf = utxoState.Snapshot();
                }
            }

            var actualUnconf = utxoState;

            return(new UTXOStateResult()
            {
                Unconfirmed = new UTXOStates()
                {
                    Known = knownUnconf,
                    Actual = actualUnconf
                },
                Confirmed = new UTXOStates()
                {
                    Known = knownConf,
                    Actual = actualConf,
                }
            });
        }
Esempio n. 2
0
        public AnnotatedTransactionCollection(IEnumerable <AnnotatedTransaction> transactions) : base(transactions)
        {
            foreach (var tx in transactions)
            {
                var h = tx.Record.Transaction.GetHash();
                _TxById.Add(h, tx);
                foreach (var keyPathInfo in tx.Record.TransactionMatch.Inputs.Concat(tx.Record.TransactionMatch.Outputs))
                {
                    if (keyPathInfo.KeyPath != null)
                    {
                        _KeyPaths.TryAdd(keyPathInfo.ScriptPubKey, keyPathInfo.KeyPath);
                    }
                }
            }


            UTXOState state = new UTXOState();

            foreach (var confirmed in transactions
                     .Where(tx => tx.Type == AnnotatedTransactionType.Confirmed)
                     .TopologicalSort())
            {
                if (state.Apply(confirmed.Record.Transaction) == ApplyTransactionResult.Conflict ||
                    !ConfirmedTransactions.TryAdd(confirmed.Record.Transaction.GetHash(), confirmed))
                {
                    Logs.Explorer.LogError("A conflict among confirmed transaction happened, this should be impossible");
                    throw new InvalidOperationException("The impossible happened");
                }
            }

            foreach (var unconfirmed in transactions
                     .Where(tx => tx.Type == AnnotatedTransactionType.Unconfirmed || tx.Type == AnnotatedTransactionType.Orphan)
                     .OrderByDescending(t => t.Record.Inserted)                                                            // OrderByDescending so that the last received is least likely to be conflicted
                     .TopologicalSort())
            {
                var hash = unconfirmed.Record.Transaction.GetHash();
                if (ConfirmedTransactions.ContainsKey(hash))
                {
                    DuplicatedTransactions.Add(unconfirmed);
                }
                else
                {
                    if (state.Apply(unconfirmed.Record.Transaction) == ApplyTransactionResult.Conflict)
                    {
                        ReplacedTransactions.TryAdd(hash, unconfirmed);
                    }
                    else
                    {
                        if (!UnconfirmedTransactions.TryAdd(hash, unconfirmed))
                        {
                            throw new InvalidOperationException("The impossible happened (!UnconfirmedTransactions.TryAdd(hash, unconfirmed))");
                        }
                    }
                }
            }
        }
        public AnnotatedTransactionCollection(IEnumerable <AnnotatedTransaction> transactions, Models.TrackedSource trackedSource) : base(transactions)
        {
            foreach (var tx in transactions)
            {
                foreach (var keyPathInfo in tx.Record.KnownKeyPathMapping)
                {
                    _KeyPaths.TryAdd(keyPathInfo.Key, keyPathInfo.Value);
                }
            }

            UTXOState state = new UTXOState();

            foreach (var confirmed in transactions
                     .Where(tx => tx.Type == AnnotatedTransactionType.Confirmed).ToList()
                     .TopologicalSort())
            {
                if (state.Apply(confirmed.Record) == ApplyTransactionResult.Conflict)
                {
                    Logs.Explorer.LogError("A conflict among confirmed transaction happened, this should be impossible");
                    throw new InvalidOperationException("The impossible happened");
                }
                ConfirmedTransactions.Add(confirmed);
                _TxById.Add(confirmed.Record.TransactionHash, confirmed);
            }

            foreach (var unconfirmed in transactions
                     .Where(tx => tx.Type == AnnotatedTransactionType.Unconfirmed || tx.Type == AnnotatedTransactionType.Orphan)
                     .OrderByDescending(t => t.Record.Inserted)                    // OrderByDescending so that the last received is least likely to be conflicted
                     .ToList()
                     .TopologicalSort())
            {
                if (_TxById.ContainsKey(unconfirmed.Record.TransactionHash))
                {
                    _TxById.Add(unconfirmed.Record.TransactionHash, unconfirmed);
                    DuplicatedTransactions.Add(unconfirmed);
                }
                else
                {
                    _TxById.Add(unconfirmed.Record.TransactionHash, unconfirmed);
                    if (state.Apply(unconfirmed.Record) == ApplyTransactionResult.Conflict)
                    {
                        ReplacedTransactions.Add(unconfirmed);
                    }
                    else
                    {
                        UnconfirmedTransactions.Add(unconfirmed);
                    }
                }
            }

            TrackedSource = trackedSource;
        }
Esempio n. 4
0
        public static UTXOState operator-(UTXOState a, UTXOState b)
        {
            UTXOState result = new UTXOState();

            foreach (var utxo in a.UTXOByOutpoint)
            {
                if (!b.UTXOByOutpoint.ContainsKey(utxo.Key))
                {
                    result.UTXOByOutpoint.TryAdd(utxo.Key, utxo.Value);
                }
            }
            foreach (var utxo in b.UTXOByOutpoint)
            {
                if (!a.UTXOByOutpoint.ContainsKey(utxo.Key))
                {
                    result.SpentUTXOs.Add(utxo.Key);
                }
            }
            return(result);
        }
Esempio n. 5
0
        public static UTXOStateResult CreateStates(IEnumerable <TrackedTransaction> unconfirmed, IEnumerable <TrackedTransaction> confirmed)
        {
            var utxoState = new UTXOState();

            foreach (var tx in confirmed)
            {
                if (utxoState.Apply(tx) == ApplyTransactionResult.Conflict)
                {
                    throw new InvalidOperationException("Conflict in UTXOStateResult.CreateStates should never happen");
                }
            }


            var actualConf = utxoState.Snapshot();

            foreach (var tx in unconfirmed)
            {
                if (utxoState.Apply(tx) == ApplyTransactionResult.Conflict)
                {
                    throw new InvalidOperationException("Conflict in UTXOStateResult.CreateStates should never happen");
                }
            }

            var actualUnconf = utxoState;

            return(new UTXOStateResult()
            {
                Unconfirmed = new UTXOStates()
                {
                    Actual = actualUnconf
                },
                Confirmed = new UTXOStates()
                {
                    Actual = actualConf,
                }
            });
        }
Esempio n. 6
0
        public static UTXOStateResult CreateStates(
            Func <Script[], bool[]> matchScript,
            uint256 knownUnconfHash, IEnumerable <Transaction> unconfirmed,
            uint256 knownConfHash, IEnumerable <Transaction> confirmed)
        {
            var utxoState = new UTXOState();

            utxoState.MatchScript = matchScript;

            var knownConf = knownConfHash == uint256.Zero ? new UTXOState() : null;

            foreach (var tx in confirmed)
            {
                var applyResult = utxoState.Apply(tx);
                if (applyResult == ApplyTransactionResult.Conflict)
                {
                    Logs.Explorer.LogError("A conflict among confirmed transaction happened, this should be impossible");
                    throw new InvalidOperationException("The impossible happened");
                }

                if (applyResult == ApplyTransactionResult.Passed)
                {
                    if (utxoState.CurrentHash == knownConfHash)
                    {
                        knownConf = utxoState.Snapshot();
                    }
                }
            }


            var actualConf = utxoState.Snapshot();

            utxoState.ResetEvents();

            var knownUnconf = knownUnconfHash == uint256.Zero ? utxoState.Snapshot() : null;

            foreach (var tx in unconfirmed)
            {
                var txid = tx.GetHash();
                if (utxoState.Apply(tx) == ApplyTransactionResult.Passed)
                {
                    if (utxoState.CurrentHash == knownUnconfHash)
                    {
                        knownUnconf = utxoState.Snapshot();
                    }
                }
            }

            var actualUnconf = utxoState;

            return(new UTXOStateResult()
            {
                Unconfirmed = new UTXOStates()
                {
                    Known = knownUnconf,
                    Actual = actualUnconf
                },
                Confirmed = new UTXOStates()
                {
                    Known = knownConf,
                    Actual = actualConf,
                }
            });
        }
 public UTXOState(UTXOState other)
 {
     UTXOByOutpoint = new UTXOByOutpoint(other.UTXOByOutpoint);
     SpentUTXOs     = new HashSet <OutPoint>(other.SpentUTXOs);
     _KnownInputs   = new HashSet <OutPoint>(other._KnownInputs);
 }