diff --git a/toolkit/offchain/src/csl.rs b/toolkit/offchain/src/csl.rs index 04229ae5a..1b4c6577f 100644 --- a/toolkit/offchain/src/csl.rs +++ b/toolkit/offchain/src/csl.rs @@ -256,12 +256,19 @@ impl CostStore for Costs { } impl Costs { + pub fn new( + mints: HashMap, + spends: HashMap, + ) -> Costs { + Costs::Costs(CostLookup { mints, spends }) + } + pub async fn calculate_costs( make_tx: F, client: &T, ) -> anyhow::Result where - F: Fn(Costs) -> Result, + F: Fn(Costs) -> anyhow::Result, { let tx = make_tx(Costs::ZeroCosts)?; // stage 1 @@ -271,7 +278,7 @@ impl Costs { // stage 2 let costs = Self::from_ogmios(&tx, client).await?; - Ok(make_tx(costs)?) + make_tx(costs) } async fn from_ogmios(tx: &Transaction, client: &T) -> anyhow::Result { diff --git a/toolkit/offchain/src/reserve/create.rs b/toolkit/offchain/src/reserve/create.rs index 3638da293..72c3d8080 100644 --- a/toolkit/offchain/src/reserve/create.rs +++ b/toolkit/offchain/src/reserve/create.rs @@ -19,27 +19,25 @@ use super::ReserveData; use crate::{ await_tx::AwaitTx, csl::{ - get_builder_config, get_validator_budgets, zero_ex_units, MultiAssetExt, OgmiosUtxoExt, - TransactionBuilderExt, TransactionContext, TransactionOutputAmountBuilderExt, + get_builder_config, CostStore, Costs, MultiAssetExt, OgmiosUtxoExt, TransactionBuilderExt, + TransactionContext, TransactionOutputAmountBuilderExt, }, init_governance::{get_governance_data, GovernanceData}, scripts_data::ReserveScripts, }; -use anyhow::anyhow; use cardano_serialization_lib::{ - ExUnits, JsError, MultiAsset, Transaction, TransactionBuilder, TransactionOutput, + JsError, MultiAsset, Transaction, TransactionBuilder, TransactionOutput, TransactionOutputBuilder, }; use ogmios_client::{ query_ledger_state::{QueryLedgerState, QueryUtxoByUtxoId}, query_network::QueryNetwork, - transactions::{OgmiosEvaluateTransactionResponse, Transactions}, + transactions::Transactions, }; use partner_chains_plutus_data::reserve::{ ReserveDatum, ReserveImmutableSettings, ReserveMutableSettings, ReserveStats, }; use sidechain_domain::{AssetId, McTxHash, PolicyId, UtxoId}; -use std::collections::HashMap; pub async fn create_reserve_utxo< T: QueryLedgerState + Transactions + QueryNetwork + QueryUtxoByUtxoId, @@ -55,31 +53,12 @@ pub async fn create_reserve_utxo< let governance = get_governance_data(genesis_utxo, client).await?; let reserve = ReserveData::get(genesis_utxo, &ctx, client).await?; - let tx_to_evaluate = create_reserve_tx( - ¶meters, - &reserve, - &governance, - zero_ex_units(), - zero_ex_units(), - &ctx, - )?; - let evaluate_response = client.evaluate_transaction(&tx_to_evaluate.to_bytes()).await?; - - let (reserve_auth_ex_units, governance_ex_units) = match_costs( - &tx_to_evaluate, - &reserve.scripts.auth_policy.csl_script_hash(), - &governance.policy_script_hash(), - evaluate_response, - )?; + let tx = Costs::calculate_costs( + |costs| create_reserve_tx(¶meters, &reserve, &governance, costs, &ctx), + client, + ) + .await?; - let tx = create_reserve_tx( - ¶meters, - &reserve, - &governance, - governance_ex_units, - reserve_auth_ex_units, - &ctx, - )?; let signed_tx = ctx.sign(&tx).to_bytes(); let res = client.submit_transaction(&signed_tx).await.map_err(|e| { anyhow::anyhow!( @@ -121,16 +100,15 @@ fn create_reserve_tx( parameters: &ReserveParameters, reserve: &ReserveData, governance: &GovernanceData, - governance_script_cost: ExUnits, - reserve_auth_script_cost: ExUnits, + costs: Costs, ctx: &TransactionContext, -) -> Result { +) -> anyhow::Result { let mut tx_builder = TransactionBuilder::new(&get_builder_config(ctx)?); tx_builder.add_mint_one_script_token_using_reference_script( &reserve.scripts.auth_policy, &reserve.auth_policy_version_utxo.to_csl_tx_input(), - &reserve_auth_script_cost, + &costs.get_mint(&reserve.scripts.auth_policy), )?; tx_builder.add_output(&reserve_validator_output(parameters, &reserve.scripts, ctx)?)?; @@ -138,46 +116,13 @@ fn create_reserve_tx( tx_builder.add_mint_one_script_token_using_reference_script( &governance.policy_script, &gov_tx_input, - &governance_script_cost, + &costs.get_mint(&governance.policy_script), )?; tx_builder.add_script_reference_input( &reserve.validator_version_utxo.to_csl_tx_input(), reserve.scripts.validator.bytes.len(), ); - tx_builder.balance_update_and_build(ctx) -} - -fn match_costs( - evaluated_transaction: &Transaction, - reserve_auth_policy: &cardano_serialization_lib::ScriptHash, - governance_policy: &cardano_serialization_lib::ScriptHash, - evaluate_response: Vec, -) -> Result<(ExUnits, ExUnits), anyhow::Error> { - let mint_keys = evaluated_transaction - .body() - .mint() - .expect("Every Create Reserve transaction should have two mints") - .keys(); - let script_to_index: HashMap = - vec![(mint_keys.get(0), 0), (mint_keys.get(1), 1)].into_iter().collect(); - let mint_ex_units = get_validator_budgets(evaluate_response).mint_ex_units; - if mint_ex_units.len() == 2 { - let reserve_auth_policy_idx = *script_to_index - .get(reserve_auth_policy) - .expect("Reserve Auth Policy Token is present in transaction mints"); - let reserve_auth_ex_units = mint_ex_units - .get(reserve_auth_policy_idx) - .expect("mint_ex_units have two items") - .clone(); - let gov_policy_idx = *script_to_index - .get(governance_policy) - .expect("Governance Policy Token is present in transaction mints"); - let governance_ex_units = - mint_ex_units.get(gov_policy_idx).expect("mint_ex_units have two items").clone(); - Ok((reserve_auth_ex_units, governance_ex_units)) - } else { - Err(anyhow!("Could not build transaction to submit, evaluate response has wrong number of mint keys.")) - } + Ok(tx_builder.balance_update_and_build(ctx)?) } // Creates output with reserve token and the initial deposit diff --git a/toolkit/offchain/src/reserve/deposit.rs b/toolkit/offchain/src/reserve/deposit.rs index 2a019067d..70b265bbe 100644 --- a/toolkit/offchain/src/reserve/deposit.rs +++ b/toolkit/offchain/src/reserve/deposit.rs @@ -19,21 +19,20 @@ use super::{reserve_utxo_input_with_validator_script_reference, ReserveData, Tok use crate::{ await_tx::AwaitTx, csl::{ - get_builder_config, get_validator_budgets, zero_ex_units, MultiAssetExt, OgmiosUtxoExt, - TransactionBuilderExt, TransactionContext, TransactionOutputAmountBuilderExt, + get_builder_config, CostStore, Costs, MultiAssetExt, OgmiosUtxoExt, TransactionBuilderExt, + TransactionContext, TransactionOutputAmountBuilderExt, }, init_governance::{get_governance_data, GovernanceData}, scripts_data::ReserveScripts, }; -use anyhow::anyhow; use cardano_serialization_lib::{ - ExUnits, JsError, MultiAsset, Transaction, TransactionBuilder, TransactionOutput, + JsError, MultiAsset, Transaction, TransactionBuilder, TransactionOutput, TransactionOutputBuilder, }; use ogmios_client::{ query_ledger_state::{QueryLedgerState, QueryUtxoByUtxoId}, query_network::QueryNetwork, - transactions::{OgmiosEvaluateTransactionResponse, Transactions}, + transactions::Transactions, types::OgmiosUtxo, }; use partner_chains_plutus_data::reserve::ReserveRedeemer; @@ -58,29 +57,12 @@ pub async fn deposit_to_reserve< let token_amount = TokenAmount { token: parameters.token, amount: current_amount + parameters.amount }; - let tx_to_evaluate = deposit_to_reserve_tx( - &token_amount, - &utxo, - &reserve, - &governance, - zero_ex_units(), - zero_ex_units(), - &ctx, - )?; - let evaluate_response = client.evaluate_transaction(&tx_to_evaluate.to_bytes()).await?; - - let spend_ex_units = get_spend_cost(evaluate_response.clone())?; - let governance_ex_units = get_governance_script_cost(evaluate_response)?; + let tx = Costs::calculate_costs( + |costs| deposit_to_reserve_tx(&token_amount, &utxo, &reserve, &governance, costs, &ctx), + client, + ) + .await?; - let tx = deposit_to_reserve_tx( - &token_amount, - &utxo, - &reserve, - &governance, - governance_ex_units, - spend_ex_units, - &ctx, - )?; let signed_tx = ctx.sign(&tx).to_bytes(); let res = client.submit_transaction(&signed_tx).await.map_err(|e| { anyhow::anyhow!( @@ -112,25 +94,24 @@ fn deposit_to_reserve_tx( current_utxo: &OgmiosUtxo, reserve: &ReserveData, governance: &GovernanceData, - governance_script_cost: ExUnits, - spend_reserve_auth_token_cost: ExUnits, + costs: Costs, ctx: &TransactionContext, -) -> Result { +) -> anyhow::Result { let mut tx_builder = TransactionBuilder::new(&get_builder_config(ctx)?); tx_builder.add_output(&validator_output(parameters, current_utxo, &reserve.scripts, ctx)?)?; tx_builder.set_inputs(&reserve_utxo_input_with_validator_script_reference( - ¤t_utxo, - &reserve, - ReserveRedeemer::DepositToReserve { governance_version: 1 }, - &spend_reserve_auth_token_cost, + current_utxo, + reserve, + ReserveRedeemer::DepositToReserve, + &costs.get_one_spend(), )?); tx_builder.add_mint_one_script_token_using_reference_script( &governance.policy_script, &governance.utxo_id_as_tx_input(), - &governance_script_cost, + &costs.get_mint(&governance.policy_script), )?; tx_builder.add_script_reference_input( @@ -141,29 +122,7 @@ fn deposit_to_reserve_tx( &reserve.illiquid_circulation_supply_validator_version_utxo.to_csl_tx_input(), reserve.scripts.illiquid_circulation_supply_validator.bytes.len(), ); - tx_builder.balance_update_and_build(ctx) -} - -// governance token is the only minted token -fn get_governance_script_cost( - response: Vec, -) -> Result { - Ok(get_validator_budgets(response) - .mint_ex_units - .first() - .ok_or_else(|| anyhow!("Mint cost is missing in evaluate response"))? - .clone()) -} - -// Auth policy token is the only spent token is the transaction -fn get_spend_cost( - response: Vec, -) -> Result { - Ok(get_validator_budgets(response) - .spend_ex_units - .first() - .ok_or_else(|| anyhow!("Spend cost is missing in evaluate response"))? - .clone()) + Ok(tx_builder.balance_update_and_build(ctx)?) } // Creates output with reserve token and updated deposit diff --git a/toolkit/offchain/src/reserve/handover.rs b/toolkit/offchain/src/reserve/handover.rs index 1efd1c872..3d78fa192 100644 --- a/toolkit/offchain/src/reserve/handover.rs +++ b/toolkit/offchain/src/reserve/handover.rs @@ -91,7 +91,7 @@ fn build_tx( governance: &GovernanceData, costs: Costs, ctx: &TransactionContext, -) -> Result { +) -> anyhow::Result { let mut tx_builder = TransactionBuilder::new(&get_builder_config(ctx)?); let reserve_auth_policy_spend_cost = costs.get_one_spend(); @@ -109,7 +109,7 @@ fn build_tx( tx_builder.set_inputs(&reserve_utxo_input_with_validator_script_reference( reserve_utxo, reserve, - ReserveRedeemer::Handover { governance_version: 1 }, + ReserveRedeemer::Handover, &reserve_auth_policy_spend_cost, )?); @@ -130,7 +130,7 @@ fn build_tx( &reserve.illiquid_circulation_supply_validator_version_utxo.to_csl_tx_input(), reserve.scripts.illiquid_circulation_supply_validator.bytes.len(), ); - tx_builder.balance_update_and_build(ctx) + Ok(tx_builder.balance_update_and_build(ctx)?) } // Creates output with reserve token and updated deposit diff --git a/toolkit/offchain/src/reserve/init.rs b/toolkit/offchain/src/reserve/init.rs index c9c59abc3..7f5c83cad 100644 --- a/toolkit/offchain/src/reserve/init.rs +++ b/toolkit/offchain/src/reserve/init.rs @@ -17,8 +17,8 @@ use crate::{ await_tx::AwaitTx, csl::{ - get_builder_config, get_validator_budgets, zero_ex_units, MultiAssetExt, OgmiosUtxoExt, - TransactionBuilderExt, TransactionContext, TransactionOutputAmountBuilderExt, + get_builder_config, CostStore, Costs, MultiAssetExt, OgmiosUtxoExt, TransactionBuilderExt, + TransactionContext, TransactionOutputAmountBuilderExt, }, init_governance::{get_governance_data, GovernanceData}, plutus_script::PlutusScript, @@ -26,20 +26,19 @@ use crate::{ }; use anyhow::anyhow; use cardano_serialization_lib::{ - AssetName, BigNum, ConstrPlutusData, ExUnits, JsError, Language, MultiAsset, PlutusData, - PlutusList, ScriptHash, ScriptRef, Transaction, TransactionBuilder, TransactionOutputBuilder, + AssetName, BigNum, ConstrPlutusData, JsError, Language, MultiAsset, PlutusData, PlutusList, + ScriptRef, Transaction, TransactionBuilder, TransactionOutputBuilder, }; use ogmios_client::{ query_ledger_state::{QueryLedgerState, QueryUtxoByUtxoId}, query_network::QueryNetwork, - transactions::{OgmiosEvaluateTransactionResponse, Transactions}, + transactions::Transactions, types::OgmiosUtxo, }; use raw_scripts::{ ScriptId, ILLIQUID_CIRCULATION_SUPPLY_VALIDATOR, RESERVE_AUTH_POLICY, RESERVE_VALIDATOR, }; use sidechain_domain::{McTxHash, UtxoId}; -use std::collections::HashMap; pub async fn init_reserve_management< T: QueryLedgerState + Transactions + QueryNetwork + QueryUtxoByUtxoId, @@ -118,31 +117,12 @@ async fn initialize_script< return Ok(None); } - let tx_to_evaluate = init_script_tx( - &script, - &governance, - zero_ex_units(), - &version_oracle, - zero_ex_units(), - &ctx, - )?; - let evaluate_response = client.evaluate_transaction(&tx_to_evaluate.to_bytes()).await?; - - let (version_oracle_ex_units, governance_ex_units) = match_costs( - &tx_to_evaluate, - &version_oracle.policy.csl_script_hash(), - &governance.policy_script_hash(), - evaluate_response, - )?; + let tx = Costs::calculate_costs( + |costs| init_script_tx(&script, &governance, &version_oracle, costs, &ctx), + client, + ) + .await?; - let tx = init_script_tx( - &script, - &governance, - governance_ex_units, - &version_oracle, - version_oracle_ex_units, - &ctx, - )?; let signed_tx = ctx.sign(&tx).to_bytes(); let res = client.submit_transaction(&signed_tx).await.map_err(|e| { anyhow!( @@ -165,11 +145,10 @@ async fn initialize_script< fn init_script_tx( script: &ScriptData, governance: &GovernanceData, - governance_script_cost: ExUnits, version_oracle: &VersionOracleData, - versioning_script_cost: ExUnits, + costs: Costs, ctx: &TransactionContext, -) -> Result { +) -> anyhow::Result { let mut tx_builder = TransactionBuilder::new(&get_builder_config(ctx)?); let applied_script = script.applied_plutus_script(version_oracle)?; { @@ -181,7 +160,7 @@ fn init_script_tx( &version_oracle.policy, &version_oracle_asset_name(), &witness, - &versioning_script_cost, + &costs.get_mint(&version_oracle.policy), )?; } { @@ -204,11 +183,11 @@ fn init_script_tx( tx_builder.add_mint_one_script_token_using_reference_script( &governance.policy_script, &gov_tx_input, - &governance_script_cost, + &costs.get_mint(&governance.policy_script), )?; tx_builder.add_script_reference_input(&gov_tx_input, governance.policy_script.bytes.len()); - tx_builder.balance_update_and_build(ctx) + Ok(tx_builder.balance_update_and_build(ctx)?) } fn version_oracle_asset_name() -> AssetName { @@ -222,39 +201,6 @@ fn version_oracle_plutus_list(script_id: u32, script_hash: &[u8]) -> PlutusList list } -fn match_costs( - evaluated_transaction: &Transaction, - version_oracle_policy: &ScriptHash, - governance_policy: &ScriptHash, - evaluate_response: Vec, -) -> Result<(ExUnits, ExUnits), anyhow::Error> { - let mint_keys = evaluated_transaction - .body() - .mint() - .expect("Every Init Reserve Management transaction should have two mints") - .keys(); - let script_to_index: HashMap = - vec![(mint_keys.get(0), 0), (mint_keys.get(1), 1)].into_iter().collect(); - let mint_ex_units = get_validator_budgets(evaluate_response).mint_ex_units; - if mint_ex_units.len() == 2 { - let version_policy_idx = *script_to_index - .get(version_oracle_policy) - .expect("Version Oracle Policy script is present in transaction mints"); - let version_oracle_ex_units = mint_ex_units - .get(version_policy_idx) - .expect("mint_ex_units have two items") - .clone(); - let gov_policy_idx = *script_to_index - .get(governance_policy) - .expect("Governance Policy script is present in transaction mints"); - let governance_ex_units = - mint_ex_units.get(gov_policy_idx).expect("mint_ex_units have two items").clone(); - Ok((version_oracle_ex_units, governance_ex_units)) - } else { - Err(anyhow!("Could not build transaction to submit, evaluate response has wrong number of mint keys.")) - } -} - // There exist UTXO at Version Oracle Validator with Datum that contains // * script id of the script being initialized // * Version Oracle Policy Id @@ -311,7 +257,7 @@ fn decode_version_oracle_validator_datum(data: PlutusData) -> Option ExUnits { ExUnits::new(&300u64.into(), &400u64.into()) } + + fn test_costs() -> Costs { + Costs::new( + vec![ + (test_governance_script().csl_script_hash(), governance_script_cost()), + (version_oracle_policy_csl_script_hash(), versioning_script_cost()), + ] + .into_iter() + .collect(), + std::collections::HashMap::new(), + ) + } } diff --git a/toolkit/offchain/src/reserve/release.rs b/toolkit/offchain/src/reserve/release.rs index dcd6837bb..7b479dab0 100644 --- a/toolkit/offchain/src/reserve/release.rs +++ b/toolkit/offchain/src/reserve/release.rs @@ -23,7 +23,7 @@ use super::{reserve_utxo_input_with_validator_script_reference, ReserveData, Tok use crate::{await_tx::AwaitTx, csl::*, plutus_script::PlutusScript, reserve::ReserveUtxo}; use anyhow::anyhow; use cardano_serialization_lib::{ - ExUnits, Int, MultiAsset, PlutusData, Transaction, TransactionBuilder, TransactionOutputBuilder, + Int, MultiAsset, PlutusData, Transaction, TransactionBuilder, TransactionOutputBuilder, }; use ogmios_client::{ query_ledger_state::*, @@ -57,37 +57,23 @@ pub async fn release_reserve_funds< let ReserveUtxo { reserve_utxo, reserve_settings } = reserve_data.get_reserve_utxo(&ctx, client).await?; - let tx = reserve_release_tx( - &ctx, - &reserve_data, - &reserve_utxo, - &reserve_settings, - &reference_utxo, - token.amount, - tip.slot, - ExUnits::new(&0u64.into(), &0u64.into()), - ExUnits::new(&0u64.into(), &0u64.into()), - )?; - let costs = client.evaluate_transaction(&tx.to_bytes()).await?; - let ScriptExUnits { mint_ex_units, spend_ex_units } = get_validator_budgets(costs); - let [mint_cost] = &mint_ex_units[..] else { - return Err(anyhow!("Error retrieving witness costs: mint cost data missing.")); - }; - let [spend_cost] = &spend_ex_units[..] else { - return Err(anyhow!("Error retrieving witness costs: spend cost data missing.")); - }; + let tx = Costs::calculate_costs( + |costs| { + reserve_release_tx( + &ctx, + &reserve_data, + &reserve_utxo, + &reserve_settings, + &reference_utxo, + token.amount, + tip.slot, + costs, + ) + }, + client, + ) + .await?; - let tx = reserve_release_tx( - &ctx, - &reserve_data, - &reserve_utxo, - &reserve_settings, - &reference_utxo, - token.amount, - tip.slot, - mint_cost.clone(), - spend_cost.clone(), - )?; let signed_tx = ctx.sign(&tx).to_bytes(); let res = client.submit_transaction(&signed_tx).await.map_err(|e| { @@ -112,8 +98,7 @@ fn reserve_release_tx( reference_utxo: &OgmiosUtxo, cumulative_total_transfer: u64, latest_slot: u64, - mint_cost: ExUnits, - reserve_auth_script_cost: ExUnits, + costs: Costs, ) -> anyhow::Result { let token = previous_reserve_datum.immutable_settings.token.clone(); let stats = previous_reserve_datum.stats.clone(); @@ -141,19 +126,20 @@ fn reserve_release_tx( // Mint v-function tokens in the number equal to the *total* number of tokens transfered. // This serves as a validation of the v-function value. + let v_function = v_function_from_utxo(reference_utxo)?; tx_builder.add_mint_script_token_using_reference_script( - &v_function_from_utxo(reference_utxo)?, + &v_function, &reference_utxo.to_csl_tx_input(), &Int::new(&cumulative_total_transfer.into()), - &mint_cost, + &costs.get_mint(&v_function), )?; // Remove tokens from the reserve tx_builder.set_inputs(&reserve_utxo_input_with_validator_script_reference( - &previous_reserve_utxo, - &reserve_data, + previous_reserve_utxo, + reserve_data, ReserveRedeemer::ReleaseFromReserve, - &reserve_auth_script_cost, + &costs.get_one_spend(), )?); // Transfer released tokens to the illiquid supply @@ -164,7 +150,7 @@ fn reserve_release_tx( ) .with_plutus_data(&PlutusData::new_empty_constr_plutus_data(&0u64.into())) .next()? - .with_minimum_ada_and_asset(&token.to_multi_asset(amount_to_transfer)?, &ctx)? + .with_minimum_ada_and_asset(&token.to_multi_asset(amount_to_transfer)?, ctx)? .build()? })?; @@ -179,7 +165,7 @@ fn reserve_release_tx( .with_minimum_ada_and_asset( &MultiAsset::from_ogmios_utxo(previous_reserve_utxo)? .with_asset_amount(&token, left_in_reserve)?, - &ctx, + ctx, )? .build()? })?; @@ -201,7 +187,7 @@ fn v_function_from_utxo(utxo: &OgmiosUtxo) -> anyhow::Result { #[cfg(test)] mod tests { - use super::{empty_asset_name, reserve_release_tx, AssetNameExt, TransactionContext}; + use super::{empty_asset_name, reserve_release_tx, AssetNameExt, Costs, TransactionContext}; use crate::{ plutus_script::PlutusScript, reserve::{release::OgmiosUtxoExt, ReserveData}, @@ -209,7 +195,7 @@ mod tests { test_values::protocol_parameters, }; use cardano_serialization_lib::{ - ExUnits, Int, Language, NetworkIdKind, PolicyID, PrivateKey, Transaction, + Int, Language, NetworkIdKind, PolicyID, PrivateKey, Transaction, }; use hex_literal::hex; use ogmios_client::types::{Asset, OgmiosScript, OgmiosTx, OgmiosUtxo, OgmiosValue}; @@ -404,8 +390,7 @@ mod tests { &reference_utxo(), 20, 0, - ExUnits::new(&0u64.into(), &0u64.into()), - ExUnits::new(&0u64.into(), &0u64.into()), + Costs::ZeroCosts, ) .unwrap() } diff --git a/toolkit/offchain/src/reserve/update_settings.rs b/toolkit/offchain/src/reserve/update_settings.rs index eb3c4279e..5f15134e3 100644 --- a/toolkit/offchain/src/reserve/update_settings.rs +++ b/toolkit/offchain/src/reserve/update_settings.rs @@ -69,39 +69,21 @@ pub async fn update_reserve_settings< return Ok(None); } - let tx_to_evaluate = update_reserve_settings_tx( - &reserve_settings, - &reserve, - &governance, - &zero_ex_units(), - &reserve_utxo, - &zero_ex_units(), - &ctx, - )?; - - let evaluate_response = client.evaluate_transaction(&tx_to_evaluate.to_bytes()).await?; + let tx = Costs::calculate_costs( + |costs| { + update_reserve_settings_tx( + &reserve_settings, + &reserve, + &governance, + &reserve_utxo, + costs, + &ctx, + ) + }, + client, + ) + .await?; - let budgets = get_validator_budgets(evaluate_response); - let gov_cost = budgets - .mint_ex_units - .first() - .expect("Every Update Reserve Settings transaction should have one mint") - .clone(); - let reserve_cost = budgets - .spend_ex_units - .first() - .expect("Every Update Reserve Settings transaction should have one spend") - .clone(); - - let tx = update_reserve_settings_tx( - &reserve_settings, - &reserve, - &governance, - &gov_cost, - &reserve_utxo, - &reserve_cost, - &ctx, - )?; let signed_tx = ctx.sign(&tx).to_bytes(); let res = client.submit_transaction(&signed_tx).await.map_err(|e| { anyhow::anyhow!( @@ -120,19 +102,18 @@ fn update_reserve_settings_tx( datum: &ReserveDatum, reserve: &ReserveData, governance: &GovernanceData, - governance_script_cost: &ExUnits, reserve_utxo: &OgmiosUtxo, - reserve_script_cost: &ExUnits, + costs: Costs, ctx: &TransactionContext, -) -> Result { +) -> anyhow::Result { let mut tx_builder = TransactionBuilder::new(&get_builder_config(ctx)?); // spend old settings tx_builder.set_inputs(&reserve_utxo_input_with_validator_script_reference( - &reserve_utxo, - &reserve, - ReserveRedeemer::UpdateReserve { governance_version: 1u64 }, - &reserve_script_cost, + reserve_utxo, + reserve, + ReserveRedeemer::UpdateReserve, + &costs.get_one_spend(), )?); { let amount_builder = TransactionOutputBuilder::new() @@ -156,7 +137,7 @@ fn update_reserve_settings_tx( tx_builder.add_mint_one_script_token_using_reference_script( &governance.policy_script, &governance.utxo_id_as_tx_input(), - governance_script_cost, + &costs.get_mint(&governance.policy_script), )?; tx_builder.add_script_reference_input( &reserve.illiquid_circulation_supply_validator_version_utxo.to_csl_tx_input(), @@ -166,5 +147,5 @@ fn update_reserve_settings_tx( &reserve.auth_policy_version_utxo.to_csl_tx_input(), reserve.scripts.auth_policy.bytes.len(), ); - tx_builder.balance_update_and_build(ctx) + Ok(tx_builder.balance_update_and_build(ctx)?) } diff --git a/toolkit/primitives/plutus-data/src/reserve.rs b/toolkit/primitives/plutus-data/src/reserve.rs index 82fe21e85..873ead787 100644 --- a/toolkit/primitives/plutus-data/src/reserve.rs +++ b/toolkit/primitives/plutus-data/src/reserve.rs @@ -7,10 +7,10 @@ use sidechain_domain::{AssetId, AssetName, PolicyId}; #[derive(Debug, Clone)] pub enum ReserveRedeemer { - DepositToReserve { governance_version: u64 }, - ReleaseFromReserve, - UpdateReserve { governance_version: u64 }, - Handover { governance_version: u64 }, + DepositToReserve = 0, + ReleaseFromReserve = 1, + UpdateReserve = 2, + Handover = 3, } #[derive(Debug, Clone, PartialEq)] @@ -38,26 +38,7 @@ pub struct ReserveStats { impl From for PlutusData { fn from(value: ReserveRedeemer) -> Self { - use ReserveRedeemer::*; - match value { - DepositToReserve { governance_version } => { - PlutusData::new_single_value_constr_plutus_data( - &BigNum::from(0_u64), - &PlutusData::new_integer(&BigInt::from(governance_version)), - ) - }, - ReleaseFromReserve => PlutusData::new_empty_constr_plutus_data(&BigNum::from(1_u64)), - UpdateReserve { governance_version } => { - PlutusData::new_single_value_constr_plutus_data( - &BigNum::from(2_u64), - &PlutusData::new_integer(&BigInt::from(governance_version)), - ) - }, - Handover { governance_version } => PlutusData::new_single_value_constr_plutus_data( - &BigNum::from(3_u64), - &PlutusData::new_integer(&BigInt::from(governance_version)), - ), - } + PlutusData::new_empty_constr_plutus_data(&BigNum::from(value as u64)) } }