Skip to content

apollo_mempool: fetch timestamps in echonet mode#12850

Merged
ayeletstarkware merged 1 commit intomain-v0.14.2from
ayelet/mempool/fifo/fetch_timestamp
Mar 6, 2026
Merged

apollo_mempool: fetch timestamps in echonet mode#12850
ayeletstarkware merged 1 commit intomain-v0.14.2from
ayelet/mempool/fifo/fetch_timestamp

Conversation

@ayeletstarkware
Copy link
Contributor

@ayeletstarkware ayeletstarkware commented Feb 25, 2026

Note

Medium Risk
Adds external HTTP dependency and changes transaction ingestion behavior in Echonet mode (transactions may be skipped on recorder failures), which can affect replay correctness and test stability.

Overview
In apollo_mempool, add_tx now conditionally fetches a transaction’s original mainnet timestamp from a configured recorder endpoint in Echonet mode (with request timeout + exponential backoff retries) and skips the transaction if the timestamp cannot be fetched.

This introduces a new static config field mempool_config.static_config.recorder_url (plumbed into node config pointers and schema), adds timestamp update plumbing (update_timestamp) on the mempool/queue trait surface, and includes ignored integration tests with an axum mock recorder server.

Written by Cursor Bugbot for commit 1eab5c8. This will update automatically on new commits. Configure here.

@reviewable-StarkWare
Copy link

This change is Reviewable

@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch from 39d5cf6 to ba917fb Compare February 25, 2026 10:03
@ayeletstarkware ayeletstarkware changed the base branch from ayelet/mempool/fifo/deployment-mode to graphite-base/12850 February 25, 2026 12:24
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch from ba917fb to 9a5a3fc Compare February 25, 2026 12:32
@ayeletstarkware ayeletstarkware changed the base branch from graphite-base/12850 to ayelet/mempool/fifo/deployment-mode February 25, 2026 12:33
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch from 9a5a3fc to 5ba5a55 Compare February 25, 2026 12:40
@ayeletstarkware ayeletstarkware changed the base branch from ayelet/mempool/fifo/deployment-mode to graphite-base/12850 February 25, 2026 14:33
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch from 5ba5a55 to 6a3d616 Compare February 25, 2026 14:36
@ayeletstarkware ayeletstarkware changed the base branch from graphite-base/12850 to ayelet/mempool/fifo/deployment-mode February 25, 2026 14:36
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch from 6a3d616 to c2e542f Compare February 25, 2026 14:46
@ayeletstarkware ayeletstarkware changed the base branch from ayelet/mempool/fifo/deployment-mode to graphite-base/12850 February 25, 2026 15:11
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch from c2e542f to 859c833 Compare February 25, 2026 15:11
@ayeletstarkware ayeletstarkware changed the base branch from graphite-base/12850 to ayelet/mempool/fifo/deployment-mode February 25, 2026 15:11
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch from 859c833 to 97080c0 Compare February 25, 2026 15:13
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch from e5f0d51 to 1ef60f5 Compare February 26, 2026 15:33
@ayeletstarkware ayeletstarkware changed the base branch from graphite-base/12850 to ayelet/mempool/fifo/deployment-mode February 26, 2026 15:33
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch from 1ef60f5 to 21674b7 Compare March 1, 2026 10:02
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/deployment-mode branch 2 times, most recently from 0d78cce to b8b509f Compare March 1, 2026 15:17
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch 2 times, most recently from 90b9b4e to a837dfb Compare March 1, 2026 15:30
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/deployment-mode branch from b8b509f to 269bda9 Compare March 1, 2026 15:30
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch from a837dfb to f8cb984 Compare March 2, 2026 08:56
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/deployment-mode branch from 269bda9 to 7eb9c20 Compare March 2, 2026 08:56
Copy link
Collaborator

@matanl-starkware matanl-starkware left a comment

Choose a reason for hiding this comment

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

@matanl-starkware reviewed 11 files and all commit messages, and made 6 comments.
Reviewable status: 11 of 12 files reviewed, 7 unresolved discussions (waiting on ayeletstarkware and ron-starkware).


