Skip to content

perf(auth): lift provider construction out of hot path ⚡ #30

@Klazomenai

Description

@Klazomenai

Problem

AuthService::has_access() in src/auth.rs (lines 185-199) constructs a new HTTP provider, parses the RPC URL, and instantiates a new contract binding on every auth request:

let url: url::Url = self.config.rpc_url.parse()...;
let provider = ProviderBuilder::new().connect_http(url);
let contract = IKeyRAAccessControl::new(self.config.contract_address, provider);

Under load this means N TCP connections for N concurrent auth requests. The provider and contract instance should be constructed once at startup and stored on AuthService.

Found during architecture review (2026-03-23).

Acceptance Criteria

  • Provider constructed once in AuthService::new() and stored as a field
  • Contract binding stored as a field (or constructed from the stored provider)
  • has_access() reuses the stored provider/binding
  • Connection pooling verified (single TCP connection reused)
  • Tests pass (cargo test --lib && cargo test --test integration)

Implementation

pub struct AuthService {
    config: AuthConfig,
    contract: IKeyRAAccessControl::IKeyRAAccessControlInstance<
        Http<reqwest::Client>,
        alloy::providers::RootProvider<Http<reqwest::Client>>,
    >,
}

impl AuthService {
    pub fn new(config: AuthConfig) -> Result<Self, AuthError> {
        let url: url::Url = config.rpc_url.parse()?;
        let provider = ProviderBuilder::new().connect_http(url);
        let contract = IKeyRAAccessControl::new(config.contract_address, provider);
        Ok(Self { config, contract })
    }

    pub async fn has_access(&self, address: Address) -> Result<bool, AuthError> {
        Ok(self.contract.hasAccess(address).call().await?.0)
    }
}

Parent: #16

Metadata

Metadata

Assignees

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions