Skip to content

Commit 567ba78

Browse files
committed
eth: add EthError variants, make all fns return EthError instead of anyhow
1 parent 8e4d015 commit 567ba78

File tree

1 file changed

+100
-65
lines changed

1 file changed

+100
-65
lines changed

src/eth.rs

Lines changed: 100 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub struct EthSubError {
5353
}
5454

5555
/// The Response type which a process will get from requesting with an [`EthAction`] will be
56-
/// of the form `Result<(), EthError>`, serialized and deserialized using `serde_json::to_vec`
56+
/// of this type, serialized and deserialized using `serde_json::to_vec`
5757
/// and `serde_json::from_slice`.
5858
#[derive(Debug, Serialize, Deserialize)]
5959
pub enum EthResponse {
@@ -74,10 +74,14 @@ pub enum EthError {
7474
SubscriptionNotFound,
7575
/// Invalid method
7676
InvalidMethod(String),
77+
/// Invalid params
78+
InvalidParams,
7779
/// Permission denied
7880
PermissionDenied,
7981
/// Internal RPC error
8082
RpcError(String),
83+
/// RPC timed out
84+
RpcTimeout,
8185
}
8286

8387
/// The action type used for configuring eth:distro:sys. Only processes which have the "root"
@@ -163,30 +167,33 @@ impl Provider {
163167
pub fn send_request_and_parse_response<T: serde::de::DeserializeOwned>(
164168
&self,
165169
action: EthAction,
166-
) -> anyhow::Result<T> {
170+
) -> Result<T, EthError> {
167171
let resp = KiRequest::new()
168172
.target(("our", "eth", "distro", "sys"))
169-
.body(serde_json::to_vec(&action)?)
170-
.send_and_await_response(self.request_timeout)??;
173+
.body(serde_json::to_vec(&action).unwrap())
174+
.send_and_await_response(self.request_timeout)
175+
.unwrap()
176+
.map_err(|_| EthError::RpcTimeout)?;
171177

172178
match resp {
173179
Message::Response { body, .. } => {
174-
let response = serde_json::from_slice::<EthResponse>(&body)?;
180+
let response = serde_json::from_slice::<EthResponse>(&body);
175181
match response {
176-
EthResponse::Response { value } => serde_json::from_value::<T>(value)
177-
.map_err(|e| anyhow::anyhow!("failed to parse response: {}", e)),
178-
_ => Err(anyhow::anyhow!("unexpected response: {:?}", response)),
182+
Ok(EthResponse::Response { value }) => serde_json::from_value::<T>(value)
183+
.map_err(|e| EthError::RpcError(format!("{e:?}"))),
184+
Ok(EthResponse::Err(e)) => Err(e),
185+
_ => Err(EthError::RpcError("unexpected response".to_string())),
179186
}
180187
}
181-
_ => Err(anyhow::anyhow!("unexpected message type: {:?}", resp)),
188+
_ => Err(EthError::RpcError("unexpected response".to_string())),
182189
}
183190
}
184191

185192
/// Retrieves the current block number.
186193
///
187194
/// # Returns
188-
/// An `anyhow::Result<u64>` representing the current block number.
189-
pub fn get_block_number(&self) -> anyhow::Result<u64> {
195+
/// A `Result<u64, EthError>` representing the current block number.
196+
pub fn get_block_number(&self) -> Result<u64, EthError> {
190197
let action = EthAction::Request {
191198
chain_id: self.chain_id,
192199
method: "eth_blockNumber".to_string(),
@@ -204,12 +211,13 @@ impl Provider {
204211
/// - `tag`: Optional block ID to specify the block at which the balance is queried.
205212
///
206213
/// # Returns
207-
/// An `anyhow::Result<U256>` representing the balance of the address.
208-
pub fn get_balance(&self, address: Address, tag: Option<BlockId>) -> anyhow::Result<U256> {
214+
/// A `Result<U256, EthError>` representing the balance of the address.
215+
pub fn get_balance(&self, address: Address, tag: Option<BlockId>) -> Result<U256, EthError> {
209216
let params = serde_json::to_value((
210217
address,
211218
tag.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)),
212-
))?;
219+
))
220+
.unwrap();
213221
let action = EthAction::Request {
214222
chain_id: self.chain_id,
215223
method: "eth_getBalance".to_string(),
@@ -225,12 +233,15 @@ impl Provider {
225233
/// - `filter`: The filter criteria for the logs.
226234
///
227235
/// # Returns
228-
/// An `anyhow::Result<Vec<Log>>` containing the logs that match the filter.
229-
pub fn get_logs(&self, filter: &Filter) -> anyhow::Result<Vec<Log>> {
236+
/// A `Result<Vec<Log>, EthError>` containing the logs that match the filter.
237+
pub fn get_logs(&self, filter: &Filter) -> Result<Vec<Log>, EthError> {
238+
let Ok(params) = serde_json::to_value(filter) else {
239+
return Err(EthError::InvalidParams);
240+
};
230241
let action = EthAction::Request {
231242
chain_id: self.chain_id,
232243
method: "eth_getLogs".to_string(),
233-
params: serde_json::to_value(filter)?,
244+
params,
234245
};
235246

236247
self.send_request_and_parse_response::<Vec<Log>>(action)
@@ -239,8 +250,8 @@ impl Provider {
239250
/// Retrieves the current gas price.
240251
///
241252
/// # Returns
242-
/// An `anyhow::Result<U256>` representing the current gas price.
243-
pub fn get_gas_price(&self) -> anyhow::Result<U256> {
253+
/// A `Result<U256, EthError>` representing the current gas price.
254+
pub fn get_gas_price(&self) -> Result<U256, EthError> {
244255
let action = EthAction::Request {
245256
chain_id: self.chain_id,
246257
method: "eth_gasPrice".to_string(),
@@ -257,13 +268,15 @@ impl Provider {
257268
/// - `tag`: Optional block ID to specify the block at which the count is queried.
258269
///
259270
/// # Returns
260-
/// An `anyhow::Result<U256>` representing the number of transactions sent from the address.
271+
/// A `Result<U256, EthError>` representing the number of transactions sent from the address.
261272
pub fn get_transaction_count(
262273
&self,
263274
address: Address,
264275
tag: Option<BlockId>,
265-
) -> anyhow::Result<U256> {
266-
let params = serde_json::to_value((address, tag.unwrap_or_default()))?;
276+
) -> Result<U256, EthError> {
277+
let Ok(params) = serde_json::to_value((address, tag.unwrap_or_default())) else {
278+
return Err(EthError::InvalidParams);
279+
};
267280
let action = EthAction::Request {
268281
chain_id: self.chain_id,
269282
method: "eth_getTransactionCount".to_string(),
@@ -280,13 +293,15 @@ impl Provider {
280293
/// - `full_tx`: Whether to return full transaction objects or just their hashes.
281294
///
282295
/// # Returns
283-
/// An `anyhow::Result<Option<Block>>` representing the block, if found.
296+
/// A `Result<Option<Block>, EthError>` representing the block, if found.
284297
pub fn get_block_by_hash(
285298
&self,
286299
hash: BlockHash,
287300
full_tx: bool,
288-
) -> anyhow::Result<Option<Block>> {
289-
let params = serde_json::to_value((hash, full_tx))?;
301+
) -> Result<Option<Block>, EthError> {
302+
let Ok(params) = serde_json::to_value((hash, full_tx)) else {
303+
return Err(EthError::InvalidParams);
304+
};
290305
let action = EthAction::Request {
291306
chain_id: self.chain_id,
292307
method: "eth_getBlockByHash".to_string(),
@@ -302,13 +317,15 @@ impl Provider {
302317
/// - `full_tx`: Whether to return full transaction objects or just their hashes.
303318
///
304319
/// # Returns
305-
/// An `anyhow::Result<Option<Block>>` representing the block, if found.
320+
/// A `Result<Option<Block>, EthError>` representing the block, if found.
306321
pub fn get_block_by_number(
307322
&self,
308323
number: BlockNumberOrTag,
309324
full_tx: bool,
310-
) -> anyhow::Result<Option<Block>> {
311-
let params = serde_json::to_value((number, full_tx))?;
325+
) -> Result<Option<Block>, EthError> {
326+
let Ok(params) = serde_json::to_value((number, full_tx)) else {
327+
return Err(EthError::InvalidParams);
328+
};
312329
let action = EthAction::Request {
313330
chain_id: self.chain_id,
314331
method: "eth_getBlockByNumber".to_string(),
@@ -326,14 +343,16 @@ impl Provider {
326343
/// - `tag`: Optional block ID to specify the block at which the storage is queried.
327344
///
328345
/// # Returns
329-
/// An `anyhow::Result<Bytes>` representing the data stored at the given address and key.
346+
/// A `Result<Bytes, EthError>` representing the data stored at the given address and key.
330347
pub fn get_storage_at(
331348
&self,
332349
address: Address,
333350
key: U256,
334351
tag: Option<BlockId>,
335-
) -> anyhow::Result<Bytes> {
336-
let params = serde_json::to_value((address, key, tag.unwrap_or_default()))?;
352+
) -> Result<Bytes, EthError> {
353+
let Ok(params) = serde_json::to_value((address, key, tag.unwrap_or_default())) else {
354+
return Err(EthError::InvalidParams);
355+
};
337356
let action = EthAction::Request {
338357
chain_id: self.chain_id,
339358
method: "eth_getStorageAt".to_string(),
@@ -350,9 +369,11 @@ impl Provider {
350369
/// - `tag`: The block ID to specify the block at which the code is queried.
351370
///
352371
/// # Returns
353-
/// An `anyhow::Result<Bytes>` representing the code stored at the given address.
354-
pub fn get_code_at(&self, address: Address, tag: BlockId) -> anyhow::Result<Bytes> {
355-
let params = serde_json::to_value((address, tag))?;
372+
/// A `Result<Bytes, EthError>` representing the code stored at the given address.
373+
pub fn get_code_at(&self, address: Address, tag: BlockId) -> Result<Bytes, EthError> {
374+
let Ok(params) = serde_json::to_value((address, tag)) else {
375+
return Err(EthError::InvalidParams);
376+
};
356377
let action = EthAction::Request {
357378
chain_id: self.chain_id,
358379
method: "eth_getCode".to_string(),
@@ -368,9 +389,11 @@ impl Provider {
368389
/// - `hash`: The hash of the transaction to retrieve.
369390
///
370391
/// # Returns
371-
/// An `anyhow::Result<Option<Transaction>>` representing the transaction, if found.
372-
pub fn get_transaction_by_hash(&self, hash: TxHash) -> anyhow::Result<Option<Transaction>> {
373-
let params = serde_json::to_value(hash)?;
392+
/// A `Result<Option<Transaction>, EthError>` representing the transaction, if found.
393+
pub fn get_transaction_by_hash(&self, hash: TxHash) -> Result<Option<Transaction>, EthError> {
394+
let Ok(params) = serde_json::to_value(hash) else {
395+
return Err(EthError::InvalidParams);
396+
};
374397
let action = EthAction::Request {
375398
chain_id: self.chain_id,
376399
method: "eth_getTransactionByHash".to_string(),
@@ -386,12 +409,14 @@ impl Provider {
386409
/// - `hash`: The hash of the transaction for which the receipt is requested.
387410
///
388411
/// # Returns
389-
/// An `anyhow::Result<Option<TransactionReceipt>>` representing the transaction receipt, if found.
412+
/// A `Result<Option<TransactionReceipt>, EthError>` representing the transaction receipt, if found.
390413
pub fn get_transaction_receipt(
391414
&self,
392415
hash: TxHash,
393-
) -> anyhow::Result<Option<TransactionReceipt>> {
394-
let params = serde_json::to_value(hash)?;
416+
) -> Result<Option<TransactionReceipt>, EthError> {
417+
let Ok(params) = serde_json::to_value(hash) else {
418+
return Err(EthError::InvalidParams);
419+
};
395420
let action = EthAction::Request {
396421
chain_id: self.chain_id,
397422
method: "eth_getTransactionReceipt".to_string(),
@@ -408,13 +433,15 @@ impl Provider {
408433
/// - `block`: Optional block ID to specify the block at which the gas estimate should be made.
409434
///
410435
/// # Returns
411-
/// An `anyhow::Result<U256>` representing the estimated gas amount.
436+
/// A `Result<U256, EthError>` representing the estimated gas amount.
412437
pub fn estimate_gas(
413438
&self,
414439
tx: TransactionRequest,
415440
block: Option<BlockId>,
416-
) -> anyhow::Result<U256> {
417-
let params = serde_json::to_value((tx, block.unwrap_or_default()))?;
441+
) -> Result<U256, EthError> {
442+
let Ok(params) = serde_json::to_value((tx, block.unwrap_or_default())) else {
443+
return Err(EthError::InvalidParams);
444+
};
418445
let action = EthAction::Request {
419446
chain_id: self.chain_id,
420447
method: "eth_estimateGas".to_string(),
@@ -427,9 +454,9 @@ impl Provider {
427454
/// Retrieves the list of accounts controlled by the node.
428455
///
429456
/// # Returns
430-
/// An `anyhow::Result<Vec<Address>>` representing the list of accounts.
457+
/// A `Result<Vec<Address>, EthError>` representing the list of accounts.
431458
/// Note: This function may return an empty list depending on the node's configuration and capabilities.
432-
pub fn get_accounts(&self) -> anyhow::Result<Vec<Address>> {
459+
pub fn get_accounts(&self) -> Result<Vec<Address>, EthError> {
433460
let action = EthAction::Request {
434461
chain_id: self.chain_id,
435462
method: "eth_accounts".to_string(),
@@ -447,14 +474,16 @@ impl Provider {
447474
/// - `reward_percentiles`: A list of percentiles to report fee rewards for.
448475
///
449476
/// # Returns
450-
/// An `anyhow::Result<FeeHistory>` representing the fee history for the specified range.
477+
/// A `Result<FeeHistory, EthError>` representing the fee history for the specified range.
451478
pub fn get_fee_history(
452479
&self,
453480
block_count: U256,
454481
last_block: BlockNumberOrTag,
455482
reward_percentiles: Vec<f64>,
456-
) -> anyhow::Result<FeeHistory> {
457-
let params = serde_json::to_value((block_count, last_block, reward_percentiles))?;
483+
) -> Result<FeeHistory, EthError> {
484+
let Ok(params) = serde_json::to_value((block_count, last_block, reward_percentiles)) else {
485+
return Err(EthError::InvalidParams);
486+
};
458487
let action = EthAction::Request {
459488
chain_id: self.chain_id,
460489
method: "eth_feeHistory".to_string(),
@@ -471,9 +500,11 @@ impl Provider {
471500
/// - `block`: Optional block ID to specify the block at which the call should be made.
472501
///
473502
/// # Returns
474-
/// An `anyhow::Result<Bytes>` representing the result of the call.
475-
pub fn call(&self, tx: TransactionRequest, block: Option<BlockId>) -> anyhow::Result<Bytes> {
476-
let params = serde_json::to_value((tx, block.unwrap_or_default()))?;
503+
/// A `Result<Bytes, EthError>` representing the result of the call.
504+
pub fn call(&self, tx: TransactionRequest, block: Option<BlockId>) -> Result<Bytes, EthError> {
505+
let Ok(params) = serde_json::to_value((tx, block.unwrap_or_default())) else {
506+
return Err(EthError::InvalidParams);
507+
};
477508
let action = EthAction::Request {
478509
chain_id: self.chain_id,
479510
method: "eth_call".to_string(),
@@ -489,12 +520,12 @@ impl Provider {
489520
/// - `tx`: The raw transaction data.
490521
///
491522
/// # Returns
492-
/// An `anyhow::Result<TxHash>` representing the hash of the transaction once it has been sent.
493-
pub fn send_raw_transaction(&self, tx: Bytes) -> anyhow::Result<TxHash> {
523+
/// A `Result<TxHash, EthError>` representing the hash of the transaction once it has been sent.
524+
pub fn send_raw_transaction(&self, tx: Bytes) -> Result<TxHash, EthError> {
494525
let action = EthAction::Request {
495526
chain_id: self.chain_id,
496527
method: "eth_sendRawTransaction".to_string(),
497-
params: serde_json::to_value(tx)?,
528+
params: serde_json::to_value(tx).unwrap(),
498529
};
499530

500531
self.send_request_and_parse_response::<TxHash>(action)
@@ -507,32 +538,36 @@ impl Provider {
507538
/// - `filter`: The filter criteria for the logs.
508539
///
509540
/// # Returns
510-
/// An `anyhow::Result<()>` indicating whether the subscription was created.
511-
pub fn subscribe(&self, sub_id: u64, filter: Filter) -> anyhow::Result<()> {
541+
/// A `Result<(), EthError>` indicating whether the subscription was created.
542+
pub fn subscribe(&self, sub_id: u64, filter: Filter) -> Result<(), EthError> {
512543
let action = EthAction::SubscribeLogs {
513544
sub_id,
514545
chain_id: self.chain_id,
515546
kind: SubscriptionKind::Logs,
516547
params: Params::Logs(Box::new(filter)),
517548
};
518549

550+
let Ok(body) = serde_json::to_vec(&action) else {
551+
return Err(EthError::InvalidParams);
552+
};
553+
519554
let resp = KiRequest::new()
520555
.target(("our", "eth", "distro", "sys"))
521-
.body(serde_json::to_vec(&action)?)
522-
.send_and_await_response(self.request_timeout)??;
556+
.body(body)
557+
.send_and_await_response(self.request_timeout)
558+
.unwrap()
559+
.map_err(|_| EthError::RpcTimeout)?;
523560

524561
match resp {
525562
Message::Response { body, .. } => {
526-
let response = serde_json::from_slice::<EthResponse>(&body)?;
563+
let response = serde_json::from_slice::<EthResponse>(&body);
527564
match response {
528-
EthResponse::Ok => Ok(()),
529-
EthResponse::Response { .. } => {
530-
Err(anyhow::anyhow!("unexpected response: {:?}", response))
531-
}
532-
EthResponse::Err(e) => Err(anyhow::anyhow!("{e:?}")),
565+
Ok(EthResponse::Ok) => Ok(()),
566+
Ok(EthResponse::Err(e)) => Err(e),
567+
_ => Err(EthError::RpcError("unexpected response".to_string())),
533568
}
534569
}
535-
_ => Err(anyhow::anyhow!("unexpected message type: {:?}", resp)),
570+
_ => Err(EthError::RpcError("unexpected response".to_string())),
536571
}
537572
}
538573

0 commit comments

Comments
 (0)