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

Sealevel balance metrics #3025

Merged
merged 3 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
23 changes: 23 additions & 0 deletions rust/chains/hyperlane-sealevel/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use hyperlane_core::ChainCommunicationError;
use solana_client::client_error::ClientError;
use solana_sdk::pubkey::ParsePubkeyError;

/// Errors from the crates specific to the hyperlane-sealevel
/// 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 HyperlaneSealevelError {
/// ParsePubkeyError error
#[error("{0}")]
ParsePubkeyError(#[from] ParsePubkeyError),
/// ClientError error
#[error("{0}")]
ClientError(#[from] ClientError),
}

impl From<HyperlaneSealevelError> for ChainCommunicationError {
fn from(value: HyperlaneSealevelError) -> Self {
ChainCommunicationError::from_other(value)
}
}
11 changes: 5 additions & 6 deletions rust/chains/hyperlane-sealevel/src/interchain_gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub struct SealevelInterchainGasPaymaster {
data_pda_pubkey: Pubkey,
domain: HyperlaneDomain,
igp_account: H256,
provider: SealevelProvider,
}

impl SealevelInterchainGasPaymaster {
Expand All @@ -43,12 +44,9 @@ impl SealevelInterchainGasPaymaster {
conf: &ConnectionConf,
igp_account_locator: &ContractLocator<'_>,
) -> ChainResult<Self> {
let rpc_client = RpcClientWithDebug::new_with_commitment(
conf.url.to_string(),
CommitmentConfig::processed(),
);
let provider = SealevelProvider::new(igp_account_locator.domain.clone(), conf);
let program_id =
Self::determine_igp_program_id(&rpc_client, &igp_account_locator.address).await?;
Self::determine_igp_program_id(provider.rpc(), &igp_account_locator.address).await?;
let (data_pda_pubkey, _) =
Pubkey::find_program_address(igp_program_data_pda_seeds!(), &program_id);

Expand All @@ -57,6 +55,7 @@ impl SealevelInterchainGasPaymaster {
data_pda_pubkey,
domain: igp_account_locator.domain.clone(),
igp_account: igp_account_locator.address,
provider,
})
}

Expand Down Expand Up @@ -91,7 +90,7 @@ impl HyperlaneChain for SealevelInterchainGasPaymaster {
}

fn provider(&self) -> Box<dyn HyperlaneProvider> {
Box::new(SealevelProvider::new(self.domain.clone()))
self.provider.provider()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,31 @@ use hyperlane_core::{
use hyperlane_sealevel_interchain_security_module_interface::InterchainSecurityModuleInstruction;
use serializable_account_meta::SimulationReturnData;

use crate::{utils::simulate_instruction, ConnectionConf, RpcClientWithDebug};
use crate::{utils::simulate_instruction, ConnectionConf, RpcClientWithDebug, SealevelProvider};

/// A reference to an InterchainSecurityModule contract on some Sealevel chain
#[derive(Debug)]
pub struct SealevelInterchainSecurityModule {
rpc_client: RpcClientWithDebug,
payer: Option<Keypair>,
program_id: Pubkey,
domain: HyperlaneDomain,
provider: SealevelProvider,
}

impl SealevelInterchainSecurityModule {
/// Create a new sealevel InterchainSecurityModule
pub fn new(conf: &ConnectionConf, locator: ContractLocator, payer: Option<Keypair>) -> Self {
let rpc_client = RpcClientWithDebug::new(conf.url.to_string());
let provider = SealevelProvider::new(locator.domain.clone(), conf);
let program_id = Pubkey::from(<[u8; 32]>::from(locator.address));
Self {
rpc_client,
payer,
program_id,
domain: locator.domain.clone(),
provider,
}
}

fn rpc(&self) -> &RpcClientWithDebug {
self.provider.rpc()
}
}

impl HyperlaneContract for SealevelInterchainSecurityModule {
Expand All @@ -43,11 +45,11 @@ impl HyperlaneContract for SealevelInterchainSecurityModule {

impl HyperlaneChain for SealevelInterchainSecurityModule {
fn domain(&self) -> &HyperlaneDomain {
&self.domain
self.provider.domain()
}

fn provider(&self) -> Box<dyn hyperlane_core::HyperlaneProvider> {
Box::new(crate::SealevelProvider::new(self.domain.clone()))
self.provider.provider()
}
}

Expand All @@ -63,7 +65,7 @@ impl InterchainSecurityModule for SealevelInterchainSecurityModule {
);

let module = simulate_instruction::<SimulationReturnData<u32>>(
&self.rpc_client,
self.rpc(),
self.payer
.as_ref()
.ok_or_else(|| ChainCommunicationError::SignerUnavailable)?,
Expand Down
1 change: 1 addition & 0 deletions rust/chains/hyperlane-sealevel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub use solana_sdk::signer::keypair::Keypair;
pub use trait_builder::*;
pub use validator_announce::*;

mod error;
mod interchain_gas;
mod interchain_security_module;
mod mailbox;
Expand Down
48 changes: 24 additions & 24 deletions rust/chains/hyperlane-sealevel/src/mailbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ pub struct SealevelMailbox {
pub(crate) program_id: Pubkey,
inbox: (Pubkey, u8),
pub(crate) outbox: (Pubkey, u8),
pub(crate) rpc_client: RpcClient,
pub(crate) domain: HyperlaneDomain,
pub(crate) provider: SealevelProvider,
payer: Option<Keypair>,
}

Expand All @@ -81,10 +80,7 @@ impl SealevelMailbox {
locator: ContractLocator,
payer: Option<Keypair>,
) -> ChainResult<Self> {
// Set the `processed` commitment at rpc level
let rpc_client =
RpcClient::new_with_commitment(conf.url.to_string(), CommitmentConfig::processed());

let provider = SealevelProvider::new(locator.domain.clone(), conf);
let program_id = Pubkey::from(<[u8; 32]>::from(locator.address));
let domain = locator.domain.id();
let inbox = Pubkey::find_program_address(mailbox_inbox_pda_seeds!(), &program_id);
Expand All @@ -99,8 +95,7 @@ impl SealevelMailbox {
program_id,
inbox,
outbox,
rpc_client,
domain: locator.domain.clone(),
provider,
payer,
})
}
Expand All @@ -112,6 +107,10 @@ impl SealevelMailbox {
self.outbox
}

pub fn rpc(&self) -> &RpcClientWithDebug {
self.provider.rpc()
}

/// Simulates an instruction, and attempts to deserialize it into a T.
/// If no return data at all was returned, returns Ok(None).
/// If some return data was returned but deserialization was unsuccesful,
Expand All @@ -121,7 +120,7 @@ impl SealevelMailbox {
instruction: Instruction,
) -> ChainResult<Option<T>> {
simulate_instruction(
&self.rpc_client,
&self.rpc(),
self.payer
.as_ref()
.ok_or_else(|| ChainCommunicationError::SignerUnavailable)?,
Expand All @@ -136,7 +135,7 @@ impl SealevelMailbox {
instruction: Instruction,
) -> ChainResult<Vec<AccountMeta>> {
get_account_metas(
&self.rpc_client,
&self.rpc(),
self.payer
.as_ref()
.ok_or_else(|| ChainCommunicationError::SignerUnavailable)?,
Expand Down Expand Up @@ -263,11 +262,11 @@ impl HyperlaneContract for SealevelMailbox {

impl HyperlaneChain for SealevelMailbox {
fn domain(&self) -> &HyperlaneDomain {
&self.domain
&self.provider.domain()
}

fn provider(&self) -> Box<dyn HyperlaneProvider> {
Box::new(SealevelProvider::new(self.domain.clone()))
self.provider.provider()
}
}

Expand Down Expand Up @@ -295,7 +294,7 @@ impl Mailbox for SealevelMailbox {
);

let account = self
.rpc_client
.rpc()
.get_account_with_commitment(
&processed_message_account_key,
CommitmentConfig::finalized(),
Expand All @@ -309,7 +308,7 @@ impl Mailbox for SealevelMailbox {
#[instrument(err, ret, skip(self))]
async fn default_ism(&self) -> ChainResult<H256> {
let inbox_account = self
.rpc_client
.rpc()
.get_account(&self.inbox.0)
.await
.map_err(ChainCommunicationError::from_other)?;
Expand Down Expand Up @@ -436,7 +435,7 @@ impl Mailbox for SealevelMailbox {
};
instructions.push(inbox_instruction);
let (recent_blockhash, _) = self
.rpc_client
.rpc()
.get_latest_blockhash_with_commitment(commitment)
.await
.map_err(ChainCommunicationError::from_other)?;
Expand All @@ -451,15 +450,15 @@ impl Mailbox for SealevelMailbox {
tracing::info!(?txn, "Created sealevel transaction to process message");

let signature = self
.rpc_client
.rpc()
.send_and_confirm_transaction(&txn)
.await
.map_err(ChainCommunicationError::from_other)?;

tracing::info!(?txn, ?signature, "Sealevel transaction sent");

let executed = self
.rpc_client
.rpc()
.confirm_transaction_with_commitment(&signature, commitment)
.await
.map_err(|err| warn!("Failed to confirm inbox process transaction: {}", err))
Expand Down Expand Up @@ -498,26 +497,27 @@ impl Mailbox for SealevelMailbox {
/// Struct that retrieves event data for a Sealevel Mailbox contract
#[derive(Debug)]
pub struct SealevelMailboxIndexer {
rpc_client: RpcClientWithDebug,
mailbox: SealevelMailbox,
program_id: Pubkey,
}

impl SealevelMailboxIndexer {
pub fn new(conf: &ConnectionConf, locator: ContractLocator) -> ChainResult<Self> {
let program_id = Pubkey::from(<[u8; 32]>::from(locator.address));
let rpc_client = RpcClientWithDebug::new(conf.url.to_string());
let mailbox = SealevelMailbox::new(conf, locator, None)?;
Ok(Self {
program_id,
rpc_client,
mailbox,
})
}

fn rpc(&self) -> &RpcClientWithDebug {
&self.mailbox.rpc()
}

async fn get_finalized_block_number(&self) -> ChainResult<u32> {
let height = self
.rpc_client
.rpc()
.get_block_height()
.await
.map_err(ChainCommunicationError::from_other)?
Expand Down Expand Up @@ -560,7 +560,7 @@ impl SealevelMailboxIndexer {
with_context: Some(false),
};
let accounts = self
.rpc_client
.rpc()
.get_program_accounts_with_config(&self.mailbox.program_id, config)
.await
.map_err(ChainCommunicationError::from_other)?;
Expand Down Expand Up @@ -595,7 +595,7 @@ impl SealevelMailboxIndexer {

// Now that we have the valid message storage PDA pubkey, we can get the full account data.
let account = self
.rpc_client
.rpc()
.get_account_with_commitment(
&valid_message_storage_pda_pubkey,
CommitmentConfig::finalized(),
Expand Down Expand Up @@ -660,7 +660,7 @@ impl Indexer<HyperlaneMessage> for SealevelMailboxIndexer {
}

async fn get_finalized_block_number(&self) -> ChainResult<u32> {
get_finalized_block_number(&self.rpc_client).await
get_finalized_block_number(&self.rpc()).await
}
}

Expand Down
6 changes: 3 additions & 3 deletions rust/chains/hyperlane-sealevel/src/merkle_tree_hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use async_trait::async_trait;
use derive_new::new;
use hyperlane_core::{
accumulator::incremental::IncrementalMerkle, ChainCommunicationError, ChainResult, Checkpoint,
Indexer, LogMeta, MerkleTreeHook, MerkleTreeInsertion, SequenceIndexer,
HyperlaneChain, Indexer, LogMeta, MerkleTreeHook, MerkleTreeInsertion, SequenceIndexer,
};
use hyperlane_sealevel_mailbox::accounts::OutboxAccount;
use solana_sdk::commitment_config::CommitmentConfig;
Expand All @@ -22,7 +22,7 @@ impl MerkleTreeHook for SealevelMailbox {
);

let outbox_account = self
.rpc_client
.rpc()
.get_account_with_commitment(&self.outbox.0, CommitmentConfig::finalized())
.await
.map_err(ChainCommunicationError::from_other)?
Expand Down Expand Up @@ -58,7 +58,7 @@ impl MerkleTreeHook for SealevelMailbox {
})?;
let checkpoint = Checkpoint {
merkle_tree_hook_address: self.program_id.to_bytes().into(),
mailbox_domain: self.domain.id(),
mailbox_domain: self.domain().id(),
root,
index,
};
Expand Down
16 changes: 10 additions & 6 deletions rust/chains/hyperlane-sealevel/src/multisig_ism.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,29 @@ use multisig_ism::interface::{
/// A reference to a MultisigIsm contract on some Sealevel chain
#[derive(Debug)]
pub struct SealevelMultisigIsm {
rpc_client: RpcClientWithDebug,
payer: Option<Keypair>,
program_id: Pubkey,
domain: HyperlaneDomain,
provider: SealevelProvider,
}

impl SealevelMultisigIsm {
/// Create a new Sealevel MultisigIsm.
pub fn new(conf: &ConnectionConf, locator: ContractLocator, payer: Option<Keypair>) -> Self {
let rpc_client = RpcClientWithDebug::new(conf.url.to_string());
let provider = SealevelProvider::new(locator.domain.clone(), conf);
let program_id = Pubkey::from(<[u8; 32]>::from(locator.address));

Self {
rpc_client,
payer,
program_id,
domain: locator.domain.clone(),
provider,
}
}

fn rpc(&self) -> &RpcClientWithDebug {
self.provider.rpc()
}
}

impl HyperlaneContract for SealevelMultisigIsm {
Expand All @@ -57,7 +61,7 @@ impl HyperlaneChain for SealevelMultisigIsm {
}

fn provider(&self) -> Box<dyn HyperlaneProvider> {
Box::new(SealevelProvider::new(self.domain.clone()))
self.provider.provider()
}
}

Expand All @@ -84,7 +88,7 @@ impl MultisigIsm for SealevelMultisigIsm {

let validators_and_threshold =
simulate_instruction::<SimulationReturnData<ValidatorsAndThreshold>>(
&self.rpc_client,
self.rpc(),
self.payer
.as_ref()
.ok_or_else(|| ChainCommunicationError::SignerUnavailable)?,
Expand Down Expand Up @@ -132,7 +136,7 @@ impl SealevelMultisigIsm {
);

get_account_metas(
&self.rpc_client,
self.rpc(),
self.payer
.as_ref()
.ok_or_else(|| ChainCommunicationError::SignerUnavailable)?,
Expand Down
Loading
Loading