Skip to content

Commit

Permalink
feat: Move run init-goveranance just after choosing the genesis-utxo,…
Browse files Browse the repository at this point in the history
… before getting MC addresses
  • Loading branch information
LGLO committed Dec 20, 2024
1 parent 41601bc commit dc8b61e
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 107 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use crate::{
cardano_key,
config::{config_fields, ServiceConfig},
IOContext,
};
use ogmios_client::types::OgmiosTx;
use partner_chains_cardano_offchain::init_governance::InitGovernance;
use sidechain_domain::{MainchainAddressHash, MainchainPrivateKey, UtxoId};

pub(crate) fn run_init_governance<C: IOContext>(
genesis_utxo: UtxoId,
ogmios_config: &ServiceConfig,
context: &C,
) -> anyhow::Result<OgmiosTx> {
let offchain = context.offchain_impl(ogmios_config)?;
let (payment_key, governance_authority) = get_private_key_and_key_hash(context)?;
let runtime = tokio::runtime::Runtime::new().map_err(|e| anyhow::anyhow!(e))?;
runtime
.block_on(offchain.init_governance(governance_authority, payment_key, genesis_utxo))
.map_err(|e| anyhow::anyhow!("Governance initalization failed: {e:?}!"))
}

fn get_private_key_and_key_hash<C: IOContext>(
context: &C,
) -> Result<(MainchainPrivateKey, MainchainAddressHash), anyhow::Error> {
let cardano_signig_key_file = config_fields::CARDANO_PAYMENT_SIGNING_KEY_FILE
.prompt_with_default_from_file_and_save(context);
let pkey = cardano_key::get_mc_pkey_from_file(&cardano_signig_key_file, context)?;
let addr_hash = pkey.to_pub_key_hash();

Ok((pkey, addr_hash))
}

#[cfg(test)]
mod tests {
use super::run_init_governance;
use crate::{
config::{
config_fields::{CARDANO_PAYMENT_SIGNING_KEY_FILE, GENESIS_UTXO, OGMIOS_PROTOCOL},
NetworkProtocol, ServiceConfig,
},
tests::{MockIO, MockIOContext, OffchainMock, OffchainMocks},
};
use hex_literal::hex;
use ogmios_client::types::OgmiosTx;
use serde_json::{json, Value};
use sidechain_domain::{MainchainAddressHash, MainchainPrivateKey, UtxoId};

#[test]
fn happy_path() {
let mock_context = MockIOContext::new()
.with_json_file(GENESIS_UTXO.config_file, serde_json::json!({}))
.with_json_file(OGMIOS_PROTOCOL.config_file, serde_json::json!({}))
.with_json_file("payment.skey", payment_key_content())
.with_offchain_mocks(preprod_offchain_mocks())
.with_expected_io(vec![
MockIO::file_read(CARDANO_PAYMENT_SIGNING_KEY_FILE.config_file),
MockIO::prompt(
"path to the payment signing key file",
Some("payment.skey"),
"payment.skey",
),
MockIO::file_read(CARDANO_PAYMENT_SIGNING_KEY_FILE.config_file),
MockIO::file_write_json(
CARDANO_PAYMENT_SIGNING_KEY_FILE.config_file,
test_resources_config(),
),
MockIO::file_read("payment.skey"),
]);
run_init_governance(TEST_GENESIS_UTXO, &ogmios_config(), &mock_context)
.expect("should succeed");
}

fn payment_key_content() -> serde_json::Value {
json!({
"type": "PaymentSigningKeyShelley_ed25519",
"description": "Payment Signing Key",
"cborHex": "5820d0a6c5c921266d15dc8d1ce1e51a01e929a686ed3ec1a9be1145727c224bf386"
})
}
const TEST_GENESIS_UTXO: UtxoId = UtxoId::new([0u8; 32], 0);

fn ogmios_config() -> ServiceConfig {
ServiceConfig {
hostname: "localhost".to_string(),
port: 1337,
protocol: NetworkProtocol::Http,
}
}

fn test_resources_config() -> Value {
serde_json::json!({
"cardano_payment_signing_key_file": "payment.skey",
})
}

fn preprod_offchain_mocks() -> OffchainMocks {
let mock = OffchainMock::new().with_init_governance(
TEST_GENESIS_UTXO,
MainchainAddressHash(hex!("e8c300330fe315531ca89d4a2e7d0c80211bc70b473b1ed4979dff2b")),
MainchainPrivateKey(hex!(
"d0a6c5c921266d15dc8d1ce1e51a01e929a686ed3ec1a9be1145727c224bf386"
)),
Ok(OgmiosTx {
id: hex!("0000000000000000000000000000000000000000000000000000000000000000"),
}),
);
OffchainMocks::new_with_mock("http://localhost:1337", mock)
}
}
17 changes: 9 additions & 8 deletions toolkit/partner-chains-cli/src/prepare_configuration/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
mod init_governance;
mod prepare_cardano_params;
mod prepare_chain_params;
mod prepare_main_chain_config;

