Skip to content
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 HWM settings in Ledger #91

Merged
merged 2 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ compile_commands.json
# Documentation files
doc/html
doc/latex
# Pytest temporary snapshots
test/snapshots-tmp
21 changes: 6 additions & 15 deletions src/apdu_query.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,14 @@ int handle_query_all_hwm(void) {
write_u32_be(resp, offset, N_data.hwm.main.highest_level);
offset += sizeof(uint32_t);

bool has_a_chain_migrated =
N_data.hwm.main.migrated_to_tenderbake || N_data.hwm.test.migrated_to_tenderbake;

if (has_a_chain_migrated) {
write_u32_be(resp, offset, N_data.hwm.main.highest_round);
offset += sizeof(uint32_t);
}
write_u32_be(resp, offset, N_data.hwm.main.highest_round);
offset += sizeof(uint32_t);

write_u32_be(resp, offset, N_data.hwm.test.highest_level);
offset += sizeof(uint32_t);

if (has_a_chain_migrated) {
write_u32_be(resp, offset, N_data.hwm.test.highest_round);
offset += sizeof(uint32_t);
}
write_u32_be(resp, offset, N_data.hwm.test.highest_round);
offset += sizeof(uint32_t);

write_u32_be(resp, offset, N_data.main_chain_id.v);
offset += sizeof(uint32_t);
Expand All @@ -69,10 +62,8 @@ int handle_query_main_hwm(void) {
write_u32_be(resp, offset, N_data.hwm.main.highest_level);
offset += sizeof(uint32_t);

if (N_data.hwm.main.migrated_to_tenderbake) {
write_u32_be(resp, offset, N_data.hwm.main.highest_round);
offset += sizeof(uint32_t);
}
write_u32_be(resp, offset, N_data.hwm.main.highest_round);
offset += sizeof(uint32_t);

return io_send_response_pointer(resp, offset, SW_OK);
}
Expand Down
2 changes: 0 additions & 2 deletions src/apdu_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,10 @@ static bool ok(void) {
ram->hwm.main.highest_round = 0;
ram->hwm.main.had_attestation = false;
ram->hwm.main.had_preattestation = false;
ram->hwm.main.migrated_to_tenderbake = false;
ram->hwm.test.highest_level = G.hwm.test;
ram->hwm.test.highest_round = 0;
ram->hwm.test.had_attestation = false;
ram->hwm.test.had_preattestation = false;
ram->hwm.test.migrated_to_tenderbake = false;
});

provide_pubkey(&global.path_with_curve);
Expand Down
1 change: 0 additions & 1 deletion src/baking_auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ tz_exc write_high_water_mark(parsed_baking_data_t const *const in) {
dest->highest_round = in->round;
dest->had_attestation |= in->type == BAKING_TYPE_ATTESTATION;
dest->had_preattestation |= in->type == BAKING_TYPE_PREATTESTATION;
dest->migrated_to_tenderbake |= in->is_tenderbake;
});

end:
Expand Down
4 changes: 4 additions & 0 deletions src/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ void init_globals(void) {
memset(&global, 0, sizeof(global));
}

void toggle_hwm(void) {
UPDATE_NVRAM(ram, { ram->hwm_disabled = !ram->hwm_disabled; });
}

// DO NOT TRY TO INIT THIS. This can only be written via an system call.
// The "N_" is *significant*. It tells the linker to put this in NVRAM.
nvram_data const N_data_real;
Expand Down
8 changes: 8 additions & 0 deletions src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ void clear_apdu_globals(void);
*/
void init_globals(void);

/**
* @brief Toggle high watermark tracking by Ledger.
*
* if its off, the responsibility to track watermark for blocks/attestation signed falls on the
* signer being used.
*/
void toggle_hwm(void);

/// Maximum number of bytes in a single APDU
#define MAX_APDU_SIZE 235u

