Skip to content

Commit

Permalink
fix serialization issue for merkleized cases
Browse files Browse the repository at this point in the history
  • Loading branch information
OlofBlomqvist committed Jul 17, 2023
1 parent 5e5eec6 commit 8ab6f3a
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 47 deletions.
15 changes: 12 additions & 3 deletions grammar.pest
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,18 @@ Action = _{ ActionHole | Notify | Choice | Deposit }
Choice = { lpar ~"Choice" ~ ChoiceId ~ ArrayOfBounds ~ rpar }
Notify = { lpar ~"Notify" ~ Observation ~ rpar }

Case = {
lpar ~ "Case" ~ Action ~ WrappedContract ~ rpar
| "Case" ~ Action ~ WrappedContract

PossiblyMerkleizedContract = _{ContractHole|NonMerkleizedContract|MerkleizedContract}
NonMerkleizedContract = { WrappedContract }
MerkleizedContract = {
lpar ~ "MerkleizedThen" ~ quoted_string ~ rpar
| "MerkleizedThen" ~ quoted_string
}

Case = {
lpar ~ "Case" ~ Action ~ PossiblyMerkleizedContract ~ rpar
| "Case" ~ Action ~ PossiblyMerkleizedContract

}

Bound = ${
Expand Down
22 changes: 18 additions & 4 deletions src/lib/parsing/marlowe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,23 @@ pub(crate) fn parse_raw_inner(pair:Pair<Rule>,input:HashMap<String,i64>) -> Resu
macro_rules! try_get_next { () => { (get_next_node(&mut current_operation))};}
macro_rules! get_next { () => { try_get_next!()? } }
macro_rules! get_next_into { () => { get_next!().try_into()? };}
match current_operation.pair_rule_type {
match current_operation.pair_rule_type {
Rule::Contract => fold_back!(get_next!()),
Rule::MerkleizedContract => {
let hash : String = get_next_into!();
fold_back!(
AstNode::MarlowePossiblyMerkleizedContract(PossiblyMerkleizedContract::Merkleized(hash))
);
},
Rule::NonMerkleizedContract => {
let contract : Contract = get_next_into!();

fold_back!(
AstNode::MarlowePossiblyMerkleizedContract(PossiblyMerkleizedContract::Raw(Box::new(contract)))
);
},
Rule::PossiblyMerkleizedContract => fold_back!(get_next!()),

Rule::Close => fold_back!(AstNode::MarloweContract(Contract::Close)),
Rule::UseValue => fold_back!(AstNode::MarloweValue(Value::UseValue(get_next_into!()))),
Rule::ConstantParam => {
Expand Down Expand Up @@ -162,10 +177,10 @@ pub(crate) fn parse_raw_inner(pair:Pair<Rule>,input:HashMap<String,i64>) -> Resu
notify_if: get_next_node(&mut current_operation)?.try_into()? })),
Rule::Case => {
let continuation_contract = get_next!();
let contract_node : Option<Contract> = continuation_contract.try_into()?;
let contract_node : Option<PossiblyMerkleizedContract> = continuation_contract.try_into()?;
let contract_node =
match contract_node {
Some(c) => Some(PossiblyMerkleizedContract::Raw(Box::new(c))),
Some(c) => Some(c),
None => None,
};
let action = get_next_into!();
Expand Down Expand Up @@ -421,7 +436,6 @@ pub(crate) fn parse_raw_inner(pair:Pair<Rule>,input:HashMap<String,i64>) -> Resu
uninitialized_const_params.dedup();
uninitialized_time_params.sort();
uninitialized_time_params.dedup();

match result_stack.pop() {
Some(v) => {
parties.sort_by_key(|x|format!("{x:?}"));
Expand Down
13 changes: 11 additions & 2 deletions src/lib/serialization/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ where
actual_contract.serialize(serializer)
},
PossiblyMerkleizedContract::Merkleized(s) => {
serializer.serialize_str(&format!("MerkleizedContinuation(\"{s}\")"))
serializer.serialize_str(&format!("(\"{s}\")"))
},
}
}
Expand Down Expand Up @@ -260,7 +260,16 @@ where
return Err(serde::ser::Error::custom(format!("A case is not fully initialized. Missing action or continuation contract.")))
}
let mut s = serializer.serialize_struct("case", 2)?;
s.serialize_field("then", &self.then)?;
match &self.then {
Some(m) =>
match m {
PossiblyMerkleizedContract::Raw(raw_contract) => s.serialize_field("then", raw_contract)?,
PossiblyMerkleizedContract::Merkleized(hash) => s.serialize_field("merkleized_then", hash)?
}

None =>
s.serialize_field("then", &self.then)?,
}
s.serialize_field("case", &self.case)?;
s.end()
}
Expand Down
12 changes: 10 additions & 2 deletions src/lib/serialization/marlowe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl std::fmt::Display for PossiblyMerkleizedContract {
write!(f,"{actual_contract}")
},
PossiblyMerkleizedContract::Merkleized(bytestring) => {
write!(f,"MerkleizedContinuation(\"{bytestring}\")")
write!(f,"\"{bytestring}\"")
},
}
}
Expand Down Expand Up @@ -282,7 +282,15 @@ impl std::fmt::Display for Case {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "(Case {} {})",
match &self.case {None=>"?action".to_string(),Some(v)=>format!("{v}")},
match &self.then {None=>"?contract".to_string(),Some(v)=>format!("{v}")},
match &self.then {
None=>"?contract".to_string(),
Some(v)=> {
match &v {
PossiblyMerkleizedContract::Raw(c) => format!("{c}"),
PossiblyMerkleizedContract::Merkleized(hash) => format!("(MerkleizedThen \"{hash}\")"),
}
}
},
)
}
}
Expand Down
119 changes: 83 additions & 36 deletions src/lib/types/marlowe.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::HashMap;
use std::fmt::Display;
use std::ops::Deref;
use serde::Deserialize;
use serde::Serialize;

