…
…
5. If the sender field does not match the address of the contract that was called, return an error to the caller and stop.
6. Construct a request URL by replacing sender with the lowercase 0x-prefixed hexadecimal formatted sender parameter, and replacing data with the 0x-prefixed hexadecimal formatted callData parameter. The client may choose which URLs to try in which order, but SHOULD prioritise URLs earlier in the list over those later in the list.
7. Make an HTTP GET request to the request URL.
8. If the response code from step (5) is in the range 400-499, return an error to the caller and stop.
9. If the response code from step (5) is in the range 500-599, go back to step (5) and pick a different URL, or stop if there are no further URLs to try.
10. Otherwise, replace data with an ABI-encoded call to the contract function specified by the 4-byte selector callbackFunction, supplying the data returned from step (7) and extraData from step (4), and return to step (1).
I think (5) mentioned in 8 & 9 is typo from draft, that should be (7)??
During CCIP read IF (7) request fails with clientside/network errors (server rejects or ssl errors) without any http status code, that’s preventing auto fallback to secondary gateway url. For failsafe scenario CCIP clients should try all fallback gateways until status code == 200 before giving up.
On ethers.js it’s sending fetch request outside of try catch. No Universal Resolver.
Edit : almost forgot ethers.js error logs, we’ve listed total primary+3 IPFS gateways for CCIP read.
ethers.min.js:1
GET https://e501017….99f7d5d….eab2c38eedc50…1a8bd0def.ipfs2.eth.limo/.well-known/eth/freetib/contenthash.json?t=0x5824
net::ERR_HTTP2_PROTOCOL_ERROR
ethers.min.js:1
Uncaught (in promise) TypeError: Failed to fetch
at FetchRequest.getUrl (ethers.min.js:1:15378)
at #send (ethers.min.js:1:21605)
....
To clarify, you mean status 4XX shouldn’t abort the gateway iteration?
What about 2XX with junk?
I’d go one step further and say termination should be decided by the contract.
OffchainNext.sol lets the contract decide if it wants to accept the response. It does randomized gateway iteration too. It works today w/o any framework modification. It only does 1-of-n but it could be extended to do m-of-n.
I have a pretty cool demo where I have an setup with various endpoints + one good one, and forcibly try all permutations and request always succeeds (at the expense of extra latency.)
I also have a demo where I use this with an EVMGateway, where it blocks a malicious gateway from supplying it invalid proofs (which would appear like normal 200 properly formatted response.) This illustrates the nuance in the error types:
if 200 but "kek" or {data: "0x"}, that’s an invalid response → next
if 200 with valid looking proofs but they were wrong, that’s an invalid response → next
if 200 with valid proofs that assert you can’t do something or divide by zero, that’s a valid response but an execution error → fail
if 200 with valid proofs and success → success
Additionally, we should also emphasize that {sender} is not necessarily actual requestor, and that requesting identity should be encoded into the endpoint URL to indicate the chain and contract (eg. signing relative to sender is bad practice.)
Aborting after 4xx error will give full power to first gateway in list to halt whole lookup process.
eg, in a randomized gateway list of N =5, if 1 gateway is throwing 4XX that’s 20% failed offchain lookup as there’s no fallback.
while(request.status !== 200){
//.. try catch next gateway
}
erc3668 is strict with that {data:"..."}, if a bad gateway wants resolver to handle that junk? it’s not breaking anything on erc3668, jus do recurcise ccip lookup directly from resolver like m-of-n multisig .
I’m not sure how far can we go without breaking ERC3668 specs. it’s cleverly designed to fit in between web2 & web3, so whole looklup process is trying to mimic http but we want more failsafe scenario for web3/decentralization…
– I’m re/thinking erc7700 draft with this erc3668 & gateways stuffs in mind… I’ll share that erc7700 redesign/suggestion here soon. we can’t change anything big in erc3668 after 4 years.
I see you’re using data uri to act like final failsafe gateway…
_shouldTryNext should also be triggered after signature/length check fails.
there’s one more thing to check from ERC3668.
This protocol can result in multiple lookups being requested by the same contract. Clients MUST implement a limit on the number of lookups they permit for a single contract call, and this limit SHOULD be at least 4.