Skip to content

Commit 85b3ac0

Browse files
committed
eth/erc20_params: group tokens also by unit len to save more bytes
This way we don't have to repeat storing the length of the unit string (if using `&str`) and also not repeat the 0-terminator (if using C-style strings) per token, shaving off another ~1 byte per token in the firmware binary (currently ~ -1600 bytes).
1 parent fedfdbf commit 85b3ac0

File tree

2 files changed

+26
-17
lines changed

2 files changed

+26
-17
lines changed

src/rust/erc20_params/build.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ fn main() {
5353
}
5454

5555
// Group tokens by decimals
56-
let mut grouped_tokens: HashMap<u8, Vec<&Token>> = HashMap::new();
56+
let mut grouped_tokens: HashMap<(u8, u8), Vec<&Token>> = HashMap::new();
5757
for token in &tokens {
5858
grouped_tokens
59-
.entry(token.decimals)
59+
.entry((token.decimals, token.unit.len().try_into().unwrap()))
6060
.or_default()
6161
.push(token);
6262
}
@@ -69,12 +69,17 @@ fn main() {
6969
.open(out_filename)
7070
.unwrap();
7171

72-
for (decimals, tokens) in &grouped_tokens {
73-
writeln!(output_file, "const PARAMS_{}: &[P] = &[", decimals).unwrap();
72+
for ((decimals, unit_len), tokens) in &grouped_tokens {
73+
writeln!(
74+
output_file,
75+
"const PARAMS_D{}_U{}: &[P] = &[",
76+
decimals, unit_len
77+
)
78+
.unwrap();
7479
for token in tokens {
7580
writeln!(
7681
output_file,
77-
" P {{ unit: b\"{}\\0\".as_ptr(), contract_address: *b\"{}\" }},",
82+
" P {{ unit: b\"{}\".as_ptr(), contract_address: *b\"{}\" }},",
7883
token.unit,
7984
token
8085
.contract_address
@@ -87,14 +92,15 @@ fn main() {
8792
writeln!(output_file, "];").unwrap();
8893
}
8994

90-
let mut decimals_vec: Vec<u8> = grouped_tokens.keys().cloned().collect();
91-
decimals_vec.sort();
9295
writeln!(
9396
output_file,
94-
"const ALL: &[(u8, &[P])] = &[{}];",
95-
decimals_vec
96-
.iter()
97-
.map(|decimal| format!("({}, PARAMS_{})", decimal, decimal))
97+
"const ALL: &[(u8, u8, &[P])] = &[{}];",
98+
grouped_tokens
99+
.keys()
100+
.map(|(decimal, unit_len)| format!(
101+
"({}, {}, PARAMS_D{}_U{})",
102+
decimal, unit_len, decimal, unit_len
103+
))
98104
.collect::<Vec<String>>()
99105
.join(", ")
100106
)

src/rust/erc20_params/src/lib.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,14 @@ pub struct Params {
3131
}
3232

3333
impl Params {
34-
fn from_p(p: &P, decimals: u8) -> Self {
34+
fn from_p(p: &P, decimals: u8, unit_len: u8) -> Self {
3535
Params {
36-
unit: (unsafe { core::ffi::CStr::from_ptr(p.unit as *const i8) })
37-
.to_str()
38-
.unwrap(),
36+
unit: unsafe {
37+
core::str::from_utf8_unchecked(core::slice::from_raw_parts(
38+
p.unit,
39+
unit_len as usize,
40+
))
41+
},
3942
contract_address: p.contract_address,
4043
decimals,
4144
}
@@ -52,11 +55,11 @@ pub fn get(chain_id: u64, contract_address: [u8; 20]) -> Option<Params> {
5255
if chain_id != 1 {
5356
return None;
5457
}
55-
for &(decimals, params) in ALL.iter() {
58+
for &(decimals, unit_len, params) in ALL.iter() {
5659
let result = params
5760
.iter()
5861
.find(|p| p.contract_address == contract_address)
59-
.map(|p| Params::from_p(p, decimals));
62+
.map(|p| Params::from_p(p, decimals, unit_len));
6063
if result.is_some() {
6164
return result;
6265
}

0 commit comments

Comments
 (0)