Skip to content

Conversation

@whankinsiv
Copy link
Collaborator

@whankinsiv whankinsiv commented Nov 13, 2025

Description

This PR refactors both UTXODeltasMessage and AddressDeltasMessage to group deltas per transaction instead of per individual UTxO delta. This fixes incorrect transaction counting in both address_state and historical_accounts_state, particularly in cases where:

  • a transaction has both inputs and outputs to the same address
  • multiple addresses belong to the same stake account

Account level transaction counting is now handled separately in historical_accounts_state, avoiding the need to index TxIdentifier values by address. A new GetAccountTotalTxCount query is added to support the /accounts/{stake_address}/addresses/total endpoint.

Related Issue(s)

How was this tested?

  • Updated existing tests to align with per transaction delta grouping.
  • Removed obsolete tests after confirming they no longer apply to the redesigned data flow.
  • Compared REST results with Blockfrost's /accounts/{stake_address}/addresses/totals to confirm that tx counts now match expected behavior.

Checklist

  • My code builds and passes local tests
  • I added/updated tests for my changes, where applicable
  • I updated comments
  • CI is green for this PR

Impact / Side effects

  • utxo_state constructs a temporary AddressTxMap per transaction to aggregate UTxO deltas before publishing address level deltas.
  • StakeDeltasMessage now includes the per block tx count in the delta.

Reviewer notes / Areas to focus

  • Tx deltas accumulation logic in tx_unpacker/src/tx_unpacker.rs
  • handle in utxo_state/src/state.rs
  • process_message in stake_delta_filter/src/utils.rs

Signed-off-by: William Hankins <william@sundae.fi>
Signed-off-by: William Hankins <william@sundae.fi>
Signed-off-by: William Hankins <william@sundae.fi>
Signed-off-by: William Hankins <william@sundae.fi>
Signed-off-by: William Hankins <william@sundae.fi>
@whankinsiv whankinsiv marked this pull request as ready for review November 13, 2025 01:27
pub received_sum: AmountList,
pub sent_sum: AmountList,
pub tx_count: u64,
pub tx_count: u32,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how many centuries Cardano will need to exist for, before an account is affected by a 4,294,967,296th transaction and makes this endpoint fail

Comment on lines 2157 to 2161
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct TxTotals {
pub sent: ValueDelta,
pub received: Value,
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is sent a ValueDelta but received a Value? It looks like in at least a few places, we assume that sent.lovelace is positive.

(also, it might make some code a little cleaner if TxTotals had an as_delta helper method which returned its data as a ValueDelta)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this Simon. I had assumed ValueDelta was needed downstream but this isn't the case. I've updated TxTotals and AddressTotals to use Value for the sent field in df09d6f.

Copy link
Collaborator

@lowhung lowhung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done 👍


for result in self.tx_count.prefix(account.get_hash().as_ref()) {
let (_, bytes) = result?;
let epoch_count = u32::from_le_bytes(bytes[..4].try_into()?);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

French methods 🤣

store-spdd = false

[module.historical-accounts-state]
# Enables /accounts/{stake_address}/rewards endpoint
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for these!

Signed-off-by: William Hankins <william@sundae.fi>
@whankinsiv whankinsiv merged commit 2a2ab2d into main Nov 14, 2025
2 checks passed
@whankinsiv whankinsiv deleted the whankinsiv/account-tx-count branch November 14, 2025 19:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants