Skip to content
Open
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
16 changes: 15 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@ ifeq ($(CMD), via-verifier)
VIA_ENV := via_verifier
DIFF := 1
MODE := verifier
else ifeq ($(CMD), via-verifier-1)
VIA_ENV := via_verifier_1
DIFF := 5
MODE := verifier
else ifeq ($(CMD), via-restart)
VIA_ENV := via
else ifeq ($(CMD), via-restart-verifier)
VIA_ENV := via_verifier
else ifeq ($(CMD), via-restart-verifier-1)
VIA_ENV := via_verifier-1
else ifeq ($(CMD), via-coordinator)
VIA_ENV := via_coordinator
DIFF := 2
Expand Down Expand Up @@ -101,6 +107,14 @@ all: base transactions btc-explorer bootstrap-dev server-genesis server
.PHONY: via-verifier
via-verifier: base verifier

# Run the basic setup workflow in verifier
.PHONY: via-verifier-1
via-verifier-1: base verifier

# Run the basic setup workflow in verifier
.PHONY: via-restart-verifier-1
via-restart-verifier-1: base verifier
Comment on lines +114 to +116
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The comment for via-restart-verifier-1 seems to be a copy-paste from via-verifier-1 and doesn't reflect that it's a restart command. Additionally, a restart command typically shouldn't run init (which is part of the base target). For consistency with via-restart-verifier, it would be better to use env-soft which is more appropriate for a restart operation.

# Restart the verifier-1
.PHONY: via-restart-verifier-1
via-restart-verifier-1: env-soft verifier


# Restart the verifier
.PHONY: via-restart-verifier
via-restart-verifier: env-soft verifier
Expand Down Expand Up @@ -209,7 +223,7 @@ bootstrap-dev:
@$(CLI_TOOL) bootstrap system-bootstrapping \
--private-key cVZduZu265sWeAqFYygoDEE1FZ7wV9rpW5qdqjRkUehjaUMWLT1R \
--start-block 1 \
--verifiers-pub-keys 03d8e2443ef58aa80fb6256bf3b94d2ecf9117f19cb17661ec60ad35fd84ff4a8b,02043f839b8ecd9ffd79f26ec7d05750555cd0d1e0777cfc84a29b7e38e6324662 \
--verifiers-pub-keys 03d8e2443ef58aa80fb6256bf3b94d2ecf9117f19cb17661ec60ad35fd84ff4a8b,02043f839b8ecd9ffd79f26ec7d05750555cd0d1e0777cfc84a29b7e38e6324662,0397970cc213de18e3b7a9fbd6e54f6b24a582d561d9d05f154a0bc152038b3543 \
--governance-address bcrt1q92gkfme6k9dkpagrkwt76etkaq29hvf02w5m38f6shs4ddpw7hzqp347zm \
--bridge-wallet-path etc/test_config/via/new_bridge_address.json \
--sequencer-address bcrt1qx2lk0unukm80qmepjp49hwf9z6xnz0s73k9j56
Expand Down
1 change: 1 addition & 0 deletions core/lib/basic_types/src/via_roles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ use serde::{Deserialize, Serialize};
pub enum ViaNodeRole {
Verifier,
Coordinator,
VerifierAndProcessor,
}
7 changes: 6 additions & 1 deletion core/lib/config/src/configs/via_btc_sender.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::time::Duration;
use std::{str::FromStr, time::Duration};

use bitcoin::Address;
use serde::{Deserialize, Serialize};

const DEFAULT_DA_LAYER: &str = "celestia";
Expand Down Expand Up @@ -60,6 +61,10 @@ impl ViaBtcSenderConfig {
pub fn stuck_inscription_block_number(&self) -> u32 {
self.stuck_inscription_block_number.unwrap_or(6)
}

pub fn wallet_address(&self) -> anyhow::Result<Address> {
Ok(Address::from_str(&self.wallet_address)?.assume_checked())
}
}

