clippy: fix
Some checks failed
ci/woodpecker/pr/server-audit Pipeline was successful
ci/woodpecker/pr/server-vet Pipeline failed
ci/woodpecker/pr/server-lint Pipeline was successful
ci/woodpecker/pr/server-test Pipeline was successful

This commit is contained in:
2026-03-14 14:30:23 +01:00
parent c1c5d14133
commit 17ac195c5d
10 changed files with 64 additions and 70 deletions

View File

@@ -3,6 +3,6 @@ disallowed-methods = [
# We only use RSA for Windows Hello (KeyCredentialManager) public-key verification — decryption # We only use RSA for Windows Hello (KeyCredentialManager) public-key verification — decryption
# is never required and must not be introduced. # is never required and must not be introduced.
{ path = "rsa::RsaPrivateKey::decrypt", reason = "RSA decryption is forbidden (RUSTSEC-2023-0071 Marvin Attack). Only PSS signing/verification is permitted." }, { path = "rsa::RsaPrivateKey::decrypt", reason = "RSA decryption is forbidden (RUSTSEC-2023-0071 Marvin Attack). Only PSS signing/verification is permitted." },
{ path = "rsa::pkcs1v15::DecryptingKey::decrypt", reason = "RSA decryption is forbidden (RUSTSEC-2023-0071 Marvin Attack). Only PSS signing/verification is permitted." }, { path = "rsa::pkcs1v15::DecryptingKey::decrypt", reason = "RSA decryption is forbidden (RUSTSEC-2023-0071 Marvin Attack). Only PSS signing/verification is permitted.", allow-invalid = true },
{ path = "rsa::oaep::DecryptingKey::decrypt", reason = "RSA decryption is forbidden (RUSTSEC-2023-0071 Marvin Attack). Only PSS signing/verification is permitted." }, { path = "rsa::oaep::DecryptingKey::decrypt", reason = "RSA decryption is forbidden (RUSTSEC-2023-0071 Marvin Attack). Only PSS signing/verification is permitted.", allow-invalid = true },
] ]

View File

@@ -17,7 +17,10 @@ use kameo::error::SendError;
use tracing::error; use tracing::error;
use crate::{ use crate::{
actors::{client::ClientConnection, router::{self, RequestClientApproval}}, actors::{
client::ClientConnection,
router::{self, RequestClientApproval},
},
db::{self, schema::program_client}, db::{self, schema::program_client},
}; };
@@ -100,7 +103,9 @@ async fn approve_new_client(
) -> Result<(), Error> { ) -> Result<(), Error> {
let result = actors let result = actors
.router .router
.ask(RequestClientApproval { client_pubkey: pubkey }) .ask(RequestClientApproval {
client_pubkey: pubkey,
})
.await; .await;
match result { match result {
@@ -166,18 +171,18 @@ async fn challenge_client(
Error::Transport Error::Transport
})?; })?;
let AuthChallengeSolution { signature } = expect_message( let AuthChallengeSolution { signature } =
&mut *props.transport, expect_message(&mut *props.transport, |req: ClientRequest| {
|req: ClientRequest| match req.payload? { match req.payload? {
ClientRequestPayload::AuthChallengeSolution(s) => Some(s), ClientRequestPayload::AuthChallengeSolution(s) => Some(s),
_ => None, _ => None,
}, }
) })
.await .await
.map_err(|e| { .map_err(|e| {
error!(error = ?e, "Failed to receive challenge solution"); error!(error = ?e, "Failed to receive challenge solution");
Error::Transport Error::Transport
})?; })?;
let formatted = format_challenge(nonce, &challenge.pubkey); let formatted = format_challenge(nonce, &challenge.pubkey);
let sig = signature.as_slice().try_into().map_err(|_| { let sig = signature.as_slice().try_into().map_err(|_| {
@@ -196,9 +201,9 @@ async fn challenge_client(
fn connect_error_code(err: &Error) -> ConnectErrorCode { fn connect_error_code(err: &Error) -> ConnectErrorCode {
match err { match err {
Error::ApproveError(ApproveError::Denied) => ConnectErrorCode::ApprovalDenied, Error::ApproveError(ApproveError::Denied) => ConnectErrorCode::ApprovalDenied,
Error::ApproveError(ApproveError::Upstream(router::ApprovalError::NoUserAgentsConnected)) => { Error::ApproveError(ApproveError::Upstream(
ConnectErrorCode::NoUserAgentsOnline router::ApprovalError::NoUserAgentsConnected,
} )) => ConnectErrorCode::NoUserAgentsOnline,
_ => ConnectErrorCode::Unknown, _ => ConnectErrorCode::Unknown,
} }
} }
@@ -234,7 +239,7 @@ async fn authenticate(props: &mut ClientConnection) -> Result<VerifyingKey, Erro
pub async fn authenticate_and_create(mut props: ClientConnection) -> Result<ClientSession, Error> { pub async fn authenticate_and_create(mut props: ClientConnection) -> Result<ClientSession, Error> {
match authenticate(&mut props).await { match authenticate(&mut props).await {
Ok(pubkey) => Ok(ClientSession::new(props, pubkey)), Ok(_pubkey) => Ok(ClientSession::new(props)),
Err(err) => { Err(err) => {
let code = connect_error_code(&err); let code = connect_error_code(&err);
let _ = props let _ = props

View File

@@ -1,5 +1,4 @@
use arbiter_proto::proto::client::{ClientRequest, ClientResponse}; use arbiter_proto::proto::client::{ClientRequest, ClientResponse};
use ed25519_dalek::VerifyingKey;
use kameo::Actor; use kameo::Actor;
use tokio::select; use tokio::select;
use tracing::{error, info}; use tracing::{error, info};
@@ -10,12 +9,11 @@ use crate::{actors::{
pub struct ClientSession { pub struct ClientSession {
props: ClientConnection, props: ClientConnection,
key: VerifyingKey,
} }
impl ClientSession { impl ClientSession {
pub(crate) fn new(props: ClientConnection, key: VerifyingKey) -> Self { pub(crate) fn new(props: ClientConnection) -> Self {
Self { props, key } Self { props }
} }
pub async fn process_transport_inbound(&mut self, req: ClientRequest) -> Output { pub async fn process_transport_inbound(&mut self, req: ClientRequest) -> Output {
@@ -24,9 +22,8 @@ impl ClientSession {
ClientError::MissingRequestPayload ClientError::MissingRequestPayload
})?; })?;
match msg { let _ = msg;
_ => Err(ClientError::UnexpectedRequestPayload), Err(ClientError::UnexpectedRequestPayload)
}
} }
} }
@@ -92,7 +89,6 @@ impl ClientSession {
use arbiter_proto::transport::DummyTransport; use arbiter_proto::transport::DummyTransport;
let transport: super::Transport = Box::new(DummyTransport::new()); let transport: super::Transport = Box::new(DummyTransport::new());
let props = ClientConnection::new(db, transport, actors); let props = ClientConnection::new(db, transport, actors);
let key = VerifyingKey::from_bytes(&[0u8; 32]).unwrap(); Self { props }
Self { props, key }
} }
} }

View File

@@ -1,4 +1,4 @@
use alloy::{consensus::TxEip1559, network::TxSigner, primitives::Address, signers::Signature}; use alloy::{consensus::TxEip1559, primitives::Address, signers::Signature};
use diesel::{ExpressionMethods, OptionalExtension as _, QueryDsl, SelectableHelper as _, dsl::insert_into}; use diesel::{ExpressionMethods, OptionalExtension as _, QueryDsl, SelectableHelper as _, dsl::insert_into};
use diesel_async::RunQueryDsl; use diesel_async::RunQueryDsl;
use kameo::{Actor, actor::ActorRef, messages}; use kameo::{Actor, actor::ActorRef, messages};

View File

@@ -67,7 +67,7 @@ async fn request_client_approval(
client_pubkey: VerifyingKey, client_pubkey: VerifyingKey,
) -> Result<bool, ApprovalError> { ) -> Result<bool, ApprovalError> {
if user_agents.is_empty() { if user_agents.is_empty() {
return Err(ApprovalError::NoUserAgentsConnected).into(); return Err(ApprovalError::NoUserAgentsConnected);
} }
let mut pool = JoinSet::new(); let mut pool = JoinSet::new();
@@ -76,7 +76,6 @@ async fn request_client_approval(
for weak_ref in user_agents { for weak_ref in user_agents {
match weak_ref.upgrade() { match weak_ref.upgrade() {
Some(agent) => { Some(agent) => {
let client_pubkey = client_pubkey.clone();
let cancel_rx = cancel_rx.clone(); let cancel_rx = cancel_rx.clone();
pool.spawn(async move { pool.spawn(async move {
agent agent
@@ -167,7 +166,7 @@ impl MessageRouter {
// handle in subtask to not to lock the actor // handle in subtask to not to lock the actor
tokio::task::spawn(async move { tokio::task::spawn(async move {
let result = request_client_approval(&weak_refs, client_pubkey).await; let result = request_client_approval(&weak_refs, client_pubkey).await;
let _ = reply_sender.send(result); reply_sender.send(result);
}); });
reply reply

View File

@@ -117,7 +117,8 @@ async fn check_shared_constraints(
let now = Utc::now(); let now = Utc::now();
// Validity window // Validity window
if shared.valid_from.map_or(false, |t| now < t) || shared.valid_until.map_or(false, |t| now > t) if shared.valid_from.is_some_and(|t| now < t)
|| shared.valid_until.is_some_and(|t| now > t)
{ {
violations.push(EvalViolation::InvalidTime); violations.push(EvalViolation::InvalidTime);
} }
@@ -125,8 +126,8 @@ async fn check_shared_constraints(
// Gas fee caps // Gas fee caps
let fee_exceeded = shared let fee_exceeded = shared
.max_gas_fee_per_gas .max_gas_fee_per_gas
.map_or(false, |cap| U256::from(context.max_fee_per_gas) > cap); .is_some_and(|cap| U256::from(context.max_fee_per_gas) > cap);
let priority_exceeded = shared.max_priority_fee_per_gas.map_or(false, |cap| { let priority_exceeded = shared.max_priority_fee_per_gas.is_some_and(|cap| {
U256::from(context.max_priority_fee_per_gas) > cap U256::from(context.max_priority_fee_per_gas) > cap
}); });
if fee_exceeded || priority_exceeded { if fee_exceeded || priority_exceeded {
@@ -228,7 +229,7 @@ impl Engine {
.values(&NewEvmBasicGrant { .values(&NewEvmBasicGrant {
wallet_id: full_grant.basic.wallet_id, wallet_id: full_grant.basic.wallet_id,
chain_id: full_grant.basic.chain as i32, chain_id: full_grant.basic.chain as i32,
client_id: client_id, client_id,
valid_from: full_grant.basic.valid_from.map(SqliteTimestamp), valid_from: full_grant.basic.valid_from.map(SqliteTimestamp),
valid_until: full_grant.basic.valid_until.map(SqliteTimestamp), valid_until: full_grant.basic.valid_until.map(SqliteTimestamp),
max_gas_fee_per_gas: full_grant max_gas_fee_per_gas: full_grant

View File

@@ -41,17 +41,12 @@ pub struct Meaning {
} }
impl Display for Meaning { impl Display for Meaning {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!( write!(f, "Ether transfer of {} to {}", self.value, self.to)
f,
"Ether transfer of {} to {}",
self.value,
self.to.to_string()
)
} }
} }
impl Into<SpecificMeaning> for Meaning { impl From<Meaning> for SpecificMeaning {
fn into(self) -> SpecificMeaning { fn from(val: Meaning) -> SpecificMeaning {
SpecificMeaning::EtherTransfer(self) SpecificMeaning::EtherTransfer(val)
} }
} }
@@ -61,9 +56,9 @@ pub struct Settings {
limit: VolumeRateLimit, limit: VolumeRateLimit,
} }
impl Into<SpecificGrant> for Settings { impl From<Settings> for SpecificGrant {
fn into(self) -> SpecificGrant { fn from(val: Settings) -> SpecificGrant {
SpecificGrant::EtherTransfer(self) SpecificGrant::EtherTransfer(val)
} }
} }

View File

@@ -51,9 +51,9 @@ impl std::fmt::Display for Meaning {
) )
} }
} }
impl Into<SpecificMeaning> for Meaning { impl From<Meaning> for SpecificMeaning {
fn into(self) -> SpecificMeaning { fn from(val: Meaning) -> SpecificMeaning {
SpecificMeaning::TokenTransfer(self) SpecificMeaning::TokenTransfer(val)
} }
} }
@@ -63,9 +63,9 @@ pub struct Settings {
target: Option<Address>, target: Option<Address>,
volume_limits: Vec<VolumeRateLimit>, volume_limits: Vec<VolumeRateLimit>,
} }
impl Into<SpecificGrant> for Settings { impl From<Settings> for SpecificGrant {
fn into(self) -> SpecificGrant { fn from(val: Settings) -> SpecificGrant {
SpecificGrant::TokenTransfer(self) SpecificGrant::TokenTransfer(val)
} }
} }
@@ -156,10 +156,10 @@ impl Policy for TokenTransfer {
return Ok(violations); return Ok(violations);
} }
if let Some(allowed) = grant.settings.target { if let Some(allowed) = grant.settings.target
if allowed != meaning.to { && allowed != meaning.to
violations.push(EvalViolation::InvalidTarget { target: meaning.to }); {
} violations.push(EvalViolation::InvalidTarget { target: meaning.to });
} }
let rate_violations = check_volume_rate_limits(grant, db).await?; let rate_violations = check_volume_rate_limits(grant, db).await?;

View File

@@ -94,13 +94,13 @@ impl SafeSigner {
&self, &self,
tx: &mut dyn SignableTransaction<Signature>, tx: &mut dyn SignableTransaction<Signature>,
) -> Result<Signature> { ) -> Result<Signature> {
if let Some(chain_id) = self.chain_id { if let Some(chain_id) = self.chain_id
if !tx.set_chain_id_checked(chain_id) { && !tx.set_chain_id_checked(chain_id)
return Err(Error::TransactionChainIdMismatch { {
signer: chain_id, return Err(Error::TransactionChainIdMismatch {
tx: tx.chain_id().unwrap(), signer: chain_id,
}); tx: tx.chain_id().unwrap(),
} });
} }
self.sign_hash_inner(&tx.signature_hash()).map_err(Error::other) self.sign_hash_inner(&tx.signature_hash()).map_err(Error::other)
} }

View File

@@ -9,7 +9,6 @@ use diesel_async::RunQueryDsl;
use memsafe::MemSafe; use memsafe::MemSafe;
use tokio::sync::mpsc; use tokio::sync::mpsc;
#[allow(dead_code)] #[allow(dead_code)]
pub async fn bootstrapped_keyholder(db: &db::DatabasePool) -> KeyHolder { pub async fn bootstrapped_keyholder(db: &db::DatabasePool) -> KeyHolder {
let mut actor = KeyHolder::new(db.clone()).await.unwrap(); let mut actor = KeyHolder::new(db.clone()).await.unwrap();
@@ -31,13 +30,14 @@ pub async fn root_key_history_id(db: &db::DatabasePool) -> i32 {
id.expect("root_key_id should be set after bootstrap") id.expect("root_key_id should be set after bootstrap")
} }
#[allow(dead_code)]
pub struct ChannelTransport<T, Y> { pub struct ChannelTransport<T, Y> {
receiver: mpsc::Receiver<T>, receiver: mpsc::Receiver<T>,
sender: mpsc::Sender<Y>, sender: mpsc::Sender<Y>,
} }
impl<T, Y> ChannelTransport<T, Y> { impl<T, Y> ChannelTransport<T, Y> {
#[allow(dead_code)]
pub fn new() -> (Self, ChannelTransport<Y, T>) { pub fn new() -> (Self, ChannelTransport<Y, T>) {
let (tx1, rx1) = mpsc::channel(10); let (tx1, rx1) = mpsc::channel(10);
let (tx2, rx2) = mpsc::channel(10); let (tx2, rx2) = mpsc::channel(10);
@@ -54,8 +54,6 @@ impl<T, Y> ChannelTransport<T, Y> {
} }
} }
#[async_trait] #[async_trait]
impl<T, Y> Bi<T, Y> for ChannelTransport<T, Y> impl<T, Y> Bi<T, Y> for ChannelTransport<T, Y>
where where