Skip to content

Commit

Permalink
fix: progress on removing unwraps (#2880)
Browse files Browse the repository at this point in the history
### Description

<!--
What's included in this PR?
-->

### Drive-by changes

<!--
Are there any minor or drive-by changes also included?
-->

### Related issues

<!--
- Fixes #[issue number here]
-->

### Backward compatibility

<!--
Are these changes backward compatible? Are there any infrastructure
implications, e.g. changes that would prohibit deploying older commits
using this infra tooling?

Yes/No
-->

### Testing

<!--
What kind of testing have these changes undergone?

None/Manual/Unit Tests
-->
  • Loading branch information
daniel-savu authored Nov 1, 2023
1 parent bd8418c commit 00bd471
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 88 deletions.
1 change: 1 addition & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 16 additions & 27 deletions rust/chains/hyperlane-cosmos/src/interchain_gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,57 +67,46 @@ impl CosmosInterchainGasPaymasterIndexer {
}
}

fn get_parser(&self) -> fn(attrs: Vec<EventAttribute>) -> Option<InterchainGasPayment> {
|attrs: Vec<EventAttribute>| -> Option<InterchainGasPayment> {
let mut res = InterchainGasPayment {
message_id: H256::zero(),
payment: U256::zero(),
gas_amount: U256::zero(),
destination: 0,
};

fn get_parser(
&self,
) -> fn(attrs: Vec<EventAttribute>) -> ChainResult<Option<InterchainGasPayment>> {
|attrs: Vec<EventAttribute>| -> ChainResult<Option<InterchainGasPayment>> {
let mut res = InterchainGasPayment::default();
for attr in attrs {
let key = attr.key.as_str();
let value = attr.value;
let value = value.as_str();

match key {
"message_id" => {
res.message_id = H256::from_slice(hex::decode(value).unwrap().as_slice())
res.message_id = H256::from_slice(hex::decode(value)?.as_slice())
}
"bWVzc2FnZV9pZA==" => {
res.message_id = H256::from_slice(
hex::decode(
String::from_utf8(STANDARD.decode(value).unwrap()).unwrap(),
)
.unwrap()
.as_slice(),
hex::decode(String::from_utf8(STANDARD.decode(value)?)?)?.as_slice(),
)
}
"payment" => res.payment = value.parse().unwrap(),
"payment" => res.payment = value.parse()?,
"cGF5bWVudA==" => {
let dec_str = String::from_utf8(STANDARD.decode(value).unwrap()).unwrap();
let dec_str = String::from_utf8(STANDARD.decode(value)?)?;
// U256's from_str assumes a radix of 16, so we explicitly use from_dec_str.
res.payment = U256::from_dec_str(dec_str.as_str()).unwrap();
res.payment = U256::from_dec_str(dec_str.as_str())?;
}
"gas_amount" => res.gas_amount = value.parse().unwrap(),
"gas_amount" => res.gas_amount = value.parse()?,
"Z2FzX2Ftb3VudA==" => {
let dec_str = String::from_utf8(STANDARD.decode(value).unwrap()).unwrap();
let dec_str = String::from_utf8(STANDARD.decode(value)?)?;
// U256's from_str assumes a radix of 16, so we explicitly use from_dec_str.
res.gas_amount = U256::from_dec_str(dec_str.as_str()).unwrap();
res.gas_amount = U256::from_dec_str(dec_str.as_str())?;
}
"dest_domain" => res.destination = value.parse().unwrap(),
"dest_domain" => res.destination = value.parse()?,
"ZGVzdF9kb21haW4=" => {
res.destination = String::from_utf8(STANDARD.decode(value).unwrap())
.unwrap()
.parse()
.unwrap()
res.destination = String::from_utf8(STANDARD.decode(value)?)?.parse()?
}
_ => {}
}
}

Some(res)
Ok(Some(res))
}
}
}
Expand Down
45 changes: 24 additions & 21 deletions rust/chains/hyperlane-cosmos/src/mailbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ use hyperlane_core::{
HyperlaneMessage, HyperlaneProvider, Indexer, LogMeta, Mailbox, TxCostEstimate, TxOutcome,
H256, U256,
};
use hyperlane_core::{ContractLocator, Decode, RawHyperlaneMessage, SequenceIndexer};
use hyperlane_core::{
ChainCommunicationError, ContractLocator, Decode, RawHyperlaneMessage, SequenceIndexer,
};
use tracing::{instrument, warn};

/// A reference to a Mailbox contract on some Cosmos chain
Expand Down Expand Up @@ -171,7 +173,7 @@ impl Mailbox for CosmosMailbox {
.await?;
Ok(TxOutcome {
transaction_id: h256_to_h512(H256::from_slice(
hex::decode(response.txhash).unwrap().as_slice(),
hex::decode(response.txhash)?.as_slice(),
)),
executed: response.code == 0,
gas_used: U256::from(response.gas_used),
Expand All @@ -194,7 +196,14 @@ impl Mailbox for CosmosMailbox {

let response: SimulateResponse = self.provider.wasm_simulate(process_message).await?;
let result = TxCostEstimate {
gas_limit: U256::from(response.gas_info.unwrap().gas_used),
gas_limit: U256::from(
response
.gas_info
.ok_or(ChainCommunicationError::TxCostEstimateError(
"Failed to estimate gas limit".to_string(),
))?
.gas_used,
),
gas_price: U256::from(2500),
l2_gas_limit: None,
};
Expand Down Expand Up @@ -250,8 +259,10 @@ impl CosmosMailboxIndexer {
}
}

fn get_parser(&self) -> fn(attrs: Vec<EventAttribute>) -> Option<HyperlaneMessage> {
|attrs: Vec<EventAttribute>| -> Option<HyperlaneMessage> {
fn get_parser(
&self,
) -> fn(attrs: Vec<EventAttribute>) -> ChainResult<Option<HyperlaneMessage>> {
|attrs: Vec<EventAttribute>| -> ChainResult<Option<HyperlaneMessage>> {
let res = HyperlaneMessage::default();

for attr in attrs {
Expand All @@ -260,26 +271,18 @@ impl CosmosMailboxIndexer {
let value = value.as_str();

if key == "message" {
let mut reader = Cursor::new(hex::decode(value).unwrap());
return Some(HyperlaneMessage::read_from(&mut reader).unwrap());
let mut reader = Cursor::new(hex::decode(value)?);
return Ok(Some(HyperlaneMessage::read_from(&mut reader)?));
}

if key == "bWVzc2FnZQ==" {
let mut reader = Cursor::new(
hex::decode(
String::from_utf8(
base64::engine::general_purpose::STANDARD
.decode(value)
.unwrap(),
)
.unwrap(),
)
.unwrap(),
);
return Some(HyperlaneMessage::read_from(&mut reader).unwrap());
let mut reader = Cursor::new(hex::decode(String::from_utf8(
base64::engine::general_purpose::STANDARD.decode(value)?,
)?)?);
return Ok(Some(HyperlaneMessage::read_from(&mut reader)?));
}
}
None
Ok(None)
}
}
}
Expand All @@ -304,7 +307,7 @@ impl Indexer<HyperlaneMessage> for CosmosMailboxIndexer {
#[async_trait]
impl Indexer<H256> for CosmosMailboxIndexer {
async fn fetch_logs(&self, range: RangeInclusive<u32>) -> ChainResult<Vec<(H256, LogMeta)>> {
let parser: fn(Vec<EventAttribute>) -> Option<HyperlaneMessage> = self.get_parser();
let parser = self.get_parser();
let result = self.indexer.get_range_event_logs(range, parser).await?;

Ok(result
Expand Down
36 changes: 14 additions & 22 deletions rust/chains/hyperlane-cosmos/src/merkle_tree_hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,10 @@ impl CosmosMerkleeTreeHookIndexer {
}

/// Get the parser for the indexer
fn get_parser(&self) -> fn(attrs: Vec<EventAttribute>) -> Option<MerkleTreeInsertion> {
|attrs: Vec<EventAttribute>| -> Option<MerkleTreeInsertion> {
fn get_parser(
&self,
) -> fn(attrs: Vec<EventAttribute>) -> ChainResult<Option<MerkleTreeInsertion>> {
|attrs: Vec<EventAttribute>| -> ChainResult<Option<MerkleTreeInsertion>> {
let mut message_id = H256::zero();
let mut leaf_index: u32 = 0;
let mut attr_count = 0;
Expand All @@ -191,35 +193,25 @@ impl CosmosMerkleeTreeHookIndexer {

match key {
"message_id" => {
message_id = H256::from_slice(hex::decode(value).unwrap().as_slice());
message_id = H256::from_slice(hex::decode(value)?.as_slice());
attr_count += 1;
}
"index" => {
leaf_index = value.parse().unwrap();
leaf_index = value.parse::<u32>()?;
attr_count += 1;
}
"aW5kZXg=" => {
leaf_index = String::from_utf8(
base64::engine::general_purpose::STANDARD
.decode(value)
.unwrap(),
)
.unwrap()
.parse()
.unwrap();
base64::engine::general_purpose::STANDARD.decode(value)?,
)?
.parse()?;
attr_count += 1;
}
"bWVzc2FnZV9pZA==" => {
message_id = H256::from_slice(
hex::decode(
String::from_utf8(
base64::engine::general_purpose::STANDARD
.decode(value)
.unwrap(),
)
.unwrap(),
)
.unwrap()
hex::decode(String::from_utf8(
base64::engine::general_purpose::STANDARD.decode(value)?,
)?)?
.as_slice(),
);
attr_count += 1;
Expand All @@ -229,10 +221,10 @@ impl CosmosMerkleeTreeHookIndexer {
}

if attr_count != 2 {
return None;
return Ok(None);
}

Some(MerkleTreeInsertion::new(leaf_index, message_id))
Ok(Some(MerkleTreeInsertion::new(leaf_index, message_id)))
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions rust/chains/hyperlane-cosmos/src/providers/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub trait WasmIndexer: Send + Sync {
async fn get_range_event_logs<T>(
&self,
range: RangeInclusive<u32>,
parser: fn(Vec<EventAttribute>) -> Option<T>,
parser: fn(Vec<EventAttribute>) -> ChainResult<Option<T>>,
) -> ChainResult<Vec<(T, LogMeta)>>
where
T: Send + Sync;
Expand Down Expand Up @@ -93,7 +93,7 @@ impl WasmIndexer for CosmosWasmIndexer {
async fn get_range_event_logs<T>(
&self,
range: RangeInclusive<u32>,
parser: fn(Vec<EventAttribute>) -> Option<T>,
parser: fn(Vec<EventAttribute>) -> ChainResult<Option<T>>,
) -> ChainResult<Vec<(T, LogMeta)>>
where
T: Send + Sync,
Expand All @@ -120,7 +120,7 @@ impl WasmIndexer for CosmosWasmIndexer {
let last_page = total_count / PAGINATION_LIMIT as u32
+ (total_count % PAGINATION_LIMIT as u32 != 0) as u32;

let handler = |txs: Vec<tx::Response>| -> Vec<(T, LogMeta)> {
let handler = |txs: Vec<tx::Response>| -> ChainResult<Vec<(T, LogMeta)>> {
let mut result: Vec<(T, LogMeta)> = vec![];
let target_type = format!("{}-{}", Self::WASM_TYPE, self.event_type);

Expand All @@ -137,7 +137,7 @@ impl WasmIndexer for CosmosWasmIndexer {

for (log_idx, event) in tx.tx_result.events.clone().into_iter().enumerate() {
if event.kind.as_str() == target_type {
if let Some(msg) = parser(event.attributes.clone()) {
if let Some(msg) = parser(event.attributes.clone())? {
let meta = LogMeta {
address: bech32_decode(contract_address.clone()),
block_number: tx.height.value(),
Expand All @@ -156,10 +156,10 @@ impl WasmIndexer for CosmosWasmIndexer {
result.extend(parse_result);
}

result
Ok(result)
};

let mut result = handler(tx_search_result.txs);
let mut result = handler(tx_search_result.txs)?;

for page in 2..=last_page {
debug!(page, "Making tx search RPC");
Expand All @@ -174,7 +174,7 @@ impl WasmIndexer for CosmosWasmIndexer {
)
.await?;

result.extend(handler(tx_search_result.txs));
result.extend(handler(tx_search_result.txs)?);
}

Ok(result)
Expand Down
1 change: 1 addition & 0 deletions rust/hyperlane-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ version = { workspace = true }
[dependencies]
async-trait.workspace = true
auto_impl.workspace = true
base64 = { workspace = true }
borsh.workspace = true
bs58.workspace = true
bytes = { workspace = true, features = ["serde"] }
Expand Down
30 changes: 20 additions & 10 deletions rust/hyperlane-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ use std::ops::Deref;
use crate::config::StrOrIntParseError;
use cosmrs::proto::prost;
use cosmrs::Error as CosmrsError;
// use ethers_contract::ContractError;
// use ethers_core::types::SignatureError;
// use ethers_providers::{Middleware, ProviderError};
use std::string::FromUtf8Error;

use crate::HyperlaneProviderError;
use crate::H256;
Expand Down Expand Up @@ -105,12 +103,27 @@ pub enum ChainCommunicationError {
/// protobuf error
#[error("{0}")]
Protobuf(#[from] prost::DecodeError),
/// base64 error
#[error("{0}")]
Base64(#[from] base64::DecodeError),
/// utf8 error
#[error("{0}")]
Utf8(#[from] FromUtf8Error),
/// Serde JSON error
#[error("{0}")]
JsonParseError(#[from] serde_json::Error),
/// Hex parse error
/// String hex parsing error
#[error("{0}")]
HexParseError(#[from] hex::FromHexError),
/// Uint hex parsing error
#[error("{0}")]
UintParseError(#[from] uint::FromHexError),
/// Decimal string parsing error
#[error("{0}")]
FromDecStrError(#[from] uint::FromDecStrErr),
/// Int string parsing error
#[error("{0}")]
ParseIntError(#[from] std::num::ParseIntError),
/// Invalid Request
#[error("Invalid Request: {msg:?}")]
InvalidRequest {
Expand All @@ -123,12 +136,9 @@ pub enum ChainCommunicationError {
/// Error message
msg: String,
},
/// Not match connection type
#[error("Not match connection type: require {msg:?}")]
NotMatchConnectionType {
/// Error message
msg: String,
},
/// Failed to estimate transaction gas cost.
#[error("Failed to estimate transaction gas cost {0}")]
TxCostEstimateError(String),
}

impl ChainCommunicationError {
Expand Down
2 changes: 1 addition & 1 deletion rust/hyperlane-core/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ pub struct GasPaymentKey {
}

/// A payment of a message's gas costs.
#[derive(Debug, Copy, Clone)]
#[derive(Debug, Copy, Clone, Default)]
pub struct InterchainGasPayment {
/// Id of the message
pub message_id: H256,
Expand Down

0 comments on commit 00bd471

Please sign in to comment.