Allow blockchain config to have sub-types

This commit is contained in:
silverpill 2022-08-10 11:57:18 +00:00
parent c4e5438ac2
commit dc7d533c42
10 changed files with 56 additions and 29 deletions

View file

@ -11,7 +11,7 @@ fn default_chain_sync_step() -> u64 { 1000 }
fn default_chain_reorg_max_depth() -> u64 { 10 } fn default_chain_reorg_max_depth() -> u64 { 10 }
#[derive(Clone, Deserialize)] #[derive(Clone, Deserialize)]
pub struct BlockchainConfig { pub struct EthereumConfig {
// CAIP-2 chain ID // CAIP-2 chain ID
pub chain_id: ChainId, pub chain_id: ChainId,
// Additional information for clients // Additional information for clients
@ -30,7 +30,7 @@ pub struct BlockchainConfig {
pub chain_reorg_max_depth: u64, pub chain_reorg_max_depth: u64,
} }
impl BlockchainConfig { impl EthereumConfig {
pub fn try_ethereum_chain_id(&self) -> Result<u32, ChainIdError> { pub fn try_ethereum_chain_id(&self) -> Result<u32, ChainIdError> {
parse_caip2_chain_id(&self.chain_id) parse_caip2_chain_id(&self.chain_id)
} }
@ -39,3 +39,16 @@ impl BlockchainConfig {
self.try_ethereum_chain_id().unwrap() 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)
}
}

View file

@ -243,11 +243,13 @@ pub fn parse_config() -> Config {
check_directory_owner(&config.storage_dir); check_directory_owner(&config.storage_dir);
config.try_instance_url().expect("invalid instance URI"); config.try_instance_url().expect("invalid instance URI");
if let Some(blockchain_config) = config.blockchain.as_ref() { if let Some(blockchain_config) = config.blockchain.as_ref() {
blockchain_config.try_ethereum_chain_id().unwrap(); if let Some(ethereum_config) = blockchain_config.ethereum_config() {
if !blockchain_config.contract_dir.exists() { ethereum_config.try_ethereum_chain_id().unwrap();
if !ethereum_config.contract_dir.exists() {
panic!("contract directory does not exist"); panic!("contract directory does not exist");
}; };
}; };
};
if config.ipfs_api_url.is_some() != config.ipfs_gateway_url.is_some() { if config.ipfs_api_url.is_some() != config.ipfs_gateway_url.is_some() {
panic!("both ipfs_api_url and ipfs_gateway_url must be set"); panic!("both ipfs_api_url and ipfs_gateway_url must be set");
}; };

View file

@ -2,6 +2,6 @@ mod blockchain;
mod environment; mod environment;
mod main; mod main;
pub use blockchain::BlockchainConfig; pub use blockchain::EthereumConfig;
pub use environment::Environment; pub use environment::Environment;
pub use main::{parse_config, Config, Instance}; pub use main::{parse_config, Config, Instance};

View file

@ -8,7 +8,7 @@ use web3::{
transports::Http, transports::Http,
}; };
use crate::config::BlockchainConfig; use crate::config::EthereumConfig;
use super::api::connect; use super::api::connect;
use super::errors::EthereumError; use super::errors::EthereumError;
use super::sync::{ use super::sync::{
@ -96,7 +96,7 @@ pub struct Blockchain {
} }
pub async fn get_contracts( pub async fn get_contracts(
config: &BlockchainConfig, config: &EthereumConfig,
storage_dir: &Path, storage_dir: &Path,
) -> Result<Blockchain, EthereumError> { ) -> Result<Blockchain, EthereumError> {
let web3 = connect(&config.api_url)?; let web3 = connect(&config.api_url)?;

View file

@ -11,7 +11,7 @@ use web3::{
types::{BlockNumber, FilterBuilder}, types::{BlockNumber, FilterBuilder},
}; };
use crate::config::BlockchainConfig; use crate::config::EthereumConfig;
use crate::database::{Pool, get_database_client}; use crate::database::{Pool, get_database_client};
use crate::errors::DatabaseError; use crate::errors::DatabaseError;
use crate::ipfs::utils::parse_ipfs_url; use crate::ipfs::utils::parse_ipfs_url;
@ -127,7 +127,7 @@ pub async fn process_nft_events(
} }
pub fn create_mint_signature( pub fn create_mint_signature(
blockchain_config: &BlockchainConfig, blockchain_config: &EthereumConfig,
user_address: &str, user_address: &str,
token_uri: &str, token_uri: &str,
) -> Result<SignatureData, EthereumError> { ) -> Result<SignatureData, EthereumError> {

View file

@ -15,7 +15,7 @@ use crate::activitypub::builders::{
remove_person::prepare_remove_person, remove_person::prepare_remove_person,
}; };
use crate::activitypub::identifiers::LocalActorCollection; use crate::activitypub::identifiers::LocalActorCollection;
use crate::config::{BlockchainConfig, Instance}; use crate::config::{EthereumConfig, Instance};
use crate::database::{Pool, get_database_client}; use crate::database::{Pool, get_database_client};
use crate::errors::{ConversionError, DatabaseError}; use crate::errors::{ConversionError, DatabaseError};
use crate::models::notifications::queries::{ use crate::models::notifications::queries::{
@ -245,7 +245,7 @@ pub async fn check_subscriptions(
} }
pub fn create_subscription_signature( pub fn create_subscription_signature(
blockchain_config: &BlockchainConfig, blockchain_config: &EthereumConfig,
user_address: &str, user_address: &str,
price: u64, price: u64,
) -> Result<SignatureData, EthereumError> { ) -> Result<SignatureData, EthereumError> {

View file

@ -53,11 +53,15 @@ async fn main() -> std::io::Result<()> {
); );
let maybe_blockchain = if let Some(blockchain_config) = &config.blockchain { let maybe_blockchain = if let Some(blockchain_config) = &config.blockchain {
if let Some(ethereum_config) = blockchain_config.ethereum_config() {
// Create blockchain interface // Create blockchain interface
get_contracts(blockchain_config, &config.storage_dir).await get_contracts(ethereum_config, &config.storage_dir).await
.map(Some).unwrap() .map(Some).unwrap()
} else { } else {
None None
}
} else {
None
}; };
let maybe_contract_set = maybe_blockchain.clone() let maybe_contract_set = maybe_blockchain.clone()
.map(|blockchain| blockchain.contract_set); .map(|blockchain| blockchain.contract_set);
@ -148,12 +152,14 @@ async fn main() -> std::io::Result<()> {
.service(nodeinfo::get_nodeinfo) .service(nodeinfo::get_nodeinfo)
.service(nodeinfo::get_nodeinfo_2_0); .service(nodeinfo::get_nodeinfo_2_0);
if let Some(blockchain_config) = &config.blockchain { if let Some(blockchain_config) = &config.blockchain {
if let Some(ethereum_config) = blockchain_config.ethereum_config() {
// Serve artifacts if available // Serve artifacts if available
app = app.service(actix_files::Files::new( app = app.service(actix_files::Files::new(
"/contracts", "/contracts",
&blockchain_config.contract_dir, &ethereum_config.contract_dir,
)); ));
} };
};
app app
}) })
.workers(num_workers) .workers(num_workers)

View file

@ -293,14 +293,16 @@ async fn authorize_subscription(
) -> Result<HttpResponse, HttpError> { ) -> Result<HttpResponse, HttpError> {
let db_client = &**get_database_client(&db_pool).await?; let db_client = &**get_database_client(&db_pool).await?;
let current_user = get_current_user(db_client, auth.token()).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)?; .ok_or(HttpError::NotSupported)?;
// Wallet address must be public, because subscribers should be able // Wallet address must be public, because subscribers should be able
// to verify that payments are actually sent to the recipient. // to verify that payments are actually sent to the recipient.
let wallet_address = current_user.public_wallet_address() let wallet_address = current_user.public_wallet_address()
.ok_or(HttpError::PermissionError)?; .ok_or(HttpError::PermissionError)?;
let signature = create_subscription_signature( let signature = create_subscription_signature(
blockchain_config, ethereum_config,
&wallet_address, &wallet_address,
query_params.price, query_params.price,
).map_err(|_| HttpError::InternalError)?; ).map_err(|_| HttpError::InternalError)?;

View file

@ -41,6 +41,8 @@ fn get_full_api_version(version: &str) -> String {
impl InstanceInfo { impl InstanceInfo {
pub fn create(config: &Config, maybe_blockchain: Option<&ContractSet>) -> Self { 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| { let blockchain_features = maybe_blockchain.map(|contract_set| {
BlockchainFeatures { BlockchainFeatures {
minter: contract_set.collectible.is_some(), minter: contract_set.collectible.is_some(),
@ -56,14 +58,14 @@ impl InstanceInfo {
registrations: config.registrations_open, registrations: config.registrations_open,
login_message: config.login_message.clone(), login_message: config.login_message.clone(),
post_character_limit: config.post_character_limit, post_character_limit: config.post_character_limit,
blockchain_id: config.blockchain.as_ref() blockchain_id: ethereum_config
.map(|val| val.chain_id.to_string()), .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()), .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()), .map(|val| val.contract_address.clone()),
blockchain_features: blockchain_features, blockchain_features: blockchain_features,
blockchain_info: config.blockchain.as_ref() blockchain_info: ethereum_config
.and_then(|val| val.chain_info.clone()), .and_then(|val| val.chain_info.clone()),
ipfs_gateway_url: config.ipfs_gateway_url.clone(), ipfs_gateway_url: config.ipfs_gateway_url.clone(),
} }

View file

@ -425,7 +425,9 @@ async fn get_signature(
) -> Result<HttpResponse, HttpError> { ) -> Result<HttpResponse, HttpError> {
let db_client = &**get_database_client(&db_pool).await?; let db_client = &**get_database_client(&db_pool).await?;
let current_user = get_current_user(db_client, auth.token()).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)?; .ok_or(HttpError::NotSupported)?;
// Wallet address must be public because minting exposes it // Wallet address must be public because minting exposes it
let wallet_address = current_user.public_wallet_address() let wallet_address = current_user.public_wallet_address()
@ -440,7 +442,7 @@ async fn get_signature(
.ok_or(HttpError::PermissionError)?; .ok_or(HttpError::PermissionError)?;
let token_uri = get_ipfs_url(&ipfs_cid); let token_uri = get_ipfs_url(&ipfs_cid);
let signature = create_mint_signature( let signature = create_mint_signature(
blockchain_config, ethereum_config,
&wallet_address, &wallet_address,
&token_uri, &token_uri,
).map_err(|_| HttpError::InternalError)?; ).map_err(|_| HttpError::InternalError)?;