Skip to content

Conversation

jtobin
Copy link
Member

@jtobin jtobin commented Aug 25, 2025

Adds some structure to price oracle error codes, along with some custom handling for them. In particular, a code of '1' now corresponds to an 'unsupported asset' error, which, considered a 'public' error, is forwarded in the customizable message field of the reject messages sent to peers. An error with any other code continues, at present, to be treated as an unspecified error.

Resolves #1749, #1326.

(This is a refinement over the closed #1751, which forwarded errors indiscriminately.)

ErrRejectWithCustomMsg constructs a RejectErr with error code 0 and the
specified error message.
@jtobin jtobin requested review from ffranr and GeorgeTsagk August 25, 2025 11:28
@jtobin jtobin added error handling RFQ Work relating to TAP channel Request For Quote (RFQ). labels Aug 25, 2025
jtobin added 7 commits August 25, 2025 09:04
Formalizes the 'Code' of an 'OracleError' as an 'OracleErrorCode', and
adds a couple of values corresponding to structured error cases.
Ensure the error code is part of an OracleError response, and pass the
error intact in query{Bid,Ask}FromPriceOracle, instead of formatting it
as a string.
Uses the OracleError returned by an oracle to customize the rejection
message sent to a peer. If the OracleError contains a "transparent" code
that's deemed to be suitable for passing on to a peer, then simply relay
that error. Otherwise relay an opaque "unknown reject error" message.
Avoids a blunt cast of the wire code, and also refrains from relaying
the full Error() message to the peer.
Simply passes an error code of 1 (unsupported subject asset) where
appropriate in the mock oracle. The raw code is used instead of
oraclerpc.UNSUPPORTED or similar to avoid dependency changes at present.

Also adds the mock oracle's log to gitignore.
@jtobin jtobin force-pushed the oracle-error-codes branch from 0a5e9ab to 6bdb36a Compare August 25, 2025 11:35
@coveralls
Copy link

coveralls commented Aug 25, 2025

Pull Request Test Coverage Report for Build 17268575857

Details

  • 1 of 99 (1.01%) changed or added relevant lines in 4 files are covered.
  • 84 unchanged lines in 16 files lost coverage.
  • Overall coverage decreased (-0.06%) to 56.558%

Changes Missing Coverage Covered Lines Changed/Added Lines %
rfqmsg/reject.go 0 6 0.0%
rfq/oracle.go 0 12 0.0%
taprpc/priceoraclerpc/price_oracle.pb.go 1 23 4.35%
rfq/negotiator.go 0 58 0.0%
Files with Coverage Reduction New Missed Lines %
address/mock.go 2 96.2%
asset/group_key.go 2 72.15%
mssmt/compacted_tree.go 2 79.49%
tapdb/assets_common.go 2 78.72%
tapdb/sqlc/transfers.sql.go 2 82.65%
tapdb/sqlc/universe.sql.go 2 75.78%
tapchannel/aux_leaf_signer.go 3 43.43%
rfqmsg/records.go 4 70.8%
rpcserver.go 4 61.03%
tapdb/universe.go 4 81.64%
Totals Coverage Status
Change from base Build 17140538774: -0.06%
Covered Lines: 60774
Relevant Lines: 107454

💛 - Coveralls

@@ -326,6 +327,7 @@ func (p *RpcPriceOracleServer) QueryAssetRates(_ context.Context,
Result: &oraclerpc.QueryAssetRatesResponse_Error{
Error: &oraclerpc.QueryAssetRatesErrResponse{
Message: "unsupported subject asset",
Code: 1,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there an enum val from our lib that we can use here instead of 1?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used a raw '1' at present to avoid updating the mock oracle's dependencies (it looks like there have been other RPC changes since it was last updated as well). Perhaps best to avoid changing the mock oracle for now, and just update it to use the latest RPC definitions in another PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(If you agree, I'll drop the commit that changes the mock oracle before merge.)

if oracleResponse.Err != nil {
return nil, fmt.Errorf("failed to query price oracle for "+
"buy price: %s", oracleResponse.Err)
return nil, oracleResponse.Err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the additional context that was here previously was useful to distinguish between buy/sell price related error. Is there a good reason for removing the additional context here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, yeah. Re-added context in a structured form in 5eaf8a9.

rfq/oracle.go Outdated
const (
// ErrUnspecifiedOracleError represents the case where the oracle has
// declined to give a more specific reason for the error.
ErrUnspecifiedOracleError OracleErrorCode = iota
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we usually start error type names with Err.... Maybe we should use names UnspecifiedOracleErrorCode and UnsupportedAssetOracleErrorCode here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used your suggestion, fixed in 6130dac.

rfqmsg/reject.go Outdated
// it with a custom error message.
func ErrRejectWithCustomMsg(msg string) RejectErr {
return RejectErr{
Code: 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use enum const here instead of 0

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 79308a2. There were also some existing cases in that file that used the raw code, so I fixed those too.

Comment on lines 86 to 92
enum ErrorCode {
// ERROR_UNSPECIFIED indicates an unspecified error.
ERROR_UNSPECIFIED = 0;

// UNSUPPORTED indicates the asset is not supported.
ERROR_UNSUPPORTED = 1;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these fields should follow the enum filed names in our code so: UNSUPPORTED_ASSET_ORACLE_ERROR_CODE etc

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, fixed in 6ff7217.

jtobin added 5 commits August 25, 2025 11:45
Changes these to avoid the 'Err..' convention presently reserved for
type names.
Defines specific consts for the two RejectErr error codes, and uses
those in place of the raw uint8 values.
Changes 'ERROR_UNSPECIFIED' and 'ERROR_SUPPORTED' to more closely match
the OracleErrorCode values in rfq/oracle.go.
Introduces a structured QueryError that wraps an arbitrary error
(usually from a price oracle) with arbitrary context, and adjusts
query{Buy,Sell}FromPriceOracle to return these errors where appropriate.

Also adjusts createCustomRejectErr to handle QueryErrors, instead of
OracleErrors.
@jtobin jtobin requested a review from ffranr August 28, 2025 15:47
@lightninglabs-deploy
Copy link

@ffranr: review reminder

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
error handling RFQ Work relating to TAP channel Request For Quote (RFQ).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[feature]: structured error codes for price oracles
4 participants