impl ViaBtcSenderConfig {
Expand Down
43 changes: 31 additions & 12 deletions core/lib/config/src/configs/via_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,22 @@ pub struct ViaVerifierConfig {
pub poll_interval: u64,

/// Port to which the coordinator server is listening.
pub coordinator_port: u16,
pub coordinator_port: Option<u16>,

/// The coordinator url.
pub coordinator_http_url: String,
pub coordinator_http_url: Option<String>,

/// Verifier Request Timeout (in seconds)
pub verifier_request_timeout: u8,
pub verifier_request_timeout: Option<u8>,

/// The verifier btc wallet address.
pub wallet_address: String,
pub wallet_address: Option<String>,

/// The bridge address merkle root.
pub bridge_address_merkle_root: Option<String>,

/// The session timeout.
pub session_timeout: u64,
pub session_timeout: Option<u64>,

/// Transaction weight limit.
pub max_tx_weight: Option<u64>,
Expand All @@ -54,13 +54,16 @@ impl ViaVerifierConfig {
}

pub fn wallet_address(&self) -> anyhow::Result<Address> {
Ok(Address::from_str(&self.wallet_address)?.assume_checked())
Ok(Address::from_str(&self.wallet_address.clone().unwrap())?.assume_checked())
}
Comment on lines 56 to 58
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Calling unwrap() on self.wallet_address will cause a panic if the value is None. Since wallet_address is now an Option, this case must be handled. Given that the function already returns a Result, it's more idiomatic to propagate an error if the address is not set.

    pub fn wallet_address(&self) -> anyhow::Result<Address> {
        let address = self.wallet_address.as_ref().context("wallet_address is not set in ViaVerifierConfig")?;
        Ok(Address::from_str(address)?.assume_checked())
    }

}

impl ViaVerifierConfig {
pub fn bind_addr(&self) -> SocketAddr {
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), self.coordinator_port)
SocketAddr::new(
IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
self.coordinator_port(),
)
}