crates/apollo_mempool/src/communication.rs line 54 at r4 (raw file):

    mempool_p2p_propagator_client: SharedMempoolP2pPropagatorClient,
    config_manager_client: SharedConfigManagerClient,
    http_client: reqwest::Client,

What's the motivation for keeping this as a member?
Is it to preserve the connection opened?

Code quote:

http_client: reqwest::Client,

crates/apollo_mempool/src/communication.rs line 109 at r4 (raw file):

            let tx_hash = args_wrapper.args.tx.tx_hash();
            if !self.fetch_and_update_timestamp(tx_hash).await {
                warn!("Failed to fetch timestamp for tx {}, skipping transaction", tx_hash);

Is it printed as hex by default?

Code quote:

{}

crates/apollo_mempool/src/communication.rs line 189 at r4 (raw file):

                }
            }
        }

Consider using reqwest_retry crate.
See example here:

let retry_policy = ExponentialBackoff::builder()

Code quote:

        for attempt in 0..MAX_RETRIES {
            match self.try_fetch_timestamp(&url, attempt).await {
                Ok(timestamp) => {
                    self.mempool.update_timestamp(tx_hash, timestamp);
                    return true;
                }
                Err(e) => {
                    if attempt + 1 >= MAX_RETRIES {
                        warn!("Failed to fetch timestamp for tx {}: {}", tx_hash, e);
                        return false;
                    }
                    sleep(std::time::Duration::from_millis(RETRY_DELAY_MS)).await;
                }
            }
        }

crates/apollo_mempool/src/communication.rs line 197 at r4 (raw file):

        &self,
        url: &reqwest::Url,
        attempt: usize,

IMO this method should not care about attempts.
The caller may print the attempt number if Err is returned.

Code quote:

attempt: usize,

