Skip to content

Commit

Permalink
[bridge] report bridge voting power when node starts (#19694)
Browse files Browse the repository at this point in the history
## Description 

so we can use this in the dashboard

## Test plan 

How did you test the new or updated feature?

---

## Release notes

Check each box that your changes affect. If none of the boxes relate to
your changes, release notes aren't required.

For each box you select, include information after the relevant heading
that describes the impact of your changes that a user might notice and
any actions they must take to implement updates.

- [ ] Protocol: 
- [ ] Nodes (Validators and Full nodes): 
- [ ] Indexer: 
- [ ] JSON-RPC: 
- [ ] GraphQL: 
- [ ] CLI: 
- [ ] Rust SDK:
- [ ] REST API:
  • Loading branch information
longbowlu authored Oct 5, 2024
1 parent 2aa1d02 commit 2c1b6e2
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 7 deletions.
4 changes: 4 additions & 0 deletions crates/sui-bridge/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ mod tests {
.unwrap();
let pubkey1 = BridgeAuthorityPublicKey::from_bytes(&public_key_bytes).unwrap();
let authority1 = BridgeAuthority {
sui_address: SuiAddress::random_for_testing_only(),
pubkey: pubkey1.clone(),
voting_power: 2500,
is_blocklisted: false,
Expand All @@ -292,6 +293,7 @@ mod tests {
.unwrap();
let pubkey2 = BridgeAuthorityPublicKey::from_bytes(&public_key_bytes).unwrap();
let authority2 = BridgeAuthority {
sui_address: SuiAddress::random_for_testing_only(),
pubkey: pubkey2.clone(),
voting_power: 2500,
is_blocklisted: false,
Expand All @@ -303,6 +305,7 @@ mod tests {
.unwrap();
let pubkey3 = BridgeAuthorityPublicKey::from_bytes(&public_key_bytes).unwrap();
let authority3 = BridgeAuthority {
sui_address: SuiAddress::random_for_testing_only(),
pubkey: pubkey3.clone(),
voting_power: 2500,
is_blocklisted: false,
Expand All @@ -314,6 +317,7 @@ mod tests {
.unwrap();
let pubkey4 = BridgeAuthorityPublicKey::from_bytes(&public_key_bytes).unwrap();
let authority4 = BridgeAuthority {
sui_address: SuiAddress::random_for_testing_only(),
pubkey: pubkey4.clone(),
voting_power: 2500,
is_blocklisted: false,
Expand Down
8 changes: 8 additions & 0 deletions crates/sui-bridge/src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pub struct BridgeMetrics {

pub(crate) sui_rpc_errors: IntCounterVec,
pub(crate) observed_governance_actions: IntCounterVec,
pub(crate) current_bridge_voting_rights: IntGaugeVec,
}

impl BridgeMetrics {
Expand Down Expand Up @@ -317,6 +318,13 @@ impl BridgeMetrics {
registry,
)
.unwrap(),
current_bridge_voting_rights: register_int_gauge_vec_with_registry!(
"current_bridge_voting_rights",
"Current voting power in the bridge committee",
&["authority"],
registry
)
.unwrap(),
}
}

Expand Down
34 changes: 27 additions & 7 deletions crates/sui-bridge/src/node.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use crate::types::BridgeCommittee;
use crate::utils::get_committee_voting_power_by_name;
use crate::{
action_executor::BridgeActionExecutor,
client::bridge_authority_aggregator::BridgeAuthorityAggregator,
Expand Down Expand Up @@ -62,13 +64,36 @@ pub async fn run_bridge_node(
))
.unwrap();

let committee = Arc::new(
server_config
.sui_client
.get_bridge_committee()
.await
.expect("Failed to get committee"),
);
// Start Client
let _handles = if let Some(client_config) = client_config {
start_client_components(client_config, metrics.clone()).await
start_client_components(client_config, committee.clone(), metrics.clone()).await
} else {
Ok(vec![])
}?;

// Update voting right metrics
// Before reconfiguration happens we only set it once when the node starts
let sui_system = server_config
.sui_client
.sui_client()
.governance_api()
.get_latest_sui_system_state()
.await?;
let committee_name_mapping = get_committee_voting_power_by_name(&committee, sui_system).await;
for (name, voting_power) in committee_name_mapping.into_iter() {
metrics
.current_bridge_voting_rights
.with_label_values(&[name.as_str()])
.set(voting_power as i64);
}

// Start Server
let socket_address = SocketAddr::new(
IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
Expand All @@ -91,6 +116,7 @@ pub async fn run_bridge_node(
// TODO: is there a way to clean up the overrides after it's stored in DB?
async fn start_client_components(
client_config: BridgeClientConfig,
committee: Arc<BridgeCommittee>,
metrics: Arc<BridgeMetrics>,
) -> anyhow::Result<Vec<JoinHandle<()>>> {
let store: std::sync::Arc<BridgeOrchestratorTables> =
Expand Down Expand Up @@ -126,12 +152,6 @@ async fn start_client_components(
.expect("Failed to start sui syncer");
all_handles.extend(task_handles);

let committee = Arc::new(
sui_client
.get_bridge_committee()
.await
.expect("Failed to get committee"),
);
let bridge_auth_agg = Arc::new(ArcSwap::from(Arc::new(BridgeAuthorityAggregator::new(
committee,
))));
Expand Down
1 change: 1 addition & 0 deletions crates/sui-bridge/src/sui_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ where
""
});
authorities.push(BridgeAuthority {
sui_address,
pubkey,
voting_power,
base_url: base_url.into(),
Expand Down
1 change: 1 addition & 0 deletions crates/sui-bridge/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub fn get_test_authority_and_key(
let (_, kp): (_, fastcrypto::secp256k1::Secp256k1KeyPair) = get_key_pair();
let pubkey = kp.public().clone();
let authority = BridgeAuthority {
sui_address: SuiAddress::random_for_testing_only(),
pubkey: pubkey.clone(),
voting_power,
base_url: format!("http://127.0.0.1:{}", port),
Expand Down
9 changes: 9 additions & 0 deletions crates/sui-bridge/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use serde::{Deserialize, Serialize};
use shared_crypto::intent::IntentScope;
use std::collections::{BTreeMap, BTreeSet};
use std::fmt::Debug;
use sui_types::base_types::SuiAddress;
use sui_types::bridge::{
BridgeChainId, MoveTypeTokenTransferPayload, APPROVAL_THRESHOLD_ADD_TOKENS_ON_EVM,
APPROVAL_THRESHOLD_ADD_TOKENS_ON_SUI, BRIDGE_COMMITTEE_MAXIMAL_VOTING_POWER,
Expand Down Expand Up @@ -51,6 +52,7 @@ pub const BRIDGE_UNPAUSED: bool = false;

#[derive(Debug, Eq, PartialEq, Clone)]
pub struct BridgeAuthority {
pub sui_address: SuiAddress,
pub pubkey: BridgeAuthorityPublicKey,
pub voting_power: u64,
pub base_url: String,
Expand Down Expand Up @@ -119,6 +121,13 @@ impl BridgeCommittee {
pub fn total_blocklisted_stake(&self) -> StakeUnit {
self.total_blocklisted_stake
}

pub fn active_stake(&self, member: &BridgeAuthorityPublicKeyBytes) -> StakeUnit {
self.members
.get(member)
.map(|a| if a.is_blocklisted { 0 } else { a.voting_power })
.unwrap_or(0)
}
}

impl core::fmt::Display for BridgeCommittee {
Expand Down
29 changes: 29 additions & 0 deletions crates/sui-bridge/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::config::{
use crate::crypto::BridgeAuthorityKeyPair;
use crate::crypto::BridgeAuthorityPublicKeyBytes;
use crate::server::APPLICATION_JSON;
use crate::types::BridgeCommittee;
use crate::types::{AddTokensOnSuiAction, BridgeAction};
use anyhow::anyhow;
use ethers::core::k256::ecdsa::SigningKey;
Expand All @@ -24,6 +25,7 @@ use fastcrypto::secp256k1::Secp256k1KeyPair;
use fastcrypto::traits::EncodeDecodeBase64;
use fastcrypto::traits::KeyPair;
use futures::future::join_all;
use std::collections::BTreeMap;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::Arc;
Expand All @@ -37,10 +39,12 @@ use sui_test_transaction_builder::TestTransactionBuilder;
use sui_types::base_types::SuiAddress;
use sui_types::bridge::BridgeChainId;
use sui_types::bridge::{BRIDGE_MODULE_NAME, BRIDGE_REGISTER_FOREIGN_TOKEN_FUNCTION_NAME};
use sui_types::committee::StakeUnit;
use sui_types::crypto::get_key_pair;
use sui_types::crypto::SuiKeyPair;
use sui_types::crypto::ToFromBytes;
use sui_types::programmable_transaction_builder::ProgrammableTransactionBuilder;
use sui_types::sui_system_state::sui_system_state_summary::SuiSystemStateSummary;
use sui_types::transaction::{ObjectArg, TransactionData};
use sui_types::BRIDGE_PACKAGE_ID;

Expand Down Expand Up @@ -380,3 +384,28 @@ pub async fn wait_for_server_to_be_up(server_url: String, timeout_sec: u64) -> a
}
Ok(())
}

/// Return a mappping from validator name to their bridge voting power.
/// If a validator is not in the Sui committee, we will use its base URL as the name.
pub async fn get_committee_voting_power_by_name(
bridge_committee: &Arc<BridgeCommittee>,
system_state: SuiSystemStateSummary,
) -> BTreeMap<String, StakeUnit> {
let mut sui_committee: BTreeMap<_, _> = system_state
.active_validators
.iter()
.map(|v| (v.sui_address, v.name.clone()))
.collect();
bridge_committee
.members()
.iter()
.map(|v| {
(
sui_committee
.remove(&v.1.sui_address)
.unwrap_or(v.1.base_url.clone()),
v.1.voting_power,
)
})
.collect()
}

0 comments on commit 2c1b6e2

Please sign in to comment.