Skip to content

feat: Store limited number of expiring elements#434

Merged
gregorydemay merged 24 commits intomainfrom
gdemay/XC-372-select-providers
Jul 1, 2025
Merged

feat: Store limited number of expiring elements#434
gregorydemay merged 24 commits intomainfrom
gdemay/XC-372-select-providers

Conversation

@gregorydemay
Copy link
Contributor

@gregorydemay gregorydemay commented Jun 18, 2025

Introduce a new data structure TimedSizedVec<T> to store a limited number of values, evicting older and expired entries. This is similar to TimedSizedCache except that it's time agnostic to ensure that it works in a canister (no Instant::now).

In a later PR, this data structure will be used to register timestamps of JSON-RPC ok responses from each supported provider. This is the second step towards dynamically ranking supported providers according to the number of their successful responses, which is done in the following 3 PRs:

  1. refactor: remove default/non-default providers #436
  2. feat: Store limited number of expiring elements #434 (this one)
  3. feat: Select supported providers based on successful responses #435

@gregorydemay gregorydemay force-pushed the gdemay/XC-372-select-providers branch from 0a25879 to 851d620 Compare June 19, 2025 15:42
@gregorydemay gregorydemay changed the base branch from main to gdemay/XC-372-supported-provider June 19, 2025 15:42
@gregorydemay gregorydemay changed the title feat: timed sized vec feat: Store limited number of expiring elements Jun 20, 2025
@gregorydemay gregorydemay marked this pull request as ready for review June 20, 2025 11:21
@gregorydemay gregorydemay requested a review from a team as a code owner June 20, 2025 11:21
@gregorydemay gregorydemay requested review from lpahlavi and ninegua June 20, 2025 11:21
Copy link
Contributor

@lpahlavi lpahlavi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @gregorydemay! Generally looks very cool! Mostly some small comments/suggestions from my side.

gregorydemay added a commit that referenced this pull request Jun 23, 2025
The notion of default/non-default providers was only useful when
Equality was chosen as consensus strategy and no providers was
explicitly specified, in which case the "default" providers would be
selected. This PR removes the notion of default/non-default providers by
replacing with an ordered list of providers for a given EVM chain,
corresponding to the supported providers. The previous notion of
"default" providers simply correspond to the first three providers in
that list.

This is similar to the refactoring done in dfinity/sol-rpc-canister#122.

Differentiating between supported and custom providers is the first step
towards dynamically ranking supported providers according to the number
of their successful responses, which is done in the following 3 PRs:

1. #436 (this one)
2. #434 
3. #435
Base automatically changed from gdemay/XC-372-supported-provider to main June 23, 2025 08:06
Copy link
Contributor Author

@gregorydemay gregorydemay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @lpahlavi for the review and the suggestions!

@lpahlavi
Copy link
Contributor

Thanks for the insightful explanations and changes @gregorydemay! There is still one minor comment but otherwise looks good!

@gregorydemay gregorydemay requested a review from lpahlavi June 24, 2025 09:55
Copy link
Contributor

@lpahlavi lpahlavi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for adding the doc @gregorydemay! Some small typos in the docs but otherwise looks great!

gregorydemay and others added 2 commits June 24, 2025 13:44
Co-authored-by: Louis Pahlavi <louis.pahlavi@gmail.com>
@gregorydemay gregorydemay requested a review from ninegua June 30, 2025 11:11
Copy link
Member

@ninegua ninegua left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! LGTM!

@gregorydemay
Copy link
Contributor Author

gregorydemay commented Jul 1, 2025

CI is currently blocked because of BlockPi, should be unblocked with #440.

@gregorydemay gregorydemay merged commit 9fafbb5 into main Jul 1, 2025
11 checks passed
@gregorydemay gregorydemay deleted the gdemay/XC-372-select-providers branch July 1, 2025 12:12
gregorydemay added a commit that referenced this pull request Jul 4, 2025
Dynamically select supported JSON-RPC providers according to the number
of successful JSON-RPC responses in the last 20 minutes, where providers
with a higher number will be prioritized over ones with lower numbers.

