Skip to content

Commit c387b9d

Browse files
authored
Merge pull request #624 from Cypherock/feat/solana/compute-budget-program-priority-fee
2 parents 25d8048 + e80edc6 commit c387b9d

File tree

5 files changed

+333
-161
lines changed

5 files changed

+333
-161
lines changed

apps/solana_app/solana_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ typedef struct {
3434
uint8_t *transaction;
3535
/// store for decoded unsigned transaction info
3636
solana_unsigned_txn transaction_info;
37+
solana_txn_extra_data extra_data;
3738

3839
bool is_token_transfer_transaction;
3940
solana_sign_txn_initiate_token_data_t token_data;

apps/solana_app/solana_sign_txn.c

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262

6363
#include <ed25519-donna.h>
6464

65+
#include "int-util.h"
6566
#include "reconstruct_wallet_flow.h"
6667
#include "solana_api.h"
6768
#include "solana_contracts.h"
@@ -346,7 +347,8 @@ STATIC bool solana_fetch_valid_transaction(solana_query_t *query) {
346347
if (SOL_OK != solana_byte_array_to_unsigned_txn(
347348
solana_txn_context->transaction,
348349
total_size,
349-
&solana_txn_context->transaction_info) ||
350+
&solana_txn_context->transaction_info,
351+
&solana_txn_context->extra_data) ||
350352
SOL_OK !=
351353
solana_validate_unsigned_txn(&solana_txn_context->transaction_info)) {
352354
return false;
@@ -355,12 +357,62 @@ STATIC bool solana_fetch_valid_transaction(solana_query_t *query) {
355357
return true;
356358
}
357359

360+
static bool verify_priority_fee() {
361+
if (solana_txn_context->extra_data.compute_unit_price_micro_lamports > 0) {
362+
// verify priority fee
363+
uint64_t priority_fee, carry;
364+
365+
// Capacity to multiply 2 numbers upto 8-byte value and store the result in
366+
// 2 separate 8-byte variables
367+
priority_fee =
368+
mul128(solana_txn_context->extra_data.compute_unit_price_micro_lamports,
369+
solana_txn_context->extra_data.compute_unit_limit,
370+
&carry);
371+
372+
// prepare the whole 128-bit little-endian representation of priority fee
373+
uint8_t be_micro_lamports[16] = {0};
374+
memcpy(be_micro_lamports, &priority_fee, sizeof(priority_fee));
375+
memcpy(be_micro_lamports + sizeof(priority_fee), &carry, sizeof(carry));
376+
377+
// outputs 128-bit (16-byte) big-endian representation of priority fee
378+
cy_reverse_byte_array(be_micro_lamports, sizeof(be_micro_lamports));
379+
380+
char priority_fee_string[33] = {'\0'},
381+
priority_fee_decimal_string[34] = {'\0'};
382+
383+
byte_array_to_hex_string(be_micro_lamports,
384+
sizeof(be_micro_lamports),
385+
priority_fee_string,
386+
sizeof(priority_fee_string));
387+
if (!convert_byte_array_to_decimal_string(
388+
sizeof(priority_fee_string) - 1,
389+
solana_get_decimal() + 6, // +6 for micro
390+
priority_fee_string,
391+
priority_fee_decimal_string,
392+
sizeof(priority_fee_decimal_string))) {
393+
solana_send_error(ERROR_COMMON_ERROR_UNKNOWN_ERROR_TAG, 1);
394+
return false;
395+
}
396+
397+
char display[100] = "";
398+
snprintf(display,
399+
sizeof(display),
400+
UI_TEXT_VERIFY_PRIORITY_FEE,
401+
priority_fee_decimal_string,
402+
SOLANA_LUNIT);
403+
if (!core_confirmation(display, solana_send_error)) {
404+
return false;
405+
}
406+
}
407+
return true;
408+
}
409+
358410
static bool verify_solana_transfer_sol_transaction() {
359411
char address[45] = {0};
360412
size_t address_size = sizeof(address);
361413

362414
const uint8_t transfer_instruction_index =
363-
solana_txn_context->transaction_info.transfer_instruction_index;
415+
solana_txn_context->extra_data.transfer_instruction_index;
364416
// verify recipient address;
365417
if (!b58enc(address,
366418
&address_size,
@@ -408,6 +460,9 @@ static bool verify_solana_transfer_sol_transaction() {
408460
return false;
409461
}
410462

463+
if (!verify_priority_fee())
464+
return false;
465+
411466
set_app_flow_status(SOLANA_SIGN_TXN_STATUS_VERIFY);
412467
return true;
413468
}
@@ -535,13 +590,14 @@ static bool is_token_whitelisted(const uint8_t *address,
535590

536591
static bool verify_solana_transfer_token_transaction() {
537592
const uint8_t transfer_instruction_index =
538-
solana_txn_context->transaction_info.transfer_instruction_index;
593+
solana_txn_context->extra_data.transfer_instruction_index;
539594

540595
const uint8_t *token_mint = solana_txn_context->transaction_info
541596
.instruction[transfer_instruction_index]
542597
.program.transfer_checked.token_mint;
543-
const solana_token_program_t *contract = NULL;
544-
if (!is_token_whitelisted(token_mint, &contract)) {
598+
solana_token_program_t contract = {0};
599+
const solana_token_program_t *contract_pointer = &contract;
600+
if (!is_token_whitelisted(token_mint, &contract_pointer)) {
545601
// Contract Unverifed, Display warning
546602
delay_scr_init(ui_text_unverified_token, DELAY_TIME);
547603

@@ -570,13 +626,16 @@ static bool verify_solana_transfer_token_transaction() {
570626
.decimal = token_decimals,
571627
};
572628

573-
contract = &empty_contract;
629+
memcpy(&contract, &empty_contract, sizeof(empty_contract));
630+
574631
} else {
632+
memcpy(&contract, contract_pointer, sizeof(contract));
633+
575634
char msg[100] = "";
576635
snprintf(msg,
577636
sizeof(msg),
578637
UI_TEXT_SEND_TOKEN_PROMPT,
579-
contract->symbol,
638+
contract.symbol,
580639
SOLANA_NAME);
581640
if (!core_confirmation(msg, solana_send_error)) {
582641
return false;
@@ -632,7 +691,7 @@ static bool verify_solana_transfer_token_transaction() {
632691

633692
byte_array_to_hex_string(be_units, 8, amount_string, sizeof(amount_string));
634693
if (!convert_byte_array_to_decimal_string(16,
635-
contract->decimal,
694+
contract.decimal,
636695
amount_string,
637696
amount_decimal_string,
638697
sizeof(amount_decimal_string))) {
@@ -644,11 +703,14 @@ static bool verify_solana_transfer_token_transaction() {
644703
sizeof(display),
645704
UI_TEXT_VERIFY_AMOUNT,
646705
amount_decimal_string,
647-
contract->symbol);
706+
contract.symbol);
648707
if (!core_confirmation(display, solana_send_error)) {
649708
return false;
650709
}
651710

711+
if (!verify_priority_fee())
712+
return false;
713+
652714
set_app_flow_status(SOLANA_SIGN_TXN_STATUS_VERIFY);
653715
return true;
654716
}

0 commit comments

Comments
 (0)