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

Refactoring and Stax UX revamp #270

Merged
merged 25 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7e4acf4
Split process_outputs into two separate preprocess_outputs and displa…
bigspider Jun 28, 2024
721ec16
Add simplified transaction validation on devices with a large screen …
bigspider Jul 2, 2024
e2a1e18
Simplify and refactor swap code.
bigspider Jul 3, 2024
3ccbf62
Use cached output info if available
bigspider Jul 3, 2024
705f4d2
Move wallet policy header into the global transaction signing state
bigspider Jul 3, 2024
6c2be42
Incorporate warnings in the simplified transaction UX
bigspider Jul 4, 2024
d239361
Update self-transfer screen; support self-transfers in the simplified…
bigspider Jul 5, 2024
aff17b2
Updated sign_psbt tests to reflect the new UX.
bigspider Jul 5, 2024
3d754f7
Increase threshold for high-fee-warning to 100k sats instead of 10k sats
bigspider Jul 8, 2024
622b04e
Format transaction amounts as "<amount> TICKER" on large screens
bigspider Jul 8, 2024
bb59e60
Align wording of the 'send transaction' flow to design guidelines
bigspider Jul 8, 2024
81f6efd
Show the 'Processing...' spinner immediately when signing starts, ins…
bigspider Jul 8, 2024
c0ffdb6
Remove obsolete code
bigspider Jul 8, 2024
a03429b
Introduce a limit of 10 keys in a supported wallet policy
bigspider Jul 8, 2024
128786b
Revamp and simplify the 'register wallet policy' when using NBGL
bigspider Jul 9, 2024
783aa15
Update wallet policy registration tests
bigspider Jul 9, 2024
67f4135
Update wording 'wallet policy' ==> 'account' also for BAGL devices
bigspider Jul 9, 2024
4023ff8
Update test with the new key limit of 10
bigspider Jul 9, 2024
4b1f0e0
Fix formatting of OP_RETURN outputs with a data push for 0x00
bigspider Jul 9, 2024
1852840
Bump version to 2.2.4; update CHANGELOG.md
bigspider Jul 9, 2024
13cca55
Update speculos automation strings
bigspider Jul 9, 2024
e9c355d
Initialize array (deal with false positive in clang static analyzer)
bigspider Jul 9, 2024
0886412
Update address verification flow to use the standard NBGL api; switch…
bigspider Jul 10, 2024
a314da7
Update ragger snapshots
bigspider Jul 9, 2024
40c3623
Update Stax snapshots to API level 21
bigspider Jul 12, 2024
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
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

Dates are in `dd-mm-yyyy` format.

## [2.2.4] - 09-07-2024

### Changed

- Major revamp of the UI for transaction signing and wallet policy registration on Stax. Changed "wallet policy" with the simpler wording "account".
- Slight performance improvements in the signing flow.
- Added a technical limit of at most 10 distinct cosigners in a wallet policy.

### Fixed

- OP_RETURN outputs with a `0x00` data push were incorrectly rejected.

## [2.2.3] - 06-05-2024

### Added
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ PATH_SLIP21_APP_LOAD_PARAMS = "LEDGER-Wallet policy"
# Application version
APPVERSION_M = 2
APPVERSION_N = 2
APPVERSION_P = 3
APPVERSION_P = 4
APPVERSION_SUFFIX = # if not empty, appended at the end. Do not add a dash.

ifeq ($(APPVERSION_SUFFIX),)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"version": 1,
"rules": [
{
"regexp": "Register wallet|Wallet name|Wallet policy|Key",
"regexp": "Register account|Account name|Wallet policy|Key",
"actions": [
["button", 2, true],
["button", 2, false]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"version": 1,
"rules": [
{
"regexp": "Spend from|Wallet name|Review|Amount|Address|Fees",
"regexp": "Spend from|Account name|Review|Amount|Address|Fees",
"actions": [
["button", 2, true],
["button", 2, false]
Expand Down
28 changes: 15 additions & 13 deletions ragger_bitcoin/ragger_instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,22 @@ def nano_skip_screen(self, text, save_screenshot=True):
self.new_request(text, NavInsID.RIGHT_CLICK, NavInsID.RIGHT_CLICK,
save_screenshot=save_screenshot)

def navigate_end_of_flow(self, save_screenshot=True):
self.new_request("Processing", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP,
save_screenshot=save_screenshot)

def review_start(self, output_count: int = 1, save_screenshot=True):
def review_start(self, output_count: int = 1, save_screenshot=True, has_warning=False):
self.new_request("Review", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP,
save_screenshot=save_screenshot)
for _ in range(0, output_count):
self.new_request("Amount", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP,
save_screenshot=save_screenshot)
save_screenshot=save_screenshot)

if has_warning:
self.same_request("Warning", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_CHOICE_CONFIRM,
save_screenshot=save_screenshot)

for output_index in range(0, output_count):
# the initial 2 outputs are cached; that depends on the N_CACHED_EXTERNAL_OUTPUTS constant
if output_index < 2:
self.same_request("Amount", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP,
save_screenshot=save_screenshot)
else:
self.new_request("Amount", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP,
save_screenshot=save_screenshot)
def review_fees(self, fees_on_same_request: bool = True, save_screenshot=True):
if fees_on_same_request:
self.same_request("Fees", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP,
Expand Down Expand Up @@ -94,10 +100,6 @@ def reject_message(self, save_screenshot=True):
self.new_request("Message", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_STATUS_DISMISS,
save_screenshot=save_screenshot)

def warning_accept(self, save_screenshot=True):
self.new_request("Warning", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_CHOICE_CONFIRM,
save_screenshot=save_screenshot)

def address_confirm(self, save_screenshot=True):
self.new_request("Confirm", NavInsID.USE_CASE_REVIEW_TAP,
NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CONFIRM,
Expand Down
27 changes: 15 additions & 12 deletions src/boilerplate/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,20 @@ void io_reset_timeouts() {
G_was_processing_screen_shown = false;
}

void io_show_processing_screen() {
if (!G_was_processing_screen_shown) {
G_was_processing_screen_shown = true;
if (!G_swap_state.called_from_swap) {
#ifdef HAVE_BAGL
ux_flow_init(0, ux_processing_flow, NULL);
#endif // HAVE_BAGL
#ifdef HAVE_NBGL
nbgl_useCaseSpinner("Processing");
#endif // HAVE_NBGL
}
}
}

uint8_t io_event(uint8_t channel) {
(void) channel;

Expand Down Expand Up @@ -121,18 +135,7 @@ uint8_t io_event(uint8_t channel) {
G_ticks - G_processing_timeout_start_tick >= PROCESSING_TIMEOUT_TICKS) {
io_clear_processing_timeout();

if (!G_was_processing_screen_shown) {
G_was_processing_screen_shown = true;
#ifdef HAVE_BAGL
ux_flow_init(0, ux_processing_flow, NULL);
#endif // HAVE_BAGL
#ifdef HAVE_NBGL

if (!G_swap_state.called_from_swap) {
nbgl_useCaseSpinner("Processing");
}
#endif // HAVE_NBGL
}
io_show_processing_screen();
}

if (G_is_timeout_active.interruption &&
Expand Down
5 changes: 5 additions & 0 deletions src/boilerplate/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ void io_clear_processing_timeout();
*/
void io_reset_timeouts();

/**
* Shows the "Processing..." screen.
*/
void io_show_processing_screen();

/**
* TODO: docs
*/
Expand Down
6 changes: 0 additions & 6 deletions src/common/base58.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,8 @@ char const BASE58_ALPHABET[] = {
};

int base58_decode(const char *in, size_t in_len, uint8_t *out, size_t out_len) {
#ifdef USE_CXRAM_SECTION
// allocate buffers inside the cxram section; safe as there are no syscalls here
uint8_t *tmp = get_cxram_buffer(); // MAX_DEC_INPUT_SIZE bytes buffer
uint8_t *buffer = get_cxram_buffer() + MAX_DEC_INPUT_SIZE; // MAX_DEC_INPUT_SIZE bytes buffer
#else
uint8_t tmp[MAX_DEC_INPUT_SIZE] = {0};
uint8_t buffer[MAX_DEC_INPUT_SIZE] = {0};
#endif

memset(tmp, 0, MAX_DEC_INPUT_SIZE);
memset(buffer, 0, MAX_DEC_INPUT_SIZE);
Expand Down
25 changes: 23 additions & 2 deletions src/common/script.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,8 @@ int format_opscript_script(const uint8_t script[],
}

if (hex_length == 1) {
if (script[offset] == 0x81 || script[offset] <= 16) {
// non-standard, it should use OP_1NEGATE, or one of OP_0, ..., OP_16
if (script[offset] == 0x81 || (1 <= script[offset] && script[offset] <= 16)) {
// non-standard, it should use OP_1NEGATE, or one of OP_1, ..., OP_16
return -1;
}
}
Expand Down Expand Up @@ -219,3 +219,24 @@ int format_opscript_script(const uint8_t script[],
out[out_ctr - 1] = '\0';
return out_ctr;
}

#ifndef SKIP_FOR_CMOCKA

bool format_script(const uint8_t script[],
size_t script_len,
char out[static MAX_OUTPUT_SCRIPT_DESC_SIZE]) {
int address_len = get_script_address(script, script_len, out, MAX_OUTPUT_SCRIPT_DESC_SIZE);
if (address_len < 0) {
// script does not have an address; check if OP_RETURN
if (is_opreturn(script, script_len)) {
if (0 > format_opscript_script(script, script_len, out)) {
return false;
}
} else {
return false;
}
}
return true;
}

#endif
25 changes: 24 additions & 1 deletion src/common/script.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#pragma once

#include "os.h"

#include "../constants.h"

/** Script opcodes */
// from bitcoin-core
enum opcodetype {
Expand Down Expand Up @@ -232,4 +236,23 @@ int get_script_address(const uint8_t script[], size_t script_len, char *out, siz
*/
int format_opscript_script(const uint8_t script[],
size_t script_len,
char out[static MAX_OPRETURN_OUTPUT_DESC_SIZE]);
char out[static MAX_OPRETURN_OUTPUT_DESC_SIZE]);

// the maximum length of the description of an output that we can display (address or OP_RETURN),
// including the terminating null character
#define MAX_OUTPUT_SCRIPT_DESC_SIZE MAX(MAX_ADDRESS_LENGTH_STR + 1, MAX_OPRETURN_OUTPUT_DESC_SIZE)

/**
* Formats a bitcoin Script in the format that is displayed to the user. Only scripts with an
* address are supported, or OP_RETURN scripts as documented in format_opscript_script.
*
* The string is written onto `out` and is 0-terminated.
*
* @param[in] script the script to parse and format.
* @param[in] script_len the length of the script.
* @param[out] out the output array, that must be at least MAX_OPRETURN_OUTPUT_DESC_SIZE bytes long.
* @return `true` the script is a supported one that can be shown to the user, `false` otherwise.
*/
bool format_script(const uint8_t script[],
size_t script_len,
char out[static MAX_OUTPUT_SCRIPT_DESC_SIZE]);
4 changes: 0 additions & 4 deletions src/common/wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1969,8 +1969,6 @@ static int16_t maxcheck(int16_t a, int16_t b) {
// Maximum supported value for n in a thresh miniscript operator (technical limitation)
#define MAX_N_IN_THRESH 128

// Separated from the main function as it is stack-intensive, therefore we allocate large buffers
// into the CXRAM section. There is some repeated work ()
static int compute_thresh_ops(const policy_node_thresh_t *node,
miniscript_ops_t *out,
MiniscriptContext ctx) {
Expand Down Expand Up @@ -2010,8 +2008,6 @@ static int compute_thresh_ops(const policy_node_thresh_t *node,
return 0;
}

// Separated from the main function as it is stack-intensive, therefore we allocate large buffers
// into the CXRAM section. There is some repeated work ()
static int compute_thresh_stacksize(const policy_node_thresh_t *node,
miniscript_stacksize_t *out,
MiniscriptContext ctx) {
Expand Down
4 changes: 4 additions & 0 deletions src/common/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
// longest supported policy in V1 is "sh(wsh(sortedmulti(5,@0,@1,@2,@3,@4)))", 38 bytes
#define MAX_DESCRIPTOR_TEMPLATE_LENGTH_V1 40

// Maximum number of keys supported for a wallet policy. It is a technical limit to
// bound the total memory occupation of a wallet policy, and could be increased if necessary.
#define MAX_N_KEYS_IN_WALLET_POLICY 10

// This amount should be enough for many useful policies
// We do not expect these limits to be reached in practice any time soon, but they can
// be further increased if necessary.
Expand Down
5 changes: 5 additions & 0 deletions src/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@
*/
#define MAX_N_INPUTS_CAN_SIGN 512

/**
* Maximum number of outputs supported while signing a transaction.
*/
#define MAX_N_OUTPUTS_CAN_SIGN 512

// SIGHASH flags
#define SIGHASH_DEFAULT 0x00000000
#define SIGHASH_ALL 0x00000001
Expand Down
Loading
Loading