2022-10-18 00:47:58 +03:00
|
|
|
//! Utlities for logging errors for admins and displaying errors to users.
|
|
|
|
|
2022-11-08 22:58:11 +03:00
|
|
|
use super::authorization::Authorization;
|
2023-05-13 21:13:02 +03:00
|
|
|
use crate::jsonrpc::{JsonRpcErrorData, JsonRpcForwardedResponse};
|
|
|
|
use crate::response_cache::JsonRpcResponseData;
|
2023-03-20 01:50:25 +03:00
|
|
|
|
2023-05-13 21:13:02 +03:00
|
|
|
use std::error::Error;
|
|
|
|
use std::{borrow::Cow, net::IpAddr};
|
2023-03-20 01:50:25 +03:00
|
|
|
|
2022-08-10 05:37:34 +03:00
|
|
|
use axum::{
|
2022-10-27 00:39:26 +03:00
|
|
|
headers,
|
2022-08-10 05:37:34 +03:00
|
|
|
http::StatusCode,
|
|
|
|
response::{IntoResponse, Response},
|
|
|
|
Json,
|
|
|
|
};
|
2023-03-20 01:50:25 +03:00
|
|
|
use derive_more::{Display, Error, From};
|
2022-10-27 00:39:26 +03:00
|
|
|
use http::header::InvalidHeaderValue;
|
|
|
|
use ipnet::AddrParseError;
|
2023-03-20 21:38:54 +03:00
|
|
|
use log::{debug, error, info, trace, warn};
|
2022-11-14 21:24:52 +03:00
|
|
|
use migration::sea_orm::DbErr;
|
2022-09-15 20:57:24 +03:00
|
|
|
use redis_rate_limiter::redis::RedisError;
|
2022-10-27 00:39:26 +03:00
|
|
|
use reqwest::header::ToStrError;
|
2022-12-14 05:13:23 +03:00
|
|
|
use tokio::{sync::AcquireError, task::JoinError, time::Instant};
|
2022-06-05 22:58:47 +03:00
|
|
|
|
2023-03-17 05:38:11 +03:00
|
|
|
pub type Web3ProxyResult<T> = Result<T, Web3ProxyError>;
|
2022-10-20 23:26:14 +03:00
|
|
|
// TODO: take "IntoResponse" instead of Response?
|
2023-03-17 05:38:11 +03:00
|
|
|
pub type Web3ProxyResponse = Web3ProxyResult<Response>;
|
2022-08-17 00:43:39 +03:00
|
|
|
|
2023-05-13 01:15:32 +03:00
|
|
|
impl From<Web3ProxyError> for Web3ProxyResult<()> {
|
|
|
|
fn from(value: Web3ProxyError) -> Self {
|
|
|
|
Err(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-20 01:50:25 +03:00
|
|
|
#[derive(Debug, Display, Error, From)]
|
2023-03-17 05:38:11 +03:00
|
|
|
pub enum Web3ProxyError {
|
2022-12-06 00:13:36 +03:00
|
|
|
AccessDenied,
|
2023-03-20 01:50:25 +03:00
|
|
|
#[error(ignore)]
|
2022-08-17 00:43:39 +03:00
|
|
|
Anyhow(anyhow::Error),
|
2023-03-20 01:50:25 +03:00
|
|
|
#[error(ignore)]
|
|
|
|
#[from(ignore)]
|
2023-02-03 21:56:05 +03:00
|
|
|
BadRequest(String),
|
2023-05-13 01:15:32 +03:00
|
|
|
#[error(ignore)]
|
|
|
|
#[from(ignore)]
|
|
|
|
BadResponse(String),
|
2023-03-20 22:47:57 +03:00
|
|
|
BadRouting,
|
2022-08-27 08:42:25 +03:00
|
|
|
Database(DbErr),
|
2023-03-20 22:47:57 +03:00
|
|
|
#[display(fmt = "{:#?}, {:#?}", _0, _1)]
|
|
|
|
EipVerificationFailed(Box<Web3ProxyError>, Box<Web3ProxyError>),
|
2023-03-20 04:52:28 +03:00
|
|
|
EthersHttpClientError(ethers::prelude::HttpClientError),
|
|
|
|
EthersProviderError(ethers::prelude::ProviderError),
|
|
|
|
EthersWsClientError(ethers::prelude::WsClientError),
|
2023-05-13 21:13:02 +03:00
|
|
|
FlumeRecvError(flume::RecvError),
|
2023-03-20 23:07:24 +03:00
|
|
|
GasEstimateNotU256,
|
2023-03-03 04:39:50 +03:00
|
|
|
Headers(headers::Error),
|
2022-10-27 00:39:26 +03:00
|
|
|
HeaderToString(ToStrError),
|
2023-02-22 09:04:47 +03:00
|
|
|
InfluxDb2RequestError(influxdb2::RequestError),
|
2023-03-20 04:52:28 +03:00
|
|
|
#[display(fmt = "{} > {}", min, max)]
|
2023-03-20 23:45:21 +03:00
|
|
|
#[from(ignore)]
|
2023-03-20 04:52:28 +03:00
|
|
|
InvalidBlockBounds {
|
|
|
|
min: u64,
|
|
|
|
max: u64,
|
|
|
|
},
|
2022-10-27 00:39:26 +03:00
|
|
|
InvalidHeaderValue(InvalidHeaderValue),
|
2023-03-20 22:47:57 +03:00
|
|
|
InvalidEip,
|
|
|
|
InvalidInviteCode,
|
2023-05-13 21:13:02 +03:00
|
|
|
UnknownReferralCode,
|
2023-03-20 22:47:57 +03:00
|
|
|
InvalidReferer,
|
|
|
|
InvalidSignatureLength,
|
|
|
|
InvalidUserAgent,
|
|
|
|
InvalidUserKey,
|
2022-10-27 00:39:26 +03:00
|
|
|
IpAddrParse(AddrParseError),
|
2023-03-20 01:50:25 +03:00
|
|
|
#[error(ignore)]
|
|
|
|
#[from(ignore)]
|
|
|
|
IpNotAllowed(IpAddr),
|
2022-11-03 02:14:16 +03:00
|
|
|
JoinError(JoinError),
|
2023-04-01 09:23:30 +03:00
|
|
|
#[display(fmt = "{:?}", _0)]
|
|
|
|
#[error(ignore)]
|
2023-03-03 04:39:50 +03:00
|
|
|
MsgPackEncode(rmp_serde::encode::Error),
|
2023-03-20 23:45:21 +03:00
|
|
|
NoBlockNumberOrHash,
|
|
|
|
NoBlocksKnown,
|
2023-04-01 09:23:30 +03:00
|
|
|
NoConsensusHeadBlock,
|
2023-03-20 04:52:28 +03:00
|
|
|
NoHandleReady,
|
2023-03-20 23:45:21 +03:00
|
|
|
NoServersSynced,
|
|
|
|
#[display(fmt = "{}/{}", num_known, min_head_rpcs)]
|
|
|
|
#[from(ignore)]
|
|
|
|
NotEnoughRpcs {
|
|
|
|
num_known: usize,
|
|
|
|
min_head_rpcs: usize,
|
|
|
|
},
|
2022-10-27 00:39:26 +03:00
|
|
|
NotFound,
|
2023-03-20 22:47:57 +03:00
|
|
|
NotImplemented,
|
2023-03-20 01:50:25 +03:00
|
|
|
OriginRequired,
|
|
|
|
#[error(ignore)]
|
|
|
|
#[from(ignore)]
|
|
|
|
OriginNotAllowed(headers::Origin),
|
2023-03-20 23:07:24 +03:00
|
|
|
#[display(fmt = "{:?}", _0)]
|
|
|
|
#[error(ignore)]
|
|
|
|
ParseBytesError(Option<ethers::types::ParseBytesError>),
|
2023-03-20 22:47:57 +03:00
|
|
|
ParseMsgError(siwe::ParseError),
|
|
|
|
ParseAddressError,
|
2023-03-20 01:50:25 +03:00
|
|
|
#[display(fmt = "{:?}, {:?}", _0, _1)]
|
2022-11-08 22:58:11 +03:00
|
|
|
RateLimited(Authorization, Option<Instant>),
|
2022-10-27 00:39:26 +03:00
|
|
|
Redis(RedisError),
|
2023-03-20 01:50:25 +03:00
|
|
|
RefererRequired,
|
|
|
|
#[display(fmt = "{:?}", _0)]
|
|
|
|
#[error(ignore)]
|
|
|
|
#[from(ignore)]
|
|
|
|
RefererNotAllowed(headers::Referer),
|
2023-03-20 04:52:28 +03:00
|
|
|
SemaphoreAcquireError(AcquireError),
|
2023-05-13 21:13:02 +03:00
|
|
|
SendAppStatError(flume::SendError<crate::stats::AppStat>),
|
2023-03-20 04:52:28 +03:00
|
|
|
SerdeJson(serde_json::Error),
|
2022-10-20 23:26:14 +03:00
|
|
|
/// simple way to return an error message to the user and an anyhow to our logs
|
2023-03-20 01:50:25 +03:00
|
|
|
#[display(fmt = "{}, {}, {:?}", _0, _1, _2)]
|
2022-11-08 22:58:11 +03:00
|
|
|
StatusCode(StatusCode, String, Option<anyhow::Error>),
|
2022-12-20 08:37:12 +03:00
|
|
|
/// TODO: what should be attached to the timout?
|
2023-03-20 04:52:28 +03:00
|
|
|
#[display(fmt = "{:?}", _0)]
|
|
|
|
#[error(ignore)]
|
|
|
|
Timeout(Option<tokio::time::error::Elapsed>),
|
2023-03-03 04:39:50 +03:00
|
|
|
UlidDecode(ulid::DecodeError),
|
2023-03-20 04:52:28 +03:00
|
|
|
UnknownBlockNumber,
|
2022-09-12 17:33:55 +03:00
|
|
|
UnknownKey,
|
2023-03-20 01:50:25 +03:00
|
|
|
UserAgentRequired,
|
|
|
|
#[error(ignore)]
|
|
|
|
UserAgentNotAllowed(headers::UserAgent),
|
2023-03-20 22:47:57 +03:00
|
|
|
UserIdZero,
|
User Balance + Referral Logic (#44)
* will implement balance topup endpoint
* will quickly fix other PR reviews
* merging from master
* will finish up godmoe
* will finish up login
* added logic to top up balance (first iteration)
* should implement additional columns soon (currency, amount, tx-hash), as well as a new table for spend
* updated migrations, will account for spend next
* get back to this later
* will merge PR from stats-v2
* stats v2
rebased all my commits and squashed them down to one
* cargo upgrade
* added migrtation for spend in accounting table. will run test-deposit next
* trying to get request from polygon
* first iteration /user/balance/:tx_hash works, needs to add accepted tokens next
* creating the referral code seems to work
* will now check if spending enough credits will lead to both parties receiving credits
* rpcstats takes care of accounting for spend data
* removed track spend from table
* Revert "removed track spend from table"
This reverts commit a50802d6ae75f786864c5ec42d0ceb2cb27124ed.
* Revert "rpcstats takes care of accounting for spend data"
This reverts commit 1cec728bf241e4cfd24351134637ed81c1a5a10b.
* removed rpc request table entity
* updated referral code to use ulid s
* credits used are aggregated
* added a bunch of fields to referrer
* added database logic whenever an aggregate stats is added. will have to iterate over this a couple times i think. go to (1) detecting accepted stables next, (2) fix influxdb bug and (3) start to write test
* removed track spend as this will occur in the database
* will first work on "balance", then referral. these should really be treated as two separate PRs (although already convoluted)
* balance logic initial commit
* breaking WIP, changing the RPC call logic functions
* will start testing next
* got rid of warnings & lint
* will proceed with subtracting / adding to balance
* added decimal points, balance tracking seems to work
* will beautify code a bit
* removed deprecated dependency, and added topic + deposit contract to app.yaml
* brownie test suite does not rely on local contract files it pulls all from polygonscan
* will continue with referral
* should perhaps (in a future revision) recordhow much the referees got for free. marking referrals seems to work rn
* user is upgraded to premium if they deposit more than 10$. we dont accept more than $10M in a single tx
* will start PR, referral seems to be fine so far, perhaps up to some numbers that still may need tweaking
* will start PR
* removed rogue comments, cleaned up payments a bit
* changes before PR
* apply stats
* added unique constraint
* some refactoring such that the user file is not too bloated
* compiling
* progress with subusers, creating a table entry seems to work
* good response type is there as well now, will work on getters from primary user and secondary user next
* subuser logic also seems fine now
* downgrade logic
* fixed bug influxdb does not support different types in same query (which makes sense)
* WIP temporary commit
* merging with PR
* Delete daemon.rs
there are multiple daemons now, so this was moved to `proxyd`
* will remove request clone to &mut
* multiple request handles for payment
* making requests still seem fine
* removed redundant commented out bits
* added deposit endpoint, added deposit amount and deposit user, untested yet
* small bug with downgrade tier id
* will add authorization so balance can be received for users
* balance history should be set now too
* will check balance over time again
* subususer can see rpc key balance if admin or owner
* stats also seems to work fine now with historical balance
* things seem to be building and working
* removed clone from OpenRequestHandle
* removed influxdb from workspace members
* changed config files
* reran sea-orm generate entities, added a foreign key, should be proper now
* removed contract from commit
* made deposit contract optional
* added topic in polygon dev
* changed deposit contract to deposit factory contract
* added selfrelation on user_tier
* added payment required
* changed chain id to u64
* add wss in polygon llamarpc
* removed origin and method from the table
* added onchain transactions naming (and forgot to add a migration before)
* changed foreign key to be the referrer (id), not the code itself
* forgot to add id as the target foreign key
* WIP adding cache to update role
* fixed merge conflicts
---------
Co-authored-by: Bryan Stitt <bryan@llamanodes.com>
Co-authored-by: Bryan Stitt <bryan@stitthappens.com>
2023-05-12 19:45:15 +03:00
|
|
|
PaymentRequired,
|
2023-03-20 22:47:57 +03:00
|
|
|
VerificationError(siwe::VerificationError),
|
2023-03-20 04:52:28 +03:00
|
|
|
WatchRecvError(tokio::sync::watch::error::RecvError),
|
2023-03-20 23:45:21 +03:00
|
|
|
WatchSendError,
|
2023-03-20 05:14:46 +03:00
|
|
|
WebsocketOnly,
|
2023-03-20 22:47:57 +03:00
|
|
|
#[display(fmt = "{:?}, {}", _0, _1)]
|
2023-03-20 21:38:54 +03:00
|
|
|
#[error(ignore)]
|
|
|
|
WithContext(Option<Box<Web3ProxyError>>, String),
|
2022-08-16 22:29:00 +03:00
|
|
|
}
|
|
|
|
|
2023-03-17 05:38:11 +03:00
|
|
|
impl Web3ProxyError {
|
2023-05-13 21:13:02 +03:00
|
|
|
pub fn into_response_parts(self) -> (StatusCode, JsonRpcResponseData) {
|
|
|
|
let (code, err): (StatusCode, JsonRpcErrorData) = match self {
|
2022-12-06 00:13:36 +03:00
|
|
|
Self::AccessDenied => {
|
|
|
|
// TODO: attach something to this trace. probably don't include much in the message though. don't want to leak creds by accident
|
|
|
|
trace!("access denied");
|
|
|
|
(
|
|
|
|
StatusCode::FORBIDDEN,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("FORBIDDEN"),
|
|
|
|
code: StatusCode::FORBIDDEN.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-12-06 00:13:36 +03:00
|
|
|
)
|
|
|
|
}
|
2022-09-10 03:12:14 +03:00
|
|
|
Self::Anyhow(err) => {
|
2022-11-12 11:24:32 +03:00
|
|
|
warn!("anyhow. err={:?}", err);
|
2022-09-10 03:12:14 +03:00
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
2022-09-20 06:26:12 +03:00
|
|
|
// TODO: is it safe to expose all of our anyhow strings?
|
2023-05-13 21:13:02 +03:00
|
|
|
message: Cow::Owned(err.to_string()),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-09-10 03:12:14 +03:00
|
|
|
)
|
|
|
|
}
|
2023-02-03 21:56:05 +03:00
|
|
|
Self::BadRequest(err) => {
|
|
|
|
debug!("BAD_REQUEST: {}", err);
|
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!("bad request: {}", err)),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-02-03 21:56:05 +03:00
|
|
|
)
|
|
|
|
}
|
2023-05-13 01:15:32 +03:00
|
|
|
Self::BadResponse(err) => {
|
|
|
|
// TODO: think about this one more. ankr gives us this because ethers fails to parse responses without an id
|
|
|
|
debug!("BAD_RESPONSE: {}", err);
|
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!("bad response: {}", err)),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-05-13 01:15:32 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 22:47:57 +03:00
|
|
|
Self::BadRouting => {
|
|
|
|
error!("BadRouting");
|
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("bad routing"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
2022-10-27 00:39:26 +03:00
|
|
|
Self::Database(err) => {
|
2023-02-22 09:04:47 +03:00
|
|
|
error!("database err={:?}", err);
|
2022-09-10 03:12:14 +03:00
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("database error!"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-09-10 03:12:14 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 22:47:57 +03:00
|
|
|
Self::EipVerificationFailed(err_1, err_191) => {
|
2023-03-22 08:52:46 +03:00
|
|
|
info!(
|
2023-03-20 22:47:57 +03:00
|
|
|
"EipVerificationFailed err_1={:#?} err2={:#?}",
|
|
|
|
err_1, err_191
|
|
|
|
);
|
|
|
|
(
|
|
|
|
StatusCode::UNAUTHORIZED,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!(
|
2023-03-20 22:47:57 +03:00
|
|
|
"both the primary and eip191 verification failed: {:#?}; {:#?}",
|
|
|
|
err_1, err_191
|
2023-05-13 21:13:02 +03:00
|
|
|
)),
|
|
|
|
code: StatusCode::UNAUTHORIZED.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 04:52:28 +03:00
|
|
|
Self::EthersHttpClientError(err) => {
|
|
|
|
warn!("EthersHttpClientError err={:?}", err);
|
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("ether http client error"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 04:52:28 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::EthersProviderError(err) => {
|
|
|
|
warn!("EthersProviderError err={:?}", err);
|
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("ether provider error"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 04:52:28 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::EthersWsClientError(err) => {
|
|
|
|
warn!("EthersWsClientError err={:?}", err);
|
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("ether ws client error"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 04:52:28 +03:00
|
|
|
)
|
|
|
|
}
|
2023-05-13 21:13:02 +03:00
|
|
|
Self::FlumeRecvError(err) => {
|
|
|
|
warn!("FlumeRecvError err={:#?}", err);
|
2023-03-20 23:45:21 +03:00
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("flume recv error!"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 23:45:21 +03:00
|
|
|
)
|
|
|
|
}
|
2023-05-13 21:13:02 +03:00
|
|
|
// Self::JsonRpcForwardedError(x) => (StatusCode::OK, x),
|
2023-03-20 23:07:24 +03:00
|
|
|
Self::GasEstimateNotU256 => {
|
|
|
|
warn!("GasEstimateNotU256");
|
|
|
|
(
|
2023-03-22 08:52:46 +03:00
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("gas estimate result is not an U256"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 23:07:24 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-03 04:39:50 +03:00
|
|
|
Self::Headers(err) => {
|
2022-11-12 11:24:32 +03:00
|
|
|
warn!("HeadersError {:?}", err);
|
2022-10-27 00:39:26 +03:00
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!("{}", err)),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-10-27 00:39:26 +03:00
|
|
|
)
|
2022-08-21 12:39:38 +03:00
|
|
|
}
|
2023-02-22 09:04:47 +03:00
|
|
|
Self::InfluxDb2RequestError(err) => {
|
|
|
|
// TODO: attach a request id to the message and to this error so that if people report problems, we can dig in sentry to find out more
|
|
|
|
error!("influxdb2 err={:?}", err);
|
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("influxdb2 error!"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-02-22 09:04:47 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 04:52:28 +03:00
|
|
|
Self::InvalidBlockBounds { min, max } => {
|
2023-03-22 08:52:46 +03:00
|
|
|
debug!("InvalidBlockBounds min={} max={}", min, max);
|
2023-03-20 04:52:28 +03:00
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!(
|
2023-03-20 04:52:28 +03:00
|
|
|
"Invalid blocks bounds requested. min ({}) > max ({})",
|
|
|
|
min, max
|
2023-05-13 21:13:02 +03:00
|
|
|
)),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 04:52:28 +03:00
|
|
|
)
|
|
|
|
}
|
2022-10-27 00:39:26 +03:00
|
|
|
Self::IpAddrParse(err) => {
|
2023-05-13 21:13:02 +03:00
|
|
|
debug!("IpAddrParse err={:?}", err);
|
2022-10-20 23:26:14 +03:00
|
|
|
(
|
2022-10-27 00:39:26 +03:00
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(err.to_string()),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-10-20 23:26:14 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 01:50:25 +03:00
|
|
|
Self::IpNotAllowed(ip) => {
|
2023-05-13 21:13:02 +03:00
|
|
|
debug!("IpNotAllowed ip={})", ip);
|
2023-03-20 01:50:25 +03:00
|
|
|
(
|
|
|
|
StatusCode::FORBIDDEN,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!("IP ({}) is not allowed!", ip)),
|
|
|
|
code: StatusCode::FORBIDDEN.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 01:50:25 +03:00
|
|
|
)
|
|
|
|
}
|
2022-10-27 00:39:26 +03:00
|
|
|
Self::InvalidHeaderValue(err) => {
|
2023-05-13 21:13:02 +03:00
|
|
|
debug!("InvalidHeaderValue err={:?}", err);
|
2022-09-10 03:12:14 +03:00
|
|
|
(
|
2022-10-27 00:39:26 +03:00
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!("{}", err)),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-10-27 00:39:26 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 22:47:57 +03:00
|
|
|
Self::InvalidEip => {
|
2023-05-13 21:13:02 +03:00
|
|
|
debug!("InvalidEip");
|
2023-03-20 22:47:57 +03:00
|
|
|
(
|
2023-05-13 21:13:02 +03:00
|
|
|
StatusCode::BAD_REQUEST,
|
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("invalid message eip given"),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::InvalidInviteCode => {
|
2023-05-13 21:13:02 +03:00
|
|
|
debug!("InvalidInviteCode");
|
2023-03-20 22:47:57 +03:00
|
|
|
(
|
|
|
|
StatusCode::UNAUTHORIZED,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("invalid invite code"),
|
|
|
|
code: StatusCode::UNAUTHORIZED.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
2023-05-13 21:13:02 +03:00
|
|
|
Self::UnknownReferralCode => {
|
|
|
|
debug!("UnknownReferralCode");
|
User Balance + Referral Logic (#44)
* will implement balance topup endpoint
* will quickly fix other PR reviews
* merging from master
* will finish up godmoe
* will finish up login
* added logic to top up balance (first iteration)
* should implement additional columns soon (currency, amount, tx-hash), as well as a new table for spend
* updated migrations, will account for spend next
* get back to this later
* will merge PR from stats-v2
* stats v2
rebased all my commits and squashed them down to one
* cargo upgrade
* added migrtation for spend in accounting table. will run test-deposit next
* trying to get request from polygon
* first iteration /user/balance/:tx_hash works, needs to add accepted tokens next
* creating the referral code seems to work
* will now check if spending enough credits will lead to both parties receiving credits
* rpcstats takes care of accounting for spend data
* removed track spend from table
* Revert "removed track spend from table"
This reverts commit a50802d6ae75f786864c5ec42d0ceb2cb27124ed.
* Revert "rpcstats takes care of accounting for spend data"
This reverts commit 1cec728bf241e4cfd24351134637ed81c1a5a10b.
* removed rpc request table entity
* updated referral code to use ulid s
* credits used are aggregated
* added a bunch of fields to referrer
* added database logic whenever an aggregate stats is added. will have to iterate over this a couple times i think. go to (1) detecting accepted stables next, (2) fix influxdb bug and (3) start to write test
* removed track spend as this will occur in the database
* will first work on "balance", then referral. these should really be treated as two separate PRs (although already convoluted)
* balance logic initial commit
* breaking WIP, changing the RPC call logic functions
* will start testing next
* got rid of warnings & lint
* will proceed with subtracting / adding to balance
* added decimal points, balance tracking seems to work
* will beautify code a bit
* removed deprecated dependency, and added topic + deposit contract to app.yaml
* brownie test suite does not rely on local contract files it pulls all from polygonscan
* will continue with referral
* should perhaps (in a future revision) recordhow much the referees got for free. marking referrals seems to work rn
* user is upgraded to premium if they deposit more than 10$. we dont accept more than $10M in a single tx
* will start PR, referral seems to be fine so far, perhaps up to some numbers that still may need tweaking
* will start PR
* removed rogue comments, cleaned up payments a bit
* changes before PR
* apply stats
* added unique constraint
* some refactoring such that the user file is not too bloated
* compiling
* progress with subusers, creating a table entry seems to work
* good response type is there as well now, will work on getters from primary user and secondary user next
* subuser logic also seems fine now
* downgrade logic
* fixed bug influxdb does not support different types in same query (which makes sense)
* WIP temporary commit
* merging with PR
* Delete daemon.rs
there are multiple daemons now, so this was moved to `proxyd`
* will remove request clone to &mut
* multiple request handles for payment
* making requests still seem fine
* removed redundant commented out bits
* added deposit endpoint, added deposit amount and deposit user, untested yet
* small bug with downgrade tier id
* will add authorization so balance can be received for users
* balance history should be set now too
* will check balance over time again
* subususer can see rpc key balance if admin or owner
* stats also seems to work fine now with historical balance
* things seem to be building and working
* removed clone from OpenRequestHandle
* removed influxdb from workspace members
* changed config files
* reran sea-orm generate entities, added a foreign key, should be proper now
* removed contract from commit
* made deposit contract optional
* added topic in polygon dev
* changed deposit contract to deposit factory contract
* added selfrelation on user_tier
* added payment required
* changed chain id to u64
* add wss in polygon llamarpc
* removed origin and method from the table
* added onchain transactions naming (and forgot to add a migration before)
* changed foreign key to be the referrer (id), not the code itself
* forgot to add id as the target foreign key
* WIP adding cache to update role
* fixed merge conflicts
---------
Co-authored-by: Bryan Stitt <bryan@llamanodes.com>
Co-authored-by: Bryan Stitt <bryan@stitthappens.com>
2023-05-12 19:45:15 +03:00
|
|
|
(
|
|
|
|
StatusCode::UNAUTHORIZED,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("invalid referral code"),
|
|
|
|
code: StatusCode::UNAUTHORIZED.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
User Balance + Referral Logic (#44)
* will implement balance topup endpoint
* will quickly fix other PR reviews
* merging from master
* will finish up godmoe
* will finish up login
* added logic to top up balance (first iteration)
* should implement additional columns soon (currency, amount, tx-hash), as well as a new table for spend
* updated migrations, will account for spend next
* get back to this later
* will merge PR from stats-v2
* stats v2
rebased all my commits and squashed them down to one
* cargo upgrade
* added migrtation for spend in accounting table. will run test-deposit next
* trying to get request from polygon
* first iteration /user/balance/:tx_hash works, needs to add accepted tokens next
* creating the referral code seems to work
* will now check if spending enough credits will lead to both parties receiving credits
* rpcstats takes care of accounting for spend data
* removed track spend from table
* Revert "removed track spend from table"
This reverts commit a50802d6ae75f786864c5ec42d0ceb2cb27124ed.
* Revert "rpcstats takes care of accounting for spend data"
This reverts commit 1cec728bf241e4cfd24351134637ed81c1a5a10b.
* removed rpc request table entity
* updated referral code to use ulid s
* credits used are aggregated
* added a bunch of fields to referrer
* added database logic whenever an aggregate stats is added. will have to iterate over this a couple times i think. go to (1) detecting accepted stables next, (2) fix influxdb bug and (3) start to write test
* removed track spend as this will occur in the database
* will first work on "balance", then referral. these should really be treated as two separate PRs (although already convoluted)
* balance logic initial commit
* breaking WIP, changing the RPC call logic functions
* will start testing next
* got rid of warnings & lint
* will proceed with subtracting / adding to balance
* added decimal points, balance tracking seems to work
* will beautify code a bit
* removed deprecated dependency, and added topic + deposit contract to app.yaml
* brownie test suite does not rely on local contract files it pulls all from polygonscan
* will continue with referral
* should perhaps (in a future revision) recordhow much the referees got for free. marking referrals seems to work rn
* user is upgraded to premium if they deposit more than 10$. we dont accept more than $10M in a single tx
* will start PR, referral seems to be fine so far, perhaps up to some numbers that still may need tweaking
* will start PR
* removed rogue comments, cleaned up payments a bit
* changes before PR
* apply stats
* added unique constraint
* some refactoring such that the user file is not too bloated
* compiling
* progress with subusers, creating a table entry seems to work
* good response type is there as well now, will work on getters from primary user and secondary user next
* subuser logic also seems fine now
* downgrade logic
* fixed bug influxdb does not support different types in same query (which makes sense)
* WIP temporary commit
* merging with PR
* Delete daemon.rs
there are multiple daemons now, so this was moved to `proxyd`
* will remove request clone to &mut
* multiple request handles for payment
* making requests still seem fine
* removed redundant commented out bits
* added deposit endpoint, added deposit amount and deposit user, untested yet
* small bug with downgrade tier id
* will add authorization so balance can be received for users
* balance history should be set now too
* will check balance over time again
* subususer can see rpc key balance if admin or owner
* stats also seems to work fine now with historical balance
* things seem to be building and working
* removed clone from OpenRequestHandle
* removed influxdb from workspace members
* changed config files
* reran sea-orm generate entities, added a foreign key, should be proper now
* removed contract from commit
* made deposit contract optional
* added topic in polygon dev
* changed deposit contract to deposit factory contract
* added selfrelation on user_tier
* added payment required
* changed chain id to u64
* add wss in polygon llamarpc
* removed origin and method from the table
* added onchain transactions naming (and forgot to add a migration before)
* changed foreign key to be the referrer (id), not the code itself
* forgot to add id as the target foreign key
* WIP adding cache to update role
* fixed merge conflicts
---------
Co-authored-by: Bryan Stitt <bryan@llamanodes.com>
Co-authored-by: Bryan Stitt <bryan@stitthappens.com>
2023-05-12 19:45:15 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 22:47:57 +03:00
|
|
|
Self::InvalidReferer => {
|
2023-05-13 21:13:02 +03:00
|
|
|
debug!("InvalidReferer");
|
2023-03-20 22:47:57 +03:00
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("invalid referer!"),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::InvalidSignatureLength => {
|
2023-05-13 21:13:02 +03:00
|
|
|
debug!("InvalidSignatureLength");
|
2023-03-20 22:47:57 +03:00
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("invalid signature length"),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::InvalidUserAgent => {
|
2023-05-13 21:13:02 +03:00
|
|
|
debug!("InvalidUserAgent");
|
2023-03-20 22:47:57 +03:00
|
|
|
(
|
2023-05-13 21:13:02 +03:00
|
|
|
StatusCode::FORBIDDEN,
|
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("invalid user agent!"),
|
|
|
|
code: StatusCode::FORBIDDEN.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::InvalidUserKey => {
|
|
|
|
warn!("InvalidUserKey");
|
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("UserKey was not a ULID or UUID"),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
2022-11-03 02:14:16 +03:00
|
|
|
Self::JoinError(err) => {
|
2022-12-20 08:37:12 +03:00
|
|
|
let code = if err.is_cancelled() {
|
|
|
|
trace!("JoinError. likely shutting down. err={:?}", err);
|
|
|
|
StatusCode::BAD_GATEWAY
|
|
|
|
} else {
|
|
|
|
warn!("JoinError. err={:?}", err);
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR
|
|
|
|
};
|
|
|
|
|
2022-11-03 02:14:16 +03:00
|
|
|
(
|
2022-12-20 08:37:12 +03:00
|
|
|
code,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
// TODO: different messages of cancelled or not?
|
|
|
|
message: Cow::Borrowed("Unable to complete request"),
|
|
|
|
code: code.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-11-03 02:14:16 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-03 04:39:50 +03:00
|
|
|
Self::MsgPackEncode(err) => {
|
2023-04-11 08:29:02 +03:00
|
|
|
warn!("MsgPackEncode Error: {}", err);
|
2023-03-03 04:39:50 +03:00
|
|
|
(
|
2023-04-11 08:29:02 +03:00
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!("msgpack encode error: {}", err)),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-03 04:39:50 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 23:45:21 +03:00
|
|
|
Self::NoBlockNumberOrHash => {
|
|
|
|
warn!("NoBlockNumberOrHash");
|
|
|
|
(
|
2023-04-11 08:29:02 +03:00
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("Blocks here must have a number or hash"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 23:45:21 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::NoBlocksKnown => {
|
|
|
|
error!("NoBlocksKnown");
|
2023-03-20 04:52:28 +03:00
|
|
|
(
|
2023-04-11 08:29:02 +03:00
|
|
|
StatusCode::BAD_GATEWAY,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("no blocks known"),
|
|
|
|
code: StatusCode::BAD_GATEWAY.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 04:52:28 +03:00
|
|
|
)
|
|
|
|
}
|
2023-04-01 09:23:30 +03:00
|
|
|
Self::NoConsensusHeadBlock => {
|
|
|
|
error!("NoConsensusHeadBlock");
|
|
|
|
(
|
2023-04-11 08:29:02 +03:00
|
|
|
StatusCode::BAD_GATEWAY,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("no consensus head block"),
|
|
|
|
code: StatusCode::BAD_GATEWAY.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-04-01 09:23:30 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 04:52:28 +03:00
|
|
|
Self::NoHandleReady => {
|
|
|
|
error!("NoHandleReady");
|
|
|
|
(
|
2023-03-22 08:52:46 +03:00
|
|
|
StatusCode::BAD_GATEWAY,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("unable to retry for request handle"),
|
|
|
|
code: StatusCode::BAD_GATEWAY.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 04:52:28 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 23:45:21 +03:00
|
|
|
Self::NoServersSynced => {
|
|
|
|
warn!("NoServersSynced");
|
|
|
|
(
|
2023-03-22 08:52:46 +03:00
|
|
|
StatusCode::BAD_GATEWAY,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("no servers synced"),
|
|
|
|
code: StatusCode::BAD_GATEWAY.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 23:45:21 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::NotEnoughRpcs {
|
|
|
|
num_known,
|
|
|
|
min_head_rpcs,
|
|
|
|
} => {
|
|
|
|
error!("NotEnoughRpcs {}/{}", num_known, min_head_rpcs);
|
|
|
|
(
|
2023-03-22 08:52:46 +03:00
|
|
|
StatusCode::BAD_GATEWAY,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!(
|
|
|
|
"not enough rpcs connected {}/{}",
|
|
|
|
num_known, min_head_rpcs
|
|
|
|
)),
|
|
|
|
code: StatusCode::BAD_GATEWAY.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 23:45:21 +03:00
|
|
|
)
|
|
|
|
}
|
2022-10-27 00:39:26 +03:00
|
|
|
Self::NotFound => {
|
|
|
|
// TODO: emit a stat?
|
2023-04-11 08:29:02 +03:00
|
|
|
// TODO: instead of an error, show a normal html page for 404?
|
2022-10-27 00:39:26 +03:00
|
|
|
(
|
|
|
|
StatusCode::NOT_FOUND,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("not found!"),
|
|
|
|
code: StatusCode::NOT_FOUND.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-09-10 03:12:14 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 22:47:57 +03:00
|
|
|
Self::NotImplemented => {
|
2023-03-22 08:52:46 +03:00
|
|
|
trace!("NotImplemented");
|
2023-03-20 22:47:57 +03:00
|
|
|
(
|
|
|
|
StatusCode::NOT_IMPLEMENTED,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("work in progress"),
|
|
|
|
code: StatusCode::NOT_IMPLEMENTED.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 01:50:25 +03:00
|
|
|
Self::OriginRequired => {
|
2023-04-11 08:29:02 +03:00
|
|
|
trace!("OriginRequired");
|
2023-03-20 01:50:25 +03:00
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("Origin required"),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 01:50:25 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::OriginNotAllowed(origin) => {
|
2023-04-11 08:29:02 +03:00
|
|
|
trace!("OriginNotAllowed origin={}", origin);
|
2023-03-20 01:50:25 +03:00
|
|
|
(
|
|
|
|
StatusCode::FORBIDDEN,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!("Origin ({}) is not allowed!", origin)),
|
|
|
|
code: StatusCode::FORBIDDEN.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 01:50:25 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 22:47:57 +03:00
|
|
|
Self::ParseBytesError(err) => {
|
2023-04-11 08:29:02 +03:00
|
|
|
trace!("ParseBytesError err={:?}", err);
|
2023-03-20 22:47:57 +03:00
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("parse bytes error!"),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::ParseMsgError(err) => {
|
2023-04-11 08:29:02 +03:00
|
|
|
trace!("ParseMsgError err={:?}", err);
|
2023-03-20 22:47:57 +03:00
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("parse message error!"),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::ParseAddressError => {
|
2023-04-11 08:29:02 +03:00
|
|
|
trace!("ParseAddressError");
|
2023-03-20 22:47:57 +03:00
|
|
|
(
|
2023-04-11 08:29:02 +03:00
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("unable to parse address"),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
User Balance + Referral Logic (#44)
* will implement balance topup endpoint
* will quickly fix other PR reviews
* merging from master
* will finish up godmoe
* will finish up login
* added logic to top up balance (first iteration)
* should implement additional columns soon (currency, amount, tx-hash), as well as a new table for spend
* updated migrations, will account for spend next
* get back to this later
* will merge PR from stats-v2
* stats v2
rebased all my commits and squashed them down to one
* cargo upgrade
* added migrtation for spend in accounting table. will run test-deposit next
* trying to get request from polygon
* first iteration /user/balance/:tx_hash works, needs to add accepted tokens next
* creating the referral code seems to work
* will now check if spending enough credits will lead to both parties receiving credits
* rpcstats takes care of accounting for spend data
* removed track spend from table
* Revert "removed track spend from table"
This reverts commit a50802d6ae75f786864c5ec42d0ceb2cb27124ed.
* Revert "rpcstats takes care of accounting for spend data"
This reverts commit 1cec728bf241e4cfd24351134637ed81c1a5a10b.
* removed rpc request table entity
* updated referral code to use ulid s
* credits used are aggregated
* added a bunch of fields to referrer
* added database logic whenever an aggregate stats is added. will have to iterate over this a couple times i think. go to (1) detecting accepted stables next, (2) fix influxdb bug and (3) start to write test
* removed track spend as this will occur in the database
* will first work on "balance", then referral. these should really be treated as two separate PRs (although already convoluted)
* balance logic initial commit
* breaking WIP, changing the RPC call logic functions
* will start testing next
* got rid of warnings & lint
* will proceed with subtracting / adding to balance
* added decimal points, balance tracking seems to work
* will beautify code a bit
* removed deprecated dependency, and added topic + deposit contract to app.yaml
* brownie test suite does not rely on local contract files it pulls all from polygonscan
* will continue with referral
* should perhaps (in a future revision) recordhow much the referees got for free. marking referrals seems to work rn
* user is upgraded to premium if they deposit more than 10$. we dont accept more than $10M in a single tx
* will start PR, referral seems to be fine so far, perhaps up to some numbers that still may need tweaking
* will start PR
* removed rogue comments, cleaned up payments a bit
* changes before PR
* apply stats
* added unique constraint
* some refactoring such that the user file is not too bloated
* compiling
* progress with subusers, creating a table entry seems to work
* good response type is there as well now, will work on getters from primary user and secondary user next
* subuser logic also seems fine now
* downgrade logic
* fixed bug influxdb does not support different types in same query (which makes sense)
* WIP temporary commit
* merging with PR
* Delete daemon.rs
there are multiple daemons now, so this was moved to `proxyd`
* will remove request clone to &mut
* multiple request handles for payment
* making requests still seem fine
* removed redundant commented out bits
* added deposit endpoint, added deposit amount and deposit user, untested yet
* small bug with downgrade tier id
* will add authorization so balance can be received for users
* balance history should be set now too
* will check balance over time again
* subususer can see rpc key balance if admin or owner
* stats also seems to work fine now with historical balance
* things seem to be building and working
* removed clone from OpenRequestHandle
* removed influxdb from workspace members
* changed config files
* reran sea-orm generate entities, added a foreign key, should be proper now
* removed contract from commit
* made deposit contract optional
* added topic in polygon dev
* changed deposit contract to deposit factory contract
* added selfrelation on user_tier
* added payment required
* changed chain id to u64
* add wss in polygon llamarpc
* removed origin and method from the table
* added onchain transactions naming (and forgot to add a migration before)
* changed foreign key to be the referrer (id), not the code itself
* forgot to add id as the target foreign key
* WIP adding cache to update role
* fixed merge conflicts
---------
Co-authored-by: Bryan Stitt <bryan@llamanodes.com>
Co-authored-by: Bryan Stitt <bryan@stitthappens.com>
2023-05-12 19:45:15 +03:00
|
|
|
Self::PaymentRequired => {
|
|
|
|
trace!("PaymentRequiredError");
|
|
|
|
(
|
|
|
|
StatusCode::PAYMENT_REQUIRED,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("Payment is required and user is not premium"),
|
|
|
|
code: StatusCode::PAYMENT_REQUIRED.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
User Balance + Referral Logic (#44)
* will implement balance topup endpoint
* will quickly fix other PR reviews
* merging from master
* will finish up godmoe
* will finish up login
* added logic to top up balance (first iteration)
* should implement additional columns soon (currency, amount, tx-hash), as well as a new table for spend
* updated migrations, will account for spend next
* get back to this later
* will merge PR from stats-v2
* stats v2
rebased all my commits and squashed them down to one
* cargo upgrade
* added migrtation for spend in accounting table. will run test-deposit next
* trying to get request from polygon
* first iteration /user/balance/:tx_hash works, needs to add accepted tokens next
* creating the referral code seems to work
* will now check if spending enough credits will lead to both parties receiving credits
* rpcstats takes care of accounting for spend data
* removed track spend from table
* Revert "removed track spend from table"
This reverts commit a50802d6ae75f786864c5ec42d0ceb2cb27124ed.
* Revert "rpcstats takes care of accounting for spend data"
This reverts commit 1cec728bf241e4cfd24351134637ed81c1a5a10b.
* removed rpc request table entity
* updated referral code to use ulid s
* credits used are aggregated
* added a bunch of fields to referrer
* added database logic whenever an aggregate stats is added. will have to iterate over this a couple times i think. go to (1) detecting accepted stables next, (2) fix influxdb bug and (3) start to write test
* removed track spend as this will occur in the database
* will first work on "balance", then referral. these should really be treated as two separate PRs (although already convoluted)
* balance logic initial commit
* breaking WIP, changing the RPC call logic functions
* will start testing next
* got rid of warnings & lint
* will proceed with subtracting / adding to balance
* added decimal points, balance tracking seems to work
* will beautify code a bit
* removed deprecated dependency, and added topic + deposit contract to app.yaml
* brownie test suite does not rely on local contract files it pulls all from polygonscan
* will continue with referral
* should perhaps (in a future revision) recordhow much the referees got for free. marking referrals seems to work rn
* user is upgraded to premium if they deposit more than 10$. we dont accept more than $10M in a single tx
* will start PR, referral seems to be fine so far, perhaps up to some numbers that still may need tweaking
* will start PR
* removed rogue comments, cleaned up payments a bit
* changes before PR
* apply stats
* added unique constraint
* some refactoring such that the user file is not too bloated
* compiling
* progress with subusers, creating a table entry seems to work
* good response type is there as well now, will work on getters from primary user and secondary user next
* subuser logic also seems fine now
* downgrade logic
* fixed bug influxdb does not support different types in same query (which makes sense)
* WIP temporary commit
* merging with PR
* Delete daemon.rs
there are multiple daemons now, so this was moved to `proxyd`
* will remove request clone to &mut
* multiple request handles for payment
* making requests still seem fine
* removed redundant commented out bits
* added deposit endpoint, added deposit amount and deposit user, untested yet
* small bug with downgrade tier id
* will add authorization so balance can be received for users
* balance history should be set now too
* will check balance over time again
* subususer can see rpc key balance if admin or owner
* stats also seems to work fine now with historical balance
* things seem to be building and working
* removed clone from OpenRequestHandle
* removed influxdb from workspace members
* changed config files
* reran sea-orm generate entities, added a foreign key, should be proper now
* removed contract from commit
* made deposit contract optional
* added topic in polygon dev
* changed deposit contract to deposit factory contract
* added selfrelation on user_tier
* added payment required
* changed chain id to u64
* add wss in polygon llamarpc
* removed origin and method from the table
* added onchain transactions naming (and forgot to add a migration before)
* changed foreign key to be the referrer (id), not the code itself
* forgot to add id as the target foreign key
* WIP adding cache to update role
* fixed merge conflicts
---------
Co-authored-by: Bryan Stitt <bryan@llamanodes.com>
Co-authored-by: Bryan Stitt <bryan@stitthappens.com>
2023-05-12 19:45:15 +03:00
|
|
|
)
|
|
|
|
}
|
2022-09-10 03:12:14 +03:00
|
|
|
// TODO: this should actually by the id of the key. multiple users might control one key
|
2022-11-08 22:58:11 +03:00
|
|
|
Self::RateLimited(authorization, retry_at) => {
|
2022-09-10 03:12:14 +03:00
|
|
|
// TODO: emit a stat
|
2022-11-08 22:58:11 +03:00
|
|
|
|
|
|
|
let retry_msg = if let Some(retry_at) = retry_at {
|
|
|
|
let retry_in = retry_at.duration_since(Instant::now()).as_secs();
|
|
|
|
|
|
|
|
format!(" Retry in {} seconds", retry_in)
|
|
|
|
} else {
|
|
|
|
"".to_string()
|
|
|
|
};
|
|
|
|
|
|
|
|
// create a string with either the IP or the rpc_key_id
|
2023-01-19 03:17:43 +03:00
|
|
|
let msg = if authorization.checks.rpc_secret_key_id.is_none() {
|
2022-11-08 22:58:11 +03:00
|
|
|
format!("too many requests from {}.{}", authorization.ip, retry_msg)
|
|
|
|
} else {
|
|
|
|
format!(
|
|
|
|
"too many requests from rpc key #{}.{}",
|
2023-01-19 03:17:43 +03:00
|
|
|
authorization.checks.rpc_secret_key_id.unwrap(),
|
2023-05-13 21:13:02 +03:00
|
|
|
retry_msg,
|
2022-11-08 22:58:11 +03:00
|
|
|
)
|
|
|
|
};
|
|
|
|
|
2022-09-10 03:12:14 +03:00
|
|
|
(
|
|
|
|
StatusCode::TOO_MANY_REQUESTS,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(msg),
|
|
|
|
code: StatusCode::TOO_MANY_REQUESTS.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-09-10 03:12:14 +03:00
|
|
|
)
|
|
|
|
}
|
2022-10-27 00:39:26 +03:00
|
|
|
Self::Redis(err) => {
|
2022-11-12 11:24:32 +03:00
|
|
|
warn!("redis err={:?}", err);
|
2022-10-27 00:39:26 +03:00
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("redis error!"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-10-27 00:39:26 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 01:50:25 +03:00
|
|
|
Self::RefererRequired => {
|
|
|
|
warn!("referer required");
|
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("Referer required"),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 01:50:25 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::RefererNotAllowed(referer) => {
|
|
|
|
warn!("referer not allowed referer={:?}", referer);
|
|
|
|
(
|
|
|
|
StatusCode::FORBIDDEN,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!("Referer ({:?}) is not allowed", referer)),
|
|
|
|
code: StatusCode::FORBIDDEN.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 01:50:25 +03:00
|
|
|
)
|
|
|
|
}
|
2022-12-14 05:13:23 +03:00
|
|
|
Self::SemaphoreAcquireError(err) => {
|
|
|
|
warn!("semaphore acquire err={:?}", err);
|
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
2022-12-14 05:13:23 +03:00
|
|
|
// TODO: is it safe to expose all of our anyhow strings?
|
2023-05-13 21:13:02 +03:00
|
|
|
message: Cow::Borrowed("semaphore acquire error"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-12-14 05:13:23 +03:00
|
|
|
)
|
|
|
|
}
|
2023-05-13 21:13:02 +03:00
|
|
|
Self::SendAppStatError(err) => {
|
2023-03-20 23:07:24 +03:00
|
|
|
error!("SendAppStatError err={:?}", err);
|
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("error stat_sender sending response_stat"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 23:07:24 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 04:52:28 +03:00
|
|
|
Self::SerdeJson(err) => {
|
2023-05-13 21:13:02 +03:00
|
|
|
warn!("serde json err={:?} source={:?}", err, err.source());
|
2023-03-20 04:52:28 +03:00
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!("de/serialization error! {}", err)),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 04:52:28 +03:00
|
|
|
)
|
|
|
|
}
|
2022-10-27 00:39:26 +03:00
|
|
|
Self::StatusCode(status_code, err_msg, err) => {
|
2022-11-16 10:19:56 +03:00
|
|
|
// different status codes should get different error levels. 500s should warn. 400s should stat
|
|
|
|
let code = status_code.as_u16();
|
|
|
|
if (500..600).contains(&code) {
|
2022-12-20 08:39:17 +03:00
|
|
|
warn!("server error {} {:?}: {:?}", code, err_msg, err);
|
2022-11-16 10:19:56 +03:00
|
|
|
} else {
|
|
|
|
trace!("user error {} {:?}: {:?}", code, err_msg, err);
|
|
|
|
}
|
|
|
|
|
2022-10-27 00:39:26 +03:00
|
|
|
(
|
|
|
|
status_code,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(err_msg),
|
|
|
|
code: code.into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-10-27 00:39:26 +03:00
|
|
|
)
|
|
|
|
}
|
2022-12-20 08:37:12 +03:00
|
|
|
Self::Timeout(x) => (
|
|
|
|
StatusCode::REQUEST_TIMEOUT,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!("request timed out: {:?}", x)),
|
|
|
|
code: StatusCode::REQUEST_TIMEOUT.as_u16().into(),
|
2022-12-20 08:37:12 +03:00
|
|
|
// TODO: include the actual id!
|
2023-05-13 21:13:02 +03:00
|
|
|
data: None,
|
|
|
|
},
|
2022-12-20 08:37:12 +03:00
|
|
|
),
|
2022-10-27 00:39:26 +03:00
|
|
|
Self::HeaderToString(err) => {
|
2022-12-20 08:37:12 +03:00
|
|
|
// trace!(?err, "HeaderToString");
|
2022-10-27 00:39:26 +03:00
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(err.to_string()),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-10-27 00:39:26 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-03 04:39:50 +03:00
|
|
|
Self::UlidDecode(err) => {
|
2022-12-20 08:37:12 +03:00
|
|
|
// trace!(?err, "UlidDecodeError");
|
2022-10-31 23:05:58 +03:00
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!("{}", err)),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-10-31 23:05:58 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 04:52:28 +03:00
|
|
|
Self::UnknownBlockNumber => {
|
|
|
|
error!("UnknownBlockNumber");
|
|
|
|
(
|
|
|
|
StatusCode::BAD_GATEWAY,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("no servers synced. unknown eth_blockNumber"),
|
|
|
|
code: StatusCode::BAD_GATEWAY.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 04:52:28 +03:00
|
|
|
)
|
|
|
|
}
|
2022-10-31 23:05:58 +03:00
|
|
|
// TODO: stat?
|
2022-09-12 17:33:55 +03:00
|
|
|
Self::UnknownKey => (
|
|
|
|
StatusCode::UNAUTHORIZED,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("unknown api key!"),
|
|
|
|
code: StatusCode::UNAUTHORIZED.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2022-09-12 17:33:55 +03:00
|
|
|
),
|
2023-03-20 01:50:25 +03:00
|
|
|
Self::UserAgentRequired => {
|
|
|
|
warn!("UserAgentRequired");
|
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("User agent required"),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 01:50:25 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::UserAgentNotAllowed(ua) => {
|
|
|
|
warn!("UserAgentNotAllowed ua={}", ua);
|
|
|
|
(
|
|
|
|
StatusCode::FORBIDDEN,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(format!("User agent ({}) is not allowed!", ua)),
|
|
|
|
code: StatusCode::FORBIDDEN.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 01:50:25 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 22:47:57 +03:00
|
|
|
Self::UserIdZero => {
|
|
|
|
warn!("UserIdZero");
|
2023-04-11 08:29:02 +03:00
|
|
|
// TODO: this might actually be an application error and not a BAD_REQUEST
|
2023-03-20 22:47:57 +03:00
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("user ids should always be non-zero"),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
Self::VerificationError(err) => {
|
2023-04-11 08:29:02 +03:00
|
|
|
trace!("VerificationError err={:?}", err);
|
2023-03-20 22:47:57 +03:00
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("verification error!"),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 22:47:57 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 04:52:28 +03:00
|
|
|
Self::WatchRecvError(err) => {
|
|
|
|
error!("WatchRecvError err={:?}", err);
|
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("watch recv error!"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 04:52:28 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 23:45:21 +03:00
|
|
|
Self::WatchSendError => {
|
|
|
|
error!("WatchSendError");
|
|
|
|
(
|
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed("watch send error!"),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 23:45:21 +03:00
|
|
|
)
|
|
|
|
}
|
2023-03-20 05:14:46 +03:00
|
|
|
Self::WebsocketOnly => {
|
2023-04-11 08:29:02 +03:00
|
|
|
trace!("WebsocketOnly");
|
2023-03-20 05:14:46 +03:00
|
|
|
(
|
|
|
|
StatusCode::BAD_REQUEST,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Borrowed(
|
|
|
|
"redirect_public_url not set. only websockets work here",
|
|
|
|
),
|
|
|
|
code: StatusCode::BAD_REQUEST.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-03-20 05:14:46 +03:00
|
|
|
)
|
|
|
|
}
|
2023-04-11 08:29:02 +03:00
|
|
|
Self::WithContext(err, msg) => match err {
|
|
|
|
Some(err) => {
|
|
|
|
warn!("{:#?} w/ context {}", err, msg);
|
2023-05-13 21:13:02 +03:00
|
|
|
return err.into_response_parts();
|
2023-04-11 08:29:02 +03:00
|
|
|
}
|
|
|
|
None => {
|
|
|
|
warn!("error w/ context {}", msg);
|
|
|
|
(
|
2023-03-20 21:38:54 +03:00
|
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
2023-05-13 21:13:02 +03:00
|
|
|
JsonRpcErrorData {
|
|
|
|
message: Cow::Owned(msg),
|
|
|
|
code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(),
|
|
|
|
data: None,
|
|
|
|
},
|
2023-04-11 08:29:02 +03:00
|
|
|
)
|
2023-03-20 21:38:54 +03:00
|
|
|
}
|
2023-04-11 08:29:02 +03:00
|
|
|
},
|
2023-05-13 21:13:02 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
(code, JsonRpcResponseData::from(err))
|
2023-01-19 03:17:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-20 23:07:24 +03:00
|
|
|
impl From<ethers::types::ParseBytesError> for Web3ProxyError {
|
|
|
|
fn from(err: ethers::types::ParseBytesError) -> Self {
|
|
|
|
Self::ParseBytesError(Some(err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-20 04:52:28 +03:00
|
|
|
impl From<tokio::time::error::Elapsed> for Web3ProxyError {
|
|
|
|
fn from(err: tokio::time::error::Elapsed) -> Self {
|
|
|
|
Self::Timeout(Some(err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-17 05:38:11 +03:00
|
|
|
impl IntoResponse for Web3ProxyError {
|
2023-01-19 03:17:43 +03:00
|
|
|
fn into_response(self) -> Response {
|
|
|
|
// TODO: include the request id in these so that users can give us something that will point to logs
|
|
|
|
// TODO: status code is in the jsonrpc response and is also the first item in the tuple. DRY
|
2023-05-13 21:13:02 +03:00
|
|
|
let (status_code, response_data) = self.into_response_parts();
|
|
|
|
|
|
|
|
// this will be missing the jsonrpc id!
|
|
|
|
// its better to get request id and call from_response_data with it then to use this IntoResponse helper.
|
|
|
|
let response =
|
|
|
|
JsonRpcForwardedResponse::from_response_data(response_data, Default::default());
|
2022-08-17 01:52:12 +03:00
|
|
|
|
2022-09-10 03:12:14 +03:00
|
|
|
(status_code, Json(response)).into_response()
|
2022-08-16 22:29:00 +03:00
|
|
|
}
|
|
|
|
}
|
2022-06-16 05:53:37 +03:00
|
|
|
|
2022-08-10 05:37:34 +03:00
|
|
|
pub async fn handler_404() -> Response {
|
2023-03-17 05:38:11 +03:00
|
|
|
Web3ProxyError::NotFound.into_response()
|
2022-06-05 22:58:47 +03:00
|
|
|
}
|
2023-03-20 21:38:54 +03:00
|
|
|
|
|
|
|
pub trait Web3ProxyErrorContext<T> {
|
|
|
|
fn web3_context<S: Into<String>>(self, msg: S) -> Result<T, Web3ProxyError>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Web3ProxyErrorContext<T> for Option<T> {
|
|
|
|
fn web3_context<S: Into<String>>(self, msg: S) -> Result<T, Web3ProxyError> {
|
|
|
|
self.ok_or(Web3ProxyError::WithContext(None, msg.into()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T, E> Web3ProxyErrorContext<T> for Result<T, E>
|
|
|
|
where
|
|
|
|
E: Into<Web3ProxyError>,
|
|
|
|
{
|
|
|
|
fn web3_context<S: Into<String>>(self, msg: S) -> Result<T, Web3ProxyError> {
|
|
|
|
self.map_err(|err| Web3ProxyError::WithContext(Some(Box::new(err.into())), msg.into()))
|
|
|
|
}
|
|
|
|
}
|