Expand Down
34 changes: 19 additions & 15 deletions src/to_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,25 +305,29 @@ int hwm_to_string(char *dest, size_t dest_size, high_watermark_t const *const hw
if (dest == NULL) {
return -1;
}
if (hwm->migrated_to_tenderbake) {
int result = number_to_string(dest, dest_size, hwm->highest_level);
if (result < 0) {
return result;
}
size_t offset = (size_t) result;
int result = number_to_string(dest, dest_size, hwm->highest_level);
if (result < 0) {
return result;
}
size_t offset = (size_t) result;

dest[offset] = ' ';
offset++;
dest[offset] = ' ';
offset++;

result = number_to_string(dest + offset, dest_size - offset, hwm->highest_round);
if (result < 0) {
return result;
}
result = number_to_string(dest + offset, dest_size - offset, hwm->highest_round);
if (result < 0) {
return result;
}

return offset + (size_t) result;
} else {
return number_to_string(dest, dest_size, hwm->highest_level);
return offset + (size_t) result;
}

int hwm_status_to_string(char *dest, size_t dest_size, volatile bool const *hwm_disabled) {
if ((dest == NULL) || (dest_size < 9u)) {
return -1;
}
memcpy(dest, *hwm_disabled ? "Disabled" : "Enabled", dest_size);
return dest_size;
}

int copy_string(char *const dest, size_t const dest_size, char const *const src) {
Expand Down
9 changes: 9 additions & 0 deletions src/to_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ int microtez_to_string(char *const dest, size_t dest_size, uint64_t number);
*/
int hwm_to_string(char *dest, size_t dest_size, high_watermark_t const *const hwm);

/**
* @brief Converts hwm status to string (Enabled/Disabled)
* @param dest output buffer
* @param dest_size output size >= 9u
* @param hwm_disabled High watermark status from NVRAM
* @return size of the result, negative integer on failure.
*/
int hwm_status_to_string(char *dest, size_t dest_size, volatile bool const *hwm_disabled);

/**
* @brief Copies a string in a buffer
*
Expand Down
25 changes: 15 additions & 10 deletions src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ typedef enum {
DERIVATION_TYPE_ED25519 = 3,
DERIVATION_TYPE_BIP32_ED25519 = 4
} derivation_type_t;

typedef enum {
SIGNATURE_TYPE_UNSET = 0,
SIGNATURE_TYPE_SECP256K1 = 1,
Expand Down Expand Up @@ -178,11 +179,10 @@ static inline bool bip32_path_with_curve_eq(bip32_path_with_curve_t volatile con
*
*/
typedef struct {
level_t highest_level; ///< highest level seen
round_t highest_round; ///< highest round seen
bool had_attestation; ///< if an attestation has been seen at current level/round
bool had_preattestation; ///< if a pre-attestation has been seen at current level/round
bool migrated_to_tenderbake; ///< if chain has migrated to tenderbake
level_t highest_level; ///< highest level seen
round_t highest_round; ///< highest round seen
bool had_attestation; ///< if an attestation has been seen at current level/round
bool had_preattestation; ///< if a pre-attestation has been seen at current level/round
} high_watermark_t;

/**
Expand All @@ -197,12 +197,17 @@ typedef struct {
high_watermark_t main; ///< HWM of main
high_watermark_t test; ///< HWM of test
} hwm;

bip32_path_with_curve_t baking_key; ///< authorized key
bool hwm_disabled; /**< Set HWM setting on/off,
e.g. if you are using signer assisted HWM,
no need to track HWM using Ledger.*/
} nvram_data;

#define SIGN_HASH_SIZE 32u // TODO: Rename or use a different constant.

#define PKH_STRING_SIZE 40u // includes null byte // TODO: use sizeof for this.
#define HWM_STATUS_SIZE 9u // HWM status takes values Enabled and Disabled.
#define PROTOCOL_HASH_BASE58_STRING_SIZE \
sizeof("ProtoBetaBetaBetaBetaBetaBetaBetaBetaBet11111a5ug96")

Expand All @@ -226,11 +231,11 @@ typedef struct {
*
*/
typedef struct parsed_contract {
uint8_t originated; ///< a lightweight bool
signature_type_t
signature_type; ///< 0 in originated case
///< An implicit contract with signature_type of 0 means not present
uint8_t hash[HASH_SIZE]; ///< hash of the contract
uint8_t originated; ///< a lightweight bool
signature_type_t signature_type; /**< 0 in originated case
An implicit contract with signature_type of 0
means not present*/
uint8_t hash[HASH_SIZE]; ///< hash of the contract
} parsed_contract_t;

/**
Expand Down
33 changes: 31 additions & 2 deletions src/ui_bagl.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,15 @@ typedef struct {
char chain_id[CHAIN_ID_BASE58_STRING_SIZE];
char authorized_key[PKH_STRING_SIZE];
char hwm[MAX_INT_DIGITS + 1u + MAX_INT_DIGITS + 1u];
char hwm_status[HWM_STATUS_SIZE];
spalmer25 marked this conversation as resolved.
Show resolved Hide resolved
} HomeContext_t;

/// Current home context
static HomeContext_t home_context;

void ui_settings(void); ///> Initialize settings page
void ui_toggle_hwm(void); ///> Toggle HWM settings
void ui_menu_init(void); ///> Load main menu page
/**
* @brief Idle flow
*
Expand All @@ -68,6 +72,7 @@ UX_STEP_NOCB(ux_app_is_ready_step, nn, {"Application", "is ready"});
UX_STEP_NOCB(ux_version_step, bnnn_paging, {"Tezos Baking", APPVERSION});
UX_STEP_NOCB(ux_chain_id_step, bnnn_paging, {"Chain", home_context.chain_id});
UX_STEP_NOCB(ux_authorized_key_step, bnnn_paging, {"Public Key Hash", home_context.authorized_key});
UX_STEP_CB(ux_settings_step, pb, ui_settings(), {&C_icon_coggle, "Settings"});
UX_STEP_CB(ux_hwm_step,
bnnn_paging,
ui_refresh_idle_hwm_screen(),
Expand All @@ -80,9 +85,34 @@ UX_FLOW(ux_idle_flow,
&ux_chain_id_step,
&ux_authorized_key_step,
&ux_hwm_step,
&ux_settings_step,
&ux_idle_quit_step,
FLOW_LOOP);

void ui_menu_init(void) {
ux_flow_init(0, ux_idle_flow, NULL);
}

UX_STEP_CB(ux_hwm_info, bn, ui_toggle_hwm(), {"High Watermark", home_context.hwm_status});
UX_STEP_CB(ux_menu_back_step, pb, ui_menu_init(), {&C_icon_back, "Back"});

// FLOW for the about submenu:
// #1 screen: app info
// #2 screen: back button to main menu
UX_FLOW(ux_settings_flow, &ux_hwm_info, &ux_menu_back_step, FLOW_LOOP);

void ui_settings(void) {
hwm_status_to_string(home_context.hwm_status,
sizeof(home_context.hwm_status),
&N_data.hwm_disabled);
ux_flow_init(0, ux_settings_flow, NULL);
}

void ui_toggle_hwm(void) {
toggle_hwm();
ui_settings();
}

tz_exc calculate_idle_screen_chain_id(void) {
tz_exc exc = SW_OK;

Expand Down Expand Up @@ -152,8 +182,7 @@ void ui_initial_screen(void) {

TZ_CHECK(calculate_baking_idle_screens_data());

ux_flow_init(0, ux_idle_flow, NULL);

ui_menu_init();
return;
end:
TZ_EXC_PRINT(exc);
Expand Down
Loading
Loading