diff --git a/p2p-specs/p2p-interface.md b/p2p-specs/p2p-interface.md index 329e16a..4a386c4 100644 --- a/p2p-specs/p2p-interface.md +++ b/p2p-specs/p2p-interface.md @@ -98,10 +98,11 @@ This section outlines constants that are used in this spec. | Name | Value | Description | |---|---|---| -| `GOSSIP_MAX_SIZE` | `2**20` (= 1048576, 1 MiB) | The maximum allowed size of uncompressed gossip messages. | -| `MAX_OPS_PER_REQUEST`| `4096` | Maximum number of UserOps in a single request. | -| `RESP_TIMEOUT` | `10s` | The maximum time for complete response transfer. | -| `TTFB_TIMEOUT` | `5s` | The maximum time to wait for first byte of request response (time-to-first-byte). | +| `GOSSIP_MAX_SIZE` | `2**20` (= 1048576, 1 MiB) | The maximum allowed size of uncompressed gossip messages. | +| `MAX_OPS_PER_REQUEST` | `4096` | Maximum number of UserOps in a single request. | +| `RESP_TIMEOUT` | `10s` | The maximum time for complete response transfer. | +| `TTFB_TIMEOUT` | `5s` | The maximum time to wait for first byte of request response (time-to-first-byte). | +| `POOLED_HASHES_CONTEXT_TIMEOUT`| `10s` | The amount of time to maintain a request context of pooled hashes. | ## MetaData @@ -494,24 +495,38 @@ Request Content: ``` ( - mempool: Bytes32 - offset: uint64 + // cursor + Bytes32 ) ``` Response Content: ``` ( - more_flag: uint64 hashes: List[Bytes32, MAX_OPS_PER_REQUEST] + next_cursor: Bytes32 ) ``` -The `pooled_user_ops_by_hash` requests UserOp mempool of all connected peers as soon as bundler node starts up. The node requests UserOps from the recipients mempool for a given `mempool_id` and `offset`. The `offset` is set to `0` for the initial call. The recommended soft limit for PooledUserOpHashes requests is `MAX_OPS_PER_REQUEST` hashes. The recipient may enforce an arbitrary limit on the response (size or serving time), which must not be considered a protocol violation. The `more_flag` is set to 0, if the connected peer's reported hashes is <= to `MAX_OPS_PER_REQUEST`. Otherwise the `more_flag` is set to a value > 0. The value of `more_flag` can be used to determine the number of subsequent req/resp a node has to perform to refetch the missing hashes from the connected peer. +The `pooled_user_ops_by_hash` request is used to sync the mempool contents of a connected peer. Clients MAY send this request to each peer as they are connected when the bundler node starts up in order to sync their mempool. -The request/response MUST be encoded as a single SSZ-field. +In the initial request the requestor should send a zero-value cursor, indicating to the recipient to start a new request context. -The response MUST consist of a single `response_chunk`. +As part of the initial handshake process the recipient of this request MUST know the mempool IDs that the requester and recipient have in common. Upon receiving a request with an empty cursor, the recipient MUST construct a list of user operation hashes from these common mempools. The recipient responds with this list of hashes. If the number of hashes is greater than `MAX_OPS_PER_REQUEST`, the recipient MAY respond with a non-zero `next_cursor` value and save a request context. + +`next_cursor` is an opaque value chosen by the recipient to enable pagination in the request context. + +If a requestor receives a non-zero `next_cursor` value, they MAY send a request with this cursor value. The recipient interprets this cursor and responds with another, disjoint, list of hashes. This process can continue until the recipient runs out valid hashes and returns a zero `next_cursor` value. The recipient MUST remove any already mined hashes from the request context as to respond with only valid user operations. The recipient should otherwise not modify the context and user operations that were added to the pool after the initial request are not subject to this request context and can be received by starting a new request. + +A recipient SHOULD drop a request context after `POOLED_HASHES_CONTEXT_TIMEOUT` seconds from initial request, if a cursor is received for a context that is timed out the recipient MUST return an error. + +The requester SHOULD: +- Complete its requests within `POOLED_HASHES_CONTEXT_TIMEOUT` +- Disconnect from any peer that responds with a user operation that does not belong to one of their supported mempools. + +The request MUST be encoded as a single SSZ-field. + +The response MUST be encoded as an SSZ-container and MUST consist of a single `response_chunk`. #### PooledUserOpsByHash