-
Notifications
You must be signed in to change notification settings - Fork 30
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
refactor(transaction): Validations for transaction requests #447
Conversation
78e175a
to
44cffa1
Compare
BTW maybe we should also add a validation for duplicate expected output notes/own notes as well. |
52a178f
to
28f1871
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. I left a couple non-blocking comments, except for one related to making sure we fail if the asset vault does not contain an asset that the notes require.
9250b6a
to
d1e9047
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.
Thank you! Overall, this looks good - but I just realized that there is one thing we are missing: assets may be deposited into the account by input notes and so just because the account doesn't have all outgoing assets, doesn't mean the transaction will fail.
So, I think we could do the following:
- Sum up all the incoming assets.
- Sum up all the outgoing assets.
- Make sure
account_assets + incoming_assets >= outgoing_assets
.
Also, I think making similar checks for faucets is a bit more involved - so, I'd remove them from this PR and create a separate issue for them.
fn calculate_outgoing_assets( | ||
&self, | ||
transaction_request: &TransactionRequest, | ||
) -> (BTreeMap<AccountId, u64>, BTreeSet<NonFungibleAsset>) { |
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: calculate_
prefix sounds a bit odd here. I'd probably use build_
or get_
.
Also, I don't think we are using anything from self
here. So, this can probably be a pure function and we could move it to the "Helper functions" section at the end of the file.
Another thought is that this could be a method on TransactionRequest
.
let (fungible_balance_map, non_fungible_set) = | ||
self.calculate_outgoing_assets(transaction_request); | ||
|
||
// Get client assets |
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: should this say "Get account assets"?
// Faucet account can only mint one asset (itself) | ||
if own_notes_assets.len() > 1 { | ||
return Err(ClientError::TransactionRequestError( | ||
TransactionRequestError::InvalidFaucetMint( | ||
"Faucet can only mint one asset".to_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.
This is only true for fungible assets. We don't currently have non-fungible faucet fully working, so this may be OK for now - but also maybe we should make the check more sophisticated here.
let own_notes_assets = match transaction_request.script_template() { | ||
Some(TransactionScriptTemplate::SendNotes(notes)) => notes | ||
.iter() | ||
.map(|note| note.assets()) | ||
.flat_map(|assets| assets.iter()) | ||
.collect::<Vec<_>>(), | ||
_ => Default::default(), | ||
}; |
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 this is sufficient to compute own_notes_assets
. In theory, it should be possible for a note script to call the distribute
procedure as well.
#[maybe_async] | ||
pub fn get_incoming_assets( | ||
&self, | ||
client: &Client< | ||
impl NodeRpcClient, | ||
impl FeltRng, | ||
impl Store, | ||
impl TransactionAuthenticator, | ||
>, | ||
) -> Result<(BTreeMap<AccountId, u64>, BTreeSet<NonFungibleAsset>), TransactionRequestError> |
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.
oh - I forgot that to get incoming note assets we need to query the store. In this case, probably better to have this in the transactions
module (rather than transaction request). And if we do this, we should probably move get_outgoing_assets
back there for consistency.
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.
Sounds good. I've moved it.
4f1f228
to
03e1671
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! I left a few small comments inline. Once these are addressed, we can merge.
b42764e
to
f63c612
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! Left a very minor non-blocking comment, feel free to disregard
// Check if the account balance plus incoming assets is greater than or equal to the outgoing | ||
// fungible assets | ||
for (faucet_id, amount) in fungible_balance_map { | ||
match account.vault().get_balance(faucet_id) { |
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: Maybe you can do get_balance(faucet_id).unwrap_or(0)
(as you did below) here and you'd be able to get rid of the second match
branch
) -> Result<(), ClientError> { | ||
let (account, _) = maybe_await!(self.get_account(transaction_request.account_id()))?; | ||
if account.is_faucet() { | ||
// TODO(SantiagoPittella): Add faucet validations. |
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.
You probably were tracking this already but just in case: let's open an issue for 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.
I just created #468 ✅
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.
Feel free to add whatever you want to the issue.
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!
One thing: let's create an issue to figure out if we want to make it so that own output notes are always a strict subset of expected output notes.
Created #470 for this |
Closes #444