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