Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: progress on removing unwraps #2880

Merged
merged 2 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -186,7 +188,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 @@ -209,7 +211,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 @@ -248,8 +257,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 @@ -258,26 +269,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 Down Expand Up @@ -333,7 +336,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 @@ -171,8 +171,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 @@ -184,35 +186,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 @@ -222,10 +214,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
8 changes: 8 additions & 0 deletions rust/hyperlane-core/src/types/primitive_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,14 @@ impl_fixed_hash_serde!(H160, 20);
impl_fixed_hash_serde!(H256, 32);
impl_fixed_hash_serde!(H512, 64);

// impl TryFrom<String> for H256 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm or keep?

// type Error = ChainCommunicationError;

// fn try_from(value: String) -> Result<Self, Self::Error> {
// Ok(H256::from_slice(hex::decode(value)?.as_slice()))
// }
// }

#[cfg(feature = "solana")]
impl From<solana_sdk::hash::Hash> for H256 {
fn from(hash: solana_sdk::hash::Hash) -> Self {
Expand Down
Loading