From 455e985f32a80e6fa99e44ab1bce0d7185d3b597 Mon Sep 17 00:00:00 2001 From: Satoshi Otomakan Date: Fri, 17 Jan 2025 16:30:35 +0100 Subject: [PATCH 1/2] [JNI]: Fix Race condition --- jni/java/wallet/core/java/GenericPhantomReference.java | 3 ++- .../kotlin/com/trustwallet/core/GenericPhantomReference.kt | 3 ++- tools/install-rust-dependencies | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/jni/java/wallet/core/java/GenericPhantomReference.java b/jni/java/wallet/core/java/GenericPhantomReference.java index 1c5ee46dc76..ef7808b902e 100644 --- a/jni/java/wallet/core/java/GenericPhantomReference.java +++ b/jni/java/wallet/core/java/GenericPhantomReference.java @@ -4,12 +4,13 @@ import java.lang.ref.ReferenceQueue; import java.util.Set; import java.util.HashSet; +import java.util.Collections; public class GenericPhantomReference extends PhantomReference { private final long nativeHandle; private final OnDeleteCallback onDeleteCallback; - private static final Set references = new HashSet<>(); + private static final Set references = Collections.synchronizedSet(new HashSet<>()); private static final ReferenceQueue queue = new ReferenceQueue<>(); static { diff --git a/kotlin/wallet-core-kotlin/src/commonAndroidJvmMain/kotlin/com/trustwallet/core/GenericPhantomReference.kt b/kotlin/wallet-core-kotlin/src/commonAndroidJvmMain/kotlin/com/trustwallet/core/GenericPhantomReference.kt index b6ca8dd3653..0e2ffdd5b8f 100644 --- a/kotlin/wallet-core-kotlin/src/commonAndroidJvmMain/kotlin/com/trustwallet/core/GenericPhantomReference.kt +++ b/kotlin/wallet-core-kotlin/src/commonAndroidJvmMain/kotlin/com/trustwallet/core/GenericPhantomReference.kt @@ -2,6 +2,7 @@ package com.trustwallet.core import java.lang.ref.PhantomReference import java.lang.ref.ReferenceQueue +import java.util.Collections internal class GenericPhantomReference private constructor( referent: Any, @@ -10,7 +11,7 @@ internal class GenericPhantomReference private constructor( ) : PhantomReference(referent, queue) { companion object { - private val references: MutableSet = HashSet() + private val references: MutableSet = Collections.synchronizedSet(HashSet()) private val queue: ReferenceQueue = ReferenceQueue() init { diff --git a/tools/install-rust-dependencies b/tools/install-rust-dependencies index 1b12239c010..be910ec7020 100755 --- a/tools/install-rust-dependencies +++ b/tools/install-rust-dependencies @@ -27,5 +27,5 @@ cargo install cbindgen --locked if [[ "$1" == "dev" ]]; then rustup component add llvm-tools-preview clippy rustfmt - cargo install cargo-llvm-cov --locked + cargo install --version 0.6.14 cargo-llvm-cov --locked fi From db9bc3afcb8c7d3042ca56310cd1142f1a96909f Mon Sep 17 00:00:00 2001 From: Satoshi Otomakan Date: Fri, 24 Jan 2025 14:36:15 +0100 Subject: [PATCH 2/2] fix(ripple): Add support for non-standard currency code (40 symbols) --- src/XRP/Transaction.cpp | 34 +++++++++++++++++---------- src/XRP/Transaction.h | 7 +++--- tests/chains/XRP/TWAnySignerTests.cpp | 21 +++++++++++++++++ 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/XRP/Transaction.cpp b/src/XRP/Transaction.cpp index 1ebf5d02732..da48bbe6ecb 100644 --- a/src/XRP/Transaction.cpp +++ b/src/XRP/Transaction.cpp @@ -85,7 +85,7 @@ Data Transaction::serialize() const { (transaction_type == TransactionType::NFTokenCreateOffer)) { encodeType(FieldType::amount, 1, data); append(data, - (currency_amount.currency.size() > 0) ? + (!currency_amount.currency.empty()) ? serializeCurrencyAmount(currency_amount) : serializeAmount(amount)); } else if (transaction_type == TransactionType::TrustSet) { @@ -257,17 +257,7 @@ Data Transaction::serializeCurrencyAmount(const CurrencyAmount& currency_amount) // https://xrpl.org/serialization.html#amount-fields auto data = Data(); encode64BE(amount_cast.value, data); - - // ISO-4217 currency code - encodeZeros(1, data); // type code (0x00) - encodeZeros(11, data); // reserved - if (currency_amount.currency.size() == 3) { - data.insert(data.end(), currency_amount.currency.begin(), currency_amount.currency.end()); - } else { - encodeZeros(3, data); // none - } - - encodeZeros(5, data); // reserved + serializeCurrencyCode(data, currency_amount.currency); data.insert(data.end(), currency_amount.issuer.begin(), currency_amount.issuer.end()); return data; } @@ -278,4 +268,24 @@ Data Transaction::serializeAddress(Address address) { return data; } +void Transaction::serializeCurrencyCode(Data& out, const std::string& currency_code) { + if (currency_code.size() == 40) { + auto code_bytes = parse_hex(currency_code); + out.insert(out.end(), code_bytes.begin(), code_bytes.end()); + return; + } + + // Standard ISO-4217 currency code + encodeZeros(1, out); // type code (0x00) + encodeZeros(11, out); // reserved + + if (currency_code.size() == 3) { + out.insert(out.end(), currency_code.begin(), currency_code.end()); + } else { + encodeZeros(3, out); // none + } + + encodeZeros(5, out); // reserved +} + } // namespace TW::Ripple diff --git a/src/XRP/Transaction.h b/src/XRP/Transaction.h index ca453c47919..0793e01131d 100644 --- a/src/XRP/Transaction.h +++ b/src/XRP/Transaction.h @@ -47,7 +47,7 @@ class Transaction { /// See https://github.com/trezor/trezor-core/tree/master/src/apps/ripple#transactions public: struct CurrencyAmount { - Data currency; + std::string currency; Data value; Data issuer; }; @@ -182,10 +182,11 @@ class Transaction { static Data serializeAmount(int64_t amount); static Data serializeCurrencyAmount(const CurrencyAmount& currency_amount); static Data serializeAddress(Address address); + static void serializeCurrencyCode(Data& out, const std::string& currency_code); private: - void setCurrencyAmount(CurrencyAmount& p_currency_amount, const std::string& currency, const std::string& value, const std::string& issuer) { - p_currency_amount.currency = Data(currency.begin(), currency.end()); + void setCurrencyAmount(CurrencyAmount& p_currency_amount, const std::string& p_currency, const std::string& value, const std::string& issuer) { + p_currency_amount.currency = p_currency; p_currency_amount.value = Data(value.begin(), value.end()); setAccount(issuer, p_currency_amount.issuer); } diff --git a/tests/chains/XRP/TWAnySignerTests.cpp b/tests/chains/XRP/TWAnySignerTests.cpp index 3dd17ea7d1b..43770e1371b 100644 --- a/tests/chains/XRP/TWAnySignerTests.cpp +++ b/tests/chains/XRP/TWAnySignerTests.cpp @@ -80,6 +80,27 @@ TEST(TWAnySignerRipple, SignTrustSetPayment) { EXPECT_EQ(hex(output.encoded()), "12001422000000002401ec60b9201b01ec60ce63d4c38d7ea4c6800000000000000000000000000055534400000000004b4e9c06f24296074f7bc48f92a97916c6dc5ea968400000000000000a732103dc4a0dae2d550de7cace9c26c1a331a114e3e7efee5577204b476d27e2dc683a7446304402206ebcc7a689845df373dd2566cd3789862d426d9ad4e6a09c2d2772b57e82696a022066b1f217a0f0d834d167613a313f74097423a9ccd11f1ae7f90ffab0d2fc26b58114308ea8e515b64f2e6616a33b42e1bbb9fa00bbd2"); } +TEST(TWAnySignerRipple, SignTrustSetPaymentNonStandardCurrencyCode) { + // https://livenet.xrpl.org/transactions/31ABD41ECAD459BCD008DBA4377047413AEE7A965517DB240016B66A3F4A97E1 + auto key = parse_hex("574e99f7946cfa2a6ca9368ca72fd37e42583cddb9ecc746aa4cb194ef4b2480"); + Proto::SigningInput input; + + input.mutable_op_trust_set()->mutable_limit_amount()->set_currency("524C555344000000000000000000000000000000"); + input.mutable_op_trust_set()->mutable_limit_amount()->set_value("1000000000"); + input.mutable_op_trust_set()->mutable_limit_amount()->set_issuer("rMxCKbEDwqr76QuheSUMdEGf4B9xJ8m5De"); + input.set_fee(500); + input.set_sequence(93674950); + input.set_last_ledger_sequence(187349950); + input.set_account("rDgEGKXWkHHr1HYq2ETnNAs9MdV4R8Gyt"); + input.set_private_key(key.data(), key.size()); + + Proto::SigningOutput output; + ANY_SIGN(input, TWCoinTypeXRP); + + EXPECT_EQ(hex(output.encoded()), "12001422000000002405955dc6201b0b2abbbe63d6c38d7ea4c68000524c555344000000000000000000000000000000e5e961c6a025c9404aa7b662dd1df975be75d13e6840000000000001f47321039c77e9329017ced5f8673ebafcd29687a1fff181140c030062fa77865688fc5d74473045022100aa5f7ffc2e11008a3fe98173c66360937cd3a72cb0951aa1b46ba32675c36b2d02206bc02de3a609e5c4b9e1510a6431a7d7efc0fba4ab9586d6595b86047e46bac281140265c09d122fab2a261a80ee59f1f4cd8fba8cf8"); +} + + TEST(TWAnySignerRipple, SignTokenPayment0) { // https://testnet.xrpl.org/transactions/8F7820892294598B58CFA2E1101D15ED98C179B25A2BA6DAEB4F5B727CB00D4E auto key = parse_hex("4ba5fd2ebf0f5d7e579b3c354c263ebb39cda4093845125786a280301af14e21");