network only.Expand description
Component responsible for fetching transactions from NewPooledTransactionHashes.
Fetches transactions that peers announced with NewPooledTransactionHashes.
The TransactionFetcher tracks every announced hash that is not known yet, together with the
peers that announced it, and turns those announcements into GetPooledTransactions requests.
§Model
Every tracked hash is in exactly one of two states:
- pending: waiting for one of the peers that announced it, its candidates, to become idle
- fetching: part of exactly one inflight request
A hash remembers the peers that announced it as candidates. Each peer keeps a FIFO queue of hashes to request, and the first peers to announce a hash get it queued right away. Later announcers are only remembered, so that a hash is not given up on when the first announcers fail to deliver it, without costing a queue entry per announcement. A request for an idle peer is built by draining its queue in the order the announcements were processed, skipping hashes that are being fetched from another peer or are not tracked anymore, until the request is full. Packing a request is therefore proportional to the request size and independent of the total number of pending hashes. FIFO refers to the fetcher’s input order; callers may reorder or deduplicate hashes within a wire announcement.
When a request resolves, delivered hashes are dropped from tracking. Undelivered hashes go back to pending and are queued for their remaining candidates, most recent announcers first, or are dropped if none remain. The responding peer is dropped as a candidate for every undelivered hash that precedes the last delivered hash of the request, treating it as skipped, and for all requested hashes if the response was empty or the request failed. Undelivered hashes after the last delivered hash keep the peer as a candidate only if it delivered at least half of the request, treating that tail as potentially truncated. This is a retry heuristic: transaction counts do not establish whether the response reached a byte limit. Requiring half the request limits repeated low-progress retries.
Request timeouts are enforced by the peer’s session, which resolves the request with
RequestError::Timeout, so the fetcher does not run any timers. A first timeout is retried
once when the responding peer is the only remaining source; otherwise another source is tried.
§Bounds
- a configurable number of inflight requests per peer, one by default, and a global inflight request limit
- a per peer limit on the number of tracked hashes it is a candidate for, so a single peer cannot flood the fetcher with announcements
- a global limit on the number of tracked hashes, at which the peer tracking the most hashes gives up its oldest pending hash, so a group of peers flooding the fetcher evicts its own hashes rather than everyone else’s
- a fixed number of candidates per hash and a separate fetch-attempt limit, so remembering recent fallback sources does not allow unlimited retries
Structs§
- Transaction
Fetcher - Fetches transactions that peers announced but that are not in the pool yet.
Enums§
- Fetch
Event - Represents possible events from fetching transactions.