-
Notifications
You must be signed in to change notification settings - Fork 592
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add err match in the package chain
#937
Conversation
2bc65fd
to
6e238fd
Compare
This commit moves the defined errors from [btcd/rpcclient/errors.go](https://github.com/btcsuite/btcd/blob/d881c686e61db35e332fb0309178152dac589b03/rpcclient/errors.go) to here so it's easier to manage error matching for different backends.
ecd01d4
to
bc151ce
Compare
cc @bhandras for review |
cc: @ziggie1984 for review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🧇
chain/btcd.go
Outdated
|
||
// 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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: it could be slightly cleaner if we move this loop inside if !backend.SupportTestMempoolAccept()
so that if the version is >= v0.24.2 we just return the error at the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah was thinking about not nesting if
s, but I guess it's cleaner so now changed.
bc151ce
to
178e735
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good thank you for this fix, had some questions.
chain/bitcoind_client.go
Outdated
} | ||
|
||
// MapRPCErr takes an error returned from calling RPC methods from various | ||
// chain backend and map it to an defined error here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: various chain backends
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool fixed
chain/neutrino.go
Outdated
@@ -815,3 +815,22 @@ out: | |||
close(s.dequeueNotification) | |||
s.wg.Done() | |||
} | |||
|
|||
// MapRPCErr takes an error returned from calling RPC methods from various | |||
// chain backend and map it to an defined error here. It uses the `BtcdErrMap`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: and maps it (because it relates to the error ?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea totally, now fixed!
@@ -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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: Why did we remove this errors for the newest versions ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they are not removed, instead, in this commit they are changed so it's easier to do error matching, as they are more "unique".
// - https://github.com/bitcoin/bitcoin/blob/master/test/functional/mempool_dust.py | ||
// - https://github.com/bitcoin/bitcoin/blob/master/test/functional/mempool_limit.py | ||
// - https://github.com/bitcoin/bitcoin/blob/master/src/validation.cpp | ||
func (r RPCErr) Error() string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: I wonder why we don't name this error in particular bitcoind error, because it reflects the errors of this particular backend ? Calling it rpcerr, I always think this is a generalized error ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah originally it was named BitcoindRPCErr
, but in reality this functions as the generalized error - when we use it in lnd
, we don't check for backends, but just check against, say, chain.ErrMempoolConflict
.
Ideally, we can define another set of errors and put them in a map similar to BtcdErrMap
, keyed by the error string returned from bitcoind
and valued by the RPCErr
, which brings more symmetry. However, unless we have a very different error string returned from the chain
, there's no point in doing so as in the current design, we always use the error string defined in bitcoind
. In other words, this Error()
needs to return something that's human-readable, and we decide to use the error string from bitcoind
.
// are results from calling either `testmempoolaccept` or `sendrawtransaction` | ||
// in `bitcoind`. | ||
// | ||
// Errors not mapped in `btcd`: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: Do you mean these are particular btcd errros which exist only in btcd or the other way around ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so these errors can be returned from btcd
, but they are not mapped. so yeah they only exist in btcd
.
// `CheckTransactionInputs`. | ||
// - errors from `CalcSequenceLock`. | ||
// | ||
// NOTE: This is not an exhaustive list of errors, but it covers the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I am still a bit surprised why we are moving the error definition to the btcwallet pkg, imo they fit better into the btcd pkg, especially the btcd errors should be defined there anyways because its the official client?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO it's better here. First of all, this set of newly defined error types are not btcd
errors, they are RPC errors, returned by either calling sendrawtransaction
or in the reject-reason
field in a response returned by testmempoolaccept
. When in lnd
, we don't care about the specific backend, rather, we just want to get a defined error and act on it.
This means whether it's btcd
, bitcoind
, or neutrino
, we should have a place to catch the implementation-specific errors, and "translate" them into a uniformized RPC error. chain
is a good place to perform this task as it acts like a backend-multiplexer - it provides a standardized interface chain.Interface
, and handles the implementation-specific logic here.
On the other hand, btcd
should just be, well, btcd
, an independent implementation, that's oblivious about how neutrino
or bitcoind
handles stuff, which is why in addition to this error handling, I also think the btcd/rpcclient
should be moved here. The overall design is, that btcwallet
provides multi-backend handling, and btcd
just being a protocol implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great explanation thank you
} | ||
|
||
// If not matched, return the original error wrapped. | ||
return fmt.Errorf("%w: %v", ErrUndefined, rpcErr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: Shouldn't we wrap it the other way around or even both ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ErrUndefined
is the defined type tho, so in lnd
when we see chain.ErrUndefined
we know it's an undefined error. On the other hand rpcErr
won't have a type in this case, also we cannot use more than one %w
in fmt.Errorf
unfortunately.
This commit adds a new interface method `MapRPCErr` and use it in `TestMempoolAccept` and `SendRawTransaction`.
178e735
to
1f08d12
Compare
1f08d12
to
a90a3ec
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🔥
Implemented the idea suggested by @Roasbeef here, we now handle the error mapping separately.
I really like this approach, as the chain backend handling is now independent of
btcd
. Image a case wherebitcoind
updates its error str someday, instead of going through the update chainbtcd -> btcwallet -> lnd
, we can now just update viabtcwallet -> lnd
. Think it's also nice to moverpcclient
tobtcwallet
since it's a chain backend multiplexer, future PR tho.The original PR when this was added to btcd: btcsuite/btcd#2138