use crate::config::config_fields;
use crate::config::config_fields::BOOTNODES;
use crate::config::config_fields::{BOOTNODES, SUBSTRATE_NODE_DATA_BASE_PATH};
use crate::config::config_values::DEFAULT_CHAIN_NAME;
use crate::generate_keys::network_key_path;
use crate::io::IOContext;
use crate::prepare_configuration::prepare_chain_params::prepare_chain_params;
use crate::prepare_configuration::prepare_chain_params::prepare_genesis_utxo;
use crate::prepare_configuration::prepare_main_chain_config::prepare_main_chain_config;
use crate::prepare_configuration::PrepareConfigurationError::NetworkKeyNotFoundError;
use crate::CmdRun;
Expand All @@ -24,8 +24,9 @@ pub struct PrepareConfigurationCmd {}
impl CmdRun for PrepareConfigurationCmd {
fn run<C: IOContext>(&self, context: &C) -> anyhow::Result<()> {
establish_bootnodes(context)?;
let (chain_params, ogmios_config) = prepare_chain_params(context)?;
prepare_main_chain_config(context, &ogmios_config, chain_params)?;
let (genesis_utxo, ogmios_config) = prepare_genesis_utxo(context)?;
let _ = init_governance::run_init_governance(genesis_utxo, &ogmios_config, context)?;
prepare_main_chain_config(context, &ogmios_config, genesis_utxo)?;
context.eprint("🚀 All done!");
Ok(())
}
Expand Down Expand Up @@ -102,8 +103,8 @@ fn deconstruct_bootnode(bootnode_opt: Option<String>) -> Option<(Protocol, Strin
fn peer_id_from_config(context: &impl IOContext) -> anyhow::Result<String> {
let chain_name: String = DEFAULT_CHAIN_NAME.into();

let substrate_node_base_path = config_fields::SUBSTRATE_NODE_DATA_BASE_PATH
.prompt_with_default_from_file_and_save(context);
let substrate_node_base_path =
SUBSTRATE_NODE_DATA_BASE_PATH.prompt_with_default_from_file_and_save(context);

let network_key_path = network_key_path(&substrate_node_base_path, &chain_name);

Expand Down Expand Up @@ -188,7 +189,7 @@ fn peer_id_from_network_key(key_str: &str) -> anyhow::Result<String> {
#[cfg(test)]
pub mod tests {
use super::*;
use crate::config::config_fields::SUBSTRATE_NODE_DATA_BASE_PATH;
use crate::config::config_fields::{BOOTNODES, SUBSTRATE_NODE_DATA_BASE_PATH};
use crate::config::{ConfigFieldDefinition, SelectOptions, RESOURCES_CONFIG_FILE_PATH};
use crate::prepare_configuration::PrepareConfigurationError::NetworkKeyNotFoundError;
use crate::prepare_configuration::Protocol::{Dns, Ipv4};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use partner_chains_cardano_offchain::csl::NetworkTypeExt;
use serde::de::DeserializeOwned;
use sidechain_domain::{NetworkType, UtxoId};

pub fn prepare_chain_params<C: IOContext>(context: &C) -> anyhow::Result<(UtxoId, ServiceConfig)> {
pub fn prepare_genesis_utxo<C: IOContext>(context: &C) -> anyhow::Result<(UtxoId, ServiceConfig)> {
context.eprint(INTRO);
let ogmios_configuration = prompt_ogmios_configuration(context)?;
let shelley_config = get_shelley_config(&ogmios_configuration.to_string(), context)?;
Expand All @@ -25,8 +25,6 @@ pub fn prepare_chain_params<C: IOContext>(context: &C) -> anyhow::Result<(UtxoId
let genesis_utxo =
select_from_utxos(context, "Select an UTXO to use as the genesis UTXO", utxo_query_result)?;

context.print(CAUTION);

save_if_missing(GENESIS_UTXO, genesis_utxo, context);
Ok((genesis_utxo, ogmios_configuration))
}
Expand Down Expand Up @@ -55,8 +53,6 @@ fn derive_address<C: IOContext>(
}

const INTRO: &str = "Now, let's set up the genesis utxo. It identifies a partner chain. This wizard will query Ogmios for your UTXOs using address derived from the payment verification key. Please provide required data.";
const CAUTION: &str =
"Please do not spend this UTXO, it needs to be consumed by the governance initialization.\n";

#[cfg(test)]
mod tests {
Expand All @@ -67,9 +63,7 @@ mod tests {
};
use crate::ogmios::test_values::preview_shelley_config;
use crate::ogmios::{OgmiosRequest, OgmiosResponse};
use crate::prepare_configuration::prepare_chain_params::{
prepare_chain_params, CAUTION, INTRO,
};
use crate::prepare_configuration::prepare_chain_params::{prepare_genesis_utxo, INTRO};
use crate::select_utxo::tests::{mock_7_valid_utxos_rows, mock_result_7_valid, query_utxos_io};
use crate::tests::{MockIO, MockIOContext};

Expand Down Expand Up @@ -100,15 +94,14 @@ mod tests {
mock_7_valid_utxos_rows(),
"4704a903b01514645067d851382efd4a6ed5d2ff07cf30a538acc78fed7c4c02#93 (1100000 lovelace)"
),
MockIO::print(CAUTION),
MockIO::file_write_json_contains(
GENESIS_UTXO.config_file,
&GENESIS_UTXO.json_pointer(),
"4704a903b01514645067d851382efd4a6ed5d2ff07cf30a538acc78fed7c4c02#93",
),
]);

let result = prepare_chain_params(&mock_context);
let result = prepare_genesis_utxo(&mock_context);

result.expect("should succeed");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ use crate::config::config_fields::{
use crate::config::ServiceConfig;
use crate::io::IOContext;
use crate::prepare_configuration::prepare_cardano_params::prepare_cardano_params;
use crate::{config::config_fields, *};
use partner_chains_cardano_offchain::init_governance::InitGovernance;
use partner_chains_cardano_offchain::scripts_data::GetScriptsData;
use sidechain_domain::{MainchainAddressHash, MainchainPrivateKey, PolicyId, UtxoId};
use sidechain_domain::{PolicyId, UtxoId};

pub fn prepare_main_chain_config<C: IOContext>(
context: &C,
Expand All @@ -20,14 +18,6 @@ pub fn prepare_main_chain_config<C: IOContext>(
cardano_parameteres.save(context);
set_up_cardano_addresses(context, genesis_utxo, ogmios_config)?;

let offchain = context.offchain_impl(ogmios_config)?;
let (payment_key, governance_authority) = get_private_key_and_key_hash(context)?;

let runtime = tokio::runtime::Runtime::new().map_err(|e| anyhow::anyhow!(e))?;
runtime
.block_on(offchain.init_governance(governance_authority, payment_key, genesis_utxo))
.map_err(|e| anyhow::anyhow!("Governance initalization failed: {e:?}!"))?;

if INITIAL_PERMISSIONED_CANDIDATES.load_from_file(context).is_none() {
INITIAL_PERMISSIONED_CANDIDATES.save_to_file(&vec![], context)
}
Expand All @@ -36,17 +26,6 @@ pub fn prepare_main_chain_config<C: IOContext>(
Ok(())
}

fn get_private_key_and_key_hash<C: IOContext>(
context: &C,
) -> Result<(MainchainPrivateKey, MainchainAddressHash), anyhow::Error> {
let cardano_signig_key_file = config_fields::CARDANO_PAYMENT_SIGNING_KEY_FILE
.prompt_with_default_from_file_and_save(context);
let pkey = cardano_key::get_mc_pkey_from_file(&cardano_signig_key_file, context)?;
let addr_hash = pkey.to_pub_key_hash();

Ok((pkey, addr_hash))
}

fn set_up_cardano_addresses<C: IOContext>(
context: &C,
genesis_utxo: UtxoId,
Expand Down Expand Up @@ -121,14 +100,11 @@ mod tests {
use super::*;
use crate::config::config_fields::{GENESIS_UTXO, OGMIOS_PROTOCOL};
use crate::config::NetworkProtocol;
use crate::ogmios::test_values::{preprod_eras_summaries, preprod_shelley_config};
use crate::ogmios::{OgmiosRequest, OgmiosResponse};
use crate::prepare_configuration::prepare_cardano_params::tests::PREPROD_CARDANO_PARAMS;
use crate::prepare_configuration::tests::save_to_existing_file;
use crate::tests::{MockIO, MockIOContext, OffchainMock, OffchainMocks};
use config_fields::CARDANO_PAYMENT_SIGNING_KEY_FILE;
use hex_literal::hex;
use ogmios::test_values::{preprod_eras_summaries, preprod_shelley_config};
use ogmios_client::types::OgmiosTx;
use partner_chains_cardano_offchain::scripts_data::{Addresses, PolicyIds, ScriptsData};
use serde_json::json;
use serde_json::Value;
Expand Down Expand Up @@ -258,18 +234,6 @@ mod tests {
),
save_to_existing_file(ILLIQUID_SUPPLY_ADDRESS, TEST_ILLIQUID_SUPPLY_ADDRESS),
print_addresses_io(),
MockIO::file_read(CARDANO_PAYMENT_SIGNING_KEY_FILE.config_file),
MockIO::prompt(
"path to the payment signing key file",
Some("payment.skey"),
"payment.skey",
),
MockIO::file_read(CARDANO_PAYMENT_SIGNING_KEY_FILE.config_file),
MockIO::file_write_json(
CARDANO_PAYMENT_SIGNING_KEY_FILE.config_file,
test_resources_config(),
),
MockIO::file_read("payment.skey"),
MockIO::file_read(INITIAL_PERMISSIONED_CANDIDATES.config_file),
MockIO::file_read(INITIAL_PERMISSIONED_CANDIDATES.config_file),
MockIO::file_write_json(
Expand Down Expand Up @@ -328,18 +292,6 @@ mod tests {
),
save_to_existing_file(ILLIQUID_SUPPLY_ADDRESS, TEST_ILLIQUID_SUPPLY_ADDRESS),
print_addresses_io(),
MockIO::file_read(CARDANO_PAYMENT_SIGNING_KEY_FILE.config_file),
MockIO::prompt(
"path to the payment signing key file",
Some("payment.skey"),
"payment.skey",
),
MockIO::file_read(CARDANO_PAYMENT_SIGNING_KEY_FILE.config_file),
MockIO::file_write_json(
CARDANO_PAYMENT_SIGNING_KEY_FILE.config_file,
test_resources_config(),
),
MockIO::file_read("payment.skey"),
MockIO::file_read(INITIAL_PERMISSIONED_CANDIDATES.config_file),
scenarios::prompt_and_save_native_asset_scripts(),
MockIO::eprint(OUTRO),
Expand All @@ -363,47 +315,26 @@ mod tests {
}

fn preprod_offchain_mocks() -> OffchainMocks {
let mock = OffchainMock::new()
.with_scripts_data(
UtxoId::from_str(TEST_GENESIS_UTXO).unwrap(),
Ok(ScriptsData {
addresses: Addresses {
committee_candidate_validator: TEST_COMMITTEE_CANDIDATES_ADDRESS
.to_string(),
illiquid_circulation_supply_validator: TEST_ILLIQUID_SUPPLY_ADDRESS
.to_string(),
..Default::default()
},
policy_ids: PolicyIds {
permissioned_candidates: PolicyId::from_hex_unsafe(
TEST_PERMISSIONED_CANDIDATES_POLICY_ID,
),
d_parameter: PolicyId::from_hex_unsafe(TEST_D_PARAMETER_POLICY_ID),
..Default::default()
},
}),
)
.with_init_governance(
UtxoId::from_str(TEST_GENESIS_UTXO).unwrap(),
MainchainAddressHash(hex!(
"e8c300330fe315531ca89d4a2e7d0c80211bc70b473b1ed4979dff2b"
)),
MainchainPrivateKey(hex!(
"d0a6c5c921266d15dc8d1ce1e51a01e929a686ed3ec1a9be1145727c224bf386"
)),
Ok(OgmiosTx {
id: hex!("0000000000000000000000000000000000000000000000000000000000000000"),
}),
);
let mock = OffchainMock::new().with_scripts_data(
UtxoId::from_str(TEST_GENESIS_UTXO).unwrap(),
Ok(ScriptsData {
addresses: Addresses {
committee_candidate_validator: TEST_COMMITTEE_CANDIDATES_ADDRESS.to_string(),
illiquid_circulation_supply_validator: TEST_ILLIQUID_SUPPLY_ADDRESS.to_string(),
..Default::default()
},
policy_ids: PolicyIds {
permissioned_candidates: PolicyId::from_hex_unsafe(
TEST_PERMISSIONED_CANDIDATES_POLICY_ID,
),
d_parameter: PolicyId::from_hex_unsafe(TEST_D_PARAMETER_POLICY_ID),
..Default::default()
},
}),
);
OffchainMocks::new_with_mock("http://localhost:1337", mock)
}

fn test_resources_config() -> Value {
serde_json::json!({
"cardano_payment_signing_key_file": "payment.skey",
})
}

fn test_chain_config() -> Value {
serde_json::json!({
"cardano": {
Expand Down
2 changes: 1 addition & 1 deletion toolkit/primitives/domain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ pub struct UtxoId {
}

impl UtxoId {
pub fn new(hash: [u8; TX_HASH_SIZE], index: u16) -> UtxoId {
pub const fn new(hash: [u8; TX_HASH_SIZE], index: u16) -> UtxoId {
UtxoId { tx_hash: McTxHash(hash), index: UtxoIndex(index) }
}
}
Expand Down

0 comments on commit dc8b61e

Please sign in to comment.