Skip to content

Conversation

@whankinsiv
Copy link
Collaborator

@whankinsiv whankinsiv commented Oct 30, 2025

This PR implements ShelleyAddress indexing by StakeAddress in historical_accounts_state along with the corresponding REST handler as part of #256. Addresses are returned in the order they were first discovered on chain to match Blockfrost's return schema.

Main changes

  • Refactored stake_delta_filter to group deltas by stake address and added a new addresses field to StakeAddressDelta, providing context on which Shelley addresses were involved in each account delta.
  • Updated mithril_snapshot_fetcher to include time deltas between pauses, providing a loose benchmarking mechanism for different implementations.
  • Implemented placeholder methods handle_address_deltas, get_addresses, and GetAccountAssociatedAddresses query handler in historical_accounts_state
  • Added and registered the /accounts/{stake_address}/addresses endpoint via handle_account_addresses_blockfrost.

Performance evaluation

3 persistence approaches were evaluated:

  1. Vec read/append/write:
    Encoded Vec approach was extremely inefficient, consuming ~7x the storage of the duplicated key strategy.
  2. read/filter/write new keys:
    Acceptable performance but ~10% slower due to read before write checks.
    • Epoch 500: 1.4 GB DB size, 75.7 minute sync
  3. Blind duplicate writes (implemented):
    Writes new keys without reads with filtering handled in the getter.
    • Epoch 500: 2.1GB DB size, 68.7 minute sync

Next steps:

The next PR will implement:

  • /accounts/{stake_address}/addresses/total
  • /acounts/{stake_address}/addresses/assets
  • /accounts/{stake_address}/utxos

Signed-off-by: William Hankins <william@sundae.fi>
…eward-processing' into whankinsiv/historical-accounts-address-indexing
Signed-off-by: William Hankins <william@sundae.fi>
…batching

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>
…tter

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>
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 3, 2025 23:30
async fn prompt_pause(description: String, next_description: String) -> bool {
async fn prompt_pause(description: String) -> bool {
info!(
"Paused at {description}. Press [Enter] to step to {next_description}, or [c + Enter] to continue without pauses."
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a reason we've removed the next description here? Just for my understanding

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was removed because next description needed to be called after incrementing to the next pause value. We don't want to increment the pause value (and the start time) until after the user ends the pause.

Signed-off-by: William Hankins <william@sundae.fi>
Signed-off-by: William Hankins <william@sundae.fi>
};

let payment_bits = (header >> 4) & 0x01;
let delegation_bits = (header >> 5) & 0x03;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
let delegation_bits = (header >> 5) & 0x03;
let delegation_bits = (header >> 5) & 0x07;

Looking at CIP-0019, there are 8 valid types of Shelley addresses (2 kinds of payment part, 4 kinds of delegation part). The high bit of the header should always be 0, and if it isn't then this isn't a valid Shelley address.

This change will make the method reject header types 8 through 15 with an "invalid delegation bits" error.

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've fixed this issue and expanded the test_shelley_address_to_from_bytes_key_roundtrip() to check for the correct header byte for all address types in 10c2c09.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the updated version still has the issue. It'll decode all 8 valid address types, but it should fail when you try decoding something where the high bit is 0x80 (and right now it won't)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've added a guard for header & 0x80 != 0 in 39a8919.

Signed-off-by: William Hankins <william@sundae.fi>
Signed-off-by: William Hankins <william@sundae.fi>
@whankinsiv whankinsiv merged commit c8b9cd9 into main Nov 5, 2025
2 checks passed
@whankinsiv whankinsiv deleted the whankinsiv/historical-accounts-address-indexing branch November 5, 2025 17:24
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