use odra::casper_types::{CLValueError, RuntimeArgs};
use odra::consts;
use odra::schema::casper_contract_schema::Entrypoint;
pub(crate) const NEW_CONTRACT: &str = "new_contract";
pub(crate) const UPGRADE_CHILD_CONTRACT: &str = "upgrade_child_contract";
pub(crate) const BATCH_UPGRADE_CHILD_CONTRACT: &str = "batch_upgrade_child_contract";
pub(crate) const CONTRACT_NAME_ARG: &str = "contract_name";
pub(crate) fn is_factory(entry_points: &[Entrypoint]) -> bool {
entry_points
.iter()
.any(|entry_point| entry_point.name == BATCH_UPGRADE_CHILD_CONTRACT)
}
pub(crate) fn insert_cfg_args(
entry_point: &str,
args: &mut RuntimeArgs
) -> Result<(), CLValueError> {
match entry_point {
NEW_CONTRACT => {
let contract_name = args
.get(CONTRACT_NAME_ARG)
.map(|name| name.clone().into_t::<String>())
.transpose()?
.unwrap_or_default();
args.insert(consts::IS_UPGRADABLE_ARG, true)?;
args.insert(consts::IS_UPGRADE_ARG, false)?;
args.insert(consts::ALLOW_KEY_OVERRIDE_ARG, true)?;
args.insert(consts::PACKAGE_HASH_KEY_NAME_ARG, contract_name)?;
}
UPGRADE_CHILD_CONTRACT | BATCH_UPGRADE_CHILD_CONTRACT => {
args.insert(consts::IS_FACTORY_UPGRADE_ARG, true)?;
args.insert(consts::ALLOW_KEY_OVERRIDE_ARG, true)?;
args.insert(consts::CREATE_UPGRADE_GROUP, false)?;
}
_ => {}
}
Ok(())
}
#[cfg(test)]
mod tests {
use odra::casper_types::{runtime_args, CLValue};
use super::*;
fn arg<T: odra::casper_types::CLTyped + odra::casper_types::bytesrepr::ToBytes>(
value: T
) -> Option<CLValue> {
Some(CLValue::from_t(value).unwrap())
}
#[test]
fn new_contract_stores_the_child_under_its_name() {
let mut args = runtime_args! { "contract_name" => "FromTen".to_string(), "value" => 10u32 };
insert_cfg_args(NEW_CONTRACT, &mut args).unwrap();
assert_eq!(args.get("odra_cfg_is_upgradable").cloned(), arg(true));
assert_eq!(args.get("odra_cfg_is_upgrade").cloned(), arg(false));
assert_eq!(args.get("odra_cfg_allow_key_override").cloned(), arg(true));
assert_eq!(
args.get("odra_cfg_package_hash_key_name").cloned(),
arg("FromTen".to_string())
);
assert_eq!(args.get("value").cloned(), arg(10u32));
}
#[test]
fn child_upgrades_are_factory_upgrades() {
for entry_point in [UPGRADE_CHILD_CONTRACT, BATCH_UPGRADE_CHILD_CONTRACT] {
let mut args = RuntimeArgs::new();
insert_cfg_args(entry_point, &mut args).unwrap();
assert_eq!(args.get("odra_cfg_is_factory_upgrade").cloned(), arg(true));
assert_eq!(args.get("odra_cfg_allow_key_override").cloned(), arg(true));
assert_eq!(
args.get("odra_cfg_create_upgrade_group").cloned(),
arg(false)
);
assert_eq!(args.len(), 3);
}
}
#[test]
fn other_entry_points_are_left_as_they_are() {
let mut args = runtime_args! { "value" => 10u32 };
insert_cfg_args("increment", &mut args).unwrap();
assert_eq!(args.len(), 1);
}
}