Skip to content

Commit

Permalink
feat(ampd): ensure unique handler config macro (axelarnetwork#623)
Browse files Browse the repository at this point in the history
  • Loading branch information
haiyizxx authored Sep 13, 2024
1 parent 573501d commit 8f410b2
Showing 1 changed file with 166 additions and 117 deletions.
283 changes: 166 additions & 117 deletions ampd/src/handlers/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,6 @@ pub enum Config {
},
}

fn validate_multisig_signer_config<'de, D>(configs: &[Config]) -> Result<(), D::Error>
where
D: Deserializer<'de>,
{
match configs
.iter()
.filter(|config| matches!(config, Config::MultisigSigner { .. }))
.count()
{
count if count > 1 => Err(de::Error::custom(
"only one multisig signer config is allowed",
)),
_ => Ok(()),
}
}
fn validate_evm_verifier_set_verifier_configs<'de, D>(configs: &[Config]) -> Result<(), D::Error>
where
D: Deserializer<'de>,
Expand Down Expand Up @@ -126,100 +111,20 @@ where
Ok(())
}

fn validate_sui_msg_verifier_config<'de, D>(configs: &[Config]) -> Result<(), D::Error>
where
D: Deserializer<'de>,
{
match configs
.iter()
.filter(|config| matches!(config, Config::SuiMsgVerifier { .. }))
.count()
{
count if count > 1 => Err(de::Error::custom(
"only one Sui msg verifier config is allowed",
)),
_ => Ok(()),
}
}

fn validate_sui_verifier_set_verifier_config<'de, D>(configs: &[Config]) -> Result<(), D::Error>
where
D: Deserializer<'de>,
{
match configs
.iter()
.filter(|config| matches!(config, Config::SuiVerifierSetVerifier { .. }))
.count()
{
count if count > 1 => Err(de::Error::custom(
"only one Sui verifier set verifier config is allowed",
)),
_ => Ok(()),
}
}

fn validate_mvx_msg_verifier_config<'de, D>(configs: &[Config]) -> Result<(), D::Error>
where
D: Deserializer<'de>,
{
match configs
.iter()
.filter(|config| matches!(config, Config::MvxMsgVerifier { .. }))
.count()
{
count if count > 1 => Err(de::Error::custom(
"only one Mvx msg verifier config is allowed",
)),
_ => Ok(()),
}
}

fn validate_mvx_worker_set_verifier_config<'de, D>(configs: &[Config]) -> Result<(), D::Error>
where
D: Deserializer<'de>,
{
match configs
.iter()
.filter(|config| matches!(config, Config::MvxVerifierSetVerifier { .. }))
.count()
{
count if count > 1 => Err(de::Error::custom(
"only one Mvx worker set verifier config is allowed",
)),
_ => Ok(()),
}
}

fn validate_stellar_msg_verifier_config<'de, D>(configs: &[Config]) -> Result<(), D::Error>
where
D: Deserializer<'de>,
{
match configs
.iter()
.filter(|config| matches!(config, Config::StellarMsgVerifier { .. }))
.count()
{
count if count > 1 => Err(de::Error::custom(
"only one Stellar msg verifier config is allowed",
)),
_ => Ok(()),
}
}

fn validate_stellar_verifier_set_verifier_config<'de, D>(configs: &[Config]) -> Result<(), D::Error>
where
D: Deserializer<'de>,
{
match configs
.iter()
.filter(|config| matches!(config, Config::StellarMsgVerifier { .. }))
.count()
{
count if count > 1 => Err(de::Error::custom(
"only one Stellar verifier set verifier config is allowed",
)),
_ => Ok(()),
}
macro_rules! ensure_unique_config {
($configs:expr, $config_type:path, $config_name:expr) => {
match $configs
.iter()
.filter(|config| matches!(config, $config_type { .. }))
.count()
{
count if count > 1 => Err(de::Error::custom(format!(
"only one {} config is allowed",
$config_name
))),
_ => Ok(()),
}
};
}

pub fn deserialize_handler_configs<'de, D>(deserializer: D) -> Result<Vec<Config>, D::Error>
Expand All @@ -230,22 +135,42 @@ where

validate_evm_msg_verifier_configs::<D>(&configs)?;
validate_evm_verifier_set_verifier_configs::<D>(&configs)?;
validate_multisig_signer_config::<D>(&configs)?;
validate_sui_msg_verifier_config::<D>(&configs)?;
validate_sui_verifier_set_verifier_config::<D>(&configs)?;
validate_mvx_msg_verifier_config::<D>(&configs)?;
validate_mvx_worker_set_verifier_config::<D>(&configs)?;
validate_stellar_msg_verifier_config::<D>(&configs)?;
validate_stellar_verifier_set_verifier_config::<D>(&configs)?;

ensure_unique_config!(&configs, Config::MultisigSigner, "Multisig signer")?;
ensure_unique_config!(&configs, Config::SuiMsgVerifier, "Sui message verifier")?;
ensure_unique_config!(
&configs,
Config::SuiVerifierSetVerifier,
"Sui verifier set verifier"
)?;
ensure_unique_config!(&configs, Config::MvxMsgVerifier, "Mvx message verifier")?;
ensure_unique_config!(
&configs,
Config::MvxVerifierSetVerifier,
"Mvx verifier set verifier"
)?;
ensure_unique_config!(
&configs,
Config::StellarMsgVerifier,
"Stellar message verifier"
)?;
ensure_unique_config!(
&configs,
Config::StellarVerifierSetVerifier,
"Stellar verifier set verifier"
)?;

Ok(configs)
}

