Skip to content

Commit 1b3cbb1

Browse files
committed
fix: defer marking tx as seen until after totals and txs are both processed
Signed-off-by: William Hankins <[email protected]>
1 parent f78f709 commit 1b3cbb1

File tree

2 files changed

+25
-20
lines changed

2 files changed

+25
-20
lines changed

modules/address_state/src/state.rs

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ impl State {
175175
pub fn apply_address_deltas(&mut self, deltas: &[AddressDelta]) {
176176
let addresses = self.volatile.window.back_mut().expect("window should never be empty");
177177

178-
// Keeps track of previous tx to avoid duplicating tx hashes or overcounting totals tx count
178+
// Keeps track seen txs to avoid overcounting totals tx count and duplicating tx identifiers
179179
let mut seen: HashMap<Address, HashSet<TxIdentifier>> = HashMap::new();
180180

181181
for delta in deltas {
@@ -191,30 +191,31 @@ impl State {
191191
}
192192
}
193193

194-
if self.config.store_transactions {
195-
let txs = entry.transactions.get_or_insert(Vec::new());
194+
if self.config.store_transactions || self.config.store_totals {
196195
let seen_for_addr = seen.entry(delta.address.clone()).or_default();
197196

198-
if !seen_for_addr.contains(&tx_id) {
199-
seen_for_addr.insert(tx_id);
200-
txs.push(tx_id);
197+
if self.config.store_transactions {
198+
let txs = entry.transactions.get_or_insert(Vec::new());
199+
if !seen_for_addr.contains(&tx_id) {
200+
txs.push(tx_id);
201+
}
201202
}
202-
}
203-
204-
if self.config.store_totals {
205-
let totals = entry.totals.get_or_insert(Vec::new());
206-
let seen_for_addr = seen.entry(delta.address.clone()).or_default();
207-
208-
if seen_for_addr.contains(&tx_id) {
209-
if let Some(last_total) = totals.last_mut() {
210-
// Create temporary map for summing same tx deltas efficently
211-
let mut map = ValueDeltaMap::from(last_total.clone());
212-
map += delta.value.clone();
213-
*last_total = ValueDelta::from(map);
203+
if self.config.store_totals {
204+
let totals = entry.totals.get_or_insert(Vec::new());
205+
206+
if seen_for_addr.contains(&tx_id) {
207+
if let Some(last_total) = totals.last_mut() {
208+
// Create temporary map for summing same tx deltas efficiently
209+
// TODO: Potentially move upstream to address deltas publisher
210+
let mut map = ValueDeltaMap::from(last_total.clone());
211+
map += delta.value.clone();
212+
*last_total = ValueDelta::from(map);
213+
}
214+
} else {
215+
totals.push(delta.value.clone());
214216
}
215-
} else {
216-
totals.push(delta.value.clone());
217217
}
218+
seen_for_addr.insert(tx_id);
218219
}
219220
}
220221
}

modules/rest_blockfrost/src/handlers/accounts.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,10 @@ pub async fn handle_account_totals_blockfrost(
680680
)
681681
.await?;
682682

683+
// TODO: Query historical accounts state to retrieve account tx count instead of
684+
// using the addresses totals as the addresses totals does not deduplicate
685+
// for multi-address transactions, overstating count
686+
683687
let rest_response = AccountTotalsREST {
684688
stake_address: account.to_string()?,
685689
received_sum: totals.received.into(),

0 commit comments

Comments
 (0)