mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-11-10 14:17:56 +01:00
Merge pull request #10136 from yyforyongyu/use-btcwallet-interface
lnwallet: use btcwallet's new interface
This commit is contained in:
@@ -174,6 +174,9 @@ reader of a payment request.
|
|||||||
- [Refactored](https://github.com/lightningnetwork/lnd/pull/10018) `channelLink`
|
- [Refactored](https://github.com/lightningnetwork/lnd/pull/10018) `channelLink`
|
||||||
to improve readability and maintainability of the code.
|
to improve readability and maintainability of the code.
|
||||||
|
|
||||||
|
- [Introduced](https://github.com/lightningnetwork/lnd/pull/10136) a wallet
|
||||||
|
interface to decouple the relationship between `lnd` and `btcwallet`.
|
||||||
|
|
||||||
## Breaking Changes
|
## Breaking Changes
|
||||||
## Performance Improvements
|
## Performance Improvements
|
||||||
|
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -11,7 +11,7 @@ require (
|
|||||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0
|
||||||
github.com/btcsuite/btclog v0.0.0-20241003133417-09c4e92e319c
|
github.com/btcsuite/btclog v0.0.0-20241003133417-09c4e92e319c
|
||||||
github.com/btcsuite/btclog/v2 v2.0.1-0.20250728225537-6090e87c6c5b
|
github.com/btcsuite/btclog/v2 v2.0.1-0.20250728225537-6090e87c6c5b
|
||||||
github.com/btcsuite/btcwallet v0.16.15-0.20250805011126-a3632ae48ab3
|
github.com/btcsuite/btcwallet v0.16.15-0.20250811092146-05b3a40651e6
|
||||||
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5
|
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5
|
||||||
github.com/btcsuite/btcwallet/wallet/txrules v1.2.2
|
github.com/btcsuite/btcwallet/wallet/txrules v1.2.2
|
||||||
github.com/btcsuite/btcwallet/walletdb v1.5.1
|
github.com/btcsuite/btcwallet/walletdb v1.5.1
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -64,8 +64,8 @@ github.com/btcsuite/btclog v0.0.0-20241003133417-09c4e92e319c/go.mod h1:w7xnGOhw
|
|||||||
github.com/btcsuite/btclog/v2 v2.0.1-0.20250728225537-6090e87c6c5b h1:MQ+Q6sDy37V1wP1Yu79A5KqJutolqUGwA99UZWQDWZM=
|
github.com/btcsuite/btclog/v2 v2.0.1-0.20250728225537-6090e87c6c5b h1:MQ+Q6sDy37V1wP1Yu79A5KqJutolqUGwA99UZWQDWZM=
|
||||||
github.com/btcsuite/btclog/v2 v2.0.1-0.20250728225537-6090e87c6c5b/go.mod h1:XItGUfVOxotJL8kkuk2Hj3EVow5KCugXl3wWfQ6K0AE=
|
github.com/btcsuite/btclog/v2 v2.0.1-0.20250728225537-6090e87c6c5b/go.mod h1:XItGUfVOxotJL8kkuk2Hj3EVow5KCugXl3wWfQ6K0AE=
|
||||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||||
github.com/btcsuite/btcwallet v0.16.15-0.20250805011126-a3632ae48ab3 h1:MAjNRpj3XhCOrhchq4wq0qI34TIBX/DCnT6OLWejx68=
|
github.com/btcsuite/btcwallet v0.16.15-0.20250811092146-05b3a40651e6 h1:s6NCipDdvDK5rBrC4dIlni1iHsuDOKdfwpL32I3b6Tw=
|
||||||
github.com/btcsuite/btcwallet v0.16.15-0.20250805011126-a3632ae48ab3/go.mod h1:H6dfoZcWPonM2wbVsR2ZBY0PKNZKdQyLAmnX8vL9JFA=
|
github.com/btcsuite/btcwallet v0.16.15-0.20250811092146-05b3a40651e6/go.mod h1:H6dfoZcWPonM2wbVsR2ZBY0PKNZKdQyLAmnX8vL9JFA=
|
||||||
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5 h1:Rr0njWI3r341nhSPesKQ2JF+ugDSzdPoeckS75SeDZk=
|
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5 h1:Rr0njWI3r341nhSPesKQ2JF+ugDSzdPoeckS75SeDZk=
|
||||||
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5/go.mod h1:+tXJ3Ym0nlQc/iHSwW1qzjmPs3ev+UVWMbGgfV1OZqU=
|
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5/go.mod h1:+tXJ3Ym0nlQc/iHSwW1qzjmPs3ev+UVWMbGgfV1OZqU=
|
||||||
github.com/btcsuite/btcwallet/wallet/txrules v1.2.2 h1:YEO+Lx1ZJJAtdRrjuhXjWrYsmAk26wLTlNzxt2q0lhk=
|
github.com/btcsuite/btcwallet/wallet/txrules v1.2.2 h1:YEO+Lx1ZJJAtdRrjuhXjWrYsmAk26wLTlNzxt2q0lhk=
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ type BtcWalletKeyRing struct {
|
|||||||
// wallet is a pointer to the active instance of the btcwallet core.
|
// wallet is a pointer to the active instance of the btcwallet core.
|
||||||
// This is required as we'll need to manually open database
|
// This is required as we'll need to manually open database
|
||||||
// transactions in order to derive addresses and lookup relevant keys
|
// transactions in order to derive addresses and lookup relevant keys
|
||||||
wallet *wallet.Wallet
|
wallet wallet.Interface
|
||||||
|
|
||||||
// chainKeyScope defines the purpose and coin type to be used when generating
|
// chainKeyScope defines the purpose and coin type to be used when generating
|
||||||
// keys for this keyring.
|
// keys for this keyring.
|
||||||
@@ -64,7 +64,7 @@ type BtcWalletKeyRing struct {
|
|||||||
//
|
//
|
||||||
// NOTE: The passed waddrmgr.Manager MUST be unlocked in order for the keychain
|
// NOTE: The passed waddrmgr.Manager MUST be unlocked in order for the keychain
|
||||||
// to function.
|
// to function.
|
||||||
func NewBtcWalletKeyRing(w *wallet.Wallet, coinType uint32) SecretKeyRing {
|
func NewBtcWalletKeyRing(w wallet.Interface, coinType uint32) SecretKeyRing {
|
||||||
// Construct the key scope that will be used within the waddrmgr to
|
// Construct the key scope that will be used within the waddrmgr to
|
||||||
// create an HD chain for deriving all of our required keys. A different
|
// create an HD chain for deriving all of our required keys. A different
|
||||||
// scope is used for each specific coin type.
|
// scope is used for each specific coin type.
|
||||||
@@ -92,14 +92,18 @@ func (b *BtcWalletKeyRing) keyScope() (*waddrmgr.ScopedKeyManager, error) {
|
|||||||
|
|
||||||
// Otherwise, we'll first do a check to ensure that the root manager
|
// Otherwise, we'll first do a check to ensure that the root manager
|
||||||
// isn't locked, as otherwise we won't be able to *use* the scope.
|
// isn't locked, as otherwise we won't be able to *use* the scope.
|
||||||
if !b.wallet.Manager.WatchOnly() && b.wallet.Manager.IsLocked() {
|
if !b.wallet.AddrManager().WatchOnly() &&
|
||||||
|
b.wallet.AddrManager().IsLocked() {
|
||||||
|
|
||||||
return nil, fmt.Errorf("cannot create BtcWalletKeyRing with " +
|
return nil, fmt.Errorf("cannot create BtcWalletKeyRing with " +
|
||||||
"locked waddrmgr.Manager")
|
"locked waddrmgr.Manager")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the manager is indeed unlocked, then we'll fetch the scope, cache
|
// If the manager is indeed unlocked, then we'll fetch the scope, cache
|
||||||
// it, and return to the caller.
|
// it, and return to the caller.
|
||||||
lnScope, err := b.wallet.Manager.FetchScopedKeyManager(b.chainKeyScope)
|
lnScope, err := b.wallet.AddrManager().FetchScopedKeyManager(
|
||||||
|
b.chainKeyScope,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -218,7 +222,7 @@ func (b *BtcWalletKeyRing) DeriveKey(keyLoc KeyLocator) (KeyDescriptor, error) {
|
|||||||
// require. We skip this if we're using a remote signer in which
|
// require. We skip this if we're using a remote signer in which
|
||||||
// case we _need_ to create all accounts when creating the
|
// case we _need_ to create all accounts when creating the
|
||||||
// wallet, so it must exist now.
|
// wallet, so it must exist now.
|
||||||
if !b.wallet.Manager.WatchOnly() {
|
if !b.wallet.AddrManager().WatchOnly() {
|
||||||
err = b.createAccountIfNotExists(
|
err = b.createAccountIfNotExists(
|
||||||
addrmgrNs, keyLoc.Family, scope,
|
addrmgrNs, keyLoc.Family, scope,
|
||||||
)
|
)
|
||||||
@@ -288,7 +292,7 @@ func (b *BtcWalletKeyRing) DerivePrivKey(keyDesc KeyDescriptor) (
|
|||||||
// require. We skip this if we're using a remote signer in which
|
// require. We skip this if we're using a remote signer in which
|
||||||
// case we _need_ to create all accounts when creating the
|
// case we _need_ to create all accounts when creating the
|
||||||
// wallet, so it must exist now.
|
// wallet, so it must exist now.
|
||||||
if !b.wallet.Manager.WatchOnly() {
|
if !b.wallet.AddrManager().WatchOnly() {
|
||||||
err = b.createAccountIfNotExists(
|
err = b.createAccountIfNotExists(
|
||||||
addrmgrNs, keyDesc.Family, scope,
|
addrmgrNs, keyDesc.Family, scope,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import (
|
|||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcwallet/chain"
|
"github.com/btcsuite/btcwallet/chain"
|
||||||
"github.com/btcsuite/btcwallet/waddrmgr"
|
"github.com/btcsuite/btcwallet/waddrmgr"
|
||||||
"github.com/btcsuite/btcwallet/wallet"
|
|
||||||
base "github.com/btcsuite/btcwallet/wallet"
|
base "github.com/btcsuite/btcwallet/wallet"
|
||||||
"github.com/btcsuite/btcwallet/wallet/txauthor"
|
"github.com/btcsuite/btcwallet/wallet/txauthor"
|
||||||
"github.com/btcsuite/btcwallet/wallet/txrules"
|
"github.com/btcsuite/btcwallet/wallet/txrules"
|
||||||
@@ -85,7 +84,7 @@ var (
|
|||||||
// operate.
|
// operate.
|
||||||
type BtcWallet struct {
|
type BtcWallet struct {
|
||||||
// wallet is an active instance of btcwallet.
|
// wallet is an active instance of btcwallet.
|
||||||
wallet *base.Wallet
|
wallet base.Interface
|
||||||
|
|
||||||
chain chain.Interface
|
chain chain.Interface
|
||||||
|
|
||||||
@@ -289,7 +288,7 @@ func (b *BtcWallet) BackEnd() string {
|
|||||||
|
|
||||||
// InternalWallet returns a pointer to the internal base wallet which is the
|
// InternalWallet returns a pointer to the internal base wallet which is the
|
||||||
// core of btcwallet.
|
// core of btcwallet.
|
||||||
func (b *BtcWallet) InternalWallet() *base.Wallet {
|
func (b *BtcWallet) InternalWallet() base.Interface {
|
||||||
return b.wallet
|
return b.wallet
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,7 +299,7 @@ func (b *BtcWallet) InternalWallet() *base.Wallet {
|
|||||||
func (b *BtcWallet) Start() error {
|
func (b *BtcWallet) Start() error {
|
||||||
// Is the wallet (according to its database) currently watch-only
|
// Is the wallet (according to its database) currently watch-only
|
||||||
// already? If it is, we won't need to convert it later.
|
// already? If it is, we won't need to convert it later.
|
||||||
walletIsWatchOnly := b.wallet.Manager.WatchOnly()
|
walletIsWatchOnly := b.wallet.AddrManager().WatchOnly()
|
||||||
|
|
||||||
// If the wallet is watch-only, but we don't expect it to be, then we
|
// If the wallet is watch-only, but we don't expect it to be, then we
|
||||||
// are in an unexpected state and cannot continue.
|
// are in an unexpected state and cannot continue.
|
||||||
@@ -336,7 +335,7 @@ func (b *BtcWallet) Start() error {
|
|||||||
// created correctly for new wallets. Existing wallets don't
|
// created correctly for new wallets. Existing wallets don't
|
||||||
// automatically add them, we need to do that manually now.
|
// automatically add them, we need to do that manually now.
|
||||||
for _, scope := range LndDefaultKeyScopes {
|
for _, scope := range LndDefaultKeyScopes {
|
||||||
_, err := b.wallet.Manager.FetchScopedKeyManager(scope)
|
_, err := b.wallet.AddrManager().FetchScopedKeyManager(scope)
|
||||||
if waddrmgr.IsError(err, waddrmgr.ErrScopeNotFound) {
|
if waddrmgr.IsError(err, waddrmgr.ErrScopeNotFound) {
|
||||||
// The default scope wasn't found, that probably means
|
// The default scope wasn't found, that probably means
|
||||||
// it was added recently and older wallets don't know it
|
// it was added recently and older wallets don't know it
|
||||||
@@ -349,7 +348,9 @@ func (b *BtcWallet) Start() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope, err := b.wallet.Manager.FetchScopedKeyManager(b.chainKeyScope)
|
scope, err := b.wallet.AddrManager().FetchScopedKeyManager(
|
||||||
|
b.chainKeyScope,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If the scope hasn't yet been created (it wouldn't been
|
// If the scope hasn't yet been created (it wouldn't been
|
||||||
// loaded by default if it was), then we'll manually create the
|
// loaded by default if it was), then we'll manually create the
|
||||||
@@ -981,11 +982,11 @@ func (b *BtcWallet) CreateSimpleTx(inputs fn.Set[wire.OutPoint],
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the optional inputs to the transaction.
|
// Add the optional inputs to the transaction.
|
||||||
optFunc := wallet.WithCustomSelectUtxos(inputs.ToSlice())
|
optFunc := base.WithCustomSelectUtxos(inputs.ToSlice())
|
||||||
|
|
||||||
return b.wallet.CreateSimpleTx(
|
return b.wallet.CreateSimpleTx(
|
||||||
nil, defaultAccount, outputs, minConfs, feeSatPerKB,
|
nil, defaultAccount, outputs, minConfs, feeSatPerKB,
|
||||||
strategy, dryRun, []wallet.TxCreateOption{optFunc}...,
|
strategy, dryRun, []base.TxCreateOption{optFunc}...,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1292,7 +1293,7 @@ func (b *BtcWallet) GetTransactionDetails(
|
|||||||
|
|
||||||
// Grab the best block the wallet knows of, we'll use this to calculate
|
// Grab the best block the wallet knows of, we'll use this to calculate
|
||||||
// # of confirmations shortly below.
|
// # of confirmations shortly below.
|
||||||
bestBlock := b.wallet.Manager.SyncedTo()
|
bestBlock := b.wallet.SyncedTo()
|
||||||
currentHeight := bestBlock.Height
|
currentHeight := bestBlock.Height
|
||||||
tx, err := b.wallet.GetTransaction(*txHash)
|
tx, err := b.wallet.GetTransaction(*txHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1482,7 +1483,7 @@ func (b *BtcWallet) ListTransactionDetails(startHeight, endHeight int32,
|
|||||||
|
|
||||||
// Grab the best block the wallet knows of, we'll use this to calculate
|
// Grab the best block the wallet knows of, we'll use this to calculate
|
||||||
// # of confirmations shortly below.
|
// # of confirmations shortly below.
|
||||||
bestBlock := b.wallet.Manager.SyncedTo()
|
bestBlock := b.wallet.SyncedTo()
|
||||||
currentHeight := bestBlock.Height
|
currentHeight := bestBlock.Height
|
||||||
|
|
||||||
// We'll attempt to find all transactions from start to end height.
|
// We'll attempt to find all transactions from start to end height.
|
||||||
@@ -1555,7 +1556,7 @@ type txSubscriptionClient struct {
|
|||||||
confirmed chan *lnwallet.TransactionDetail
|
confirmed chan *lnwallet.TransactionDetail
|
||||||
unconfirmed chan *lnwallet.TransactionDetail
|
unconfirmed chan *lnwallet.TransactionDetail
|
||||||
|
|
||||||
w *base.Wallet
|
w base.Interface
|
||||||
|
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
@@ -1598,7 +1599,7 @@ out:
|
|||||||
select {
|
select {
|
||||||
case txNtfn := <-t.txClient.C:
|
case txNtfn := <-t.txClient.C:
|
||||||
// TODO(roasbeef): handle detached blocks
|
// TODO(roasbeef): handle detached blocks
|
||||||
currentHeight := t.w.Manager.SyncedTo().Height
|
currentHeight := t.w.SyncedTo().Height
|
||||||
|
|
||||||
// Launch a goroutine to re-package and send
|
// Launch a goroutine to re-package and send
|
||||||
// notifications for any newly confirmed transactions.
|
// notifications for any newly confirmed transactions.
|
||||||
@@ -1654,7 +1655,7 @@ out:
|
|||||||
//
|
//
|
||||||
// This is a part of the WalletController interface.
|
// This is a part of the WalletController interface.
|
||||||
func (b *BtcWallet) SubscribeTransactions() (lnwallet.TransactionSubscription, error) {
|
func (b *BtcWallet) SubscribeTransactions() (lnwallet.TransactionSubscription, error) {
|
||||||
walletClient := b.wallet.NtfnServer.TransactionNotifications()
|
walletClient := b.wallet.NotificationServer().TransactionNotifications()
|
||||||
|
|
||||||
txClient := &txSubscriptionClient{
|
txClient := &txSubscriptionClient{
|
||||||
txClient: walletClient,
|
txClient: walletClient,
|
||||||
@@ -1675,7 +1676,7 @@ func (b *BtcWallet) SubscribeTransactions() (lnwallet.TransactionSubscription, e
|
|||||||
// This is a part of the WalletController interface.
|
// This is a part of the WalletController interface.
|
||||||
func (b *BtcWallet) IsSynced() (bool, int64, error) {
|
func (b *BtcWallet) IsSynced() (bool, int64, error) {
|
||||||
// Grab the best chain state the wallet is currently aware of.
|
// Grab the best chain state the wallet is currently aware of.
|
||||||
syncState := b.wallet.Manager.SyncedTo()
|
syncState := b.wallet.SyncedTo()
|
||||||
|
|
||||||
// We'll also extract the current best wallet timestamp so the caller
|
// We'll also extract the current best wallet timestamp so the caller
|
||||||
// can get an idea of where we are in the sync timeline.
|
// can get an idea of where we are in the sync timeline.
|
||||||
@@ -1753,7 +1754,7 @@ func (b *BtcWallet) GetRecoveryInfo() (bool, float64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grab the best chain state the wallet is currently aware of.
|
// Grab the best chain state the wallet is currently aware of.
|
||||||
syncState := b.wallet.Manager.SyncedTo()
|
syncState := b.wallet.SyncedTo()
|
||||||
|
|
||||||
// Next, query the chain backend to grab the info about the tip of the
|
// Next, query the chain backend to grab the info about the tip of the
|
||||||
// main chain.
|
// main chain.
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ func TestScriptImport(t *testing.T) {
|
|||||||
require.Equal(t, firstAddressTaproot, firstDerivedAddr.String())
|
require.Equal(t, firstAddressTaproot, firstDerivedAddr.String())
|
||||||
|
|
||||||
scope := waddrmgr.KeyScopeBIP0086
|
scope := waddrmgr.KeyScopeBIP0086
|
||||||
_, err = w.InternalWallet().Manager.FetchScopedKeyManager(scope)
|
_, err = w.InternalWallet().AddrManager().FetchScopedKeyManager(scope)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Let's create a taproot script output now. This is a hash lock with a
|
// Let's create a taproot script output now. This is a hash lock with a
|
||||||
|
|||||||
Reference in New Issue
Block a user