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