Skip to content

Commit

Permalink
feat: add native-script verify function (#332)
Browse files Browse the repository at this point in the history
* feat: add native-script verify function
  • Loading branch information
hadelive authored Jun 11, 2024
1 parent 255500b commit 4299c23
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 16 deletions.
5 changes: 2 additions & 3 deletions chain/rust/src/builders/tx_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,13 +720,12 @@ impl TransactionBuilder {

match &script_witness.script {
PlutusScriptWitness::Ref(ref_script) => {
if self
if !self
.witness_builders
.witness_set_builder
.required_wits
.script_refs
.get(ref_script)
.is_none()
.contains(ref_script)
{
Err(TxBuilderError::RefScriptNotFound(
*ref_script,
Expand Down
6 changes: 3 additions & 3 deletions chain/rust/src/builders/witness_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ impl TransactionWitnessSetBuilder {
pub fn get_native_script(&self) -> Vec<NativeScript> {
self.scripts
.iter()
.filter(|entry| self.required_wits.script_refs.get(entry.0).is_none())
.filter(|entry| !self.required_wits.script_refs.contains(entry.0))
.fold(
Vec::<NativeScript>::new(),
|mut acc, script| match &script.1 {
Expand All @@ -291,7 +291,7 @@ impl TransactionWitnessSetBuilder {
pub fn get_plutus_v1_script(&self) -> Vec<PlutusV1Script> {
self.scripts
.iter()
.filter(|entry| self.required_wits.script_refs.get(entry.0).is_none())
.filter(|entry| !self.required_wits.script_refs.contains(entry.0))
.fold(
Vec::<PlutusV1Script>::new(),
|mut acc, script| match &script.1 {
Expand All @@ -307,7 +307,7 @@ impl TransactionWitnessSetBuilder {
pub fn get_plutus_v2_script(&self) -> Vec<PlutusV2Script> {
self.scripts
.iter()
.filter(|entry| self.required_wits.script_refs.get(entry.0).is_none())
.filter(|entry| !self.required_wits.script_refs.contains(entry.0))
.fold(
Vec::<PlutusV2Script>::new(),
|mut acc, script| match &script.1 {
Expand Down
55 changes: 53 additions & 2 deletions chain/rust/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use cbor_event::{de::Deserializer, se::Serializer, Sz};
use cml_core::{
error::{DeserializeError, DeserializeFailure},
serialization::{fit_sz, sz_max, Deserialize, LenEncoding, Serialize},
Int,
Int, Slot,
};
use cml_crypto::{RawBytesEncoding, ScriptHash};
use cml_crypto::{Ed25519KeyHash, RawBytesEncoding, ScriptHash};
use derivative::Derivative;
use std::io::{BufRead, Seek, Write};
use std::iter::IntoIterator;
Expand Down Expand Up @@ -41,6 +41,57 @@ impl NativeScript {
pub fn hash(&self) -> ScriptHash {
hash_script(ScriptHashNamespace::NativeScript, &self.to_cbor_bytes())
}

pub fn verify(
&self,
lower_bound: Option<Slot>,
upper_bound: Option<Slot>,
key_hashes: &Vec<Ed25519KeyHash>,
) -> bool {
fn verify_helper(
script: &NativeScript,
lower_bound: Option<Slot>,
upper_bound: Option<Slot>,
key_hashes: &Vec<Ed25519KeyHash>,
) -> bool {
match &script {
NativeScript::ScriptPubkey(pub_key) => {
key_hashes.contains(&pub_key.ed25519_key_hash)
}
NativeScript::ScriptAll(script_all) => {
script_all.native_scripts.iter().all(|sub_script| {
verify_helper(sub_script, lower_bound, upper_bound, key_hashes)
})
}
NativeScript::ScriptAny(script_any) => {
script_any.native_scripts.iter().any(|sub_script| {
verify_helper(sub_script, lower_bound, upper_bound, key_hashes)
})
}
NativeScript::ScriptNOfK(script_atleast) => {
script_atleast
.native_scripts
.iter()
.map(|sub_script| {
verify_helper(sub_script, lower_bound, upper_bound, key_hashes)
})
.filter(|r| *r)
.count()
>= script_atleast.n as usize
}
NativeScript::ScriptInvalidBefore(timelock_start) => match lower_bound {
Some(tx_slot) => tx_slot >= timelock_start.before,
_ => false,
},
NativeScript::ScriptInvalidHereafter(timelock_expiry) => match upper_bound {
Some(tx_slot) => tx_slot < timelock_expiry.after,
_ => false,
},
}
}

verify_helper(self, lower_bound, upper_bound, key_hashes)
}
}

impl From<NativeScript> for Script {
Expand Down
1 change: 0 additions & 1 deletion chain/wasm/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use cml_crypto_wasm::{
AuxiliaryDataHash, DatumHash, Ed25519KeyHash, ScriptDataHash, TransactionHash,
};
use wasm_bindgen::prelude::{wasm_bindgen, JsError, JsValue};

pub mod utils;

#[derive(Clone, Debug)]
Expand Down
10 changes: 10 additions & 0 deletions chain/wasm/src/transaction/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
utils::LanguageList,
Ed25519KeyHashList, NativeScript, Value,
};
use cml_core::Slot;
use cml_crypto_wasm::{DatumHash, ScriptHash};
use wasm_bindgen::prelude::wasm_bindgen;

Expand Down Expand Up @@ -68,6 +69,15 @@ impl NativeScript {
pub fn hash(&self) -> ScriptHash {
self.0.hash().into()
}

pub fn verify(
&self,
lower_bound: Option<Slot>,
upper_bound: Option<Slot>,
key_hashes: &Ed25519KeyHashList,
) -> bool {
self.0.verify(lower_bound, upper_bound, key_hashes.as_ref())
}
}

#[wasm_bindgen]
Expand Down
6 changes: 3 additions & 3 deletions multi-era/rust/src/alonzo/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ impl From<AlonzoAuxiliaryData> for AuxiliaryData {
AlonzoAuxiliaryData::ShelleyMA(md) => AuxiliaryData::new_shelley_m_a(md.clone()),
AlonzoAuxiliaryData::Alonzo(md) => AuxiliaryData::new_conway({
let mut conway = ConwayFormatAuxData::new();
conway.metadata = md.metadata.clone();
conway.native_scripts = md.native_scripts.clone();
conway.plutus_v1_scripts = md.plutus_v1_scripts.clone();
conway.metadata.clone_from(&md.metadata);
conway.native_scripts.clone_from(&md.native_scripts);
conway.plutus_v1_scripts.clone_from(&md.plutus_v1_scripts);
conway
}),
}
Expand Down
8 changes: 4 additions & 4 deletions multi-era/rust/src/babbage/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ impl From<BabbageAuxiliaryData> for AuxiliaryData {
BabbageAuxiliaryData::ShelleyMA(md) => AuxiliaryData::new_shelley_m_a(md.clone()),
BabbageAuxiliaryData::Babbage(md) => AuxiliaryData::new_conway({
let mut conway = ConwayFormatAuxData::new();
conway.metadata = md.metadata.clone();
conway.native_scripts = md.native_scripts.clone();
conway.plutus_v1_scripts = md.plutus_v1_scripts.clone();
conway.plutus_v2_scripts = md.plutus_v2_scripts.clone();
conway.metadata.clone_from(&md.metadata);
conway.native_scripts.clone_from(&md.native_scripts);
conway.plutus_v1_scripts.clone_from(&md.plutus_v1_scripts);
conway.plutus_v2_scripts.clone_from(&md.plutus_v2_scripts);
conway
}),
}
Expand Down

0 comments on commit 4299c23

Please sign in to comment.