Skip to content

Commit 6e9567b

Browse files
Migrates Barz and Eth Address APIs to Rust (trustwallet#4422)
* Migrates Barz and Eth Address APIs to rust * Adds FFI tests and migrate C++ tests * FMT * Fixes memory leak * Fixes invalid ptr issue * Another try * Addresses review comments * Addresses review comments * Addresses review comment --------- Co-authored-by: Sergei Boiko <[email protected]>
1 parent fdbfb61 commit 6e9567b

File tree

50 files changed

+2017
-980
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2017
-980
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ include/TrustWalletCore/TWWalletConnectRequest.h
5151
include/TrustWalletCore/TWSolanaTransaction.h
5252
include/TrustWalletCore/TWCryptoBoxPublicKey.h
5353
include/TrustWalletCore/TWCryptoBoxSecretKey.h
54+
include/TrustWalletCore/TWEthereum.h
55+
include/TrustWalletCore/TWBarz.h
5456

5557
# Wasm
5658
emsdk/

codegen-v2/src/codegen/cpp/code_gen.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,15 @@ fn generate_return_type(func: &TWFunction, converted_args: &Vec<String>) -> Resu
235235
.map_err(|e| BadFormat(e.to_string()))?;
236236
}
237237
(TWPointerType::NonnullMut, "TWString") | (TWPointerType::Nonnull, "TWString") => {
238-
panic!("Nonnull TWString is not supported");
238+
write!(
239+
&mut return_string,
240+
"\tconst Rust::TWStringWrapper result = Rust::{}{}\n\
241+
\tconst auto resultString = result.toStringOrDefault();\n\
242+
\treturn TWStringCreateWithUTF8Bytes(resultString.c_str());\n",
243+
func.rust_name,
244+
generate_function_call(&converted_args)?.as_str()
245+
)
246+
.map_err(|e| BadFormat(e.to_string()))?;
239247
}
240248
(TWPointerType::NullableMut, "TWData") | (TWPointerType::Nullable, "TWData") => {
241249
write!(
@@ -390,7 +398,7 @@ fn generate_conversion_code_with_var_name(tw_type: TWType, name: &str) -> Result
390398
.map_err(|e| BadFormat(e.to_string()))?;
391399
Ok((conversion_code, format!("{}RustData.get()", name)))
392400
}
393-
(TWPointerType::Nonnull, "TWPrivateKey") => {
401+
(TWPointerType::Nonnull, "TWPrivateKey") | (TWPointerType::NonnullMut, "TWPrivateKey") => {
394402
let mut conversion_code = String::new();
395403
writeln!(
396404
&mut conversion_code,
@@ -401,7 +409,7 @@ fn generate_conversion_code_with_var_name(tw_type: TWType, name: &str) -> Result
401409
.map_err(|e| BadFormat(e.to_string()))?;
402410
Ok((conversion_code, format!("{}RustPrivateKey.get()", name)))
403411
}
404-
(TWPointerType::Nullable, "TWPrivateKey") => {
412+
(TWPointerType::Nullable, "TWPrivateKey") | (TWPointerType::NullableMut, "TWPrivateKey") => {
405413
let mut conversion_code = String::new();
406414
writeln!(
407415
&mut conversion_code,
@@ -415,7 +423,7 @@ fn generate_conversion_code_with_var_name(tw_type: TWType, name: &str) -> Result
415423
.map_err(|e| BadFormat(e.to_string()))?;
416424
Ok((conversion_code, format!("{}RustPrivateKey.get()", name)))
417425
}
418-
(TWPointerType::Nonnull, "TWPublicKey") => {
426+
(TWPointerType::Nonnull, "TWPublicKey") | (TWPointerType::NonnullMut, "TWPublicKey") => {
419427
let mut conversion_code = String::new();
420428
writeln!(
421429
&mut conversion_code,
@@ -427,7 +435,7 @@ fn generate_conversion_code_with_var_name(tw_type: TWType, name: &str) -> Result
427435
.map_err(|e| BadFormat(e.to_string()))?;
428436
Ok((conversion_code, format!("{}RustPublicKey.get()", name)))
429437
}
430-
(TWPointerType::Nullable, "TWPublicKey") => {
438+
(TWPointerType::Nullable, "TWPublicKey") | (TWPointerType::NullableMut, "TWPublicKey") => {
431439
let mut conversion_code = String::new();
432440
writeln!(
433441
&mut conversion_code,

include/TrustWalletCore/TWBarz.h

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

include/TrustWalletCore/TWEthereum.h

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

rust/Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/tw_coin_entry/src/error/address_error.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Copyright © 2017 Trust Wallet.
44

55
use strum_macros::Display;
6+
use tw_encoding::hex::FromHexError;
67

78
pub type AddressResult<T> = Result<T, AddressError>;
89

@@ -25,3 +26,9 @@ pub enum AddressError {
2526
InvalidWitnessProgram,
2627
Internal,
2728
}
29+
30+
impl From<FromHexError> for AddressError {
31+
fn from(_: FromHexError) -> Self {
32+
AddressError::FromHexError
33+
}
34+
}

rust/tw_encoding/src/hex.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,28 @@ pub fn encode<T: AsRef<[u8]>>(data: T, prefixed: bool) -> String {
6767
encoded
6868
}
6969

70+
pub fn hex_to_bits(str: &str) -> FromHexResult<String> {
71+
let hex_str = str.trim_start_matches("0x");
72+
let mut bits = String::new();
73+
for (index, c) in hex_str.chars().enumerate() {
74+
let val = c
75+
.to_digit(16)
76+
.ok_or(FromHexError::InvalidHexCharacter { c, index })?;
77+
bits.push_str(&format!("{:04b}", val));
78+
}
79+
Ok(bits)
80+
}
81+
82+
pub fn data_to_bits(data: &[u8]) -> FromHexResult<String> {
83+
let hex_str = encode(data, false);
84+
hex_to_bits(&hex_str)
85+
}
86+
87+
pub fn bits_to_u32(bits: &str, from: usize, to: usize) -> FromHexResult<u32> {
88+
u32::from_str_radix(&bits[from..to], 2)
89+
.map_err(|_| FromHexError::InvalidHexCharacter { c: '0', index: 0 })
90+
}
91+
7092
pub mod as_hex {
7193
use super::*;
7294
use serde::de::Error;
@@ -160,6 +182,31 @@ pub mod as_hex_prefixed {
160182
}
161183
}
162184

185+
pub mod u8_as_hex {
186+
use super::*;
187+
use serde::{Deserialize, Deserializer, Serializer};
188+
189+
pub fn serialize<S>(value: &u8, serializer: S) -> Result<S::Ok, S::Error>
190+
where
191+
S: Serializer,
192+
{
193+
let hex_str = encode([*value], true);
194+
serializer.serialize_str(&hex_str)
195+
}
196+
197+
pub fn deserialize<'de, D>(deserializer: D) -> Result<u8, D::Error>
198+
where
199+
D: Deserializer<'de>,
200+
{
201+
let hex_str = String::deserialize(deserializer)?;
202+
let bytes = decode(&hex_str).map_err(serde::de::Error::custom)?;
203+
bytes
204+
.first()
205+
.copied()
206+
.ok_or_else(|| serde::de::Error::custom("Expected single byte but got empty bytes"))
207+
}
208+
}
209+
163210
#[cfg(test)]
164211
mod tests {
165212
use super::*;
@@ -187,4 +234,12 @@ mod tests {
187234
Ok(expected)
188235
);
189236
}
237+
238+
#[test]
239+
fn test_encode_bits() {
240+
assert_eq!(
241+
hex_to_bits("0x2db500ac919cdde351ac36e3711d832c6db97669").unwrap(),
242+
"0010110110110101000000001010110010010001100111001101110111100011010100011010110000110110111000110111000100011101100000110010110001101101101110010111011001101001"
243+
);
244+
}
190245
}

rust/tw_evm/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@ tw_coin_entry = { path = "../tw_coin_entry" }
1313
tw_encoding = { path = "../tw_encoding" }
1414
tw_hash = { path = "../tw_hash" }
1515
tw_keypair = { path = "../tw_keypair" }
16+
tw_macros = { path = "../tw_macros" }
1617
tw_memory = { path = "../tw_memory" }
1718
tw_misc = { path = "../tw_misc" }
1819
tw_number = { path = "../tw_number", features = ["serde"] }
1920
tw_proto = { path = "../tw_proto" }
2021

2122
[dev-dependencies]
2223
tw_coin_entry = { path = "../tw_coin_entry", features = ["test-utils"] }
24+
tw_memory = { path = "../tw_memory", features = ["test-utils"] }
25+
tw_keypair = { path = "../tw_keypair", features = ["test-utils"] }

rust/tw_evm/fuzz/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,9 @@ name = "sign"
5252
path = "fuzz_targets/sign.rs"
5353
test = false
5454
doc = false
55+
56+
[[bin]]
57+
name = "diamond_cut_code"
58+
path = "fuzz_targets/diamond_cut_code.rs"
59+
test = false
60+
doc = false
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
//
3+
// Copyright © 2017 Trust Wallet.
4+
5+
#![no_main]
6+
7+
use libfuzzer_sys::fuzz_target;
8+
use tw_evm::modules::barz::core;
9+
use tw_proto::Barz::Proto;
10+
11+
fuzz_target!(|input: Proto::DiamondCutInput<'_>| {
12+
let _ = core::get_diamond_cut_code(&input);
13+
});

0 commit comments

Comments
 (0)