Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ default-members = [
]

[workspace.package]
version = "0.12.0"
version = "0.12.1"
authors = ["Dr Maxim Orlovsky <[email protected]>"]
homepage = "https://github.com/LNP-BP"
repository = "https://github.com/LNP-BP/client_side_validation"
Expand All @@ -24,7 +24,7 @@ license = "Apache-2.0"
[workspace.dependencies]
amplify = "~4.9.0"
strict_encoding = "~2.9.1"
strict_types = "~2.9.0"
strict_types = "~2.9.1"
serde = { version = "1", features = ["derive"] }

[package]
Expand Down
6 changes: 3 additions & 3 deletions commit_verify/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ required-features = ["stl", "vesper"]
amplify = { workspace = true }
strict_encoding = { workspace = true }
strict_types = { workspace = true }
vesper-lang = "0.2.1"
vesper-lang = "0.2.3"
commit_encoding_derive = { version = "0.12.0", path = "derive" }
sha2 = "0.10.8"
ripemd = "0.1.3"
Expand All @@ -40,8 +40,8 @@ default = ["derive"]
all = ["rand", "derive", "stl", "vesper", "serde"]
derive = []
rand = ["dep:rand"]
stl = ["strict_types/armor"]
vesper = []
stl = ["strict_types/armor", "strict_types/stl"]
vesper = ["strict_types/vesper"]
serde = ["dep:serde", "amplify/serde"]