Expand Down Expand Up @@ -33,8 +34,8 @@ pub enum AstNode {
MarloweObservation(crate::types::marlowe::Observation),
MarlowePayee(crate::types::marlowe::Payee),
MarloweChoiceId(crate::types::marlowe::ChoiceId),
MarloweNumber(i64),
//MarlowePossiblyMerkleizedContract(PossiblyMerkleizedContract),
MarloweNumber(i64),
MarlowePossiblyMerkleizedContract(crate::types::marlowe::PossiblyMerkleizedContract),
Null
}

Expand Down Expand Up @@ -469,6 +470,9 @@ Impl_From_For!(@Contract,MarloweContract);
Impl_From_For!(@i64,MarloweNumber);
Impl_From_For!(@Observation,MarloweObservation);
Impl_From_For!(@ValueId,MarloweValueId);
Impl_From_For!(@PossiblyMerkleizedContract,MarlowePossiblyMerkleizedContract);



pub(crate) fn walk_any<T>(x:T,f:&mut dyn FnMut(&AstNode)) -> () where crate::types::marlowe::AstNode: From<T> {
walk(&x.into(),f);
Expand All @@ -490,41 +494,85 @@ pub(crate) fn walk(
Party::Role { role_token:_ } => {},
}
}
AstNode::MarloweContract(x) => match x {
Contract::Pay { from_account:Some(a), to:Some(b), token:Some(c), pay:Some(d), then:Some(e) } => {
walk_any(a,func);
walk_any(b,func);
walk_any(c,func);
walk_any(d,func);
walk_any(e,func);
},
Contract::If { x_if:Some(a), then:Some(b), x_else:Some(c) } => {
walk_any(a,func);
walk_any(b,func);
walk_any(c,func);
},
Contract::When { when, timeout:Some(b), timeout_continuation:Some(c) } => {
for x in when {
if let Some(case) = x {
walk_any(case,func)
AstNode::MarloweContract(x) => {
match x {
Contract::Pay { from_account:Some(a), to:Some(b), token:Some(c), pay:Some(d), then:Some(e) } => {
walk_any(a,func);
walk_any(b,func);
walk_any(c,func);
walk_any(d,func);
walk_any(e,func);
},
Contract::If { x_if:Some(a), then:Some(b), x_else:Some(c) } => {
walk_any(a,func);
walk_any(b,func);
walk_any(c,func);
},
Contract::When { when, timeout:Some(b), timeout_continuation:Some(c) } => {
for x in when {
if let Some(case) = x {
walk_any(case,func)
}
}
walk_any(b,func);
walk_any(c,func);
},
Contract::Let { x_let, be:Some(a), then:Some(b) } => {
walk_any(x_let,func);
walk_any(a,func);
walk_any(b,func);

},
Contract::Assert { assert:Some(a), then:Some(b) } => {
walk_any(a,func);
walk_any(b,func);
},
Contract::Close => {},
_ => {
//panic!("BAD CONTRACT: {c:?}")
}
walk_any(b,func);
walk_any(c,func);
},
Contract::Let { x_let, be:Some(a), then:Some(b) } => {
walk_any(x_let,func);
walk_any(a,func);
walk_any(b,func);

},
Contract::Assert { assert:Some(a), then:Some(b) } => {
walk_any(a,func);
walk_any(b,func);
},
Contract::Close => {},
_ => {
//panic!("BAD CONTRACT: {c:?}")
}
},
AstNode::MarlowePossiblyMerkleizedContract(x) => {
match x {
PossiblyMerkleizedContract::Raw(raw) => match raw.deref() {
Contract::Pay { from_account:Some(a), to:Some(b), token:Some(c), pay:Some(d), then:Some(e) } => {
walk_any(a,func);
walk_any(b,func);
walk_any(c,func);
walk_any(d,func);
walk_any(e,func);
},
Contract::If { x_if:Some(a), then:Some(b), x_else:Some(c) } => {
walk_any(a,func);
walk_any(b,func);
walk_any(c,func);
},
Contract::When { when, timeout:Some(b), timeout_continuation:Some(c) } => {
for x in when {
if let Some(case) = x {
walk_any(case,func)
}
}
walk_any(b,func);
walk_any(c,func);
},
Contract::Let { x_let, be:Some(a), then:Some(b) } => {
walk_any(x_let,func);
walk_any(a,func);
walk_any(b,func);

},
Contract::Assert { assert:Some(a), then:Some(b) } => {
walk_any(a,func);
walk_any(b,func);
},
Contract::Close => {},
_ => {
//panic!("BAD CONTRACT: {c:?}")
}
},
PossiblyMerkleizedContract::Merkleized(_) => {},
}
},
AstNode::MarloweCaseList(x) => {
Expand Down Expand Up @@ -909,7 +957,6 @@ impl Contract {
} else {
vec![]
};

match &x.then {
Some(PossiblyMerkleizedContract::Raw(c)) => get_from_contract(&c,action_fields),
_ => action_fields
Expand Down

0 comments on commit 8ab6f3a

Please sign in to comment.