-
Notifications
You must be signed in to change notification settings - Fork 331
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
chore(ckbtc): add check_transaction_query method to Bitcoin checker #3454
base: master
Are you sure you want to change the base?
chore(ckbtc): add check_transaction_query method to Bitcoin checker #3454
Conversation
f4bfb78
to
5354b6f
Compare
5354b6f
to
0331d1d
Compare
0331d1d
to
3184c66
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.
Thanks @lpahlavi for this PR! Some preliminary comments.
// Same as check_transaction, but query method, hence it does not perform any HTTP | ||
// outcalls to fetch the required information. | ||
// IMPORTANT: this endpoint is meant as a debugging tool and is not guaranteed to be backwards-compatible. | ||
check_transaction_query: (CheckTransactionArgs) -> (CheckTransactionQueryResponse) query; |
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.
I think there I would provide a new input type, e.g. CheckTransactionQueryArgs
which would be an enum, to be able to handle the transaction Id given in binary or in String format. This is to avoid having a check_transaction_query_str
, which would be the pendant to check_transaction_str
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: the names of the variants are not too descriptive (Blob
/Text
) so I would rename them to something like TxIdBin/TxIdStr
(or similar) since it should be clear that those are transaction IDs.
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.
Good point! Done.
type CheckTransactionQueryStatus = variant { | ||
// The result is not available, but may be obtained via a call to the non-query version | ||
// of `check_transaction`. | ||
HttpOutcallRequired; | ||
// The result is unknown due to an irrecoverable error. | ||
Error: CheckTransactionIrrecoverableError; | ||
}; |
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.
I'm not sure we need this:
CheckTransactionIrrecoverableError::InvalidTransaction
would not be seen from the query call which only access the cache, since this error is not recorded in the stateCheckTransactionIrrecoverableError::InvalidTransactionId
: in that case the query call should just panic.- I don't know if need to differentiate
CheckTransactionIrrecoverableError::ResponseTooLarge
fromCheckTransactionQueryStatus::HttpOutcallRequired
in the query call.
With all this I would tend to just have an Unknown;
variant (like Passed
). WDYT @ninegua ?
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.
I think that's a sensible suggestion. I've implemented it as you suggested, @ninegua lmk if you disagree.
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 with the simplified result type for queries.
@gregorydemay Thanks a lot for the feedback! I've implemented your suggested changes, and will wait for @ninegua's +1 before adding all of the required tests. |
.input_addresses | ||
.iter() | ||
.flatten() | ||
.find(|address| is_blocked(address)) |
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.
@ninegua : Do you have any idea why we only return one blocked address here? I tried to keep the same behavior as before, but imo we could also return all blocked addresses, no?
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.
Yes, it should be totally fine to return all blocked addresses. I don't even remember why it was coded this way to return early
rs/bitcoin/checker/src/main.rs
Outdated
CheckMode::Normal => { | ||
if let Some(FetchTxStatus::Fetched(fetched)) = state::get_fetch_status(txid) { | ||
if let Some(response) = check_no_input_address_is_blocked(&fetched) { | ||
return response.into(); | ||
} | ||
} | ||
CheckTransactionQueryStatus::HttpOutcallRequired.into() | ||
} |
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: you could have everything under a single match statement
CheckMode::Normal => { | |
if let Some(FetchTxStatus::Fetched(fetched)) = state::get_fetch_status(txid) { | |
if let Some(response) = check_no_input_address_is_blocked(&fetched) { | |
return response.into(); | |
} | |
} | |
CheckTransactionQueryStatus::HttpOutcallRequired.into() | |
} | |
CheckMode::Normal => match state::get_fetch_status(txid) { | |
Some(FetchTxStatus::Fetched(fetched)) => { | |
check_for_blocked_input_addresses(&fetched).into() | |
} | |
Some( | |
FetchTxStatus::PendingOutcall | |
| FetchTxStatus::PendingRetry { .. } | |
| FetchTxStatus::Error(_), | |
) | |
| None => CheckTransactionQueryResponse::Unknown, | |
}, |
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.
Nice! I didn't realize I could use the |
operator inside Some(...)
. I thought I had to do something like Some(A) | Some(B) | ... | None
which didn't look so great... Always happy to learn some new Rust tricks!
(XC-194) Query interface to retrieve check_transaction status.
The check_transaction call requires cycles to execute due to to the HTTP outcalls it has to perform. However, in the event a transaction and all of its inputs have already been loaded to the cache in heap memory, no HTTP calls are required. This new query method therefore checks whether a transaction status may be obtained using only cached information, and if so, returns it without charging any cycles.