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]: https://github.com/bitcoin/bitcoin/pull/23508
[2]: https://github.com/bitcoin/bitcoin/pull/25114
Fixes #6773
2022-08-05 04:55:10 +02:00
|
|
|
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.
|
2022-08-13 00:29:54 +02:00
|
|
|
switch {
|
|
|
|
// Bitcoind versions before 0.19 and also btcd use the
|
|
|
|
// SoftForks fields.
|
|
|
|
case chainInfo.SoftForks != nil:
|
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]: https://github.com/bitcoin/bitcoin/pull/23508
[2]: https://github.com/bitcoin/bitcoin/pull/25114
Fixes #6773
2022-08-05 04:55:10 +02:00
|
|
|
_, ok := chainInfo.SoftForks.Bip9SoftForks["taproot"]
|
|
|
|
if ok {
|
|
|
|
return ok
|
|
|
|
}
|
2022-08-13 00:29:54 +02:00
|
|
|
|
|
|
|
// Bitcoind versions after 0.19 will use the UnifiedSoftForks
|
|
|
|
// field that factors in the set of "buried" soft forks.
|
|
|
|
case chainInfo.UnifiedSoftForks != nil:
|
|
|
|
_, ok := chainInfo.UnifiedSoftForks.SoftForks["taproot"]
|
|
|
|
if ok {
|
|
|
|
return ok
|
|
|
|
}
|
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]: https://github.com/bitcoin/bitcoin/pull/23508
[2]: https://github.com/bitcoin/bitcoin/pull/25114
Fixes #6773
2022-08-05 04:55:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|