What changed, and why it matters
This commit only adds new automated tests for the Tron cryptocurrency transaction handling code in a hardware wallet firmware project. It does not change any production behavior, fix bugs, or introduce new features. There is no security-relevant change visible in the diff.
No security action needed. Treat as routine test-coverage improvement. If reviewing for security, consider whether the new tests adequately cover edge cases such as malformed protobuf payloads, zero-value transfers, and mismatched derivation paths, but that is a code-quality question, not an incident response matter.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit adds unit tests in three Rust source files under rust/apps/tron: lib.rs gets tests for sign_raw_tx, parse_raw_tx, and check_raw_tx; wrapped_tron.rs gets tests for signature_hash, format_amount, format_method (TRX/TRC-20/TRC-10), format_unit, and check_input with an invalid xfp. parser.rs only has a whitespace/trailing blank line cleanup. No production logic is modified.
Changed components
rust/apps/tron/src/lib.rsrust/apps/tron/src/transaction/parser.rsrust/apps/tron/src/transaction/wrapped_tron.rsInspect captured patch +148 / −1
diff --git a/rust/apps/tron/src/lib.rs b/rust/apps/tron/src/lib.rs
index 4689c41..42af347 100644
--- a/rust/apps/tron/src/lib.rs
+++ b/rust/apps/tron/src/lib.rs
@@ -64,4 +64,41 @@ mod test {
let base: Base = parse_protobuf(unzip_data).unwrap();
base.data.unwrap()
}
+
+ #[test]
+ fn test_sign_raw_tx() {
+ let hex = "1f8b08000000000000030dcebb4ac3501c807153444a17b553e95482501142ce39f99f4b8b83362d74696cd38897eddca205db60ac22d95db49b4fe0e6e8e4e65bf80a6e3e80a083816ffb965fb552df9ce461666c6b9c67cb4c6757cd5fa75aa95739e283419f85eeb7535b4fe2a3a8bea3710a42748cc729621e60a43cc1c17801a2c03166444bd4dc1ef9006d1f7768db47653e6aad5e578f7f6877a3f7e234dd2499f2331adc4c212ff27eb83c97b3dbb8b8be3798c96568c971ecbac99416e32c84d3416f3ebceb47878bc509b91806a3c9a58e23368be77b6bc4c1dda8760046714cb148b154982949b400ad4a8f92960bc23ae5e20a510bda12c9d2006b0bd2d8148ca582045b0f9fcf8dc6cfd753291cbebdefb73ec6ff42b912d514010000";
+ let pubkey_str = "xpub6C3ndD75jvoARyqUBTvrsMZaprs2ZRF84kRTt5r9oxKQXn5oFChRRgrP2J8QhykhKACBLF2HxwAh4wccFqFsuJUBBcwyvkyqfzJU5gfn5pY";
+ let payload = prepare_payload(hex);
+ let context = prepare_parse_context(pubkey_str);
+ let seed = hex::decode("5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4").unwrap();
+ let result = sign_raw_tx(payload, context, &seed);
+ assert!(result.is_ok());
+ let (tx_hex, tx_id) = result.unwrap();
+ assert!(!tx_hex.is_empty());
+ assert!(!tx_id.is_empty());
+ }
+
+ #[test]
+ fn test_parse_raw_tx() {
+ let hex = "1f8b08000000000000030dcebb4ac3501c807153444a17b553e95482501142ce39f99f4b8b83362d74696cd38897eddca205db60ac22d95db49b4fe0e6e8e4e65bf80a6e3e80a083816ffb965fb552df9ce461666c6b9c67cb4c6757cd5fa75aa95739e283419f85eeb7535b4fe2a3a8bea3710a42748cc729621e60a43cc1c17801a2c03166444bd4dc1ef9006d1f7768db47653e6aad5e578f7f6877a3f7e234dd2499f2331adc4c212ff27eb83c97b3dbb8b8be3798c96568c971ecbac99416e32c84d3416f3ebceb47878bc509b91806a3c9a58e23368be77b6bc4c1dda8760046714cb148b154982949b400ad4a8f92960bc23ae5e20a510bda12c9d2006b0bd2d8148ca582045b0f9fcf8dc6cfd753291cbebdefb73ec6ff42b912d514010000";
+ let pubkey_str = "xpub6C3ndD75jvoARyqUBTvrsMZaprs2ZRF84kRTt5r9oxKQXn5oFChRRgrP2J8QhykhKACBLF2HxwAh4wccFqFsuJUBBcwyvkyqfzJU5gfn5pY";
+ let payload = prepare_payload(hex);
+ let context = prepare_parse_context(pubkey_str);
+ let result = parse_raw_tx(payload, context);
+ assert!(result.is_ok());
+ let parsed = result.unwrap();
+ assert!(!parsed.overview.value.is_empty());
+ }
+
+ #[test]
+ fn test_check_raw_tx() {
+ // Use a valid test case from checker.rs
+ let hex = "1f8b08000000000000030dcfbd4ac34000c071220ea58bdaa9742a41a84bc87d27270e9ab61890c4268d54bb5dee2e26607b508b4a9fa26fe01bf8b128f812be82b383b8161703ffe9bffd1a5bad9d64d1374a77470bb334d2dc7436567d1b1e96540920ec6fabb99da5e7716b5f4a4e58ae91e36b221d8272ed088ca04399a058f8b2a09075f62297909e0b39edb9a0ce05dde79faf8f0d3868048f56c7ce2e86d3b13abb35833089f4f4be2a97ca04554cd8eaa13c9d5ca9d0b6b3315d8d4c9f5c0e83597837884fe6f309ba0e719494328d5995ce90050fe3e671c17c0ab9d2bc904011a031a502f202e414032e19c60c78be209e409aab1cfa9041e603c204821ad588ddd7f5baddfefd7c7aff03e1cbdbd13f2aab0f710f010000";
+ let pubkey_str = "xpub6D1AabNHCupeiLM65ZR9UStMhJ1vCpyV4XbZdyhMZBiJXALQtmn9p42VTQckoHVn8WNqS7dqnJokZHAHcHGoaQgmv8D45oNUKx6DZMNZBCd";
+ let payload = prepare_payload(hex);
+ let context = prepare_parse_context(pubkey_str);
+ let result = check_raw_tx(payload, context);
+ assert!(result.is_ok());
+ }
}
diff --git a/rust/apps/tron/src/transaction/parser.rs b/rust/apps/tron/src/transaction/parser.rs
index 84124e1..49c3419 100644
--- a/rust/apps/tron/src/transaction/parser.rs
+++ b/rust/apps/tron/src/transaction/parser.rs
@@ -39,7 +39,7 @@ impl TxParser for WrappedTron {
let from = self.from.to_string();
let to = self.to.to_string();
let network = NETWORK.to_string();
-
+
let overview = OverviewTx {
value: value.clone(),
method: method.clone(),
diff --git a/rust/apps/tron/src/transaction/wrapped_tron.rs b/rust/apps/tron/src/transaction/wrapped_tron.rs
index 9c3a3e5..7efd930 100644
--- a/rust/apps/tron/src/transaction/wrapped_tron.rs
+++ b/rust/apps/tron/src/transaction/wrapped_tron.rs
@@ -336,3 +336,113 @@ impl WrappedTron {
pub const DIVIDER: f64 = 1000000_f64;
pub const NETWORK: &str = "TRON";
+
+#[cfg(test)]
+mod tests {
+ extern crate std;
+ use super::*;
+ use crate::test::{prepare_parse_context, prepare_payload};
+ use alloc::string::ToString;
+ use bitcoin::bip32::Fingerprint;
+ use core::str::FromStr;
+
+ #[test]
+ fn test_signature_hash() {
+ let hex = "1f8b08000000000000030dcfbd4ac34000c071220ea58bdaa9742a41a84bc87d27270e9ab61890c4268d54bb5dee2e26607b508b4a9fa26fe01bf8b128f812be82b383b8161703ffe9bffd1a5bad9d64d1374a77470bb334d2dc7436567d1b1e96540920ec6fabb99da5e7716b5f4a4e58ae91e36b221d8272ed088ca04399a058f8b2a09075f62297909e0b39edb9a0ce05dde79faf8f0d3868048f56c7ce2e86d3b13abb35833089f4f4be2a97ca04554cd8eaa13c9d5ca9d0b6b3315d8d4c9f5c0e83597837884fe6f309ba0e719494328d5995ce90050fe3e671c17c0ab9d2bc904011a031a502f202e414032e19c60c78be209e409aab1cfa9041e603c204821ad588ddd7f5baddfefd7c7aff03e1cbdbd13f2aab0f710f010000";
+ let pubkey_str = "xpub6D1AabNHCupeiLM65ZR9UStMhJ1vCpyV4XbZdyhMZBiJXALQtmn9p42VTQckoHVn8WNqS7dqnJokZHAHcHGoaQgmv8D45oNUKx6DZMNZBCd";
+ let payload = prepare_payload(hex);
+ let context = prepare_parse_context(pubkey_str);
+ let tx = WrappedTron::from_payload(payload, &context).unwrap();
+ let hash = tx.signature_hash().unwrap();
+ assert_eq!(32, hash.len());
+ }
+
+ #[test]
+ fn test_format_amount_trx() {
+ let hex = "1f8b08000000000000030dcfbd4ac34000c071220ea58bdaa9742a41a84bc87d27270e9ab61890c4268d54bb5dee2e26607b508b4a9fa26fe01bf8b128f812be82b383b8161703ffe9bffd1a5bad9d64d1374a77470bb334d2dc7436567d1b1e96540920ec6fabb99da5e7716b5f4a4e58ae91e36b221d8272ed088ca04399a058f8b2a09075f62297909e0b39edb9a0ce05dde79faf8f0d3868048f56c7ce2e86d3b13abb35833089f4f4be2a97ca04554cd8eaa13c9d5ca9d0b6b3315d8d4c9f5c0e83597837884fe6f309ba0e719494328d5995ce90050fe3e671c17c0ab9d2bc904011a031a502f202e414032e19c60c78be209e409aab1cfa9041e603c204821ad588ddd7f5baddfefd7c7aff03e1cbdbd13f2aab0f710f010000";
+ let pubkey_str = "xpub6D1AabNHCupeiLM65ZR9UStMhJ1vCpyV4XbZdyhMZBiJXALQtmn9p42VTQckoHVn8WNqS7dqnJokZHAHcHGoaQgmv8D45oNUKx6DZMNZBCd";
+ let payload = prepare_payload(hex);
+ let context = prepare_parse_context(pubkey_str);
+ let tx = WrappedTron::from_payload(payload, &context).unwrap();
+ let formatted = tx.format_amount().unwrap();
+ assert!(formatted.contains("TRX"));
+ }
+
+ #[test]
+ fn test_format_method_trx() {
+ let hex = "1f8b08000000000000030dcfbd4ac34000c071220ea58bdaa9742a41a84bc87d27270e9ab61890c4268d54bb5dee2e26607b508b4a9fa26fe01bf8b128f812be82b383b8161703ffe9bffd1a5bad9d64d1374a77470bb334d2dc7436567d1b1e96540920ec6fabb99da5e7716b5f4a4e58ae91e36b221d8272ed088ca04399a058f8b2a09075f62297909e0b39edb9a0ce05dde79faf8f0d3868048f56c7ce2e86d3b13abb35833089f4f4be2a97ca04554cd8eaa13c9d5ca9d0b6b3315d8d4c9f5c0e83597837884fe6f309ba0e719494328d5995ce90050fe3e671c17c0ab9d2bc904011a031a502f202e414032e19c60c78be209e409aab1cfa9041e603c204821ad588ddd7f5baddfefd7c7aff03e1cbdbd13f2aab0f710f010000";
+ let pubkey_str = "xpub6D1AabNHCupeiLM65ZR9UStMhJ1vCpyV4XbZdyhMZBiJXALQtmn9p42VTQckoHVn8WNqS7dqnJokZHAHcHGoaQgmv8D45oNUKx6DZMNZBCd";
+ let payload = prepare_payload(hex);
+ let context = prepare_parse_context(pubkey_str);
+ let tx = WrappedTron::from_payload(payload, &context).unwrap();
+ let method = tx.format_method().unwrap();
+ assert_eq!("TRX Transfer", method);
+ }
+
+ #[test]
+ fn test_format_method_trc20() {
+ let hex = "1f8b08000000000000031590bf4ac3501c46359452bba871299d4a102a42c8bffbbbf7c6499b1403b6b14d52b42e92e426b5c53636462979029d7d01477707279f40147c0007df41707130856f3870a6f355387ebd9f1a098b1abd34c99230b9acbf70158eaf1099b4db26368427ae5af29c639bdf0e98a652d50fc4500922110121a21efb548c028010142d8814bdbed995106a4a8a0e4d492e26c98defb78ffb3f79a7dcfa5ae505cf21b6359f4447fdc5a1678ce99c9e0dd1558726999b8f269d09ceea82e7b96408dab58bd23c358deccc1fdf38f97cc114ec6746a40e1c41f05cc87b89814edbada9756bda07b3d9893ab2b46eff22746c3c76a6bb2b6a49d129d9b3abfb3e8be3400335f4090d3506818c303042402f0c669851888160504286502c2b408b001d01f5fd40d6286c3c7f3ed46a773fef45486bab5a1ab8a6c7af2d6f395f62ad6c3dfee2c66bef1f257dc3fe50010000";
+ let pubkey_str = "xpub6C3ndD75jvoARyqUBTvrsMZaprs2ZRF84kRTt5r9oxKQXn5oFChRRgrP2J8QhykhKACBLF2HxwAh4wccFqFsuJUBBcwyvkyqfzJU5gfn5pY";
+ let payload = prepare_payload(hex);
+ let context = prepare_parse_context(pubkey_str);
+ let tx = WrappedTron::from_payload(payload, &context).unwrap();
+ let method = tx.format_method().unwrap();
+ assert_eq!("TRC-20 Transfer", method);
+ }
+
+ #[test]
+ fn test_format_method_trc10() {
+ // Create a transaction with non-empty token but empty contract_address
+ let hex = "1f8b08000000000000030dcfbd4ac34000c071220ea58bdaa9742a41a84bc87d27270e9ab61890c4268d54bb5dee2e26607b508b4a9fa26fe01bf8b128f812be82b383b8161703ffe9bffd1a5bad9d64d1374a77470bb334d2dc7436567d1b1e96540920ec6fabb99da5e7716b5f4a4e58ae91e36b221d8272ed088ca04399a058f8b2a09075f62297909e0b39edb9a0ce05dde79faf8f0d3868048f56c7ce2e86d3b13abb35833089f4f4be2a97ca04554cd8eaa13c9d5ca9d0b6b3315d8d4c9f5c0e83597837884fe6f309ba0e719494328d5995ce90050fe3e671c17c0ab9d2bc904011a031a502f202e414032e19c60c78be209e409aab1cfa9041e603c204821ad588ddd7f5baddfefd7c7aff03e1cbdbd13f2aab0f710f010000";
+ let pubkey_str = "xpub6D1AabNHCupeiLM65ZR9UStMhJ1vCpyV4XbZdyhMZBiJXALQtmn9p42VTQckoHVn8WNqS7dqnJokZHAHcHGoaQgmv8D45oNUKx6DZMNZBCd";
+ let payload = prepare_payload(hex);
+ let context = prepare_parse_context(pubkey_str);
+ let mut tx = WrappedTron::from_payload(payload, &context).unwrap();
+ // Modify to simulate TRC-10
+ tx.contract_address = String::new();
+ tx.token = "1002000".to_string();
+ let method = tx.format_method().unwrap();
+ assert_eq!("TRC-10 Transfer", method);
+ }
+
+ #[test]
+ fn test_format_unit_with_token_short_name() {
+ let hex = "1f8b08000000000000030dcfbd4ac34000c071220ea58bdaa9742a41a84bc87d27270e9ab61890c4268d54bb5dee2e26607b508b4a9fa26fe01bf8b128f812be82b383b8161703ffe9bffd1a5bad9d64d1374a77470bb334d2dc7436567d1b1e96540920ec6fabb99da5e7716b5f4a4e58ae91e36b221d8272ed088ca04399a058f8b2a09075f62297909e0b39edb9a0ce05dde79faf8f0d3868048f56c7ce2e86d3b13abb35833089f4f4be2a97ca04554cd8eaa13c9d5ca9d0b6b3315d8d4c9f5c0e83597837884fe6f309ba0e719494328d5995ce90050fe3e671c17c0ab9d2bc904011a031a502f202e414032e19c60c78be209e409aab1cfa9041e603c204821ad588ddd7f5baddfefd7c7aff03e1cbdbd13f2aab0f710f010000";
+ let pubkey_str = "xpub6D1AabNHCupeiLM65ZR9UStMhJ1vCpyV4XbZdyhMZBiJXALQtmn9p42VTQckoHVn8WNqS7dqnJokZHAHcHGoaQgmv8D45oNUKx6DZMNZBCd";
+ let payload = prepare_payload(hex);
+ let context = prepare_parse_context(pubkey_str);
+ let mut tx = WrappedTron::from_payload(payload, &context).unwrap();
+ tx.token_short_name = Some("USDT".to_string());
+ let unit = tx.format_unit().unwrap();
+ assert_eq!("USDT", unit);
+ }
+
+ #[test]
+ fn test_format_unit_without_token_short_name() {
+ let hex = "1f8b08000000000000030dcfbd4ac34000c071220ea58bdaa9742a41a84bc87d27270e9ab61890c4268d54bb5dee2e26607b508b4a9fa26fe01bf8b128f812be82b383b8161703ffe9bffd1a5bad9d64d1374a77470bb334d2dc7436567d1b1e96540920ec6fabb99da5e7716b5f4a4e58ae91e36b221d8272ed088ca04399a058f8b2a09075f62297909e0b39edb9a0ce05dde79faf8f0d3868048f56c7ce2e86d3b13abb35833089f4f4be2a97ca04554cd8eaa13c9d5ca9d0b6b3315d8d4c9f5c0e83597837884fe6f309ba0e719494328d5995ce90050fe3e671c17c0ab9d2bc904011a031a502f202e414032e19c60c78be209e409aab1cfa9041e603c204821ad588ddd7f5baddfefd7c7aff03e1cbdbd13f2aab0f710f010000";
+ let pubkey_str = "xpub6D1AabNHCupeiLM65ZR9UStMhJ1vCpyV4XbZdyhMZBiJXALQtmn9p42VTQckoHVn8WNqS7dqnJokZHAHcHGoaQgmv8D45oNUKx6DZMNZBCd";
+ let payload = prepare_payload(hex);
+ let context = prepare_parse_context(pubkey_str);
+ let tx = WrappedTron::from_payload(payload, &context).unwrap();
+ let unit = tx.format_unit().unwrap();
+ assert_eq!("TRX", unit);
+ }
+
+ #[test]
+ fn test_check_input_invalid_xfp() {
+ let hex = "1f8b08000000000000030dcfbd4ac34000c071220ea58bdaa9742a41a84bc87d27270e9ab61890c4268d54bb5dee2e26607b508b4a9fa26fe01bf8b128f812be82b383b8161703ffe9bffd1a5bad9d64d1374a77470bb334d2dc7436567d1b1e96540920ec6fabb99da5e7716b5f4a4e58ae91e36b221d8272ed088ca04399a058f8b2a09075f62297909e0b39edb9a0ce05dde79faf8f0d3868048f56c7ce2e86d3b13abb35833089f4f4be2a97ca04554cd8eaa13c9d5ca9d0b6b3315d8d4c9f5c0e83597837884fe6f309ba0e719494328d5995ce90050fe3e671c17c0ab9d2bc904011a031a502f202e414032e19c60c78be209e409aab1cfa9041e603c204821ad588ddd7f5baddfefd7c7aff03e1cbdbd13f2aab0f710f010000";
+ let pubkey_str = "xpub6D1AabNHCupeiLM65ZR9UStMhJ1vCpyV4XbZdyhMZBiJXALQtmn9p42VTQckoHVn8WNqS7dqnJokZHAHcHGoaQgmv8D45oNUKx6DZMNZBCd";
+ let payload = prepare_payload(hex);
+ let context = prepare_parse_context(pubkey_str);
+ let tx = WrappedTron::from_payload(payload, &context).unwrap();
+ // Create context with different fingerprint
+ let wrong_fp = Fingerprint::from_str("00000000").unwrap();
+ let wrong_context = keystone::ParseContext::new(wrong_fp, context.extended_public_key);
+ let result = tx.check_input(&wrong_context);
+ assert!(result.is_err());
+ assert!(matches!(
+ result.unwrap_err(),
+ TronError::InvalidParseContext(_)
+ ));
+ }
+}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.