This is a heuristic that aims at selecting only currently functioning
providers. The idea is that since JSON-RPC errors cannot be relied upon,
as they are not specified by the Ethereum JSON-RPC API and so different
EVM clients or JSON-RPC providers do use different errors, we only count
instead the number of successful responses. Obviously, this is still not
bulletproof, since it won't help in case the provider returns a
successful JSON-RPC response with incorrect data.

Looking back at previous incidents with Ethereum JSON-RPC providers for
the EVM RPC canister or the ckETH/ckERC20 minter, we can see that having
this heuristic would have helped in most cases, excepted when a provider
returns successful responses with incorrect data (1 out of 4 incidents):

1. 😌 `Cloudflare` always return an error (proposal
[136701](https://dashboard.internetcomputer.org/proposal/136701))
2. 😌 `LlamaNodes` is down (proposal
[132474](https://dashboard.internetcomputer.org/proposal/132474))
3. 😌 `Ankr` dropped IPv6 connectivity
([132415](https://dashboard.internetcomputer.org/proposal/132415)
4. 😱`Cloudflare` returns successful responses with wrong results
(proposal
[128365](https://dashboard.internetcomputer.org/proposal/128365))

This is the last step towards dynamically ranking supported providers
according to the number of their successful responses, which is done in
the following 3 PRs:

1. #436
5. #434 
6. #435 (this one)
gregorydemay added a commit to dfinity/canhttp that referenced this pull request Jul 9, 2025
…ster#434)

Introduce a new data structure `TimedSizedVec<T>` to store a limited
number of values, evicting older and expired entries. This is similar to
[`TimedSizedCache`](https://docs.rs/cached/0.55.1/cached/stores/struct.TimedSizedCache.html)
except that it's time agnostic to ensure that it works in a canister (no
`Instant::now`).

In a later PR, this data structure will be used to register timestamps
of JSON-RPC ok responses from each supported provider. This is the
second step towards dynamically ranking supported providers according to
the number of their successful responses, which is done in the following
3 PRs:

1. dfinity/evm-rpc-canister#436 
2. dfinity/evm-rpc-canister#434 (this one)
3. dfinity/evm-rpc-canister#435

---------

Co-authored-by: Louis Pahlavi <louis.pahlavi@gmail.com>
gregorydemay added a commit to dfinity/canhttp that referenced this pull request Jul 9, 2025
…ty/evm-rpc-canister#435)

Dynamically select supported JSON-RPC providers according to the number
of successful JSON-RPC responses in the last 20 minutes, where providers
with a higher number will be prioritized over ones with lower numbers.

This is a heuristic that aims at selecting only currently functioning
providers. The idea is that since JSON-RPC errors cannot be relied upon,
as they are not specified by the Ethereum JSON-RPC API and so different
EVM clients or JSON-RPC providers do use different errors, we only count
instead the number of successful responses. Obviously, this is still not
bulletproof, since it won't help in case the provider returns a
successful JSON-RPC response with incorrect data.

Looking back at previous incidents with Ethereum JSON-RPC providers for
the EVM RPC canister or the ckETH/ckERC20 minter, we can see that having
this heuristic would have helped in most cases, excepted when a provider
returns successful responses with incorrect data (1 out of 4 incidents):

1. 😌 `Cloudflare` always return an error (proposal
[136701](https://dashboard.internetcomputer.org/proposal/136701))
2. 😌 `LlamaNodes` is down (proposal
[132474](https://dashboard.internetcomputer.org/proposal/132474))
3. 😌 `Ankr` dropped IPv6 connectivity
([132415](https://dashboard.internetcomputer.org/proposal/132415)
4. 😱`Cloudflare` returns successful responses with wrong results
(proposal
[128365](https://dashboard.internetcomputer.org/proposal/128365))

This is the last step towards dynamically ranking supported providers
according to the number of their successful responses, which is done in
the following 3 PRs:

1. dfinity/evm-rpc-canister#436
5. dfinity/evm-rpc-canister#434 
6. dfinity/evm-rpc-canister#435 (this one)
@github-actions github-actions bot mentioned this pull request Sep 24, 2025
This was referenced Oct 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants