Skip to content

Commit 492f8b6

Browse files
committed
chainreg: shutdown if backend node doesn't support taproot
In this commit, we add a check during normal node construction to see if the backend node supports Taproot. If it doesn't, then we want to shutdown and force the user to take note. To check if the node supports Taproot, we'll first try the normal getblockchaininfo call. If this works, cool, then we can rely on the value. If it doesn't, then we'll fall back to the getdeploymentinfo call which was added in a recent version of bitcoind [1]. Newer versions of bitcoind might also have this call, and the getblockchaininfo call, but not actually populate the softforks field [2]. In this case, we'll fall back, and we also account for the case when the getblockchaininfo RPC is removed all together. [1]: bitcoin/bitcoin#23508 [2]: bitcoin/bitcoin#25114 Fixes #6773
1 parent 115b041 commit 492f8b6

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

chainreg/chainregistry.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,14 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) {
496496
return nil, nil, err
497497
}
498498

499+
// Before we continue any further, we'll ensure that the
500+
// backend understands Taproot. If not, then all the default
501+
// features can't be used.
502+
if !backendSupportsTaproot(chainConn) {
503+
return nil, nil, fmt.Errorf("node backend does not " +
504+
"support taproot")
505+
}
506+
499507
// The api we will use for our health check depends on the
500508
// bitcoind version.
501509
cmd, ver, err := getBitcoindHealthCheckCmd(chainConn)
@@ -675,6 +683,21 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) {
675683
return nil, nil, err
676684
}
677685

686+
// Before we continue any further, we'll ensure that the
687+
// backend understands Taproot. If not, then all the default
688+
// features can't be used.
689+
restConfCopy := *rpcConfig
690+
restConfCopy.Endpoint = ""
691+
restConfCopy.HTTPPostMode = true
692+
chainConn, err := rpcclient.New(&restConfCopy, nil)
693+
if err != nil {
694+
return nil, nil, err
695+
}
696+
if !backendSupportsTaproot(chainConn) {
697+
return nil, nil, fmt.Errorf("node backend does not " +
698+
"support taproot")
699+
}
700+
678701
cc.ChainSource = chainRPC
679702

680703
// Use a query for our best block as a health check.

chainreg/taproot_check.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package chainreg
2+
3+
import (
4+
"encoding/json"
5+
6+
"github.com/btcsuite/btcd/rpcclient"
7+
)
8+
9+
// backendSupportsTaproot returns true if the backend understands the taproot
10+
// soft fork.
11+
func backendSupportsTaproot(rpc *rpcclient.Client) bool {
12+
// First, we'll try to access the normal getblockchaininfo call.
13+
chainInfo, err := rpc.GetBlockChainInfo()
14+
if err == nil {
15+
// If this call worked, then we'll check that the taproot
16+
// deployment is defined.
17+
if chainInfo.SoftForks != nil {
18+
_, ok := chainInfo.SoftForks.Bip9SoftForks["taproot"]
19+
if ok {
20+
return ok
21+
}
22+
}
23+
}
24+
25+
// The user might be running a newer version of bitcoind that doesn't
26+
// implement the getblockchaininfo call any longer, so we'll fall back
27+
// here.
28+
//
29+
// Alternatively, the fork wasn't specified, but the user might be
30+
// running a newer version of bitcoind that still has the
31+
// getblockchaininfo call, but doesn't populate the data, so we'll hit
32+
// the new getdeploymentinfo call.
33+
resp, err := rpc.RawRequest("getdeploymentinfo", nil)
34+
if err != nil {
35+
log.Warnf("unable to make getdeploymentinfo request: %v", err)
36+
return false
37+
}
38+
39+
info := struct {
40+
Deployments map[string]struct {
41+
Type string `json:"type"`
42+
Active bool `json:"active"`
43+
Height int32 `json:"height"`
44+
} `json:"deployments"`
45+
}{}
46+
if err := json.Unmarshal(resp, &info); err != nil {
47+
log.Warnf("unable to decode getdeploymentinfo resp: %v", err)
48+
return false
49+
}
50+
51+
_, ok := info.Deployments["taproot"]
52+
return ok
53+
}

docs/release-notes/release-notes-0.15.1.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
binary digest to be different whether that folder exists or
1212
not](https://github.com/lightningnetwork/lnd/pull/6676).
1313

14+
## Taproot
15+
16+
[`lnd` will now refuse to start if it detects the full node backned does not
17+
support Tapoot](https://github.com/lightningnetwork/lnd/pull/6798).
18+
19+
1420
## `lncli`
1521

1622
* [Add `payment_addr` flag to

0 commit comments

Comments
 (0)