pub fn max_tx_weight(&self) -> u64 {
Expand All @@ -72,15 +75,31 @@ impl ViaVerifierConfig {
.unwrap_or((MAX_STANDARD_TX_WEIGHT - 20000).into())
}

pub fn coordinator_port(&self) -> u16 {
self.coordinator_port.unwrap_or_default()
}
Comment on lines +78 to +80
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using unwrap_or_default() here will cause coordinator_port() to return 0 if the port is not configured. When bind_addr() uses this, it will bind to a random ephemeral port. The Coordinator role, which is the one using this, should always have a specific port configured. Using expect() will cause a panic with a clear error message on startup if the configuration is missing, which is safer than silently using a random port.

    pub fn coordinator_port(&self) -> u16 {
        self.coordinator_port.expect("coordinator_port is not set in ViaVerifierConfig")
    }


pub fn coordinator_http_url(&self) -> String {
self.coordinator_http_url.clone().unwrap_or_default()
}
Comment on lines +82 to +84
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using unwrap_or_default() will return an empty string if coordinator_http_url is None. This will lead to invalid URLs (e.g., "/session") being constructed, causing runtime errors in network requests. For roles that require this URL, it should be mandatory. Using expect() will ensure that the configuration is present, causing an early panic if it's missing.

    pub fn coordinator_http_url(&self) -> String {
        self.coordinator_http_url.clone().expect("coordinator_http_url is not set in ViaVerifierConfig")
    }


pub fn verifier_request_timeout(&self) -> u8 {
self.verifier_request_timeout.unwrap_or(60)
}

pub fn session_timeout(&self) -> u64 {
self.session_timeout.unwrap_or(300)
}

pub fn for_tests() -> Self {
Self {
role: ViaNodeRole::Verifier,
poll_interval: 1000,
coordinator_http_url: "http://localhost:3000".into(),
coordinator_port: 3000,
verifier_request_timeout: 10,
wallet_address: "".into(),
session_timeout: 30,
coordinator_http_url: None,
coordinator_port: None,
verifier_request_timeout: None,
wallet_address: None,
session_timeout: None,
max_tx_weight: None,
bridge_address_merkle_root: None,
}
Expand Down
2 changes: 1 addition & 1 deletion docker-compose-via.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ x-cli-env: &cli-env
TEST_ADDRESS_OP_RETURN: bcrt1qu7z4qrlwl33qqz8duph0k7hv8trvgx8dt8jzfz
VERIFIER_1_ADDRESS: bcrt1qw2mvkvm6alfhe86yf328kgvr7mupdx4vln7kpv
VERIFIER_2_ADDRESS: bcrt1qk8mkhrmgtq24nylzyzejznfzws6d98g4kmuuh4
VERIFIER_3_ADDRESS: bcrt1q23lgaa90s85jvtl6dsrkvn0g949cwjkwuyzwdm
VERIFIER_3_ADDRESS: bcrt1qynr9a3cxue43kluh0v2yaxp4cyhfanna7se755
BRIDGE_TEST_ADDRESS: bcrt1pcx974cg2w66cqhx67zadf85t8k4sd2wp68l8x8agd3aj4tuegsgsz97amg
BRIDGE_TEST_ADDRESS2: bcrt1pm4rre0xv8ryr9lr5lrnzx5tpyk0xr43kfw3aja68c0845vsu5wus3u40fp
GOV_ADDRESS: bcrt1q92gkfme6k9dkpagrkwt76etkaq29hvf02w5m38f6shs4ddpw7hzqp347zm
Expand Down
2 changes: 1 addition & 1 deletion etc/env/configs/via_verifier.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ __imports__ = ["base", "l2-inits/via_verifier.init.env"]

[via_verifier]
# The verifier role.
role = "Verifier"
role = "VerifierAndProcessor"
# The wallet used in musig2 sessions.
private_key = "cQ4UHjdsGWFMcQ8zXcaSr7m4Kxq9x7g9EKqguTaFH7fA34mZAnqW"
wallet_address = "bcrt1qk8mkhrmgtq24nylzyzejznfzws6d98g4kmuuh4"
Expand Down
10 changes: 10 additions & 0 deletions etc/env/configs/via_verifier_1.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
__imports__ = ["base", "l2-inits/via_verifier_1.init.env"]

[via_verifier]
# The verifier role.
role = "Verifier"

[via_btc_sender]
# The wallet used in the btc sender.
private_key = "cNgSiSJnL76tCs2gFdXeLMC2CcB553qThyVnodbgyjFFYtb4NLT6"
wallet_address = "bcrt1qynr9a3cxue43kluh0v2yaxp4cyhfanna7se755"
8 changes: 4 additions & 4 deletions via_verifier/bin/verifier_server/src/node_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,13 @@ use zksync_types::via_roles::ViaNodeRole;
use zksync_vlog::prometheus::PrometheusExporterConfig;

pub struct ViaNodeBuilder {
is_coordinator: bool,
node: ZkStackServiceBuilder,
configs: ViaGeneralVerifierConfig,
}

impl ViaNodeBuilder {
pub fn new(configs: ViaGeneralVerifierConfig) -> anyhow::Result<Self> {
Ok(Self {
is_coordinator: configs.via_verifier_config.role == ViaNodeRole::Coordinator,
node: ZkStackServiceBuilder::new().context("Cannot create ZkStackServiceBuilder")?,
configs,
})
Expand Down Expand Up @@ -218,11 +216,13 @@ impl ViaNodeBuilder {
.add_object_store_layer()?
.add_zkp_verification_layer()?;

if self.is_coordinator {
if self.configs.via_verifier_config.role == ViaNodeRole::Coordinator {
self = self.add_verifier_coordinator_api_layer()?
}

self = self.add_withdrawal_verifier_task_layer()?;
if self.configs.via_verifier_config.role != ViaNodeRole::Verifier {
self = self.add_withdrawal_verifier_task_layer()?;
}

Ok(self.node.build())
}
Expand Down
2 changes: 1 addition & 1 deletion via_verifier/lib/verifier_dal/src/withdrawals_dal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ impl ViaWithdrawalDal<'_, '_> {
bridge_withdrawal_id: i64,
withdrawal: &WithdrawalRequest,
) -> DalResult<()> {
let result = sqlx::query!(
sqlx::query!(
r#"
UPDATE via_withdrawals SET
bridge_withdrawal_id = $4,
Expand Down
28 changes: 27 additions & 1 deletion via_verifier/node/via_btc_sender/src/btc_vote_inscription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use via_btc_client::{
};
use via_verifier_dal::{Connection, ConnectionPool, Verifier, VerifierDal};
use zksync_config::ViaBtcSenderConfig;
use zksync_types::via_verifier_btc_inscription_operations::ViaVerifierBtcInscriptionRequestType;
use zksync_types::{
via_verifier_btc_inscription_operations::ViaVerifierBtcInscriptionRequestType,
via_wallet::SystemWallets,
};

use crate::metrics::METRICS;

Expand Down Expand Up @@ -56,6 +59,8 @@ impl ViaVoteInscription {
&mut self,
storage: &mut Connection<'_, Verifier>,
) -> anyhow::Result<()> {
self.validate_verifier_address().await?;

if storage
.via_l1_block_dal()
.has_reorg_in_progress()
Expand Down Expand Up @@ -149,4 +154,25 @@ impl ViaVoteInscription {
reversed_bytes.reverse();
Txid::from_slice(&reversed_bytes).with_context(|| "Failed to convert H256 to Txid")
}

/// Check if the wallet is in the verifier set.
async fn validate_verifier_address(&self) -> anyhow::Result<()> {
let mut storage = self.pool.connection().await?;

let last_processed_l1_block = storage
.via_indexer_dal()
.get_last_processed_l1_block("via_btc_watch")
.await?;

let Some(wallets_map) = storage
.via_wallet_dal()
.get_system_wallets_raw(last_processed_l1_block as i64)
.await?
else {
anyhow::bail!("System wallets not found")
};

let wallets = SystemWallets::try_from(wallets_map)?;
wallets.is_valid_verifier_address(self.config.wallet_address()?)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ impl RestApi {
.iter()
.map(|s| bitcoin::secp256k1::PublicKey::from_str(s).unwrap())
.collect(),
verifier_request_timeout: config.verifier_request_timeout,
session_timeout: config.session_timeout,
verifier_request_timeout: config.verifier_request_timeout(),
session_timeout: config.session_timeout(),
};

let transaction_builder = Arc::new(TransactionBuilder::new(btc_client.clone())?);
Expand Down
12 changes: 6 additions & 6 deletions via_verifier/node/via_verifier_coordinator/src/verifier/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ impl ViaWithdrawalVerifier {
}

async fn get_session(&self) -> anyhow::Result<SigningSessionResponse> {
let url = format!("{}/session", self.verifier_config.coordinator_http_url);
let url = format!("{}/session", self.verifier_config.coordinator_http_url());
let headers = self.create_request_headers()?;
let resp = self
.client
Expand All @@ -295,7 +295,7 @@ impl ViaWithdrawalVerifier {
async fn get_session_nonces(&self) -> anyhow::Result<BTreeMap<usize, BTreeMap<usize, String>>> {
let nonces_url = format!(
"{}/session/nonce",
self.verifier_config.coordinator_http_url
self.verifier_config.coordinator_http_url()
);
let headers = self.create_request_headers()?;
let resp = self
Expand Down Expand Up @@ -338,7 +338,7 @@ impl ViaWithdrawalVerifier {

let url = format!(
"{}/session/nonce",
self.verifier_config.coordinator_http_url
self.verifier_config.coordinator_http_url()
);
let headers = self.create_request_headers()?;

Expand Down Expand Up @@ -373,7 +373,7 @@ impl ViaWithdrawalVerifier {
) -> anyhow::Result<BTreeMap<usize, BTreeMap<usize, PartialSignature>>> {
let url = format!(
"{}/session/signature",
self.verifier_config.coordinator_http_url
self.verifier_config.coordinator_http_url()
);
let headers = self.create_request_headers()?;
let resp = self
Expand Down Expand Up @@ -475,7 +475,7 @@ impl ViaWithdrawalVerifier {

let url = format!(
"{}/session/signature",
self.verifier_config.coordinator_http_url
self.verifier_config.coordinator_http_url()
);
let headers = self.create_request_headers()?;

Expand Down Expand Up @@ -535,7 +535,7 @@ impl ViaWithdrawalVerifier {
}

async fn create_new_session(&mut self) -> anyhow::Result<()> {
let url = format!("{}/session/new", self.verifier_config.coordinator_http_url);
let url = format!("{}/session/new", self.verifier_config.coordinator_http_url());
let headers = self.create_request_headers()?;
let resp = self
.client
Expand Down
24 changes: 1 addition & 23 deletions via_verifier/node/via_zk_verifier/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use via_verifier_types::protocol_version::check_if_supported_sequencer_version;
use zksync_config::{ViaBtcWatchConfig, ViaVerifierConfig};
use zksync_da_client::{types::InclusionData, DataAvailabilityClient};
use zksync_object_store::ObjectStore;
use zksync_types::{via_wallet::SystemWallets, L1BatchNumber, H160, H256};
use zksync_types::{L1BatchNumber, H160, H256};

mod metrics;

Expand Down Expand Up @@ -91,8 +91,6 @@ impl ViaVerifier {
return Ok(());
}

self.validate_verifier_address().await?;

if let Some((l1_batch_number, mut raw_tx_id)) = storage
.via_votes_dal()
.get_first_not_verified_l1_batch_in_canonical_inscription_chain()
Expand Down Expand Up @@ -407,24 +405,4 @@ impl ViaVerifier {

Ok((blob, hash))
}
/// Check if the wallet is in the verifier set.
async fn validate_verifier_address(&self) -> anyhow::Result<()> {
let mut storage = self.pool.connection().await?;

let last_processed_l1_block = storage
.via_indexer_dal()
.get_last_processed_l1_block("via_btc_watch")
.await?;

let Some(wallets_map) = storage
.via_wallet_dal()
.get_system_wallets_raw(last_processed_l1_block as i64)
.await?
else {
anyhow::bail!("System wallets not found")
};

let wallets = SystemWallets::try_from(wallets_map)?;
wallets.is_valid_verifier_address(self.config.wallet_address()?)
}
}