From 083ff66af23deb8dec0dfef97506af2a0e74ae8f Mon Sep 17 00:00:00 2001 From: hdbg Date: Sat, 4 Apr 2026 12:04:24 +0200 Subject: [PATCH] refactor(server): removed `miette` out of server --- server/Cargo.lock | 2 +- server/Cargo.toml | 2 +- server/crates/arbiter-client/src/auth.rs | 4 +- .../arbiter-client/src/bin/test_connect.rs | 7 +--- server/crates/arbiter-client/src/client.rs | 19 +++++---- server/crates/arbiter-proto/src/url.rs | 1 - server/crates/arbiter-server/Cargo.toml | 2 +- .../arbiter-server/src/actors/bootstrap.rs | 7 +--- .../arbiter-server/src/actors/client/auth.rs | 7 +--- .../arbiter-server/src/actors/client/mod.rs | 5 +-- .../src/actors/client/session.rs | 10 +++-- .../arbiter-server/src/actors/evm/mod.rs | 13 +----- .../client_connect_approval.rs | 8 +++- .../src/actors/keyholder/mod.rs | 10 +---- .../crates/arbiter-server/src/actors/mod.rs | 5 +-- .../actors/user_agent/session/connection.rs | 2 +- .../crates/arbiter-server/src/context/mod.rs | 9 +---- .../crates/arbiter-server/src/context/tls.rs | 14 ++----- server/crates/arbiter-server/src/db/mod.rs | 9 +---- server/crates/arbiter-server/src/evm/mod.rs | 13 ++---- .../crates/arbiter-server/src/evm/policies.rs | 10 +---- .../arbiter-server/src/grpc/client/auth.rs | 8 ++-- .../arbiter-server/src/grpc/client/evm.rs | 24 ++++++----- .../arbiter-server/src/grpc/client/inbound.rs | 1 + .../src/grpc/client/outbound.rs | 1 + .../arbiter-server/src/grpc/client/vault.rs | 12 +++--- .../arbiter-server/src/grpc/common/inbound.rs | 7 ++-- .../src/grpc/common/outbound.rs | 9 +++-- .../arbiter-server/src/grpc/user_agent.rs | 10 ++--- .../src/grpc/user_agent/auth.rs | 16 +++++--- .../arbiter-server/src/grpc/user_agent/evm.rs | 40 ++++++++++--------- .../src/grpc/user_agent/outbound.rs | 4 +- .../src/grpc/user_agent/sdk_client.rs | 24 ++++++----- .../src/grpc/user_agent/vault.rs | 25 ++++++------ server/crates/arbiter-server/src/main.rs | 8 ++-- .../arbiter-server/tests/user_agent/unseal.rs | 7 ++-- 36 files changed, 156 insertions(+), 199 deletions(-) diff --git a/server/Cargo.lock b/server/Cargo.lock index 32a1587..ae401a6 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -724,6 +724,7 @@ name = "arbiter-server" version = "0.1.0" dependencies = [ "alloy", + "anyhow", "arbiter-proto", "arbiter-tokens-registry", "argon2", @@ -741,7 +742,6 @@ dependencies = [ "k256", "kameo", "memsafe", - "miette", "pem", "prost-types", "rand 0.10.0", diff --git a/server/Cargo.toml b/server/Cargo.toml index ddc9416..1e41511 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -22,7 +22,6 @@ chrono = { version = "0.4.44", features = ["serde"] } rand = "0.10.0" rustls = { version = "0.23.37", features = ["aws-lc-rs"] } smlang = "0.8.0" -miette = { version = "7.6.0", features = ["fancy", "serde"] } thiserror = "2.0.18" async-trait = "0.1.89" futures = "0.3.32" @@ -43,3 +42,4 @@ k256 = { version = "0.13.4", features = ["ecdsa", "pkcs8"] } rsa = { version = "0.9", features = ["sha2"] } sha2 = "0.10" spki = "0.7" +miette = { version = "7.6.0", features = ["fancy", "serde"] } \ No newline at end of file diff --git a/server/crates/arbiter-client/src/auth.rs b/server/crates/arbiter-client/src/auth.rs index b42f82a..ff26e09 100644 --- a/server/crates/arbiter-client/src/auth.rs +++ b/server/crates/arbiter-client/src/auth.rs @@ -122,9 +122,7 @@ async fn receive_auth_confirmation( .await .map_err(|_| AuthError::UnexpectedAuthResponse)?; - let payload = response - .payload - .ok_or(AuthError::UnexpectedAuthResponse)?; + let payload = response.payload.ok_or(AuthError::UnexpectedAuthResponse)?; match payload { ClientResponsePayload::Auth(response) => match response.payload { Some(AuthResponsePayload::Result(result)) diff --git a/server/crates/arbiter-client/src/bin/test_connect.rs b/server/crates/arbiter-client/src/bin/test_connect.rs index 6b127a2..311d333 100644 --- a/server/crates/arbiter-client/src/bin/test_connect.rs +++ b/server/crates/arbiter-client/src/bin/test_connect.rs @@ -1,4 +1,3 @@ - use std::io::{self, Write}; use arbiter_client::ArbiterClient; @@ -22,8 +21,6 @@ async fn main() { return; } - - let url = match ArbiterUrl::try_from(input) { Ok(url) => url, Err(err) => { @@ -32,7 +29,7 @@ async fn main() { } }; - println!("{:#?}", url); + println!("{:#?}", url); let metadata = ClientMetadata { name: "arbiter-client test_connect".to_string(), @@ -44,4 +41,4 @@ async fn main() { Ok(_) => println!("Connected and authenticated successfully."), Err(err) => eprintln!("Failed to connect: {:#?}", err), } -} \ No newline at end of file +} diff --git a/server/crates/arbiter-client/src/client.rs b/server/crates/arbiter-client/src/client.rs index a9e9391..8a77441 100644 --- a/server/crates/arbiter-client/src/client.rs +++ b/server/crates/arbiter-client/src/client.rs @@ -1,11 +1,16 @@ -use arbiter_proto::{ClientMetadata, proto::arbiter_service_client::ArbiterServiceClient, url::ArbiterUrl}; +use arbiter_proto::{ + ClientMetadata, proto::arbiter_service_client::ArbiterServiceClient, url::ArbiterUrl, +}; use std::sync::Arc; use tokio::sync::{Mutex, mpsc}; use tokio_stream::wrappers::ReceiverStream; use tonic::transport::ClientTlsConfig; use crate::{ - StorageError, auth::{AuthError, authenticate}, storage::{FileSigningKeyStorage, SigningKeyStorage}, transport::{BUFFER_LENGTH, ClientTransport} + StorageError, + auth::{AuthError, authenticate}, + storage::{FileSigningKeyStorage, SigningKeyStorage}, + transport::{BUFFER_LENGTH, ClientTransport}, }; #[cfg(feature = "evm")] @@ -30,7 +35,6 @@ pub enum Error { #[error("Storage error")] Storage(#[from] StorageError), - } pub struct ArbiterClient { @@ -61,10 +65,11 @@ impl ArbiterClient { let anchor = webpki::anchor_from_trusted_cert(&url.ca_cert)?.to_owned(); let tls = ClientTlsConfig::new().trust_anchor(anchor); - let channel = tonic::transport::Channel::from_shared(format!("https://{}:{}", url.host, url.port))? - .tls_config(tls)? - .connect() - .await?; + let channel = + tonic::transport::Channel::from_shared(format!("https://{}:{}", url.host, url.port))? + .tls_config(tls)? + .connect() + .await?; let mut client = ArbiterServiceClient::new(channel); let (tx, rx) = mpsc::channel(BUFFER_LENGTH); diff --git a/server/crates/arbiter-proto/src/url.rs b/server/crates/arbiter-proto/src/url.rs index 7459a4b..321df0b 100644 --- a/server/crates/arbiter-proto/src/url.rs +++ b/server/crates/arbiter-proto/src/url.rs @@ -7,7 +7,6 @@ const ARBITER_URL_SCHEME: &str = "arbiter"; const CERT_QUERY_KEY: &str = "cert"; const BOOTSTRAP_TOKEN_QUERY_KEY: &str = "bootstrap_token"; - #[derive(Debug, Clone)] pub struct ArbiterUrl { pub host: String, diff --git a/server/crates/arbiter-server/Cargo.toml b/server/crates/arbiter-server/Cargo.toml index 8996fce..7a3794d 100644 --- a/server/crates/arbiter-server/Cargo.toml +++ b/server/crates/arbiter-server/Cargo.toml @@ -25,7 +25,6 @@ tonic.features = ["tls-aws-lc"] tokio.workspace = true rustls.workspace = true smlang.workspace = true -miette.workspace = true thiserror.workspace = true fatality = "0.1.1" diesel_migrations = { version = "2.3.1", features = ["sqlite"] } @@ -53,6 +52,7 @@ spki.workspace = true alloy.workspace = true prost-types.workspace = true arbiter-tokens-registry.path = "../arbiter-tokens-registry" +anyhow = "1.0.102" [dev-dependencies] insta = "1.46.3" diff --git a/server/crates/arbiter-server/src/actors/bootstrap.rs b/server/crates/arbiter-server/src/actors/bootstrap.rs index 515ad54..de85d06 100644 --- a/server/crates/arbiter-server/src/actors/bootstrap.rs +++ b/server/crates/arbiter-server/src/actors/bootstrap.rs @@ -2,7 +2,7 @@ use arbiter_proto::{BOOTSTRAP_PATH, home_path}; use diesel::QueryDsl; use diesel_async::RunQueryDsl; use kameo::{Actor, messages}; -use miette::Diagnostic; + use rand::{RngExt, distr::Alphanumeric, make_rng, rngs::StdRng}; use thiserror::Error; @@ -25,18 +25,15 @@ pub async fn generate_token() -> Result { Ok(token) } -#[derive(Error, Debug, Diagnostic)] +#[derive(Error, Debug)] pub enum Error { #[error("Database error: {0}")] - #[diagnostic(code(arbiter_server::bootstrap::database))] Database(#[from] db::PoolError), #[error("Database query error: {0}")] - #[diagnostic(code(arbiter_server::bootstrap::database_query))] Query(#[from] diesel::result::Error), #[error("I/O error: {0}")] - #[diagnostic(code(arbiter_server::bootstrap::io))] Io(#[from] std::io::Error), } diff --git a/server/crates/arbiter-server/src/actors/client/auth.rs b/server/crates/arbiter-server/src/actors/client/auth.rs index 181b974..ed049dc 100644 --- a/server/crates/arbiter-server/src/actors/client/auth.rs +++ b/server/crates/arbiter-server/src/actors/client/auth.rs @@ -287,10 +287,7 @@ where Ok(()) } -pub async fn authenticate( - props: &mut ClientConnection, - transport: &mut T, -) -> Result +pub async fn authenticate(props: &mut ClientConnection, transport: &mut T) -> Result where T: Bi> + Send + ?Sized, { @@ -319,7 +316,7 @@ where sync_client_metadata(&props.db, info.id, &metadata).await?; challenge_client(transport, pubkey, info.current_nonce).await?; - + transport .send(Ok(Outbound::AuthSuccess)) .await diff --git a/server/crates/arbiter-server/src/actors/client/mod.rs b/server/crates/arbiter-server/src/actors/client/mod.rs index f747572..4984316 100644 --- a/server/crates/arbiter-server/src/actors/client/mod.rs +++ b/server/crates/arbiter-server/src/actors/client/mod.rs @@ -20,10 +20,7 @@ pub struct ClientConnection { impl ClientConnection { pub fn new(db: db::DatabasePool, actors: GlobalActors) -> Self { - Self { - db, - actors, - } + Self { db, actors } } } diff --git a/server/crates/arbiter-server/src/actors/client/session.rs b/server/crates/arbiter-server/src/actors/client/session.rs index a68a3c2..184c650 100644 --- a/server/crates/arbiter-server/src/actors/client/session.rs +++ b/server/crates/arbiter-server/src/actors/client/session.rs @@ -6,11 +6,10 @@ use alloy::{consensus::TxEip1559, primitives::Address, signers::Signature}; use crate::{ actors::{ GlobalActors, - client::ClientConnection, flow_coordinator::RegisterClient, - + client::ClientConnection, evm::{ClientSignTransaction, SignTransactionError}, + flow_coordinator::RegisterClient, keyholder::KeyHolderState, - }, db, evm::VetError, @@ -95,7 +94,10 @@ impl Actor for ClientSession { impl ClientSession { pub fn new_test(db: db::DatabasePool, actors: GlobalActors) -> Self { let props = ClientConnection::new(db, actors); - Self { props, client_id: 0 } + Self { + props, + client_id: 0, + } } } diff --git a/server/crates/arbiter-server/src/actors/evm/mod.rs b/server/crates/arbiter-server/src/actors/evm/mod.rs index 10df1d2..5a3a2f7 100644 --- a/server/crates/arbiter-server/src/actors/evm/mod.rs +++ b/server/crates/arbiter-server/src/actors/evm/mod.rs @@ -25,45 +25,36 @@ use crate::{ pub use crate::evm::safe_signer; -#[derive(Debug, thiserror::Error, miette::Diagnostic)] +#[derive(Debug, thiserror::Error)] pub enum SignTransactionError { #[error("Wallet not found")] - #[diagnostic(code(arbiter::evm::sign::wallet_not_found))] WalletNotFound, #[error("Database error: {0}")] - #[diagnostic(code(arbiter::evm::sign::database))] Database(#[from] DatabaseError), #[error("Keyholder error: {0}")] - #[diagnostic(code(arbiter::evm::sign::keyholder))] Keyholder(#[from] crate::actors::keyholder::Error), #[error("Keyholder mailbox error")] - #[diagnostic(code(arbiter::evm::sign::keyholder_send))] KeyholderSend, #[error("Signing error: {0}")] - #[diagnostic(code(arbiter::evm::sign::signing))] Signing(#[from] alloy::signers::Error), #[error("Policy error: {0}")] - #[diagnostic(code(arbiter::evm::sign::vet))] Vet(#[from] evm::VetError), } -#[derive(Debug, thiserror::Error, miette::Diagnostic)] +#[derive(Debug, thiserror::Error)] pub enum Error { #[error("Keyholder error: {0}")] - #[diagnostic(code(arbiter::evm::keyholder))] Keyholder(#[from] crate::actors::keyholder::Error), #[error("Keyholder mailbox error")] - #[diagnostic(code(arbiter::evm::keyholder_send))] KeyholderSend, #[error("Database error: {0}")] - #[diagnostic(code(arbiter::evm::database))] Database(#[from] DatabaseError), } diff --git a/server/crates/arbiter-server/src/actors/flow_coordinator/client_connect_approval.rs b/server/crates/arbiter-server/src/actors/flow_coordinator/client_connect_approval.rs index a3868e0..c5b20c3 100644 --- a/server/crates/arbiter-server/src/actors/flow_coordinator/client_connect_approval.rs +++ b/server/crates/arbiter-server/src/actors/flow_coordinator/client_connect_approval.rs @@ -15,7 +15,7 @@ use crate::actors::{ pub struct Args { pub client: ClientProfile, pub user_agents: Vec>, - pub reply: ReplySender> + pub reply: ReplySender>, } pub struct ClientApprovalController { @@ -39,7 +39,11 @@ impl Actor for ClientApprovalController { type Error = (); async fn on_start( - Args { client, mut user_agents, reply }: Self::Args, + Args { + client, + mut user_agents, + reply, + }: Self::Args, actor_ref: ActorRef, ) -> Result { let this = Self { diff --git a/server/crates/arbiter-server/src/actors/keyholder/mod.rs b/server/crates/arbiter-server/src/actors/keyholder/mod.rs index fbf3d50..36afe5b 100644 --- a/server/crates/arbiter-server/src/actors/keyholder/mod.rs +++ b/server/crates/arbiter-server/src/actors/keyholder/mod.rs @@ -35,36 +35,28 @@ enum State { }, } -#[derive(Debug, thiserror::Error, miette::Diagnostic)] +#[derive(Debug, thiserror::Error)] pub enum Error { #[error("Keyholder is already bootstrapped")] - #[diagnostic(code(arbiter::keyholder::already_bootstrapped))] AlreadyBootstrapped, #[error("Keyholder is not bootstrapped")] - #[diagnostic(code(arbiter::keyholder::not_bootstrapped))] NotBootstrapped, #[error("Invalid key provided")] - #[diagnostic(code(arbiter::keyholder::invalid_key))] InvalidKey, #[error("Requested aead entry not found")] - #[diagnostic(code(arbiter::keyholder::aead_not_found))] NotFound, #[error("Encryption error: {0}")] - #[diagnostic(code(arbiter::keyholder::encryption_error))] Encryption(#[from] chacha20poly1305::aead::Error), #[error("Database error: {0}")] - #[diagnostic(code(arbiter::keyholder::database_error))] DatabaseConnection(#[from] db::PoolError), #[error("Database transaction error: {0}")] - #[diagnostic(code(arbiter::keyholder::database_transaction_error))] DatabaseTransaction(#[from] diesel::result::Error), #[error("Broken database")] - #[diagnostic(code(arbiter::keyholder::broken_database))] BrokenDatabase, } diff --git a/server/crates/arbiter-server/src/actors/mod.rs b/server/crates/arbiter-server/src/actors/mod.rs index 1b70dd7..8ff1fce 100644 --- a/server/crates/arbiter-server/src/actors/mod.rs +++ b/server/crates/arbiter-server/src/actors/mod.rs @@ -1,5 +1,4 @@ use kameo::actor::{ActorRef, Spawn}; -use miette::Diagnostic; use thiserror::Error; use crate::{ @@ -17,14 +16,12 @@ pub mod flow_coordinator; pub mod keyholder; pub mod user_agent; -#[derive(Error, Debug, Diagnostic)] +#[derive(Error, Debug)] pub enum SpawnError { #[error("Failed to spawn Bootstrapper actor")] - #[diagnostic(code(SpawnError::Bootstrapper))] Bootstrapper(#[from] bootstrap::Error), #[error("Failed to spawn KeyHolder actor")] - #[diagnostic(code(SpawnError::KeyHolder))] KeyHolder(#[from] keyholder::Error), } diff --git a/server/crates/arbiter-server/src/actors/user_agent/session/connection.rs b/server/crates/arbiter-server/src/actors/user_agent/session/connection.rs index 01f2193..382dec5 100644 --- a/server/crates/arbiter-server/src/actors/user_agent/session/connection.rs +++ b/server/crates/arbiter-server/src/actors/user_agent/session/connection.rs @@ -5,8 +5,8 @@ use chacha20poly1305::{AeadInPlace, XChaCha20Poly1305, XNonce, aead::KeyInit}; use diesel::{ExpressionMethods as _, QueryDsl as _, SelectableHelper}; use diesel_async::{AsyncConnection, RunQueryDsl}; use kameo::error::SendError; -use kameo::prelude::Context; use kameo::messages; +use kameo::prelude::Context; use tracing::{error, info}; use x25519_dalek::{EphemeralSecret, PublicKey}; diff --git a/server/crates/arbiter-server/src/context/mod.rs b/server/crates/arbiter-server/src/context/mod.rs index 9867cf1..dd44655 100644 --- a/server/crates/arbiter-server/src/context/mod.rs +++ b/server/crates/arbiter-server/src/context/mod.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use miette::Diagnostic; use thiserror::Error; use crate::{ @@ -11,30 +10,24 @@ use crate::{ pub mod tls; -#[derive(Error, Debug, Diagnostic)] +#[derive(Error, Debug)] pub enum InitError { #[error("Database setup failed: {0}")] - #[diagnostic(code(arbiter_server::init::database_setup))] DatabaseSetup(#[from] db::DatabaseSetupError), #[error("Connection acquire failed: {0}")] - #[diagnostic(code(arbiter_server::init::database_pool))] DatabasePool(#[from] db::PoolError), #[error("Database query error: {0}")] - #[diagnostic(code(arbiter_server::init::database_query))] DatabaseQuery(#[from] diesel::result::Error), #[error("TLS initialization failed: {0}")] - #[diagnostic(code(arbiter_server::init::tls_init))] Tls(#[from] tls::InitError), #[error("Actor spawn failed: {0}")] - #[diagnostic(code(arbiter_server::init::actor_spawn))] ActorSpawn(#[from] crate::actors::SpawnError), #[error("I/O Error: {0}")] - #[diagnostic(code(arbiter_server::init::io))] Io(#[from] std::io::Error), } diff --git a/server/crates/arbiter-server/src/context/tls.rs b/server/crates/arbiter-server/src/context/tls.rs index eca7b3f..0a0d95a 100644 --- a/server/crates/arbiter-server/src/context/tls.rs +++ b/server/crates/arbiter-server/src/context/tls.rs @@ -2,7 +2,7 @@ use std::{net::IpAddr, string::FromUtf8Error}; use diesel::{ExpressionMethods as _, QueryDsl, SelectableHelper as _}; use diesel_async::{AsyncConnection, RunQueryDsl}; -use miette::Diagnostic; + use pem::Pem; use rcgen::{ BasicConstraints, Certificate, CertificateParams, CertifiedIssuer, DistinguishedName, DnType, @@ -29,30 +29,24 @@ const ENCODE_CONFIG: pem::EncodeConfig = { pem::EncodeConfig::new().set_line_ending(line_ending) }; -#[derive(Error, Debug, Diagnostic)] +#[derive(Error, Debug)] pub enum InitError { #[error("Key generation error during TLS initialization: {0}")] - #[diagnostic(code(arbiter_server::tls_init::key_generation))] KeyGeneration(#[from] rcgen::Error), #[error("Key invalid format: {0}")] - #[diagnostic(code(arbiter_server::tls_init::key_invalid_format))] KeyInvalidFormat(#[from] FromUtf8Error), #[error("Key deserialization error: {0}")] - #[diagnostic(code(arbiter_server::tls_init::key_deserialization))] KeyDeserializationError(rcgen::Error), #[error("Database error during TLS initialization: {0}")] - #[diagnostic(code(arbiter_server::tls_init::database_error))] DatabaseError(#[from] diesel::result::Error), #[error("Pem deserialization error during TLS initialization: {0}")] - #[diagnostic(code(arbiter_server::tls_init::pem_deserialization))] PemDeserializationError(#[from] rustls::pki_types::pem::Error), #[error("Database pool acquire error during TLS initialization: {0}")] - #[diagnostic(code(arbiter_server::tls_init::database_pool_acquire))] DatabasePoolAcquire(#[from] db::PoolError), } @@ -116,9 +110,7 @@ impl TlsCa { ]; params .subject_alt_names - .push(SanType::IpAddress(IpAddr::from([ - 127, 0, 0, 1, - ]))); + .push(SanType::IpAddress(IpAddr::from([127, 0, 0, 1]))); let mut dn = DistinguishedName::new(); dn.push(DnType::CommonName, "Arbiter Instance Leaf"); diff --git a/server/crates/arbiter-server/src/db/mod.rs b/server/crates/arbiter-server/src/db/mod.rs index ba7ef0e..c1825b8 100644 --- a/server/crates/arbiter-server/src/db/mod.rs +++ b/server/crates/arbiter-server/src/db/mod.rs @@ -5,7 +5,7 @@ use diesel_async::{ sync_connection_wrapper::SyncConnectionWrapper, }; use diesel_migrations::{EmbeddedMigrations, MigrationHarness, embed_migrations}; -use miette::Diagnostic; + use thiserror::Error; use tracing::info; @@ -21,26 +21,21 @@ static DB_FILE: &str = "arbiter.sqlite"; const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations"); -#[derive(Error, Diagnostic, Debug)] +#[derive(Error, Debug)] pub enum DatabaseSetupError { #[error("Failed to determine home directory")] - #[diagnostic(code(arbiter::db::home_dir))] HomeDir(std::io::Error), #[error(transparent)] - #[diagnostic(code(arbiter::db::connection))] Connection(diesel::ConnectionError), #[error(transparent)] - #[diagnostic(code(arbiter::db::concurrency))] ConcurrencySetup(diesel::result::Error), #[error(transparent)] - #[diagnostic(code(arbiter::db::migration))] Migration(Box), #[error(transparent)] - #[diagnostic(code(arbiter::db::pool))] Pool(#[from] PoolInitError), } diff --git a/server/crates/arbiter-server/src/evm/mod.rs b/server/crates/arbiter-server/src/evm/mod.rs index 5b4be05..d840d81 100644 --- a/server/crates/arbiter-server/src/evm/mod.rs +++ b/server/crates/arbiter-server/src/evm/mod.rs @@ -28,39 +28,32 @@ pub mod policies; mod utils; /// Errors that can only occur once the transaction meaning is known (during policy evaluation) -#[derive(Debug, thiserror::Error, miette::Diagnostic)] +#[derive(Debug, thiserror::Error)] pub enum PolicyError { #[error("Database error")] Database(#[from] crate::db::DatabaseError), #[error("Transaction violates policy: {0:?}")] - #[diagnostic(code(arbiter_server::evm::policy_error::violation))] Violations(Vec), #[error("No matching grant found")] - #[diagnostic(code(arbiter_server::evm::policy_error::no_matching_grant))] NoMatchingGrant, } -#[derive(Debug, thiserror::Error, miette::Diagnostic)] +#[derive(Debug, thiserror::Error)] pub enum VetError { #[error("Contract creation transactions are not supported")] - #[diagnostic(code(arbiter_server::evm::vet_error::contract_creation_unsupported))] ContractCreationNotSupported, #[error("Engine can't classify this transaction")] - #[diagnostic(code(arbiter_server::evm::vet_error::unsupported))] UnsupportedTransactionType, #[error("Policy evaluation failed: {1}")] - #[diagnostic(code(arbiter_server::evm::vet_error::evaluated))] Evaluated(SpecificMeaning, #[source] PolicyError), } -#[derive(Debug, thiserror::Error, miette::Diagnostic)] +#[derive(Debug, thiserror::Error)] pub enum AnalyzeError { #[error("Engine doesn't support granting permissions for contract creation")] - #[diagnostic(code(arbiter_server::evm::analyze_error::contract_creation_not_supported))] ContractCreationNotSupported, #[error("Unsupported transaction type")] - #[diagnostic(code(arbiter_server::evm::analyze_error::unsupported_transaction_type))] UnsupportedTransactionType, } diff --git a/server/crates/arbiter-server/src/evm/policies.rs b/server/crates/arbiter-server/src/evm/policies.rs index 4d37884..f0e7796 100644 --- a/server/crates/arbiter-server/src/evm/policies.rs +++ b/server/crates/arbiter-server/src/evm/policies.rs @@ -6,7 +6,7 @@ use diesel::{ ExpressionMethods as _, QueryDsl, SelectableHelper, result::QueryResult, sqlite::Sqlite, }; use diesel_async::{AsyncConnection, RunQueryDsl}; -use miette::Diagnostic; + use thiserror::Error; use crate::{ @@ -33,33 +33,27 @@ pub struct EvalContext { pub max_priority_fee_per_gas: u128, } -#[derive(Debug, Error, Diagnostic)] +#[derive(Debug, Error)] pub enum EvalViolation { #[error("This grant doesn't allow transactions to the target address {target}")] - #[diagnostic(code(arbiter_server::evm::eval_violation::invalid_target))] InvalidTarget { target: Address }, #[error("Gas limit exceeded for this grant")] - #[diagnostic(code(arbiter_server::evm::eval_violation::gas_limit_exceeded))] GasLimitExceeded { max_gas_fee_per_gas: Option, max_priority_fee_per_gas: Option, }, #[error("Rate limit exceeded for this grant")] - #[diagnostic(code(arbiter_server::evm::eval_violation::rate_limit_exceeded))] RateLimitExceeded, #[error("Transaction exceeds volumetric limits of the grant")] - #[diagnostic(code(arbiter_server::evm::eval_violation::volumetric_limit_exceeded))] VolumetricLimitExceeded, #[error("Transaction is outside of the grant's validity period")] - #[diagnostic(code(arbiter_server::evm::eval_violation::invalid_time))] InvalidTime, #[error("Transaction type is not allowed by this grant")] - #[diagnostic(code(arbiter_server::evm::eval_violation::invalid_transaction_type))] InvalidTransactionType, } diff --git a/server/crates/arbiter-server/src/grpc/client/auth.rs b/server/crates/arbiter-server/src/grpc/client/auth.rs index 84fdffa..939c057 100644 --- a/server/crates/arbiter-server/src/grpc/client/auth.rs +++ b/server/crates/arbiter-server/src/grpc/client/auth.rs @@ -140,7 +140,9 @@ impl Receiver for AuthTransportAdapter<'_> { let Some(payload) = auth_request.payload else { let _ = self .bi - .send(Err(Status::invalid_argument("Missing client auth request payload"))) + .send(Err(Status::invalid_argument( + "Missing client auth request payload", + ))) .await; return None; }; @@ -170,9 +172,7 @@ impl Receiver for AuthTransportAdapter<'_> { metadata: client_metadata_from_proto(client_info), }) } - AuthRequestPayload::ChallengeSolution(ProtoAuthChallengeSolution { - signature, - }) => { + AuthRequestPayload::ChallengeSolution(ProtoAuthChallengeSolution { signature }) => { let Ok(signature) = ed25519_dalek::Signature::try_from(signature.as_slice()) else { let _ = self .send_auth_result(ProtoAuthResult::InvalidSignature) diff --git a/server/crates/arbiter-server/src/grpc/client/evm.rs b/server/crates/arbiter-server/src/grpc/client/evm.rs index b44234f..5b5ba2e 100644 --- a/server/crates/arbiter-server/src/grpc/client/evm.rs +++ b/server/crates/arbiter-server/src/grpc/client/evm.rs @@ -34,7 +34,9 @@ pub(super) async fn dispatch( req: proto_evm::Request, ) -> Result { let Some(payload) = req.payload else { - return Err(Status::invalid_argument("Missing client EVM request payload")); + return Err(Status::invalid_argument( + "Missing client EVM request payload", + )); }; match payload { @@ -59,13 +61,13 @@ pub(super) async fn dispatch( ))) => EvmSignTransactionResponse { result: Some(vet_error.convert()), }, - Err(kameo::error::SendError::HandlerError( - SignTransactionRpcError::Internal, - )) => EvmSignTransactionResponse { - result: Some(EvmSignTransactionResult::Error( - ProtoEvmError::Internal.into(), - )), - }, + Err(kameo::error::SendError::HandlerError(SignTransactionRpcError::Internal)) => { + EvmSignTransactionResponse { + result: Some(EvmSignTransactionResult::Error( + ProtoEvmError::Internal.into(), + )), + } + } Err(err) => { warn!(error = ?err, "Failed to sign EVM transaction"); EvmSignTransactionResponse { @@ -78,8 +80,8 @@ pub(super) async fn dispatch( Ok(wrap_response(EvmResponsePayload::SignTransaction(response))) } - EvmRequestPayload::AnalyzeTransaction(_) => { - Err(Status::unimplemented("EVM transaction analysis is not yet implemented")) - } + EvmRequestPayload::AnalyzeTransaction(_) => Err(Status::unimplemented( + "EVM transaction analysis is not yet implemented", + )), } } diff --git a/server/crates/arbiter-server/src/grpc/client/inbound.rs b/server/crates/arbiter-server/src/grpc/client/inbound.rs index e69de29..8b13789 100644 --- a/server/crates/arbiter-server/src/grpc/client/inbound.rs +++ b/server/crates/arbiter-server/src/grpc/client/inbound.rs @@ -0,0 +1 @@ + diff --git a/server/crates/arbiter-server/src/grpc/client/outbound.rs b/server/crates/arbiter-server/src/grpc/client/outbound.rs index e69de29..8b13789 100644 --- a/server/crates/arbiter-server/src/grpc/client/outbound.rs +++ b/server/crates/arbiter-server/src/grpc/client/outbound.rs @@ -0,0 +1 @@ + diff --git a/server/crates/arbiter-server/src/grpc/client/vault.rs b/server/crates/arbiter-server/src/grpc/client/vault.rs index 241580f..b5e98e7 100644 --- a/server/crates/arbiter-server/src/grpc/client/vault.rs +++ b/server/crates/arbiter-server/src/grpc/client/vault.rs @@ -12,11 +12,9 @@ use kameo::{actor::ActorRef, error::SendError}; use tonic::Status; use tracing::warn; -use crate::{ - actors::{ - client::session::{ClientSession, Error, HandleQueryVaultState}, - keyholder::KeyHolderState, - }, +use crate::actors::{ + client::session::{ClientSession, Error, HandleQueryVaultState}, + keyholder::KeyHolderState, }; pub(super) async fn dispatch( @@ -24,7 +22,9 @@ pub(super) async fn dispatch( req: proto_vault::Request, ) -> Result { let Some(payload) = req.payload else { - return Err(Status::invalid_argument("Missing client vault request payload")); + return Err(Status::invalid_argument( + "Missing client vault request payload", + )); }; match payload { diff --git a/server/crates/arbiter-server/src/grpc/common/inbound.rs b/server/crates/arbiter-server/src/grpc/common/inbound.rs index d132b31..d9e4d9a 100644 --- a/server/crates/arbiter-server/src/grpc/common/inbound.rs +++ b/server/crates/arbiter-server/src/grpc/common/inbound.rs @@ -28,9 +28,8 @@ impl TryConvert for RawEvmTransaction { type Error = tonic::Status; fn try_convert(self) -> Result { - let tx = TxEip1559::decode(&mut self.0.as_slice()).map_err(|_| { - tonic::Status::invalid_argument("Invalid EVM transaction format") - })?; + let tx = TxEip1559::decode(&mut self.0.as_slice()) + .map_err(|_| tonic::Status::invalid_argument("Invalid EVM transaction format"))?; Ok(tx) } -} \ No newline at end of file +} diff --git a/server/crates/arbiter-server/src/grpc/common/outbound.rs b/server/crates/arbiter-server/src/grpc/common/outbound.rs index d2c6e7d..6ca8916 100644 --- a/server/crates/arbiter-server/src/grpc/common/outbound.rs +++ b/server/crates/arbiter-server/src/grpc/common/outbound.rs @@ -1,9 +1,12 @@ use alloy::primitives::U256; use arbiter_proto::proto::{ - evm::{EvmError as ProtoEvmError, evm_sign_transaction_response::Result as EvmSignTransactionResult}, + evm::{ + EvmError as ProtoEvmError, + evm_sign_transaction_response::Result as EvmSignTransactionResult, + }, shared::evm::{ - EvalViolation as ProtoEvalViolation, GasLimitExceededViolation, - NoMatchingGrantError, PolicyViolationsError, SpecificMeaning as ProtoSpecificMeaning, + EvalViolation as ProtoEvalViolation, GasLimitExceededViolation, NoMatchingGrantError, + PolicyViolationsError, SpecificMeaning as ProtoSpecificMeaning, TokenInfo as ProtoTokenInfo, TransactionEvalError as ProtoTransactionEvalError, eval_violation::Kind as ProtoEvalViolationKind, specific_meaning::Meaning as ProtoSpecificMeaningKind, diff --git a/server/crates/arbiter-server/src/grpc/user_agent.rs b/server/crates/arbiter-server/src/grpc/user_agent.rs index 4a32ab7..651dbe4 100644 --- a/server/crates/arbiter-server/src/grpc/user_agent.rs +++ b/server/crates/arbiter-server/src/grpc/user_agent.rs @@ -1,12 +1,10 @@ use tokio::sync::mpsc; use arbiter_proto::{ - proto::{ - user_agent::{ - UserAgentRequest, UserAgentResponse, - user_agent_request::Payload as UserAgentRequestPayload, - user_agent_response::Payload as UserAgentResponsePayload, - }, + proto::user_agent::{ + UserAgentRequest, UserAgentResponse, + user_agent_request::Payload as UserAgentRequestPayload, + user_agent_response::Payload as UserAgentResponsePayload, }, transport::{Error as TransportError, Receiver, Sender, grpc::GrpcBi}, }; diff --git a/server/crates/arbiter-server/src/grpc/user_agent/auth.rs b/server/crates/arbiter-server/src/grpc/user_agent/auth.rs index 15eeba6..d7c89e6 100644 --- a/server/crates/arbiter-server/src/grpc/user_agent/auth.rs +++ b/server/crates/arbiter-server/src/grpc/user_agent/auth.rs @@ -1,12 +1,14 @@ use arbiter_proto::{ proto::user_agent::{ - UserAgentRequest, UserAgentResponse, auth::{ + UserAgentRequest, UserAgentResponse, + auth::{ self as proto_auth, AuthChallenge as ProtoAuthChallenge, AuthChallengeRequest as ProtoAuthChallengeRequest, AuthChallengeSolution as ProtoAuthChallengeSolution, AuthResult as ProtoAuthResult, KeyType as ProtoKeyType, request::Payload as AuthRequestPayload, response::Payload as AuthResponsePayload, - }, user_agent_request::Payload as UserAgentRequestPayload, + }, + user_agent_request::Payload as UserAgentRequestPayload, user_agent_response::Payload as UserAgentResponsePayload, }, transport::{Bi, Error as TransportError, Receiver, Sender, grpc::GrpcBi}, @@ -63,7 +65,9 @@ impl Sender> for AuthTransportAdapter<'_> { Ok(Outbound::AuthChallenge { nonce }) => { AuthResponsePayload::Challenge(ProtoAuthChallenge { nonce }) } - Ok(Outbound::AuthSuccess) => AuthResponsePayload::Result(ProtoAuthResult::Success.into()), + Ok(Outbound::AuthSuccess) => { + AuthResponsePayload::Result(ProtoAuthResult::Success.into()) + } Err(Error::UnregisteredPublicKey) => { AuthResponsePayload::Result(ProtoAuthResult::InvalidKey.into()) } @@ -171,9 +175,9 @@ impl Receiver for AuthTransportAdapter<'_> { bootstrap_token, }) } - AuthRequestPayload::ChallengeSolution(ProtoAuthChallengeSolution { - signature, - }) => Some(auth::Inbound::AuthChallengeSolution { signature }), + AuthRequestPayload::ChallengeSolution(ProtoAuthChallengeSolution { signature }) => { + Some(auth::Inbound::AuthChallengeSolution { signature }) + } } } } diff --git a/server/crates/arbiter-server/src/grpc/user_agent/evm.rs b/server/crates/arbiter-server/src/grpc/user_agent/evm.rs index c9b02eb..a65b220 100644 --- a/server/crates/arbiter-server/src/grpc/user_agent/evm.rs +++ b/server/crates/arbiter-server/src/grpc/user_agent/evm.rs @@ -3,8 +3,7 @@ use arbiter_proto::proto::{ EvmError as ProtoEvmError, EvmGrantCreateRequest, EvmGrantCreateResponse, EvmGrantDeleteRequest, EvmGrantDeleteResponse, EvmGrantList, EvmGrantListResponse, EvmSignTransactionResponse, GrantEntry, WalletCreateResponse, WalletEntry, WalletList, - WalletListResponse, - evm_grant_create_response::Result as EvmGrantCreateResult, + WalletListResponse, evm_grant_create_response::Result as EvmGrantCreateResult, evm_grant_delete_response::Result as EvmGrantDeleteResult, evm_grant_list_response::Result as EvmGrantListResult, evm_sign_transaction_response::Result as EvmSignTransactionResult, @@ -165,7 +164,12 @@ async fn handle_grant_delete( actor: &ActorRef, req: EvmGrantDeleteRequest, ) -> Result, Status> { - let result = match actor.ask(HandleGrantDelete { grant_id: req.grant_id }).await { + let result = match actor + .ask(HandleGrantDelete { + grant_id: req.grant_id, + }) + .await + { Ok(()) => EvmGrantDeleteResult::Ok(()), Err(err) => { warn!(error = ?err, "Failed to delete EVM grant"); @@ -202,18 +206,18 @@ async fn handle_sign_transaction( signature.as_bytes().to_vec(), )), }, - Err(kameo::error::SendError::HandlerError( - SessionSignTransactionError::Vet(vet_error), - )) => EvmSignTransactionResponse { - result: Some(vet_error.convert()), - }, - Err(kameo::error::SendError::HandlerError( - SessionSignTransactionError::Internal, - )) => EvmSignTransactionResponse { - result: Some(EvmSignTransactionResult::Error( - ProtoEvmError::Internal.into(), - )), - }, + Err(kameo::error::SendError::HandlerError(SessionSignTransactionError::Vet(vet_error))) => { + EvmSignTransactionResponse { + result: Some(vet_error.convert()), + } + } + Err(kameo::error::SendError::HandlerError(SessionSignTransactionError::Internal)) => { + EvmSignTransactionResponse { + result: Some(EvmSignTransactionResult::Error( + ProtoEvmError::Internal.into(), + )), + } + } Err(err) => { warn!(error = ?err, "Failed to sign EVM transaction"); EvmSignTransactionResponse { @@ -224,7 +228,7 @@ async fn handle_sign_transaction( } }; - Ok(Some(wrap_evm_response(EvmResponsePayload::SignTransaction( - response, - )))) + Ok(Some(wrap_evm_response( + EvmResponsePayload::SignTransaction(response), + ))) } diff --git a/server/crates/arbiter-server/src/grpc/user_agent/outbound.rs b/server/crates/arbiter-server/src/grpc/user_agent/outbound.rs index 53ea729..805386e 100644 --- a/server/crates/arbiter-server/src/grpc/user_agent/outbound.rs +++ b/server/crates/arbiter-server/src/grpc/user_agent/outbound.rs @@ -5,9 +5,7 @@ use arbiter_proto::proto::{ TransactionRateLimit as ProtoTransactionRateLimit, VolumeRateLimit as ProtoVolumeRateLimit, specific_grant::Grant as ProtoSpecificGrantType, }, - user_agent::sdk_client::{ - WalletAccess, WalletAccessEntry as ProtoSdkClientWalletAccess, - }, + user_agent::sdk_client::{WalletAccess, WalletAccessEntry as ProtoSdkClientWalletAccess}, }; use chrono::{DateTime, Utc}; use prost_types::Timestamp as ProtoTimestamp; diff --git a/server/crates/arbiter-server/src/grpc/user_agent/sdk_client.rs b/server/crates/arbiter-server/src/grpc/user_agent/sdk_client.rs index f1827af..e06e4b1 100644 --- a/server/crates/arbiter-server/src/grpc/user_agent/sdk_client.rs +++ b/server/crates/arbiter-server/src/grpc/user_agent/sdk_client.rs @@ -1,4 +1,5 @@ use arbiter_proto::proto::{ + shared::ClientInfo as ProtoClientMetadata, user_agent::{ sdk_client::{ self as proto_sdk_client, ConnectionCancel as ProtoSdkClientConnectionCancel, @@ -13,7 +14,6 @@ use arbiter_proto::proto::{ }, user_agent_response::Payload as UserAgentResponsePayload, }, - shared::ClientInfo as ProtoClientMetadata, }; use kameo::actor::ActorRef; use tonic::Status; @@ -62,18 +62,22 @@ pub(super) async fn dispatch( req: proto_sdk_client::Request, ) -> Result, Status> { let Some(payload) = req.payload else { - return Err(Status::invalid_argument("Missing SDK client request payload")); + return Err(Status::invalid_argument( + "Missing SDK client request payload", + )); }; match payload { SdkClientRequestPayload::ConnectionResponse(resp) => { handle_connection_response(actor, resp).await } - SdkClientRequestPayload::Revoke(_) => { - Err(Status::unimplemented("SdkClientRevoke is not yet implemented")) - } + SdkClientRequestPayload::Revoke(_) => Err(Status::unimplemented( + "SdkClientRevoke is not yet implemented", + )), SdkClientRequestPayload::List(_) => handle_list(actor).await, - SdkClientRequestPayload::GrantWalletAccess(req) => handle_grant_wallet_access(actor, req).await, + SdkClientRequestPayload::GrantWalletAccess(req) => { + handle_grant_wallet_access(actor, req).await + } SdkClientRequestPayload::RevokeWalletAccess(req) => { handle_revoke_wallet_access(actor, req).await } @@ -128,11 +132,11 @@ async fn handle_list( ProtoSdkClientListResult::Error(ProtoSdkClientError::Internal.into()) } }; - Ok(Some(wrap_sdk_client_response(SdkClientResponsePayload::List( - ProtoSdkClientListResponse { + Ok(Some(wrap_sdk_client_response( + SdkClientResponsePayload::List(ProtoSdkClientListResponse { result: Some(result), - }, - )))) + }), + ))) } async fn handle_grant_wallet_access( diff --git a/server/crates/arbiter-server/src/grpc/user_agent/vault.rs b/server/crates/arbiter-server/src/grpc/user_agent/vault.rs index 669d35c..8a2940f 100644 --- a/server/crates/arbiter-server/src/grpc/user_agent/vault.rs +++ b/server/crates/arbiter-server/src/grpc/user_agent/vault.rs @@ -1,3 +1,4 @@ +use arbiter_proto::proto::shared::VaultState as ProtoVaultState; use arbiter_proto::proto::user_agent::{ user_agent_response::Payload as UserAgentResponsePayload, vault::{ @@ -11,25 +12,21 @@ use arbiter_proto::proto::user_agent::{ unseal::{ self as proto_unseal, UnsealEncryptedKey as ProtoUnsealEncryptedKey, UnsealResult as ProtoUnsealResult, UnsealStart, - request::Payload as UnsealRequestPayload, - response::Payload as UnsealResponsePayload, + request::Payload as UnsealRequestPayload, response::Payload as UnsealResponsePayload, }, }, }; -use arbiter_proto::proto::shared::VaultState as ProtoVaultState; use kameo::{actor::ActorRef, error::SendError}; use tonic::Status; use tracing::warn; -use crate::{ - actors::{ - keyholder::KeyHolderState, - user_agent::{ - UserAgentSession, - session::connection::{ - BootstrapError, HandleBootstrapEncryptedKey, HandleQueryVaultState, - HandleUnsealEncryptedKey, HandleUnsealRequest, UnsealError, - }, +use crate::actors::{ + keyholder::KeyHolderState, + user_agent::{ + UserAgentSession, + session::connection::{ + BootstrapError, HandleBootstrapEncryptedKey, HandleQueryVaultState, + HandleUnsealEncryptedKey, HandleUnsealRequest, UnsealError, }, }, }; @@ -151,7 +148,9 @@ async fn handle_bootstrap_encrypted_key( .await { Ok(()) => ProtoBootstrapResult::Success, - Err(SendError::HandlerError(BootstrapError::InvalidKey)) => ProtoBootstrapResult::InvalidKey, + Err(SendError::HandlerError(BootstrapError::InvalidKey)) => { + ProtoBootstrapResult::InvalidKey + } Err(SendError::HandlerError(BootstrapError::AlreadyBootstrapped)) => { ProtoBootstrapResult::AlreadyBootstrapped } diff --git a/server/crates/arbiter-server/src/main.rs b/server/crates/arbiter-server/src/main.rs index 7605523..0b8a8e7 100644 --- a/server/crates/arbiter-server/src/main.rs +++ b/server/crates/arbiter-server/src/main.rs @@ -1,8 +1,8 @@ use std::net::SocketAddr; +use anyhow::anyhow; use arbiter_proto::{proto::arbiter_service_server::ArbiterServiceServer, url::ArbiterUrl}; use arbiter_server::{Server, actors::bootstrap::GetToken, context::ServerContext, db}; -use miette::miette; use rustls::crypto::aws_lc_rs; use tonic::transport::{Identity, ServerTlsConfig}; use tracing::info; @@ -10,7 +10,7 @@ use tracing::info; const PORT: u16 = 50051; #[tokio::main] -async fn main() -> miette::Result<()> { +async fn main() -> anyhow::Result<()> { aws_lc_rs::default_provider().install_default().unwrap(); tracing_subscriber::fmt() @@ -46,11 +46,11 @@ async fn main() -> miette::Result<()> { tonic::transport::Server::builder() .tls_config(tls) - .map_err(|err| miette!("Faild to setup TLS: {err}"))? + .map_err(|err| anyhow!("Failed to setup TLS: {err}"))? .add_service(ArbiterServiceServer::new(Server::new(context))) .serve(addr) .await - .map_err(|e| miette::miette!("gRPC server error: {e}"))?; + .map_err(|e| anyhow!("gRPC server error: {e}"))?; unreachable!("gRPC server should run indefinitely"); } diff --git a/server/crates/arbiter-server/tests/user_agent/unseal.rs b/server/crates/arbiter-server/tests/user_agent/unseal.rs index 76a68aa..fcc3e50 100644 --- a/server/crates/arbiter-server/tests/user_agent/unseal.rs +++ b/server/crates/arbiter-server/tests/user_agent/unseal.rs @@ -2,9 +2,10 @@ use arbiter_server::{ actors::{ GlobalActors, keyholder::{Bootstrap, Seal}, - user_agent::{UserAgentSession, session::connection::{ - HandleUnsealEncryptedKey, HandleUnsealRequest, UnsealError, - }}, + user_agent::{ + UserAgentSession, + session::connection::{HandleUnsealEncryptedKey, HandleUnsealRequest, UnsealError}, + }, }, db, safe_cell::{SafeCell, SafeCellHandle as _},