diff --git a/chainreg/chainregistry.go b/chainreg/chainregistry.go index bd6f34b0b..5b9c77ffd 100644 --- a/chainreg/chainregistry.go +++ b/chainreg/chainregistry.go @@ -496,6 +496,14 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) { return nil, nil, err } + // Before we continue any further, we'll ensure that the + // backend understands Taproot. If not, then all the default + // features can't be used. + if !backendSupportsTaproot(chainConn) { + return nil, nil, fmt.Errorf("node backend does not " + + "support taproot") + } + // The api we will use for our health check depends on the // bitcoind version. cmd, ver, err := getBitcoindHealthCheckCmd(chainConn) @@ -675,6 +683,21 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) { return nil, nil, err } + // Before we continue any further, we'll ensure that the + // backend understands Taproot. If not, then all the default + // features can't be used. + restConfCopy := *rpcConfig + restConfCopy.Endpoint = "" + restConfCopy.HTTPPostMode = true + chainConn, err := rpcclient.New(&restConfCopy, nil) + if err != nil { + return nil, nil, err + } + if !backendSupportsTaproot(chainConn) { + return nil, nil, fmt.Errorf("node backend does not " + + "support taproot") + } + cc.ChainSource = chainRPC // Use a query for our best block as a health check. diff --git a/chainreg/taproot_check.go b/chainreg/taproot_check.go new file mode 100644 index 000000000..5528e9f71 --- /dev/null +++ b/chainreg/taproot_check.go @@ -0,0 +1,53 @@ +package chainreg + +import ( + "encoding/json" + + "github.com/btcsuite/btcd/rpcclient" +) + +// backendSupportsTaproot returns true if the backend understands the taproot +// soft fork. +func backendSupportsTaproot(rpc *rpcclient.Client) bool { + // First, we'll try to access the normal getblockchaininfo call. + chainInfo, err := rpc.GetBlockChainInfo() + if err == nil { + // If this call worked, then we'll check that the taproot + // deployment is defined. + if chainInfo.SoftForks != nil { + _, ok := chainInfo.SoftForks.Bip9SoftForks["taproot"] + if ok { + return ok + } + } + } + + // The user might be running a newer version of bitcoind that doesn't + // implement the getblockchaininfo call any longer, so we'll fall back + // here. + // + // Alternatively, the fork wasn't specified, but the user might be + // running a newer version of bitcoind that still has the + // getblockchaininfo call, but doesn't populate the data, so we'll hit + // the new getdeploymentinfo call. + resp, err := rpc.RawRequest("getdeploymentinfo", nil) + if err != nil { + log.Warnf("unable to make getdeploymentinfo request: %v", err) + return false + } + + info := struct { + Deployments map[string]struct { + Type string `json:"type"` + Active bool `json:"active"` + Height int32 `json:"height"` + } `json:"deployments"` + }{} + if err := json.Unmarshal(resp, &info); err != nil { + log.Warnf("unable to decode getdeploymentinfo resp: %v", err) + return false + } + + _, ok := info.Deployments["taproot"] + return ok +} diff --git a/docs/release-notes/release-notes-0.15.1.md b/docs/release-notes/release-notes-0.15.1.md index 976e1f33d..a106c621a 100644 --- a/docs/release-notes/release-notes-0.15.1.md +++ b/docs/release-notes/release-notes-0.15.1.md @@ -11,6 +11,12 @@ binary digest to be different whether that folder exists or not](https://github.com/lightningnetwork/lnd/pull/6676). +## Taproot + +[`lnd` will now refuse to start if it detects the full node backned does not +support Tapoot](https://github.com/lightningnetwork/lnd/pull/6798). + + ## `lncli` * [Add `payment_addr` flag to