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

[bridge 62/n] make bridge_client_gas_object optional, add tests for starting bridge node #16771

Merged
merged 3 commits into from
Mar 28, 2024
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
4 changes: 4 additions & 0 deletions .github/workflows/mysticeti.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ jobs:
uses: pierotofy/set-swap-space@master
with:
swap-size-gb: 256
- name: Install Foundry
run: |
curl -L https://foundry.paradigm.xyz | { cat; echo '$FOUNDRY_BIN_DIR/foundryup'; } | bash
echo "$HOME/.config/.foundry/bin" >> $GITHUB_PATH
- name: cargo test
run: |
cargo nextest run --profile ci
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ jobs:
uses: pierotofy/set-swap-space@master
with:
swap-size-gb: 256
- name: Install Foundry
run: |
curl -L https://foundry.paradigm.xyz | { cat; echo '$FOUNDRY_BIN_DIR/foundryup'; } | bash
echo "$HOME/.config/.foundry/bin" >> $GITHUB_PATH
- name: cargo test
run: |
cargo nextest run --profile ci
Expand Down
13 changes: 9 additions & 4 deletions crates/sui-bridge/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,21 @@ fn main() -> Result<(), ExitStatus> {
.output()
.map(|output| output.status.success())
.unwrap_or(false);
if !forge_installed {
eprintln!("Installing forge");
let anvil_installed = Command::new("which")
.arg("anvil")
.output()
.map(|output| output.status.success())
.unwrap_or(false);
if !forge_installed || !anvil_installed {
eprintln!("Installing forge and/or anvil");
// Also print the path where foundryup is installed
let install_cmd = "curl -L https://foundry.paradigm.xyz | { cat; echo 'echo foundryup-path=\"$FOUNDRY_BIN_DIR/foundryup\"'; } | bash";

let output = Command::new("sh")
.arg("-c")
.arg(install_cmd)
.output()
.expect("Failed to install Forge");
.expect("Failed to fetch foundryup");

// extract foundryup path
let output_str = String::from_utf8_lossy(&output.stdout);
Expand All @@ -44,7 +49,7 @@ fn main() -> Result<(), ExitStatus> {
}
}
if foundryup_path.is_none() {
eprintln!("Error installing forge: expect a foundry path in output");
eprintln!("Error installing forge/anvil: expect a foundry path in output");
exit(1);
}
let foundryup_path = foundryup_path.unwrap();
Expand Down
56 changes: 50 additions & 6 deletions crates/sui-bridge/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ use crate::types::BridgeAction;
use anyhow::anyhow;
use ethers::types::Address as EthAddress;
use fastcrypto::traits::EncodeDecodeBase64;
use futures::{future, StreamExt};
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use std::collections::{BTreeMap, HashSet};
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::Arc;
use sui_config::Config;
use sui_sdk::SuiClient as SuiSdkClient;
use sui_json_rpc_types::Coin;
use sui_sdk::apis::CoinReadApi;
use sui_sdk::{SuiClient as SuiSdkClient, SuiClientBuilder};
use sui_types::base_types::ObjectRef;
use sui_types::base_types::{ObjectID, SuiAddress};
use sui_types::crypto::SuiKeyPair;
Expand Down Expand Up @@ -48,10 +51,12 @@ pub struct BridgeNodeConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub bridge_client_key_path_base64_sui_key: Option<PathBuf>,
/// Whether to run client. If true, `bridge_client_key_path_base64_sui_key`,
/// `bridge_client_gas_object` and `db_path` needs to be provided.
/// and `db_path` needs to be provided.
pub run_client: bool,
/// The gas object to use for paying for gas fees for the client. It needs to
/// be owned by the address associated with bridge client key.
/// be owned by the address associated with bridge client key. If not set
/// and `run_client` is true, it will query and use the gas object with highest
/// amount for the account.
#[serde(skip_serializing_if = "Option::is_none")]
pub bridge_client_gas_object: Option<ObjectID>,
/// Path of the client storage. Required when `run_client` is true.
Expand Down Expand Up @@ -144,9 +149,18 @@ impl BridgeNodeConfig {

let client_sui_address = SuiAddress::from(&bridge_client_key.public());
info!("Bridge client sui address: {:?}", client_sui_address);
let gas_object_id = self.bridge_client_gas_object.ok_or(anyhow!(
"`bridge_client_gas_object` is required when `run_client` is true"
))?;

// TODO: decide a minimal amount here and return if no coin has enough balance
let gas_object_id = match self.bridge_client_gas_object {
Some(id) => id,
None => {
let sui_client = SuiClientBuilder::default().build(&self.sui_rpc_url).await?;
let coin =
pick_highest_balance_coin(sui_client.coin_read_api(), client_sui_address, 0)
.await?;
coin.coin_object_id
}
};
let db_path = self
.db_path
.clone()
Expand Down Expand Up @@ -300,3 +314,33 @@ pub struct BridgeCommitteeConfig {
}

impl Config for BridgeCommitteeConfig {}

pub async fn pick_highest_balance_coin(
coin_read_api: &CoinReadApi,
address: SuiAddress,
minimal_amount: u64,
) -> anyhow::Result<Coin> {
let mut highest_balance = 0;
let mut highest_balance_coin = None;
coin_read_api
.get_coins_stream(address, None)
.for_each(|coin: Coin| {
if coin.balance > highest_balance {
highest_balance = coin.balance;
highest_balance_coin = Some(coin.clone());
}
future::ready(())
})
.await;
if highest_balance_coin.is_none() {
return Err(anyhow!("No Sui coins found for address {:?}", address));
}
if highest_balance < minimal_amount {
return Err(anyhow!(
"Found no single coin that has >= {} balance Sui for address {:?}",
minimal_amount,
address,
));
}
Ok(highest_balance_coin.unwrap())
}
1 change: 1 addition & 0 deletions crates/sui-bridge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub mod sui_syncer;
pub mod sui_transaction_builder;
pub mod tools;
pub mod types;
pub mod utils;

#[cfg(test)]
pub(crate) mod eth_mock_provider;
Expand Down
Loading
Loading