From dc7d533c426389718f766d634b82aa50907dc8ca Mon Sep 17 00:00:00 2001 From: silverpill Date: Wed, 10 Aug 2022 11:57:18 +0000 Subject: [PATCH] Allow blockchain config to have sub-types --- src/config/blockchain.rs | 17 +++++++++++++++-- src/config/main.rs | 8 +++++--- src/config/mod.rs | 2 +- src/ethereum/contracts.rs | 4 ++-- src/ethereum/nft.rs | 4 ++-- src/ethereum/subscriptions.rs | 4 ++-- src/main.rs | 24 +++++++++++++++--------- src/mastodon_api/accounts/views.rs | 6 ++++-- src/mastodon_api/instance/types.rs | 10 ++++++---- src/mastodon_api/statuses/views.rs | 6 ++++-- 10 files changed, 56 insertions(+), 29 deletions(-) diff --git a/src/config/blockchain.rs b/src/config/blockchain.rs index 0d0da8d..3fe999d 100644 --- a/src/config/blockchain.rs +++ b/src/config/blockchain.rs @@ -11,7 +11,7 @@ fn default_chain_sync_step() -> u64 { 1000 } fn default_chain_reorg_max_depth() -> u64 { 10 } #[derive(Clone, Deserialize)] -pub struct BlockchainConfig { +pub struct EthereumConfig { // CAIP-2 chain ID pub chain_id: ChainId, // Additional information for clients @@ -30,7 +30,7 @@ pub struct BlockchainConfig { pub chain_reorg_max_depth: u64, } -impl BlockchainConfig { +impl EthereumConfig { pub fn try_ethereum_chain_id(&self) -> Result { parse_caip2_chain_id(&self.chain_id) } @@ -39,3 +39,16 @@ impl BlockchainConfig { self.try_ethereum_chain_id().unwrap() } } + +#[derive(Clone, Deserialize)] +#[serde(untagged)] +pub enum BlockchainConfig { + Ethereum(EthereumConfig), +} + +impl BlockchainConfig { + pub fn ethereum_config(&self) -> Option<&EthereumConfig> { + let Self::Ethereum(ethereum_config) = self; + Some(ethereum_config) + } +} diff --git a/src/config/main.rs b/src/config/main.rs index 4fced9b..d3a41dd 100644 --- a/src/config/main.rs +++ b/src/config/main.rs @@ -243,9 +243,11 @@ pub fn parse_config() -> Config { check_directory_owner(&config.storage_dir); config.try_instance_url().expect("invalid instance URI"); if let Some(blockchain_config) = config.blockchain.as_ref() { - blockchain_config.try_ethereum_chain_id().unwrap(); - if !blockchain_config.contract_dir.exists() { - panic!("contract directory does not exist"); + if let Some(ethereum_config) = blockchain_config.ethereum_config() { + ethereum_config.try_ethereum_chain_id().unwrap(); + if !ethereum_config.contract_dir.exists() { + panic!("contract directory does not exist"); + }; }; }; if config.ipfs_api_url.is_some() != config.ipfs_gateway_url.is_some() { diff --git a/src/config/mod.rs b/src/config/mod.rs index fa33a13..e93eda3 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -2,6 +2,6 @@ mod blockchain; mod environment; mod main; -pub use blockchain::BlockchainConfig; +pub use blockchain::EthereumConfig; pub use environment::Environment; pub use main::{parse_config, Config, Instance}; diff --git a/src/ethereum/contracts.rs b/src/ethereum/contracts.rs index 05bb6f7..55cdbfe 100644 --- a/src/ethereum/contracts.rs +++ b/src/ethereum/contracts.rs @@ -8,7 +8,7 @@ use web3::{ transports::Http, }; -use crate::config::BlockchainConfig; +use crate::config::EthereumConfig; use super::api::connect; use super::errors::EthereumError; use super::sync::{ @@ -96,7 +96,7 @@ pub struct Blockchain { } pub async fn get_contracts( - config: &BlockchainConfig, + config: &EthereumConfig, storage_dir: &Path, ) -> Result { let web3 = connect(&config.api_url)?; diff --git a/src/ethereum/nft.rs b/src/ethereum/nft.rs index 6184826..33bdd52 100644 --- a/src/ethereum/nft.rs +++ b/src/ethereum/nft.rs @@ -11,7 +11,7 @@ use web3::{ types::{BlockNumber, FilterBuilder}, }; -use crate::config::BlockchainConfig; +use crate::config::EthereumConfig; use crate::database::{Pool, get_database_client}; use crate::errors::DatabaseError; use crate::ipfs::utils::parse_ipfs_url; @@ -127,7 +127,7 @@ pub async fn process_nft_events( } pub fn create_mint_signature( - blockchain_config: &BlockchainConfig, + blockchain_config: &EthereumConfig, user_address: &str, token_uri: &str, ) -> Result { diff --git a/src/ethereum/subscriptions.rs b/src/ethereum/subscriptions.rs index 4c51fe5..969275b 100644 --- a/src/ethereum/subscriptions.rs +++ b/src/ethereum/subscriptions.rs @@ -15,7 +15,7 @@ use crate::activitypub::builders::{ remove_person::prepare_remove_person, }; use crate::activitypub::identifiers::LocalActorCollection; -use crate::config::{BlockchainConfig, Instance}; +use crate::config::{EthereumConfig, Instance}; use crate::database::{Pool, get_database_client}; use crate::errors::{ConversionError, DatabaseError}; use crate::models::notifications::queries::{ @@ -245,7 +245,7 @@ pub async fn check_subscriptions( } pub fn create_subscription_signature( - blockchain_config: &BlockchainConfig, + blockchain_config: &EthereumConfig, user_address: &str, price: u64, ) -> Result { diff --git a/src/main.rs b/src/main.rs index 31d981e..08e6e38 100644 --- a/src/main.rs +++ b/src/main.rs @@ -53,9 +53,13 @@ async fn main() -> std::io::Result<()> { ); let maybe_blockchain = if let Some(blockchain_config) = &config.blockchain { - // Create blockchain interface - get_contracts(blockchain_config, &config.storage_dir).await - .map(Some).unwrap() + if let Some(ethereum_config) = blockchain_config.ethereum_config() { + // Create blockchain interface + get_contracts(ethereum_config, &config.storage_dir).await + .map(Some).unwrap() + } else { + None + } } else { None }; @@ -148,12 +152,14 @@ async fn main() -> std::io::Result<()> { .service(nodeinfo::get_nodeinfo) .service(nodeinfo::get_nodeinfo_2_0); if let Some(blockchain_config) = &config.blockchain { - // Serve artifacts if available - app = app.service(actix_files::Files::new( - "/contracts", - &blockchain_config.contract_dir, - )); - } + if let Some(ethereum_config) = blockchain_config.ethereum_config() { + // Serve artifacts if available + app = app.service(actix_files::Files::new( + "/contracts", + ðereum_config.contract_dir, + )); + }; + }; app }) .workers(num_workers) diff --git a/src/mastodon_api/accounts/views.rs b/src/mastodon_api/accounts/views.rs index 634fd9b..99e9d52 100644 --- a/src/mastodon_api/accounts/views.rs +++ b/src/mastodon_api/accounts/views.rs @@ -293,14 +293,16 @@ async fn authorize_subscription( ) -> Result { let db_client = &**get_database_client(&db_pool).await?; let current_user = get_current_user(db_client, auth.token()).await?; - let blockchain_config = config.blockchain.as_ref() + let ethereum_config = config.blockchain.as_ref() + .ok_or(HttpError::NotSupported)? + .ethereum_config() .ok_or(HttpError::NotSupported)?; // Wallet address must be public, because subscribers should be able // to verify that payments are actually sent to the recipient. let wallet_address = current_user.public_wallet_address() .ok_or(HttpError::PermissionError)?; let signature = create_subscription_signature( - blockchain_config, + ethereum_config, &wallet_address, query_params.price, ).map_err(|_| HttpError::InternalError)?; diff --git a/src/mastodon_api/instance/types.rs b/src/mastodon_api/instance/types.rs index 47ae0c3..c938758 100644 --- a/src/mastodon_api/instance/types.rs +++ b/src/mastodon_api/instance/types.rs @@ -41,6 +41,8 @@ fn get_full_api_version(version: &str) -> String { impl InstanceInfo { pub fn create(config: &Config, maybe_blockchain: Option<&ContractSet>) -> Self { + let ethereum_config = config.blockchain.as_ref() + .and_then(|conf| conf.ethereum_config()); let blockchain_features = maybe_blockchain.map(|contract_set| { BlockchainFeatures { minter: contract_set.collectible.is_some(), @@ -56,14 +58,14 @@ impl InstanceInfo { registrations: config.registrations_open, login_message: config.login_message.clone(), post_character_limit: config.post_character_limit, - blockchain_id: config.blockchain.as_ref() + blockchain_id: ethereum_config .map(|val| val.chain_id.to_string()), - blockchain_explorer_url: config.blockchain.as_ref() + blockchain_explorer_url: ethereum_config .and_then(|val| val.explorer_url.clone()), - blockchain_contract_address: config.blockchain.as_ref() + blockchain_contract_address: ethereum_config .map(|val| val.contract_address.clone()), blockchain_features: blockchain_features, - blockchain_info: config.blockchain.as_ref() + blockchain_info: ethereum_config .and_then(|val| val.chain_info.clone()), ipfs_gateway_url: config.ipfs_gateway_url.clone(), } diff --git a/src/mastodon_api/statuses/views.rs b/src/mastodon_api/statuses/views.rs index 25d5b6f..cb9060a 100644 --- a/src/mastodon_api/statuses/views.rs +++ b/src/mastodon_api/statuses/views.rs @@ -425,7 +425,9 @@ async fn get_signature( ) -> Result { let db_client = &**get_database_client(&db_pool).await?; let current_user = get_current_user(db_client, auth.token()).await?; - let blockchain_config = config.blockchain.as_ref() + let ethereum_config = config.blockchain.as_ref() + .ok_or(HttpError::NotSupported)? + .ethereum_config() .ok_or(HttpError::NotSupported)?; // Wallet address must be public because minting exposes it let wallet_address = current_user.public_wallet_address() @@ -440,7 +442,7 @@ async fn get_signature( .ok_or(HttpError::PermissionError)?; let token_uri = get_ipfs_url(&ipfs_cid); let signature = create_mint_signature( - blockchain_config, + ethereum_config, &wallet_address, &token_uri, ).map_err(|_| HttpError::InternalError)?;