Cow instead of String

This commit is contained in:
Bryan Stitt 2023-05-30 23:17:05 -07:00
parent f1636d3b85
commit d64761403b
13 changed files with 108 additions and 90 deletions

@ -29,18 +29,16 @@ pub async fn query_admin_modify_usertier<'a>(
let user_address: Vec<u8> = params
.get("user_address")
.ok_or_else(|| {
Web3ProxyError::BadRequest("Unable to find user_address key in request".to_string())
Web3ProxyError::BadRequest("Unable to find user_address key in request".into())
})?
.parse::<Address>()
.map_err(|_| {
Web3ProxyError::BadRequest("Unable to parse user_address as an Address".to_string())
Web3ProxyError::BadRequest("Unable to parse user_address as an Address".into())
})?
.to_fixed_bytes()
.into();
let user_tier_title = params.get("user_tier_title").ok_or_else(|| {
Web3ProxyError::BadRequest(
"Unable to get the user_tier_title key from the request".to_string(),
)
Web3ProxyError::BadRequest("Unable to get the user_tier_title key from the request".into())
})?;
// Prepare output body
@ -84,7 +82,7 @@ pub async fn query_admin_modify_usertier<'a>(
.one(&db_conn)
.await?
.ok_or(Web3ProxyError::BadRequest(
"No user with this id found".to_string(),
"No user with this id found".into(),
))?;
// Return early if the target user_tier_id is the same as the original user_tier_id
response_body.insert(
@ -98,7 +96,7 @@ pub async fn query_admin_modify_usertier<'a>(
.one(&db_conn)
.await?
.ok_or(Web3ProxyError::BadRequest(
"User Tier name was not found".to_string(),
"User Tier name was not found".into(),
))?;
if user.user_tier_id == new_user_tier.id {

@ -739,6 +739,13 @@ impl Web3ProxyApp {
self.watch_consensus_head_receiver.clone()
}
/// an ethers provider that you can use with ether's abigen.
/// this works for now, but I don't like it
/// TODO: I would much prefer we figure out the traits and `impl JsonRpcClient for Web3ProxyApp`
pub fn internal_provider(&self) -> &Arc<EthersHttpProvider> {
&self.internal_provider
}
pub async fn prometheus_metrics(&self) -> String {
let globals = HashMap::new();
// TODO: what globals? should this be the hostname or what?
@ -1417,19 +1424,19 @@ impl Web3ProxyApp {
.as_array()
.ok_or_else(|| {
Web3ProxyError::BadRequest(
"Unable to get array from params".to_string(),
"Unable to get array from params".into(),
)
})?
.get(0)
.ok_or_else(|| {
Web3ProxyError::BadRequest(
"Unable to get item 0 from params".to_string(),
"Unable to get item 0 from params".into(),
)
})?
.as_str()
.ok_or_else(|| {
Web3ProxyError::BadRequest(
"Unable to get string from params item 0".to_string(),
"Unable to get string from params item 0".into(),
)
})?;
@ -1546,7 +1553,7 @@ impl Web3ProxyApp {
.map_err(|x| {
trace!("bad request: {:?}", x);
Web3ProxyError::BadRequest(
"param 0 could not be read as H256".to_string(),
"param 0 could not be read as H256".into(),
)
})?;

@ -174,10 +174,10 @@ pub async fn block_needed(
// TODO: jsonrpc has a specific code for this
let obj = params
.get_mut(0)
.ok_or_else(|| Web3ProxyError::BadRequest("invalid format. no params".to_string()))?
.ok_or_else(|| Web3ProxyError::BadRequest("invalid format. no params".into()))?
.as_object_mut()
.ok_or_else(|| {
Web3ProxyError::BadRequest("invalid format. params not object".to_string())
Web3ProxyError::BadRequest("invalid format. params not object".into())
})?;
if obj.contains_key("blockHash") {

@ -41,7 +41,7 @@ pub enum Web3ProxyError {
Anyhow(anyhow::Error),
#[error(ignore)]
#[from(ignore)]
BadRequest(String),
BadRequest(Cow<'static, str>),
#[error(ignore)]
#[from(ignore)]
BadResponse(String),

@ -67,32 +67,30 @@ pub async fn admin_increase_balance(
let user_address: Address = params
.get("user_address")
.ok_or_else(|| {
Web3ProxyError::BadRequest("Unable to find user_address key in request".to_string())
Web3ProxyError::BadRequest("Unable to find user_address key in request".into())
})?
.parse::<Address>()
.map_err(|_| {
Web3ProxyError::BadRequest("Unable to parse user_address as an Address".to_string())
Web3ProxyError::BadRequest("Unable to parse user_address as an Address".into())
})?;
let user_address_bytes: Vec<u8> = user_address.to_fixed_bytes().into();
let note: String = params
.get("note")
.ok_or_else(|| {
Web3ProxyError::BadRequest("Unable to find 'note' key in request".to_string())
})?
.ok_or_else(|| Web3ProxyError::BadRequest("Unable to find 'note' key in request".into()))?
.parse::<String>()
.map_err(|_| {
Web3ProxyError::BadRequest("Unable to parse 'note' as a String".to_string())
})?;
.map_err(|_| Web3ProxyError::BadRequest("Unable to parse 'note' as a String".into()))?;
// Get the amount from params
// Decimal::from_str
let amount: Decimal = params
.get("amount")
.ok_or_else(|| {
Web3ProxyError::BadRequest("Unable to get the amount key from the request".to_string())
Web3ProxyError::BadRequest("Unable to get the amount key from the request".into())
})
.map(|x| Decimal::from_str(x))?
.map_err(|err| {
Web3ProxyError::BadRequest(format!("Unable to parse amount from the request {:?}", err))
Web3ProxyError::BadRequest(
format!("Unable to parse amount from the request {:?}", err).into(),
)
})?;
let user_entry: user::Model = user::Entity::find()
@ -100,7 +98,7 @@ pub async fn admin_increase_balance(
.one(&db_conn)
.await?
.ok_or(Web3ProxyError::BadRequest(
"No user with this id found".to_string(),
"No user with this id found".into(),
))?;
let increase_balance_receipt = admin_increase_balance_receipt::ActiveModel {
@ -211,22 +209,22 @@ pub async fn admin_login_get(
let admin_address: Address = params
.get("admin_address")
.ok_or_else(|| {
Web3ProxyError::BadRequest("Unable to find admin_address key in request".to_string())
Web3ProxyError::BadRequest("Unable to find admin_address key in request".into())
})?
.parse::<Address>()
.map_err(|_err| {
Web3ProxyError::BadRequest("Unable to parse admin_address as an Address".to_string())
Web3ProxyError::BadRequest("Unable to parse admin_address as an Address".into())
})?;
// Fetch the user_address parameter from the login string ... (as who we want to be logging in ...)
let user_address: Vec<u8> = params
.get("user_address")
.ok_or_else(|| {
Web3ProxyError::BadRequest("Unable to find user_address key in request".to_string())
Web3ProxyError::BadRequest("Unable to find user_address key in request".into())
})?
.parse::<Address>()
.map_err(|_err| {
Web3ProxyError::BadRequest("Unable to parse user_address as an Address".to_string())
Web3ProxyError::BadRequest("Unable to parse user_address as an Address".into())
})?
.to_fixed_bytes()
.into();
@ -277,7 +275,7 @@ pub async fn admin_login_get(
.one(db_replica.as_ref())
.await?
.ok_or(Web3ProxyError::BadRequest(
"Could not find user in db".to_string(),
"Could not find user in db".into(),
))?;
// TODO: Gotta check if encoding messes up things maybe ...
@ -288,7 +286,7 @@ pub async fn admin_login_get(
.one(db_replica.as_ref())
.await?
.ok_or(Web3ProxyError::BadRequest(
"Could not find admin in db".to_string(),
"Could not find admin in db".into(),
))?;
// Note that the admin is trying to log in as this user

@ -415,9 +415,9 @@ async fn handle_socket_payload(
Ok(response.into())
}
Err(err) => Err(Web3ProxyError::BadRequest(f!(
"incorrect params given for eth_unsubscribe. {err:?}"
))),
Err(err) => Err(Web3ProxyError::BadRequest(
f!("incorrect params given for eth_unsubscribe. {err:?}").into(),
)),
}
}
_ => app

@ -352,10 +352,13 @@ pub async fn user_login_post(
.filter(referrer::Column::ReferralCode.eq(referral_code))
.one(db_replica.as_ref())
.await?
.ok_or(Web3ProxyError::BadRequest(format!(
"The referral_link you provided does not exist {}",
referral_code
)))?;
.ok_or(Web3ProxyError::BadRequest(
format!(
"The referral_link you provided does not exist {}",
referral_code
)
.into(),
))?;
// Create a new item in the database,
// marking this guy as the referrer (and ignoring a duplicate insert, if there is any...)

@ -38,6 +38,8 @@ abigen!(
PaymentFactory,
r#"[
event PaymentReceived(address indexed account, address token, uint256 amount)
account_to_payment_address(address) -> address
payment_address_to_account(address) -> address
]"#,
);
@ -137,30 +139,31 @@ pub async fn user_balance_post(
// Let's say that for now, 1 credit is equivalent to 1 dollar (assuming any stablecoin has a 1:1 peg)
let tx_hash: H256 = params
.remove("tx_hash")
// TODO: map_err so this becomes a 500. routing must be bad
.ok_or(Web3ProxyError::BadRequest(
"You have not provided the tx_hash in which you paid in".to_string(),
"You have not provided a tx_hash".into(),
))?
.parse()
.context("unable to parse tx_hash")?;
.map_err(|err| {
Web3ProxyError::BadRequest(format!("unable to parse tx_hash: {}", err).into())
})?;
let db_conn = app.db_conn().context("query_user_stats needs a db")?;
// let db_replica = app
// .db_replica()
// .context("query_user_stats needs a db replica")?;
// Return straight false if the tx was already added ...
// TODO: TxHash being string
let receipt = increase_on_chain_balance_receipt::Entity::find()
if increase_on_chain_balance_receipt::Entity::find()
.filter(increase_on_chain_balance_receipt::Column::TxHash.eq(tx_hash.encode_hex()))
.one(&db_conn)
.await?;
if receipt.is_some() {
return Err(Web3ProxyError::BadRequest(
"The transaction you provided has already been accounted for!".to_string(),
));
.await?
.is_some()
{
let response = Json(json!({
"result": "success",
"message": "this transaction was already in the database",
}))
.into_response();
return Ok(response);
}
debug!("Receipt: {:?}", receipt);
// Iterate through all logs, and add them to the transaction list if there is any
// Address will be hardcoded in the config
@ -170,18 +173,32 @@ pub async fn user_balance_post(
trace!("Transaction receipt: {:#?}", transaction_receipt);
// there is no need to check accepted tokens. the smart contract already does that
// there is no need to check accepted tokens. the smart contract already reverts if the token isn't accepted
// parse the log from the transaction receipt to get the token address,
/*
event PaymentReceived:
account: indexed(address)
token: address
amount: uint256
*/
let payment_factory_address = app
.config
.deposit_factory_contract
.context("A deposit_contract must be provided in the config to parse payments")?;
let payment_factory =
PaymentFactory::new(payment_factory_address, app.internal_provider().clone());
// TODO: parse the log from the transaction receipt
// let deposit_log = payment_factory.payment_received_filter().topic;
// // // TODO: do a quick check that this transaction contains the required log
// if !transaction_receipt.logs_bloom.contains_input(deposit_log) {
// return Err(Web3ProxyError::BadRequest("no matching logs found".into()));
// }
// TODO: get the payment token address
// TODO: get the account the payment was received on behalf of (any account could have sent it)
// TODO: get the decimals for the token
// TODO: payment_factory.payment_address_to_account(...).call();
// Go through all logs, this should prob capture it,
// At least according to this SE logs are just concatenations of the underlying types (like a struct..)
// https://ethereum.stackexchange.com/questions/87653/how-to-decode-log-event-of-my-transaction-log
@ -380,8 +397,4 @@ pub async fn user_balance_post(
return Ok(response);
}
*/
Err(Web3ProxyError::BadRequest(
"No such transaction was found, or token is not supported!".to_string(),
))
}

@ -111,7 +111,7 @@ pub async fn get_subusers(
.remove("rpc_key")
// TODO: map_err so this becomes a 500. routing must be bad
.ok_or(Web3ProxyError::BadRequest(
"You have not provided the 'rpc_key' whose access to modify".to_string(),
"You have not provided the 'rpc_key' whose access to modify".into(),
))?
.parse()
.context(format!("unable to parse rpc_key {:?}", params))?;
@ -122,7 +122,7 @@ pub async fn get_subusers(
.one(db_replica.as_ref())
.await?
.ok_or(Web3ProxyError::BadRequest(
"The provided RPC key cannot be found".to_string(),
"The provided RPC key cannot be found".into(),
))?;
// Get all secondary users that have access to this rpc key
@ -188,7 +188,7 @@ pub async fn modify_subuser(
.remove("rpc_key")
// TODO: map_err so this becomes a 500. routing must be bad
.ok_or(Web3ProxyError::BadRequest(
"You have not provided the 'rpc_key' whose access to modify".to_string(),
"You have not provided the 'rpc_key' whose access to modify".into(),
))?
.parse::<Ulid>()
.context(format!("unable to parse rpc_key {:?}", params))?;
@ -198,7 +198,7 @@ pub async fn modify_subuser(
.remove("subuser_address")
// TODO: map_err so this becomes a 500. routing must be bad
.ok_or(Web3ProxyError::BadRequest(
"You have not provided the 'user_address' whose access to modify".to_string(),
"You have not provided the 'user_address' whose access to modify".into(),
))?
.parse()
.context(format!("unable to parse subuser_address {:?}", params))?;
@ -209,14 +209,14 @@ pub async fn modify_subuser(
.remove("new_status")
// TODO: map_err so this becomes a 500. routing must be bad
.ok_or(Web3ProxyError::BadRequest(
"You have not provided the new_stats key in the request".to_string(),
"You have not provided the new_stats key in the request".into(),
))?
.as_str()
{
"upsert" => Ok(true),
"remove" => Ok(false),
_ => Err(Web3ProxyError::BadRequest(
"'new_status' must be one of 'upsert' or 'remove'".to_string(),
"'new_status' must be one of 'upsert' or 'remove'".into(),
)),
}?;
@ -224,7 +224,7 @@ pub async fn modify_subuser(
.remove("new_role")
// TODO: map_err so this becomes a 500. routing must be bad
.ok_or(Web3ProxyError::BadRequest(
"You have not provided the new_role key in the request".to_string(),
"You have not provided the new_role key in the request".into(),
))?
.as_str()
{
@ -235,7 +235,7 @@ pub async fn modify_subuser(
"admin" => Ok(Role::Admin),
"collaborator" => Ok(Role::Collaborator),
_ => Err(Web3ProxyError::BadRequest(
"'new_role' must be one of 'owner', 'admin', 'collaborator'".to_string(),
"'new_role' must be one of 'owner', 'admin', 'collaborator'".into(),
)),
}?;
@ -253,13 +253,13 @@ pub async fn modify_subuser(
.one(db_replica.as_ref())
.await?
.ok_or(Web3ProxyError::BadRequest(
"Provided RPC key does not exist!".to_owned(),
"Provided RPC key does not exist!".into(),
))?;
// Make sure that the user owns the rpc_key_entity
if rpc_key_entity.user_id != user.id {
return Err(Web3ProxyError::BadRequest(
"you must own the RPC for which you are giving permissions out".to_string(),
"you must own the RPC for which you are giving permissions out".into(),
));
}
@ -308,7 +308,7 @@ pub async fn modify_subuser(
Some(subuser) => {
if subuser.id == user.id {
return Err(Web3ProxyError::BadRequest(
"you cannot make a subuser out of yourself".to_string(),
"you cannot make a subuser out of yourself".into(),
));
}

@ -224,7 +224,7 @@ pub fn get_query_window_seconds_from_params(
|query_window_seconds: &String| {
// parse the given timestamp
query_window_seconds.parse::<u64>().map_err(|_| {
Web3ProxyError::BadRequest("Unable to parse query_window_seconds".to_string())
Web3ProxyError::BadRequest("Unable to parse query_window_seconds".into())
})
},
)
@ -259,7 +259,7 @@ pub fn get_stats_column_from_params(params: &HashMap<String, String>) -> Web3Pro
sum_response_millis, \
sum_credits_used, \
balance"
.to_string(),
.into(),
)),
}
},

@ -84,7 +84,7 @@ impl JsonRpcRequestEnum {
Self::Batch(x) => match x.first() {
Some(x) => Ok(x.id.clone()),
None => Err(Web3ProxyError::BadRequest(
"no requests in the batch".to_string(),
"no requests in the batch".into(),
)),
},
Self::Single(x) => Ok(x.id.clone()),

@ -208,7 +208,7 @@ pub async fn query_user_stats<'a>(
// TODO: move getting the param and checking the bearer token into a helper function
if let Some(rpc_key_id) = params.get("rpc_key_id") {
let rpc_key_id = rpc_key_id.parse::<u64>().map_err(|e| {
Web3ProxyError::BadRequest(format!("Unable to parse rpc_key_id. {:?}", e))
Web3ProxyError::BadRequest(format!("Unable to parse rpc_key_id. {}", e).into())
})?;
response_body.insert("rpc_key_id", serde_json::Value::Number(rpc_key_id.into()));

@ -33,18 +33,18 @@ pub async fn query_user_stats<'a>(
params: &'a HashMap<String, String>,
stat_response_type: StatType,
) -> Web3ProxyResponse {
let user_id = match bearer {
Some(inner_bearer) => {
let (user, _semaphore) = app.bearer_is_authorized(inner_bearer.0 .0).await?;
user.id
let (user_id, _semaphore) = match bearer {
Some(TypedHeader(Authorization(bearer))) => {
let (user, semaphore) = app.bearer_is_authorized(bearer).await?;
(user.id, Some(semaphore))
}
None => 0,
None => (0, None),
};
// Return an error if the bearer is set, but the StatType is Detailed
// Return an error if the bearer is **not** set, but the StatType is Detailed
if stat_response_type == StatType::Detailed && user_id == 0 {
return Err(Web3ProxyError::BadRequest(
"Detailed Stats Response requires you to authorize with a bearer token".to_owned(),
"Detailed Stats Response requires you to authorize with a bearer token".into(),
));
}
@ -66,8 +66,7 @@ pub async fn query_user_stats<'a>(
// Return a bad request if query_start == query_stop, because then the query is empty basically
if query_start == query_stop {
return Err(Web3ProxyError::BadRequest(
"Start and Stop date cannot be equal. Please specify a (different) start date."
.to_owned(),
"Start and Stop date cannot be equal. Please specify a (different) start date.".into(),
));
}
@ -128,7 +127,7 @@ pub async fn query_user_stats<'a>(
if user_rpc_keys.is_empty() {
return Err(Web3ProxyError::BadRequest(
"User has no secret RPC keys yet".to_string(),
"User has no secret RPC keys yet".into(),
));
}
@ -481,7 +480,7 @@ pub async fn query_user_stats<'a>(
if let Some(rpc_key_id) = params.get("rpc_key_id") {
let rpc_key_id = rpc_key_id
.parse::<u64>()
.map_err(|_| Web3ProxyError::BadRequest("Unable to parse rpc_key_id".to_string()))?;
.map_err(|_| Web3ProxyError::BadRequest("Unable to parse rpc_key_id".into()))?;
response_body.insert("rpc_key_id", serde_json::Value::Number(rpc_key_id.into()));
}