wallet+db: add GetAccountSecret Store surface and keyvault routing#1272
Draft
yyforyongyu wants to merge 11 commits into
Draft
wallet+db: add GetAccountSecret Store surface and keyvault routing#1272yyforyongyu wants to merge 11 commits into
yyforyongyu wants to merge 11 commits into
Conversation
Coverage Report for CI Build 28320808284Warning No base build found for commit Coverage: 56.298%Details
Uncovered Changes
Coverage RegressionsRequires a base build to compare against. How to fix this → Coverage Stats
💛 - Coveralls |
449c243 to
e919fcb
Compare
7eee2d2 to
63a7a7d
Compare
Collaborator
Author
|
cc @GustavoStingelin for taking over, I think we can open a new PR instead, as this PR is only a draft. |
e919fcb to
e8d5e1a
Compare
c70b257 to
f572dca
Compare
b7b60d7 to
a354b6c
Compare
f572dca to
370e20c
Compare
a354b6c to
0908fc0
Compare
370e20c to
315a429
Compare
0908fc0 to
91960b1
Compare
315a429 to
7c30a37
Compare
91960b1 to
edba65b
Compare
4b277a5 to
de9ddb6
Compare
a5924bd to
edea01b
Compare
2e6f6b4 to
ba9f44a
Compare
de9ddb6 to
c5c3305
Compare
ba9f44a to
3fe8cf7
Compare
c5c3305 to
97946c4
Compare
3fe8cf7 to
180f71b
Compare
97946c4 to
120f1c4
Compare
180f71b to
e21896f
Compare
Add LegacyManagerVault wrapping walletdb.DB and *waddrmgr.Manager, implementing keyvault.Vault by delegating to the legacy address manager. Unlock authenticates the private passphrase inside a walletdb view and ignores the auto-lock timeout, since the controller keeps owning that timer. Lock is void and swallows the idempotent ErrLocked, logging any other failure. IsLocked, Encrypt, and Decrypt forward to the manager, and RefreshPrivatePassphrase is a no-op because the manager rotates its crypto state in place. The shim lives beside the other kvdb legacy adapters and lets later commits route wallet auth and key-material encryption through the vault seam without changing behavior. (cherry picked from commit fec2904)
Add the GetAccountSecret query to the pg and sqlite account query sets and regenerate the sqlc bindings. The query joins accounts to key_scopes and left-joins account_secrets so callers can distinguish a watch-only account (no secret row) from an absent account. Generated code is kept in its own commit, separate from the hand-written Go that consumes it. (cherry picked from commit 99c5994)
Add the AccountSecret result type and the GetAccountSecretQuery selector, plus the GetAccountSecretQuery.Validate helper and the ErrAccountSecretUnavailable sentinel. AccountSecret carries only encrypted private-key material; decryption stays with the wallet key vault. These types back the per-backend GetAccountSecret implementations that follow. (cherry picked from commit dc242ba)
Add the PostgreSQL Store.GetAccountSecret method backed by the generated GetAccountSecret query. It validates the selector, maps the row to the backend-independent AccountSecret, and reports a typed ErrAccountNotFound when no account row matches. The method is not yet part of the AccountStore interface; that wiring lands once every backend implements it. (cherry picked from commit 69c0b75)
Add the SQLite Store.GetAccountSecret method backed by the generated GetAccountSecret query, mirroring the PostgreSQL implementation: validate the selector, map the row to AccountSecret, and surface ErrAccountNotFound for a missing account. Interface wiring lands once all backends implement it. (cherry picked from commit cf0865f)
Add GetAccountSecret to the AccountStore interface now that pg and sqlite implement it, and complete the remaining implementations: the kvdb backend reports ErrAccountSecretUnavailable (legacy secrets stay in waddrmgr), and the testify mock store gains the method. The runtime cache exposes a pass-through GetAccountSecret seam, and an itest covers derived, watch-only, and absent-account outcomes. (cherry picked from commit 21ce20d)
Build the keyVault from kvdb.NewLegacyManagerVault during Load and OpenWithRetry instead of the not-yet-implemented keyvault.NewDBVault stub. The kvdb-open path now flows wallet auth and key-material encryption through a real legacy-backed vault while behavior stays unchanged. The SQL-open path keeps the DBVault stub until its runtime crypto lands. (cherry picked from commit 2d073a5)
Route handleUnlockReq and handleLockReq through the key vault instead of the wallet-owned DBUnlock helper, and delete DBUnlock and its test. Unlock passes a negative timeout so the controller keeps owning its auto-lock timer; Lock is void, with the idempotent ErrLocked swallow now living in the vault. The vault interface has no passphrase-change method, so the passphrase rotation stays in the wallet: handleChangePassphraseReq persists the change through DBPutPassphrase and then asks the vault to refresh its runtime state on a private rotation. The controller tests assert against the vault and the restored DBPutPassphrase path. (cherry picked from commit da88730)
Add deriveStoredAccountChildKey, which decrypts an account's encrypted private key through the key vault and derives the branch/index leaf key while zeroing intermediate material, and isWaddrmgrAccountClassError for classifying waddrmgr scope/account misses. Also add the ErrWatchOnlyAccount and ErrAccountNotInStore sentinels. These primitives back the store-backed signer fallback wired in next. (cherry picked from commit be8bb18)
Add derivePathPrivKey and resolveDerivedPrivKeyFromStore, and thread a context through the signing paths (ECDH, SignDigest, ComputeRawSig, DerivePrivKey and the output/imported-key helpers). When the legacy waddrmgr lookup misses on a scope or account, resolve the account's encrypted private key from the Store and derive the leaf key through the key vault, with precise watch-only and not-in-store errors. Covers SQL-only accounts that have no mirrored waddrmgr row. (cherry picked from commit de9ddb6)
…BT account #13: mirror deprecated public-key + taproot-script imports into w.store for SQL (skip the redundant kvdb mirror, where the legacy manager is the store). #14: DerivePubKey falls back to the account xpub from the store for SQL-only accounts (resolveDerivedPubKeyFromStore), matching the privkey fallback. #15: parseBip32Path sets InternalAccount alongside Account so non-zero-account PSBT signing resolves the correct account secret instead of account 0. (cherry picked from commit ca4c9d4) # Conflicts: # wallet/signer_test.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the account-secret surface to the runtime
db.Store: theGetAccountSecretquery, secret types, sqlite/pg implementations, and the store-contract method.
Also adds the legacy manager keyvault shim and routes wallet unlock/lock and
signer key derivation through the keyvault (store-backed derivation primitives,
with a legacy-miss fallback).
Split out of the secret Store PR for reviewability; content-preserving, no
commit changes. Stacked on
impl-runtime-store-5.