From 14b47084bf527a37f71c105c0c84f8376678a999 Mon Sep 17 00:00:00 2001 From: Moein zargarzadeh Date: Sat, 31 May 2025 16:23:37 +0330 Subject: [PATCH 1/3] refactor: encapsulate oracle config access via getter methods - Add getter methods for oracle_address, oracle_mnemonic, change_address, and network_prefix - Prefer reading oracle_mnemonic from env vars or oracle-config file - Replace direct field access with getter methods throughout the codebase - Remove unnecessary address cloning and unwrapping - Improve encapsulation and enable more secure config handling --- core/src/actions.rs | 4 +- core/src/api.rs | 6 +- core/src/cli_commands/bootstrap.rs | 4 +- .../src/cli_commands/extract_reward_tokens.rs | 6 +- core/src/cli_commands/prepare_update.rs | 17 +- .../src/cli_commands/transfer_oracle_token.rs | 8 +- core/src/cli_commands/update_pool.rs | 8 +- core/src/cli_commands/vote_update_pool.rs | 6 +- core/src/explorer_api.rs | 2 +- core/src/main.rs | 10 +- core/src/metrics.rs | 4 +- core/src/node_interface/node_api.rs | 9 +- core/src/oracle_config.rs | 178 ++++++++++++++---- core/src/pool_commands.rs | 2 +- 14 files changed, 178 insertions(+), 86 deletions(-) diff --git a/core/src/actions.rs b/core/src/actions.rs index e862eee1..606d237a 100644 --- a/core/src/actions.rs +++ b/core/src/actions.rs @@ -64,7 +64,7 @@ fn execute_refresh_action( node_api: &NodeApi, ) -> Result<(), ActionExecError> { let tx_id = node_api.sign_and_submit_transaction(action.transaction_context)?; - let network_prefix = &ORACLE_CONFIG.oracle_address.network(); + let network_prefix = &ORACLE_CONFIG.get_network_prefix(); log::info!( "Refresh tx published. Check status: {}", ergo_explorer_transaction_link(tx_id, *network_prefix) @@ -77,7 +77,7 @@ fn execute_publish_datapoint_action( node_api: &NodeApi, ) -> Result<(), ActionExecError> { let tx_id = node_api.sign_and_submit_transaction(action.transaction_context)?; - let network_prefix = &ORACLE_CONFIG.oracle_address.network(); + let network_prefix = &ORACLE_CONFIG.get_network_prefix(); log::info!( "Datapoint tx published. Check status: {}", ergo_explorer_transaction_link(tx_id, *network_prefix) diff --git a/core/src/api.rs b/core/src/api.rs index c7691dcf..f2731467 100644 --- a/core/src/api.rs +++ b/core/src/api.rs @@ -37,7 +37,7 @@ async fn root() -> &'static str { async fn oracle_info() -> impl IntoResponse { let conf = &ORACLE_CONFIG; Json(json! ( { - "oracle_address": conf.oracle_address.to_base58(), + "oracle_address": conf.get_oracle_address().to_base58(), "base_fee": conf.base_fee, } )) } @@ -79,7 +79,7 @@ fn oracle_status_sync(oracle_pool: Arc) -> Result impl IntoResponse { let conf = &POOL_CONFIG; - let network = &ORACLE_CONFIG.oracle_address.network(); + let network = &ORACLE_CONFIG.get_network_prefix(); let address_encoder = AddressEncoder::new(*network); let pool_box_address = Address::P2S( conf.pool_box_wrapper_inputs @@ -243,7 +243,7 @@ fn pool_health_sync(oracle_pool: Arc) -> Result Result<(), any let oracle_config = &ORACLE_CONFIG; let s = std::fs::read_to_string(config_file_name)?; let config: BootstrapConfig = serde_yaml::from_str(&s)?; - let change_address = ORACLE_CONFIG.change_address.clone().unwrap(); + let change_address = ORACLE_CONFIG.get_change_address().clone(); debug!("Change address: {:?}", change_address); let erg_value_per_box = config.oracle_contract_parameters.min_storage_rent; let input = BootstrapInput { - oracle_address: oracle_config.oracle_address.clone(), + oracle_address: oracle_config.get_oracle_address().clone(), config, node_api, tx_fee: *BASE_FEE, diff --git a/core/src/cli_commands/extract_reward_tokens.rs b/core/src/cli_commands/extract_reward_tokens.rs index 04c1c6bf..87bc8998 100644 --- a/core/src/cli_commands/extract_reward_tokens.rs +++ b/core/src/cli_commands/extract_reward_tokens.rs @@ -74,15 +74,15 @@ pub fn extract_reward_tokens( let rewards_destination = AddressEncoder::unchecked_parse_network_address_from_str(&rewards_destination_str)?; let network_prefix = rewards_destination.network(); - let oracle_address = ORACLE_CONFIG.oracle_address.clone(); - let change_address = ORACLE_CONFIG.change_address.clone(); + let oracle_address = ORACLE_CONFIG.get_oracle_address().clone(); + let change_address = ORACLE_CONFIG.get_change_address().clone(); let (context, num_reward_tokens) = build_extract_reward_tokens_tx( local_datapoint_box_source, node_api, rewards_destination.address(), height, oracle_address, - change_address.unwrap().address(), + change_address.address(), )?; println!( diff --git a/core/src/cli_commands/prepare_update.rs b/core/src/cli_commands/prepare_update.rs index bcc9acc6..7f467347 100644 --- a/core/src/cli_commands/prepare_update.rs +++ b/core/src/cli_commands/prepare_update.rs @@ -91,7 +91,7 @@ pub fn prepare_update( let s = std::fs::read_to_string(config_file_name)?; let config_serde: UpdateBootstrapConfigSerde = serde_yaml::from_str(&s)?; - let change_address = ORACLE_CONFIG.change_address.clone().unwrap().address(); + let change_address = ORACLE_CONFIG.get_change_address().clone().address(); let config = UpdateBootstrapConfig::try_from(config_serde)?; let update_bootstrap_input = PrepareUpdateInput { node_api, @@ -199,7 +199,7 @@ impl<'a> PrepareUpdate<'a> { pool_config: &'a PoolConfig, oracle_config: &'a OracleConfig, ) -> Result { - let wallet_pk_ergo_tree = oracle_config.oracle_address.address().script()?; + let wallet_pk_ergo_tree = oracle_config.get_oracle_address().address().script()?; Ok(Self { input, wallet_pk_ergo_tree, @@ -341,7 +341,7 @@ impl<'a> PrepareUpdate<'a> { let target_balance = self.calc_target_balance(self.num_transactions_left)?; debug!("target_balance: {:?}", target_balance); let unspent_boxes = self.input.node_api.get_unspent_boxes_by_address( - &self.oracle_config.oracle_address.to_base58(), + &self.oracle_config.get_oracle_address().to_base58(), target_balance, [].into(), )?; @@ -617,16 +617,16 @@ token_ids: rescan_height: 141887 "#).unwrap(); - let old_oracle_config: OracleConfig = serde_yaml::from_str( + let mut old_oracle_config: OracleConfig = serde_yaml::from_str( r#" node_url: http://10.94.77.47:9052 base_fee: 1100000 scan_start_height: 0 log_level: ~ core_api_port: 9010 -oracle_address: 3Wy3BaCjGDWE3bjjZkNo3aWaMz3cYrePMFhchcKovY9uG9vhpAuW data_point_source: NanoErgXau data_point_source_custom_script: ~ +oracle_network: testnet "#, ) .unwrap(); @@ -638,10 +638,7 @@ data_point_source_custom_script: ~ NetworkPrefix::Testnet, &Address::P2Pk(secret.public_image()), ); - let old_oracle_config = OracleConfig { - oracle_address: network_address.clone(), - ..old_oracle_config - }; + old_oracle_config.set_oracle_address(Some(network_address.clone())); let ergo_tree = network_address.address().script().unwrap(); let value = BASE_FEE.checked_mul_u32(10000).unwrap(); @@ -710,6 +707,6 @@ data_point_source_custom_script: ~ let prepare = PrepareUpdate::new(prepare_update_input, &old_pool_config, &old_oracle_config).unwrap(); let (new_pool_config, _) = prepare.execute(state).unwrap(); - assert!(new_pool_config.token_ids != old_pool_config.token_ids); + assert_ne!(new_pool_config.token_ids, old_pool_config.token_ids); } } diff --git a/core/src/cli_commands/transfer_oracle_token.rs b/core/src/cli_commands/transfer_oracle_token.rs index 570bca83..d8c6384e 100644 --- a/core/src/cli_commands/transfer_oracle_token.rs +++ b/core/src/cli_commands/transfer_oracle_token.rs @@ -72,11 +72,9 @@ pub fn transfer_oracle_token( ) -> Result<(), anyhow::Error> { let rewards_destination = AddressEncoder::unchecked_parse_network_address_from_str(&rewards_destination_str)?; - let oracle_address = ORACLE_CONFIG.oracle_address.clone(); - let (change_address, network_prefix) = { - let net_address = ORACLE_CONFIG.change_address.clone().unwrap(); - (net_address.address(), net_address.network()) - }; + let oracle_address = ORACLE_CONFIG.get_oracle_address().clone(); + let change_address = ORACLE_CONFIG.get_change_address().clone().address(); + let network_prefix = ORACLE_CONFIG.get_network_prefix(); let context = build_transfer_oracle_token_tx( local_datapoint_box_source, node_api, diff --git a/core/src/cli_commands/update_pool.rs b/core/src/cli_commands/update_pool.rs index 157c3914..0b08f608 100644 --- a/core/src/cli_commands/update_pool.rs +++ b/core/src/cli_commands/update_pool.rs @@ -85,11 +85,9 @@ pub fn update_pool( "Reward token id in pool_config_updated.yaml does not match the one from the command line" ); } - let oracle_address = ORACLE_CONFIG.oracle_address.clone(); - let (change_address, network_prefix) = { - let net_addr = ORACLE_CONFIG.change_address.clone().unwrap(); - (net_addr.address(), net_addr.network()) - }; + let oracle_address = ORACLE_CONFIG.get_oracle_address().clone(); + let change_address = ORACLE_CONFIG.get_change_address().clone().address(); + let network_prefix = ORACLE_CONFIG.get_network_prefix(); let new_pool_contract = PoolContract::checked_load(&new_pool_config.pool_box_wrapper_inputs.contract_inputs)?; diff --git a/core/src/cli_commands/vote_update_pool.rs b/core/src/cli_commands/vote_update_pool.rs index 58bfbb0a..1b5b04a7 100644 --- a/core/src/cli_commands/vote_update_pool.rs +++ b/core/src/cli_commands/vote_update_pool.rs @@ -68,12 +68,12 @@ pub fn vote_update_pool( height: BlockHeight, ballot_contract: &BallotContract, ) -> Result<(), anyhow::Error> { - let oracle_address = ORACLE_CONFIG.oracle_address.clone(); - let change_network_address = ORACLE_CONFIG.change_address.clone().unwrap(); + let oracle_address = ORACLE_CONFIG.get_oracle_address().clone(); + let change_network_address = ORACLE_CONFIG.get_change_address().clone(); let network_prefix = change_network_address.network(); let new_pool_box_address_hash = Digest32::try_from(new_pool_box_address_hash_str)?; let ballot_token_owner = - if let Address::P2Pk(ballot_token_owner) = ORACLE_CONFIG.oracle_address.address() { + if let Address::P2Pk(ballot_token_owner) = oracle_address.address() { ballot_token_owner.h } else { return Err(VoteUpdatePoolError::IncorrectBallotTokenOwnerAddress.into()); diff --git a/core/src/explorer_api.rs b/core/src/explorer_api.rs index 924d5b7c..afe32760 100644 --- a/core/src/explorer_api.rs +++ b/core/src/explorer_api.rs @@ -84,7 +84,7 @@ pub fn wait_for_tx_confirmation(tx_id: TxId) { } pub fn wait_for_txs_confirmation(tx_ids: Vec) { - let network = ORACLE_CONFIG.oracle_address.network(); + let network = ORACLE_CONFIG.get_network_prefix(); let timeout = Duration::from_secs(1200); let explorer_url = ORACLE_CONFIG .explorer_url diff --git a/core/src/main.rs b/core/src/main.rs index e5d9ce3d..9bb57d42 100644 --- a/core/src/main.rs +++ b/core/src/main.rs @@ -274,14 +274,15 @@ fn main() { log_on_launch(); let node_api = NodeApi::new(&ORACLE_CONFIG.node_url); + let _ = node_api.get_wallet(); if !node_api.node.indexer_status().unwrap().is_active { error!("Blockchain indexer is not active on the node"); std::process::exit(exitcode::SOFTWARE); } let _ = node_api.wait_for_indexer_sync(); - let change_address = ORACLE_CONFIG.change_address.clone().unwrap(); - let network_prefix = change_address.network(); + let change_address = ORACLE_CONFIG.get_change_address().clone(); + let network_prefix = ORACLE_CONFIG.get_network_prefix(); #[allow(clippy::wildcard_enum_match_arm)] match args.command { @@ -574,11 +575,6 @@ fn log_and_continue_if_non_fatal( fn log_on_launch() { log::info!("{}", APP_VERSION); - let oracle_address_opt = ORACLE_CONFIG_OPT.as_ref().map(|c| c.oracle_address.clone()); - if let Ok(oracle_address) = oracle_address_opt { - // log::info!("Token ids: {:?}", config.token_ids); - log::info!("Oracle address: {}", oracle_address.to_base58()); - } } fn check_reward_token_opt( diff --git a/core/src/metrics.rs b/core/src/metrics.rs index 8e89f43e..5aef0547 100644 --- a/core/src/metrics.rs +++ b/core/src/metrics.rs @@ -338,7 +338,7 @@ pub fn update_metrics( node_api: &NodeApi, ) -> Result<(), anyhow::Error> { let current_height = (node_api.node.current_block_height()? as u32).into(); - let network_prefix = ORACLE_CONFIG.change_address.clone().unwrap().network(); + let network_prefix = ORACLE_CONFIG.get_network_prefix(); let pool_box = &oracle_pool.get_pool_box_source().get_pool_box()?; { let rate = pool_box.rate(); @@ -362,7 +362,7 @@ pub fn update_metrics( update_oracle_health(&oracle_health); let wallet_balance: i64 = node_api .node - .nano_ergs_balance(&ORACLE_CONFIG.oracle_address.to_base58())? + .nano_ergs_balance(&ORACLE_CONFIG.get_oracle_address().to_base58())? as i64; ORACLE_NODE_WALLET_BALANCE.set(wallet_balance); POOL_BOX_REWARD_TOKEN_AMOUNT.set(pool_box.reward_token().amount.into()); diff --git a/core/src/node_interface/node_api.rs b/core/src/node_interface/node_api.rs index d76899a2..d589d85e 100644 --- a/core/src/node_interface/node_api.rs +++ b/core/src/node_interface/node_api.rs @@ -1,8 +1,7 @@ -use crate::oracle_config::ORACLE_SECRETS; +use crate::oracle_config::ORACLE_CONFIG; use ergo_lib::chain::ergo_state_context::ErgoStateContext; use ergo_lib::chain::transaction::unsigned::UnsignedTransaction; use ergo_lib::chain::transaction::{Transaction, TxId}; -use ergo_lib::ergotree_ir::chain::address::AddressEncoderError; use ergo_lib::ergotree_ir::chain::ergo_box::box_value::BoxValue; use ergo_lib::ergotree_ir::chain::ergo_box::ErgoBox; use ergo_lib::ergotree_ir::chain::token::{Token, TokenId}; @@ -260,7 +259,7 @@ impl NodeApi { /// Get the wallet instance from the oracle secrets. pub fn get_wallet(&self) -> Result { - let secret = ORACLE_SECRETS.secret_key.clone(); + let secret = ORACLE_CONFIG.get_oracle_secret_key(); Ok(Wallet::from_secrets(vec![secret])) } @@ -328,8 +327,4 @@ pub enum NodeApiError { NodeInterfaceError(#[from] NodeError), #[error("Wallet error: {0}")] WalletError(#[from] WalletError), - #[error("AddressEncoder error: {0}")] - AddressEncoderError(#[from] AddressEncoderError), - #[error("no change address is set in node")] - NoChangeAddressSetInNode, } diff --git a/core/src/oracle_config.rs b/core/src/oracle_config.rs index 233dd2c2..69294846 100644 --- a/core/src/oracle_config.rs +++ b/core/src/oracle_config.rs @@ -12,18 +12,20 @@ use ergo_lib::{ ergotree_ir::chain::address::NetworkAddress, ergotree_ir::{ chain::{ - address::{Address, AddressEncoder}, + address::{Address}, ergo_box::box_value::BoxValue, }, sigma_protocol::sigma_boolean::ProveDlog, }, wallet::tx_builder::{self, SUGGESTED_TX_FEE}, }; +use ergo_lib::ergotree_ir::chain::address::NetworkPrefix; use log::LevelFilter; use once_cell::sync; use reqwest::Url; use serde::{Deserialize, Serialize}; use thiserror::Error; +use base16; use crate::explorer_api::explorer_url::default_explorer_api_url; @@ -35,39 +37,131 @@ pub struct OracleConfig { pub base_fee: u64, pub log_level: Option, pub core_api_port: u16, - pub oracle_address: NetworkAddress, - pub change_address: Option, + oracle_network: String, + #[serde(skip)] + network_prefix: Option, + #[serde(skip)] + oracle_address: Option, + #[serde(skip)] + oracle_secret_key: Option, + oracle_secret: Option, + mnemonic: Option, + change_address: Option, pub data_point_source_custom_script: Option, pub explorer_url: Option, pub metrics_port: Option, } -pub struct OracleSecrets { - pub secret_key: SecretKey, -} +impl OracleConfig { + pub fn write_default_config_file(path: &Path) { + let config = OracleConfig::default(); + let yaml_str = serde_yaml::to_string(&config).unwrap(); + let mut file = std::fs::File::create(path).unwrap(); + file.write_all(yaml_str.as_bytes()).unwrap(); + } + + fn network_prefix(network: &str) -> Result { + match network.to_lowercase().as_str() { + "mainnet" => Ok(NetworkPrefix::Mainnet), + "testnet" => Ok(NetworkPrefix::Testnet), + _ => Err(OracleConfigFileError::InvalidNetwork(network.to_string())), + } + } + + /// Returns network prefix (mainnet/testnet) from config + pub fn get_network_prefix(&self) -> NetworkPrefix { + self.network_prefix.unwrap_or_else(|| { + Self::network_prefix(&self.oracle_network).unwrap() + }) + } + + /// Sets oracle address for testing purposes only + pub fn set_oracle_address(&mut self, oracle_address: Option) { + self.oracle_address = oracle_address + } + + /// Returns the oracle address, panics if not set + pub fn get_oracle_address(&self) -> NetworkAddress { + self.oracle_address.clone().unwrap() + } + + /// Returns change address for transactions, panics if not set + pub fn get_change_address(&self) -> NetworkAddress { + self.change_address.clone().unwrap() + } + + /// Returns the oracle's secret key, panics if not set + pub fn get_oracle_secret_key(&self) -> SecretKey { + self.oracle_secret_key.clone().unwrap() + } -impl OracleSecrets { - pub fn load() -> Self { - let mnemonic = std::env::var("ORACLE_WALLET_MNEMONIC").unwrap_or_else(|_| { - panic!("ORACLE_WALLET_MNEMONIC environment variable for sign transactions is not set") - }); + /// Sets oracle secret key from environment or config file + fn set_mnemonic_secret(&mut self) -> Result<(), OracleConfigFileError> { + // Try environment variable ORACLE_WALLET_SECRET + if let Ok(secret) = std::env::var("ORACLE_WALLET_SECRET") { + let secret_bytes = base16::decode(&secret) + .map_err(|e| OracleConfigFileError::MnemonicError(format!("Invalid hex format: {}", e)))?; + + if let Ok(secret_key) = SecretKey::from_bytes(&secret_bytes) { + self.oracle_secret_key = Some(secret_key); + return Ok(()); + } + } + + // Try config's oracle_secret + if let Some(secret) = &self.oracle_secret { + let secret_bytes = base16::decode(secret) + .map_err(|e| OracleConfigFileError::MnemonicError(format!("Invalid hex format in config: {}", e)))?; + + if let Ok(secret_key) = SecretKey::from_bytes(&secret_bytes) { + self.oracle_secret_key = Some(secret_key); + return Ok(()); + } + } + + // Try environment variable ORACLE_WALLET_MNEMONIC + if let Ok(mnemonic) = std::env::var("ORACLE_WALLET_MNEMONIC") { + if let Ok(secret_key) = self.derive_secret_from_mnemonic(&mnemonic) { + self.oracle_secret_key = Some(secret_key); + return Ok(()); + } + } + + // Try config's mnemonic + if let Some(mnemonic) = &self.mnemonic { + if let Ok(secret_key) = self.derive_secret_from_mnemonic(mnemonic) { + self.oracle_secret_key = Some(secret_key); + return Ok(()); + } + } + + Err(OracleConfigFileError::MissingMnemonicSecret) + } + + fn derive_secret_from_mnemonic(&self, mnemonic: &str) -> Result { + let seed = Mnemonic::to_seed(mnemonic, ""); + let ext_sk = ExtSecretKey::derive_master(seed) + .map_err(|e| OracleConfigFileError::MnemonicError(e.to_string()))?; - let seed = Mnemonic::to_seed(&mnemonic, ""); - let ext_sk = ExtSecretKey::derive_master(seed).unwrap(); // bip-32 path for the first key let path = "m/44'/429'/0'/0/0"; - let secret = ext_sk.derive(path.parse().unwrap()).unwrap().secret_key(); + let secret_key = ext_sk.derive(path.parse().unwrap()) + .map_err(|e| OracleConfigFileError::MnemonicError(e.to_string()))? + .secret_key(); - Self { secret_key: secret } + Ok(secret_key) } -} -impl OracleConfig { - pub fn write_default_config_file(path: &Path) { - let config = OracleConfig::default(); - let yaml_str = serde_yaml::to_string(&config).unwrap(); - let mut file = std::fs::File::create(path).unwrap(); - file.write_all(yaml_str.as_bytes()).unwrap(); + /// Derives oracle address from the secret key + fn derive_oracle_address(&mut self) -> Result { + self.set_mnemonic_secret()?; + let network_prefix = self.get_network_prefix(); + let oracle_address = NetworkAddress::new( + network_prefix, + &self.oracle_secret_key.clone().unwrap().get_address_from_public_image(), + ); + log::info!("Oracle Address derived from secret: {}", oracle_address.to_base58()); + Ok(oracle_address) } fn load() -> Result { @@ -81,14 +175,20 @@ impl OracleConfig { ))?; let mut config = Self::load_from_str(&config_str).context("failed to parse oracle config file")?; + + // Set network prefix + config.network_prefix = Some(Self::network_prefix(&config.oracle_network) + .context("failed to parse network prefix")?); + + // Derive oracle address from mnemonic + config.oracle_address = Some(config + .derive_oracle_address() + .context("failed to derive oracle address from mnemonic")?); + if config.change_address.is_none() { - config.change_address = Some(config.oracle_address.clone()); + config.change_address = Some(config.oracle_address.clone().unwrap()); log::info!("Set oracle address as change address"); } - let _ = config - .oracle_address_p2pk() - .context("failed to parse oracle address")?; - let _ = config .change_address_p2pk() .context("failed to parse change address")?; @@ -108,7 +208,7 @@ impl OracleConfig { } pub fn oracle_address_p2pk(&self) -> Result { - if let Address::P2Pk(public_key) = self.oracle_address.address() { + if let Address::P2Pk(public_key) = self.get_oracle_address().address() { Ok(public_key.clone()) } else { Err(OracleConfigFileError::InvalidOracleAddress) @@ -134,23 +234,32 @@ pub enum OracleConfigFileError { InvalidOracleAddress, #[error("Invalid change address, must be P2PK")] InvalidChangeAddress, + #[error("Invalid network: {0}. Must be either 'mainnet' or 'testnet'")] + InvalidNetwork(String), + #[error("Mnemonic or Secret not found in environment or config file")] + MissingMnemonicSecret, + #[error("Error processing mnemonic: {0}")] + MnemonicError(String), } impl Default for OracleConfig { fn default() -> Self { - let address = AddressEncoder::unchecked_parse_network_address_from_str( - "9hEQHEMyY1K1vs79vJXFtNjr2dbQbtWXF99oVWGJ5c4xbcLdBsw", - ) - .unwrap(); + let network = "mainnet".to_string(); + let network_prefix = NetworkPrefix::Mainnet; Self { - oracle_address: address.clone(), + oracle_address: None, + oracle_secret: None, + oracle_secret_key: None, + mnemonic: None, + oracle_network: network.clone(), + network_prefix: Some(network_prefix), change_address: None, core_api_port: 9010, data_point_source_custom_script: None, base_fee: *tx_builder::SUGGESTED_TX_FEE().as_u64(), log_level: LevelFilter::Info.into(), node_url: Url::parse("http://127.0.0.1:9053").unwrap(), - explorer_url: Some(default_explorer_api_url(address.network())), + explorer_url: Some(default_explorer_api_url(network_prefix)), metrics_port: None, } } @@ -159,7 +268,6 @@ impl Default for OracleConfig { pub static ORACLE_CONFIG_FILE_PATH: sync::OnceCell = sync::OnceCell::new(); lazy_static! { pub static ref ORACLE_CONFIG: OracleConfig = OracleConfig::load().unwrap(); - pub static ref ORACLE_SECRETS: OracleSecrets = OracleSecrets::load(); pub static ref ORACLE_CONFIG_OPT: Result = OracleConfig::load(); pub static ref BASE_FEE: BoxValue = ORACLE_CONFIG_OPT .as_ref() diff --git a/core/src/pool_commands.rs b/core/src/pool_commands.rs index 3c4f95a7..e48aa6f5 100644 --- a/core/src/pool_commands.rs +++ b/core/src/pool_commands.rs @@ -60,7 +60,7 @@ pub fn build_action( let datapoint_boxes_source = op.get_posted_datapoint_boxes_source(); let pool_box = op.get_pool_box_source().get_pool_box()?; let current_epoch_counter = pool_box.epoch_counter(); - let oracle_address = &ORACLE_CONFIG.oracle_address; + let oracle_address = &ORACLE_CONFIG.get_oracle_address(); match cmd { PoolCommand::PublishFirstDataPoint => build_publish_first_datapoint_action( node_api, From c6a704389f238df0e2ea350904db25f9310da1e0 Mon Sep 17 00:00:00 2001 From: Moein zargarzadeh Date: Sat, 31 May 2025 16:34:47 +0330 Subject: [PATCH 2/3] rename mnemonic config name --- core/src/oracle_config.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/oracle_config.rs b/core/src/oracle_config.rs index 69294846..1d8b82be 100644 --- a/core/src/oracle_config.rs +++ b/core/src/oracle_config.rs @@ -45,7 +45,7 @@ pub struct OracleConfig { #[serde(skip)] oracle_secret_key: Option, oracle_secret: Option, - mnemonic: Option, + oracle_mnemonic: Option, change_address: Option, pub data_point_source_custom_script: Option, pub explorer_url: Option, @@ -128,7 +128,7 @@ impl OracleConfig { } // Try config's mnemonic - if let Some(mnemonic) = &self.mnemonic { + if let Some(mnemonic) = &self.oracle_mnemonic { if let Ok(secret_key) = self.derive_secret_from_mnemonic(mnemonic) { self.oracle_secret_key = Some(secret_key); return Ok(()); @@ -250,7 +250,7 @@ impl Default for OracleConfig { oracle_address: None, oracle_secret: None, oracle_secret_key: None, - mnemonic: None, + oracle_mnemonic: None, oracle_network: network.clone(), network_prefix: Some(network_prefix), change_address: None, From bfd5137657747b9e0dd83e240c5961ecef22af6a Mon Sep 17 00:00:00 2001 From: Moein zargarzadeh Date: Sat, 31 May 2025 21:22:07 +0330 Subject: [PATCH 3/3] apply fmt and clippy --- core/Cargo.toml | 49 +++++++++--------- core/src/cli_commands/vote_update_pool.rs | 11 ++-- core/src/oracle_config.rs | 62 ++++++++++++++--------- rust-toolchain | 2 +- 4 files changed, 66 insertions(+), 58 deletions(-) diff --git a/core/Cargo.toml b/core/Cargo.toml index 17cbc641..63de9725 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -14,40 +14,37 @@ edition = "2021" [dependencies] yaml-rust = "0.4.4" -reqwest = { version = "0.11", features = ["blocking"] } -url = { version = "2.2", features = ["serde"] } -serde = { version = "1.0", features = ["derive"] } -serde_yaml = "0.9" +reqwest = { version = "0.11.27", features = ["blocking"] } +url = { version = "2.5.4", features = ["serde"] } +serde = { version = "1.0.219", features = ["derive"] } +serde_yaml = "0.9.27" json = "0.12.4" -serde_json = "1.0.57" -thiserror = "1.0.20" -anyhow = "1.0.32" +serde_json = "1.0.140" +thiserror = "1.0.69" +anyhow = "1.0.97" base16 = "0.2.1" -base64 = "0.13.0" -log = "0.4.11" -log-panics = "2.0.0" -log4rs = "1.2.0" -crossbeam = "0.8" -tokio = { version = "1", features = ["full"] } -tower-http = { version = "0.3.0", features = ["cors"] } -axum = "0.6" +base64 = "0.13.1" +log = "0.4.27" +log-panics = "2.1.0" +log4rs = "1.3.0" +crossbeam = "0.8.4" +tokio = { version = "1.44.1", features = ["full"] } +tower-http = { version = "0.3.5", features = ["cors"] } +axum = "0.6.20" ergo-lib = { workspace = true } ergo-node-interface = { version = "0.5.0" } -derive_more = "0.99" -clap = { version = "4.2.4", features = ["derive"] } +derive_more = "0.99.19" +clap = { version = "4.5.35", features = ["derive"] } exitcode = "1.1.2" -lazy_static = "1.4.0" -once_cell = "1.15.0" -futures = "0.3" -prometheus = "0.13" +lazy_static = "1.5.0" +once_cell = "1.21.3" +futures = "0.3.31" +prometheus = "0.13.4" [dev-dependencies] ergo-lib = { workspace = true, features = ["arbitrary"] } proptest = { version = "1.0.0" } -proptest-derive = { version = "0.3.0" } sigma-test-util = { version = "0.3.0" } ergo-chain-sim = { version = "0.1.0", path = "../ergo-chain-sim" } -env_logger = { version = "0.10.0" } -tokio-test = { version = "0.4" } -pretty_assertions = { workspace = true } -expect-test = "1.0.1" +env_logger = { version = "0.10.2" } +tokio-test = { version = "0.4.4" } diff --git a/core/src/cli_commands/vote_update_pool.rs b/core/src/cli_commands/vote_update_pool.rs index 1b5b04a7..693f57c9 100644 --- a/core/src/cli_commands/vote_update_pool.rs +++ b/core/src/cli_commands/vote_update_pool.rs @@ -72,12 +72,11 @@ pub fn vote_update_pool( let change_network_address = ORACLE_CONFIG.get_change_address().clone(); let network_prefix = change_network_address.network(); let new_pool_box_address_hash = Digest32::try_from(new_pool_box_address_hash_str)?; - let ballot_token_owner = - if let Address::P2Pk(ballot_token_owner) = oracle_address.address() { - ballot_token_owner.h - } else { - return Err(VoteUpdatePoolError::IncorrectBallotTokenOwnerAddress.into()); - }; + let ballot_token_owner = if let Address::P2Pk(ballot_token_owner) = oracle_address.address() { + ballot_token_owner.h + } else { + return Err(VoteUpdatePoolError::IncorrectBallotTokenOwnerAddress.into()); + }; let context = if let Some(local_ballot_box) = local_ballot_box_source.get_ballot_box()? { log::debug!("Found local ballot box"); // Note: the ballot box contains the ballot token, but the box is guarded by the contract, diff --git a/core/src/oracle_config.rs b/core/src/oracle_config.rs index 1d8b82be..f718b9dd 100644 --- a/core/src/oracle_config.rs +++ b/core/src/oracle_config.rs @@ -5,27 +5,23 @@ use std::{ }; use anyhow::Context; +use ergo_lib::ergotree_ir::chain::address::NetworkPrefix; use ergo_lib::wallet::ext_secret_key::ExtSecretKey; use ergo_lib::wallet::mnemonic::Mnemonic; use ergo_lib::wallet::secret_key::SecretKey; use ergo_lib::{ ergotree_ir::chain::address::NetworkAddress, ergotree_ir::{ - chain::{ - address::{Address}, - ergo_box::box_value::BoxValue, - }, + chain::{address::Address, ergo_box::box_value::BoxValue}, sigma_protocol::sigma_boolean::ProveDlog, }, wallet::tx_builder::{self, SUGGESTED_TX_FEE}, }; -use ergo_lib::ergotree_ir::chain::address::NetworkPrefix; use log::LevelFilter; use once_cell::sync; use reqwest::Url; use serde::{Deserialize, Serialize}; use thiserror::Error; -use base16; use crate::explorer_api::explorer_url::default_explorer_api_url; @@ -70,9 +66,8 @@ impl OracleConfig { /// Returns network prefix (mainnet/testnet) from config pub fn get_network_prefix(&self) -> NetworkPrefix { - self.network_prefix.unwrap_or_else(|| { - Self::network_prefix(&self.oracle_network).unwrap() - }) + self.network_prefix + .unwrap_or_else(|| Self::network_prefix(&self.oracle_network).unwrap()) } /// Sets oracle address for testing purposes only @@ -99,9 +94,10 @@ impl OracleConfig { fn set_mnemonic_secret(&mut self) -> Result<(), OracleConfigFileError> { // Try environment variable ORACLE_WALLET_SECRET if let Ok(secret) = std::env::var("ORACLE_WALLET_SECRET") { - let secret_bytes = base16::decode(&secret) - .map_err(|e| OracleConfigFileError::MnemonicError(format!("Invalid hex format: {}", e)))?; - + let secret_bytes = base16::decode(&secret).map_err(|e| { + OracleConfigFileError::MnemonicError(format!("Invalid hex format: {}", e)) + })?; + if let Ok(secret_key) = SecretKey::from_bytes(&secret_bytes) { self.oracle_secret_key = Some(secret_key); return Ok(()); @@ -110,9 +106,10 @@ impl OracleConfig { // Try config's oracle_secret if let Some(secret) = &self.oracle_secret { - let secret_bytes = base16::decode(secret) - .map_err(|e| OracleConfigFileError::MnemonicError(format!("Invalid hex format in config: {}", e)))?; - + let secret_bytes = base16::decode(secret).map_err(|e| { + OracleConfigFileError::MnemonicError(format!("Invalid hex format in config: {}", e)) + })?; + if let Ok(secret_key) = SecretKey::from_bytes(&secret_bytes) { self.oracle_secret_key = Some(secret_key); return Ok(()); @@ -138,14 +135,18 @@ impl OracleConfig { Err(OracleConfigFileError::MissingMnemonicSecret) } - fn derive_secret_from_mnemonic(&self, mnemonic: &str) -> Result { + fn derive_secret_from_mnemonic( + &self, + mnemonic: &str, + ) -> Result { let seed = Mnemonic::to_seed(mnemonic, ""); let ext_sk = ExtSecretKey::derive_master(seed) .map_err(|e| OracleConfigFileError::MnemonicError(e.to_string()))?; // bip-32 path for the first key let path = "m/44'/429'/0'/0/0"; - let secret_key = ext_sk.derive(path.parse().unwrap()) + let secret_key = ext_sk + .derive(path.parse().unwrap()) .map_err(|e| OracleConfigFileError::MnemonicError(e.to_string()))? .secret_key(); @@ -158,9 +159,16 @@ impl OracleConfig { let network_prefix = self.get_network_prefix(); let oracle_address = NetworkAddress::new( network_prefix, - &self.oracle_secret_key.clone().unwrap().get_address_from_public_image(), + &self + .oracle_secret_key + .clone() + .unwrap() + .get_address_from_public_image(), + ); + log::info!( + "Oracle Address derived from secret: {}", + oracle_address.to_base58() ); - log::info!("Oracle Address derived from secret: {}", oracle_address.to_base58()); Ok(oracle_address) } @@ -175,15 +183,19 @@ impl OracleConfig { ))?; let mut config = Self::load_from_str(&config_str).context("failed to parse oracle config file")?; - + // Set network prefix - config.network_prefix = Some(Self::network_prefix(&config.oracle_network) - .context("failed to parse network prefix")?); + config.network_prefix = Some( + Self::network_prefix(&config.oracle_network) + .context("failed to parse network prefix")?, + ); // Derive oracle address from mnemonic - config.oracle_address = Some(config - .derive_oracle_address() - .context("failed to derive oracle address from mnemonic")?); + config.oracle_address = Some( + config + .derive_oracle_address() + .context("failed to derive oracle address from mnemonic")?, + ); if config.change_address.is_none() { config.change_address = Some(config.oracle_address.clone().unwrap()); diff --git a/rust-toolchain b/rust-toolchain index e3a84f22..8f03ba21 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.81.0 \ No newline at end of file +1.82.0 \ No newline at end of file