Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Move run init-goveranance just after choosing the genesis-utxo #342

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading