Replace Config::blockchain() with chain-specific methods in preparation for multi-chain deployments
This commit is contained in:
parent
0906fd8ae3
commit
bd371189a0
9 changed files with 56 additions and 77 deletions
|
@ -567,8 +567,7 @@ impl CreateMoneroWallet {
|
||||||
&self,
|
&self,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let monero_config = config.blockchain()
|
let monero_config = config.monero_config()
|
||||||
.and_then(|conf| conf.monero_config())
|
|
||||||
.ok_or(anyhow!("monero configuration not found"))?;
|
.ok_or(anyhow!("monero configuration not found"))?;
|
||||||
create_monero_wallet(
|
create_monero_wallet(
|
||||||
monero_config,
|
monero_config,
|
||||||
|
@ -592,8 +591,7 @@ impl CheckExpiredInvoice {
|
||||||
config: &Config,
|
config: &Config,
|
||||||
db_client: &impl DatabaseClient,
|
db_client: &impl DatabaseClient,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let monero_config = config.blockchain()
|
let monero_config = config.monero_config()
|
||||||
.and_then(|conf| conf.monero_config())
|
|
||||||
.ok_or(anyhow!("monero configuration not found"))?;
|
.ok_or(anyhow!("monero configuration not found"))?;
|
||||||
check_expired_invoice(
|
check_expired_invoice(
|
||||||
monero_config,
|
monero_config,
|
||||||
|
|
|
@ -71,21 +71,3 @@ pub enum BlockchainConfig {
|
||||||
Ethereum(EthereumConfig),
|
Ethereum(EthereumConfig),
|
||||||
Monero(MoneroConfig),
|
Monero(MoneroConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockchainConfig {
|
|
||||||
pub fn ethereum_config(&self) -> Option<&EthereumConfig> {
|
|
||||||
if let Self::Ethereum(ethereum_config) = self {
|
|
||||||
Some(ethereum_config)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn monero_config(&self) -> Option<&MoneroConfig> {
|
|
||||||
if let Self::Monero(monero_config) = self {
|
|
||||||
Some(monero_config)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,7 +7,11 @@ use url::Url;
|
||||||
|
|
||||||
use mitra_utils::urls::normalize_url;
|
use mitra_utils::urls::normalize_url;
|
||||||
|
|
||||||
use super::blockchain::BlockchainConfig;
|
use super::blockchain::{
|
||||||
|
BlockchainConfig,
|
||||||
|
EthereumConfig,
|
||||||
|
MoneroConfig,
|
||||||
|
};
|
||||||
use super::environment::Environment;
|
use super::environment::Environment;
|
||||||
use super::federation::FederationConfig;
|
use super::federation::FederationConfig;
|
||||||
use super::limits::Limits;
|
use super::limits::Limits;
|
||||||
|
@ -117,16 +121,31 @@ impl Config {
|
||||||
self.storage_dir.join("media")
|
self.storage_dir.join("media")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn blockchain(&self) -> Option<&BlockchainConfig> {
|
pub fn blockchains(&self) -> &[BlockchainConfig] {
|
||||||
if let Some(ref _blockchain_config) = self._blockchain {
|
if let Some(ref _blockchain_config) = self._blockchain {
|
||||||
panic!("'blockchain' setting is not supported anymore, use 'blockchains' instead");
|
panic!("'blockchain' setting is not supported anymore, use 'blockchains' instead");
|
||||||
} else {
|
} else {
|
||||||
match &self.blockchains[..] {
|
if self.blockchains.len() > 1 {
|
||||||
[blockchain_config] => Some(blockchain_config),
|
panic!("multichain deployments are not supported");
|
||||||
[] => None,
|
};
|
||||||
_ => panic!("multichain deployments are not supported"),
|
&self.blockchains
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ethereum_config(&self) -> Option<&EthereumConfig> {
|
||||||
|
self.blockchains().iter()
|
||||||
|
.find_map(|item| match item {
|
||||||
|
BlockchainConfig::Ethereum(config) => Some(config),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn monero_config(&self) -> Option<&MoneroConfig> {
|
||||||
|
self.blockchains().iter()
|
||||||
|
.find_map(|item| match item {
|
||||||
|
BlockchainConfig::Monero(config) => Some(config),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,14 +102,12 @@ pub fn parse_config() -> (Config, Vec<&'static str>) {
|
||||||
};
|
};
|
||||||
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() {
|
if let Some(ethereum_config) = config.ethereum_config() {
|
||||||
if let Some(ethereum_config) = blockchain_config.ethereum_config() {
|
|
||||||
ethereum_config.try_ethereum_chain_id().unwrap();
|
ethereum_config.try_ethereum_chain_id().unwrap();
|
||||||
if !ethereum_config.contract_dir.exists() {
|
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");
|
||||||
};
|
};
|
||||||
|
|
|
@ -93,9 +93,7 @@ pub async fn monero_payment_monitor(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
db_pool: &DbPool,
|
db_pool: &DbPool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let maybe_monero_config = config.blockchain()
|
let monero_config = match config.monero_config() {
|
||||||
.and_then(|conf| conf.monero_config());
|
|
||||||
let monero_config = match maybe_monero_config {
|
|
||||||
Some(monero_config) => monero_config,
|
Some(monero_config) => monero_config,
|
||||||
None => return Ok(()), // not configured
|
None => return Ok(()), // not configured
|
||||||
};
|
};
|
||||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -61,16 +61,12 @@ async fn main() -> std::io::Result<()> {
|
||||||
.expect("failed to create media directory");
|
.expect("failed to create media directory");
|
||||||
};
|
};
|
||||||
|
|
||||||
let maybe_ethereum_blockchain = if let Some(blockchain_config) = config.blockchain() {
|
let maybe_ethereum_blockchain = if let Some(ethereum_config) = config.ethereum_config() {
|
||||||
if let Some(ethereum_config) = blockchain_config.ethereum_config() {
|
|
||||||
// Create blockchain interface
|
// Create blockchain interface
|
||||||
get_contracts(&**db_client, ethereum_config, &config.storage_dir).await
|
get_contracts(&**db_client, ethereum_config, &config.storage_dir).await
|
||||||
.map(Some).unwrap()
|
.map(Some).unwrap()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
};
|
||||||
let maybe_ethereum_contracts = maybe_ethereum_blockchain.clone()
|
let maybe_ethereum_contracts = maybe_ethereum_blockchain.clone()
|
||||||
.map(|blockchain| blockchain.contract_set);
|
.map(|blockchain| blockchain.contract_set);
|
||||||
|
@ -188,15 +184,13 @@ async fn main() -> std::io::Result<()> {
|
||||||
web::resource("/.well-known/{path}")
|
web::resource("/.well-known/{path}")
|
||||||
.to(HttpResponse::NotFound)
|
.to(HttpResponse::NotFound)
|
||||||
);
|
);
|
||||||
if let Some(blockchain_config) = config.blockchain() {
|
if let Some(ethereum_config) = config.ethereum_config() {
|
||||||
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",
|
||||||
ðereum_config.contract_dir,
|
ðereum_config.contract_dir,
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
};
|
|
||||||
if let Some(ref web_client_dir) = config.web_client_dir {
|
if let Some(ref web_client_dir) = config.web_client_dir {
|
||||||
app = app.service(web_client::static_service(web_client_dir));
|
app = app.service(web_client::static_service(web_client_dir));
|
||||||
};
|
};
|
||||||
|
|
|
@ -91,9 +91,8 @@ impl InstanceInfo {
|
||||||
post_count: i64,
|
post_count: i64,
|
||||||
peer_count: i64,
|
peer_count: i64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut blockchains = vec![];
|
let blockchains = config.blockchains().iter().map(|item| match item {
|
||||||
match config.blockchain() {
|
BlockchainConfig::Ethereum(ethereum_config) => {
|
||||||
Some(BlockchainConfig::Ethereum(ethereum_config)) => {
|
|
||||||
let features = if let Some(contract_set) = maybe_ethereum_contracts {
|
let features = if let Some(contract_set) = maybe_ethereum_contracts {
|
||||||
BlockchainFeatures {
|
BlockchainFeatures {
|
||||||
gate: contract_set.gate.is_some(),
|
gate: contract_set.gate.is_some(),
|
||||||
|
@ -110,29 +109,28 @@ impl InstanceInfo {
|
||||||
let maybe_chain_metadata = ethereum_config
|
let maybe_chain_metadata = ethereum_config
|
||||||
.chain_metadata.as_ref()
|
.chain_metadata.as_ref()
|
||||||
.and_then(|metadata| to_value(metadata).ok());
|
.and_then(|metadata| to_value(metadata).ok());
|
||||||
blockchains.push(BlockchainInfo {
|
BlockchainInfo {
|
||||||
chain_id: ethereum_config.chain_id.to_string(),
|
chain_id: ethereum_config.chain_id.to_string(),
|
||||||
chain_metadata: maybe_chain_metadata,
|
chain_metadata: maybe_chain_metadata,
|
||||||
contract_address:
|
contract_address:
|
||||||
Some(ethereum_config.contract_address.clone()),
|
Some(ethereum_config.contract_address.clone()),
|
||||||
features: features,
|
features: features,
|
||||||
});
|
}
|
||||||
},
|
},
|
||||||
Some(BlockchainConfig::Monero(monero_config)) => {
|
BlockchainConfig::Monero(monero_config) => {
|
||||||
let features = BlockchainFeatures {
|
let features = BlockchainFeatures {
|
||||||
gate: false,
|
gate: false,
|
||||||
minter: false,
|
minter: false,
|
||||||
subscriptions: true,
|
subscriptions: true,
|
||||||
};
|
};
|
||||||
blockchains.push(BlockchainInfo {
|
BlockchainInfo {
|
||||||
chain_id: monero_config.chain_id.to_string(),
|
chain_id: monero_config.chain_id.to_string(),
|
||||||
chain_metadata: None,
|
chain_metadata: None,
|
||||||
contract_address: None,
|
contract_address: None,
|
||||||
features: features,
|
features: features,
|
||||||
})
|
}
|
||||||
},
|
},
|
||||||
None => (),
|
}).collect();
|
||||||
};
|
|
||||||
Self {
|
Self {
|
||||||
uri: config.instance().hostname(),
|
uri: config.instance().hostname(),
|
||||||
title: config.instance_title.clone(),
|
title: config.instance_title.clone(),
|
||||||
|
|
|
@ -625,9 +625,7 @@ async fn get_signature(
|
||||||
) -> Result<HttpResponse, MastodonError> {
|
) -> Result<HttpResponse, MastodonError> {
|
||||||
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 ethereum_config = config.blockchain()
|
let ethereum_config = config.ethereum_config()
|
||||||
.ok_or(MastodonError::NotSupported)?
|
|
||||||
.ethereum_config()
|
|
||||||
.ok_or(MastodonError::NotSupported)?;
|
.ok_or(MastodonError::NotSupported)?;
|
||||||
// User must have a public ethereum address
|
// User must have a public ethereum address
|
||||||
let wallet_address = current_user
|
let wallet_address = current_user
|
||||||
|
|
|
@ -66,9 +66,7 @@ pub async fn authorize_subscription(
|
||||||
) -> Result<HttpResponse, MastodonError> {
|
) -> Result<HttpResponse, MastodonError> {
|
||||||
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 ethereum_config = config.blockchain()
|
let ethereum_config = config.ethereum_config()
|
||||||
.ok_or(MastodonError::NotSupported)?
|
|
||||||
.ethereum_config()
|
|
||||||
.ok_or(MastodonError::NotSupported)?;
|
.ok_or(MastodonError::NotSupported)?;
|
||||||
// The user must have a public ethereum address,
|
// The user must have a public ethereum address,
|
||||||
// because subscribers should be able
|
// because subscribers should be able
|
||||||
|
@ -115,8 +113,7 @@ pub async fn register_subscription_option(
|
||||||
|
|
||||||
let maybe_payment_option = match subscription_option.into_inner() {
|
let maybe_payment_option = match subscription_option.into_inner() {
|
||||||
SubscriptionOption::Ethereum => {
|
SubscriptionOption::Ethereum => {
|
||||||
let ethereum_config = config.blockchain()
|
let ethereum_config = config.ethereum_config()
|
||||||
.and_then(|conf| conf.ethereum_config())
|
|
||||||
.ok_or(MastodonError::NotSupported)?;
|
.ok_or(MastodonError::NotSupported)?;
|
||||||
let contract_set = maybe_ethereum_contracts.as_ref().as_ref()
|
let contract_set = maybe_ethereum_contracts.as_ref().as_ref()
|
||||||
.ok_or(MastodonError::NotSupported)?;
|
.ok_or(MastodonError::NotSupported)?;
|
||||||
|
@ -142,8 +139,7 @@ pub async fn register_subscription_option(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SubscriptionOption::Monero { price, payout_address } => {
|
SubscriptionOption::Monero { price, payout_address } => {
|
||||||
let monero_config = config.blockchain()
|
let monero_config = config.monero_config()
|
||||||
.and_then(|conf| conf.monero_config())
|
|
||||||
.ok_or(MastodonError::NotSupported)?;
|
.ok_or(MastodonError::NotSupported)?;
|
||||||
if price == 0 {
|
if price == 0 {
|
||||||
return Err(ValidationError("price must be greater than 0").into());
|
return Err(ValidationError("price must be greater than 0").into());
|
||||||
|
@ -207,9 +203,7 @@ async fn create_invoice_view(
|
||||||
db_pool: web::Data<DbPool>,
|
db_pool: web::Data<DbPool>,
|
||||||
invoice_data: web::Json<InvoiceData>,
|
invoice_data: web::Json<InvoiceData>,
|
||||||
) -> Result<HttpResponse, MastodonError> {
|
) -> Result<HttpResponse, MastodonError> {
|
||||||
let monero_config = config.blockchain()
|
let monero_config = config.monero_config()
|
||||||
.ok_or(MastodonError::NotSupported)?
|
|
||||||
.monero_config()
|
|
||||||
.ok_or(MastodonError::NotSupported)?;
|
.ok_or(MastodonError::NotSupported)?;
|
||||||
if invoice_data.sender_id == invoice_data.recipient_id {
|
if invoice_data.sender_id == invoice_data.recipient_id {
|
||||||
return Err(ValidationError("sender must be different from recipient").into());
|
return Err(ValidationError("sender must be different from recipient").into());
|
||||||
|
|
Loading…
Reference in a new issue