-
Notifications
You must be signed in to change notification settings - Fork 30
add additional UTXO info to partially signed tx #1799
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 additional UTXO info to partially signed tx #1799
Conversation
2c28c54 to
ef80f00
Compare
| /// Additional info for UTXOs | ||
| #[derive(Debug, Eq, PartialEq, Clone, Encode, Decode)] | ||
| pub enum UtxoAdditionalInfo { | ||
| TokenInfo { num_decimals: u8, ticker: Vec<u8> }, | ||
| PoolInfo { staker_balance: Amount }, | ||
| NoAdditionalInfo, | ||
| } | ||
|
|
||
| #[derive(Debug, Eq, PartialEq, Clone, Encode, Decode)] | ||
| pub struct PartiallySignedTransaction { | ||
| tx: Transaction, | ||
| witnesses: Vec<Option<InputWitness>>, | ||
|
|
||
| input_utxos: Vec<Option<TxOutput>>, | ||
| input_utxos: Vec<Option<(TxOutput, UtxoAdditionalInfo)>>, | ||
| destinations: Vec<Option<Destination>>, | ||
| } | ||
|
|
||
| impl PartiallySignedTransaction { | ||
| pub fn new( | ||
| tx: Transaction, | ||
| witnesses: Vec<Option<InputWitness>>, | ||
| input_utxos: Vec<Option<TxOutput>>, | ||
| input_utxos: Vec<Option<(TxOutput, UtxoAdditionalInfo)>>, | ||
| destinations: Vec<Option<Destination>>, | ||
| ) -> Result<Self, TransactionCreationError> { |
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 indeed rather hacky. Can we put this info somewhere beside PartiallySignedTransaction instead?
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 agree that the way it's done right now is hacky.
Maybe moving PartiallySignedTransaction from wallet to common was not that good idea after all. I did that few months ago because the struct looked really basic and a good companion for SignedTransaction, also I thought I'd use it in tx-verifier. But maybe I misunderstood it and the type is from wallet layer. Thoughts?
1cd8110 to
c23f38d
Compare
dae3bf3 to
51a9d60
Compare
| | TxOutput::IssueFungibleToken(_) | ||
| | TxOutput::AnyoneCanTake(_) => None, | ||
| TxOutput::IssueNft(_, _, _) => make_token_id(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.
Why is IssueFungibleToken ignored here?
Btw, this changes the logic of the wallet's OutputCache::find_unspent_unlocked_utxo/utxos_with_token_ids, which previously were producing token ids both for ft and nft. I wonder if it's intentional.
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.
IssueFungibleToken is ignored as it can't be spent as a utxo, this was added to fix the utxo functions, because they were not updated when TokenV1 was added, so they were only handeling the TokensV0 and NFT.
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.
Returning token id only for spendable output is a very specific logic, common crate might not be the best place for it. Why not moving it to the wallet and renaming to get_token_id_for_spendable_utxo?
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.
removed the token ids being returned for the utxos, and added a separate call to fetch them at the places where they are needed to be checked for frozen tokens.
wallet/src/send_request/mod.rs
Outdated
| TxOutput::AnyoneCanTake(data) => { | ||
| find_additional_info(data.as_ref().ask(), additional_info)? |
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 might be missing something, but does it make sense to handle AnyoneCanTake here? I mean, is it a spendable output? I had the impression that it is not, @azarovh could you clarify?
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 spendable by anyone who will provide "asked" currency in exchange.
P.S. I think data.as_ref().ask() is wrong and it should be give() which is the value that creator of the output locked with 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.
Also this value can be a token so I think it does make sense
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.
Sorry guys I confused everyone here. AnyoneCanTake output is not included into utxo set (but rather creates an account) and is not spendable.
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.
Sorry guys I confused everyone here.
AnyoneCanTakeoutput is not included into utxo set (but rather creates an account) and is not spendable.
Can you add some doc comment for AnyoneCanTake describing its nuances?
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 still present as we not only need additional info for UTXOs but also for the output UTXOs
| pub fn into_partially_signed_tx( | ||
| self, | ||
| additional_info: &BTreeMap<PoolOrTokenId, UtxoAdditionalInfo>, | ||
| ) -> WalletResult<PartiallySignedTransaction> { |
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 wonder if we can put
additional_infoinsideSendRequest, so that there is less chance for them to become out of sync. - The match statement in
fetch_utxo_exra_infohas the same logic. I wonder if we can factor it out. Or maybe put the two implementations near each other so that it's clear that they must be in sync.
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 have small additional request: is_v0_token_output should check that values inside OrderData of AnyoneCanTake output does not contain tokens v0.
| } | ||
| } | ||
|
|
||
| pub async fn fetch_utxo_exra_info<T>( |
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.
typo: extra
| witnesses: Vec<Option<InputWitness>>, | ||
|
|
||
| input_utxos: Vec<Option<TxOutput>>, | ||
| input_utxos: Vec<Option<UtxoWithAdditionalInfo>>, |
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.
why not storing utxo separately from info and zipping if necessary? Right now the data is duplicated. Also it looks cleaner with all the data inside ptx flatten. If such new type is required for trezor I'd move it closer to 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.
I went with this to preserve the invariant that you can't have additional info if you don't have an UTXO as well. Also the none case of the optional for the additional info does not mean missing it means no additional info. Maybe I should go back to the enum instead of the option + enum?
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 see. Would it work if output_additional_infos field is removed and the getter return mapped Iter over input_utxos?
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.
Now I get it. I'd leave a comment about that invariant and new field just to make it clear for the future.
| let output_additional_infos = self | ||
| .outputs | ||
| .iter() | ||
| .map(|utxo| find_additional_info(utxo, additional_info)) |
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.
So yeah this should be None or even an error because it's not spendable and cannot be a utxo.
6444490 to
b31700d
Compare
190d6f3 to
8d105c2
Compare
8d105c2 to
c24ff7b
Compare
c23f38d to
4824da8
Compare
add additional UTXO info for tokens (number of decimals and ticker) and pools (balance) to partially signed tx, intended to be shown on a hardware wallet UI like Trezor.