async fn relay_valid_valset(
    latest_cosmos_valset_nonce: u64,
    valset_to_relay: Valset,
    current_valset: Valset,
    conformations: Vec<ValsetConfirmResponse>,
    web3: &Web3,
    gravity_contract_address: EthAddress,
    gravity_id: String,
    ethereum_key: EthPrivateKey,
    timeout: Duration,
    relayer_config: RelayerConfig,
) {
    let cost = ethereum_gravity::valset_update::estimate_valset_cost(
        &valset_to_relay,
        &current_valset,
        &conformations,
        web3,
        gravity_contract_address,
        gravity_id.clone(),
        ethereum_key,
    )
    .await;
    if cost.is_err() {
        valset_cost_error(
            cost,
            &ethereum_key,
            &gravity_contract_address,
            web3,
            valset_to_relay.clone(),
            current_valset,
        )
        .await;
        return;
    }
    let cost = cost.unwrap();

    info!(
           "We have detected that valset {} is valid to submit. Latest on Ethereum is {} This update is estimated to cost {} Gas / {:.4} ETH to submit",
            valset_to_relay.nonce, current_valset.nonce,
            cost.gas_price.clone(),
            downcast_to_u128(cost.get_total()).unwrap() as f32
                / downcast_to_u128(one_eth()).unwrap() as f32
        );

    let should_relay = match relayer_config.valset_relaying_mode {
        // if the user has configured only profitable relaying then it is our only consideration
        ValsetRelayingMode::ProfitableOnly => {
            let s =
                is_relaying_valset_profitable(&valset_to_relay, &ethereum_key, cost, web3).await;
            if !s {
                info!(
                    "Not relaying valset {} because it is not currently profitable",
                    valset_to_relay.nonce
                );
            }
            s
        }
        // if the user has requested to relay every single valset, we do so
        ValsetRelayingMode::EveryValset => true,
        // user is an altruistic relayer, so we'll do our best to balance not spending
        // all their money with keeping the validator set up to date.
        //
        // This logic is very financially conservative and will only relay valsets when find_latest_valid_valset() does not
        // return the latest valset. This means that voting power has sufficiently changed that a two step update
        // is required, where one older valset is played back, and then the latest one. At this stage it is critical an update be
        // performed, or relaying batches will be impossible.
        //
        // remember the philosophy of valset creation is to create valsets such that there is always a valid chain of updates to submit
        // since we store all the required signatures for as long as we may need them on the cosmos chain it's not fatal to wait, we can always play
        // them back later when we need them. Since 2/3 of voting power is required to spend funds and only 1/3 of voting power must change over
        // before this condition is triggered it should not risk a stale validator set in the Ethereum side of the bridge sending funds.
        ValsetRelayingMode::Altruistic => latest_cosmos_valset_nonce != valset_to_relay.nonce,
    };

    if should_relay {
        let _res = send_eth_valset_update(
            valset_to_relay,
            current_valset,
            &conformations,
            web3,
            timeout,
            gravity_contract_address,
            gravity_id,
            ethereum_key,
        )
        .await;
    }
}
/// determines if the provided validator set should be relayed according to user preferences
determines if the provided validator set should be relayed according to user preferences
determines if the provided validator set should be relayed according to user preferences
async fn relay_valid_valset(
    latest_cosmos_valset_nonce: u64,
    valset_to_relay: Valset,
    current_valset: Valset,
    conformations: Vec<ValsetConfirmResponse>,
    web3: &Web3,
    gravity_contract_address: EthAddress,
    gravity_id: String,
    ethereum_key: EthPrivateKey,
    timeout: Duration,
    relayer_config: RelayerConfig,
) {
    let cost = ethereum_gravity::valset_update::estimate_valset_cost(
        &valset_to_relay,
        &current_valset,
        &conformations,
        web3,
        gravity_contract_address,
        gravity_id.clone(),
        ethereum_key,
    )
    .await;
    if cost.is_err() {
        valset_cost_error(
            cost,
            &ethereum_key,
            &gravity_contract_address,
            web3,
            valset_to_relay.clone(),
            current_valset,
        )
        .await;
        return;
    }
    let cost = cost.unwrap();
    info!(
           "We have detected that valset {} is valid to submit. Latest on Ethereum is {} This update is estimated to cost {} Gas / {:.4} ETH to submit",
            valset_to_relay.nonce, current_valset.nonce,
            cost.gas_price.clone(),
            downcast_to_u128(cost.get_total()).unwrap() as f32
                / downcast_to_u128(one_eth()).unwrap() as f32
        );
    let should_relay = match relayer_config.valset_relaying_mode {
        // if the user has configured only profitable relaying then it is our only consideration
        ValsetRelayingMode::ProfitableOnly => {
            let s =
                is_relaying_valset_profitable(&valset_to_relay, &ethereum_key, cost, web3).await;
            if !s {
                info!(
                    "Not relaying valset {} because it is not currently profitable",
                    valset_to_relay.nonce
                );
            }
            s
        }
        // if the user has requested to relay every single valset, we do so
        ValsetRelayingMode::EveryValset => true,
        // user is an altruistic relayer, so we'll do our best to balance not spending
        // all their money with keeping the validator set up to date.
        //
        // This logic is very financially conservative and will only relay valsets when find_latest_valid_valset() does not
        // return the latest valset. This means that voting power has sufficiently changed that a two step update
        // is required, where one older valset is played back, and then the latest one. At this stage it is critical an update be
        // performed, or relaying batches will be impossible.
        //
        // remember the philosophy of valset creation is to create valsets such that there is always a valid chain of updates to submit
        // since we store all the required signatures for as long as we may need them on the cosmos chain it's not fatal to wait, we can always play
        // them back later when we need them. Since 2/3 of voting power is required to spend funds and only 1/3 of voting power must change over
        // before this condition is triggered it should not risk a stale validator set in the Ethereum side of the bridge sending funds.
        ValsetRelayingMode::Altruistic => latest_cosmos_valset_nonce != valset_to_relay.nonce,
    };
    if should_relay {
        let _res = send_eth_valset_update(
            valset_to_relay,
            current_valset,
            &conformations,
            web3,
            timeout,
            gravity_contract_address,
            gravity_id,
            ethereum_key,
        )
        .await;
    }
}
async fn relay_valid_valset ( latest_cosmos_valset_nonce : u64 , valset_to_relay : Valset , current_valset : Valset , conformations : Vec < ValsetConfirmResponse > , web3 : & Web3 , gravity_contract_address : EthAddress , gravity_id : String , ethereum_key : EthPrivateKey , timeout : Duration , relayer_config : RelayerConfig , ) { let cost = ethereum_gravity :: valset_update :: estimate_valset_cost ( & valset_to_relay , & current_valset , & conformations , web3 , gravity_contract_address , gravity_id . clone ( ) , ethereum_key , ) . await ; if cost . is_err ( ) { valset_cost_error ( cost , & ethereum_key , & gravity_contract_address , web3 , valset_to_relay . clone ( ) , current_valset , ) . await ; return ; } let cost = cost . unwrap ( ) ; info ! ( " " valset_to_relay nonce current_valset nonce cost gas_price clone ( ) downcast_to_u128 ( cost get_total ( ) ) unwrap ( ) as f32 downcast_to_u128 ( one_eth ( ) ) unwrap ( ) as f32 ) ; let should_relay = match relayer_config . valset_relaying_mode { // if the user has configured only profitable relaying then it is our only consideration ValsetRelayingMode :: ProfitableOnly => { let s = is_relaying_valset_profitable ( & valset_to_relay , & ethereum_key , cost , web3 ) . await ; if ! s { info ! ( " " valset_to_relay nonce ) ; } s } // if the user has requested to relay every single valset, we do so ValsetRelayingMode :: EveryValset => true , // user is an altruistic relayer, so we'll do our best to balance not spending // all their money with keeping the validator set up to date. // // This logic is very financially conservative and will only relay valsets when find_latest_valid_valset() does not // return the latest valset. This means that voting power has sufficiently changed that a two step update // is required, where one older valset is played back, and then the latest one. At this stage it is critical an update be // performed, or relaying batches will be impossible. // // remember the philosophy of valset creation is to create valsets such that there is always a valid chain of updates to submit // since we store all the required signatures for as long as we may need them on the cosmos chain it's not fatal to wait, we can always play // them back later when we need them. Since 2/3 of voting power is required to spend funds and only 1/3 of voting power must change over // before this condition is triggered it should not risk a stale validator set in the Ethereum side of the bridge sending funds. ValsetRelayingMode :: Altruistic => latest_cosmos_valset_nonce != valset_to_relay . nonce , } ; if should_relay { let _res = send_eth_valset_update ( valset_to_relay , current_valset , & conformations , web3 , timeout , gravity_contract_address , gravity_id , ethereum_key , ) . await ; } }
determines if the provided validator set should be relayed according to user preferences
determines if the provided validator set should be relayed according to user preferences
latest_cosmos_valset_nonce
u64
valset_to_relay
Valset
current_valset
Valset
conformations
Vec<ValsetConfirmResponse>
web3
&Web3
gravity_contract_address
EthAddress
gravity_id
String
ethereum_key
EthPrivateKey
timeout
Duration
relayer_config
RelayerConfig
latest_cosmos_valset_nonce
u64
valset_to_relay
Valset
current_valset
Valset
conformations
Vec<ValsetConfirmResponse>
web3
&Web3
gravity_contract_address
EthAddress
gravity_id
String
ethereum_key
EthPrivateKey
timeout
Duration
relayer_config
RelayerConfig