Beispiel #1
0
 private void InsertKeyInformation(DBreeze.Transactions.Transaction tx, Script scriptPubKey, KeyInformation info)
 {
     if (Caching)
     {
         _Cache.TryAdd(scriptPubKey.Hash, info);
     }
     tx.Insert("KeysByScript", scriptPubKey.Hash.ToString(), Zip(Serializer.ToString(info)));
 }
Beispiel #2
0
        public void MarkAsUsed(KeyInformation info)
        {
            var tableName            = $"U-{Hashes.Hash160(info.RootKey).ToString()}";
            var highestUsedIndexes   = new Dictionary <KeyPath, long>();
            var highestUnusedIndexes = new Dictionary <KeyPath, long>();

            using (var tx = _Engine.GetTransaction())
            {
                tx.ValuesLazyLoadingIsOn = false;
                if (info.KeyPath != null)
                {
                    tx.Insert(tableName, info.KeyPath.ToString(), true);
                }

                foreach (var row in tx.SelectForward <string, bool>(tableName))
                {
                    if (info.KeyPath == null)
                    {
                        return;                         //Early exit, no need to create the first keys, it has already been done
                    }
                    var     highestIndexes = row.Value ? highestUsedIndexes : highestUnusedIndexes;
                    KeyPath k = new KeyPath(row.Key);
                    long    highestKey;
                    if (!highestIndexes.TryGetValue(k.Parent, out highestKey))
                    {
                        highestKey = -1;
                    }
                    highestKey = Math.Max(highestKey, k.Indexes.Last());
                    highestIndexes.AddOrReplace(k.Parent, highestKey);
                }

                foreach (var trackedPath in TrackedPathes)
                {
                    ExtPubKey pathPubKey = null;
                    long      highestUnused;
                    if (!highestUnusedIndexes.TryGetValue(trackedPath, out highestUnused))
                    {
                        highestUnused = -1;
                    }

                    long highestUsed;
                    if (!highestUsedIndexes.TryGetValue(trackedPath, out highestUsed))
                    {
                        highestUsed = -1;
                    }

                    KeyPath highestUnusedPath = null;
                    while (highestUnused - highestUsed < MinGap)
                    {
                        if (highestUnused == uint.MaxValue)
                        {
                            break;
                        }
                        highestUnused++;

                        highestUnusedPath = trackedPath.Derive((uint)highestUnused);
                        pathPubKey        = pathPubKey ?? new ExtPubKey(info.RootKey).Derive(trackedPath);

                        var scriptPubKey = pathPubKey.Derive((uint)highestUnused).PubKey.Hash.ScriptPubKey;
                        InsertKeyInformation(tx, scriptPubKey, new KeyInformation()
                        {
                            KeyPath = trackedPath.Derive((uint)highestUnused),
                            RootKey = info.RootKey
                        });
                    }

                    if (highestUnusedPath != null)
                    {
                        byte[] inserted;
                        bool   existed;
                        tx.Insert(tableName, highestUnusedPath.ToString(), false, out inserted, out existed, dontUpdateIfExists: true);
                    }
                }
                tx.Commit();
            }
        }