Skip to content

Commit f71fe57

Browse files
committed
rust: proper bip39 async unlock combined with unlock animation
We join the bip39 async task and the unlock animation task to run in tandem until both are finished. The old interrupt-timer based lock animation is now unused and deleted.
1 parent d04bcb8 commit f71fe57

File tree

11 files changed

+61
-250
lines changed

11 files changed

+61
-250
lines changed

src/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ set(DBB-FIRMWARE-USB-SOURCES ${DBB-FIRMWARE-USB-SOURCES} PARENT_SCOPE)
5353
set(DBB-FIRMWARE-UI-SOURCES
5454
${CMAKE_SOURCE_DIR}/src/screen.c
5555
${CMAKE_SOURCE_DIR}/src/ui/graphics/graphics.c
56-
${CMAKE_SOURCE_DIR}/src/ui/graphics/lock_animation.c
5756
${CMAKE_SOURCE_DIR}/src/ui/ugui/ugui.c
5857
${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_9X9.c
5958
${CMAKE_SOURCE_DIR}/src/ui/fonts/font_a_11X10.c

src/rust/bitbox02-rust/src/workflow/unlock.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ pub async fn unlock_bip39(hal: &mut impl crate::hal::Hal, seed: &[u8]) {
133133
}
134134
}
135135

136-
let result = bitbox02::ui::with_lock_animation(async || {
136+
let ((), result) = util::bb02_async::join(
137+
super::unlock_animation::animate(),
137138
keystore::unlock_bip39(
138139
crate::secp256k1::SECP256K1,
139140
seed,
@@ -146,10 +147,10 @@ pub async fn unlock_bip39(hal: &mut impl crate::hal::Hal, seed: &[u8]) {
146147
// iteration to a minimum.
147148
#[cfg(not(feature = "c-unit-testing"))]
148149
async |_idx| util::bb02_async::yield_now().await,
149-
)
150-
.await
151-
})
150+
),
151+
)
152152
.await;
153+
153154
if result.is_err() {
154155
abort("bip39 unlock failed");
155156
}

src/rust/bitbox02-sys/build.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,6 @@ const ALLOWLIST_FNS: &[&str] = &[
8686
"keystore_test_get_retained_bip39_seed_encrypted",
8787
"label_create",
8888
"localtime",
89-
"lock_animation_start",
90-
"lock_animation_stop",
9189
"memory_set_salt_root",
9290
"memory_add_noise_remote_static_pubkey",
9391
"memory_bootloader_hash",
@@ -215,6 +213,7 @@ const BITBOX02_SOURCES: &[&str] = &[
215213
"src/ui/components/label.c",
216214
"src/ui/components/left_arrow.c",
217215
"src/ui/components/lockscreen.c",
216+
"src/ui/components/unlock_animation.c",
218217
"src/ui/components/menu.c",
219218
"src/ui/components/orientation_arrows.c",
220219
"src/ui/components/progress.c",
@@ -238,7 +237,6 @@ const BITBOX02_SOURCES: &[&str] = &[
238237
"src/ui/fonts/password_11X12.c",
239238
"src/ui/fonts/password_9X9.c",
240239
"src/ui/graphics/graphics.c",
241-
"src/ui/graphics/lock_animation.c",
242240
"src/ui/oled/sh1107.c",
243241
"src/ui/oled/ssd1312.c",
244242
"src/ui/screen_process.c",

src/rust/bitbox02-sys/wrapper.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
#include <ui/fonts/font_a_9X9.h>
4545
#include <ui/fonts/monogram_5X9.h>
4646
#include <ui/fonts/password_11X12.h>
47-
#include <ui/graphics/lock_animation.h>
4847
#include <ui/oled/oled.h>
4948
#include <ui/screen_process.h>
5049
#include <ui/screen_saver.h>

src/rust/bitbox02/src/ui/ui.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -436,13 +436,6 @@ pub fn trinary_input_string_set_input(component: &mut Component, word: &str) {
436436
}
437437
}
438438

439-
pub async fn with_lock_animation<F: AsyncFn() -> R, R>(f: F) -> R {
440-
unsafe { bitbox02_sys::lock_animation_start() };
441-
let result = f().await;
442-
unsafe { bitbox02_sys::lock_animation_stop() };
443-
result
444-
}
445-
446439
pub fn screen_stack_pop_all() {
447440
unsafe {
448441
bitbox02_sys::ui_screen_stack_pop_all();

src/rust/bitbox02/src/ui/ui_stub.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,6 @@ pub fn trinary_input_string_set_input(_component: &mut Component, _word: &str) {
119119
panic!("not used")
120120
}
121121

122-
pub fn with_lock_animation<F: Fn() -> R, R>(f: F) -> R {
123-
f()
124-
}
125-
126122
pub fn screen_stack_pop_all() {}
127123

128124
pub fn progress_create<'a>(_title: &str) -> Component<'a> {

src/rust/bitbox02/src/ui/ui_stub_c_unit_tests.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,6 @@ pub fn trinary_input_string_set_input(_component: &mut Component, _word: &str) {
162162
panic!("not implemented")
163163
}
164164

165-
pub fn with_lock_animation<F: Fn() -> R, R>(f: F) -> R {
166-
f()
167-
}
168-
169165
pub fn screen_stack_pop_all() {}
170166

171167
pub fn progress_create<'a>(_title: &str) -> Component<'a> {

src/rust/util/src/bb02_async.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,38 @@ pub fn yield_now() -> impl core::future::Future<Output = ()> {
7474
})
7575
}
7676

77+
/// Executes both futures in tandem, returning the results of both when both are done.
78+
pub fn join<O1, O2>(
79+
fut1: impl core::future::Future<Output = O1>,
80+
fut2: impl core::future::Future<Output = O2>,
81+
) -> impl core::future::Future<Output = (O1, O2)> {
82+
let mut fut1 = Box::pin(fut1);
83+
let mut fut2 = Box::pin(fut2);
84+
85+
let mut result1 = None;
86+
let mut result2 = None;
87+
88+
core::future::poll_fn(move |cx| {
89+
if result1.is_none() {
90+
if let Poll::Ready(res) = fut1.as_mut().poll(cx) {
91+
result1 = Some(res);
92+
}
93+
}
94+
95+
if result2.is_none() {
96+
if let Poll::Ready(res) = fut2.as_mut().poll(cx) {
97+
result2 = Some(res);
98+
}
99+
}
100+
101+
if result1.is_some() && result2.is_some() {
102+
Poll::Ready((result1.take().unwrap(), result2.take().unwrap()))
103+
} else {
104+
Poll::Pending
105+
}
106+
})
107+
}
108+
77109
#[cfg(test)]
78110
mod tests {
79111
use super::*;
@@ -93,4 +125,21 @@ mod tests {
93125
assert_eq!(spin(&mut task), Poll::Pending);
94126
assert_eq!(spin(&mut task), Poll::Ready(42));
95127
}
128+
129+
#[test]
130+
fn test_join() {
131+
async fn f1() -> i32 {
132+
-42
133+
}
134+
135+
async fn f2() -> Box<u32> {
136+
yield_now().await;
137+
yield_now().await;
138+
yield_now().await;
139+
Box::new(42)
140+
}
141+
142+
assert_eq!(block_on(join(f1(), f2())), (-42, Box::new(42)));
143+
assert_eq!(block_on(join(f2(), f1())), (Box::new(42), -42));
144+
}
96145
}

src/ui/components/unlock_animation.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <hardfault.h>
1818
#include <screen.h>
1919
#include <ui/component.h>
20+
#include <ui/screen_process.h>
2021
#include <ui/ui_util.h>
2122

2223
#include <stdint.h>
@@ -25,7 +26,11 @@
2526
// This many iterations times the slowdown factor to render the whole animation.
2627
#define LOCK_ANIMATION_N_FRAMES (38)
2728

28-
#define SLOWDOWN_FACTOR (10)
29+
// Since BIP39 unlock takes 2048 iterations, and the screen frame rate is 30 (SCREEN_FRAME_RATE,
30+
// render is called only every 30th iteration), if we want both to finish at the same time, the
31+
// slowdown factor becomes the following. 1 is subtracted so the animation takes longer, not
32+
// shorter, than the actual unlock.
33+
#define SLOWDOWN_FACTOR (2048 / ((float)LOCK_ANIMATION_N_FRAMES * (float)SCREEN_FRAME_RATE - 1))
2934

3035
#define LOCK_ANIMATION_FRAME_WIDTH (28)
3136
#define LOCK_ANIMATION_FRAME_HEIGHT (25)

src/ui/graphics/lock_animation.c

Lines changed: 0 additions & 204 deletions
This file was deleted.

0 commit comments

Comments
 (0)