From df375df9e5ea98276e5f9119ebed74b553478fdb Mon Sep 17 00:00:00 2001 From: Mateusz Jasiuk Date: Wed, 9 Oct 2024 11:37:17 +0200 Subject: [PATCH] fix: add new validators on become validator --- chain/src/main.rs | 25 +++++++++++--------- chain/src/repository/pos.rs | 10 ++++++-- chain/src/services/namada.rs | 2 +- orm/src/transactions.rs | 4 ++++ pos/src/services/namada.rs | 4 +++- shared/src/block.rs | 34 ++++++++++++++++++++++++++- shared/src/checksums.rs | 9 +++---- shared/src/transaction.rs | 14 +++++++++-- shared/src/validator.rs | 8 ++++--- webserver/src/response/transaction.rs | 4 ++++ 10 files changed, 89 insertions(+), 25 deletions(-) diff --git a/chain/src/main.rs b/chain/src/main.rs index caac01a4..f9135c62 100644 --- a/chain/src/main.rs +++ b/chain/src/main.rs @@ -19,7 +19,6 @@ use clap_verbosity_flag::LevelFilter; use deadpool_diesel::postgres::Object; use namada_sdk::time::DateTimeUtc; use orm::migrations::run_migrations; -use orm::validators::ValidatorInsertDb; use shared::block::Block; use shared::block_result::BlockResult; use shared::checksums::Checksums; @@ -28,6 +27,7 @@ use shared::crawler_state::ChainCrawlerState; use shared::error::{AsDbError, AsRpcError, ContextDbInteractError, MainError}; use shared::id::Id; use shared::token::Token; +use shared::validator::ValidatorSet; use tendermint_rpc::HttpClient; use tracing::Level; use tracing_subscriber::FmtSubscriber; @@ -180,6 +180,12 @@ async fn crawling_fn( let proposals_votes = block.governance_votes(); tracing::info!("Creating {} governance votes...", proposals_votes.len()); + let validators = block.validators(); + let validator_set = ValidatorSet { + validators: validators.clone(), + epoch, + }; + let addresses = block.bond_addresses(); let bonds = query_bonds(&client, addresses).await.into_rpc_error()?; tracing::info!("Updating bonds for {} addresses", bonds.len()); @@ -246,6 +252,11 @@ async fn crawling_fn( proposals_votes, )?; + repository::pos::upsert_validators( + transaction_conn, + validator_set, + )?; + // We first remove all the bonds and then insert the new ones repository::pos::clear_bonds( transaction_conn, @@ -313,15 +324,13 @@ async fn initial_query( .await .into_rpc_error()?; // We need to add pipeline_length to the epoch as it is possible to bond in advance - let validators_set = namada_service::get_validator_set_at_epoch( + let validator_set = namada_service::get_validator_set_at_epoch( client, epoch + pipeline_length as u32, ) .await .into_rpc_error()?; - tracing::info!("Validator set length: {}", validators_set.validators.len()); - tracing::info!("Querying bonds and unbonds..."); let (bonds, unbonds) = query_all_bonds_and_unbonds(client, None, None) .await @@ -373,15 +382,9 @@ async fn initial_query( proposals_votes, )?; - let validators_dbo = &validators_set - .validators - .into_iter() - .map(ValidatorInsertDb::from_validator) - .collect::>(); - repository::pos::upsert_validators( transaction_conn, - validators_dbo, + validator_set, )?; repository::pos::insert_bonds(transaction_conn, bonds)?; diff --git a/chain/src/repository/pos.rs b/chain/src/repository/pos.rs index ed3abc78..56aa3800 100644 --- a/chain/src/repository/pos.rs +++ b/chain/src/repository/pos.rs @@ -16,7 +16,7 @@ use shared::block::Epoch; use shared::bond::Bonds; use shared::id::Id; use shared::unbond::{UnbondAddresses, Unbonds}; -use shared::validator::ValidatorMetadataChange; +use shared::validator::{ValidatorMetadataChange, ValidatorSet}; pub fn clear_bonds( transaction_conn: &mut PgConnection, @@ -202,8 +202,14 @@ pub fn update_validator_metadata( pub fn upsert_validators( transaction_conn: &mut PgConnection, - validators_db: &Vec, + validators_set: ValidatorSet, ) -> anyhow::Result<()> { + let validators_db = &validators_set + .validators + .into_iter() + .map(ValidatorInsertDb::from_validator) + .collect::>(); + diesel::insert_into(validators::table) .values::<&Vec>(validators_db) .on_conflict(validators::columns::namada_address) diff --git a/chain/src/services/namada.rs b/chain/src/services/namada.rs index f663d77b..339b59a9 100644 --- a/chain/src/services/namada.rs +++ b/chain/src/services/namada.rs @@ -673,7 +673,7 @@ pub async fn get_validator_set_at_epoch( }) }) .buffer_unordered(100) - .try_collect::>() + .try_collect::>() .await?; Ok(ValidatorSet { validators, epoch }) diff --git a/orm/src/transactions.rs b/orm/src/transactions.rs index 54d7cd60..29a06182 100644 --- a/orm/src/transactions.rs +++ b/orm/src/transactions.rs @@ -25,6 +25,7 @@ pub enum TransactionKindDb { ChangeMetadata, ChangeCommission, RevealPk, + BecomeValidator, Unknown, } @@ -54,6 +55,9 @@ impl From for TransactionKindDb { TransactionKindDb::ChangeCommission } TransactionKind::RevealPk(_) => TransactionKindDb::RevealPk, + TransactionKind::BecomeValidator(_) => { + TransactionKindDb::BecomeValidator + } TransactionKind::Unknown => TransactionKindDb::Unknown, } } diff --git a/pos/src/services/namada.rs b/pos/src/services/namada.rs index 40b6b388..9261648a 100644 --- a/pos/src/services/namada.rs +++ b/pos/src/services/namada.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use anyhow::Context; use futures::{StreamExt, TryStreamExt}; use namada_core::chain::Epoch as NamadaSdkEpoch; @@ -83,7 +85,7 @@ pub async fn get_validator_set_at_epoch( }) }) .buffer_unordered(100) - .try_collect::>() + .try_collect::>() .await?; Ok(ValidatorSet { validators, epoch }) diff --git a/shared/src/block.rs b/shared/src/block.rs index b66bb872..58890c5c 100644 --- a/shared/src/block.rs +++ b/shared/src/block.rs @@ -24,7 +24,7 @@ use crate::transaction::{ }; use crate::unbond::UnbondAddresses; use crate::utils::BalanceChange; -use crate::validator::ValidatorMetadataChange; +use crate::validator::{Validator, ValidatorMetadataChange, ValidatorState}; use crate::vote::GovernanceVote; pub type Epoch = u32; @@ -490,6 +490,38 @@ impl Block { Some(recv_msg) } + pub fn validators(&self) -> HashSet { + self.transactions + .iter() + .flat_map(|(_, txs)| txs) + .filter(|tx| { + tx.data.is_some() + && tx.exit_code == TransactionExitStatus::Applied + }) + .filter_map(|tx| match &tx.kind { + TransactionKind::BecomeValidator(data) => { + let data = data.clone().unwrap(); + Some(Validator { + address: Id::from(data.address.clone()), + voting_power: "0".to_string(), + max_commission: data + .max_commission_rate_change + .to_string(), + commission: data.commission_rate.to_string(), + name: data.name.clone(), + email: Some(data.email.clone()), + description: data.description.clone(), + website: data.website.clone(), + discord_handler: data.discord_handle.clone(), + avatar: data.avatar.clone(), + state: ValidatorState::Inactive, + }) + } + _ => None, + }) + .collect() + } + pub fn bond_addresses(&self) -> HashSet { self.transactions .iter() diff --git a/shared/src/checksums.rs b/shared/src/checksums.rs index 725cfd52..27389744 100644 --- a/shared/src/checksums.rs +++ b/shared/src/checksums.rs @@ -1,9 +1,9 @@ use bimap::BiMap; use namada_sdk::tx::{ - TX_BOND_WASM, TX_CHANGE_COMMISSION_WASM, TX_CHANGE_METADATA_WASM, - TX_CLAIM_REWARDS_WASM, TX_IBC_WASM, TX_INIT_PROPOSAL, TX_REDELEGATE_WASM, - TX_REVEAL_PK, TX_TRANSFER_WASM, TX_UNBOND_WASM, TX_VOTE_PROPOSAL, - TX_WITHDRAW_WASM, + TX_BECOME_VALIDATOR_WASM, TX_BOND_WASM, TX_CHANGE_COMMISSION_WASM, + TX_CHANGE_METADATA_WASM, TX_CLAIM_REWARDS_WASM, TX_IBC_WASM, + TX_INIT_PROPOSAL, TX_REDELEGATE_WASM, TX_REVEAL_PK, TX_TRANSFER_WASM, + TX_UNBOND_WASM, TX_VOTE_PROPOSAL, TX_WITHDRAW_WASM, }; use serde::{Deserialize, Serialize}; @@ -43,6 +43,7 @@ impl Checksums { TX_CHANGE_METADATA_WASM.to_string(), TX_CHANGE_COMMISSION_WASM.to_string(), TX_IBC_WASM.to_string(), + TX_BECOME_VALIDATOR_WASM.to_string(), ] } } diff --git a/shared/src/transaction.rs b/shared/src/transaction.rs index 66539fae..60220aac 100644 --- a/shared/src/transaction.rs +++ b/shared/src/transaction.rs @@ -8,8 +8,8 @@ use namada_sdk::masp::ShieldedTransfer; use namada_sdk::token::Transfer; use namada_sdk::uint::Uint; use namada_tx::data::pos::{ - Bond, ClaimRewards, CommissionChange, MetaDataChange, Redelegation, Unbond, - Withdraw, + BecomeValidator, Bond, ClaimRewards, CommissionChange, MetaDataChange, + Redelegation, Unbond, Withdraw, }; use namada_tx::data::{compute_inner_tx_hash, TxType}; use namada_tx::either::Either; @@ -47,6 +47,7 @@ pub enum TransactionKind { MetadataChange(Option), CommissionChange(Option), RevealPk(Option), + BecomeValidator(Option), Unknown, } @@ -162,6 +163,15 @@ impl TransactionKind { }; TransactionKind::IbcMsgTransfer(data.map(IbcMessage)) } + "tx_become_validator" => { + let data = + if let Ok(data) = BecomeValidator::try_from_slice(data) { + Some(data) + } else { + None + }; + TransactionKind::BecomeValidator(data) + } _ => { tracing::warn!("Unknown transaction kind: {}", tx_kind_name); TransactionKind::Unknown diff --git a/shared/src/validator.rs b/shared/src/validator.rs index 5d4c5384..eead4e11 100644 --- a/shared/src/validator.rs +++ b/shared/src/validator.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use fake::faker::company::en::{CatchPhrase, CompanyName}; use fake::faker::internet::en::{DomainSuffix, SafeEmail, Username}; use fake::Fake; @@ -9,7 +11,7 @@ use crate::id::Id; pub type VotingPower = String; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub enum ValidatorState { Consensus, BelowCapacity, @@ -37,11 +39,11 @@ impl From for ValidatorState { #[derive(Debug, Clone)] pub struct ValidatorSet { - pub validators: Vec, + pub validators: HashSet, pub epoch: Epoch, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Validator { pub address: Id, pub voting_power: VotingPower, diff --git a/webserver/src/response/transaction.rs b/webserver/src/response/transaction.rs index e45056c5..56d9b9b0 100644 --- a/webserver/src/response/transaction.rs +++ b/webserver/src/response/transaction.rs @@ -28,6 +28,7 @@ pub enum TransactionKind { ChangeCommission, RevealPk, IbcMsgTransfer, + BecomeValidator, Unknown, } @@ -119,6 +120,9 @@ impl From for TransactionKind { TransactionKindDb::IbcMsgTransfer => { TransactionKind::IbcMsgTransfer } + TransactionKindDb::BecomeValidator => { + TransactionKind::BecomeValidator + } } } }