crates/apollo_mempool/src/mempool.rs line 293 at r4 (raw file):

    pub(crate) fn update_timestamp(&mut self, tx_hash: TransactionHash, timestamp: UnixTimestamp) {
        if !self.is_fifo() {
            debug!(

This should never happen, unless something is broken.
In fact, I suggest:

Suggestion (i):

panic

Code snippet (ii):

assert!(self.is_fifo(), "Update timestamp called for tx {} in non-echonet mode")

crates/apollo_node/resources/config_schema.json line 3602 at r4 (raw file):

    "value": 1000000
  }
}

Missing a new line

@ayeletstarkware ayeletstarkware changed the base branch from ayelet/mempool/fifo/deployment-mode to graphite-base/12850 March 3, 2026 08:57
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch from f8cb984 to 938bbec Compare March 3, 2026 11:49
Copy link
Contributor Author

@ayeletstarkware ayeletstarkware left a comment

Choose a reason for hiding this comment

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

@ayeletstarkware made 6 comments.
Reviewable status: 11 of 12 files reviewed, 7 unresolved discussions (waiting on matanl-starkware and ron-starkware).


crates/apollo_mempool/src/communication.rs line 54 at r4 (raw file):

Previously, matanl-starkware (Matan Lior) wrote…

What's the motivation for keeping this as a member?
Is it to preserve the connection opened?

stale


crates/apollo_mempool/src/communication.rs line 109 at r4 (raw file):

Previously, matanl-starkware (Matan Lior) wrote…

Is it printed as hex by default?

yes


crates/apollo_mempool/src/communication.rs line 189 at r4 (raw file):

Previously, matanl-starkware (Matan Lior) wrote…

Consider using reqwest_retry crate.
See example here:

let retry_policy = ExponentialBackoff::builder()

Done.


crates/apollo_mempool/src/communication.rs line 197 at r4 (raw file):

Previously, matanl-starkware (Matan Lior) wrote…

IMO this method should not care about attempts.
The caller may print the attempt number if Err is returned.

Done.


crates/apollo_mempool/src/mempool.rs line 293 at r4 (raw file):

Previously, matanl-starkware (Matan Lior) wrote…

This should never happen, unless something is broken.
In fact, I suggest:

Done.


crates/apollo_node/resources/config_schema.json line 3602 at r4 (raw file):

Previously, matanl-starkware (Matan Lior) wrote…

Missing a new line

Done.

@ayeletstarkware ayeletstarkware changed the base branch from graphite-base/12850 to ayelet/mempool/fifo/deployment-mode March 3, 2026 11:49
@ayeletstarkware ayeletstarkware changed the base branch from ayelet/mempool/fifo/deployment-mode to graphite-base/12850 March 3, 2026 15:27
@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch from 938bbec to fa47fa1 Compare March 4, 2026 13:33
@ayeletstarkware ayeletstarkware changed the base branch from graphite-base/12850 to main-v0.14.2 March 4, 2026 13:33
Copy link
Collaborator

@matanl-starkware matanl-starkware left a comment

Choose a reason for hiding this comment

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

@matanl-starkware reviewed 6 files and all commit messages, made 3 comments, and resolved 6 discussions.
Reviewable status: 11 of 12 files reviewed, 4 unresolved discussions (waiting on ayeletstarkware and ron-starkware).


crates/apollo_mempool/src/communication.rs line 58 at r5 (raw file):

    mempool_p2p_propagator_client: SharedMempoolP2pPropagatorClient,
    config_manager_client: SharedConfigManagerClient,
    client: ClientWithMiddleware,

Too generic IMO.
Maybe echonet_client?

Code quote:

client

crates/apollo_mempool/src/communication.rs line 68 at r5 (raw file):

    ) -> Self {
        const MIN_RETRY_INTERVAL: Duration = Duration::from_millis(50);
        const MAX_RETRY_INTERVAL: Duration = Duration::from_millis(50);

Suggestion:

const MAX_RETRY_INTERVAL: Duration = Duration::from_millis(500);

crates/apollo_mempool/src/communication.rs line 180 at r5 (raw file):

    // Returns true if successful, false if failed after all retries.
    pub(crate) async fn fetch_and_update_timestamp(&mut self, tx_hash: TransactionHash) -> bool {
        let recorder_url = &self.mempool.config.static_config.recorder_url;

Lets add a comment explaining why in EchoNet setup we fetch the timestamp from the recorder...

Code quote:

.recorder_url

@ayeletstarkware ayeletstarkware force-pushed the ayelet/mempool/fifo/fetch_timestamp branch from fa47fa1 to 1eab5c8 Compare March 5, 2026 13:45
Copy link
Contributor Author

@ayeletstarkware ayeletstarkware left a comment

Choose a reason for hiding this comment

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

@ayeletstarkware made 3 comments.
Reviewable status: 11 of 12 files reviewed, 4 unresolved discussions (waiting on matanl-starkware and ron-starkware).


crates/apollo_mempool/src/communication.rs line 58 at r5 (raw file):

Previously, matanl-starkware (Matan Lior) wrote…

Too generic IMO.
Maybe echonet_client?

Done.


crates/apollo_mempool/src/communication.rs line 180 at r5 (raw file):

Previously, matanl-starkware (Matan Lior) wrote…

Lets add a comment explaining why in EchoNet setup we fetch the timestamp from the recorder...

Done.


crates/apollo_mempool/src/communication.rs line 68 at r5 (raw file):

    ) -> Self {
        const MIN_RETRY_INTERVAL: Duration = Duration::from_millis(50);
        const MAX_RETRY_INTERVAL: Duration = Duration::from_millis(50);

Done. just to confirm:
Previously, with min=max=50ms, there’s no exponential backoff, the client retries every 50ms for up to 10s (~200 attempts).
With min=50ms, max=500ms, exponential backoff is enabled (50, 100,... 500ms), resulting in ~30 retries over 10s with increasing delays.

Copy link
Collaborator

@matanl-starkware matanl-starkware left a comment

Choose a reason for hiding this comment

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

@matanl-starkware reviewed 4 files and all commit messages, and resolved 3 discussions.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on ron-starkware).

@ayeletstarkware ayeletstarkware added this pull request to the merge queue Mar 6, 2026
Merged via the queue into main-v0.14.2 with commit e193b0f Mar 6, 2026
41 of 45 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Mar 8, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants