|
| 1 | +--- |
| 2 | +description: Batch Gateway Protocol |
| 3 | +contributors: |
| 4 | + - raffy.eth |
| 5 | + - nick.eth |
| 6 | +ensip: |
| 7 | + created: "2025-03-15" |
| 8 | + status: draft |
| 9 | +--- |
| 10 | + |
| 11 | +# ENSIP-21: Batch Gateway Offchain Lookup Protocol |
| 12 | + |
| 13 | +## Abstract |
| 14 | + |
| 15 | +This standard establishes the Batch Gateway Offchain Lookup Protocol (BGOLP). |
| 16 | + |
| 17 | +## Motivation |
| 18 | + |
| 19 | +[EIP-3668](https://eips.ethereum.org/EIPS/eip-3668) describes a serial `OffchainLookup` mechanism. To perform more than one `OffchainLookup`, lookups can be preformed in sequence using recursive calls. |
| 20 | + |
| 21 | +This proposal standardizes an existing ENS solution, colloquially called the "Batch Gateway", utilized first by the [`UniversalResolver`](https://etherscan.io/address/0xce01f8eee7E479C928F8919abD53E553a36CeF67#code). It is effectively [`Promise.allSettled()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled) for `OffchainLookup` reverts. |
| 22 | + |
| 23 | +## Specification |
| 24 | + |
| 25 | +The BGOLP has the following Solidity interface: |
| 26 | + |
| 27 | +```solidity |
| 28 | +/// @dev Interface selector: `0xa780bab6` |
| 29 | +interface IBatchGateway { |
| 30 | + /// @notice An HTTP error occurred. |
| 31 | + /// @dev Error selector: `0x01800152` |
| 32 | + error HttpError(uint16 status, string message); |
| 33 | +
|
| 34 | + /// @dev Information extracted from an `OffchainLookup` revert. |
| 35 | + struct Request { |
| 36 | + address sender; // same as `OffchainLookup.sender` |
| 37 | + string[] urls; // same as `OffchainLookup.urls` |
| 38 | + bytes data; // same as `OffchainLookup.callData` |
| 39 | + } |
| 40 | +
|
| 41 | + /// @notice Perform multiple `OffchainLookup` in parallel. |
| 42 | + /// @notice Callers should enable EIP-3668. |
| 43 | + /// @param requests The array of requests to lookup in parallel. |
| 44 | + /// @return failures The failure status of the corresponding request. |
| 45 | + /// @return responses The response or error data of the corresponding request. |
| 46 | + function query( |
| 47 | + Request[] memory requests |
| 48 | + ) external view returns (bool[] memory failures, bytes[] memory responses); |
| 49 | +} |
| 50 | +``` |
| 51 | + |
| 52 | +1. Given an array of `OffchainLookup` reverts, transform each error into a `Request`. |
| 53 | + |
| 54 | +1. Revert `OffchainLookup` with `abi.encodeCall(IBatchedGateway.query, (requests))` as the calldata. |
| 55 | + |
| 56 | + - The reverter must supply its own BGOLP gateway(s). |
| 57 | + - `x-batch-gateway:true` is defined as a special-purpose URL, which indicates an EIP-3668 client may substitute a local BGOLP implementation. If present, the client should always use the local gateway and ignore the other options. All compliant BGOLP gateways are **equivalent**. |
| 58 | + |
| 59 | +1. Upon receiving the callback, decode the response, and propagate the inner callbacks accordingly. It is the developers responsibility to continue the EIP-3668 process. |
| 60 | + |
| 61 | +### Batch Gateway Response |
| 62 | + |
| 63 | +- The length of `failures` and `responses` must equal the number of `requests`. |
| 64 | +- `failures[i]` is `false` if a response was received according to EIP-3668, even if it was error data. |
| 65 | +- `failures[i]` is `true` if the request could not be completed. |
| 66 | + - If a HTTP error is encountered, encode the response using `HttpError`. |
| 67 | + - Otherwise, encode the reason using `Error(string)`. |
| 68 | +- `responses[i]` is the response or error data. |
| 69 | + |
| 70 | +## Rationale |
| 71 | + |
| 72 | +This standard is a prerequisite for local BGOLP implementations in client frameworks. |
| 73 | + |
| 74 | +A local BGOLP gateway is a privacy and latency improvement. |
| 75 | + |
| 76 | +## Backwards Compatibility |
| 77 | + |
| 78 | +The `UniversalResolver` is the only known contract that uses the BGOLP. Its design permits client-supplied gateways. In nearly all implementations, clients are using the default. |
| 79 | + |
| 80 | +## Security Considerations |
| 81 | + |
| 82 | +A local BGOLP gateway is **always preferable** as an external gateway leaks information and adds latency. |
| 83 | + |
| 84 | +BGOLP gateways **should curtail the maximum number of simultaneous requests** in aggregate and per host to avoid DDOS attacks. |
| 85 | + |
| 86 | +BGOLP gateways **should not be trusted**. Each individual `OffchainLookup` must secure its own protocol. |
| 87 | + |
| 88 | +## Copyright |
| 89 | + |
| 90 | +<!-- Just leave this how it is --> |
| 91 | + |
| 92 | +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). |
| 93 | + |
| 94 | +## Annex: Fault Tolerance |
| 95 | + |
| 96 | +To perform an `OffchainLookup` that does not terminate unexpectedly, a single lookup with `n` gateways can be transformed into a BGOLP lookup with `n` requests, each with a single gateway. In exchange for fault tolerance, the response time will match the slowest gateway and successful responses will be replicated. |
0 commit comments