-
Notifications
You must be signed in to change notification settings - Fork 1
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
Token2022 (extensions) support #9
base: compute-budget-rf-v2
Are you sure you want to change the base?
Conversation
Fix ci warnings
workflows/sonarcloud.yml: Update workflow following app-bitcoin-new example
[auto] Update Screenshots
[auto] Update Screenshots
Added: * token2022 program id * ProgramIdToken2022 enum value * switch case to handle token2022 in message and transaction_printer * extension names to the token instruction tag 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.
Hey there! I performed a functional test on a real hardware and found that none of the basic operations like transfer, burn, mint, etc. are clear-signed. I faced with an issue of unrecognized format that requires blind signing. Please, see my comment where I assume the logic is broken.
libsol/message.c
Outdated
@@ -99,6 +100,8 @@ int process_message_body(const uint8_t* message_body, | |||
case ProgramIdUnknown: | |||
display_instruction_info[display_instruction_count++] = info; | |||
break; | |||
//Currently we don't display these instructions | |||
case ProgramIdToken2022: |
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.
At the moment it seems that the bug is here. We skip the logic where we count instructions and setting instruction info which leads us to unrecognized format handling upper in handle_sign_message_parse_message
since process_message_body
returns 1
.
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.
Hello, thanks for the tests and feedback @sponomarev. It is interesting that "that none of the basic operations" does not work, we've tested it on the real hardware too (NanoX and NanoSP) and it looked fine.
I'll double check that this branch contains the correct code (as it was separated from the other feature recently), but I'm quite sure about that.
In addition to that, are you able to share the Transaction that you used to perform tests? It would be great to reproduce the problem with the same data that you have used. After that we will handle this problem asap.
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.
Sure. Here is an example https://explorer.solana.com/tx/2DRngy89okvFT9gekHKQv5uAy43FVHKndf7qJvm3Q7JbRcE62PKwdHBc1dWWWsK4hW1uTCqNN9WovfXMUNUcKbWC?cluster=devnet. This transaction contains only one instruction from token2022 program. In that case, if we closely take a look at these lines, display_instruction_count
won't be incremented and end up as zero, that's passed down to print_transaction
and print_transaction_nonce_processed
.
You can recreate this transaction easily with spl-token
cli.
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, yes, you are right, we will handle this and come back soon
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.
Fixed!
Remove separate Token2022 program id.
26f9042
to
5d6fdac
Compare
@sponomarev Hello, I've made some changes. Hopefully I didn't miss anything :) In my opinion the best way to handle this was to unify both token types as the same programId. Otherwise handling transaction_printers was getting a little tricky. Let me know it there is anything else to change or if you find any other problems. |
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.
Hey @0xMMBD! It seems that the original issue is resolved. I was able to perform basic token operations for both Token2022 and the original Token program. I've also tried to play with extensions, but nothing was successful. It seems that something goes wrong on that side. Here is my test scenarios report:
✅ Token creation without extensions
✅ Token account creation
✅ Token transfer
✅ Mint token
✅ Burn token
🔴 Token creation with transfer fee extension
🔴 Token creation with confidential transfers extension
🔴 Token creation with default account state extension
🔴 Token account creation with immutable owner extension
🔴 Token account: enable/disable required memo transfers
My raw assumption is that the issue is happening somewhere in print_transaction_nonce_processed
where we can mess instruction amount since extensions are enabled with a separate instruction and enable/disable required memo transfers is a separate instruction as well.
The extensions are not supported currently. The main purpose of this PR was to properly handle basic operations on token when using Token2022 program. We wanted to make it backward compatible with existing features without the need of blind signing. So current extensions are recognized and are added in the code but we dont have any special logic for them |
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.
Need clarification on the transfer decoding
@@ -18,6 +19,8 @@ enum ProgramId instruction_program_id(const Instruction* instruction, const Mess | |||
return ProgramIdVote; | |||
} else if (memcmp(program_id, &spl_token_program_id, PUBKEY_SIZE) == 0) { | |||
return ProgramIdSplToken; | |||
} else if(memcmp(program_id, &spl_token2022_program_id, PUBKEY_SIZE) == 0) { | |||
return ProgramIdSplToken;//Treat the Token2022 exactly the same as the SplToken |
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.
Is the decoding resulting from this used in the user signing loop?
If so this may cause issues, as the user may be unaware that he is signing transactions using the token22 program that may contain transfer fee or transfer hooks with unintended consequences
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.
The main reason behind this is the code thats prints transaction details. If I detect token2022 as something different then it gets more messy to handle basic token instruction like mint, burn etc. At this point, if we use for example TransferFeeExtension
we just ignore it - we don't display any additional screens.
What we can do is to throw error(instruction not supported) when we get any extension instruction. This way there will be no chance to sign something that you are not able to verify visually on the screen. Otherwise we would need to redesign this function https://github.com/blockydevs/app-solana/blob/develop/libsol/transaction_printers.c#L535 https://github.com/blockydevs/app-solana/blob/develop/libsol/transaction_printers.c#L535
because it is not able to handle anything with more than 3 instructions and we dont know what extensions someone will send and in what order
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, like main idea in this PR is to allow transactions that use the token2022 program id to be able to perform basic instructions that are also compatible with the old token
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, like main idea in this PR is to allow transactions that use the token2022 program id to be able to perform basic instructions that are also compatible with the old token
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.
There is a slight mix up between extension setup and the extension usage.
The TransferFeeExtension
instruction is only called to setup the extension, so not supporting it here makes total sense. However, if its setup, any calls to Transfer
are going to need extra accounts to correctly execute the transfer with the fee.
The way the decoding is currently setup, any Token22 mint with extensions such as Transfer Fees or Transfer Hooks enabled, are going to execute completely blind to the decoding operation due to the Transfer
instruction being ABI compatible between both programs (extra accounts needed by extensions are appended at the end, everything else maintains the same binary structure).
At the very least, during decoding, the user should be aware that its signing a Transfer
for a mint with such extensions enabled (fees can go all the way up to 100% and can change over time, on the other end of the spectrum transfer hooks can enable bad actors to effectively wipe accounts).
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 simple approach seems reasonable at that stage of token2022 support.
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.
Its much better.
However, if I understood this correctly, the warning message only pops up if there are Extensions related instructions on the TX right? For that scenario its the right behaviour.
However, if there is only a TransferChecked
instruction in the transaction and it is of a token mint with possible damaging extensions enabled (high transfer fees, draining transfer hook), the user will think he's signing a token transfer from the old Token Program without any side effects as none of that is present in the transaction.
IMO there needs to be another warning on any T22 TransferChecked
like:
"Token Extensions" "Cannot verify mint extensions"
"Verify mint issuer before signing"
(not sure of character limits, but something along these lines)
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, any extension thats coming from T22 generates this warning, the idea behind this PR was to allow users to use the old backward compatible features.
Due to the current code design we are a little bit limited in terms of detecting any complex cases with different instructions. Transaction printers contains hardcoded switch case that does not allow a lot of flexibility unfortunately.
Can you specify what exact cases should trigger that additional warning? Is it for transactions that only contains single TransferChecked
instruction (https://solana-labs.github.io/solana-program-library/token/js/functions/createTransferCheckedInstruction.html) or are they any other cases?
And there is also another issue. On the older nanos devices we are really close to the memory limit, so adding long strings in to the binary may cause problems too, some of them appear only in specific features so maybe we just reuse the same warning text?
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.
The additional warning should be triggered on TransferChecked
when programId == token22
, regardless of how many instructions are present in the transaction.
I'd say you can recycle the title part of the warnings.
Title: "Extension warning"
Messages: "Can't check mint extensions" -> "Check explorer"
Is the memory available enough for those? If not we can rework these warnings to further reuse strings.
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.
@tiago18c ok, I've added additional warning screens and i've also merged latest develop changes to verify that everything is still working as planned.
I did few tests on the nanos model and it looks that we are still within memory limits
* Added support for compute budget instructions: * request heap frame * set compute unit price * request units * set compute unit limit * added unit tests Co-authored-by: Piotr Swierzy <[email protected]>
* Added split-stake instruction support for: * SystemTransfer + SystemAllocate + SystemAssign + StakeSplit * SystemTransfer + SystemAllocateWithSeed + StakeSplit Co-authored-by: Maciej Nabiałek <[email protected]>
* Added split-stake instruction support for: * SystemTransfer + SystemAllocate + SystemAssign + StakeSplit * SystemTransfer + SystemAllocateWithSeed + StakeSplit Co-authored-by: Maciej Nabiałek <[email protected]>
[auto] Update Screenshots
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
Hello @tiago18c can you please summarize what are the next steps? Is there anything else from our side that should be done? |
Add support for Token2022 instructions(extensions).
Added: