mirror of
https://github.com/btcsuite/btcd.git
synced 2024-11-19 01:40:07 +01:00
multi: turn BackendVersion
into an interface
This commit adds a new interface, `BackendVersion`, to support checking versions for multiple both btcd and bitcoind. Once neutrino version is also pinned here, it should also be checked.
This commit is contained in:
parent
9e6070a707
commit
4cf49bd72c
@ -2,13 +2,32 @@ package rpcclient
|
||||
|
||||
import "strings"
|
||||
|
||||
// BackendVersion represents the version of the backend the client is currently
|
||||
// connected to.
|
||||
type BackendVersion uint8
|
||||
// BackendVersion defines an interface to handle the version of the backend
|
||||
// used by the client.
|
||||
type BackendVersion interface {
|
||||
// String returns a human-readable backend version.
|
||||
String() string
|
||||
|
||||
// SupportUnifiedSoftForks returns true if the backend supports the
|
||||
// unified softforks format.
|
||||
SupportUnifiedSoftForks() bool
|
||||
|
||||
// SupportTestMempoolAccept returns true if the backend supports the
|
||||
// testmempoolaccept RPC.
|
||||
SupportTestMempoolAccept() bool
|
||||
|
||||
// SupportGetTxSpendingPrevOut returns true if the backend supports the
|
||||
// gettxspendingprevout RPC.
|
||||
SupportGetTxSpendingPrevOut() bool
|
||||
}
|
||||
|
||||
// BitcoindVersion represents the version of the bitcoind the client is
|
||||
// currently connected to.
|
||||
type BitcoindVersion uint8
|
||||
|
||||
const (
|
||||
// BitcoindPre19 represents a bitcoind version before 0.19.0.
|
||||
BitcoindPre19 BackendVersion = iota
|
||||
BitcoindPre19 BitcoindVersion = iota
|
||||
|
||||
// BitcoindPre22 represents a bitcoind version equal to or greater than
|
||||
// 0.19.0 and smaller than 22.0.0.
|
||||
@ -28,7 +47,7 @@ const (
|
||||
)
|
||||
|
||||
// String returns a human-readable backend version.
|
||||
func (b BackendVersion) String() string {
|
||||
func (b BitcoindVersion) String() string {
|
||||
switch b {
|
||||
case BitcoindPre19:
|
||||
return "bitcoind 0.19 and below"
|
||||
@ -50,6 +69,29 @@ func (b BackendVersion) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
// SupportUnifiedSoftForks returns true if the backend supports the unified
|
||||
// softforks format.
|
||||
func (b BitcoindVersion) SupportUnifiedSoftForks() bool {
|
||||
// Versions of bitcoind on or after v0.19.0 use the unified format.
|
||||
return b > BitcoindPre19
|
||||
}
|
||||
|
||||
// SupportTestMempoolAccept returns true if bitcoind version is 22.0.0 or
|
||||
// above.
|
||||
func (b BitcoindVersion) SupportTestMempoolAccept() bool {
|
||||
return b > BitcoindPre22
|
||||
}
|
||||
|
||||
// SupportGetTxSpendingPrevOut returns true if bitcoind version is 24.0.0 or
|
||||
// above.
|
||||
func (b BitcoindVersion) SupportGetTxSpendingPrevOut() bool {
|
||||
return b > BitcoindPre24
|
||||
}
|
||||
|
||||
// Compile-time checks to ensure that BitcoindVersion satisfy the
|
||||
// BackendVersion interface.
|
||||
var _ BackendVersion = BitcoindVersion(0)
|
||||
|
||||
const (
|
||||
// bitcoind19Str is the string representation of bitcoind v0.19.0.
|
||||
bitcoind19Str = "0.19.0"
|
||||
@ -74,7 +116,7 @@ const (
|
||||
|
||||
// parseBitcoindVersion parses the bitcoind version from its string
|
||||
// representation.
|
||||
func parseBitcoindVersion(version string) BackendVersion {
|
||||
func parseBitcoindVersion(version string) BitcoindVersion {
|
||||
// Trim the version of its prefix and suffix to determine the
|
||||
// appropriate version number.
|
||||
version = strings.TrimPrefix(
|
||||
@ -127,6 +169,28 @@ func (b BtcdVersion) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
// SupportUnifiedSoftForks returns true if the backend supports the unified
|
||||
// softforks format.
|
||||
//
|
||||
// NOTE: always true for btcd as we didn't track it before.
|
||||
func (b BtcdVersion) SupportUnifiedSoftForks() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SupportTestMempoolAccept returns true if btcd version is 24.1.0 or above.
|
||||
func (b BtcdVersion) SupportTestMempoolAccept() bool {
|
||||
return b > BtcdPre2401
|
||||
}
|
||||
|
||||
// SupportGetTxSpendingPrevOut returns true if btcd version is 24.1.0 or above.
|
||||
func (b BtcdVersion) SupportGetTxSpendingPrevOut() bool {
|
||||
return b > BtcdPre2401
|
||||
}
|
||||
|
||||
// Compile-time checks to ensure that BtcdVersion satisfy the BackendVersion
|
||||
// interface.
|
||||
var _ BackendVersion = BtcdVersion(0)
|
||||
|
||||
const (
|
||||
// btcd2401Val is the int representation of btcd v0.24.1.
|
||||
btcd2401Val = 240100
|
||||
|
@ -14,7 +14,7 @@ func TestParseBitcoindVersion(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
rpcVersion string
|
||||
parsedVersion BackendVersion
|
||||
parsedVersion BitcoindVersion
|
||||
}{
|
||||
{
|
||||
name: "parse version 0.19 and below",
|
||||
@ -104,3 +104,45 @@ func TestParseBtcdVersion(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestVersionSupports checks all the versions of bitcoind and btcd to ensure
|
||||
// that the RPCs are supported correctly.
|
||||
func TestVersionSupports(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := require.New(t)
|
||||
|
||||
// For bitcoind, unified softforks format is supported in 19.0 and
|
||||
// above.
|
||||
require.False(BitcoindPre19.SupportUnifiedSoftForks())
|
||||
require.True(BitcoindPre22.SupportUnifiedSoftForks())
|
||||
require.True(BitcoindPre24.SupportUnifiedSoftForks())
|
||||
require.True(BitcoindPre25.SupportUnifiedSoftForks())
|
||||
require.True(BitcoindPost25.SupportUnifiedSoftForks())
|
||||
|
||||
// For bitcoind, `testmempoolaccept` is supported in 22.0 and above.
|
||||
require.False(BitcoindPre19.SupportTestMempoolAccept())
|
||||
require.False(BitcoindPre22.SupportTestMempoolAccept())
|
||||
require.True(BitcoindPre24.SupportTestMempoolAccept())
|
||||
require.True(BitcoindPre25.SupportTestMempoolAccept())
|
||||
require.True(BitcoindPost25.SupportTestMempoolAccept())
|
||||
|
||||
// For bitcoind, `gettxspendingprevout` is supported in 24.0 and above.
|
||||
require.False(BitcoindPre19.SupportGetTxSpendingPrevOut())
|
||||
require.False(BitcoindPre22.SupportGetTxSpendingPrevOut())
|
||||
require.False(BitcoindPre24.SupportGetTxSpendingPrevOut())
|
||||
require.True(BitcoindPre25.SupportGetTxSpendingPrevOut())
|
||||
require.True(BitcoindPost25.SupportGetTxSpendingPrevOut())
|
||||
|
||||
// For btcd, unified softforks format is supported in all versions.
|
||||
require.True(BtcdPre2401.SupportUnifiedSoftForks())
|
||||
require.True(BtcdPost2401.SupportUnifiedSoftForks())
|
||||
|
||||
// For btcd, `testmempoolaccept` is supported in 24.1 and above.
|
||||
require.False(BtcdPre2401.SupportTestMempoolAccept())
|
||||
require.True(BtcdPost2401.SupportTestMempoolAccept())
|
||||
|
||||
// For btcd, `gettxspendingprevout` is supported in 24.1 and above.
|
||||
require.False(BtcdPre2401.SupportGetTxSpendingPrevOut())
|
||||
require.True(BtcdPost2401.SupportGetTxSpendingPrevOut())
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ func unmarshalGetBlockChainInfoResultSoftForks(chainInfo *btcjson.GetBlockChainI
|
||||
version BackendVersion, res []byte) error {
|
||||
|
||||
// Versions of bitcoind on or after v0.19.0 use the unified format.
|
||||
if version > BitcoindPre19 {
|
||||
if version.SupportUnifiedSoftForks() {
|
||||
var softForks btcjson.UnifiedSoftForks
|
||||
if err := json.Unmarshal(res, &softForks); err != nil {
|
||||
return err
|
||||
|
@ -134,7 +134,7 @@ type Client struct {
|
||||
// backendVersion is the version of the backend the client is currently
|
||||
// connected to. This should be retrieved through GetVersion.
|
||||
backendVersionMu sync.Mutex
|
||||
backendVersion *BackendVersion
|
||||
backendVersion BackendVersion
|
||||
|
||||
// mtx is a mutex to protect access to connection related fields.
|
||||
mtx sync.Mutex
|
||||
@ -1577,7 +1577,7 @@ func (c *Client) BackendVersion() (BackendVersion, error) {
|
||||
defer c.backendVersionMu.Unlock()
|
||||
|
||||
if c.backendVersion != nil {
|
||||
return *c.backendVersion, nil
|
||||
return c.backendVersion, nil
|
||||
}
|
||||
|
||||
// We'll start by calling GetInfo. This method doesn't exist for
|
||||
@ -1589,20 +1589,20 @@ func (c *Client) BackendVersion() (BackendVersion, error) {
|
||||
// Parse the btcd version and cache it.
|
||||
case nil:
|
||||
log.Debugf("Detected btcd version: %v", info.Version)
|
||||
version := Btcd
|
||||
c.backendVersion = &version
|
||||
return *c.backendVersion, nil
|
||||
version := parseBtcdVersion(info.Version)
|
||||
c.backendVersion = version
|
||||
return c.backendVersion, nil
|
||||
|
||||
// Inspect the RPC error to ensure the method was not found, otherwise
|
||||
// we actually ran into an error.
|
||||
case *btcjson.RPCError:
|
||||
if err.Code != btcjson.ErrRPCMethodNotFound.Code {
|
||||
return 0, fmt.Errorf("unable to detect btcd version: "+
|
||||
return nil, fmt.Errorf("unable to detect btcd version: "+
|
||||
"%v", err)
|
||||
}
|
||||
|
||||
default:
|
||||
return 0, fmt.Errorf("unable to detect btcd version: %v", err)
|
||||
return nil, fmt.Errorf("unable to detect btcd version: %v", err)
|
||||
}
|
||||
|
||||
// Since the GetInfo method was not found, we assume the client is
|
||||
@ -1610,7 +1610,8 @@ func (c *Client) BackendVersion() (BackendVersion, error) {
|
||||
// GetNetworkInfo.
|
||||
networkInfo, err := c.GetNetworkInfo()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("unable to detect bitcoind version: %v", err)
|
||||
return nil, fmt.Errorf("unable to detect bitcoind version: %v",
|
||||
err)
|
||||
}
|
||||
|
||||
// Parse the bitcoind version and cache it.
|
||||
@ -1618,7 +1619,7 @@ func (c *Client) BackendVersion() (BackendVersion, error) {
|
||||
version := parseBitcoindVersion(networkInfo.SubVersion)
|
||||
c.backendVersion = &version
|
||||
|
||||
return *c.backendVersion, nil
|
||||
return c.backendVersion, nil
|
||||
}
|
||||
|
||||
func (c *Client) sendAsync() FutureGetBulkResult {
|
||||
|
@ -360,7 +360,9 @@ func (c *Client) SendRawTransactionAsync(tx *wire.MsgTx, allowHighFees bool) Fut
|
||||
|
||||
var cmd *btcjson.SendRawTransactionCmd
|
||||
// Starting from bitcoind v0.19.0, the MaxFeeRate field should be used.
|
||||
if version > BitcoindPre19 {
|
||||
//
|
||||
// When unified softforks format is supported, it's 0.19 and above.
|
||||
if version.SupportUnifiedSoftForks() {
|
||||
// Using a 0 MaxFeeRate is interpreted as a maximum fee rate not
|
||||
// being enforced by bitcoind.
|
||||
var maxFeeRate int32
|
||||
@ -943,7 +945,7 @@ func (c *Client) TestMempoolAcceptAsync(txns []*wire.MsgTx,
|
||||
//
|
||||
// We decide to not support this call for versions below 22.0.0. as the
|
||||
// request/response formats are very different.
|
||||
if version < BitcoindPre22 {
|
||||
if !version.SupportTestMempoolAccept() {
|
||||
err := fmt.Errorf("%w: %v", ErrBitcoindVersion, version)
|
||||
return newFutureError(err)
|
||||
}
|
||||
@ -1057,7 +1059,7 @@ func (c *Client) GetTxSpendingPrevOutAsync(
|
||||
log.Debugf("GetTxSpendingPrevOutAsync: backend version %s", version)
|
||||
|
||||
// Exit early if the version is below 24.0.0.
|
||||
if version < BitcoindPre24 {
|
||||
if !version.SupportGetTxSpendingPrevOut() {
|
||||
err := fmt.Errorf("%w: %v", ErrBitcoindVersion, version)
|
||||
return newFutureError(err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user