diff --git a/chain/bitcoind_client.go b/chain/bitcoind_client.go index d8326acd1d..e10fd2ce82 100644 --- a/chain/bitcoind_client.go +++ b/chain/bitcoind_client.go @@ -233,6 +233,15 @@ func (c *BitcoindClient) MapRPCErr(rpcErr error) error { } } + // Perhaps the backend is a newer version of bitcoind, try to match it + // against the v28.0 and later errors. + for btcdErr, matchedErr := range Bitcoind28ErrMap { + // Match it against btcd's error. + if matchErrStr(rpcErr, btcdErr) { + return matchedErr + } + } + // If not matched, return the original error wrapped. return fmt.Errorf("%w: %v", ErrUndefined, rpcErr) } diff --git a/chain/errors.go b/chain/errors.go index 6302ad6ccf..159ec4125e 100644 --- a/chain/errors.go +++ b/chain/errors.go @@ -337,6 +337,14 @@ func (r RPCErr) Error() string { return "unknown error" } +// Bitcoind28ErrMap contains error messages from bitcoind version v28.0 (and +// later) that are returned from the `testmempoolaccept` and are different than +// in previous versions. +var Bitcoind28ErrMap = map[string]error{ + // https://github.com/bitcoin/bitcoin/pull/30212 + "transaction outputs already in utxo set": ErrTxAlreadyConfirmed, +} + // 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`