#[cfg(test)]
mod tests {
use serde_json::to_value;

use crate::evm::finalizer::Finalization;
use crate::handlers::config::Chain;
use crate::handlers::config::{deserialize_handler_configs, Chain, Config};
use crate::types::TMAddress;
use crate::PREFIX;

#[test]
fn finalizer_should_default_to_ethereum() {
Expand All @@ -257,4 +182,128 @@ mod tests {
let chain_config: Chain = toml::from_str(chain_config_toml).unwrap();
assert_eq!(chain_config.finalization, Finalization::RPCFinalizedBlock);
}

#[test]
fn unique_config_validation() {
let configs = vec![
Config::MultisigSigner {
cosmwasm_contract: TMAddress::random(PREFIX),
},
Config::MultisigSigner {
cosmwasm_contract: TMAddress::random(PREFIX),
},
];

assert!(
matches!(deserialize_handler_configs(to_value(configs).unwrap()),
Err(e) if e.to_string().contains("only one Multisig signer config is allowed")
)
);

let configs = vec![
Config::SuiMsgVerifier {
cosmwasm_contract: TMAddress::random(PREFIX),
rpc_url: "http://localhost:7545/".parse().unwrap(),
rpc_timeout: None,
},
Config::SuiMsgVerifier {
cosmwasm_contract: TMAddress::random(PREFIX),
rpc_url: "http://localhost:7545/".parse().unwrap(),
rpc_timeout: None,
},
];

assert!(
matches!(deserialize_handler_configs(to_value(configs).unwrap()),
Err(e) if e.to_string().contains("only one Sui message verifier config is allowed")
)
);

let configs = vec![
Config::SuiVerifierSetVerifier {
cosmwasm_contract: TMAddress::random(PREFIX),
rpc_url: "http://localhost:7545/".parse().unwrap(),
rpc_timeout: None,
},
Config::SuiVerifierSetVerifier {
cosmwasm_contract: TMAddress::random(PREFIX),
rpc_url: "http://localhost:7545/".parse().unwrap(),
rpc_timeout: None,
},
];

assert!(
matches!(deserialize_handler_configs(to_value(configs).unwrap()),
Err(e) if e.to_string().contains("only one Sui verifier set verifier config is allowed")
)
);

let configs = vec![
Config::MvxMsgVerifier {
cosmwasm_contract: TMAddress::random(PREFIX),
proxy_url: "http://localhost:7545/".parse().unwrap(),
},
Config::MvxMsgVerifier {
cosmwasm_contract: TMAddress::random(PREFIX),
proxy_url: "http://localhost:7545/".parse().unwrap(),
},
];

assert!(
matches!(deserialize_handler_configs(to_value(configs).unwrap()),
Err(e) if e.to_string().contains("only one Mvx message verifier config is allowed")
)
);

let configs = vec![
Config::MvxVerifierSetVerifier {
cosmwasm_contract: TMAddress::random(PREFIX),
proxy_url: "http://localhost:7545/".parse().unwrap(),
},
Config::MvxVerifierSetVerifier {
cosmwasm_contract: TMAddress::random(PREFIX),
proxy_url: "http://localhost:7545/".parse().unwrap(),
},
];

assert!(
matches!(deserialize_handler_configs(to_value(configs).unwrap()),
Err(e) if e.to_string().contains("only one Mvx verifier set verifier config is allowed")
)
);

let configs = vec![
Config::StellarMsgVerifier {
cosmwasm_contract: TMAddress::random(PREFIX),
http_url: "http://localhost:8080/".parse().unwrap(),
},
Config::StellarMsgVerifier {
cosmwasm_contract: TMAddress::random(PREFIX),
http_url: "http://localhost:8080/".parse().unwrap(),
},
];

assert!(
matches!(deserialize_handler_configs(to_value(configs).unwrap()),
Err(e) if e.to_string().contains("only one Stellar message verifier config is allowed")
)
);

let configs = vec![
Config::StellarVerifierSetVerifier {
cosmwasm_contract: TMAddress::random(PREFIX),
http_url: "http://localhost:8080/".parse().unwrap(),
},
Config::StellarVerifierSetVerifier {
cosmwasm_contract: TMAddress::random(PREFIX),
http_url: "http://localhost:8080/".parse().unwrap(),
},
];

assert!(
matches!(deserialize_handler_configs(to_value(configs).unwrap()),
Err(e) if e.to_string().contains("only one Stellar verifier set verifier config is allowed")
)
);
}
}

0 comments on commit 8f410b2

Please sign in to comment.