From f240edce421aeea1d66071e0a68c6c5d82ee6919 Mon Sep 17 00:00:00 2001 From: Vid Kersic Date: Sat, 14 Jan 2023 10:42:24 +0100 Subject: [PATCH 1/4] feat: implement rpc endpoint send_userUserOperation --- Cargo.lock | 1 + Cargo.toml | 1 + bin/bundler-rpc.rs | 11 +++- bin/bundler.rs | 8 +++ src/proto/uopool/uopool.proto | 5 +- src/rpc/eth.rs | 42 ++++++++---- src/rpc/eth_api.rs | 10 ++- src/uopool/mod.rs | 4 +- src/uopool/server.rs | 116 +++++++++++++++++++++++++++++++++- src/uopool/services/uopool.rs | 35 +++++++--- 10 files changed, 203 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 84e714ce..cbb113d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,7 @@ name = "aa-bundler" version = "0.1.0" dependencies = [ "anyhow", + "arrayref", "async-trait", "clap", "dirs", diff --git a/Cargo.toml b/Cargo.toml index 6893c3c6..8a62cabb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ rust-version = "1.66.1" [dependencies] anyhow = "1" +arrayref = "0.3" async-trait = "0.1" clap = { version = "4", features = ["derive"] } dirs = "4.0" diff --git a/bin/bundler-rpc.rs b/bin/bundler-rpc.rs index 9847cbb1..b30718f8 100644 --- a/bin/bundler-rpc.rs +++ b/bin/bundler-rpc.rs @@ -3,7 +3,10 @@ use clap::Parser; use jsonrpsee::{core::server::rpc_module::Methods, server::ServerBuilder, tracing::info}; use std::future::pending; -use aa_bundler::rpc::{eth::EthApiServerImpl, eth_api::EthApiServer}; +use aa_bundler::{ + rpc::{eth::EthApiServerImpl, eth_api::EthApiServer}, + uopool::server::uopool::uo_pool_client::UoPoolClient, +}; #[derive(Parser)] #[clap( @@ -13,6 +16,9 @@ use aa_bundler::rpc::{eth::EthApiServerImpl, eth_api::EthApiServer}; pub struct Opt { #[clap(long, default_value = "127.0.0.1:4337")] pub rpc_listen_address: String, + + #[clap(long, default_value = "127.0.0.1:3001")] + pub uopool_grpc_listen_address: String, } #[tokio::main] @@ -26,9 +32,12 @@ async fn main() -> Result<()> { .await?; let mut api = Methods::new(); + let uopool_grpc_client = + UoPoolClient::connect(format!("http://{}", opt.uopool_grpc_listen_address)).await?; api.merge( EthApiServerImpl { call_gas_limit: 100_000_000, + uopool_grpc_client, } .into_rpc(), ) diff --git a/bin/bundler.rs b/bin/bundler.rs index 7a987616..6f56b01d 100644 --- a/bin/bundler.rs +++ b/bin/bundler.rs @@ -2,6 +2,7 @@ use aa_bundler::{ bundler::Bundler, models::wallet::Wallet, rpc::{eth::EthApiServerImpl, eth_api::EthApiServer}, + uopool::server::uopool::uo_pool_client::UoPoolClient, utils::{parse_address, parse_u256}, }; use anyhow::Result; @@ -81,9 +82,16 @@ fn main() -> Result<()> { .unwrap(); let mut api = Methods::new(); + let uopool_grpc_client = UoPoolClient::connect(format!( + "http://{}", + opt.uopool_opts.uopool_grpc_listen_address + )) + .await + .unwrap(); api.merge( EthApiServerImpl { call_gas_limit: 100_000_000, + uopool_grpc_client, } .into_rpc(), ) diff --git a/src/proto/uopool/uopool.proto b/src/proto/uopool/uopool.proto index 9b96b79c..41f03d81 100644 --- a/src/proto/uopool/uopool.proto +++ b/src/proto/uopool/uopool.proto @@ -7,7 +7,6 @@ package uopool; message AddRequest { types.UserOperation uo = 1; types.H160 ep = 2; - uint64 cid = 3; } enum AddResult { @@ -17,7 +16,7 @@ enum AddResult { message AddResponse { AddResult result = 1; - string error = 2; + string data = 2; } message RemoveRequest { @@ -31,7 +30,7 @@ enum RemoveResult { message RemoveResponse { RemoveResult result = 1; - string error = 2; + string data = 2; } message AllRequest {} diff --git a/src/rpc/eth.rs b/src/rpc/eth.rs index b35c3b54..7f8f870b 100644 --- a/src/rpc/eth.rs +++ b/src/rpc/eth.rs @@ -1,6 +1,7 @@ use crate::{ rpc::eth_api::{EstimateUserOperationGasResponse, EthApiServer}, types::user_operation::{UserOperation, UserOperationHash, UserOperationReceipt}, + uopool::server::uopool::{uo_pool_client::UoPoolClient, AddRequest}, }; use async_trait::async_trait; use ethers::types::{Address, U256, U64}; @@ -13,8 +14,11 @@ use jsonrpsee::{ }, }; +use super::eth_api::SendUserOperationResponse; + pub struct EthApiServerImpl { pub call_gas_limit: u64, + pub uopool_grpc_client: UoPoolClient, } #[async_trait] @@ -31,18 +35,34 @@ impl EthApiServer for EthApiServerImpl { &self, user_operation: UserOperation, entry_point: Address, - ) -> RpcResult { - info!("{:?}", user_operation); + ) -> RpcResult { info!("{:?}", entry_point); - // Ok(SendUserOperationResponse::Success(H256::default())) - let data = serde_json::value::to_raw_value(&"{\"a\": 100, \"b\": 200}").unwrap(); - Err(jsonrpsee::core::Error::Call(CallError::Custom( - ErrorObject::owned( - ErrorCode::ServerError(-32000).code(), - "Not implemented", - Some(data), - ), - ))) + info!("{:?}", user_operation); + + let mut uopool_grpc_client = self.uopool_grpc_client.clone(); + + let request = tonic::Request::new(AddRequest { + uo: Some(user_operation.into()), + ep: Some(entry_point.into()), + }); + + let response = uopool_grpc_client + .add(request) + .await + .map_err(|status| { + jsonrpsee::core::Error::Call(CallError::Custom(ErrorObject::owned( + ErrorCode::InternalError.code(), + status.message(), + Some(status.details()), + ))) + })? + .into_inner(); + + info!("{:?}", response.data); + + Ok(SendUserOperationResponse::Success( + UserOperationHash::default(), + )) } async fn estimate_user_operation_gas( diff --git a/src/rpc/eth_api.rs b/src/rpc/eth_api.rs index 9a5d59a2..1afb8bbe 100644 --- a/src/rpc/eth_api.rs +++ b/src/rpc/eth_api.rs @@ -1,9 +1,15 @@ use ethers::types::{Address, U256, U64}; -use jsonrpsee::{core::RpcResult, proc_macros::rpc}; +use jsonrpsee::{core::RpcResult, proc_macros::rpc, types::ErrorObject}; use serde::{Deserialize, Serialize}; use crate::types::user_operation::{UserOperation, UserOperationHash, UserOperationReceipt}; +#[derive(Serialize, Deserialize)] +pub enum SendUserOperationResponse { + Success(UserOperationHash), + Failure(ErrorObject<'static>), +} + #[derive(Serialize, Deserialize)] pub struct EstimateUserOperationGasResponse { pub pre_verification_gas: U256, @@ -22,7 +28,7 @@ pub trait EthApi { &self, user_operation: UserOperation, entry_point: Address, - ) -> RpcResult; + ) -> RpcResult; #[method(name = "estimateUserOperationGas")] async fn estimate_user_operation_gas( &self, diff --git a/src/uopool/mod.rs b/src/uopool/mod.rs index a05d1d7a..2d0c44f2 100644 --- a/src/uopool/mod.rs +++ b/src/uopool/mod.rs @@ -1,7 +1,7 @@ use crate::{ types::user_operation::{UserOperation, UserOperationHash}, uopool::{ - memory::MemoryMempool, server::uopool_server::uo_pool_server::UoPoolServer, + memory::MemoryMempool, server::uopool::uo_pool_server::UoPoolServer, services::UoPoolService, }, }; @@ -53,7 +53,7 @@ pub struct UserOperationPool { pub pool: Arc, } -#[derive(Educe, Parser)] +#[derive(Clone, Copy, Educe, Parser)] #[educe(Debug)] pub struct UoPoolOpts { #[clap(long, default_value = "127.0.0.1:3001")] diff --git a/src/uopool/server.rs b/src/uopool/server.rs index 823dd49a..e4e2ec65 100644 --- a/src/uopool/server.rs +++ b/src/uopool/server.rs @@ -1,7 +1,119 @@ -mod types { +// https://github.com/ledgerwatch/interfaces/blob/master/src/lib.rs#L1 +pub mod types { + use arrayref::array_ref; + use ethers::types::{Address, Bytes, U256}; + tonic::include_proto!("types"); + + impl From for H128 { + fn from(value: ethers::types::H128) -> Self { + Self { + hi: u64::from_be_bytes(*array_ref!(value, 0, 8)), + lo: u64::from_be_bytes(*array_ref!(value, 8, 8)), + } + } + } + + impl From for H160 { + fn from(value: ethers::types::H160) -> Self { + Self { + hi: Some(ethers::types::H128::from_slice(&value[..16]).into()), + lo: u32::from_be_bytes(*array_ref!(value, 16, 4)), + } + } + } + + impl From for H256 { + fn from(value: ethers::types::H256) -> Self { + Self { + hi: Some(ethers::types::H128::from_slice(&value[..16]).into()), + lo: Some(ethers::types::H128::from_slice(&value[16..]).into()), + } + } + } + + impl From for ethers::types::H128 { + fn from(value: H128) -> Self { + let mut v = [0; Self::len_bytes()]; + v[..8].copy_from_slice(&value.hi.to_be_bytes()); + v[8..].copy_from_slice(&value.lo.to_be_bytes()); + + v.into() + } + } + + impl From for ethers::types::H160 { + fn from(value: H160) -> Self { + type H = ethers::types::H128; + + let mut v = [0; Self::len_bytes()]; + v[..H::len_bytes()] + .copy_from_slice(H::from(value.hi.unwrap_or_default()).as_fixed_bytes()); + v[H::len_bytes()..].copy_from_slice(&value.lo.to_be_bytes()); + + v.into() + } + } + + impl From for ethers::types::H256 { + fn from(value: H256) -> Self { + type H = ethers::types::H128; + + let mut v = [0; Self::len_bytes()]; + v[..H::len_bytes()] + .copy_from_slice(H::from(value.hi.unwrap_or_default()).as_fixed_bytes()); + v[H::len_bytes()..] + .copy_from_slice(H::from(value.lo.unwrap_or_default()).as_fixed_bytes()); + + v.into() + } + } + + impl From for UserOperation { + fn from(user_operation: crate::types::user_operation::UserOperation) -> Self { + Self { + sender: Some(user_operation.sender.into()), + nonce: user_operation.nonce.as_u64(), + init_code: prost::bytes::Bytes::copy_from_slice(user_operation.init_code.as_ref()), + call_data: prost::bytes::Bytes::copy_from_slice(user_operation.call_data.as_ref()), + call_gas_limit: user_operation.call_gas_limit.as_u64(), + verification_gas_limit: user_operation.verification_gas_limit.as_u64(), + pre_verification_gas: user_operation.pre_verification_gas.as_u64(), + max_fee_per_gas: user_operation.max_fee_per_gas.as_u64(), + max_priority_fee_per_gas: user_operation.max_priority_fee_per_gas.as_u64(), + paymaster_and_data: prost::bytes::Bytes::copy_from_slice( + user_operation.paymaster_and_data.as_ref(), + ), + signature: prost::bytes::Bytes::copy_from_slice(user_operation.signature.as_ref()), + } + } + } + + impl From for crate::types::user_operation::UserOperation { + fn from(user_operation: UserOperation) -> Self { + Self { + sender: { + if let Some(sender) = user_operation.sender { + sender.into() + } else { + Address::zero() + } + }, + nonce: U256::from(user_operation.nonce), + init_code: Bytes::from(user_operation.init_code), + call_data: Bytes::from(user_operation.call_data), + call_gas_limit: U256::from(user_operation.call_gas_limit), + verification_gas_limit: U256::from(user_operation.verification_gas_limit), + pre_verification_gas: U256::from(user_operation.pre_verification_gas), + max_fee_per_gas: U256::from(user_operation.max_fee_per_gas), + max_priority_fee_per_gas: U256::from(user_operation.max_priority_fee_per_gas), + paymaster_and_data: Bytes::from(user_operation.paymaster_and_data), + signature: Bytes::from(user_operation.signature), + } + } + } } -pub mod uopool_server { +pub mod uopool { tonic::include_proto!("uopool"); } diff --git a/src/uopool/services/uopool.rs b/src/uopool/services/uopool.rs index 0c5cd8a2..407a3c7c 100644 --- a/src/uopool/services/uopool.rs +++ b/src/uopool/services/uopool.rs @@ -1,17 +1,17 @@ -use std::{collections::HashMap, sync::Arc}; - use crate::{ types::user_operation::UserOperation, uopool::{ - server::uopool_server::{ - uo_pool_server::UoPool, AddRequest, AddResponse, AllRequest, AllResponse, + server::uopool::{ + uo_pool_server::UoPool, AddRequest, AddResponse, AddResult, AllRequest, AllResponse, RemoveRequest, RemoveResponse, }, MempoolBox, MempoolId, }, }; use async_trait::async_trait; +use jsonrpsee::tracing::info; use parking_lot::RwLock; +use std::{collections::HashMap, sync::Arc}; use tonic::Response; pub struct UoPoolService { @@ -30,12 +30,29 @@ impl UoPoolService { impl UoPool for UoPoolService { async fn add( &self, - _request: tonic::Request, + request: tonic::Request, ) -> Result, tonic::Status> { - // let req = request.into_inner(); - // TODO: sanity checks - // TODO: simulation - Err(tonic::Status::unimplemented("todo")) + let req = request.into_inner(); + let mut res = AddResponse::default(); + + if let Some(user_operation) = req.uo { + let user_operation: UserOperation = user_operation + .try_into() + .map_err(|_| tonic::Status::invalid_argument("user operation is not valid"))?; + + info!("{:?}", user_operation); + + // TODO: validate user operation + // TODO: sanity checks + // TODO: simulation + + res.set_result(AddResult::NotAdded); + res.data = String::from("\"{\"code\": -32602, \"message\": \"user operation was not added\", \"data\": {\"reason\": \"this is error\"}}\""); + + return Ok(tonic::Response::new(res)); + } + + Err(tonic::Status::invalid_argument("user operation is missing")) } async fn remove( From f69fa71ae2ec097749dd7fa9820f010bd4d1eb55 Mon Sep 17 00:00:00 2001 From: Vid Kersic Date: Sat, 14 Jan 2023 19:18:54 +0100 Subject: [PATCH 2/4] chore: fix result format for eth_sendUserOperation --- src/rpc/eth.rs | 34 ++++++++++++++++++++++++++-------- src/rpc/eth_api.rs | 10 ++-------- src/uopool/server.rs | 2 +- src/uopool/services/uopool.rs | 16 ++++++++++++++-- 4 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/rpc/eth.rs b/src/rpc/eth.rs index 7f8f870b..54ecd732 100644 --- a/src/rpc/eth.rs +++ b/src/rpc/eth.rs @@ -1,7 +1,9 @@ +use std::str::FromStr; + use crate::{ rpc::eth_api::{EstimateUserOperationGasResponse, EthApiServer}, types::user_operation::{UserOperation, UserOperationHash, UserOperationReceipt}, - uopool::server::uopool::{uo_pool_client::UoPoolClient, AddRequest}, + uopool::server::uopool::{uo_pool_client::UoPoolClient, AddRequest, AddResult}, }; use async_trait::async_trait; use ethers::types::{Address, U256, U64}; @@ -14,8 +16,6 @@ use jsonrpsee::{ }, }; -use super::eth_api::SendUserOperationResponse; - pub struct EthApiServerImpl { pub call_gas_limit: u64, pub uopool_grpc_client: UoPoolClient, @@ -35,7 +35,7 @@ impl EthApiServer for EthApiServerImpl { &self, user_operation: UserOperation, entry_point: Address, - ) -> RpcResult { + ) -> RpcResult { info!("{:?}", entry_point); info!("{:?}", user_operation); @@ -58,11 +58,29 @@ impl EthApiServer for EthApiServerImpl { })? .into_inner(); - info!("{:?}", response.data); + if response.result == AddResult::Added as i32 { + return UserOperationHash::from_str(&response.data).map_err(|err| { + jsonrpsee::core::Error::Call(CallError::Custom(ErrorObject::owned( + ErrorCode::InternalError.code(), + "user operation was not added", + Some(err.to_string()), + ))) + }); + } - Ok(SendUserOperationResponse::Success( - UserOperationHash::default(), - )) + serde_json::from_str(&response.data) + .map_err(|err| { + jsonrpsee::core::Error::Call(CallError::Custom(ErrorObject::owned( + ErrorCode::InternalError.code(), + "error parsing error object", + Some(err.to_string()), + ))) + }) + .and_then(|error_object| { + return Err(jsonrpsee::core::Error::Call(CallError::Custom( + error_object, + ))); + }) } async fn estimate_user_operation_gas( diff --git a/src/rpc/eth_api.rs b/src/rpc/eth_api.rs index 1afb8bbe..9a5d59a2 100644 --- a/src/rpc/eth_api.rs +++ b/src/rpc/eth_api.rs @@ -1,15 +1,9 @@ use ethers::types::{Address, U256, U64}; -use jsonrpsee::{core::RpcResult, proc_macros::rpc, types::ErrorObject}; +use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use serde::{Deserialize, Serialize}; use crate::types::user_operation::{UserOperation, UserOperationHash, UserOperationReceipt}; -#[derive(Serialize, Deserialize)] -pub enum SendUserOperationResponse { - Success(UserOperationHash), - Failure(ErrorObject<'static>), -} - #[derive(Serialize, Deserialize)] pub struct EstimateUserOperationGasResponse { pub pre_verification_gas: U256, @@ -28,7 +22,7 @@ pub trait EthApi { &self, user_operation: UserOperation, entry_point: Address, - ) -> RpcResult; + ) -> RpcResult; #[method(name = "estimateUserOperationGas")] async fn estimate_user_operation_gas( &self, diff --git a/src/uopool/server.rs b/src/uopool/server.rs index e4e2ec65..b817eeec 100644 --- a/src/uopool/server.rs +++ b/src/uopool/server.rs @@ -1,4 +1,4 @@ -// https://github.com/ledgerwatch/interfaces/blob/master/src/lib.rs#L1 +// Code adapted from: https://github.com/ledgerwatch/interfaces/blob/master/src/lib.rs#L1 pub mod types { use arrayref::array_ref; use ethers::types::{Address, Bytes, U256}; diff --git a/src/uopool/services/uopool.rs b/src/uopool/services/uopool.rs index 407a3c7c..9abb129e 100644 --- a/src/uopool/services/uopool.rs +++ b/src/uopool/services/uopool.rs @@ -9,11 +9,14 @@ use crate::{ }, }; use async_trait::async_trait; -use jsonrpsee::tracing::info; +use jsonrpsee::{tracing::info, types::ErrorObject}; use parking_lot::RwLock; +use serde_json::json; use std::{collections::HashMap, sync::Arc}; use tonic::Response; +pub type UoPoolError = ErrorObject<'static>; + pub struct UoPoolService { _mempools: Arc>>>>, } @@ -46,8 +49,17 @@ impl UoPool for UoPoolService { // TODO: sanity checks // TODO: simulation + let uo_pool_error = UoPoolError::owned( + -32602, + "user operation was not added", + Some(json!({ + "reason": "this is error", + })), + ); + res.set_result(AddResult::NotAdded); - res.data = String::from("\"{\"code\": -32602, \"message\": \"user operation was not added\", \"data\": {\"reason\": \"this is error\"}}\""); + res.data = serde_json::to_string(&uo_pool_error) + .map_err(|_| tonic::Status::cancelled("user operation was not added"))?; return Ok(tonic::Response::new(res)); } From 8b9819282befa305ac4e7c892560b8c334e28972 Mon Sep 17 00:00:00 2001 From: Vid Kersic Date: Sat, 14 Jan 2023 19:25:39 +0100 Subject: [PATCH 3/4] chore: format and lint --- src/rpc/eth.rs | 4 ++-- src/uopool/server.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rpc/eth.rs b/src/rpc/eth.rs index 54ecd732..303a505c 100644 --- a/src/rpc/eth.rs +++ b/src/rpc/eth.rs @@ -77,9 +77,9 @@ impl EthApiServer for EthApiServerImpl { ))) }) .and_then(|error_object| { - return Err(jsonrpsee::core::Error::Call(CallError::Custom( + Err(jsonrpsee::core::Error::Call(CallError::Custom( error_object, - ))); + ))) }) } diff --git a/src/uopool/server.rs b/src/uopool/server.rs index b817eeec..bfb30b80 100644 --- a/src/uopool/server.rs +++ b/src/uopool/server.rs @@ -88,7 +88,7 @@ pub mod types { } } } - + impl From for crate::types::user_operation::UserOperation { fn from(user_operation: UserOperation) -> Self { Self { From 7d995c46f1b5c67f22f480cc268b95c79a6af5fc Mon Sep 17 00:00:00 2001 From: Vid Kersic Date: Sun, 15 Jan 2023 18:22:02 +0100 Subject: [PATCH 4/4] chore: simplify error handling --- src/rpc/eth.rs | 44 +++++++++-------------------------- src/uopool/services/uopool.rs | 6 ++--- 2 files changed, 14 insertions(+), 36 deletions(-) diff --git a/src/rpc/eth.rs b/src/rpc/eth.rs index 303a505c..756e0c3b 100644 --- a/src/rpc/eth.rs +++ b/src/rpc/eth.rs @@ -1,20 +1,17 @@ -use std::str::FromStr; - use crate::{ rpc::eth_api::{EstimateUserOperationGasResponse, EthApiServer}, types::user_operation::{UserOperation, UserOperationHash, UserOperationReceipt}, uopool::server::uopool::{uo_pool_client::UoPoolClient, AddRequest, AddResult}, }; +use anyhow::format_err; use async_trait::async_trait; use ethers::types::{Address, U256, U64}; use jsonrpsee::{ core::RpcResult, tracing::info, - types::{ - error::{CallError, ErrorCode}, - ErrorObject, - }, + types::{error::CallError, ErrorObject}, }; +use std::str::FromStr; pub struct EthApiServerImpl { pub call_gas_limit: u64, @@ -49,38 +46,19 @@ impl EthApiServer for EthApiServerImpl { let response = uopool_grpc_client .add(request) .await - .map_err(|status| { - jsonrpsee::core::Error::Call(CallError::Custom(ErrorObject::owned( - ErrorCode::InternalError.code(), - status.message(), - Some(status.details()), - ))) - })? + .map_err(|status| format_err!("GRPC error (uopool): {}", status.message()))? .into_inner(); if response.result == AddResult::Added as i32 { - return UserOperationHash::from_str(&response.data).map_err(|err| { - jsonrpsee::core::Error::Call(CallError::Custom(ErrorObject::owned( - ErrorCode::InternalError.code(), - "user operation was not added", - Some(err.to_string()), - ))) - }); + let user_operation_hash = UserOperationHash::from_str(&response.data) + .map_err(|err| format_err!("error parsing user operation hash: {}", err))?; + return Ok(user_operation_hash); } - serde_json::from_str(&response.data) - .map_err(|err| { - jsonrpsee::core::Error::Call(CallError::Custom(ErrorObject::owned( - ErrorCode::InternalError.code(), - "error parsing error object", - Some(err.to_string()), - ))) - }) - .and_then(|error_object| { - Err(jsonrpsee::core::Error::Call(CallError::Custom( - error_object, - ))) - }) + Err(jsonrpsee::core::Error::Call(CallError::Custom( + serde_json::from_str::(&response.data) + .map_err(|err| format_err!("error parsing error object: {}", err))?, + ))) } async fn estimate_user_operation_gas( diff --git a/src/uopool/services/uopool.rs b/src/uopool/services/uopool.rs index 9abb129e..d4c77679 100644 --- a/src/uopool/services/uopool.rs +++ b/src/uopool/services/uopool.rs @@ -41,7 +41,7 @@ impl UoPool for UoPoolService { if let Some(user_operation) = req.uo { let user_operation: UserOperation = user_operation .try_into() - .map_err(|_| tonic::Status::invalid_argument("user operation is not valid"))?; + .map_err(|_| tonic::Status::invalid_argument("invalid user operation"))?; info!("{:?}", user_operation); @@ -59,12 +59,12 @@ impl UoPool for UoPoolService { res.set_result(AddResult::NotAdded); res.data = serde_json::to_string(&uo_pool_error) - .map_err(|_| tonic::Status::cancelled("user operation was not added"))?; + .map_err(|_| tonic::Status::internal("error adding user operation"))?; return Ok(tonic::Response::new(res)); } - Err(tonic::Status::invalid_argument("user operation is missing")) + Err(tonic::Status::invalid_argument("missing user operation")) } async fn remove(