From a5497fa01b4b5294f61b41e7ec62a989a2ec777a Mon Sep 17 00:00:00 2001 From: John Cairns Date: Fri, 9 Feb 2024 09:42:39 -0600 Subject: [PATCH 1/6] 43: introducing yamlfmt --- .github/workflows/coverage.yml | 2 +- .github/workflows/ghcr-image.yml | 22 ++++++---------------- .github/workflows/github-pages.yml | 4 ++-- .github/workflows/prod-ci-image.yml | 2 +- Dockerfile | 2 ++ 5 files changed, 12 insertions(+), 20 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 89d8ef3..26dfcb2 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -20,6 +20,6 @@ jobs: - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: - token: ${{ secrets.CODECOV_TOKEN }} + token: ${{ secrets.CODECOV_TOKEN }} files: lcov.info fail_ci_if_error: true diff --git a/.github/workflows/ghcr-image.yml b/.github/workflows/ghcr-image.yml index d95cc2d..2f4ba8c 100644 --- a/.github/workflows/ghcr-image.yml +++ b/.github/workflows/ghcr-image.yml @@ -1,41 +1,32 @@ name: Docker Image Build Push - on: push: tags: - "*" - concurrency: group: "docker-image" cancel-in-progress: true - jobs: build: runs-on: ubuntu-latest steps: - - - name: Checkout + - name: Checkout uses: actions/checkout@v3 - - - name: Set up QEMU + - name: Set up QEMU uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - - name: Generate repository name run: | echo "REPOSITORY_PATH=$( echo ${GITHUB_REPOSITORY} | tr '[:upper:]' '[:lower:]' )" >> ${GITHUB_ENV} echo "REPOSITORY_SHA=$( echo ${GITHUB_SHA} | cut -c 1-8 )" >> ${GITHUB_ENV} - - - name: Login to GitHub Container Registry + - name: Login to GitHub Container Registry uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - - - name: Build and Push + - name: Build and Push uses: docker/build-push-action@v3 with: context: . @@ -49,8 +40,7 @@ jobs: ghcr.io/${{ env.REPOSITORY_PATH }}:v${{ github.ref_name }} ghcr.io/${{ env.REPOSITORY_PATH }}:${{ env.REPOSITORY_SHA }} ghcr.io/${{ env.REPOSITORY_PATH }}:latest - - - name: GitHub Release + - name: GitHub Release uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index c245849..2e8eb49 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -34,10 +34,10 @@ jobs: profile: minimal override: true - name: Run tests + run: | + cargo test --tests tests -p lib-didethresolver --all-features env: CARGO_INCREMENTAL: 0 - run: | - cargo test --workspace --all-features --tests tests id: test - name: Invoke cargo doc run: | diff --git a/.github/workflows/prod-ci-image.yml b/.github/workflows/prod-ci-image.yml index e838484..d3b2d4a 100644 --- a/.github/workflows/prod-ci-image.yml +++ b/.github/workflows/prod-ci-image.yml @@ -21,7 +21,7 @@ jobs: uses: docker/build-push-action@v3 with: context: . - file: prod/Dockerfile + file: prod/Dockerfile platforms: linux/amd64 push: false build-args: | diff --git a/Dockerfile b/Dockerfile index f84123f..5030976 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,8 @@ COPY --from=ghcr.io/xmtp/foundry:latest /usr/local/bin/anvil /usr/local/bin/anvi COPY --chown=xmtp:xmtp . . +RUN yamlfmt -lint .github/workflows/*.yml + ENV CARGO_INCREMENTAL=${CARGO_INCREMENTAL:-1} RUN cargo check --all-features RUN cargo fmt --check --all From dd724ed9fcf18b464e57bcccfd44d8b6a7475dec Mon Sep 17 00:00:00 2001 From: John Cairns Date: Fri, 9 Feb 2024 14:09:15 -0600 Subject: [PATCH 2/6] CHANGELOG.md --- CHANGELOG.md | 6 +++++- resolver/Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32d3bdc..5897625 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ +# 0.1.1 (2024-02-09) + +* parsing improvements + # 0.1.0 (2024-01-24) * inital production support * light refactor * command line and environment variables -* url parser \ No newline at end of file +* url parser diff --git a/resolver/Cargo.toml b/resolver/Cargo.toml index b2e3338..2269e74 100644 --- a/resolver/Cargo.toml +++ b/resolver/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "resolver" -version = "0.1.0" +version = "0.1.1" authors = ["XMTP Labs "] description = "Standalone did:ethr Resolution JSON-RPC Gateway" homepage = "https://github.com/xmtp/didethresolver" From 05b7e66372fdac703bebc51d01afcbce0e460908 Mon Sep 17 00:00:00 2001 From: 37ng Date: Mon, 12 Feb 2024 18:19:04 -0800 Subject: [PATCH 3/6] chore: add --all-features to rust-analyzer in .vscode/settings.json (#45) --- .vscode/settings.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..90537fe --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "rust-analyzer.cargo.buildScripts.overrideCommand": null, + "rust-analyzer.cargo.features": "all" +} \ No newline at end of file From c7f745210ea8f2d234817be96fb69ea33be96369 Mon Sep 17 00:00:00 2001 From: John Cairns Date: Thu, 15 Feb 2024 13:48:41 -0600 Subject: [PATCH 4/6] 51: use address for resolveDid parameter --- Cargo.lock | 2 +- lib/src/resolver.rs | 33 +++++++++++++-------------------- lib/src/rpc/api.rs | 4 ++-- lib/src/rpc/methods.rs | 4 ++-- resolver/src/main.rs | 8 ++++---- 5 files changed, 22 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b99e0e..4f0d63b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3536,7 +3536,7 @@ dependencies = [ [[package]] name = "resolver" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "async-trait", diff --git a/lib/src/resolver.rs b/lib/src/resolver.rs index ea61702..7559ac6 100644 --- a/lib/src/resolver.rs +++ b/lib/src/resolver.rs @@ -39,27 +39,20 @@ impl Resolver { /// Resolve a did:ethr identifier pub async fn resolve_did( &self, - public_key: H160, + address: H160, version_id: Option, ) -> Result> { - let history = self.changelog(public_key).await?; - self.wrap_did_resolution(public_key, version_id, history) - .await + let history = self.changelog(address).await?; + self.wrap_did_resolution(address, version_id, history).await } async fn changelog( &self, - public_key: H160, + address: H160, ) -> Result, ResolverError> { - let mut previous_change: U64 = self - .registry - .changed(public_key) - .call() - .await? - .as_u64() - .into(); + let mut previous_change: U64 = self.registry.changed(address).call().await?.as_u64().into(); - log::trace!("Previous Change for {}: {:?}", public_key, previous_change); + log::trace!("Previous Change for {}: {:?}", address, previous_change); let mut history = Vec::new(); @@ -73,7 +66,7 @@ impl Resolver { .events() .from_block(previous_change) .to_block(previous_change) - .topic1(H256::from(public_key)) + .topic1(H256::from(address)) .query_with_meta() .await?; @@ -93,7 +86,7 @@ impl Resolver { fn dispatch_event( &self, doc: &mut EthrBuilder, - public_key: H160, + address: H160, event: DIDRegistryEvents, meta: LogMeta, ) { @@ -120,19 +113,19 @@ impl Resolver { if let Err(e) = res { log::error!( "Error while resolving for {} at event block={}, log index={}, incorrect format?: {}", - public_key, meta.block_number, meta.log_index, e, + address, meta.block_number, meta.log_index, e, ); }; } async fn wrap_did_resolution( &self, - public_key: H160, + address: H160, version_id: Option, history: Vec<(DIDRegistryEvents, LogMeta)>, ) -> Result> { let mut base_document = DidDocument::ethr_builder(); - base_document.account_address(&public_key)?; + base_document.account_address(&address)?; let current_block = self .signer() @@ -157,7 +150,7 @@ impl Resolver { if version_id.unwrap_or_default() > U64::zero() { if meta.block_number <= version_id.unwrap_or_default() { // 1. delegate events - Resolver::dispatch_event(self, &mut base_document, public_key, event, meta); + Resolver::dispatch_event(self, &mut base_document, address, event, meta); // 2. set latest version if current_version_id < block_number { current_version_id = block_number; @@ -169,7 +162,7 @@ impl Resolver { } } else { // 1. delegate events - Resolver::dispatch_event(self, &mut base_document, public_key, event, meta); + Resolver::dispatch_event(self, &mut base_document, address, event, meta); // 2. set latest version if current_version_id < block_number { current_version_id = block_number; diff --git a/lib/src/rpc/api.rs b/lib/src/rpc/api.rs index abc27ab..18578fa 100644 --- a/lib/src/rpc/api.rs +++ b/lib/src/rpc/api.rs @@ -11,7 +11,7 @@ pub trait DidRegistry { #[method(name = "resolveDid")] async fn resolve_did( &self, - public_key: String, + address: String, version_id: Option, ) -> Result; } @@ -23,7 +23,7 @@ pub trait DidRegistry { #[method(name = "resolveDid")] async fn resolve_did( &self, - public_key: String, + address: String, version_id: Option, ) -> Result; } diff --git a/lib/src/rpc/methods.rs b/lib/src/rpc/methods.rs index a47dca0..a9449c4 100644 --- a/lib/src/rpc/methods.rs +++ b/lib/src/rpc/methods.rs @@ -29,7 +29,7 @@ impl DidRegistryMethods { impl DidRegistryServer for DidRegistryMethods { async fn resolve_did( &self, - public_key: String, + address: String, version_id: Option, ) -> Result { log::debug!("did_resolveDid called"); @@ -40,7 +40,7 @@ impl DidRegistryServer for DidRegistryMethods { let resolution_result = self .resolver .resolve_did( - H160::from_str(&public_key).map_err(RpcError::from)?, + H160::from_str(&address).map_err(RpcError::from)?, parsed_version_id, ) .await?; diff --git a/resolver/src/main.rs b/resolver/src/main.rs index b269de5..c316f04 100644 --- a/resolver/src/main.rs +++ b/resolver/src/main.rs @@ -12,14 +12,14 @@ //! //! ### Request Format //! -//! The request should be a JSON object containing one field: `publicKey`. +//! The request should be a JSON object containing one field: `address`. //! -//! - `publicKey` (string, required): The Ethereum public key (starting with '0x'). +//! - `address` (string, required): The Ethereum address (starting with '0x'). //! //! Example Request: //! ```json //! { -//! "publicKey": "0x123abc..." +//! "address": "0x123abc..." //! } //! ``` //! @@ -61,7 +61,7 @@ //! Example Error Response: //! ```json //! { -//! "error": "Invalid public key format" +//! "error": "Invalid address format" //! } //! ``` //! From bb2c7d66028af5b5e3b04ede80bfafaffed6b921 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Thu, 15 Feb 2024 18:28:34 -0500 Subject: [PATCH 5/6] add timestamp to ethr builder (#48) * add timestamp to ethr builder * improve coverage * add `get_query_value` fn to did_url * clippy * use AsRef * timestamp -> block_timestamp, always return error * store block timestamp in seconds * fix bugs w.r.t byte conversions * remove constant use std::time::Duration * fmt --- Cargo.lock | 1 + lib/Cargo.toml | 1 + lib/src/error.rs | 7 ++ lib/src/resolver.rs | 62 ++++++++++-- lib/src/rpc/methods.rs | 7 +- lib/src/types.rs | 2 +- lib/src/types/did_url.rs | 19 ++++ lib/src/types/ethr.rs | 154 ++++++++++++++++++++++-------- lib/src/types/xmtp.rs | 27 +++++- lib/tests/integration_test.rs | 110 ++++++++------------- lib/tests/integration_util/mod.rs | 39 +++++++- resolver/src/argenv.rs | 16 ++-- 12 files changed, 310 insertions(+), 135 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f0d63b..2eef657 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2580,6 +2580,7 @@ dependencies = [ "peg", "percent-encoding", "rand 0.8.5", + "regex", "rustc-hex", "serde", "serde_json", diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 16af6c1..f3bd624 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -50,6 +50,7 @@ tokio-test = "0.4" futures = "0.3" ctor = "0.2.5" surf = "2.3" +regex = "1.10" [features] default = [] diff --git a/lib/src/error.rs b/lib/src/error.rs index f48af7a..02d2a50 100644 --- a/lib/src/error.rs +++ b/lib/src/error.rs @@ -3,6 +3,7 @@ use ethers::{ contract::ContractError, providers::{Middleware, ProviderError}, signers::WalletError, + types::U64, }; use jsonrpsee::types::ErrorObjectOwned; use thiserror::Error; @@ -16,6 +17,12 @@ pub enum ResolverError { ContractError(#[from] ContractError), #[error("{0}")] Middleware(String), + #[error("Block {0} containing Registry event not found")] + MissingBlock(U64), + #[error(transparent)] + Time(#[from] ethers::core::types::TimeError), + #[error("Block {0} timestamp out of range")] + TimestampOutOfRange(U64), } /// Errors originating from the parsing of a did url identifier, [`Did`](crate::types::DidUrl) diff --git a/lib/src/resolver.rs b/lib/src/resolver.rs index 7559ac6..aff92cf 100644 --- a/lib/src/resolver.rs +++ b/lib/src/resolver.rs @@ -28,6 +28,32 @@ impl From> for Resolver { } } +/// Extra context passed to the document builder from the [`Resolver`] +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct EventContext { + /// the timestamp in seconds in which the block from the document was built. + pub block_timestamp: u64, +} + +impl EventContext { + pub async fn new( + meta: &LogMeta, + signer: impl Middleware, + ) -> Result> { + let block = signer + .get_block(meta.block_number) + .await + .map_err(|e| ResolverError::Middleware(e.to_string()))?; + + let block_timestamp: u64 = block + .ok_or(ResolverError::MissingBlock(meta.block_number))? + .timestamp + .as_u64(); + + Ok(Self { block_timestamp }) + } +} + impl Resolver { /// Instantiate a new did:ethr resolver pub async fn new(middleware: M, registry: Address) -> Result> { @@ -83,21 +109,22 @@ impl Resolver { Ok(history) } - fn dispatch_event( + async fn dispatch_event( &self, doc: &mut EthrBuilder, address: H160, event: DIDRegistryEvents, meta: LogMeta, - ) { + ) -> Result<(), ResolverError> { + let context = EventContext::new(&meta, self.signer()).await?; let res = match event { DIDRegistryEvents::DiddelegateChangedFilter(delegate_changed) => { log::trace!("Delegate Changed {:?}", delegate_changed); - doc.delegate_event(delegate_changed) + doc.delegate_event(delegate_changed, &context) } DIDRegistryEvents::DidattributeChangedFilter(attribute_event) => { log::trace!("Attribute Changed {:?}", attribute_event); - doc.attribute_event(attribute_event) + doc.attribute_event(attribute_event, &context) } DIDRegistryEvents::DidownerChangedFilter(owner_changed) => { log::trace!("Owner Changed {:?}", owner_changed); @@ -116,6 +143,7 @@ impl Resolver { address, meta.block_number, meta.log_index, e, ); }; + Ok(()) } async fn wrap_did_resolution( @@ -150,7 +178,8 @@ impl Resolver { if version_id.unwrap_or_default() > U64::zero() { if meta.block_number <= version_id.unwrap_or_default() { // 1. delegate events - Resolver::dispatch_event(self, &mut base_document, address, event, meta); + Resolver::dispatch_event(self, &mut base_document, address, event, meta) + .await?; // 2. set latest version if current_version_id < block_number { current_version_id = block_number; @@ -162,7 +191,7 @@ impl Resolver { } } else { // 1. delegate events - Resolver::dispatch_event(self, &mut base_document, address, event, meta); + Resolver::dispatch_event(self, &mut base_document, address, event, meta).await?; // 2. set latest version if current_version_id < block_number { current_version_id = block_number; @@ -216,6 +245,8 @@ impl Resolver { #[cfg(test)] mod tests { + use ethers::{prelude::Provider, providers::MockProvider, types::TxHash}; + use super::*; #[test] @@ -225,4 +256,23 @@ mod tests { let resolver = Resolver::from(registry); assert_eq!(resolver.registry.address(), Address::zero()); } + + #[tokio::test] + async fn test_context_constructor() { + let (provider, mock) = Provider::mocked(); + mock.push(Block::::default()).unwrap(); + + let meta = LogMeta { + address: Address::zero(), + block_hash: H256::zero(), + block_number: U64::zero(), + log_index: U256::zero(), + transaction_hash: H256::zero(), + transaction_index: U64::zero(), + }; + let context = EventContext::new::>(&meta, Arc::new(provider)) + .await + .unwrap(); + assert_eq!(context.block_timestamp, 0); + } } diff --git a/lib/src/rpc/methods.rs b/lib/src/rpc/methods.rs index a9449c4..ea2a727 100644 --- a/lib/src/rpc/methods.rs +++ b/lib/src/rpc/methods.rs @@ -34,6 +34,8 @@ impl DidRegistryServer for DidRegistryMethods { ) -> Result { log::debug!("did_resolveDid called"); + log::trace!("Resolving for key {}", &address); + // parse the version_id let parsed_version_id = version_id.map(|str| U64::from(u64::from_str(&str).unwrap())); @@ -43,9 +45,10 @@ impl DidRegistryServer for DidRegistryMethods { H160::from_str(&address).map_err(RpcError::from)?, parsed_version_id, ) - .await?; + .await; + log::debug!("Resolution Result {:?}", resolution_result); - Ok(resolution_result) + Ok(resolution_result?) } } diff --git a/lib/src/types.rs b/lib/src/types.rs index 531b217..33561ac 100644 --- a/lib/src/types.rs +++ b/lib/src/types.rs @@ -272,7 +272,7 @@ impl From for [u8; 32] { // internal function to fill a [u8; 32] with bytes. // anything over 32 bytes will be cutoff. -fn string_to_bytes32>(s: S) -> [u8; 32] { +pub fn string_to_bytes32>(s: S) -> [u8; 32] { let s = s.as_ref(); let mut attr_bytes: [u8; 32] = [b' '; 32]; let length = std::cmp::min(s.as_bytes().len(), 32); diff --git a/lib/src/types/did_url.rs b/lib/src/types/did_url.rs index fdf50e6..e33179f 100644 --- a/lib/src/types/did_url.rs +++ b/lib/src/types/did_url.rs @@ -300,6 +300,15 @@ impl DidUrl { minion } + /// get a query value based on its `key` + pub fn get_query_value>(&self, key: S) -> Option { + self.query.as_ref().and_then(|q| { + q.iter() + .find(|(k, _)| k == key.as_ref()) + .map(|(_, v)| v.to_string()) + }) + } + /// Immutable copy constructor to add a query parameter to the DID URL. /// # Examples /// ```rust @@ -745,4 +754,14 @@ mod tests { assert_eq!(Network::Sepolia.to_string(), "sepolia"); assert_eq!(Network::Other(0x1a1).to_string(), "417"); } + + #[test] + fn test_get_query_value() { + let did_url = DidUrl::parse("did:ethr:mainnet:0x0000000000000000000000000000000000000000?meta=hi&username=&password=hunter2").unwrap(); + + assert_eq!(did_url.get_query_value("meta"), Some("hi".into())); + assert_eq!(did_url.get_query_value("username"), Some("".into())); + assert_eq!(did_url.get_query_value("password"), Some("hunter2".into())); + assert_eq!(did_url.get_query_value("does_not_exist"), None); + } } diff --git a/lib/src/types/ethr.rs b/lib/src/types/ethr.rs index 09634fd..c01b3e2 100644 --- a/lib/src/types/ethr.rs +++ b/lib/src/types/ethr.rs @@ -16,8 +16,11 @@ use super::{ }; use crate::{ error::EthrBuilderError, - resolver::did_registry::{ - DidattributeChangedFilter, DiddelegateChangedFilter, DidownerChangedFilter, + resolver::{ + did_registry::{ + DidattributeChangedFilter, DiddelegateChangedFilter, DidownerChangedFilter, + }, + EventContext, }, types::{self, NULL_ADDRESS}, }; @@ -78,7 +81,7 @@ pub struct EthrBuilder { /// Map of keys to their index in the document /// _*NOTE*_: this is used to ensure the order of keys is maintained, but indexes of the same /// number are expected. (EX: a delegate and service both with index 0) - pub(super) keys: HashMap, + pub(super) keys: HashMap, } impl Default for EthrBuilder { @@ -139,6 +142,7 @@ impl EthrBuilder { Ok(()) } + /// check whether the document has been deactivated pub fn is_deactivated(&mut self) -> bool { self.is_deactivated } @@ -152,6 +156,7 @@ impl EthrBuilder { pub fn delegate_event( &mut self, event: DiddelegateChangedFilter, + context: &EventContext, ) -> Result<(), EthrBuilderError> { let delegate_type = String::from_utf8_lossy(&event.delegate_type); let key_purpose = types::parse_delegate(&delegate_type)?; @@ -167,7 +172,8 @@ impl EthrBuilder { return Ok(()); } - self.keys.insert(key, self.delegate_count); + self.keys + .insert(key, (self.delegate_count, context.clone())); self.delegate_count += 1; Ok(()) @@ -180,6 +186,7 @@ impl EthrBuilder { pub fn attribute_event( &mut self, event: DidattributeChangedFilter, + context: &EventContext, ) -> Result<(), EthrBuilderError> { let name = event.name_string_lossy(); let attribute = types::parse_attribute(&name).unwrap_or(Attribute::Other(name.to_string())); @@ -208,19 +215,20 @@ impl EthrBuilder { match attribute { Attribute::PublicKey(_) => { if event.is_valid(&self.now) { - self.keys.insert(key, self.delegate_count); + self.keys + .insert(key, (self.delegate_count, context.clone())); } self.delegate_count += 1; } Attribute::Service(_) => { if event.is_valid(&self.now) { - self.keys.insert(key, self.service_count); + self.keys.insert(key, (self.service_count, context.clone())); } self.service_count += 1; } Attribute::Xmtp(_) => { if event.is_valid(&self.now) { - self.keys.insert(key, self.xmtp_count); + self.keys.insert(key, (self.xmtp_count, context.clone())); } self.xmtp_count += 1; } @@ -313,8 +321,13 @@ impl EthrBuilder { value: V, encoding: KeyEncoding, ) -> Result, EthrBuilderError> { - let value = hex::decode(value.as_ref())?; - Ok(match encoding { + log::debug!( + "decoding attribute value {:?} with encoding: {}", + value.as_ref(), + encoding + ); + + let enc = match encoding { KeyEncoding::Hex => Some(VerificationMethodProperties::PublicKeyHex { public_key_hex: hex::encode(value), }), @@ -324,7 +337,9 @@ impl EthrBuilder { KeyEncoding::Base58 => Some(VerificationMethodProperties::PublicKeyBase58 { public_key_base58: bs58::encode(value).into_string(), }), - }) + }; + log::debug!("Encoded {:?}", enc); + Ok(enc) } /// Adds a delegate to the document @@ -413,10 +428,13 @@ impl EthrBuilder { } fn build_keys(&mut self) -> Result<(), EthrBuilderError> { - let mut keys = self.keys.drain().collect::>(); - keys.sort_by_key(|k| k.1); + let mut keys = self + .keys + .drain() + .collect::>(); + keys.sort_by_key(|(_, (index, _))| *index); - for (key, index) in keys { + for (key, (index, context)) in keys { match key { Key::Attribute { value, attribute, .. @@ -427,7 +445,7 @@ impl EthrBuilder { Attribute::Service(service) => { self.service(index, value, service)?; } - Attribute::Xmtp(xmtp) => self.xmtp_key(index, value, xmtp)?, + Attribute::Xmtp(xmtp) => self.xmtp_key(index, value, xmtp, &context)?, Attribute::Other(_) => (), }, Key::Delegate { delegate, purpose } => { @@ -445,6 +463,12 @@ pub(crate) mod tests { use super::*; use crate::types::test::address; + impl EventContext { + pub fn mock(block_timestamp: u64) -> Self { + Self { block_timestamp } + } + } + //TODO: dids are case-sensitive w.r.t their addresses. One did should equal the other, no //matter the case of the address (other than blockchain_account_id b/c of EIP55) pub fn base_attr_changed( @@ -466,14 +490,19 @@ pub(crate) mod tests { let event = DidattributeChangedFilter { name: *b"did/pub/Secp256k1/veriKey/hex ", - value: b"02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), + value: hex::decode( + "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71", + ) + .unwrap() + .into(), ..base_attr_changed(identity, None) }; let mut builder = EthrBuilder::default(); builder.account_address(&identity).unwrap(); builder.now(U256::zero()); - builder.attribute_event(event).unwrap(); + let context = EventContext::mock(0); + builder.attribute_event(event, &context).unwrap(); let doc = builder.build().unwrap(); assert_eq!( doc.verification_method[1], @@ -496,14 +525,18 @@ pub(crate) mod tests { let identity = address("0x7e575682a8e450e33eb0493f9972821ae333cd7f"); let event = DidattributeChangedFilter { name: *b"did/pub/Ed25519/veriKey/base58 ", - value: b"b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), + value: hex::decode("b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71") + .unwrap() + .into(), ..base_attr_changed(identity, None) }; let mut builder = EthrBuilder::default(); builder.account_address(&identity).unwrap(); builder.now(U256::zero()); - builder.attribute_event(event).unwrap(); + builder + .attribute_event(event, &EventContext::mock(0)) + .unwrap(); let doc = builder.build().unwrap(); assert_eq!( doc.verification_method[1], @@ -525,14 +558,16 @@ pub(crate) mod tests { let identity = address("0x7e575682a8e450e33eb0493f9972821ae333cd7f"); let event = DidattributeChangedFilter { name: *b"did/pub/X25519/enc/base64 ", - value: b"302a300506032b656e032100118557777ffb078774371a52b00fed75561dcf975e61c47553e664a617661052".into(), + value: hex::decode("302a300506032b656e032100118557777ffb078774371a52b00fed75561dcf975e61c47553e664a617661052").unwrap().into(), ..base_attr_changed(identity, None) }; let mut builder = EthrBuilder::default(); builder.account_address(&identity).unwrap(); builder.now(U256::zero()); - builder.attribute_event(event).unwrap(); + builder + .attribute_event(event, &EventContext::mock(0)) + .unwrap(); let doc = builder.build().unwrap(); assert_eq!( doc.verification_method[1], @@ -562,7 +597,9 @@ pub(crate) mod tests { let mut builder = EthrBuilder::default(); builder.account_address(&identity).unwrap(); builder.now(U256::zero()); - builder.attribute_event(event).unwrap(); + builder + .attribute_event(event, &EventContext::mock(0)) + .unwrap(); let doc = builder.build().unwrap(); assert_eq!( doc.service, @@ -582,17 +619,17 @@ pub(crate) mod tests { let events = vec![ DidattributeChangedFilter { name: *b"did/pub/Secp256k1/veriKey/hex ", - value: b"02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), + value: hex::decode("02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71").unwrap().into(), ..base_attr_changed(identity, None) }, DidattributeChangedFilter { name: *b"did/pub/Secp256k1/sigAuth/base58", - value: b"b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), + value: hex::decode("b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71").unwrap().into(), ..base_attr_changed(identity, None) }, DidattributeChangedFilter { name: *b"did/pub/X25519/enc/base64 ", - value: b"302a300506032b656e032100118557777ffb078774371a52b00fed75561dcf975e61c47553e664a617661052".into(), + value: hex::decode("302a300506032b656e032100118557777ffb078774371a52b00fed75561dcf975e61c47553e664a617661052").unwrap().into(), ..base_attr_changed(identity, None) }, DidattributeChangedFilter { @@ -612,7 +649,9 @@ pub(crate) mod tests { builder.now(U256::zero()); for event in events { - builder.attribute_event(event).unwrap(); + builder + .attribute_event(event, &EventContext::mock(0)) + .unwrap(); } let doc = builder.build().unwrap(); @@ -638,17 +677,17 @@ pub(crate) mod tests { let events = vec![ DidattributeChangedFilter { name: *b"did/pub/Secp256k1/veriKey/hex ", - value: b"02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), + value: hex::decode("02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71").unwrap().into(), ..base_attr_changed(identity, None) }, DidattributeChangedFilter { name: *b"did/pub/Secp256k1/sigAuth/base58", - value: b"b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), + value: hex::decode("b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71").unwrap().into(), ..base_attr_changed(identity, Some(10)) }, DidattributeChangedFilter { name: *b"did/pub/X25519/enc/base64 ", - value: b"302a300506032b656e032100118557777ffb078774371a52b00fed75561dcf975e61c47553e664a617661052".into(), + value: hex::decode("302a300506032b656e032100118557777ffb078774371a52b00fed75561dcf975e61c47553e664a617661052").unwrap().into(), ..base_attr_changed(identity, None) }, DidattributeChangedFilter { @@ -667,7 +706,9 @@ pub(crate) mod tests { builder.account_address(&identity).unwrap(); builder.now(U256::from(100)); for event in events { - builder.attribute_event(event).unwrap(); + builder + .attribute_event(event, &EventContext::mock(0)) + .unwrap(); } let doc = builder.build().unwrap(); @@ -726,7 +767,9 @@ pub(crate) mod tests { builder.account_address(&identity).unwrap(); builder.now(U256::zero()); for event in events { - builder.delegate_event(event).unwrap(); + builder + .delegate_event(event, &EventContext::mock(0)) + .unwrap(); } let doc = builder.build().unwrap(); @@ -802,7 +845,9 @@ pub(crate) mod tests { builder.account_address(&identity).unwrap(); builder.now(U256::zero()); for event in &events { - builder.delegate_event(event.clone()).unwrap(); + builder + .delegate_event(event.clone(), &EventContext::mock(0)) + .unwrap(); } // both events are valid @@ -812,7 +857,9 @@ pub(crate) mod tests { builder.account_address(&identity).unwrap(); builder.now(U256::from(75)); for event in &events { - builder.delegate_event(event.clone()).unwrap(); + builder + .delegate_event(event.clone(), &EventContext::mock(0)) + .unwrap(); } // only one event is valid assert_eq!(builder.keys.len(), 1); @@ -821,7 +868,9 @@ pub(crate) mod tests { builder.account_address(&identity).unwrap(); builder.now(U256::from(125)); for event in &events { - builder.delegate_event(event.clone()).unwrap(); + builder + .delegate_event(event.clone(), &EventContext::mock(0)) + .unwrap(); } // no events valid @@ -834,12 +883,20 @@ pub(crate) mod tests { let attributes = vec![ DidattributeChangedFilter { name: *b"did/pub/Secp256k1/veriKey/hex ", - value: b"02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), + value: hex::decode( + "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71", + ) + .unwrap() + .into(), ..base_attr_changed(identity, None) }, DidattributeChangedFilter { name: *b"did/pub/Secp256k1/sigAuth/base58", - value: b"b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), + value: hex::decode( + "b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71", + ) + .unwrap() + .into(), ..base_attr_changed(identity, None) }, ]; @@ -864,10 +921,19 @@ pub(crate) mod tests { builder.account_address(&identity).unwrap(); builder.now(U256::zero()); - builder.attribute_event(attributes[0].clone()).unwrap(); - builder.delegate_event(delegates[0].clone()).unwrap(); - builder.attribute_event(attributes[1].clone()).unwrap(); - builder.delegate_event(delegates[1].clone()).unwrap(); + let context = EventContext::mock(0); + builder + .attribute_event(attributes[0].clone(), &context) + .unwrap(); + builder + .delegate_event(delegates[0].clone(), &context) + .unwrap(); + builder + .attribute_event(attributes[1].clone(), &context) + .unwrap(); + builder + .delegate_event(delegates[1].clone(), &context) + .unwrap(); let doc = builder.build().unwrap(); @@ -932,7 +998,11 @@ pub(crate) mod tests { let identity = address("0x7e575682a8e450e33eb0493f9972821ae333cd7f"); let event = DidattributeChangedFilter { name: *b"test/random/attribute99999999 ", - value: b"02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), + value: hex::decode( + "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71", + ) + .unwrap() + .into(), ..base_attr_changed(identity, None) }; @@ -940,7 +1010,9 @@ pub(crate) mod tests { builder.account_address(&identity).unwrap(); builder.now(U256::zero()); - builder.attribute_event(event).unwrap(); + builder + .attribute_event(event, &EventContext::mock(0)) + .unwrap(); let doc = builder.build().unwrap(); diff --git a/lib/src/types/xmtp.rs b/lib/src/types/xmtp.rs index fae6399..5fd2f8e 100644 --- a/lib/src/types/xmtp.rs +++ b/lib/src/types/xmtp.rs @@ -17,8 +17,9 @@ use super::{string_to_bytes32, Attribute, EthrBuilder, KeyEncoding, KeyType, VerificationMethod}; use crate::error::EthrBuilderError; -use std::fmt; +use std::{fmt, time::Duration}; +use crate::resolver::EventContext; use serde::{Deserialize, Serialize}; /// The XMTP Attribute Type @@ -83,12 +84,18 @@ impl EthrBuilder { index: usize, value: V, key: XmtpAttribute, + context: &EventContext, ) -> Result<(), EthrBuilderError> { log::debug!("index: {}", index); + + let timestamp_ns = Duration::from_secs(context.block_timestamp).as_nanos(); + let did_url = self .id .with_fragment(Some(&format!("xmtp-{}", index))) - .with_query("meta", Some(&key.purpose.to_string())); + .with_query("meta", Some(&key.purpose.to_string())) + .with_query("timestamp", Some(×tamp_ns.to_string())); + let method = VerificationMethod { id: did_url, controller: self.id.clone(), @@ -131,7 +138,9 @@ mod test { builder.now(U256::zero()); for attr in attributes { - builder.attribute_event(attr).unwrap() + builder + .attribute_event(attr, &EventContext::mock(10_000)) + .unwrap() } let doc = builder.build().unwrap(); @@ -139,7 +148,13 @@ mod test { assert_eq!(doc.verification_method[1].id.fragment().unwrap(), "xmtp-0"); assert_eq!( doc.verification_method[1].id.query().unwrap(), - vec![("meta".to_string(), "installation".to_string())] + vec![ + ("meta".to_string(), "installation".to_string()), + ( + "timestamp".to_string(), + Duration::from_secs(10000).as_nanos().to_string() + ) + ] ); assert_eq!(doc.verification_method.len(), 2); @@ -160,7 +175,9 @@ mod test { builder.now(U256::from(100)); for attr in attributes { - builder.attribute_event(attr).unwrap() + builder + .attribute_event(attr, &EventContext::mock(10_000)) + .unwrap() } assert_eq!(builder.xmtp_count, 1); diff --git a/lib/tests/integration_test.rs b/lib/tests/integration_test.rs index 62c0586..89cd97f 100644 --- a/lib/tests/integration_test.rs +++ b/lib/tests/integration_test.rs @@ -7,7 +7,8 @@ use ethers::{ signers::{LocalWallet, Signer as _}, types::{Address, U256}, }; -use integration_util::{validate_document, with_client}; +use integration_util::{revoke_attribute, set_attribute, validate_document, with_client}; +use regex::Regex; #[cfg(test)] mod it { @@ -24,21 +25,8 @@ mod it { pub async fn test_attributes() -> Result<()> { with_client(None, |client, registry, signer, _| async move { let me = signer.address(); - let did = registry.set_attribute( - me, - *b"did/pub/Secp256k1/veriKey/hex ", - b"02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), - U256::from(604_800), - ); - did.send().await?.await?; - - let did = registry.set_attribute( - me, - *b"did/pub/Ed25519/veriKey/base64 ", - b"302a300506032b656e032100118557777ffb078774371a52b00fed75561dcf975e61c47553e664a617661052".into(), - U256::from(604_800), - ); - did.send().await?.await?; + set_attribute(®istry, me, "did/pub/Secp256k1/veriKey/hex", "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71", 604_800).await?; + set_attribute(®istry, me, "did/pub/Ed25519/veriKey/base64", "302a300506032b656e032100118557777ffb078774371a52b00fed75561dcf975e61c47553e664a617661052", 604_800).await?; let resolution_response = client.resolve_did(hex::encode(me), None).await?; validate_document(&resolution_response.document).await; @@ -57,8 +45,7 @@ mod it { assert_eq!( resolution_response.document.verification_method[1].verification_properties, Some(VerificationMethodProperties::PublicKeyHex { - public_key_hex: - "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".to_string() + public_key_hex: "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".to_string() }) ); @@ -81,9 +68,8 @@ mod it { .to_string() }) ); - assert_eq!( - resolution_response.metadata.clone().deactivated, - false + assert!( + !resolution_response.metadata.clone().deactivated ); assert_eq!( resolution_response.metadata.clone().version_id, @@ -103,28 +89,14 @@ mod it { pub async fn test_attributes_versions() -> Result<()> { with_client(None, |client, registry, signer, _| async move { let me = signer.address(); - let did = registry.set_attribute( - me, - *b"did/pub/Secp256k1/veriKey/hex ", - b"02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), - U256::from(604_800), - ); - did.send().await?.await?; - - let did = registry.set_attribute( - me, - *b"did/pub/Ed25519/veriKey/base64 ", - b"302a300506032b656e032100118557777ffb078774371a52b00fed75561dcf975e61c47553e664a617661052".into(), - U256::from(604_800), - ); - did.send().await?.await?; + set_attribute(®istry, me,"did/pub/Secp256k1/veriKey/hex", "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71", 604_800).await?; + set_attribute(®istry, me, "did/pub/Ed25519/veriKey/base64", "302a300506032b656e032100118557777ffb078774371a52b00fed75561dcf975e61c47553e664a617661052", 604_800).await?; let resolution_response = client.resolve_did(hex::encode(me), Some::("2".to_string())).await?; validate_document(&resolution_response.document).await; - assert_eq!( - resolution_response.metadata.clone().deactivated, - false + assert!( + !resolution_response.metadata.clone().deactivated ); assert_eq!( resolution_response.metadata.clone().version_id, @@ -226,20 +198,22 @@ mod it { pub async fn test_attribute_revocation() -> Result<()> { with_client(None, |client, registry, signer, _| async move { let me = signer.address(); - let did = registry.set_attribute( - me, - *b"did/pub/Secp256k1/veriKey/hex ", - b"02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), - U256::from(604_800), - ); - did.send().await?.await?; - let did = registry.revoke_attribute( + set_attribute( + ®istry, me, - *b"did/pub/Secp256k1/veriKey/hex ", - b"02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), - ); - did.send().await?.await?; + "did/pub/Secp256k1/veriKey/hex", + "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71", + 604_800, + ) + .await?; + revoke_attribute( + ®istry, + me, + "did/pub/Secp256k1/veriKey/hex", + "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71", + ) + .await?; let document = client.resolve_did(hex::encode(me), None).await?.document; validate_document(&document).await; @@ -323,31 +297,31 @@ mod it { pub async fn test_xmtp_revocation() -> Result<()> { with_client(None, |client, registry, signer, _| async move { let me = signer.address(); - let attribute_name = *b"xmtp/installation/hex "; - let did = registry.set_attribute( + let attribute_name = "xmtp/installation/hex "; + set_attribute( + ®istry, me, attribute_name, - b"02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), - U256::from(604_800), - ); - did.send().await?.await?; + "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71", + 604_800, + ) + .await?; let document = client.resolve_did(hex::encode(me), None).await?.document; - assert_eq!( - document.verification_method[1].id, - DidUrl::parse(format!( - "did:ethr:0x{}?meta=installation#xmtp-0", - hex::encode(me) - )) - .unwrap() + let regexr = format!( + r"did:ethr:mainnet:0x{}\?meta=installation×tamp=\d+#xmtp-0", + hex::encode(me) ); + let test = Regex::new(®exr).unwrap(); + assert!(test.is_match(&document.verification_method[1].id.to_string())); - let did = registry.revoke_attribute( + revoke_attribute( + ®istry, me, attribute_name, - b"02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), - ); - did.send().await?.await?; + "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71", + ) + .await?; let document = client.resolve_did(hex::encode(me), None).await?.document; validate_document(&document).await; diff --git a/lib/tests/integration_util/mod.rs b/lib/tests/integration_util/mod.rs index 64a9c31..92b8e59 100644 --- a/lib/tests/integration_util/mod.rs +++ b/lib/tests/integration_util/mod.rs @@ -1,5 +1,7 @@ //! Shared setup code for integration tests use ethers::providers::Middleware; +use ethers::types::{Bytes, H160}; +use hex::FromHex; use std::sync::{Arc, Once}; use std::{future::Future, time::Duration}; use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Registry}; @@ -11,7 +13,7 @@ use ethers::{ middleware::SignerMiddleware, providers::{Provider, Ws}, signers::{LocalWallet, Signer as _}, - types::Address, + types::{Address, U256}, }; use futures::future::FutureExt; use jsonrpsee::{ @@ -19,8 +21,8 @@ use jsonrpsee::{ ws_client::{WsClient, WsClientBuilder}, }; use lib_didethresolver::{ - did_registry::DIDRegistry, rpc::DidRegistryMethods, types::DidDocument, DidRegistryServer, - Resolver, + did_registry::DIDRegistry, rpc::DidRegistryMethods, types::string_to_bytes32, + types::DidDocument, DidRegistryServer, Resolver, }; use serde::{Deserialize, Serialize}; use tokio::time::timeout as timeout_tokio; @@ -109,7 +111,7 @@ where async fn deploy_to_anvil(anvil: &AnvilInstance) -> Address { let wallet: LocalWallet = anvil.keys()[0].clone().into(); - let client = client(&anvil, wallet).await; + let client = client(anvil, wallet).await; let registry = DIDRegistry::deploy(client.clone(), ()) .unwrap() @@ -164,3 +166,32 @@ pub async fn validate_document(document: &DidDocument) { } assert!(response.valid); } + +pub async fn set_attribute( + registry: &DIDRegistry, + did: H160, + key: &str, + value: &str, + validity: u64, +) -> Result<()> { + let attribute = registry.set_attribute( + did, + string_to_bytes32(key), + Bytes::from_hex(value)?, + U256::from(validity), + ); + + attribute.send().await?.await?; + Ok(()) +} + +pub async fn revoke_attribute( + registry: &DIDRegistry, + did: H160, + key: &str, + value: &str, +) -> Result<()> { + let attribute = registry.revoke_attribute(did, string_to_bytes32(key), Bytes::from_hex(value)?); + attribute.send().await?.await?; + Ok(()) +} diff --git a/resolver/src/argenv.rs b/resolver/src/argenv.rs index f812bb7..59f4e42 100644 --- a/resolver/src/argenv.rs +++ b/resolver/src/argenv.rs @@ -53,12 +53,12 @@ mod tests { #[test] fn test_parse_host_arg() -> anyhow::Result<()> { let env = setup(); - let args = Args::parse_from(&["didethresolver", "-s", "host.xyz"]); + let args = Args::parse_from(["didethresolver", "-s", "host.xyz"]); assert_eq!(args.host, "host.xyz"); assert_eq!(args.port, DEFAULT_PORT); assert_eq!(args.rpc_url, DEFAULT_RPC_URL); assert_eq!(args.did_registry, DID_ETH_REGISTRY); - let args2 = Args::parse_from(&["didethresolver", "--host", "h.xyz"]); + let args2 = Args::parse_from(["didethresolver", "--host", "h.xyz"]); assert_eq!(args2.host, "h.xyz"); putback(env) } @@ -66,12 +66,12 @@ mod tests { #[test] fn test_parse_port_arg() -> anyhow::Result<()> { let env = setup(); - let args = Args::parse_from(&["didethresolver", "-p", "1234"]); + let args = Args::parse_from(["didethresolver", "-p", "1234"]); assert_eq!(args.host, DEFAULT_HOST); assert_eq!(args.port, 1234); assert_eq!(args.rpc_url, DEFAULT_RPC_URL); assert_eq!(args.did_registry, DID_ETH_REGISTRY); - let args2 = Args::parse_from(&["didethresolver", "--port", "4321"]); + let args2 = Args::parse_from(["didethresolver", "--port", "4321"]); assert_eq!(args2.host, DEFAULT_HOST); assert_eq!(args2.port, 4321); putback(env) @@ -80,12 +80,12 @@ mod tests { #[test] fn test_parse_rpc_url_arg() -> anyhow::Result<()> { let env = setup(); - let args = Args::parse_from(&["didethresolver", "-r", "http://rpc.xyz"]); + let args = Args::parse_from(["didethresolver", "-r", "http://rpc.xyz"]); assert_eq!(args.host, DEFAULT_HOST); assert_eq!(args.port, DEFAULT_PORT); assert_eq!(args.rpc_url, "http://rpc.xyz"); assert_eq!(args.did_registry, DID_ETH_REGISTRY); - let args2 = Args::parse_from(&["didethresolver", "--rpc-url", "http://rpc2.xyz"]); + let args2 = Args::parse_from(["didethresolver", "--rpc-url", "http://rpc2.xyz"]); assert_eq!(args2.host, DEFAULT_HOST); assert_eq!(args2.port, DEFAULT_PORT); assert_eq!(args2.rpc_url, "http://rpc2.xyz"); @@ -95,12 +95,12 @@ mod tests { #[test] fn test_parse_did_registry_arg() -> anyhow::Result<()> { let env = setup(); - let args = Args::parse_from(&["didethresolver", "-d", "0x1234567890"]); + let args = Args::parse_from(["didethresolver", "-d", "0x1234567890"]); assert_eq!(args.host, DEFAULT_HOST); assert_eq!(args.port, DEFAULT_PORT); assert_eq!(args.rpc_url, DEFAULT_RPC_URL); assert_eq!(args.did_registry, "0x1234567890"); - let args2 = Args::parse_from(&[ + let args2 = Args::parse_from([ "didethresolver", "--did-registry", "0x0987654321", From fb93d06f48e90c8e0d0a870cd5d41a7230fe3ecb Mon Sep 17 00:00:00 2001 From: John Cairns Date: Wed, 14 Feb 2024 09:28:10 -0600 Subject: [PATCH 6/6] 47: add support for handling name bytes if they have nul - fixes documentation - add documentation test to ci --- .github/workflows/github-pages.yml | 12 +- .vscode/launch.json | 4 +- Cargo.lock | 513 +++++++++++++++-------------- Dockerfile | 2 + lib/src/resolver/did_registry.rs | 6 + lib/src/types/did_parser.rs | 30 +- lib/src/types/did_url.rs | 6 +- lib/src/types/ethr.rs | 91 ++++- resolver/src/main.rs | 7 +- 9 files changed, 399 insertions(+), 272 deletions(-) diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index 2e8eb49..69b12d5 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -34,18 +34,22 @@ jobs: profile: minimal override: true - name: Run tests - run: | - cargo test --tests tests -p lib-didethresolver --all-features env: CARGO_INCREMENTAL: 0 + run: | + cargo test -p lib-didethresolver --all-features --tests tests id: test - name: Invoke cargo doc run: | rm -rf ./_site - cargo doc --workspace --no-deps + RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps rm -f target/doc/.lock cp -r target/doc _site - echo "" > _site/index.html + if [ ! -d _site/lib_didethresolver ]; then + echo "Error: _site/lib_didethresolver does not exist" + exit 1 + fi + echo "" > _site/index.html echo "Taking care of pedantic permissions requirements required by GitHub Pages" chmod -R +rX _site id: docgen diff --git a/.vscode/launch.json b/.vscode/launch.json index f4719eb..4bcaa7e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -29,7 +29,6 @@ "cargo": { "args": [ "build", - "--bin=resolver", "--package=resolver" ], "filter": { @@ -38,6 +37,9 @@ } }, "args": [], + "env": { + "RPC_URL": "wss://eth-sepolia.g.alchemy.com/v2/", + }, "cwd": "${workspaceFolder}" }, ] diff --git a/Cargo.lock b/Cargo.lock index 2eef657..bf1174e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,9 +49,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher 0.4.4", @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" @@ -198,13 +198,13 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" +checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" dependencies = [ "concurrent-queue", - "event-listener 4.0.3", - "event-listener-strategy", + "event-listener 5.0.0", + "event-listener-strategy 0.5.0", "futures-core", "pin-project-lite", ] @@ -229,9 +229,9 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel 2.1.1", + "async-channel 2.2.0", "async-executor", - "async-io 2.3.0", + "async-io 2.3.1", "async-lock 3.3.0", "blocking", "futures-lite 2.2.0", @@ -260,9 +260,9 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb41eb19024a91746eba0773aa5e16036045bbf45733766661099e182ea6a744" +checksum = "8f97ab0c5b00a7cdbe5a371b9a782ee7be1316095885c8a4ea1daf490eb0ef65" dependencies = [ "async-lock 3.3.0", "cfg-if", @@ -270,8 +270,8 @@ dependencies = [ "futures-io", "futures-lite 2.2.0", "parking", - "polling 3.3.2", - "rustix 0.38.30", + "polling 3.4.0", + "rustix 0.38.31", "slab", "tracing", "windows-sys 0.52.0", @@ -293,7 +293,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" dependencies = [ "event-listener 4.0.3", - "event-listener-strategy", + "event-listener-strategy 0.4.0", "pin-project-lite", ] @@ -342,7 +342,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -359,7 +359,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -381,14 +381,13 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "823b8bb275161044e2ac7a25879cb3e2480cb403e3943022c7c769c599b756aa" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.49", ] [[package]] @@ -480,9 +479,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bitvec" @@ -520,7 +519,7 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ - "async-channel 2.1.1", + "async-channel 2.2.0", "async-lock 3.3.0", "async-task", "fastrand 2.0.1", @@ -542,9 +541,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f" [[package]] name = "byte-slice-cast" @@ -605,9 +604,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" dependencies = [ "serde", ] @@ -644,16 +643,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] @@ -677,9 +676,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.18" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" dependencies = [ "clap_builder", "clap_derive", @@ -687,9 +686,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" dependencies = [ "anstream", "anstyle", @@ -699,21 +698,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "coins-bip32" @@ -784,9 +783,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +checksum = "18d59688ad0945eaf6b84cb44fedbe93484c81b48970e98f09db8a22832d7961" dependencies = [ "cfg-if", "cpufeatures", @@ -863,9 +862,9 @@ checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -940,7 +939,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30d2b3721e861707777e3195b0158f950ae6dc4a27e4d02ff9f67e3eb3de199e" dependencies = [ "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -963,24 +962,24 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.44" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +checksum = "1e2161dd6eba090ff1594084e95fd67aeccf04382ffea77999ea94ed42ec67b6" dependencies = [ "curl-sys", "libc", "openssl-probe", "openssl-sys", "schannel", - "socket2 0.4.10", - "winapi", + "socket2 0.5.5", + "windows-sys 0.52.0", ] [[package]] name = "curl-sys" -version = "0.4.70+curl-8.5.0" +version = "0.4.72+curl-8.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0333d8849afe78a4c8102a429a446bfdd055832af071945520e835ae2d841e" +checksum = "29cbdc8314c447d11e8fd156dcdd031d9e02a7a976163e396b548c03153bc9ea" dependencies = [ "cc", "libc", @@ -989,7 +988,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1131,9 +1130,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "elliptic-curve" @@ -1212,7 +1211,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" dependencies = [ - "aes 0.8.3", + "aes 0.8.4", "ctr 0.9.2", "digest 0.10.7", "hex", @@ -1278,9 +1277,9 @@ dependencies = [ [[package]] name = "ethers" -version = "2.0.11" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5344eea9b20effb5efeaad29418215c4d27017639fd1f908260f59cbbd226e" +checksum = "6c7cd562832e2ff584fa844cd2f6e5d4f35bbe11b28c7c9b8df957b2e1d0c701" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -1294,9 +1293,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bf35eb7d2e2092ad41f584951e08ec7c077b142dba29c4f1b8f52d2efddc49c" +checksum = "35dc9a249c066d17e8947ff52a4116406163cf92c7f0763cb8c001760b26403f" dependencies = [ "ethers-core", "once_cell", @@ -1306,9 +1305,9 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "2.0.11" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0111ead599d17a7bff6985fd5756f39ca7033edc79a31b23026a8d5d64fa95cd" +checksum = "43304317c7f776876e47f2f637859f6d0701c1ec7930a150f169d5fbe7d76f5a" dependencies = [ "const-hex", "ethers-contract-abigen", @@ -1325,9 +1324,9 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbdfb952aafd385b31d316ed80d7b76215ce09743c172966d840e96924427e0c" +checksum = "f9f96502317bf34f6d71a3e3d270defaa9485d754d789e15a8e04a84161c95eb" dependencies = [ "Inflector", "const-hex", @@ -1342,16 +1341,16 @@ dependencies = [ "reqwest", "serde", "serde_json", - "syn 2.0.48", + "syn 2.0.49", "toml", "walkdir", ] [[package]] name = "ethers-contract-derive" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7465c814a2ecd0de0442160da13584205d1cdc08f4717a6511cad455bd5d7dc4" +checksum = "452ff6b0a64507ce8d67ffd48b1da3b42f03680dcf5382244e9c93822cbbf5de" dependencies = [ "Inflector", "const-hex", @@ -1360,14 +1359,14 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] name = "ethers-core" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918b1a9ba585ea61022647def2f27c29ba19f6d2a4a4c8f68a9ae97fd5769737" +checksum = "aab3cef6cc1c9fd7f787043c81ad3052eff2b96a3878ef1526aa446311bdbfc9" dependencies = [ "arrayvec", "bytes 1.5.0", @@ -1386,7 +1385,7 @@ dependencies = [ "serde", "serde_json", "strum", - "syn 2.0.48", + "syn 2.0.49", "tempfile", "thiserror", "tiny-keccak", @@ -1395,9 +1394,9 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "facabf8551b4d1a3c08cb935e7fca187804b6c2525cc0dafb8e5a6dd453a24de" +checksum = "16d45b981f5fa769e1d0343ebc2a44cfa88c9bc312eb681b676318b40cef6fb1" dependencies = [ "chrono", "ethers-core", @@ -1411,9 +1410,9 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "2.0.11" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681ece6eb1d10f7cf4f873059a77c04ff1de4f35c63dd7bccde8f438374fcb93" +checksum = "145211f34342487ef83a597c1e69f0d3e01512217a7c72cc8a25931854c7dca0" dependencies = [ "async-trait", "auto_impl", @@ -1438,9 +1437,9 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "2.0.11" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25d6c0c9455d93d4990c06e049abf9b30daf148cf461ee939c11d88907c60816" +checksum = "fb6b15393996e3b8a78ef1332d6483c11d839042c17be58decc92fa8b1c3508a" dependencies = [ "async-trait", "auto_impl", @@ -1476,9 +1475,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "2.0.11" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb1b714e227bbd2d8c53528adb580b203009728b17d0d0e4119353aa9bc5532" +checksum = "b3b125a103b56aef008af5d5fb48191984aa326b50bfd2557d231dc499833de3" dependencies = [ "async-trait", "coins-bip32", @@ -1495,9 +1494,9 @@ dependencies = [ [[package]] name = "ethers-solc" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2e46e3ec8ef0c986145901fa9864205dc4dcee701f9846be2d56112d34bdea" +checksum = "d21df08582e0a43005018a858cc9b465c5fff9cf4056651be64f844e57d1f55f" dependencies = [ "cfg-if", "const-hex", @@ -1542,6 +1541,17 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "event-listener" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72557800024fabbaa2449dd4bf24e37b93702d457a4d4f2b0dd1f0f039f20c1" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + [[package]] name = "event-listener-strategy" version = "0.4.0" @@ -1552,11 +1562,21 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "event-listener-strategy" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +dependencies = [ + "event-listener 5.0.0", + "pin-project-lite", +] + [[package]] name = "eyre" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", @@ -1751,7 +1771,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -1917,9 +1937,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b553656127a00601c8ae5590fcfdc118e4083a7924b6cf4ffc1ea4b99dc429d7" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes 1.5.0", "fnv", @@ -1957,9 +1977,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" [[package]] name = "hex" @@ -2117,9 +2137,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.58" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2194,9 +2214,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" dependencies = [ "equivalent", "hashbrown", @@ -2245,12 +2265,12 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ "hermit-abi", - "rustix 0.38.30", + "libc", "windows-sys 0.52.0", ] @@ -2303,18 +2323,18 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" dependencies = [ "wasm-bindgen", ] @@ -2358,7 +2378,7 @@ dependencies = [ "tokio-util", "tracing", "url", - "webpki-roots 0.26.0", + "webpki-roots 0.26.1", ] [[package]] @@ -2415,7 +2435,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d94b7505034e2737e688e1153bf81e6f93ad296695c43958d6da2e4321f0a990" dependencies = [ "heck", - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", "syn 1.0.109", @@ -2597,9 +2617,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.152" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libm" @@ -2623,16 +2643,16 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "libc", "redox_syscall", ] [[package]] name = "libz-sys" -version = "1.1.14" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "295c17e837573c8c821dbaeb3cceb3d745ad082f7572191409e69cbc1b3fd050" +checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" dependencies = [ "cc", "libc", @@ -2648,9 +2668,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -2714,9 +2734,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] @@ -2759,21 +2779,26 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", "libm", @@ -2804,10 +2829,10 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -2864,9 +2889,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.98" +version = "0.9.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" dependencies = [ "cc", "libc", @@ -2906,7 +2931,7 @@ version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", "syn 1.0.109", @@ -3072,7 +3097,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -3095,22 +3120,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -3148,9 +3173,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "polling" @@ -3170,14 +3195,14 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.2" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c980a3880efd47b2e262f6a4bb6daad6555cf3367aa9c4e52895f69537a41" +checksum = "30054e72317ab98eddd8561db0f6524df3367636884b7b21b703e4b280a84a14" dependencies = [ "cfg-if", "concurrent-queue", "pin-project-lite", - "rustix 0.38.30", + "rustix 0.38.31", "tracing", "windows-sys 0.52.0", ] @@ -3218,7 +3243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" dependencies = [ "proc-macro2", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -3247,38 +3272,14 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" dependencies = [ "toml_datetime", "toml_edit 0.20.2", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -3287,9 +3288,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -3300,7 +3301,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "lazy_static", "num-traits", "rand 0.8.5", @@ -3407,9 +3408,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -3417,9 +3418,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3447,13 +3448,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", + "regex-automata 0.4.5", "regex-syntax 0.8.2", ] @@ -3468,9 +3469,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", @@ -3497,9 +3498,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" dependencies = [ "base64 0.21.7", "bytes 1.5.0", @@ -3523,6 +3524,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-rustls 0.24.1", @@ -3531,7 +3533,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.25.3", + "webpki-roots 0.25.4", "winreg", ] @@ -3694,14 +3696,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", - "linux-raw-sys 0.4.12", + "linux-raw-sys 0.4.13", "windows-sys 0.52.0", ] @@ -3726,7 +3728,7 @@ dependencies = [ "log", "ring 0.17.7", "rustls-pki-types", - "rustls-webpki 0.102.1", + "rustls-webpki 0.102.2", "subtle", "zeroize", ] @@ -3750,7 +3752,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" dependencies = [ "openssl-probe", - "rustls-pemfile 2.0.0", + "rustls-pemfile 2.1.0", "rustls-pki-types", "schannel", "security-framework", @@ -3767,9 +3769,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e4980fa29e4c4b212ffb3db068a564cbf560e51d3944b7c88bd8bf5bec64f4" +checksum = "3c333bb734fcdedcea57de1602543590f545f127dc8b533324318fd492c5c70b" dependencies = [ "base64 0.21.7", "rustls-pki-types", @@ -3777,9 +3779,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9d979b3ce68192e42760c7810125eb6cf2ea10efae545a156063e61f314e2a" +checksum = "048a63e5b3ac996d78d402940b5fa47973d2d080c6c6fffa1d0f19c4445310b7" [[package]] name = "rustls-webpki" @@ -3793,9 +3795,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.1" +version = "0.102.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4ca26037c909dedb327b48c3327d0ba91d3dd3c4e05dad328f210ffb68e95b" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" dependencies = [ "ring 0.17.7", "rustls-pki-types", @@ -3968,29 +3970,29 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", @@ -4130,7 +4132,7 @@ dependencies = [ "num-bigint", "num-traits", "thiserror", - "time 0.3.31", + "time 0.3.34", ] [[package]] @@ -4161,9 +4163,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.12.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "smart-default" @@ -4173,7 +4175,7 @@ checksum = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -4336,9 +4338,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" [[package]] name = "strum" @@ -4359,7 +4361,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -4393,9 +4395,9 @@ dependencies = [ [[package]] name = "svm-rs" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20689c7d03b6461b502d0b95d6c24874c7d24dea2688af80486a130a06af3b07" +checksum = "11297baafe5fa0c99d5722458eac6a5e25c01eb1b8e5cd137f54079093daa7a4" dependencies = [ "dirs", "fs2", @@ -4424,15 +4426,21 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "system-configuration" version = "0.5.1" @@ -4462,14 +4470,13 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.9.0" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" dependencies = [ "cfg-if", "fastrand 2.0.1", - "redox_syscall", - "rustix 0.38.30", + "rustix 0.38.31", "windows-sys 0.52.0", ] @@ -4486,22 +4493,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -4531,16 +4538,17 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", - "time-macros 0.2.16", + "time-macros 0.2.17", ] [[package]] @@ -4561,10 +4569,11 @@ dependencies = [ [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ + "num-conv", "time-core", ] @@ -4607,9 +4616,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes 1.5.0", @@ -4630,7 +4639,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -4690,7 +4699,7 @@ dependencies = [ "tokio", "tokio-rustls 0.24.1", "tungstenite", - "webpki-roots 0.25.3", + "webpki-roots 0.25.4", ] [[package]] @@ -4800,7 +4809,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", ] [[package]] @@ -4913,9 +4922,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -5002,9 +5011,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "value-bag" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cdbaf5e132e593e9fc1de6a15bbec912395b11fb9719e061cf64f804524c503" +checksum = "126e423afe2dd9ac52142e7e9d5ce4135d7e13776c529d27fd6bc49f19e3280b" [[package]] name = "vcpkg" @@ -5057,9 +5066,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -5067,24 +5076,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" dependencies = [ "cfg-if", "js-sys", @@ -5094,9 +5103,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5104,28 +5113,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.49", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" dependencies = [ "js-sys", "wasm-bindgen", @@ -5133,15 +5142,15 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de2cfda980f21be5a7ed2eadb3e6fe074d56022bea2cdeb1a62eb220fc04188" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" dependencies = [ "rustls-pki-types", ] @@ -5179,11 +5188,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.51.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] @@ -5320,9 +5329,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.34" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] @@ -5383,7 +5392,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" dependencies = [ - "aes 0.8.3", + "aes 0.8.4", "byteorder", "bzip2", "constant_time_eq", @@ -5393,7 +5402,7 @@ dependencies = [ "hmac 0.12.1", "pbkdf2 0.11.0", "sha1 0.10.6", - "time 0.3.31", + "time 0.3.34", "zstd", ] diff --git a/Dockerfile b/Dockerfile index 5030976..77da2e2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,6 +22,8 @@ RUN cargo check --all-features RUN cargo fmt --check --all RUN cargo clippy --all-features --no-deps -- -D warnings RUN cargo test --workspace --all-features +ENV RUSTDOCFLAGS="-D warnings" +RUN cargo doc --all-features --workspace --no-deps RUN CARGO_TARGET_DIR=/workspaces/${PROJECT}/target cargo install --path resolver --bin=resolver --root ~${USER}/.cargo/ RUN valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose ~${USER}/.cargo/bin/resolver --help diff --git a/lib/src/resolver/did_registry.rs b/lib/src/resolver/did_registry.rs index 7680569..22d2eed 100644 --- a/lib/src/resolver/did_registry.rs +++ b/lib/src/resolver/did_registry.rs @@ -1,4 +1,5 @@ //! Generated ABI Functions, along with some extra to make it easier to interact with the registry. +use std::ffi::CStr; use crate::error::RegistrySignerError; use ethers::{ @@ -56,6 +57,11 @@ impl DidattributeChangedFilter { /// Get the name of the attribute as a string. non-UTF8 bytes will be replaced with the unicode replacement character, �. pub fn name_string_lossy(&self) -> String { + let is_cstr = self.name.iter().rev().any(|&c| c == 0); + if is_cstr { + let cstr = CStr::from_bytes_until_nul(self.name.as_ref()).expect("Nul check succeeded"); + return cstr.to_string_lossy().to_string(); + } String::from_utf8_lossy(self.name.as_ref()).to_string() } diff --git a/lib/src/types/did_parser.rs b/lib/src/types/did_parser.rs index af228da..7c6bb98 100644 --- a/lib/src/types/did_parser.rs +++ b/lib/src/types/did_parser.rs @@ -1,5 +1,4 @@ //! Parsing Expression Grammer (PEG) parsing rules for parts of a Decentralized Identifier - use ethers::types::Address; use crate::types::*; @@ -235,8 +234,11 @@ peg::parser! { #[cfg(test)] mod tests { + use super::*; + use std::ffi::CStr; + #[test] fn test_did_attribute_parser() { let keys = [ @@ -285,6 +287,32 @@ mod tests { } } + #[test] + fn test_parse_hex_c_string_svc() { + let decoded_data = + hex::decode("6469642f7376632f4d6573736167696e67536572766963650000000000000000") + .unwrap(); + let cstr = CStr::from_bytes_until_nul(decoded_data.as_slice()).unwrap(); + let parsed = parse_attribute(&cstr.as_ref().to_str().unwrap()); + assert_eq!(parsed, Ok(Attribute::Service(ServiceType::Messaging))); + } + + #[test] + fn test_parse_hex_c_string_pub() { + let decoded_data = + hex::decode("6469642f7075622f456432353531392f766572694b65792f62617365353800").unwrap(); + let cstr = CStr::from_bytes_until_nul(decoded_data.as_slice()).unwrap(); + let parsed = parse_attribute(&cstr.as_ref().to_str().unwrap()); + assert_eq!( + parsed, + Ok(Attribute::PublicKey(PublicKey { + key_type: KeyType::Ed25519VerificationKey2020, + purpose: KeyPurpose::VerificationKey, + encoding: KeyEncoding::Base58 + })) + ); + } + #[test] fn test_did_xmtp_attribute_parser() { let keys = [ diff --git a/lib/src/types/did_url.rs b/lib/src/types/did_url.rs index e33179f..a5ac061 100644 --- a/lib/src/types/did_url.rs +++ b/lib/src/types/did_url.rs @@ -40,7 +40,7 @@ pub struct DidUrl { pub fragment: Option, } -/// The `did` part of a [did:ethr](https://github.com/decentralized-identity/ethr-did-resolver/blob/master/doc/did-method-spec.md) URL. returned by [`parse_ethr_did`] +/// The `did` part of a [did:ethr](https://github.com/decentralized-identity/ethr-did-resolver/blob/master/doc/did-method-spec.md) URL. returned by [`super::parse_ethr_did`] #[derive(Debug, Clone, PartialEq, Eq, SmartDefault)] pub struct Did { pub method: Method, @@ -245,7 +245,7 @@ impl DidUrl { /// Retrieves the chainId for an DID:ETHR URL, as defined in the [did-ethr](https://github.com/decentralized-identity/ethr-did-resolver/blob/master/doc/did-method-spec.md). /// /// # Returns - /// A enum [`ChainId`] indicating the chain this DID belongs to. + /// A enum [`Network`] indicating the chain this DID belongs to. /// /// # Examples /// ``` @@ -261,7 +261,7 @@ impl DidUrl { /// Retrieves the identity part from the DID URL, as defined in the [did-ethr spec](https://github.com/decentralized-identity/ethr-did-resolver/blob/master/doc/did-method-spec.md)). /// /// # Returns - /// A Enum [`AddressOrHexKey`] which identifies the DID. This can be either an 20-byte [`Address`] or a 33-byte [`Vec`]. + /// A Enum [`Account`] which identifies the DID. This can be either an 20-byte [`Address`] or a 33-byte [`Vec`]. /// /// # Examples /// ``` diff --git a/lib/src/types/ethr.rs b/lib/src/types/ethr.rs index c01b3e2..429afd9 100644 --- a/lib/src/types/ethr.rs +++ b/lib/src/types/ethr.rs @@ -189,16 +189,19 @@ impl EthrBuilder { context: &EventContext, ) -> Result<(), EthrBuilderError> { let name = event.name_string_lossy(); - let attribute = types::parse_attribute(&name).unwrap_or(Attribute::Other(name.to_string())); - - log::trace!( - "Attribute Event name={}, value={}, now={}, valid_to={}, attr={:?}", - name, - event.value, - self.now, - event.valid_to, - attribute - ); + + if log::log_enabled!(log::Level::Trace) { + log::trace!( + "Attribute Event name={}, value={}, now={}, valid_to={}", + name.clone(), + event.value_string_lossy(), + self.now, + event.valid_to + ); + } + + let attribute = + types::parse_attribute(&name).unwrap_or_else(|_err| Attribute::Other(name.to_owned())); let key = Key::Attribute { name: event.name, @@ -553,6 +556,42 @@ pub(crate) mod tests { ); } + #[test] + fn test_attribute_changed_ed25519_from_hex_bytes() { + let identity = address("0x7e575682a8e450e33eb0493f9972821ae333cd7f"); + let name_from_hex_str = + hex::decode("6469642f7075622f456432353531392f766572694b65792f6261736535380000") + .unwrap(); + let name_bytes: [u8; 32] = name_from_hex_str.try_into().unwrap(); + + let event = DidattributeChangedFilter { + name: name_bytes, + value: b"b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".into(), + ..base_attr_changed(identity, None) + }; + + let mut builder = EthrBuilder::default(); + builder.account_address(&identity).unwrap(); + builder.now(U256::zero()); + builder + .attribute_event(event, &EventContext::mock(0)) + .unwrap(); + let doc = builder.build().unwrap(); + assert_eq!( + doc.verification_method[1], + VerificationMethod { + id: DidUrl::parse("did:ethr:0x7e575682a8e450e33eb0493f9972821ae333cd7f#delegate-0") + .unwrap(), + verification_type: KeyType::Ed25519VerificationKey2020, + controller: DidUrl::parse("did:ethr:0x7e575682a8e450e33eb0493f9972821ae333cd7f") + .unwrap(), + verification_properties: Some(VerificationMethodProperties::PublicKeyBase58 { + public_key_base58: "2xuEQzL6v6ML38ta35FLU2H1cLKL1cqwzHsJSkkiFZ3ro6be4cs9XScN9n4f7KDTfbZ3DZEuWDYBDhcE924G8Rp4".into() + }), + } + ); + } + #[test] fn test_attribute_changed_x25519() { let identity = address("0x7e575682a8e450e33eb0493f9972821ae333cd7f"); @@ -613,6 +652,38 @@ pub(crate) mod tests { ); } + #[test] + fn test_attribute_changed_service_from_hex_bytes() { + let name_data = + hex::decode("6469642f7376632f4d6573736167696e67536572766963650000000000000000") + .unwrap(); + let name_bytes: [u8; 32] = name_data.try_into().unwrap(); + let identity = address("0x7e575682a8e450e33eb0493f9972821ae333cd7f"); + let event = DidattributeChangedFilter { + name: name_bytes, + value: b"https://xmtp.com/resolver".into(), + ..base_attr_changed(identity, None) + }; + + let mut builder = EthrBuilder::default(); + builder.account_address(&identity).unwrap(); + builder.now(U256::zero()); + builder + .attribute_event(event, &EventContext::mock(0)) + .unwrap(); + let doc = builder.build().unwrap(); + assert_eq!( + doc.service, + vec![Service { + id: DidUrl::parse("did:ethr:0x7e575682a8e450e33eb0493f9972821ae333cd7f#service-0") + .unwrap(), + service_type: ServiceType::Messaging, + service_endpoint: Url::parse("https://xmtp.com/resolver").unwrap(), + recipient_keys: "".into(), + }] + ); + } + #[test] fn test_attribute_increments_correctly() { let identity = address("0x7e575682a8e450e33eb0493f9972821ae333cd7f"); diff --git a/resolver/src/main.rs b/resolver/src/main.rs index c316f04..8c9c79a 100644 --- a/resolver/src/main.rs +++ b/resolver/src/main.rs @@ -7,7 +7,7 @@ //! ### Endpoint //! //! ```text -//! POST /api/v1/resolveDid +//! POST //! ``` //! //! ### Request Format @@ -74,6 +74,11 @@ //! - All requests must be made over HTTPS. //! - Rate limiting is applied to prevent abuse. //! +//! ### Example +//! +//! ```bash +//! curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method":"did_resolveDid", "params": { "publicKey":"x"} }' http://localhost:8080 +//! ``` //! //! ### Support //!