Skip to content

Commit

Permalink
Merge branch 'master' into ETCM-9019-docker-image-for-smart-contracts…
Browse files Browse the repository at this point in the history
…-tests
  • Loading branch information
skylar-simoncelli authored Dec 10, 2024
2 parents 911831b + 38c2bed commit 3a3fa9f
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 55 deletions.
5 changes: 4 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ This changelog is based on [Keep A Changelog](https://keepachangelog.com/en/1.1.

## Changed

* `setup-main-chain-state` command now uses native Rust to insert the D-Parameter

## Removed

## Fixed
Expand Down Expand Up @@ -36,7 +38,8 @@ Do **NOT** perform a normal runtime upgrade, it will break your chain.

## Added

* Added `smart-contracts` command to the node with sub-commands `init-governance` and `get-scripts`.
* Added `smart-contracts` command to the node with sub-commands `init-governance`, `get-scripts` and
`upsert-d-parameter`.

# v1.3.0

Expand Down
35 changes: 35 additions & 0 deletions toolkit/cli/smart-contracts-commands/src/d_parameter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use jsonrpsee::http_client::HttpClient;
use partner_chains_cardano_offchain::d_param::upsert_d_param;
use sidechain_domain::DParameter;
use sidechain_domain::UtxoId;

use crate::read_private_key_from_file;

#[derive(Clone, Debug, clap::Parser)]
pub struct UpsertDParameterCmd {
#[clap(flatten)]
common_arguments: crate::CommonArguments,
#[arg(long)]
permissioned_candidates_count: u16,
#[arg(long)]
registered_candidates_count: u16,
#[arg(long, short('k'))]
payment_key_file: String,
#[arg(long, short('c'))]
genesis_utxo: UtxoId,
}

impl UpsertDParameterCmd {
pub async fn execute(self) -> crate::CmdResult<()> {
let payment_key = read_private_key_from_file(&self.payment_key_file)?;
let d_param = DParameter {
num_permissioned_candidates: self.permissioned_candidates_count,
num_registered_candidates: self.registered_candidates_count,
};
let client = HttpClient::builder().build(self.common_arguments.ogmios_host)?;

upsert_d_param(self.genesis_utxo, &d_param, payment_key.0, &client).await?;

Ok(())
}
}
4 changes: 4 additions & 0 deletions toolkit/cli/smart-contracts-commands/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use log4rs::{
use sidechain_domain::MainchainPrivateKey;

pub mod get_scripts;
pub mod d_parameter;
pub mod init_governance;

#[derive(Clone, Debug, clap::Subcommand)]
Expand All @@ -14,6 +15,8 @@ pub enum SmartContractsCmd {
GetScripts(get_scripts::GetScripts),
/// Initialize Partner Chain governance
InitGovernance(init_governance::InitGovernanceCmd),
/// Upsert DParameter
UpsertDParameter(d_parameter::UpsertDParameterCmd),
}

#[derive(Clone, Debug, clap::Parser)]
Expand All @@ -30,6 +33,7 @@ impl SmartContractsCmd {
match self {
Self::InitGovernance(cmd) => cmd.execute().await,
Self::GetScripts(cmd) => cmd.execute().await,
Self::UpsertDParameter(cmd) => cmd.execute().await,
}
}

Expand Down
21 changes: 21 additions & 0 deletions toolkit/offchain/src/d_param/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,27 @@ use sidechain_domain::{DParameter, McTxHash, UtxoId};
#[cfg(test)]
mod tests;

pub trait UpsertDParam {
#[allow(async_fn_in_trait)]
async fn upsert_d_param(
&self,
genesis_utxo: UtxoId,
d_parameter: &DParameter,
payment_signing_key: [u8; 32],
) -> anyhow::Result<Option<McTxHash>>;
}

impl<C: QueryLedgerState + QueryNetwork + Transactions> UpsertDParam for C {
async fn upsert_d_param(
&self,
genesis_utxo: UtxoId,
d_parameter: &DParameter,
payment_signing_key: [u8; 32],
) -> anyhow::Result<Option<McTxHash>> {
upsert_d_param(genesis_utxo, d_parameter, payment_signing_key, self).await
}
}

pub async fn upsert_d_param<C: QueryLedgerState + QueryNetwork + Transactions>(
genesis_utxo: UtxoId,
d_parameter: &DParameter,
Expand Down
20 changes: 20 additions & 0 deletions toolkit/partner-chains-cli/src/cardano_key.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::IOContext;
use anyhow::anyhow;
use sidechain_domain::{MainchainAddressHash, MainchainPrivateKey};

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
Expand Down Expand Up @@ -37,3 +38,22 @@ pub(crate) fn get_key_bytes_from_file<const N: usize>(
})?;
Ok(bytes)
}

pub(crate) fn get_mc_pkey_from_file(
path: &str,
context: &impl IOContext,
) -> anyhow::Result<MainchainPrivateKey> {
Ok(MainchainPrivateKey(get_key_bytes_from_file(path, context)?))
}

pub(crate) fn get_mc_address_hash_from_pkey(pkey: &MainchainPrivateKey) -> MainchainAddressHash {
let csl_private_key = cardano_serialization_lib::PrivateKey::from_normal_bytes(&pkey.0)
.expect("Conversion is infallible");
let csl_public_key_hash = csl_private_key
.to_public()
.hash()
.to_bytes()
.try_into()
.expect("Bytes represent correct public key hash");
MainchainAddressHash(csl_public_key_hash)
}
3 changes: 2 additions & 1 deletion toolkit/partner-chains-cli/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::config::ServiceConfig;
use crate::ogmios::{ogmios_request, OgmiosRequest, OgmiosResponse};
use anyhow::{anyhow, Context};
use jsonrpsee::http_client::HttpClient;
use partner_chains_cardano_offchain::d_param::UpsertDParam;
use partner_chains_cardano_offchain::init_governance::InitGovernance;
use partner_chains_cardano_offchain::scripts_data::GetScriptsData;
use sp_core::offchain::Timestamp;
Expand All @@ -15,7 +16,7 @@ use tempfile::{TempDir, TempPath};

pub trait IOContext {
/// It should implement all the required traits for offchain operations
type Offchain: GetScriptsData + InitGovernance;
type Offchain: GetScriptsData + InitGovernance + UpsertDParam;

fn run_command(&self, cmd: &str) -> anyhow::Result<String>;
fn print(&self, msg: &str);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::config::ServiceConfig;
use crate::io::IOContext;
use crate::prepare_configuration::prepare_cardano_params::prepare_cardano_params;
use crate::{config::config_fields, *};
use cardano_serialization_lib::*;
use partner_chains_cardano_offchain::init_governance::InitGovernance;
use partner_chains_cardano_offchain::scripts_data::GetScriptsData;
use sidechain_domain::{MainchainAddressHash, MainchainPrivateKey, PolicyId, UtxoId};
Expand Down Expand Up @@ -42,17 +41,10 @@ fn get_private_key_and_key_hash<C: IOContext>(
) -> 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 bytes = cardano_key::get_key_bytes_from_file(&cardano_signig_key_file, context)?;
let pkey = cardano_key::get_mc_pkey_from_file(&cardano_signig_key_file, context)?;
let addr_hash = cardano_key::get_mc_address_hash_from_pkey(&pkey);

let csl_private_key = PrivateKey::from_normal_bytes(&bytes)?;
let csl_public_key_hash = csl_private_key
.to_public()
.hash()
.to_bytes()
.try_into()
.expect("Bytes represent correct public key hash");

Ok((MainchainPrivateKey(bytes), MainchainAddressHash(csl_public_key_hash)))
Ok((pkey, addr_hash))
}

fn set_up_cardano_addresses<C: IOContext>(
Expand Down
55 changes: 28 additions & 27 deletions toolkit/partner-chains-cli/src/setup_main_chain_state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ use crate::config::{
CHAIN_CONFIG_FILE_PATH, PC_CONTRACTS_CLI_PATH,
};
use crate::io::IOContext;
use crate::pc_contracts_cli_resources::establish_pc_contracts_cli_configuration;
use crate::pc_contracts_cli_resources::{
establish_pc_contracts_cli_configuration, prompt_ogmios_configuration,
};
use crate::permissioned_candidates::{ParsedPermissionedCandidatesKeys, PermissionedCandidateKeys};
use crate::{smart_contracts, CmdRun};
use crate::{cardano_key, smart_contracts, CmdRun};
use anyhow::anyhow;
use anyhow::Context;
use partner_chains_cardano_offchain::d_param::UpsertDParam;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use sidechain_domain::mainchain_epoch::MainchainEpochDerivation;
Expand Down Expand Up @@ -50,13 +53,6 @@ enum InsertOrUpdate {
}

impl InsertOrUpdate {
fn d_parameter_command(&self) -> &'static str {
match self {
InsertOrUpdate::Insert => "insert-d-parameter",
InsertOrUpdate::Update => "update-d-parameter",
}
}

fn permissioned_candidates_command(&self) -> &'static str {
"update-permissioned-candidates --remove-all-candidates"
}
Expand Down Expand Up @@ -92,6 +88,13 @@ impl SortedPermissionedCandidates {

impl CmdRun for SetupMainChainStateCmd {
fn run<C: IOContext>(&self, context: &C) -> anyhow::Result<()> {
let runtime = tokio::runtime::Runtime::new().map_err(|e| anyhow::anyhow!(e))?;
runtime.block_on(self.run_async(context))
}
}

impl SetupMainChainStateCmd {
async fn run_async<C: IOContext>(&self, context: &C) -> anyhow::Result<()> {
let chain_config = crate::config::load_chain_config(context)?;
context.print(
"This wizard will set or update D-Parameter and Permissioned Candidates on the main chain. Setting either of these costs ADA!",
Expand Down Expand Up @@ -128,8 +131,8 @@ impl CmdRun for SetupMainChainStateCmd {
context,
ariadne_parameters.d_parameter,
chain_config.chain_parameters.genesis_utxo,
InsertOrUpdate::Update,
)?;
)
.await?;
} else {
set_candidates_on_main_chain(
context,
Expand All @@ -143,8 +146,8 @@ impl CmdRun for SetupMainChainStateCmd {
context,
default_d_parameter,
chain_config.chain_parameters.genesis_utxo,
InsertOrUpdate::Insert,
)?;
)
.await?;
}
context.print("Done. Main chain state is set. Please remember that any changes can be observed immediately, but from the Partner Chain point of view they will be effective in two main chain epochs.");
Ok(())
Expand Down Expand Up @@ -283,37 +286,35 @@ fn set_candidates_on_main_chain<C: IOContext>(
Ok(())
}

fn set_d_parameter_on_main_chain<C: IOContext>(
async fn set_d_parameter_on_main_chain<C: IOContext>(
context: &C,
default_d_parameter: DParameter,
genesis_utxo: UtxoId,
insert: InsertOrUpdate,
) -> anyhow::Result<()> {
let update = context
.prompt_yes_no("Do you want to set/update the D-parameter on the main chain?", false);
if update {
let ogmios_config = prompt_ogmios_configuration(context)?;
let p = context.prompt(
"Enter P, the number of permissioned candidates seats, as a non-negative integer.",
Some(&default_d_parameter.num_permissioned_candidates.to_string()),
);
let p: u64 = p.parse()?;
let num_permissioned_candidates: u16 = p.parse()?;
let r = context.prompt(
"Enter R, the number of registered candidates seats, as a non-negative integer.",
Some(&default_d_parameter.num_registered_candidates.to_string()),
);
let r: u64 = r.parse()?;
let pc_contracts_cli_resources = establish_pc_contracts_cli_configuration(context)?;
let num_registered_candidates: u16 = r.parse()?;
let payment_signing_key_path =
CARDANO_PAYMENT_SIGNING_KEY_FILE.prompt_with_default_from_file_and_save(context);
let pc_contracts_cli_command = insert.d_parameter_command();
let cardano_network = get_cardano_network_from_file(context)?;
let command = format!(
"{PC_CONTRACTS_CLI_PATH} {pc_contracts_cli_command} --network {} --d-parameter-permissioned-candidates-count {p} --d-parameter-registered-candidates-count {r} {} {}",
cardano_network,
smart_contracts::sidechain_params_arguments(genesis_utxo),
smart_contracts::runtime_config_arguments(&pc_contracts_cli_resources, &payment_signing_key_path)
);
context.run_command(&command).context("Setting D-parameter failed")?;
let payment_signing_key =
cardano_key::get_mc_pkey_from_file(&payment_signing_key_path, context)?;
let d_parameter =
sidechain_domain::DParameter { num_permissioned_candidates, num_registered_candidates };
context
.offchain_impl(&ogmios_config)?
.upsert_d_param(genesis_utxo, &d_parameter, payment_signing_key.0)
.await?;
context.print(&format!("D-parameter updated to ({}, {}). The change will be effective in two main chain epochs.", p, r));
}
Ok(())
Expand Down
Loading

0 comments on commit 3a3fa9f

Please sign in to comment.