Skip to content

Commit 3f6313d

Browse files
committed
Handle traces missing transactions_order
Make Trace.transactions_order default when deserializing and add Trace::root_transaction to pick the root transaction either from transactions_order or (if missing) fall back to the only transaction present. Update map_root_trace_transaction to use Trace::root_transaction. Add a unit test to cover traces without transactions_order and adjust serde_json imports. Also include minor formatting/assert simplifications and whitespace cleanup in support crates.
1 parent fc77293 commit 3f6313d

5 files changed

Lines changed: 46 additions & 18 deletions

File tree

core/crates/gem_ton/src/models/transaction.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,22 @@ pub struct TraceByAddressQuery {
7373
pub struct Trace {
7474
pub is_incomplete: bool,
7575
pub actions: Vec<TraceAction>,
76+
#[serde(default)]
7677
pub transactions_order: Vec<String>,
7778
pub transactions: HashMap<String, TransactionMessage>,
7879
}
7980

8081
impl Trace {
8182
pub fn root_transaction(&self) -> Option<&TransactionMessage> {
82-
let transaction_id = self.transactions_order.first()?;
83-
self.transactions.get(transaction_id)
83+
if let Some(transaction_id) = self.transactions_order.first() {
84+
return self.transactions.get(transaction_id);
85+
}
86+
87+
if self.transactions.len() == 1 {
88+
return self.transactions.values().next();
89+
}
90+
91+
None
8492
}
8593

8694
pub fn has_actions(&self) -> bool {

core/crates/gem_ton/src/provider/transactions_mapper.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@ struct TransferDetails {
7171

7272
fn map_root_trace_transaction(trace: Trace) -> Option<Transaction> {
7373
let state = if trace.is_incomplete || trace.has_actions() { Some(trace.action_state()) } else { None };
74-
let root_hash = trace.transactions_order.first()?;
75-
let root = trace.transactions.get(root_hash)?;
74+
let root = trace.root_transaction()?;
7675

7776
let details = jetton_swap_details(&trace.actions)
7877
.or_else(|| nft_transfer_details(&trace.actions))
@@ -262,7 +261,7 @@ mod tests {
262261
use crate::models::{MessageTransactions, TraceResponse};
263262
use crate::provider::testkit::{FAILED_SWAP_ROOT_TRANSACTION_HEX_HASH, SUCCESS_SWAP_ROOT_TRANSACTION_HEX_HASH, TEST_TRANSACTION_ID};
264263
use primitives::testkit::signer_mock::TEST_TON_SENDER;
265-
use serde_json::json;
264+
use serde_json::{Map, Value, json};
266265

267266
const NFT_NEW_OWNER: &str = "UQDSkZZueXRl0lUk4hagLa8KrJzZbmtTE_RPZwTDSIw32WNH";
268267

@@ -494,4 +493,36 @@ mod tests {
494493
assert_eq!(transactions[0].state, TransactionState::Confirmed);
495494
assert_eq!(transactions[1].state, TransactionState::Reverted);
496495
}
496+
497+
#[test]
498+
fn test_map_trace_transactions_without_transactions_order() {
499+
let message_transactions: MessageTransactions = serde_json::from_str(include_str!("../../testdata/transaction_transfer_state_success.json")).unwrap();
500+
let root = message_transactions.transactions.first().unwrap();
501+
502+
let mut root_value = serde_json::to_value(root).unwrap();
503+
if let Value::Object(transaction) = &mut root_value {
504+
transaction.insert("total_fees".to_string(), json!(root.total_fees.to_string()));
505+
}
506+
507+
let mut transactions = Map::new();
508+
transactions.insert(root.hash.clone(), root_value);
509+
510+
let mut trace = Map::new();
511+
trace.insert("is_incomplete".to_string(), json!(false));
512+
trace.insert("actions".to_string(), json!([]));
513+
trace.insert("transactions".to_string(), Value::Object(transactions));
514+
515+
let mut response = Map::new();
516+
response.insert("traces".to_string(), Value::Array(vec![Value::Object(trace)]));
517+
518+
let traces: TraceResponse = serde_json::from_value(Value::Object(response)).unwrap();
519+
520+
assert_eq!(traces.traces[0].transactions_order, Vec::<String>::new());
521+
522+
let transactions = map_trace_transactions(traces.traces);
523+
524+
assert_eq!(transactions.len(), 1);
525+
assert_eq!(transactions[0].hash, "9ba7d317aaed24089e5cc3b0df4432294cb88ed485d202768cc2766432aec3e0");
526+
assert_eq!(transactions[0].state, TransactionState::Confirmed);
527+
}
497528
}

core/crates/primitives/src/support.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,3 @@ pub enum SupportAction {
9595
Typing(SupportTypingStatus),
9696
LastSeen,
9797
}
98-

core/crates/support/src/model.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -371,12 +371,7 @@ mod tests {
371371
assert_eq!(messages.len(), 1);
372372
assert_eq!(messages[0].id, "1");
373373
assert_eq!(messages[0].content, "from agent");
374-
assert_eq!(
375-
messages[0].sender,
376-
SupportMessageSender::Agent(SupportAgent {
377-
name: "Test Agent".to_string(),
378-
})
379-
);
374+
assert_eq!(messages[0].sender, SupportMessageSender::Agent(SupportAgent { name: "Test Agent".to_string() }));
380375
assert_eq!(messages[0].status, SupportMessageDeliveryStatus::Sent);
381376
}
382377

core/crates/support/tests/model_tests.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,7 @@ fn test_support_message_mapping() {
3939
assert_eq!(message.id, "1");
4040
assert_eq!(message.content, "from agent");
4141
assert!(message.images.is_empty());
42-
assert_eq!(
43-
message.sender,
44-
SupportMessageSender::Agent(SupportAgent {
45-
name: "Test Agent".to_string(),
46-
})
47-
);
42+
assert_eq!(message.sender, SupportMessageSender::Agent(SupportAgent { name: "Test Agent".to_string() }));
4843
assert_eq!(message.status, SupportMessageDeliveryStatus::Sent);
4944
}
5045

0 commit comments

Comments
 (0)