diff --git a/keychain/btcwallet.go b/keychain/btcwallet.go index 02b72139..8d5dab3b 100644 --- a/keychain/btcwallet.go +++ b/keychain/btcwallet.go @@ -252,14 +252,30 @@ func (b *BtcWalletKeyRing) DerivePrivKey(keyDesc KeyDescriptor) ( var key *btcec.PrivateKey - db := b.wallet.Database() - err := walletdb.Update(db, func(tx walletdb.ReadWriteTx) error { - addrmgrNs := tx.ReadWriteBucket(waddrmgrNamespaceKey) + scope, err := b.keyScope() + if err != nil { + return nil, err + } - scope, err := b.keyScope() - if err != nil { - return err + // First, attempt to see if we can read the key directly from + // btcwallet's internal cache, if we can then we can skip all the + // operations below (fast path). + if keyDesc.PubKey == nil { + keyPath := waddrmgr.DerivationPath{ + InternalAccount: uint32(keyDesc.Family), + Account: uint32(keyDesc.Family), + Branch: 0, + Index: keyDesc.Index, } + privKey, err := scope.DeriveFromKeyPathCache(keyPath) + if err == nil { + return privKey, nil + } + } + + db := b.wallet.Database() + err = walletdb.Update(db, func(tx walletdb.ReadWriteTx) error { + addrmgrNs := tx.ReadWriteBucket(waddrmgrNamespaceKey) // If the account doesn't exist, then we may need to create it // for the first time in order to derive the keys that we diff --git a/lnwallet/btcwallet/signer.go b/lnwallet/btcwallet/signer.go index 953ec100..bc48360e 100644 --- a/lnwallet/btcwallet/signer.go +++ b/lnwallet/btcwallet/signer.go @@ -75,6 +75,20 @@ func (b *BtcWallet) deriveKeyByLocator(keyLoc keychain.KeyLocator) (*btcec.Priva return nil, err } + // First try to read the key from the cached store, if this fails, then + // we'll fall through to the method below that requires a database + // transaction. + path := waddrmgr.DerivationPath{ + InternalAccount: uint32(keyLoc.Family), + Account: uint32(keyLoc.Family), + Branch: 0, + Index: keyLoc.Index, + } + privKey, err := scopedMgr.DeriveFromKeyPathCache(path) + if err == nil { + return privKey, nil + } + var key *btcec.PrivateKey err = walletdb.Update(b.db, func(tx walletdb.ReadWriteTx) error { addrmgrNs := tx.ReadWriteBucket(waddrmgrNamespaceKey)