private void Received(TrackedScript match, IndexedTxOut txout, ChainedBlock block, MerkleBlock proof) { var operation = new Operation(txout.Transaction, block, proof); SetUnconfirmedSeenIfPossible(txout.Transaction, block, operation); var coin = new Coin(txout); operation.ReceivedCoins.Add(Tuple.Create(coin, match.GetId())); _Operations.AddOrUpdate(operation.GetId(), operation, (k, old) => old.Merge(operation)); var trackedOutpoint = new TrackedOutpoint() { Coin = coin, TrackedScriptId = match.GetId(), Filter = match.Filter }; _TrackedOutpoints.TryAdd(trackedOutpoint.GetId(), trackedOutpoint); }
public bool NotifyTransaction(Transaction transaction, ChainedBlock chainedBlock, MerkleBlock proof) { if (chainedBlock != null) { if (proof == null) { throw new ArgumentNullException(nameof(proof)); } if (proof.Header.GetHash() != chainedBlock.Header.GetHash()) { throw new InvalidOperationException("The chained block and the merkle block are different blocks"); } if (!proof.PartialMerkleTree.Check(chainedBlock.Header.HashMerkleRoot)) { throw new InvalidOperationException("The MerkleBlock does not have the expected merkle root"); } if (!proof.PartialMerkleTree.GetMatchedTransactions().Contains(transaction.GetHash())) { throw new InvalidOperationException("The MerkleBlock does not contains the input transaction"); } } var interesting = false; List <Operation> operations = null; lock (cs) { foreach (var txin in transaction.Inputs.AsIndexedInputs()) { var key = TrackedOutpoint.GetId(txin.PrevOut); TrackedOutpoint match; if (_TrackedOutpoints.TryGetValue(key, out match)) { TrackedScript parentMetadata; if (_TrackedScripts.TryGetValue(match.TrackedScriptId, out parentMetadata)) { interesting = true; var op = Spent(parentMetadata, txin, match.Coin, chainedBlock, proof); if (op != null) { operations = operations ?? new List <Operation>(); operations.Add(op); } } } } foreach (var txout in transaction.Outputs.AsIndexedOutputs()) { var key = TrackedScript.GetId(txout.TxOut.ScriptPubKey); TrackedScript match; if (_TrackedScripts.TryGetValue(key, out match)) { interesting = true; var op = Received(match, txout, chainedBlock, proof); if (op != null) { operations = operations ?? new List <Operation>(); operations.Add(op); } } } } if (operations != null) { FireCallbacks(operations); } return(interesting); }
internal static TrackedOutpoint FromJson(JObject obj) { TrackedOutpoint tracked = new TrackedOutpoint(); tracked.TrackedScriptId = (string)obj["TrackedScriptId"]; tracked.Filter = (string)obj["Filter"]; obj = (JObject)obj["Coin"]; tracked.Coin = Operation.FromJsonCoin(obj); return tracked; }
private Operation Received(TrackedScript match, IndexedTxOut txout, ChainedBlock block, MerkleBlock proof) { var operation = new Operation(txout.Transaction, block, proof, _TrackedScripts); SetUnconfirmedSeenIfPossible(txout.Transaction, block, operation); var coin = new Coin(txout); operation.ReceivedCoins.Add(Tuple.Create(coin, match.GetId())); bool merged = false; var returned = _Operations.AddOrUpdate(operation.GetId(), operation, (k, old) => old.Merge(operation, out merged)); var trackedOutpoint = new TrackedOutpoint() { Coin = coin, TrackedScriptId = match.GetId(), Filter = match.Filter }; _TrackedOutpoints.TryAdd(trackedOutpoint.GetId(), trackedOutpoint); return (operation == returned || merged) ? operation : null; }