In the context of the ERC-6860 web3://
standard, this ERC extends the ERC-6944 resolve mode. It introduces mechanisms to address limitations that prevent the use of standard RFC 9111 HTTP caching.
Calls to Ethereum RPC providers are costly—both CPU-wise for local nodes and monetarily for paid external RPC providers. Furthermore, external RPC providers are rate-limited, which can quickly cause disruptions when loading web3://
URLs.
Therefore, it makes sense to implement caching mechanisms to reduce RPC calls when possible. Since web3://
aims to be as close to HTTP as possible, leveraging standard RFC 9111 HTTP caching is the natural choice. In the ERC-6944 resolve mode, smart contracts can already return standard HTTP caching headers like Cache-Control
and ETag
.
However, due to the ERC-6944 resolve mode not forwarding request HTTP headers to the smart contract, smart contracts cannot handle If-None-Match
and If-Modified-Since
cache validation headers. Consequently, they are limited to using the Cache-control: max-age=XX
mechanism, which causes each cache validation request to trigger an RPC call, regenerating the full response.
This ERC proposes a solution to bypass this limitation by allowing websites to broadcast cache invalidations via smart contract events.
Additionally, even if smart contracts could read request HTTP headers, using smart contract events is more efficient, as it moves cache invalidation logic outside the contract.
We add this feature to the ERC-6944 resolve mode because it can be added without changes to the interface. Future resolve modes that allow for request HTTP headers may also implement this ERC.
This standard introduces the evm-events
cache directive for the Cache-Control
header of request responses, as an extension directive as defined in section 5.2.3 of RFC 9111.
When an ERC-6944 resolve mode website wants to use event-based caching for a request, it MUST:
evm-events
directive in the Cache-Control
header of the response.ETag
and/or Cache-Control
headers in the response, as per traditional RFC 9111 HTTP caching.A value to the evm-events
cache directive is optional, and can be used to specify to listen for additional events on other smart contracts, and/or for other paths. The cache directive value syntax in ABNF notation is :
cache-directive-value = [ address-path-absolute *( " " address-path-absolute ) ]
address-path-absolute = [ address ] path-absolute [ "?" query ]
address = "0x" 20( HEXDIG HEXDIG )
path-absolute = <path-absolute, see RFC 3986, Section 3.3>
query = <query, see RFC 3986, Section 3.4>
Examples:
Cache-control: evm-events
: The cache of the page returning this directive will be cleared when the contract having responded to the request emits a cache clearing event for the path of the page having been served.Cache-control: evm-events="/path/path2"
: Same behavior than the first example, but additionally the cache of the page returning this directive will be cleared when the contract having responded to the request emits a cache clearing event for path /path/path2
.Cache-control: evm-events="0xe4ba0e245436b737468c206ab5c8f4950597ab7f/path/path2"
: Same behavior than the first example, but additionally the cache of the page returning this directive will be cleared when the contract 0xe4ba0e245436b737468c206ab5c8f4950597ab7f
emits a cache clearing event for path /path/path2
.Cache-control: evm-events="0xe4ba0e245436b737468c206ab5c8f4950597ab7f"
: Same behavior than the first example, but additionally the cache of the page returning this directive will be cleared when the contract 0xe4ba0e245436b737468c206ab5c8f4950597ab7f
emits a cache clearing event for the path of the page having been served.Cache-control: evm-events="/path/path2 /path/path3"
: Same behavior than the first example, but additionally the cache of the page returning this directive will be cleared when the contract having responded to the request emits a cache clearing event for path /path/path2
or /path/path3
.The event is defined as:
event ClearPathCache(string[] paths);
This event clears the cache for an array of paths
. Each path
refers to the pathQuery
part of the ABNF definition in ERC-6860.
path
MUST NOT end with a /
, except when the whole path is the root path, which is /
.paths
are considered identical if they have the same ERC-5219 resource entries and their parameter values match, regardless of the order.Example:
- /test?a=1&b=2
and /test?b=2&a=1
are considered identical.
paths
may contain *
wildcards, with the following rules:
*
) can be used on its own in an ERC-5219 resource entry.path
will be ignored.Examples:
- /*
will match /test
but not /test/abc
and not /
.
- /test/*
will match /test/abc
but will not match /test/
or /test/abc/def
.
- /*/abc
will match /test/abc
, but not //abc
.
- /t*t
is invalid, so the path
will be ignored.
path
will be ignored.Examples:
- /abc?a=*
will match /abc?a=zz
but not /abc?a=
or /abc?a=zz&b=cc
.
- /abc?a=*&b=*
will match /abc?a=1&b=2
and /abc?b=2&a=1
.
- /abc?a=z*
is invalid, so the path
will be ignored.
path
containing only a *
will match every path within the smart contract.Wildcards are intentionally limited to these simple cases to facilitate efficient path lookup implementations.
web3://
ClientsA web3://
client can be in one of two cache invalidation states for each chain and smart contract:
Listening for Events:
The web3://
client MUST listen for the cache invalidation events defined earlier and should aim to stay as close to real-time as possible.
Not Listening for Events:
This is the default state when this ERC is not implemented. In this state, the web3://
client ignores all HTTP caching validation requests (e.g., If-None-Match
, If-Modified-Since
request headers).
The web3://
client can switch between these states at any time and MAY implement heuristics to optimize the use of RPC providers by switching states as appropriate.
The web3://
client maintains a key-value mapping for caching, which MUST be cleared whenever it transitions from "Listening for Events" to "Not Listening for Events." The mapping is structured as follows:
mapping(
(<chain id>, <contract address>, <ERC-6860 pathQuery>)
=>
(<last modified date>, <ETag>)
)
Additional elements can be included in the mapping key when necessary. For example, ERC-7618 requires the inclusion of the Accept-Encoding
request header in the mapping key.
When a request is received in the "Listening for Events" state:
web3://
client queries the smart contract.evm-events
directive in the Cache-Control
header and an ETag
, a mapping entry is created using the ETag
.evm-events
directive and a max-age=XX
directive in the Cache-Control
header, the mapping entry is created with the last modified date
, determined in the following order of priority:Last-Modified
header, if present.Date
header, if present.If the response includes both an ETag
and a Cache-Control: evm-events max-age=XX
directive, a single mapping entry is created containing both the ETag
and the last modified date
.
If a mapping entry exists:
If the request contains a valid If-None-Match
header:
ETag
in the mapping matches the If-None-Match
value, the web3://
client returns a 304 Not Modified
response immediately.ETag
does not match, the client queries the smart contract, deletes the mapping entry, and processes the request as if no mapping entry existed.If the request contains a valid If-Modified-Since
header:
last modified date
in the mapping is earlier than the If-Modified-Since
date, the client returns a 304 Not Modified
response immediately.If the request contains neither If-None-Match
nor If-Modified-Since
headers (or they are invalid):
In the "Listening for Events" state, the web3://
client listens to the blockchain for the cache invalidation events defined in the previous section. For each path match, it deletes the corresponding mapping entry.
To stay as close as possible to standard HTTP, we reuse the HTTP caching mechanism headers.
The use of the evm-events
directive is necessary to avoid a situation where a website uses traditional RFC 9111 HTTP caching headers, but the contract does not implement this ERC by failing to emit the events. In such cases, web3://
clients implementing this ERC would serve stale content for that website indefinitely.
Stale content will be served during the delay between a user transaction emitting a cache clearing event, and the web3://
client picking and processing the event.
For each cached page, websites must properly implement cache invalidation events; otherwise, stale content will be served indefinitely.
In the event of a chain reorganization, the web3://
client must roll back its caching state, or reverted content will be served until the next cache clearing event.
Copyright and related rights waived via CC0.