diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 22843571589..231e9ff182b 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1973,8 +1973,6 @@ dependencies = [ "arbitrary 1.3.0", "pb-rs", "quick-protobuf", - "tw_encoding", - "tw_memory", ] [[package]] @@ -2074,6 +2072,15 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "uuid" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +dependencies = [ + "getrandom", +] + [[package]] name = "vec_map" version = "0.8.2" @@ -2092,7 +2099,6 @@ version = "0.1.0" dependencies = [ "serde_json", "tw_any_coin", - "tw_aptos", "tw_bitcoin", "tw_coin_entry", "tw_coin_registry", @@ -2105,6 +2111,7 @@ dependencies = [ "tw_number", "tw_proto", "tw_solana", + "uuid", ] [[package]] diff --git a/rust/tw_proto/Cargo.toml b/rust/tw_proto/Cargo.toml index 73be2eecd76..3e80de2c895 100644 --- a/rust/tw_proto/Cargo.toml +++ b/rust/tw_proto/Cargo.toml @@ -10,8 +10,6 @@ fuzz = ["arbitrary"] # Enable in fuzz tests only! arbitrary = { version = "1", features = ["derive"], optional = true } quick-protobuf = "0.8.1" -tw_encoding = { path = "../tw_encoding" } -tw_memory = { path = "../tw_memory" } [build-dependencies] pb-rs = "0.10.0" diff --git a/rust/tw_proto/src/ffi.rs b/rust/tw_proto/src/ffi.rs deleted file mode 100644 index 5eb33e557c7..00000000000 --- a/rust/tw_proto/src/ffi.rs +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -#![allow(clippy::missing_safety_doc)] - -use std::borrow::Cow; -use tw_memory::ffi::c_byte_array::{CByteArray, CByteArrayResult}; -use tw_memory::ffi::c_byte_array_ref::CByteArrayRef; -use tw_memory::ffi::c_result::ErrorCode; - -#[repr(C)] -pub enum CProtoError { - Ok = 0, - Internal = 1, - ErrorDeserializingMsg = 2, - ErrorSerializingMsg = 3, -} - -impl From for ErrorCode { - fn from(e: CProtoError) -> Self { - e as ErrorCode - } -} - -/// Takes a serialized `Ethereum::Proto::SigningInput` message, deserializes it and returns a serialized message back. -/// This FFI is used within integration tests. -/// \param input *non-null* byte array. -/// \param input_len length of the input byte array. -/// \return C-compatible result with a C-compatible byte array. -#[no_mangle] -pub unsafe extern "C" fn pass_eth_signing_msg_through( - input: *const u8, - input_len: usize, -) -> CByteArrayResult { - let data = CByteArrayRef::new(input, input_len) - .to_vec() - .unwrap_or_default(); - - let msg: crate::Ethereum::Proto::SigningInput = match crate::deserialize(&data) { - Ok(msg) => msg, - Err(_) => return CByteArrayResult::error(CProtoError::ErrorDeserializingMsg), - }; - crate::serialize(&msg) - .map(CByteArray::from) - .map_err(|_| CProtoError::ErrorSerializingMsg) - .into() -} - -/// Returns a serialized `Polkadot::Proto::SigningInput` message. -/// This FFI is used within integration tests. -/// \return C-compatible result with a C-compatible byte array. -#[no_mangle] -pub unsafe extern "C" fn polkadot_test_signing_input() -> CByteArrayResult { - use crate::Polkadot::Proto::{ - self as proto, mod_Balance::OneOfmessage_oneof as BalanceEnum, - mod_SigningInput::OneOfmessage_oneof as SigningMsgEnum, - }; - - let block_hash = "0x343a3f4258fd92f5ca6ca5abdf473d86a78b0bcd0dc09c568ca594245cc8c642"; - let genesis_hash = "91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3"; - let to_address = "14E5nqKAp3oAJcmzgZhUD2RcptBeUBScxKHgJKU4HPNcKVf3"; - let privkey = [ - 171, 248, 229, 189, 190, 48, 198, 86, 86, 192, 163, 203, 209, 129, 255, 138, 86, 41, 74, - 105, 223, 237, 210, 121, 130, 170, 206, 74, 118, 144, 145, 21, - ]; - let value = [48, 57]; // 12345 - - let block_hash = tw_encoding::hex::decode(block_hash).expect("Expect valid hash"); - let genesis_hash = tw_encoding::hex::decode(genesis_hash).expect("Expect valid hash"); - - let balance = BalanceEnum::transfer(proto::mod_Balance::Transfer { - to_address: Cow::from(to_address), - value: Cow::Borrowed(&value), - memo: Cow::default(), - call_indices: None, - }); - let signing_input = proto::SigningInput { - block_hash: Cow::Owned(block_hash), - genesis_hash: Cow::Owned(genesis_hash), - nonce: 0, - spec_version: 17, - transaction_version: 3, - era: Some(proto::Era { - block_number: 927699, - period: 8, - }), - private_key: Cow::Borrowed(&privkey), - network: 0, - message_oneof: SigningMsgEnum::balance_call(proto::Balance { - message_oneof: balance, - }), - ..proto::SigningInput::default() - }; - - crate::serialize(&signing_input) - .map(CByteArray::from) - .map_err(|_| CProtoError::ErrorSerializingMsg) - .into() -} diff --git a/rust/tw_proto/src/lib.rs b/rust/tw_proto/src/lib.rs index fd222ddbb4e..aa7a3345b54 100644 --- a/rust/tw_proto/src/lib.rs +++ b/rust/tw_proto/src/lib.rs @@ -21,8 +21,6 @@ pub use quick_protobuf::{ Error as ProtoError, MessageRead, MessageWrite, Result as ProtoResult, }; -pub mod ffi; - /// Serializes a Protobuf message without the length prefix. /// Please note that [`quick_protobuf::serialize_into_vec`] appends a `varint32` length prefix. pub fn serialize(message: &T) -> ProtoResult> { diff --git a/rust/tw_proto/tests/proto_ffi_tests.rs b/rust/tw_proto/tests/proto_ffi_tests.rs deleted file mode 100644 index 8c8bb0e9441..00000000000 --- a/rust/tw_proto/tests/proto_ffi_tests.rs +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -use tw_memory::ffi::c_byte_array::CByteArray; - -/// Test `pass_eth_signing_msg_through` to avoid dropping code coverage. -#[test] -fn test_pass_eth_signing_msg_through() { - let serialized = tw_encoding::hex::decode("0a0101120100220509c76524002a030130b9422a3078366231373534373465383930393463343464613938623935346565646561633439353237316430664a20608dcb1742bb3fb7aec002074e3420e4fab7d00cced79ccdac53ed5b27138151523812360a2a30783533323262333463383865643036393139373162663532613730343734343866306634656663383412081bc16d674ec80000").unwrap(); - let actual = unsafe { - let array = CByteArray::from(serialized.clone()); - tw_proto::ffi::pass_eth_signing_msg_through(array.data(), array.size()) - .unwrap() - .into_vec() - }; - assert_eq!(actual, serialized); -} - -/// Test `polkadot_test_signing_input` to avoid dropping code coverage. -#[test] -fn test_polkadot_test_signing_input() { - unsafe { tw_proto::ffi::polkadot_test_signing_input().unwrap() }; -} diff --git a/rust/wallet_core_rs/Cargo.toml b/rust/wallet_core_rs/Cargo.toml index effc5c0ad81..d0c43170fdf 100644 --- a/rust/wallet_core_rs/Cargo.toml +++ b/rust/wallet_core_rs/Cargo.toml @@ -8,30 +8,46 @@ name = "wallet_core_rs" crate-type = ["staticlib", "rlib"] # Creates static lib [features] -default = ["bitcoin-legacy", "ethereum-abi", "ethereum-rlp", "solana-address", "solana-transaction"] -bitcoin-legacy = [] -ethereum-abi = [] -ethereum-rlp = [] -solana-address = [] -solana-transaction = [] +default = [ + "any-coin", + "bitcoin", + "ethereum", + "keypair", + "solana", + "utils", +] +any-coin = ["tw_any_coin"] +bitcoin = ["tw_bitcoin"] +ethereum = ["tw_ethereum", "tw_coin_registry"] +keypair = ["tw_keypair"] +solana = ["tw_solana"] +utils = [ + "tw_encoding", + "tw_hash", + "tw_memory", + "tw_number", + "tw_proto", + "uuid" +] [dependencies] -tw_any_coin = { path = "../tw_any_coin" } -tw_aptos = { path = "../tw_aptos" } -tw_bitcoin = { path = "../tw_bitcoin" } -tw_coin_entry = { path = "../tw_coin_entry", features = ["test-utils"] } -tw_coin_registry = { path = "../tw_coin_registry" } -tw_encoding = { path = "../tw_encoding" } -tw_ethereum = { path = "../tw_ethereum" } -tw_hash = { path = "../tw_hash" } -tw_keypair = { path = "../tw_keypair" } -tw_memory = { path = "../tw_memory" } +tw_any_coin = { path = "../tw_any_coin", optional = true } +tw_bitcoin = { path = "../tw_bitcoin", optional = true } +tw_coin_registry = { path = "../tw_coin_registry", optional = true } +tw_encoding = { path = "../tw_encoding", optional = true } +tw_ethereum = { path = "../tw_ethereum", optional = true } +tw_hash = { path = "../tw_hash", optional = true } +tw_keypair = { path = "../tw_keypair", optional = true } +tw_memory = { path = "../tw_memory", optional = true } +tw_number = { path = "../tw_number", optional = true } tw_misc = { path = "../tw_misc" } -tw_proto = { path = "../tw_proto" } -tw_solana = { path = "../chains/tw_solana" } +tw_proto = { path = "../tw_proto", optional = true } +tw_solana = { path = "../chains/tw_solana", optional = true } +uuid = { version = "1.7", features = ["v4"], optional = true } [dev-dependencies] serde_json = "1.0" tw_any_coin = { path = "../tw_any_coin", features = ["test-utils"] } +tw_coin_entry = { path = "../tw_coin_entry", features = ["test-utils"] } tw_memory = { path = "../tw_memory", features = ["test-utils"] } tw_number = { path = "../tw_number", features = ["helpers"] } diff --git a/rust/wallet_core_rs/cbindgen.toml b/rust/wallet_core_rs/cbindgen.toml index fcab0505411..6697f798a56 100644 --- a/rust/wallet_core_rs/cbindgen.toml +++ b/rust/wallet_core_rs/cbindgen.toml @@ -8,25 +8,15 @@ namespaces = ["TW", "Rust"] parse_deps = true extra_bindings = [ "tw_any_coin", - "tw_bitcoin", - "tw_coin_registry", "tw_encoding", - "tw_ethereum", "tw_hash", "tw_keypair", "tw_memory", - "tw_move_parser", - "tw_proto" ] include = [ "tw_any_coin", - "tw_bitcoin", - "tw_coin_registry", "tw_encoding", - "tw_ethereum", "tw_hash", "tw_keypair", "tw_memory", - "tw_move_parser", - "tw_proto" ] diff --git a/rust/wallet_core_rs/src/ffi/bitcoin/mod.rs b/rust/wallet_core_rs/src/ffi/bitcoin/mod.rs index 84b48e76e1e..4a2477e69f2 100644 --- a/rust/wallet_core_rs/src/ffi/bitcoin/mod.rs +++ b/rust/wallet_core_rs/src/ffi/bitcoin/mod.rs @@ -2,5 +2,4 @@ // // Copyright © 2017 Trust Wallet. -#[cfg(feature = "bitcoin-legacy")] pub mod legacy; diff --git a/rust/wallet_core_rs/src/ffi/ethereum/mod.rs b/rust/wallet_core_rs/src/ffi/ethereum/mod.rs index c3de348c12c..3817d406809 100644 --- a/rust/wallet_core_rs/src/ffi/ethereum/mod.rs +++ b/rust/wallet_core_rs/src/ffi/ethereum/mod.rs @@ -2,7 +2,5 @@ // // Copyright © 2017 Trust Wallet. -#[cfg(feature = "ethereum-abi")] pub mod abi; -#[cfg(feature = "ethereum-rlp")] pub mod rlp; diff --git a/rust/wallet_core_rs/src/ffi/mod.rs b/rust/wallet_core_rs/src/ffi/mod.rs index 4b64452c2e7..8b0bc21ca38 100644 --- a/rust/wallet_core_rs/src/ffi/mod.rs +++ b/rust/wallet_core_rs/src/ffi/mod.rs @@ -2,6 +2,11 @@ // // Copyright © 2017 Trust Wallet. +#[cfg(feature = "bitcoin")] pub mod bitcoin; +#[cfg(feature = "ethereum")] pub mod ethereum; +#[cfg(feature = "solana")] pub mod solana; +#[cfg(feature = "utils")] +pub mod utils; diff --git a/rust/wallet_core_rs/src/ffi/solana/mod.rs b/rust/wallet_core_rs/src/ffi/solana/mod.rs index 19e39015399..19d3bb454a1 100644 --- a/rust/wallet_core_rs/src/ffi/solana/mod.rs +++ b/rust/wallet_core_rs/src/ffi/solana/mod.rs @@ -2,7 +2,5 @@ // // Copyright © 2017 Trust Wallet. -#[cfg(feature = "solana-address")] pub mod address; -#[cfg(feature = "solana-transaction")] pub mod transaction; diff --git a/rust/wallet_core_rs/src/ffi/utils/mod.rs b/rust/wallet_core_rs/src/ffi/utils/mod.rs new file mode 100644 index 00000000000..f233b194cb3 --- /dev/null +++ b/rust/wallet_core_rs/src/ffi/utils/mod.rs @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +pub mod uuid_ffi; diff --git a/rust/wallet_core_rs/src/ffi/utils/uuid_ffi.rs b/rust/wallet_core_rs/src/ffi/utils/uuid_ffi.rs new file mode 100644 index 00000000000..159a4a079de --- /dev/null +++ b/rust/wallet_core_rs/src/ffi/utils/uuid_ffi.rs @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +#![allow(clippy::missing_safety_doc)] + +use std::ffi::{c_char, CString}; + +/// Creates a random UUID. +/// This uses the [`getrandom`] crate to utilise the operating system's RNG +/// as the source of random numbers. +#[no_mangle] +pub unsafe extern "C" fn tw_uuid_random() -> *const c_char { + let res = uuid::Uuid::new_v4(); + CString::new(res.to_string()).unwrap().into_raw() +} diff --git a/rust/wallet_core_rs/src/lib.rs b/rust/wallet_core_rs/src/lib.rs index fa6c23b6bb6..f26f8e9364e 100644 --- a/rust/wallet_core_rs/src/lib.rs +++ b/rust/wallet_core_rs/src/lib.rs @@ -2,15 +2,17 @@ // // Copyright © 2017 Trust Wallet. +#[cfg(feature = "any-coin")] pub extern crate tw_any_coin; -pub extern crate tw_aptos; +#[cfg(feature = "bitcoin")] pub extern crate tw_bitcoin; -pub extern crate tw_coin_registry; +#[cfg(feature = "utils")] pub extern crate tw_encoding; -pub extern crate tw_ethereum; +#[cfg(feature = "utils")] pub extern crate tw_hash; +#[cfg(feature = "keypair")] pub extern crate tw_keypair; +#[cfg(feature = "utils")] pub extern crate tw_memory; -pub extern crate tw_proto; pub mod ffi; diff --git a/rust/wallet_core_rs/tests/uuid.rs b/rust/wallet_core_rs/tests/uuid.rs new file mode 100644 index 00000000000..a5c9aad34e4 --- /dev/null +++ b/rust/wallet_core_rs/tests/uuid.rs @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright © 2017 Trust Wallet. + +use std::collections::HashSet; +use std::ffi::CStr; +use wallet_core_rs::ffi::utils::uuid_ffi::tw_uuid_random; + +/// Example of the valid UUID: 3cbbcce1-db89-4ea2-be24-88a686be461c +#[test] +fn test_tw_uuid_random_is_valid() { + let uuid = unsafe { CStr::from_ptr(tw_uuid_random()) } + .to_str() + .unwrap(); + + let tokens: Vec<_> = uuid.split("-").collect(); + assert_eq!(tokens.len(), 5); + assert_eq!(tokens[0].len(), 8); + assert_eq!(tokens[1].len(), 4); + assert_eq!(tokens[2].len(), 4); + assert_eq!(tokens[3].len(), 4); + assert_eq!(tokens[4].len(), 12); +} + +#[test] +fn test_tw_uuid_random_do_not_repeat() { + const ITERATIONS: usize = 10000; + + // Use `Vec` instead of `HashSet` here to make each iteration as fast as possible. + let mut uuids = Vec::with_capacity(ITERATIONS); + for _ in 0..ITERATIONS { + let uuid = unsafe { CStr::from_ptr(tw_uuid_random()) } + .to_str() + .unwrap(); + uuids.push(uuid); + } + + let unique_uuids: HashSet<&str> = uuids.into_iter().collect(); + assert_eq!(unique_uuids.len(), ITERATIONS); +} diff --git a/src/Aion/RLP.h b/src/Aion/RLP.h index 6330bc278de..643c7289d16 100644 --- a/src/Aion/RLP.h +++ b/src/Aion/RLP.h @@ -7,16 +7,14 @@ #include "Transaction.h" #include "Ethereum/RLP.h" +#include "uint256.h" -#include #include #include #include namespace TW::Aion { -using boost::multiprecision::uint128_t; - /// Aion's RLP encoding for long numbers /// https://github.com/aionnetwork/aion/issues/680 struct RLP { diff --git a/src/Aion/Signer.cpp b/src/Aion/Signer.cpp index b3cacc038e4..8fe86f3904f 100644 --- a/src/Aion/Signer.cpp +++ b/src/Aion/Signer.cpp @@ -3,8 +3,6 @@ // Copyright © 2017 Trust Wallet. #include "Signer.h" -#include "../uint256.h" -#include using namespace TW; @@ -59,8 +57,6 @@ Proto::SigningOutput Signer::compile(const Data& signature, const PublicKey& pub } Transaction Signer::buildTransaction(const Proto::SigningInput& input) noexcept { - using boost::multiprecision::uint128_t; - auto transaction = Transaction( /* nonce: */ static_cast(load(input.nonce())), /* gasPrice: */ static_cast(load(input.gas_price())), diff --git a/src/Aion/Transaction.cpp b/src/Aion/Transaction.cpp index c4681472340..c2c6eee46aa 100644 --- a/src/Aion/Transaction.cpp +++ b/src/Aion/Transaction.cpp @@ -10,7 +10,6 @@ #include "uint256.h" using namespace TW; -using boost::multiprecision::uint128_t; namespace TW::Aion { diff --git a/src/Aion/Transaction.h b/src/Aion/Transaction.h index d3805859df3..257ddb68736 100644 --- a/src/Aion/Transaction.h +++ b/src/Aion/Transaction.h @@ -6,14 +6,12 @@ #include "Address.h" #include "Data.h" - -#include +#include "uint256.h" namespace TW::Aion { class Transaction { public: - using uint128_t = boost::multiprecision::uint128_t; uint128_t nonce; uint128_t gasPrice; diff --git a/src/EOS/Asset.cpp b/src/EOS/Asset.cpp index 86a53e38a89..7dbb5a87d11 100644 --- a/src/EOS/Asset.cpp +++ b/src/EOS/Asset.cpp @@ -3,9 +3,8 @@ // Copyright © 2017 Trust Wallet. #include "Asset.h" +#include "algorithm/string.hpp" -#include -#include #include namespace TW::EOS { @@ -38,7 +37,7 @@ Asset::Asset(int64_t amount, uint8_t decimals, const std::string& symbol) { Asset Asset::fromString(std::string assetString) { using namespace std; - boost::algorithm::trim(assetString); + trim(assetString); // Find space in order to split amount and symbol auto spacePosition = assetString.find(' '); @@ -46,7 +45,7 @@ Asset Asset::fromString(std::string assetString) { throw std::invalid_argument("Asset's amount and symbol should be separated with space"); } - auto symbolString = boost::algorithm::trim_copy(assetString.substr(spacePosition + 1)); + auto symbolString = trim_copy(assetString.substr(spacePosition + 1)); auto amountString = assetString.substr(0, spacePosition); // Ensure that if decimal point is used (.), decimal fraction is specified @@ -65,13 +64,13 @@ Asset Asset::fromString(std::string assetString) { // Parse amount int64_t intPart, fractPart = 0; if (dotPosition != string::npos) { - intPart = boost::lexical_cast(amountString.data(), dotPosition); - fractPart = boost::lexical_cast(amountString.data() + dotPosition + 1, decimals); + intPart = std::stoll(amountString.substr(0, dotPosition)); + fractPart = std::stoll(amountString.substr(dotPosition + 1, decimals)); if (amountString[0] == '-') { fractPart *= -1; } } else { - intPart = boost::lexical_cast(amountString); + intPart = std::stoll(amountString); } int64_t amount = intPart; diff --git a/src/EOS/Name.cpp b/src/EOS/Name.cpp index 9825a0f5b5b..6ce388d800f 100644 --- a/src/EOS/Name.cpp +++ b/src/EOS/Name.cpp @@ -4,8 +4,8 @@ #include "../BinaryCoding.h" #include "Name.h" +#include "algorithm/string.hpp" -#include #include namespace TW::EOS { @@ -50,7 +50,7 @@ std::string Name::string() const noexcept { tmp >>= 5; } - boost::algorithm::trim_right_if(str, [](char c) { return c == '.'; }); + trim_right(str, "."); return str; } diff --git a/src/Everscale/CommonTON/Cell.cpp b/src/Everscale/CommonTON/Cell.cpp index b148168fa00..c7488285d3f 100644 --- a/src/Everscale/CommonTON/Cell.cpp +++ b/src/Everscale/CommonTON/Cell.cpp @@ -9,11 +9,9 @@ #include #include +#include "Base64.h" #include "BinaryCoding.h" -#include -#include - using namespace TW; namespace TW::CommonTON { @@ -87,11 +85,7 @@ struct Reader { }; std::shared_ptr Cell::fromBase64(const std::string& encoded) { - // `Hash::base64` trims \0 bytes from the end of the _decoded_ data, so - // raw transform is used here - using namespace boost::archive::iterators; - using It = transform_width, 8, 6>; - Data boc(It(begin(encoded)), It(end(encoded))); + auto boc = Base64::decode(encoded); return Cell::deserialize(boc.data(), boc.size()); } diff --git a/src/Everscale/CommonTON/Cell.h b/src/Everscale/CommonTON/Cell.h index 90a024d0eb0..aaa03d67a9d 100644 --- a/src/Everscale/CommonTON/Cell.h +++ b/src/Everscale/CommonTON/Cell.h @@ -8,8 +8,6 @@ #include #include -#include - #include "Data.h" #include "Hash.h" diff --git a/src/Everscale/CommonTON/CellBuilder.h b/src/Everscale/CommonTON/CellBuilder.h index 1a22e9bc65e..6054e8d23be 100644 --- a/src/Everscale/CommonTON/CellBuilder.h +++ b/src/Everscale/CommonTON/CellBuilder.h @@ -11,6 +11,7 @@ #include "Cell.h" #include "CellSlice.h" #include "RawAddress.h" +#include "uint256.h" namespace TW::CommonTON { @@ -20,8 +21,6 @@ class CellBuilder { std::vector references{}; public: - using uint128_t = boost::multiprecision::uint128_t; - CellBuilder() = default; CellBuilder(Data& appendedData, uint16_t bits); diff --git a/src/Everscale/CommonTON/Messages.h b/src/Everscale/CommonTON/Messages.h index 4103a2f2feb..232f92664d0 100644 --- a/src/Everscale/CommonTON/Messages.h +++ b/src/Everscale/CommonTON/Messages.h @@ -16,8 +16,6 @@ namespace TW::CommonTON { -using uint128_t = CellBuilder::uint128_t; - class CommonMsgInfo { public: virtual void writeTo(CellBuilder& builder) const = 0; diff --git a/src/Everscale/Wallet.h b/src/Everscale/Wallet.h index a32a8fb5c1d..7efd68b7778 100644 --- a/src/Everscale/Wallet.h +++ b/src/Everscale/Wallet.h @@ -4,7 +4,6 @@ #pragma once -#include #include #include "PublicKey.h" diff --git a/src/FullSS58Address.h b/src/FullSS58Address.h index a9616186af2..04644660204 100644 --- a/src/FullSS58Address.h +++ b/src/FullSS58Address.h @@ -10,7 +10,6 @@ #include #include -#include const std::string FullSS58Prefix = "SS58PRE"; diff --git a/src/Harmony/Signer.h b/src/Harmony/Signer.h index f45fdb9b90a..0c8b073a196 100644 --- a/src/Harmony/Signer.h +++ b/src/Harmony/Signer.h @@ -12,7 +12,6 @@ #include "../proto/Harmony.pb.h" #include "../proto/EthereumRlp.pb.h" -#include #include #include #include diff --git a/src/Harmony/Staking.h b/src/Harmony/Staking.h index ef778a01a19..eff3ba8b37f 100644 --- a/src/Harmony/Staking.h +++ b/src/Harmony/Staking.h @@ -4,7 +4,6 @@ #pragma once -#include #include #include #include diff --git a/src/IOST/Signer.cpp b/src/IOST/Signer.cpp index 5b6f39f34d5..645be9f610f 100644 --- a/src/IOST/Signer.cpp +++ b/src/IOST/Signer.cpp @@ -5,10 +5,7 @@ #include "Signer.h" #include "Account.h" #include "../BinaryCoding.h" -#include "../Hash.h" -#include "../PrivateKey.h" #include -#include #include #include diff --git a/src/Icon/Signer.cpp b/src/Icon/Signer.cpp index 8a54194df2b..e537a72740d 100644 --- a/src/Icon/Signer.cpp +++ b/src/Icon/Signer.cpp @@ -9,7 +9,6 @@ #include "../HexCoding.h" #include "../PrivateKey.h" -#include #include #include diff --git a/src/Keystore/StoredKey.cpp b/src/Keystore/StoredKey.cpp index 8742e2760af..fb0d8701f00 100644 --- a/src/Keystore/StoredKey.cpp +++ b/src/Keystore/StoredKey.cpp @@ -9,11 +9,6 @@ #include "Mnemonic.h" #include "PrivateKey.h" -#define BOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX 1 - -#include -#include -#include #include #include @@ -76,8 +71,10 @@ StoredKey::StoredKey(StoredKeyType type, std::string name, const Data& password, : type(type), id(), name(std::move(name)), accounts() { const auto encryptionParams = EncryptionParameters::getPreset(encryptionLevel, encryption); payload = EncryptedPayload(password, data, encryptionParams); - boost::uuids::random_generator gen; - id = boost::lexical_cast(gen()); + + const char* uuid_ptr = Rust::tw_uuid_random(); + id = std::make_optional(uuid_ptr); + Rust::free_string(uuid_ptr); } const HDWallet<> StoredKey::wallet(const Data& password) const { diff --git a/src/Nano/Signer.cpp b/src/Nano/Signer.cpp index c18eb036eee..bfac78f141d 100644 --- a/src/Nano/Signer.cpp +++ b/src/Nano/Signer.cpp @@ -5,16 +5,14 @@ #include "Signer.h" #include "../BinaryCoding.h" -#include "../Hash.h" #include "../HexCoding.h" +#include "../uint256.h" #include -#include #include using namespace TW; -using uint128_t = boost::multiprecision::uint128_t; using json = nlohmann::json; namespace TW::Nano { @@ -27,8 +25,6 @@ const std::array kBlockHashPreamble{ }; std::array store(const uint128_t& value) { - using boost::multiprecision::cpp_int; - Data buf; buf.reserve(16); export_bits(value, std::back_inserter(buf), 8); diff --git a/src/Polkadot/ScaleCodec.h b/src/Polkadot/ScaleCodec.h index 47a0dbdf99d..eb7dbadab12 100644 --- a/src/Polkadot/ScaleCodec.h +++ b/src/Polkadot/ScaleCodec.h @@ -4,18 +4,17 @@ #pragma once -#include "../BinaryCoding.h" +#include "BinaryCoding.h" #include "Data.h" -#include "../PublicKey.h" +#include "PublicKey.h" #include "SS58Address.h" -#include +#include "uint256.h" + #include #include #include - -/// Reference https://github.com/soramitsu/kagome/blob/master/core/scale/scale_encoder_stream.cpp -using CompactInteger = boost::multiprecision::cpp_int; +using CompactInteger = TW::uint256_t; namespace TW::Polkadot { diff --git a/src/Tezos/MessageSigner.cpp b/src/Tezos/MessageSigner.cpp index b3ed0c797c2..077564019dc 100644 --- a/src/Tezos/MessageSigner.cpp +++ b/src/Tezos/MessageSigner.cpp @@ -2,11 +2,8 @@ // // Copyright © 2017 Trust Wallet. -#include #include #include -#include -#include #include "Base58.h" #include "HexCoding.h" diff --git a/src/VeChain/Signer.h b/src/VeChain/Signer.h index 2e3422a3f9f..aec2d1746b9 100644 --- a/src/VeChain/Signer.h +++ b/src/VeChain/Signer.h @@ -10,7 +10,6 @@ #include "../Hash.h" #include "../PrivateKey.h" -#include #include #include #include diff --git a/src/WebAuthn.cpp b/src/WebAuthn.cpp index 83fa598cea5..780b0c0b4f8 100644 --- a/src/WebAuthn.cpp +++ b/src/WebAuthn.cpp @@ -6,7 +6,6 @@ #include "Cbor.h" #include "PublicKey.h" -#include #include #include #include diff --git a/src/algorithm/string.hpp b/src/algorithm/string.hpp index 8d5fc8145a4..806b14b9899 100644 --- a/src/algorithm/string.hpp +++ b/src/algorithm/string.hpp @@ -10,7 +10,34 @@ namespace TW { -static std::vector ssplit(const std::string& input, char delimiter) { +constexpr std::string_view kWitespaces = " \t\n\r\f\v"; + +// trim from end of string (right) +inline void trim_right(std::string& s, std::string_view t = kWitespaces) +{ + s.erase(s.find_last_not_of(t) + 1); +} + +// trim from beginning of string (left) +inline void trim_left(std::string& s, std::string_view t = kWitespaces) +{ + s.erase(0, s.find_first_not_of(t)); +} + +// trim from both ends of string (right then left) +inline void trim(std::string& s, std::string_view t = kWitespaces) +{ + trim_left(s, t); + trim_right(s, t); +} + +// trim from both ends of string (right then left) +inline std::string trim_copy(std::string s, std::string_view t = kWitespaces) { + trim(s, t); + return s; +} + +inline std::vector ssplit(const std::string& input, char delimiter) { std::istringstream iss(input); std::vector tokens; std::string token; diff --git a/src/uint256.h b/src/uint256.h index 9d5e4f01171..43c6999a21a 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -11,6 +11,7 @@ namespace TW { +using uint128_t = boost::multiprecision::uint128_t; using int256_t = boost::multiprecision::int256_t; using uint256_t = boost::multiprecision::uint256_t; @@ -26,20 +27,6 @@ inline uint256_t load(const Data& data) { return result; } -/// Loads a `uint256_t` from a collection of bytes. -/// The leftmost offset bytes are skipped, and the next 32 bytes are taken. At least 32 (+offset) -/// bytes are needed. -inline uint256_t loadWithOffset(const Data& data, size_t offset) { - using boost::multiprecision::cpp_int; - if (data.empty() || (data.size() < (256 / 8 + offset))) { - // not enough bytes in data - return uint256_t(0); - } - uint256_t result; - import_bits(result, data.begin() + offset, data.begin() + offset + 256 / 8); - return result; -} - /// Loads a `uint256_t` from Protobuf bytes (which are wrongly represented as /// std::string). inline uint256_t load(const std::string& data) { diff --git a/tests/chains/Everscale/CellTests.cpp b/tests/chains/Everscale/CellTests.cpp index 8fb9c913cd5..139878ec6c1 100644 --- a/tests/chains/Everscale/CellTests.cpp +++ b/tests/chains/Everscale/CellTests.cpp @@ -64,7 +64,7 @@ TEST(EverscaleCell, EmptyCell) { ASSERT_EQ(hex(cell3->hash), EMPTY_CELL); // With `storeHashes` (provided hash should be skipped) - const auto cell4 = Cell::fromBase64("te6ccgEBAQEAJAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + const auto cell4 = Cell::fromBase64("te6ccgEBAQEAJAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="); ASSERT_EQ(hex(cell4->hash), EMPTY_CELL); } diff --git a/tests/chains/Ontology/TransactionTests.cpp b/tests/chains/Ontology/TransactionTests.cpp index 154245ff49b..43def521309 100644 --- a/tests/chains/Ontology/TransactionTests.cpp +++ b/tests/chains/Ontology/TransactionTests.cpp @@ -11,7 +11,6 @@ #include -#include #include namespace TW::Ontology::tests { diff --git a/tests/common/Uint256Tests.cpp b/tests/common/Uint256Tests.cpp index 9d084e62b02..5b01de5a3c5 100644 --- a/tests/common/Uint256Tests.cpp +++ b/tests/common/Uint256Tests.cpp @@ -97,12 +97,6 @@ TEST(Uint256, LoadEmpty) { EXPECT_EQ(load(parse_hex("0000")), uint256_t(0)); } -TEST(Uint256, LoadWithOffset) { - EXPECT_EQ(loadWithOffset(parse_hex("0000000000000000000000000000000000000000000000000000000000000003"), 0), uint256_t(3)); - EXPECT_EQ(loadWithOffset(parse_hex("abcdef0000000000000000000000000000000000000000000000000000000000000003"), 3), uint256_t(3)); - EXPECT_EQ(loadWithOffset(parse_hex("0000000000000000000000000000000000000000000000000000000000000003"), 1), uint256_t(0)); // not enough bytes -} - TEST(Uint256, loadStringProtobuf) { const Data data = parse_hex("03"); const std::string str = std::string(reinterpret_cast(data.data()), data.size()); diff --git a/tests/common/algorithm/string.cpp b/tests/common/algorithm/string.cpp index 18f51c95e9c..1371ddcf8b2 100644 --- a/tests/common/algorithm/string.cpp +++ b/tests/common/algorithm/string.cpp @@ -14,4 +14,16 @@ namespace TW::tests { ASSERT_EQ(splitted[1], "0"); ASSERT_EQ(splitted[2], "1"); } + + TEST(Algorithm, StringTrim) { + std::string str = " \t \n Hello, \n World \t \n"; + trim(str); + ASSERT_EQ(str, "Hello, \n World"); + } + + TEST(Algorithm, StringTrimSpecificSymbols) { + std::string str = ".\n Hello. World ..."; + trim(str, "."); + ASSERT_EQ(str, "\n Hello. World "); + } } diff --git a/tests/common/rust/bindgen/WalletCoreRsTests.cpp b/tests/common/rust/bindgen/WalletCoreRsTests.cpp deleted file mode 100644 index f2f1eb7f1f5..00000000000 --- a/tests/common/rust/bindgen/WalletCoreRsTests.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// Copyright © 2017 Trust Wallet. - -#include "HexCoding.h" -#include "Polkadot/Signer.h" -#include "TestUtilities.h" -#include "rust/bindgen/WalletCoreRSBindgen.h" -#include "gtest/gtest.h" -#include "proto/Ethereum.pb.h" -#include "proto/Polkadot.pb.h" -#include "uint256.h" - -TEST(RustBindgen, EthSigningMessageProto) { - using namespace TW; - - auto chainId = store(uint256_t(1)); - auto nonce = store(uint256_t(0)); - auto gasPrice = store(uint256_t(42000000000ul)); // 0x09c7652400 - auto gasLimit = store(uint256_t(78009ul)); // 130B9 - auto toAddress = "0x5322b34c88ed0691971bf52a7047448f0f4efc84"; - auto token = "0x6b175474e89094c44da98b954eedeac495271d0f"; // DAI - auto amount = uint256_t(2000000000000000000); - auto amountData = store(amount); - auto key = parse_hex("0x608dcb1742bb3fb7aec002074e3420e4fab7d00cced79ccdac53ed5b27138151"); - - Ethereum::Proto::SigningInput input; - input.set_chain_id(chainId.data(), chainId.size()); - input.set_nonce(nonce.data(), nonce.size()); - // tx_mode not set, Legacy is the default - input.set_gas_price(gasPrice.data(), gasPrice.size()); - input.set_gas_limit(gasLimit.data(), gasLimit.size()); - input.set_to_address(token); - input.set_private_key(key.data(), key.size()); - auto& erc20 = *input.mutable_transaction()->mutable_erc20_transfer(); - erc20.set_to(toAddress); - erc20.set_amount(amountData.data(), amountData.size()); - - Data serialized = data(input.SerializeAsString()); - Rust::CByteArrayResultWrapper res = Rust::pass_eth_signing_msg_through(serialized.data(), serialized.size()); - ASSERT_TRUE(res.isOk()); - ASSERT_EQ(res.unwrap().data, serialized); -} - -TEST(RustBindgen, PolkadotSignTxProto) { - using namespace TW; - - auto blockHash = parse_hex("0x343a3f4258fd92f5ca6ca5abdf473d86a78b0bcd0dc09c568ca594245cc8c642"); - auto genesisHash = parse_hex("91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3"); - auto toAddress = "14E5nqKAp3oAJcmzgZhUD2RcptBeUBScxKHgJKU4HPNcKVf3"; - auto privateKey = parse_hex("0xabf8e5bdbe30c65656c0a3cbd181ff8a56294a69dfedd27982aace4a76909115"); - auto expectedEncoded = "29028488dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee003d91a06263956d8ce3ce5c55455baefff299d9cb2bb3f76866b6828ee4083770b6c03b05d7b6eb510ac78d047002c1fe5c6ee4b37c9c5a8b09ea07677f12e50d3200000005008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48e5c0"; - - Rust::CByteArrayResultWrapper res = Rust::polkadot_test_signing_input(); - ASSERT_TRUE(res.isOk()); - auto serialized = std::move(res.unwrap().data); - - Polkadot::Proto::SigningInput input; - input.ParseFromArray(serialized.data(), static_cast(serialized.size())); - - ASSERT_EQ(input.nonce(), 0ul); - ASSERT_EQ(input.spec_version(), 17ul); - ASSERT_EQ(data(input.private_key()), privateKey); - ASSERT_EQ(input.network(), 0ul); - ASSERT_EQ(input.transaction_version(), 3ul); - - ASSERT_EQ(input.era().block_number(), 927699ul); - ASSERT_EQ(input.era().period(), 8ul); - - auto transfer = input.balance_call().transfer(); - ASSERT_EQ(data(transfer.value()), store(uint256_t(12345ul))); - ASSERT_EQ(transfer.to_address(), toAddress); - - auto output = Polkadot::Signer::sign(input); - ASSERT_EQ(hex(output.encoded()), expectedEncoded); -}