-
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
Add support of messages into coinsToSpend
#591
Conversation
…and messages. We can't use `Input` or `Output` naming because we already do that with transactions. So I introduced a new one. We can think about the naming in the PR=) Renamed `coinsToSpent` into `banknotesToSpent`. Move it to a separate file. Changed the signature. Not it returns `Vec<Vec<Banknote>>` instead of `Vec<Coin>`. The result is a list of `Banknote` per asset(we can have many different assets, so it is why it has an additional vector). Replaced exclude vector with two vectors in the separate struct. One vector allows filtering by utxos, another by messages. Reduced the number of operations in the `banknotesToSpent`. Added some abstraction to remove logic duplicating. I want to reuse it in the other schemas like `balance`. Added `schema::Scalar` for `MessageId`. I need to add the support of `Message` into tests and the code. I will do it in the next commit=)
I see a lot of API changes in here, are you sure of how this affects downstream consumers of |
Do you ask about
The changes in the database it forcing people to change how they work with it to have more optimal code. |
Changing to |
Before I will update the tests let's discuss the final query signature in the issue=) |
coinsToSpent
coinsToSpend
# Conflicts: # fuel-client/src/client.rs # fuel-core/src/coin_query.rs # fuel-core/src/database/coin.rs # fuel-core/src/schema/coin.rs # fuel-tests/tests/coin.rs
Uncommented and fixed old tests.
…m to work with coins, messages, and coins and messages test cases. Added new field to `schema::Message` - `message_id`. It is calculated based on the `Message`. Added check of errors in the client's tests.
fuel-core/src/database/utils.rs
Outdated
@@ -0,0 +1,218 @@ | |||
use crate::{ |
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'd prefer to avoid a generic utils
module, as it makes organization less clear and will just keep growing with potentially unrelated things.
Since this is mostly about coins and messages, maybe rename this utils module into resources
within the database instead?
fuel-core/src/coin_query.rs
Outdated
let mut collected_amount = 0u64; | ||
let mut resources = vec![]; | ||
|
||
for coin in inputs { |
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.
for coin in inputs { | |
for resource in inputs { |
fuel-core/src/database/utils.rs
Outdated
|
||
/// At least required `target` of the query per asset's `id` with `max` resources. | ||
#[derive(Clone)] | ||
pub struct Asset { |
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.
This is a selection criteria, not an asset 🤔
Maybe something like AssetSpendTarget
?
fuel-core/src/database/utils.rs
Outdated
/// The primary type of spent or not spent resources(coins, messages, etc). The not spent resource | ||
/// can be used as a source of information for the creation of the transaction's input. | ||
#[derive(Debug)] | ||
pub enum Resource<C, M> { |
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.
Since the schema has its own analog to resource, why include these generics 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.
To avoid unnecessary Copy
and Clone
. The query to DB returns Resource<Cow<Coin>, Cow<Message>>
. But the graphql query returns Resource<Coin, Message>
.
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.
Since the schema has its own analog to resource
It looks like the schema doesn't rely on this enum, since it has it's own: https://github.com/FuelLabs/fuel-core/blob/feature/coins-to-spent-messages/fuel-core/src/schema/resource.rs#L52
Couldn't we just simplify this type by making it always a Cow?
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.
No, because Cow
requires lifetime from DB, and in the resources_to_spend
we can't return Vec<Vec<Resource<Cow, Cow>>>
=(
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.
Do we really need Cow
? Or is it always owned once deserialized from the DB anyways? Even though the storage trait uses Cow, I don't think it would ever be borrowed unless we had some kind of zero-copy deserialization going on.
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, if we use RocksDB, in this case, it is useless=) I tried to be consistent with our API. Database
returns Cow
, and in some cases (maybe in the future), it can be useful.
If you think it adds unjustified complexity, I can remove it=)
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.
eh it's not a big deal. I just prefer to find ways to hide generics when possible since it can get out of hand sometimes (like in substrate codebases lol)
@@ -221,6 +221,8 @@ impl KeyValueStore for RocksDb { | |||
.iterator_cf_opt(&self.cf(column), opts, iter_mode) | |||
.map(|item| { | |||
item.map(|(key, value)| { | |||
// TODO: Avoid copy of the slices into vector. |
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.
We could also adjust the API to make use of boxed slices instead of vec 🤔
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.
We can, the question do we want to add complexity to database API=) But it will force us to work with raw slice where it is possible=)
.unwrap(); | ||
assert_eq!(resources_per_asset.len(), 2); | ||
assert_eq!(resources_per_asset[0].len(), 3); | ||
assert_eq!(resources_per_asset[1].len(), 3); |
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.
should we also check that the returned resources add up to >= target in these tests?
Done reviewing for now, will wait for the requested changes before approving. |
@@ -76,8 +76,9 @@ impl BalanceQuery { | |||
) -> async_graphql::Result<Balance> { | |||
let db = ctx.data_unchecked::<Database>(); | |||
|
|||
// TODO: Reuse [`AssetQuery`](crate::database::utils::AssetQuery) with 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.
nit: would be nice to see Issues created for these TODO
s (if not already)
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, there are handful of TODOs, would be nice that Issues are created for and possibly referenced
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, will move new coinsToSpend
tests over to my rstest PR once merged. We may also want to look at organizing fuel-tests
in a future issue as it is mostly flat right now and could benefit from tests being organized into folders
Also +1 on moving TODOs to issues (with TODO comment referencing the issue #)
Renamed `CoinQueryError` into `ResourceQueryError`. Added `asset_id` and `collected_amount` into `ResourceQueryError`.
59e8ab0
# Conflicts: # fuel-core/src/coin_query.rs # fuel-core/src/database.rs # fuel-core/src/database/coin.rs # fuel-core/src/database/message.rs # fuel-core/src/state.rs # fuel-core/src/test_utils.rs
Created a new entity -
Resource
. It is an aggregator for the coins and messages. For more information, check the discussion at the #586The API looks like:
Added some abstraction to remove logic duplicating. I want to reuse it in the other schemas like
balance
.Added
schema::Scalar
forMessageId
.Added
message_id
for theschema::Message
.Closes #586