From 178e7354a3085ffff55a3d2a6d6798e9db87582f Mon Sep 17 00:00:00 2001 From: yyforyongyu Date: Wed, 3 Jul 2024 23:01:29 +0800 Subject: [PATCH] chain: match errors from `btcd pre-v0.24.2` --- chain/btcd.go | 30 ++++++++++++++++++++++++++++++ chain/errors.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/chain/btcd.go b/chain/btcd.go index 4d9763d249..4851572dae 100644 --- a/chain/btcd.go +++ b/chain/btcd.go @@ -593,6 +593,36 @@ func (c *RPCClient) MapRPCErr(rpcErr error) error { } } + // If no matching error is found, we try to match it to an older + // version of `btcd`. + // + // Get the backend's version. + backend, bErr := c.BackendVersion() + if bErr != nil { + // If there's an error getting the backend version, we return + // the original error and the backend error. + return fmt.Errorf("%w: %v, failed to get backend version %v", + ErrUndefined, rpcErr, bErr) + } + + // If this version doesn't support `testmempoolaccept`, it must be + // below v0.24.2. In this case, we will match the errors defined in + // pre-v0.24.2. + // + // NOTE: `testmempoolaccept` is implemented in v0.24.1, but this + // version was never tagged, which means it must be v0.24.2 when it's + // supported. + if !backend.SupportTestMempoolAccept() { + // If the backend is older than v0.24.2, we will try to match + // the error to the older version of `btcd`. + for btcdErr, matchedErr := range BtcdErrMapPre2402 { + // 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 b71241d681..6302ad6ccf 100644 --- a/chain/errors.go +++ b/chain/errors.go @@ -477,6 +477,52 @@ var BtcdErrMap = map[string]error{ "max-fee-exceeded": ErrMaxFeeExceeded, } +// BtcdErrMapPre2402 defines the error mapping for btcd versions prior to +// 0.24.2 - all the errors changed in this commit have been defined here to +// support older versions: +// - https://github.com/btcsuite/btcd/pull/2053/commits/ef54c49df443815d50765e8c4f31a87944d950a6 +var BtcdErrMapPre2402 = map[string]error{ + // A transaction with too large output value. + "is higher than max allowed value": ErrLargeOutput, + + // A transaction that conflicts with an unconfirmed tx. Happens when + // RBF is not enabled. + "already spent by transaction": ErrMempoolConflict, + + // When a transaction causes too many transactions being replaced. This + // is set by `MAX_REPLACEMENT_CANDIDATES` in `bitcoind` and defaults to + // 100. + "evicts more transactions than permitted": ErrTooManyReplacements, + + // A transaction that spends conflicting tx outputs that are rejected. + "spends parent transaction": ErrConflictingTx, + + // BIP125 related errors. + // + // When fee rate used or fees paid doesn't meet the requirements. + "has an insufficient fee rate": ErrInsufficientFee, + "has an insufficient absolute fee": ErrInsufficientFee, + + // A transaction in the mempool. + "already have transaction": ErrTxAlreadyInMempool, + + // A coinbase transaction. + "is an individual coinbase": ErrCoinbaseTx, + + // A transaction already in the blockchain. + "transaction already exists": ErrTxAlreadyConfirmed, + + // Some nonstandard transactions - too large tx size. + "is larger than max allowed weight of": ErrTxTooLarge, + + // Some nonstandard transactions - too large scriptSig (>1650 + // bytes). + "bytes is larger than max allowed size of": ErrScriptSigSize, + + // Some nonstandard transactions - output too small. + "is dust": ErrDust, +} + // matchErrStr takes an error returned from RPC client and matches it against // the specified string. If the expected string pattern is found in the error // passed, return true. Both the error strings are normalized before matching.