-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Use indexation cache to satisfy "coins to spend" queries #2463
base: master
Are you sure you want to change the base?
Conversation
…to_spend_cache_part_2
…to_spend_cache_part_2
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 stuff so far. I have only done a relatively shallow sweep and will get back again during the week for a deeper look. I have a few nits and suggestions so far, but nothing major.
I'm not a fan of the lack of explicit error handling in crates/fuel-core/src/graphql_api/storage/coins.rs
but other than that I think the code looks generally really well-written.
…to_spend_cache_part_2
Closes #2474 ## Description This PR changes the following: 1. Adds new test in `tests/tests/relayer.rs` - to ensure that only **non**-retryable messages contribute to the balance returned from `balance()`, `balances()` and `coins_to_spend()`[^1] endpoints 2. Modifies the `balance()` test in `tests/tests/balances.rs` to also include some retryable message which is expected **not** to contribute to the total balance. * for `balances()` and `coins_to_spend()` it was already the case 1<sup>st</sup> test checks the behavior of the actual blockchain operations while the 2<sup>nd</sup> tests the proper initialization of the balances index at genesis. ## Checklist - [X] Breaking changes are clearly marked as such in the PR description and changelog - [X] New behavior is reflected in tests ### Before requesting review - [X] I have reviewed the code myself [^1]: currently, `coins_to_spend()` is not using indexation, this will change when [this PR](#2463) is merged. --------- Co-authored-by: Green Baneling <XgreenX9999@gmail.com>
excluded_ids: &ExcludedCoinIds<'_>, | ||
batch_size: usize, | ||
) -> Result<Vec<CoinsToSpendIndexEntry>, CoinsQueryError> { | ||
const TOTAL_AMOUNT_ADJUSTMENT_FACTOR: u64 = 2; |
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.
It would be nice to put a comment why we decided to do it like this=)
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.
+1
// TODO[RC]: No clone() required for coins? Double check the types used, | ||
// maybe we want `MessageCoin` (which is Copy) for messages? | ||
// 1) Currently we use the same types as embedded in the executor `Event`. | ||
// 2) `MessageCoin` will refuse to construct itself from a `Message` if the data is empty | ||
// impl TryFrom<Message> for MessageCoin { ... if !data.is_empty() ... } | ||
// Actually it shouldn't matter from the indexation perspective, as we just need | ||
// to read data from the type and don't care about which data type we took it from. |
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.
It is okay to use clone in tests=) I don't think that we need to add more specific type
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.
Apologies for taking longer than expected. While most of this looks good to me, I have a few questions of some things that puzzle me. Moreover, there are two concrete things I'd like to see updated before approving:
First, we should update the description and name of the random_improve
function. Second, I'd like to see an integration test that shows how this algorithm behaves end to 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.
Commenting on this file since Github doesn't allow me to comment on some unmodified lines for some reason.
The random_improve
function has a TODO comment which references this change. While we still seem to keep the function around for when indexation is unavailable, the comment and name seems to assume the function is to be removed. It should be updated to reflect that the method is used if indexation is not available.
excluded_ids: &ExcludedCoinIds<'_>, | ||
batch_size: usize, | ||
) -> Result<Vec<CoinsToSpendIndexEntry>, CoinsQueryError> { | ||
const TOTAL_AMOUNT_ADJUSTMENT_FACTOR: u64 = 2; |
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.
+1
let big_coins_stream = futures::stream::iter(big_coins_iter).yield_each(batch_size); | ||
let dust_coins_stream = futures::stream::iter(dust_coins_iter).yield_each(batch_size); |
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 would expect these to typically be quite short iterators, so do we really need to convert them into futures? The default batch size is 100, and I'd expect it to be quite uncommon to exceed that number of coins for a single transaction. Especially since the max number of inputs in ignition is 255 if I recall correctly.
// Indicates that a message is retryable. | ||
pub(crate) const RETRYABLE_BYTE: [u8; 1] = [0x00]; |
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.
What does it mean for a message to be retryable? I can see that it means that the message contains data, but what is it that we can retry in this case that we cannot with empty messages?
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.
Could we add an integration test that demonstrates the expected behavior of the algorithm? I.e. a test that sets up a wallet with a few big and small coins, makes a query that should be satisfied by adding X big coins and Y small ones for a few sensible scenarios.
Closes #2391
This PR includes all changes from the Part 1 PR, making it deprecated.
Description
Changes in this PR:
The new
CoinsToSpend
indexMessages
orCoins
on-chain databasesNonce
UtxoId
IndexedCoinType
enum, so we know which on-chain database to query when returning the actual coinsmax
andexcluded
params)max
) we fill the remaining slots with a random number of "dust" coinsChanges to
CoinsQueryError
typeMaxCoinsReached
variant has been removed because in the new algorithm we never query for more coins than the specifiedmax
, hence, without additional effort, we are not able to tell whether the query could be satisfied if user provided biggermax
InsufficientCoins
has been renamed toInsufficientCoinsForTheMax
and it now contains the additionalmax
fieldOff-chain database metadata
IndexationKind
-CoinsToSpend
Refactoring
indexation.rs
module was split into separate files, each per indexation type + errors + some utils.Other
coinsToSpend
GraphQL query is now limited to the maximum number of inputs allowed in transaction.Before requesting review
Follow-up issues
CoinsToSpendIndexKey
fromVec<u8>
to typed struct, similarly toOwnedTransactionIndexKey
#2498OffChainDatabase::coins_to_spend_index()
function should return error if indexation is not available #2499