rpcclient: add bitcoind version dependent error matching

Fixes #2404.
If different versions of bitcoind return different error strings, we
need a way to match those as well.
This commit is contained in:
Oliver Gugger 2025-08-15 08:37:51 +02:00
parent baebb836c2
commit ffcda0f629
No known key found for this signature in database
GPG key ID: 8E4256593F177720
2 changed files with 35 additions and 1 deletions

View file

@ -338,6 +338,23 @@ func (r BitcoindRPCErr) Error() string {
return "unknown error"
}
// BitcoindErrMap is a map of additional errors bitcoind can throw that are
// version dependent (e.g. versions up to v29 return the error as specified in
// `Error()` above, while versions v30 and beyond return the error as mapped
// here. We add a new map for errors that were simply renamed but have the same
// semantic meaning. New errors should be added above as new error constants.
var BitcoindErrMap = map[string]error{
// The error message was changed in
// https://github.com/bitcoin/bitcoin/pull/33050 which will be included
// in bitcoind v30.0 and beyond.
"mempool script verify flag failed": ErrNonMandatoryScriptVerifyFlag,
// The error message was changed in
// https://github.com/bitcoin/bitcoin/pull/33183 which will also be
// included in bitcoind v30.0 and beyond.
"block script verify flag failed": ErrScriptVerifyFlag,
}
// BtcdErrMap takes the errors returned from btcd's `testmempoolaccept` and
// `sendrawtransaction` RPCs and map them to the errors defined above, which
// are results from calling either `testmempoolaccept` or `sendrawtransaction`
@ -480,7 +497,7 @@ var BtcdErrMap = map[string]error{
//
// NOTE: we assume neutrino shares the same error strings as btcd.
func MapRPCErr(rpcErr error) error {
// Iterate the map and find the matching error.
// Iterate the btcd error map and find the matching error.
for btcdErr, err := range BtcdErrMap {
// Match it against btcd's error first.
if matchErrStr(rpcErr, btcdErr) {
@ -488,6 +505,15 @@ func MapRPCErr(rpcErr error) error {
}
}
// Also check the bitcoind error map, which is used for bitcoind version
// dependent errors.
for bitcoindErr, err := range BitcoindErrMap {
// Match it against bitcoind's error.
if matchErrStr(rpcErr, bitcoindErr) {
return err
}
}
// If not found, try to match it against bitcoind's error.
for i := uint32(0); i < uint32(errSentinel); i++ {
err := BitcoindRPCErr(i)

View file

@ -61,6 +61,14 @@ func TestMatchErrStr(t *testing.T) {
matchStr: "missingorspent",
matched: false,
},
{
name: "new bitcoind v30 error",
bitcoindErr: errors.New(
"mempool-script-verify-flag-failed",
),
matchStr: "mempool script verify flag failed",
matched: true,
},
}
for _, tc := range testCases {