Skip to content

Commit

Permalink
Feature/vote (#88)
Browse files Browse the repository at this point in the history
* add voting support

* bump version
  • Loading branch information
twwu123 authored Oct 1, 2024
1 parent e4cdc8d commit 6b2efbb
Show file tree
Hide file tree
Showing 19 changed files with 667 additions and 162 deletions.
6 changes: 3 additions & 3 deletions packages/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
version = "0.8.5"
version = "0.8.6"
resolver = "2"
members = [
"sidan-csl-rs",
Expand Down
2 changes: 1 addition & 1 deletion packages/sidan-csl-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sidan-csl-rs"
version = "0.8.5"
version = "0.8.6"
edition = "2021"
license = "Apache-2.0"
description = "Wrapper around the cardano-serialization-lib for easier transaction building, heavily inspired by cardano-cli APIs"
Expand Down
19 changes: 19 additions & 0 deletions packages/sidan-csl-rs/src/core/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub fn serialize_tx_body(
TxBuilderCore::add_all_withdrawals(&mut mesh_csl, mesh_tx_builder_body.withdrawals.clone())?;
TxBuilderCore::add_all_mints(&mut mesh_csl, mesh_tx_builder_body.mints.clone())?;
TxBuilderCore::add_all_certificates(&mut mesh_csl, mesh_tx_builder_body.certificates.clone())?;
TxBuilderCore::add_all_votes(&mut mesh_csl, mesh_tx_builder_body.votes.clone())?;
TxBuilderCore::add_validity_range(&mut mesh_csl, mesh_tx_builder_body.validity_range.clone());
TxBuilderCore::add_all_required_signature(
&mut mesh_csl,
Expand Down Expand Up @@ -150,6 +151,7 @@ impl TxBuilderCore {
change_address: "".to_string(),
change_datum: None,
certificates: vec![],
votes: vec![],
metadata: vec![],
validity_range: ValidityRange {
invalid_before: None,
Expand Down Expand Up @@ -344,6 +346,23 @@ impl TxBuilderCore {
Ok(())
}

/// ## Internal method
///
/// Add multiple votes to the TxBuilder instance
///
/// ### Arguments
///
/// * `mesh_csl` - The MeshCSL instance
/// * `votes` - A vector of votes
fn add_all_votes(mesh_csl: &mut MeshCSL, votes: Vec<Vote>) -> Result<(), JsError> {
let mut vote_builder = csl::VotingBuilder::new();
for (index, vote) in votes.into_iter().enumerate() {
mesh_csl.add_vote(&mut vote_builder, vote, index as u64)?
}
mesh_csl.tx_builder.set_voting_builder(&vote_builder);
Ok(())
}

/// ## Internal method
///
/// Add a validity range to the TxBuilder instance
Expand Down
254 changes: 107 additions & 147 deletions packages/sidan-csl-rs/src/core/core_csl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use cardano_serialization_lib::{JsError, MintWitness};

use super::{
constants::build_csl_cost_models,
utils::{build_tx_builder, sign_transaction, to_bignum, to_csl_cert, to_value},
utils::{
build_tx_builder, sign_transaction, to_bignum, to_csl_anchor, to_csl_cert, to_csl_redeemer,
to_csl_script_source, to_csl_simple_script_source, to_csl_vote_kind, to_csl_voter,
to_value,
},
};

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -68,9 +72,7 @@ impl MeshCSL {
&to_value(&input.tx_in.amount.unwrap()),
);
Ok(())
} // Err(JsError::from_str(
// "Reference Native scripts not implemented",
// )),
}
}
}

Expand All @@ -95,35 +97,7 @@ impl MeshCSL {
}
};

let csl_script: csl::PlutusScriptSource = match script_source {
ScriptSource::ProvidedScriptSource(script) => {
let language_version: csl::Language = match script.language_version {
LanguageVersion::V1 => csl::Language::new_plutus_v1(),
LanguageVersion::V2 => csl::Language::new_plutus_v2(),
LanguageVersion::V3 => csl::Language::new_plutus_v3(),
};
csl::PlutusScriptSource::new(&csl::PlutusScript::from_hex_with_version(
&script.script_cbor,
&language_version,
)?)
}
ScriptSource::InlineScriptSource(script) => {
let language_version: csl::Language = match script.language_version {
LanguageVersion::V1 => csl::Language::new_plutus_v1(),
LanguageVersion::V2 => csl::Language::new_plutus_v2(),
LanguageVersion::V3 => csl::Language::new_plutus_v3(),
};
csl::PlutusScriptSource::new_ref_input(
&csl::ScriptHash::from_hex(&script.script_hash)?,
&csl::TransactionInput::new(
&csl::TransactionHash::from_hex(&script.ref_tx_in.tx_hash)?,
script.ref_tx_in.tx_index,
),
&language_version,
script.script_size,
)
}
};
let csl_script: csl::PlutusScriptSource = to_csl_script_source(script_source)?;

let csl_redeemer: csl::Redeemer = csl::Redeemer::new(
&csl::RedeemerTag::new_spend(),
Expand Down Expand Up @@ -263,35 +237,7 @@ impl MeshCSL {
let script_source = withdrawal.script_source.unwrap();
let redeemer = withdrawal.redeemer.unwrap();

let csl_script: csl::PlutusScriptSource = match script_source {
ScriptSource::ProvidedScriptSource(script) => {
let language_version: csl::Language = match script.language_version {
LanguageVersion::V1 => csl::Language::new_plutus_v1(),
LanguageVersion::V2 => csl::Language::new_plutus_v2(),
LanguageVersion::V3 => csl::Language::new_plutus_v3(),
};
csl::PlutusScriptSource::new(&csl::PlutusScript::from_hex_with_version(
&script.script_cbor,
&language_version,
)?)
}
ScriptSource::InlineScriptSource(script) => {
let language_version: csl::Language = match script.language_version {
LanguageVersion::V1 => csl::Language::new_plutus_v1(),
LanguageVersion::V2 => csl::Language::new_plutus_v2(),
LanguageVersion::V3 => csl::Language::new_plutus_v3(),
};
csl::PlutusScriptSource::new_ref_input(
&csl::ScriptHash::from_hex(&script.script_hash)?,
&csl::TransactionInput::new(
&csl::TransactionHash::from_hex(&script.ref_tx_in.tx_hash)?,
script.ref_tx_in.tx_index,
),
&language_version,
script.script_size,
)
}
};
let csl_script: csl::PlutusScriptSource = to_csl_script_source(script_source)?;

let csl_redeemer: csl::Redeemer = csl::Redeemer::new(
&csl::RedeemerTag::new_spend(),
Expand Down Expand Up @@ -368,35 +314,7 @@ impl MeshCSL {
),
);
let script_source_info = script_mint.script_source.unwrap();
let mint_script = match script_source_info {
ScriptSource::InlineScriptSource(script) => {
let language_version: csl::Language = match script.language_version {
LanguageVersion::V1 => csl::Language::new_plutus_v1(),
LanguageVersion::V2 => csl::Language::new_plutus_v2(),
LanguageVersion::V3 => csl::Language::new_plutus_v3(),
};
csl::PlutusScriptSource::new_ref_input(
&csl::ScriptHash::from_hex(script_mint.mint.policy_id.as_str())?,
&csl::TransactionInput::new(
&csl::TransactionHash::from_hex(&script.ref_tx_in.tx_hash)?,
script.ref_tx_in.tx_index,
),
&language_version,
script.script_size,
)
}
ScriptSource::ProvidedScriptSource(script) => {
let language_version: csl::Language = match script.language_version {
LanguageVersion::V1 => csl::Language::new_plutus_v1(),
LanguageVersion::V2 => csl::Language::new_plutus_v2(),
LanguageVersion::V3 => csl::Language::new_plutus_v3(),
};
csl::PlutusScriptSource::new(&csl::PlutusScript::from_hex_with_version(
script.script_cbor.as_str(),
&language_version,
)?)
}
};
let mint_script = to_csl_script_source(script_source_info)?;
mint_builder.add_asset(
&csl::MintWitness::new_plutus_script(&mint_script, &mint_redeemer),
&csl::AssetName::new(hex::decode(script_mint.mint.asset_name).unwrap())?,
Expand Down Expand Up @@ -447,51 +365,15 @@ impl MeshCSL {
}
Certificate::ScriptCertificate(script_cert) => {
let cert_script_source: csl::PlutusScriptSource = match script_cert.script_source {
Some(script_source) => match script_source {
ScriptSource::InlineScriptSource(script) => {
let language_version: csl::Language = match script.language_version {
LanguageVersion::V1 => csl::Language::new_plutus_v1(),
LanguageVersion::V2 => csl::Language::new_plutus_v2(),
LanguageVersion::V3 => csl::Language::new_plutus_v3(),
};
csl::PlutusScriptSource::new_ref_input(
&csl::ScriptHash::from_hex(&script.script_hash)?,
&csl::TransactionInput::new(
&csl::TransactionHash::from_hex(&script.ref_tx_in.tx_hash)?,
script.ref_tx_in.tx_index,
),
&language_version,
script.script_size,
)
}
ScriptSource::ProvidedScriptSource(script) => {
let language_version: csl::Language = match script.language_version {
LanguageVersion::V1 => csl::Language::new_plutus_v1(),
LanguageVersion::V2 => csl::Language::new_plutus_v2(),
LanguageVersion::V3 => csl::Language::new_plutus_v3(),
};
csl::PlutusScriptSource::new(&csl::PlutusScript::from_hex_with_version(
script.script_cbor.as_str(),
&language_version,
)?)
}
},
Some(script_source) => to_csl_script_source(script_source)?,
None => {
return Err(JsError::from_str(
"Missing Plutus Script Source in Plutus Cert",
))
}
};
let cert_redeemer = match script_cert.redeemer {
Some(redeemer) => csl::Redeemer::new(
&csl::RedeemerTag::new_cert(),
&to_bignum(index),
&csl::PlutusData::from_hex(&redeemer.data)?,
&csl::ExUnits::new(
&to_bignum(redeemer.ex_units.mem),
&to_bignum(redeemer.ex_units.steps),
),
),
Some(redeemer) => to_csl_redeemer(RedeemerTag::Cert, redeemer, index)?,
None => return Err(JsError::from_str("Missing Redeemer in Plutus Cert")),
};
let csl_plutus_witness: csl::PlutusWitness =
Expand All @@ -505,24 +387,9 @@ impl MeshCSL {
Certificate::SimpleScriptCertificate(simple_script_cert) => {
let script_info = simple_script_cert.simple_script_source;
let script_source: csl::NativeScriptSource = match script_info {
Some(script_source) => match script_source {
SimpleScriptSource::ProvidedSimpleScriptSource(script) => {
csl::NativeScriptSource::new(&csl::NativeScript::from_hex(
&script.script_cbor,
)?)
}

SimpleScriptSource::InlineSimpleScriptSource(script) => {
csl::NativeScriptSource::new_ref_input(
&csl::ScriptHash::from_hex(&script.simple_script_hash)?,
&csl::TransactionInput::new(
&csl::TransactionHash::from_hex(&script.ref_tx_in.tx_hash)?,
script.ref_tx_in.tx_index,
),
script.script_size,
)
}
},
Some(simple_script_source) => {
to_csl_simple_script_source(simple_script_source)?
}
None => {
return Err(JsError::from_str(
"Missing Native Script Source in Native Cert",
Expand All @@ -538,6 +405,99 @@ impl MeshCSL {
Ok(())
}

pub fn add_vote(
&mut self,
vote_builder: &mut csl::VotingBuilder,
vote: Vote,
index: u64,
) -> Result<(), JsError> {
match vote {
Vote::BasicVote(vote_type) => {
let voter = to_csl_voter(vote_type.voter)?;
let vote_kind = to_csl_vote_kind(vote_type.voting_procedure.vote_kind);
let voting_procedure = match vote_type.voting_procedure.anchor {
Some(anchor) => {
csl::VotingProcedure::new_with_anchor(vote_kind, &to_csl_anchor(&anchor)?)
}
None => csl::VotingProcedure::new(vote_kind),
};
vote_builder.add(
&voter,
&csl::GovernanceActionId::new(
&csl::TransactionHash::from_hex(&vote_type.gov_action_id.tx_hash)?,
vote_type.gov_action_id.tx_index,
),
&voting_procedure,
)?
}
Vote::ScriptVote(script_vote) => {
let voter = to_csl_voter(script_vote.vote.voter)?;
let vote_kind = to_csl_vote_kind(script_vote.vote.voting_procedure.vote_kind);
let voting_procedure = match script_vote.vote.voting_procedure.anchor {
Some(anchor) => {
csl::VotingProcedure::new_with_anchor(vote_kind, &to_csl_anchor(&anchor)?)
}
None => csl::VotingProcedure::new(vote_kind),
};
let vote_script_source: csl::PlutusScriptSource = match script_vote.script_source {
Some(script_source) => to_csl_script_source(script_source)?,
None => {
return Err(JsError::from_str(
"Missing Plutus Script Source in Plutus Vote",
))
}
};
let vote_redeemer = match script_vote.redeemer {
Some(redeemer) => to_csl_redeemer(RedeemerTag::Vote, redeemer, index)?,
None => return Err(JsError::from_str("Missing Redeemer in Plutus Vote")),
};
let csl_plutus_witness: csl::PlutusWitness =
csl::PlutusWitness::new_with_ref_without_datum(
&vote_script_source,
&vote_redeemer,
);
vote_builder.add_with_plutus_witness(
&voter,
&csl::GovernanceActionId::new(
&csl::TransactionHash::from_hex(&script_vote.vote.gov_action_id.tx_hash)?,
script_vote.vote.gov_action_id.tx_index,
),
&voting_procedure,
&csl_plutus_witness,
)?
}
Vote::SimpleScriptVote(simple_script_vote) => {
let voter = to_csl_voter(simple_script_vote.vote.voter)?;
let vote_kind =
to_csl_vote_kind(simple_script_vote.vote.voting_procedure.vote_kind);
let voting_procedure = match simple_script_vote.vote.voting_procedure.anchor {
Some(anchor) => {
csl::VotingProcedure::new_with_anchor(vote_kind, &to_csl_anchor(&anchor)?)
}
None => csl::VotingProcedure::new(vote_kind),
};
let csl_simple_script_source = match simple_script_vote.simple_script_source {
Some(simple_script_source) => {
to_csl_simple_script_source(simple_script_source)?
}
None => return Err(JsError::from_str("Missing ")),
};
vote_builder.add_with_native_script(
&voter,
&csl::GovernanceActionId::new(
&csl::TransactionHash::from_hex(
&simple_script_vote.vote.gov_action_id.tx_hash,
)?,
simple_script_vote.vote.gov_action_id.tx_index,
),
&voting_procedure,
&csl_simple_script_source,
)?
}
};
Ok(())
}

pub fn add_invalid_before(&mut self, invalid_before: u64) {
self.tx_builder
.set_validity_start_interval_bignum(to_bignum(invalid_before));
Expand Down
Loading

0 comments on commit 6b2efbb

Please sign in to comment.