-
Notifications
You must be signed in to change notification settings - Fork 420
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: finish removing unwraps (#2881)
### Description - Removes unwraps and expects from everywhere but `run-locally` - Precomputes the `address` in `Signer` at construction time, to propagate the error early and keep signatures ergonomic by not requiring a `Result`. Couldn't also precompile `SigningKey` (the privkey type) because it's not `Sync` 😢 - Defines a `hyperlane-cosmos`-specific error enum (`HyperlaneCosmosError`), which can be converted to `ChainCommunicationError` with the `?` operator. This is a pattern we'd like to refactor towards in the future, to remove dependencies from `hyperlane-core` as much as possible - One inconvenience is that you need to `.map_err()` to `HyperlaneCosmosError` first, to use `?`. I wish `?` had deref coercion semantics where it'd keep covnerting until an error matches, but I assume this isn't possible because while you can only have a single `Deref` impl, you can have multiple `From<Err>` impls. - Writing this I'm realising we could write a small macro to implement `From<Err> for ChainCommunicationError` for all the sub-errors of `HyperlaneCosmosError` et al (cc @tkporter)
- Loading branch information
1 parent
35dcc7d
commit 7289e0f
Showing
14 changed files
with
104 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use hyperlane_core::ChainCommunicationError; | ||
|
||
/// Errors from the crates specific to the hyperlane-cosmos | ||
/// implementation. | ||
/// This error can then be converted into the broader error type | ||
/// in hyperlane-core using the `From` trait impl | ||
#[derive(Debug, thiserror::Error)] | ||
pub enum HyperlaneCosmosError { | ||
/// bech32 error | ||
#[error("{0}")] | ||
Bech32(#[from] bech32::Error), | ||
/// gRPC error | ||
#[error("{0}")] | ||
GrpcError(#[from] tonic::Status), | ||
} | ||
|
||
impl From<HyperlaneCosmosError> for ChainCommunicationError { | ||
fn from(value: HyperlaneCosmosError) -> Self { | ||
ChainCommunicationError::from_other(value) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,59 @@ | ||
use cosmrs::crypto::secp256k1::SigningKey; | ||
use cosmrs::crypto::{secp256k1::SigningKey, PublicKey}; | ||
use hyperlane_core::ChainResult; | ||
|
||
use crate::verify; | ||
|
||
#[derive(Clone, Debug)] | ||
/// Signer for cosmos chain | ||
pub struct Signer { | ||
/// prefix for signer address | ||
/// public key | ||
pub public_key: PublicKey, | ||
/// precomputed address, because computing it is a fallible operation | ||
/// and we want to avoid returning `Result` | ||
pub address: String, | ||
/// address prefix | ||
pub prefix: String, | ||
pub(crate) private_key: Vec<u8>, | ||
private_key: Vec<u8>, | ||
} | ||
|
||
impl Signer { | ||
/// create new signer | ||
pub fn new(private_key: Vec<u8>, prefix: String) -> Self { | ||
Self { | ||
/// | ||
/// # Arguments | ||
/// * `private_key` - private key for signer | ||
/// * `prefix` - prefix for signer address | ||
pub fn new(private_key: Vec<u8>, prefix: String) -> ChainResult<Self> { | ||
let address = Self::address(&private_key, &prefix)?; | ||
|
||
let signing_key = Self::build_signing_key(&private_key)?; | ||
SigningKey::from_slice(&private_key)?; | ||
let public_key = signing_key.public_key(); | ||
Ok(Self { | ||
public_key, | ||
private_key, | ||
address, | ||
prefix, | ||
} | ||
}) | ||
} | ||
|
||
/// get bech32 address | ||
pub fn address(&self) -> String { | ||
verify::pub_to_addr( | ||
SigningKey::from_slice(self.private_key.as_slice()) | ||
.unwrap() | ||
fn address(private_key: &Vec<u8>, prefix: &str) -> ChainResult<String> { | ||
let address = verify::pub_to_addr( | ||
SigningKey::from_slice(private_key.as_slice())? | ||
.public_key() | ||
.to_bytes(), | ||
self.prefix.as_str(), | ||
) | ||
.unwrap() | ||
prefix, | ||
)?; | ||
Ok(address) | ||
} | ||
|
||
/// Build a SigningKey from a private key. This cannot be | ||
/// precompiled and stored in `Signer`, because `SigningKey` is not `Sync`. | ||
pub fn signing_key(&self) -> ChainResult<SigningKey> { | ||
Self::build_signing_key(&self.private_key) | ||
} | ||
|
||
fn build_signing_key(private_key: &Vec<u8>) -> ChainResult<SigningKey> { | ||
Ok(SigningKey::from_slice(private_key.as_slice())?) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters