From e17c25a60460d172dfc845becf05248d288dc7f2 Mon Sep 17 00:00:00 2001 From: Stas Date: Sat, 4 Apr 2026 14:06:02 +0000 Subject: [PATCH 1/2] ci(server-test): ensure that all features are compiling --- .woodpecker/server-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker/server-test.yaml b/.woodpecker/server-test.yaml index 1839e88..027cf87 100644 --- a/.woodpecker/server-test.yaml +++ b/.woodpecker/server-test.yaml @@ -24,4 +24,4 @@ steps: - mise install rust - mise install protoc - mise install cargo:cargo-nextest - - mise exec cargo:cargo-nextest -- cargo nextest run --no-fail-fast \ No newline at end of file + - mise exec cargo:cargo-nextest -- cargo nextest run --no-fail-fast --all-features \ No newline at end of file From c6f440fdadbd23294f0ce0f76b457fd1b0401699 Mon Sep 17 00:00:00 2001 From: CleverWild Date: Sat, 4 Apr 2026 15:28:39 +0200 Subject: [PATCH 2/2] fix(client): evm-feature's code for new proto --- server/crates/arbiter-client/src/lib.rs | 2 +- .../crates/arbiter-client/src/wallets/evm.rs | 69 +++++++++++++++---- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/server/crates/arbiter-client/src/lib.rs b/server/crates/arbiter-client/src/lib.rs index 83fdf48..6e4516c 100644 --- a/server/crates/arbiter-client/src/lib.rs +++ b/server/crates/arbiter-client/src/lib.rs @@ -9,4 +9,4 @@ pub use client::{ArbiterClient, Error}; pub use storage::{FileSigningKeyStorage, SigningKeyStorage, StorageError}; #[cfg(feature = "evm")] -pub use wallets::evm::ArbiterEvmWallet; +pub use wallets::evm::{ArbiterEvmSignTransactionError, ArbiterEvmWallet}; diff --git a/server/crates/arbiter-client/src/wallets/evm.rs b/server/crates/arbiter-client/src/wallets/evm.rs index 4533793..5c975c9 100644 --- a/server/crates/arbiter-client/src/wallets/evm.rs +++ b/server/crates/arbiter-client/src/wallets/evm.rs @@ -10,14 +10,48 @@ use tokio::sync::Mutex; use arbiter_proto::proto::{ client::{ - ClientRequest, client_request::Payload as ClientRequestPayload, + ClientRequest, + client_request::Payload as ClientRequestPayload, client_response::Payload as ClientResponsePayload, + evm::{ + self as proto_evm, request::Payload as EvmRequestPayload, + response::Payload as EvmResponsePayload, + }, }, - evm::evm_sign_transaction_response::Result as EvmSignTransactionResult, + evm::{ + EvmSignTransactionRequest, + evm_sign_transaction_response::Result as EvmSignTransactionResult, + }, + shared::evm::TransactionEvalError, }; use crate::transport::{ClientTransport, next_request_id}; +/// A typed error payload returned by [`ArbiterEvmWallet`] transaction signing. +/// +/// This is wrapped into `alloy::signers::Error::Other`, so consumers can downcast by [`TryFrom`] and +/// interpret the concrete policy evaluation failure instead of parsing strings. +#[derive(Debug, thiserror::Error)] +#[non_exhaustive] +pub enum ArbiterEvmSignTransactionError { + #[error("transaction rejected by policy: {0:?}")] + PolicyEval(TransactionEvalError), +} + +impl<'a> TryFrom<&'a Error> for &'a ArbiterEvmSignTransactionError { + type Error = (); + + fn try_from(value: &'a Error) -> Result { + if let Error::Other(inner) = value + && let Some(eval_error) = inner.downcast_ref() + { + Ok(eval_error) + } else { + Err(()) + } + } +} + pub struct ArbiterEvmWallet { transport: Arc>, address: Address, @@ -96,12 +130,14 @@ impl TxSigner for ArbiterEvmWallet { transport .send(ClientRequest { request_id, - payload: Some(ClientRequestPayload::EvmSignTransaction( - arbiter_proto::proto::evm::EvmSignTransactionRequest { - wallet_address: self.address.to_vec(), - rlp_transaction, - }, - )), + payload: Some(ClientRequestPayload::Evm(proto_evm::Request { + payload: Some(EvmRequestPayload::SignTransaction( + EvmSignTransactionRequest { + wallet_address: self.address.to_vec(), + rlp_transaction, + }, + )), + })), }) .await .map_err(|_| Error::other("failed to send evm sign transaction request"))?; @@ -121,12 +157,21 @@ impl TxSigner for ArbiterEvmWallet { .payload .ok_or_else(|| Error::other("missing evm sign transaction response payload"))?; - let ClientResponsePayload::EvmSignTransaction(response) = payload else { + let ClientResponsePayload::Evm(proto_evm::Response { + payload: Some(payload), + }) = payload + else { return Err(Error::other( "unexpected response payload for evm sign transaction request", )); }; + let EvmResponsePayload::SignTransaction(response) = payload else { + return Err(Error::other( + "unexpected evm response payload for sign transaction request", + )); + }; + let result = response .result .ok_or_else(|| Error::other("missing evm sign transaction result"))?; @@ -136,9 +181,9 @@ impl TxSigner for ArbiterEvmWallet { Signature::try_from(signature.as_slice()) .map_err(|_| Error::other("invalid signature returned by server")) } - EvmSignTransactionResult::EvalError(eval_error) => Err(Error::other(format!( - "transaction rejected by policy: {eval_error:?}" - ))), + EvmSignTransactionResult::EvalError(eval_error) => Err(Error::other( + ArbiterEvmSignTransactionError::PolicyEval(eval_error), + )), EvmSignTransactionResult::Error(code) => Err(Error::other(format!( "server failed to sign transaction with error code {code}" ))),