-
Notifications
You must be signed in to change notification settings - Fork 28
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
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.
AnyoneCanTake
output 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_info
insideSendRequest
, so that there is less chance for them to become out of sync. - The match statement in
fetch_utxo_exra_info
has 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
#[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<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.