Skip to content

Commit

Permalink
multi: add more bitcoind versions to the BackendVersion
Browse files Browse the repository at this point in the history
This commit adds bitcoind version 22.0 and 25.0 to our `BackendVersion`
set to handle the `testmempoolaccept` RPC calls. A unit test is added to
make sure the parser works as expected.
  • Loading branch information
yyforyongyu authored and kcalvinalvin committed Nov 5, 2024
1 parent 511078b commit bbfa799
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 31 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/davecgh/go-spew v1.1.1
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1
github.com/decred/dcrd/lru v1.0.0
github.com/gorilla/websocket v1.5.0
github.com/jessevdk/go-flags v1.4.0
github.com/jrick/logrotate v1.0.0
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23
Expand Down
16 changes: 2 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,6 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/utreexo/utreexo v0.0.0-20240130053814-4aa282fe3804 h1:9uJDD7lEbhQ/JQhdIPVJ2yk8tLh8nvwNz87shyUe+RQ=
github.com/utreexo/utreexo v0.0.0-20240130053814-4aa282fe3804/go.mod h1:RT9JpZADhLr2YJVBgp48tmUxVeAHaAbOSr6p6nAEJpI=
github.com/utreexo/utreexo v0.0.0-20240207085148-754fd0816976 h1:1r3hZAaf7zhLd/hT4wYB8PkYOLylgCDlJaxS8MRitZA=
github.com/utreexo/utreexo v0.0.0-20240207085148-754fd0816976/go.mod h1:RT9JpZADhLr2YJVBgp48tmUxVeAHaAbOSr6p6nAEJpI=
github.com/utreexo/utreexo v0.1.0 h1:ddbIk/yU7sqZ/7Q2XoZhaeWqMBRwhHXaoFRvKYx7uLo=
github.com/utreexo/utreexo v0.1.0/go.mod h1:RT9JpZADhLr2YJVBgp48tmUxVeAHaAbOSr6p6nAEJpI=
github.com/utreexo/utreexo v0.1.2 h1:KLC8rlwPep3w9sYapEgDROYUBNmLzsO5aTPTorBJhJc=
github.com/utreexo/utreexo v0.1.2/go.mod h1:RT9JpZADhLr2YJVBgp48tmUxVeAHaAbOSr6p6nAEJpI=
github.com/utreexo/utreexo v0.1.3 h1:Z7tj8DTZNHd927ZWT7NSKx14+Dk6BoMeDPhDOmFlibo=
github.com/utreexo/utreexo v0.1.3/go.mod h1:RT9JpZADhLr2YJVBgp48tmUxVeAHaAbOSr6p6nAEJpI=
github.com/utreexo/utreexo v0.1.4 h1:jygjZscJEzab7woP7aB6YWUKjhsV5Mrbjj873inhwR8=
github.com/utreexo/utreexo v0.1.4/go.mod h1:RT9JpZADhLr2YJVBgp48tmUxVeAHaAbOSr6p6nAEJpI=
github.com/utreexo/utreexo v0.1.5 h1:nnG2VvwDYPkXCSRicV15eAbh2vvTp/g4Pot3vlseGdQ=
github.com/utreexo/utreexo v0.1.5/go.mod h1:RT9JpZADhLr2YJVBgp48tmUxVeAHaAbOSr6p6nAEJpI=
github.com/utreexo/utreexo v0.2.1 h1:xycdaHK+HhDZO5MY6Clq7YeXEDguzar1GrAYqIJ1gvs=
github.com/utreexo/utreexo v0.2.1/go.mod h1:xIu3cTtT0jNdntc1qJhVyQV/RX03Sk9gFD3UAzALvuU=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
Expand All @@ -113,6 +99,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand All @@ -129,6 +116,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
Expand Down
7 changes: 3 additions & 4 deletions rpcclient/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,17 +440,16 @@ func unmarshalPartialGetBlockChainInfoResult(res []byte) (*btcjson.GetBlockChain
func unmarshalGetBlockChainInfoResultSoftForks(chainInfo *btcjson.GetBlockChainInfoResult,
version BackendVersion, res []byte) error {

switch version {
// Versions of bitcoind on or after v0.19.0 use the unified format.
case BitcoindPost19:
if version > BitcoindPre19 {
var softForks btcjson.UnifiedSoftForks
if err := json.Unmarshal(res, &softForks); err != nil {
return err
}
chainInfo.UnifiedSoftForks = &softForks
} else {

// All other versions use the original format.
default:
// All other versions use the original format.
var softForks btcjson.SoftForks
if err := json.Unmarshal(res, &softForks); err != nil {
return err
Expand Down
14 changes: 10 additions & 4 deletions rpcclient/chain_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package rpcclient

import "testing"
import (
"testing"

"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{}

// TestUnmarshalGetBlockChainInfoResult ensures that the SoftForks and
// UnifiedSoftForks fields of GetBlockChainInfoResult are properly unmarshaled
Expand All @@ -22,7 +28,7 @@ func TestUnmarshalGetBlockChainInfoResultSoftForks(t *testing.T) {
},
{
name: "bitcoind >= 0.19.0 with separate softforks",
version: BitcoindPost19,
version: BitcoindPre22,
res: []byte(`{"softforks": [{"version": 2}]}`),
compatible: false,
},
Expand All @@ -34,7 +40,7 @@ func TestUnmarshalGetBlockChainInfoResultSoftForks(t *testing.T) {
},
{
name: "bitcoind >= 0.19.0 with unified softforks",
version: BitcoindPost19,
version: BitcoindPre22,
res: []byte(`{"softforks": {"segwit": {"type": "bip9"}}}`),
compatible: true,
},
Expand Down Expand Up @@ -76,7 +82,7 @@ func TestUnmarshalGetBlockChainInfoResultSoftForks(t *testing.T) {

// If the version is compatible with the response, we
// should expect to see the proper softforks field set.
if test.version == BitcoindPost19 &&
if test.version == BitcoindPre22 &&
info.SoftForks != nil {
t.Fatal("expected SoftForks to be empty")
}
Expand Down
52 changes: 48 additions & 4 deletions rpcclient/infrastructure.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,45 @@ const (
// BitcoindPre19 represents a bitcoind version before 0.19.0.
BitcoindPre19 BackendVersion = iota

// BitcoindPost19 represents a bitcoind version equal to or greater than
// 0.19.0.
BitcoindPost19
// BitcoindPre22 represents a bitcoind version equal to or greater than
// 0.19.0 and smaller than 22.0.0.
BitcoindPre22

// BitcoindPre25 represents a bitcoind version equal to or greater than
// 22.0.0 and smaller than 25.0.0.
BitcoindPre25

// BitcoindPre25 represents a bitcoind version equal to or greater than
// 25.0.0.
BitcoindPost25

// Btcd represents a catch-all btcd version.
Btcd
)

// String returns a human-readable backend version.
func (b BackendVersion) String() string {
switch b {
case BitcoindPre19:
return "bitcoind 0.19 and below"

case BitcoindPre22:
return "bitcoind v0.19.0-v22.0.0"

case BitcoindPre25:
return "bitcoind v22.0.0-v25.0.0"

case BitcoindPost25:
return "bitcoind v25.0.0 and above"

case Btcd:
return "btcd"

default:
return "unknown"
}
}

// Client represents a Bitcoin RPC client which allows easy access to the
// various RPC methods available on a Bitcoin RPC server. Each of the wrapper
// functions handle the details of converting the passed and return types to and
Expand Down Expand Up @@ -1544,6 +1575,12 @@ const (
// bitcoind19Str is the string representation of bitcoind v0.19.0.
bitcoind19Str = "0.19.0"

// bitcoind22Str is the string representation of bitcoind v22.0.0.
bitcoind22Str = "22.0.0"

// bitcoind25Str is the string representation of bitcoind v25.0.0.
bitcoind25Str = "25.0.0"

// bitcoindVersionPrefix specifies the prefix included in every bitcoind
// version exposed through GetNetworkInfo.
bitcoindVersionPrefix = "/Satoshi:"
Expand All @@ -1565,8 +1602,15 @@ func parseBitcoindVersion(version string) BackendVersion {
switch {
case version < bitcoind19Str:
return BitcoindPre19

case version < bitcoind22Str:
return BitcoindPre22

case version < bitcoind25Str:
return BitcoindPre25

default:
return BitcoindPost19
return BitcoindPost25
}
}

Expand Down
64 changes: 64 additions & 0 deletions rpcclient/infrastructure_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package rpcclient

import (
"testing"

"github.com/stretchr/testify/require"
)

// TestParseBitcoindVersion checks that the correct version from bitcoind's
// `getnetworkinfo` RPC call is parsed.
func TestParseBitcoindVersion(t *testing.T) {
t.Parallel()

testCases := []struct {
name string
rpcVersion string
parsedVersion BackendVersion
}{
{
name: "parse version 0.19 and below",
rpcVersion: "/Satoshi:0.18.0/",
parsedVersion: BitcoindPre19,
},
{
name: "parse version 0.19",
rpcVersion: "/Satoshi:0.19.0/",
parsedVersion: BitcoindPre22,
},
{
name: "parse version 0.19 - 22.0",
rpcVersion: "/Satoshi:0.20.1/",
parsedVersion: BitcoindPre22,
},
{
name: "parse version 22.0",
rpcVersion: "/Satoshi:22.0.0/",
parsedVersion: BitcoindPre25,
},
{
name: "parse version 22.0 - 25.0",
rpcVersion: "/Satoshi:23.0.0/",
parsedVersion: BitcoindPre25,
},
{
name: "parse version 25.0",
rpcVersion: "/Satoshi:25.0.0/",
parsedVersion: BitcoindPost25,
},
{
name: "parse version 25.0 and above",
rpcVersion: "/Satoshi:26.0.0/",
parsedVersion: BitcoindPost25,
},
}

for _, tc := range testCases {
tc := tc

t.Run(tc.name, func(t *testing.T) {
version := parseBitcoindVersion(tc.rpcVersion)
require.Equal(t, tc.parsedVersion, version)
})
}
}
8 changes: 3 additions & 5 deletions rpcclient/rawtransactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,19 +359,17 @@ func (c *Client) SendRawTransactionAsync(tx *wire.MsgTx, allowHighFees bool) Fut
}

var cmd *btcjson.SendRawTransactionCmd
switch version {
// Starting from bitcoind v0.19.0, the MaxFeeRate field should be used.
case BitcoindPost19:
if version > BitcoindPre19 {
// Using a 0 MaxFeeRate is interpreted as a maximum fee rate not
// being enforced by bitcoind.
var maxFeeRate int32
if !allowHighFees {
maxFeeRate = defaultMaxFeeRate
}
cmd = btcjson.NewBitcoindSendRawTransactionCmd(txHex, maxFeeRate)

// Otherwise, use the AllowHighFees field.
default:
} else {
// Otherwise, use the AllowHighFees field.
cmd = btcjson.NewSendRawTransactionCmd(txHex, &allowHighFees)
}

Expand Down

0 comments on commit bbfa799

Please sign in to comment.