[target.'cfg(target_arch = "wasm32")'.dependencies]
Expand Down
2 changes: 1 addition & 1 deletion commit_verify/derive/src/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl CommitDerive {
},
StrategyAttr::ConcealStrict => quote! {
use #trait_crate::Conceal;
engine.commit_to_concealed(&self.conceal());
engine.commit_to_concealed(self);
},
StrategyAttr::Transparent => quote! {
use amplify::Wrapper;
Expand Down
32 changes: 23 additions & 9 deletions commit_verify/src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,12 @@ pub enum CommitStep {
Merklized(TypeFqn),

/// Serialization with [`CommitEngine::commit_to_concealed`].
Concealed(TypeFqn),
Concealed {
/// The source type to which the concealment is applied.
src: TypeFqn,
/// The destination type of the concealment.
dst: TypeFqn,
},
}

/// A helper engine used in computing commitment ids.
Expand Down Expand Up @@ -183,9 +188,13 @@ impl CommitEngine {
T: Conceal + StrictType,
T::Concealed: StrictEncode,
{
let fqn = commitment_fqn::<T>();
let src = commitment_fqn::<T>();
let dst = commitment_fqn::<T::Concealed>();
self.layout
.push(CommitStep::Concealed(fqn))
.push(CommitStep::Concealed {
src,
dst: dst.clone(),
})
.expect("too many fields for commitment");

let concealed = value.conceal();
Expand Down Expand Up @@ -311,6 +320,7 @@ pub trait CommitEncode {
#[derive(Getters, Clone, Eq, PartialEq, Hash, Debug)]
pub struct CommitLayout {
idty: TypeFqn,
ty: TypeFqn,
#[getter(as_copy)]
tag: &'static str,
fields: TinyVec<CommitStep>,
Expand Down Expand Up @@ -339,12 +349,13 @@ pub trait CommitmentLayout: CommitEncode {
}

impl<T> CommitmentLayout for T
where T: CommitEncode + StrictDumb
where T: CommitEncode + StrictType + StrictDumb
{
fn commitment_layout() -> CommitLayout {
let dumb = Self::strict_dumb();
let fields = dumb.commit().into_layout();
CommitLayout {
ty: commitment_fqn::<T>(),
idty: TypeFqn::with(
libname!(Self::CommitmentId::STRICT_LIB_NAME),
Self::CommitmentId::strict_name()
Expand Down Expand Up @@ -407,14 +418,14 @@ impl From<Sha256> for StrictHash {
}

#[cfg(test)]
mod tests {
pub(crate) mod tests {
#![cfg_attr(coverage_nightly, coverage(off))]
use super::*;

#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default)]
#[derive(StrictType, StrictEncode, StrictDecode)]
#[strict_type(lib = "Test")]
struct DumbConceal(u8);
pub struct DumbConceal(u8);

impl Conceal for DumbConceal {
type Concealed = DumbHash;
Expand All @@ -426,14 +437,14 @@ mod tests {
#[strict_type(lib = "Test")]
#[derive(CommitEncode)]
#[commit_encode(crate = self, strategy = strict, id = StrictHash)]
struct DumbHash(u8);
pub struct DumbHash(u8);

#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default)]
#[derive(StrictType, StrictEncode, StrictDecode)]
#[strict_type(lib = "Test")]
#[derive(CommitEncode)]
#[commit_encode(crate = self, strategy = strict, id = MerkleHash)]
struct DumbMerkle(u8);
pub struct DumbMerkle(u8);

#[test]
fn commit_engine_strict() {
Expand Down Expand Up @@ -474,7 +485,10 @@ mod tests {
engine.commit_to_concealed(&val);
engine.set_finished();
let (id, layout) = engine.finish_layout();
assert_eq!(layout, tiny_vec![CommitStep::Concealed(TypeFqn::from("Test.DumbConceal"))]);
assert_eq!(layout, tiny_vec![CommitStep::Concealed {
src: TypeFqn::from("Test.DumbConceal"),
dst: TypeFqn::from("Test.DumbHash")
},]);
assert_eq!(
id.finish(),
Sha256::from_tag("test")
Expand Down
112 changes: 96 additions & 16 deletions commit_verify/src/vesper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ pub type VesperCommit = TExpr<Pred>;
#[display(lowercase)]
pub enum Pred {
Commitment,
Serialized,
Hashed,
Merklized,
Concealed,
Serialize,
Hash,
Merklize,
Conceal,
List,
Set,
Element,
Expand All @@ -55,6 +55,7 @@ impl Predicate for Pred {

#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub enum Attr {
For(TypeFqn),
Tagged(&'static str),
Concealed(TypeFqn),
LenRange(LenRange),
Expand All @@ -74,15 +75,17 @@ impl Attribute for Attr {

fn name(&self) -> Option<Ident> {
match self {
Attr::For(_) => Some(ident!("for")),
Attr::Tagged(_) => Some(ident!("tagged")),
Attr::Concealed(_) => Some(ident!("concealed")),
Attr::Concealed { .. } => Some(ident!("to")),
Attr::LenRange(_) => Some(ident!("len")),
Attr::Hasher => Some(ident!("hasher")),
}
}

fn value(&self) -> AttrVal<Self::Expression> {
match self {
Attr::For(fqn) => AttrVal::Ident(fqn.name.to_ident()),
Attr::Tagged(tag) => AttrVal::Expr(AttrExpr::Tag(tag)),
Attr::Concealed(fqn) => AttrVal::Ident(fqn.name.to_ident()),
Attr::LenRange(range) => AttrVal::Expr(AttrExpr::LenRange(range.clone())),
Expand All @@ -98,28 +101,28 @@ impl CommitStep {
CommitStep::Collection(_, _, fqn) => fqn,
CommitStep::Hashed(fqn) => fqn,
CommitStep::Merklized(fqn) => fqn,
CommitStep::Concealed(fqn) => fqn,
CommitStep::Concealed { src, dst: _ } => src,
}
.name
.to_ident()
}

fn predicate(&self) -> Pred {
match self {
CommitStep::Serialized(_) => Pred::Serialized,
CommitStep::Serialized(_) => Pred::Serialize,
CommitStep::Collection(CommitColType::List, _, _) => Pred::List,
CommitStep::Collection(CommitColType::Set, _, _) => Pred::Set,
CommitStep::Collection(CommitColType::Map { .. }, _, _) => Pred::Map,
CommitStep::Hashed(_) => Pred::Hashed,
CommitStep::Merklized(_) => Pred::Merklized,
CommitStep::Concealed(_) => Pred::Concealed,
CommitStep::Hashed(_) => Pred::Hash,
CommitStep::Merklized(_) => Pred::Merklize,
CommitStep::Concealed { .. } => Pred::Conceal,
}
}

fn attributes(&self) -> SmallVec<Attr> {
match self {
CommitStep::Collection(_, sizing, _) => small_vec![Attr::LenRange((*sizing).into())],
CommitStep::Concealed(from) => small_vec![Attr::Concealed(from.clone())],
CommitStep::Concealed { src: _, dst } => small_vec![Attr::Concealed(dst.clone())],
CommitStep::Serialized(_) | CommitStep::Hashed(_) | CommitStep::Merklized(_) => none!(),
}
}
Expand Down Expand Up @@ -154,10 +157,17 @@ impl CommitStep {
})
]
}
CommitStep::Serialized(_) |
CommitStep::Hashed(_) |
CommitStep::Merklized(_) |
CommitStep::Concealed(_) => empty!(),
CommitStep::Serialized(_) => none!(),

CommitStep::Hashed(subj) |
CommitStep::Merklized(subj) |
CommitStep::Concealed { src: _, dst: subj } => tiny_vec![Box::new(VesperCommit {
subject: subj.name.to_ident(),
predicate: Pred::Serialize,
attributes: none!(),
content: none!(),
comment: None,
})],
}
}
}
Expand All @@ -182,9 +192,79 @@ impl CommitLayout {
VesperCommit {
subject,
predicate: Pred::Commitment,
attributes: small_vec![Attr::Hasher, Attr::Tagged(self.tag())],
attributes: small_vec![
Attr::For(self.ty().clone()),
Attr::Hasher,
Attr::Tagged(self.tag())
],
content: Confined::from_iter_checked(content),
comment: None,
}
}
}

#[cfg(test)]
mod tests {
#![cfg_attr(coverage_nightly, coverage(off))]

use amplify::confinement::{LargeString, SmallOrdMap, SmallOrdSet};
use strict_encoding::{StrictDecode, StrictEncode};

use super::*;
use crate::id::tests::*;
use crate::{CommitEncode, CommitEngine, CommitmentLayout, StrictHash};

#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default)]
#[derive(StrictType, StrictEncode, StrictDecode)]
#[strict_type(lib = "Test")]
struct NamedWrapper<T: Default + StrictEncode + StrictDecode>(T);

#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default)]
#[derive(StrictType, StrictEncode, StrictDecode)]
#[strict_type(lib = "Test")]
struct Test {
serialized: NamedWrapper<LargeString>,
concealed: DumbConceal,
hash: DumbHash,
merkle_list: TinyVec<DumbMerkle>,
set: SmallOrdSet<DumbHash>,
map: SmallOrdMap<u8, u64>,
}
impl CommitEncode for Test {
type CommitmentId = StrictHash;
fn commit_encode(&self, e: &mut CommitEngine) {
e.commit_to_serialized(&self.serialized);
e.commit_to_concealed(&self.concealed);
e.commit_to_hash(&self.hash);
e.commit_to_merkle(&self.merkle_list);
e.commit_to_linear_set(&self.set);
e.commit_to_linear_map(&self.map);
}
}

#[test]
fn display() {
let layout = Test::commitment_layout();
assert_eq!(
layout
.to_vesper()
.display()
.to_string()
.replace(" \n", "\n"),
r#"commitment StrictHash: for Test, hasher SHA256, tagged urn:ubideco:strict-types:value-hash#2024-02-10
serialize NamedWrapperConfinedString04294967295
conceal DumbConceal: to DumbHash
serialize DumbHash
hash DumbHash
serialize DumbHash
merklize DumbMerkle
serialize DumbMerkle
set DumbHash: len 0..<2^16
element DumbHash
map U64: len 0..<2^16
mapKey U8
mapValue U64
"#
);
}
}
Loading
Loading