Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(iroh-relay)!: use explicit key cache #3053

Merged
merged 18 commits into from
Dec 16, 2024
Merged

Conversation

rklaehn
Copy link
Contributor

@rklaehn rklaehn commented Dec 16, 2024

Description

This wires up an explicit key cache to replace the implicit one that was removed in #3051.

The default for a key cache is Disabled. A disabled key cache has a size of 1 pointer and otherwise zero performance overhead.

I have removed the Default instance for both KeyCache and DerpProtocol so you don't accidentally pass the default despite having a cache available.

We use the lru crate for the cache for now. Please comment if it should be something else.

Benchmarks have shown that conversion from a [u8;32] to a VerifyingKey is relatively cheap, so the purpose of the cache is solely to validate incoming public keys.

We add a Borrow instance to PublicKey so we can use it as a cache key.

Some performance measurements:

Benchmarking validate valid ed25519 key: 3.7674 µs
Benchmarking validate invalid ed25519 key: 3.6637 µs
Benchmarking validate valid iroh ed25519 key: 67.089 ns
Benchmarking validate invalid iroh ed25519 key: 64.004 ns

So just from validating incoming keys, without cache you would be limited to ~250 000 msgs/s per thread. At a message size of 1KiB that would be 250MB/s, which is not great.

With the cache deserialization can do 14 000 000 msgs/s, which means that this is no longer a bottleneck.

Breaking Changes

  • RelayConfig has new public field key_cache_capacity

Notes & open questions

  • Size of the cache
  • source_and_box has a PublicKey::try_from. Is that perf critical?

Change checklist

  • Self-review.
  • Documentation updates following the style guide, if relevant.
  • Tests if relevant.
  • All breaking changes documented.

@@ -96,6 +96,7 @@ url = { version = "2.5", features = ["serde"] }
webpki = { package = "rustls-webpki", version = "0.102" }
webpki-roots = "0.26"
data-encoding = "2.6.0"
lru = "0.12.5"
Copy link
Contributor

Choose a reason for hiding this comment

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

Purely a drive-by comment. But I've had another reason to add an LRU cache to iroh-relay very recently. So I think this dependency would make it here at some point.

Copy link

github-actions bot commented Dec 16, 2024

Documentation for this PR has been generated and is available at: https://n0-computer.github.io/iroh/pr/3053/docs/iroh/

Last updated: 2024-12-16T18:57:52Z

Copy link

github-actions bot commented Dec 16, 2024

Netsim report & logs for this PR have been generated and is available at: LOGS
This report will remain available for 3 days.

Last updated for commit: 4f19d1c

@dignifiedquire
Copy link
Contributor

I think a default of maybe 128 or so would be good, as it is very small still but will improve perf for most basic endpoint usages

128 for clients, this will help a bit but not have much mem use
1024 * 1024 for servers, this will consume 32 mb and work up to 1 mil connections
@rklaehn rklaehn force-pushed the feat-explicit-key-cache branch from 81228c6 to 015b28a Compare December 16, 2024 13:52
@rklaehn
Copy link
Contributor Author

rklaehn commented Dec 16, 2024

I think a default of maybe 128 or so would be good, as it is very small still but will improve perf for most basic endpoint usages

I made 128 the default for client and 1024 * 1024 the default for a http server. Presumably for the server 32 megabytes (or 56 megabytes if you add the 2 ptrs that LruEntry adds and the key) is no big deal, and it will work up to 1m connections.

Also add DerpCodec::test as a default for tests
@rklaehn rklaehn marked this pull request as ready for review December 16, 2024 15:20

impl DerpCodec {
#[cfg(test)]
pub fn test() -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

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

pub(crate)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does it matter, given this is cfg(test)?

@dignifiedquire
Copy link
Contributor

I am having a hard time finding the place this is configured for a non server endpoint, can you point me to that?

@rklaehn
Copy link
Contributor Author

rklaehn commented Dec 16, 2024

I am having a hard time finding the place this is configured for a non server endpoint, can you point me to that?

It is configurable using the ClientBuilder, with a default of 128 as you suggested.

  /// Create a new [`ClientBuilder`]
  pub fn new(url: impl Into<RelayUrl>) -> Self {
      ClientBuilder {
          is_preferred: false,
          address_family_selector: None,
          is_prober: false,
          server_public_key: None,
          url: url.into(),
          protocol: Protocol::Relay,
          #[cfg(any(test, feature = "test-utils"))]
          insecure_skip_cert_verify: false,
          proxy_url: None,
          key_cache_capacity: 128,
      }
  }
...


  /// Set the capacity of the cache for public keys.
  pub fn key_cache_capacity(mut self, capacity: usize) -> Self {
      self.key_cache_capacity = capacity;
      self
  }

Is that not the right place?

@dignifiedquire dignifiedquire changed the title feat: Explicit key cache feat!: use explicit key cache in iroh-relay Dec 16, 2024
@dignifiedquire dignifiedquire changed the title feat!: use explicit key cache in iroh-relay feat(iroh-relay)!: use explicit key cache Dec 16, 2024
@dignifiedquire
Copy link
Contributor

Is that not the right place?

It is, I was just being blind

@rklaehn rklaehn added this pull request to the merge queue Dec 16, 2024
Merged via the queue into main with commit d4f72fa Dec 16, 2024
27 of 28 checks passed
@rklaehn rklaehn deleted the feat-explicit-key-cache branch December 16, 2024 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants