Beispiel #1
0
        void LoadCore(Stream stream)
        {
            lock (cs)
            {
                _Operations.Clear();
                _TrackedOutpoints.Clear();
                _TrackedScripts.Clear();
                JObject obj = JObject.Load(new JsonTextReader(new StreamReader(stream))
                {
                    DateParseHandling = DateParseHandling.DateTimeOffset
                });
                _Tweak = (uint)(long)obj["Tweak"];
                var operations = (JArray)obj["Operations"];
                foreach (var operation in operations.OfType <JObject>())
                {
                    var op = Operation.FromJson(operation, _TrackedScripts);
                    _Operations.TryAdd(op.GetId(), op);
                }
                var outpoints = (JArray)obj["Outpoints"];
                foreach (var outpoint in outpoints.OfType <JObject>())
                {
                    var op = TrackedOutpoint.FromJson(outpoint);
                    _TrackedOutpoints.TryAdd(op.GetId(), op);
                }

                var scripts = (JArray)obj["Scripts"];
                foreach (var script in scripts.OfType <JObject>())
                {
                    var op = TrackedScript.FromJson(script);
                    _TrackedScripts.TryAdd(op.GetId(), op);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Register the specified ScriptPubKey
        /// </summary>
        /// <param name="scriptPubKey">The ScriptPubKey</param>
        /// <param name="isRedeemScript">If true, the P2SH of the destination's script will be tracked (Default: false)</param>
        /// <param name="isInternal">If true, the scriptPubKey will not belong to tracked data, typically, change addresses (Default: false)</param>
        /// <param name="filter">The filter in which this key will appear (http://eprint.iacr.org/2014/763.pdf)</param>
        /// <param name="wallet">The wallet name to which it belongs</param>
        public bool Add(Script scriptPubKey, bool isRedeemScript = false, bool isInternal = false, string filter = "a", string wallet = "default")
        {
            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }
            if (wallet == null)
            {
                throw new ArgumentNullException("wallet");
            }
            Script redeem = isRedeemScript ? scriptPubKey : null;

            scriptPubKey = isRedeemScript ? scriptPubKey.Hash.ScriptPubKey : scriptPubKey;
            var data = scriptPubKey.ToOps().First(o => o.PushData != null).PushData;

            var trackedScript = new TrackedScript()
            {
                ScriptPubKey = scriptPubKey,
                RedeemScript = redeem,
                AddedDate    = DateTimeOffset.UtcNow,
                IsInternal   = isInternal,
                Filter       = filter,
                Wallet       = wallet
            };

            bool added = false;

            lock (cs)
            {
                added = _TrackedScripts.TryAdd(trackedScript.GetId(), trackedScript);
            }
            return(added);
        }
Beispiel #3
0
        private void Spent(TrackedScript metadata, IndexedTxIn txin, Coin coin, ChainedBlock block, MerkleBlock proof)
        {
            var operation = new Operation(txin.Transaction, block, proof);

            operation.SpentCoins.Add(Tuple.Create(coin, metadata.GetId()));
            SetUnconfirmedSeenIfPossible(txin.Transaction, block, operation);
            _Operations.AddOrUpdate(operation.GetId(), operation, (k, old) => old.Merge(operation));
        }
Beispiel #4
0
        private Operation Spent(TrackedScript metadata, IndexedTxIn txin, Coin coin, ChainedBlock block, MerkleBlock proof)
        {
            var operation = new Operation(txin.Transaction, block, proof, _TrackedScripts);

            operation.SpentCoins.Add(Tuple.Create(coin, metadata.GetId()));
            SetUnconfirmedSeenIfPossible(txin.Transaction, block, operation);

            bool merged   = false;
            var  returned = _Operations.AddOrUpdate(operation.GetId(), operation, (k, old) => old.Merge(operation, out merged));

            return((operation == returned || merged) ? operation : null);
        }
Beispiel #5
0
        public bool NotifyTransaction(Transaction transaction, ChainedBlock chainedBlock, MerkleBlock proof)
        {
            if (chainedBlock != null)
            {
                if (proof == null)
                {
                    throw new ArgumentNullException("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;

            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;
                            Spent(parentMetadata, txin, match.Coin, chainedBlock, proof);
                        }
                    }
                }
                foreach (var txout in transaction.Outputs.AsIndexedOutputs())
                {
                    var           key = TrackedScript.GetId(txout.TxOut.ScriptPubKey);
                    TrackedScript match;
                    if (_TrackedScripts.TryGetValue(key, out match))
                    {
                        interesting = true;
                        Received(match, txout, chainedBlock, proof);
                    }
                }
            }
            return(interesting);
        }
Beispiel #6
0
            internal static TrackedScript FromJson(JObject obj)
            {
                TrackedScript script = new TrackedScript();

                script.ScriptPubKey = Script.FromBytesUnsafe(Encoders.Hex.DecodeData((string)obj["ScriptPubKey"]));
                var redeem = (string)obj["RedeemScript"];

                if (redeem != null)
                {
                    script.RedeemScript = Script.FromBytesUnsafe(Encoders.Hex.DecodeData((string)obj["RedeemScript"]));
                }
                script.AddedDate = obj["AddedDate"].Value <DateTimeOffset>();
                script.Filter    = (string)obj["Filter"];
                script.Wallet    = (string)obj["Wallet"];
                return(script);
            }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
		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);
		}
Beispiel #10
0
		private void Spent(TrackedScript metadata, IndexedTxIn txin, Coin coin, ChainedBlock block, MerkleBlock proof)
		{
			var operation = new Operation(txin.Transaction, block, proof);
			operation.SpentCoins.Add(Tuple.Create(coin, metadata.GetId()));
			SetUnconfirmedSeenIfPossible(txin.Transaction, block, operation);
			_Operations.AddOrUpdate(operation.GetId(), operation, (k, old) => old.Merge(operation));
		}
Beispiel #11
0
		/// <summary>
		/// Register the specified ScriptPubKey
		/// </summary>
		/// <param name="scriptPubKey">The ScriptPubKey</param>
		/// <param name="isRedeemScript">If true, the P2SH of the destination's script will be tracked (Default: false)</param>
		/// <param name="isInternal">If true, the scriptPubKey will not belong to tracked data, typically, change addresses (Default: false)</param>
		/// <param name="filter">The filter in which this key will appear (http://eprint.iacr.org/2014/763.pdf)</param>
		/// <param name="wallet">The wallet name to which it belongs</param>
		public bool Add(Script scriptPubKey, bool isRedeemScript = false, bool isInternal = false, string filter = "a", string wallet = "default")
		{
			if(filter == null)
				throw new ArgumentNullException("filter");
			if(wallet == null)
				throw new ArgumentNullException("wallet");
			Script redeem = isRedeemScript ? scriptPubKey : null;
			scriptPubKey = isRedeemScript ? scriptPubKey.Hash.ScriptPubKey : scriptPubKey;
			var data = scriptPubKey.ToOps().First(o => o.PushData != null).PushData;

			var trackedScript = new TrackedScript()
			{
				ScriptPubKey = scriptPubKey,
				RedeemScript = redeem,
				AddedDate = DateTimeOffset.UtcNow,
				IsInternal = isInternal,
				Filter = filter,
				Wallet = wallet
			};

			bool added = false;
			lock(cs)
			{
				added = _TrackedScripts.TryAdd(trackedScript.GetId(), trackedScript);
			}
			return added;
		}
Beispiel #12
0
			internal static TrackedScript FromJson(JObject obj)
			{
				TrackedScript script = new TrackedScript();
				script.ScriptPubKey = Script.FromBytesUnsafe(Encoders.Hex.DecodeData((string)obj["ScriptPubKey"]));
				var redeem = (string)obj["RedeemScript"];
				if(redeem != null)
				{
					script.RedeemScript = Script.FromBytesUnsafe(Encoders.Hex.DecodeData((string)obj["RedeemScript"]));
				}
				script.AddedDate = obj["AddedDate"].Value<DateTimeOffset>();
				script.Filter = (string)obj["Filter"];
				script.Wallet = (string)obj["Wallet"];
				return script;
			}
Beispiel #13
0
		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;
		}
Beispiel #14
0
		private Operation Spent(TrackedScript metadata, IndexedTxIn txin, Coin coin, ChainedBlock block, MerkleBlock proof)
		{
			var operation = new Operation(txin.Transaction, block, proof, _TrackedScripts);
			operation.SpentCoins.Add(Tuple.Create(coin, metadata.GetId()));
			SetUnconfirmedSeenIfPossible(txin.Transaction, block, operation);

			bool merged = false;
			var returned = _Operations.AddOrUpdate(operation.GetId(), operation, (k, old) => old.Merge(operation, out merged));
			return (operation == returned || merged) ? operation : null;
		}