Skip to content

Commit fdac879

Browse files
committed
test: complete coverage of id module
1 parent 1d9619d commit fdac879

4 files changed

Lines changed: 215 additions & 3 deletions

File tree

codecov.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ codecov:
44
coverage:
55
precision: 1
66
round: nearest
7-
range: "0...95"
7+
range: "0...80"
88
status:
99
project:
1010
default:

commit_verify/src/digest.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,23 @@ pub trait DigestExt<const BYTE_LEN: usize = 32>: Digest {
3535
/// Digest raw byte slice.
3636
fn input_raw(&mut self, data: &[u8]);
3737

38+
/// Digest raw byte slice returning self.
39+
fn with_raw(mut self, data: &[u8]) -> Self
40+
where Self: Sized {
41+
self.input_raw(data);
42+
self
43+
}
44+
45+
/// Digest bytes, adding the data length to the digest (preventing length
46+
/// extension attack).
47+
///
48+
/// Returns self.
49+
fn with_len<const MAX: usize>(mut self, data: &[u8]) -> Self
50+
where Self: Sized {
51+
self.input_with_len::<MAX>(data);
52+
self
53+
}
54+
3855
/// Digest bytes, adding the data length to the digest (preventing length
3956
/// extension attack).
4057
fn input_with_len<const MAX: usize>(&mut self, data: &[u8]) {

commit_verify/src/id.rs

Lines changed: 190 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,13 @@ impl CommitEngine {
121121
debug_assert!(
122122
Some(&fqn.name) != MerkleHash::strict_name().as_ref() ||
123123
fqn.lib.as_str() != MerkleHash::STRICT_LIB_NAME,
124-
"do not use commit_to_serialized for merklized collections, use commit_to_merkle \
124+
"do not use `commit_to_serialized` for merklized collections, use `commit_to_merkle` \
125125
instead"
126126
);
127127
debug_assert!(
128128
Some(&fqn.name) != StrictHash::strict_name().as_ref() ||
129129
fqn.lib.as_str() != StrictHash::STRICT_LIB_NAME,
130-
"do not use commit_to_serialized for StrictHash types, use commit_to_hash instead"
130+
"do not use `commit_to_serialized` for StrictHash types, use `commit_to_hash` instead"
131131
);
132132
self.layout
133133
.push(CommitStep::Serialized(fqn))
@@ -405,3 +405,191 @@ impl CommitmentId for StrictHash {
405405
impl From<Sha256> for StrictHash {
406406
fn from(hash: Sha256) -> Self { hash.finish().into() }
407407
}
408+
409+
#[cfg(test)]
410+
mod tests {
411+
#![cfg_attr(coverage_nightly, coverage(off))]
412+
use super::*;
413+
414+
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default)]
415+
#[derive(StrictType, StrictEncode, StrictDecode)]
416+
#[strict_type(lib = "Test")]
417+
struct DumbConceal(u8);
418+
419+
impl Conceal for DumbConceal {
420+
type Concealed = DumbHash;
421+
fn conceal(&self) -> Self::Concealed { DumbHash(0xFF - self.0) }
422+
}
423+
424+
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default)]
425+
#[derive(StrictType, StrictEncode, StrictDecode)]
426+
#[strict_type(lib = "Test")]
427+
#[derive(CommitEncode)]
428+
#[commit_encode(crate = self, strategy = strict, id = StrictHash)]
429+
struct DumbHash(u8);
430+
431+
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default)]
432+
#[derive(StrictType, StrictEncode, StrictDecode)]
433+
#[strict_type(lib = "Test")]
434+
#[derive(CommitEncode)]
435+
#[commit_encode(crate = self, strategy = strict, id = MerkleHash)]
436+
struct DumbMerkle(u8);
437+
438+
#[test]
439+
fn commit_engine_strict() {
440+
let val = 123u64;
441+
let mut engine = CommitEngine::new("test");
442+
engine.commit_to_serialized(&val);
443+
engine.set_finished();
444+
let (id, layout) = engine.finish_layout();
445+
assert_eq!(layout, tiny_vec![CommitStep::Serialized(TypeFqn::from("_.U64"))]);
446+
assert_eq!(
447+
id.finish(),
448+
Sha256::from_tag("test")
449+
.with_raw(&val.to_le_bytes())
450+
.finish()
451+
);
452+
}
453+
454+
#[test]
455+
fn commit_engine_option() {
456+
let val = Some(128u64);
457+
let mut engine = CommitEngine::new("test");
458+
engine.commit_to_option(&val);
459+
engine.set_finished();
460+
let (id, layout) = engine.finish_layout();
461+
assert_eq!(layout, tiny_vec![CommitStep::Serialized(TypeFqn::from("_.U64"))]);
462+
assert_eq!(
463+
id.finish(),
464+
Sha256::from_tag("test")
465+
.with_raw(b"\x01\x80\x00\x00\x00\x00\x00\x00\x00")
466+
.finish()
467+
);
468+
}
469+
470+
#[test]
471+
fn commit_engine_conceal() {
472+
let val = DumbConceal(123);
473+
let mut engine = CommitEngine::new("test");
474+
engine.commit_to_concealed(&val);
475+
engine.set_finished();
476+
let (id, layout) = engine.finish_layout();
477+
assert_eq!(layout, tiny_vec![CommitStep::Concealed(TypeFqn::from("Test.DumbConceal"))]);
478+
assert_eq!(
479+
id.finish(),
480+
Sha256::from_tag("test")
481+
.with_raw(&(0xFF - val.0).to_le_bytes())
482+
.finish()
483+
);
484+
}
485+
486+
#[test]
487+
fn commit_engine_hash() {
488+
let val = DumbHash(10);
489+
let mut engine = CommitEngine::new("test");
490+
engine.commit_to_hash(&val);
491+
engine.set_finished();
492+
let (id, layout) = engine.finish_layout();
493+
assert_eq!(layout, tiny_vec![CommitStep::Hashed(TypeFqn::from("Test.DumbHash"))]);
494+
assert_eq!(
495+
id.finish(),
496+
Sha256::from_tag("test")
497+
.with_raw(val.commit_id().as_slice())
498+
.finish()
499+
);
500+
}
501+
502+
#[test]
503+
fn commit_engine_merkle() {
504+
let val = [DumbMerkle(1), DumbMerkle(2), DumbMerkle(3), DumbMerkle(4)];
505+
let mut engine = CommitEngine::new("test");
506+
engine.commit_to_merkle(&val);
507+
engine.set_finished();
508+
let (id, layout) = engine.finish_layout();
509+
assert_eq!(layout, tiny_vec![CommitStep::Merklized(TypeFqn::from("Test.DumbMerkle"))]);
510+
assert_eq!(
511+
id.finish(),
512+
Sha256::from_tag("test")
513+
.with_raw(MerkleHash::merklize(&val).as_slice())
514+
.finish()
515+
);
516+
}
517+
518+
#[test]
519+
fn commit_engine_list() {
520+
let val = tiny_vec![0, 1, 2u8];
521+
let mut engine = CommitEngine::new("test");
522+
engine.commit_to_linear_list(&val);
523+
engine.set_finished();
524+
let (id, layout) = engine.finish_layout();
525+
assert_eq!(layout, tiny_vec![CommitStep::Collection(
526+
CommitColType::List,
527+
Sizing::new(0, 0xFF),
528+
TypeFqn::from("_.U8")
529+
)]);
530+
assert_eq!(
531+
id.finish(),
532+
Sha256::from_tag("test")
533+
.with_len::<0xFF>(b"\x00\x01\x02")
534+
.finish()
535+
);
536+
}
537+
538+
#[test]
539+
fn commit_engine_set() {
540+
let val = tiny_bset![0, 1, 2u8];
541+
let mut engine = CommitEngine::new("test");
542+
engine.commit_to_linear_set(&val);
543+
engine.set_finished();
544+
let (id, layout) = engine.finish_layout();
545+
assert_eq!(layout, tiny_vec![CommitStep::Collection(
546+
CommitColType::Set,
547+
Sizing::new(0, 0xFF),
548+
TypeFqn::from("_.U8")
549+
)]);
550+
assert_eq!(
551+
id.finish(),
552+
Sha256::from_tag("test")
553+
.with_len::<0xFF>(b"\x00\x01\x02")
554+
.finish()
555+
);
556+
}
557+
558+
#[test]
559+
fn commit_engine_map() {
560+
let val = tiny_bmap! {0 => tn!("A"), 1 => tn!("B"), 2u8 => tn!("C")};
561+
let mut engine = CommitEngine::new("test");
562+
engine.commit_to_linear_map(&val);
563+
engine.set_finished();
564+
let (id, layout) = engine.finish_layout();
565+
assert_eq!(layout, tiny_vec![CommitStep::Collection(
566+
CommitColType::Map {
567+
key: TypeFqn::from("_.U8")
568+
},
569+
Sizing::new(0, 0xFF),
570+
TypeFqn::from("StrictTypes.TypeName")
571+
)]);
572+
assert_eq!(
573+
id.finish(),
574+
Sha256::from_tag("test")
575+
.with_raw(b"\x03\x00\x01A\x01\x01B\x02\x01C")
576+
.finish()
577+
);
578+
}
579+
580+
#[test]
581+
#[should_panic]
582+
fn commit_engine_reject_hash() {
583+
let val = StrictHash::strict_dumb();
584+
let mut engine = CommitEngine::new("test");
585+
engine.commit_to_serialized(&val);
586+
}
587+
588+
#[test]
589+
#[should_panic]
590+
fn commit_engine_reject_merkle() {
591+
let val = MerkleHash::strict_dumb();
592+
let mut engine = CommitEngine::new("test");
593+
engine.commit_to_serialized(&val);
594+
}
595+
}

commit_verify/src/merkle.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,13 @@ pub trait MerkleLeaves {
229229
fn merkle_leaves(&self) -> impl ExactSizeIterator<Item = &Self::Leaf>;
230230
}
231231

232+
impl<T, const LEN: usize> MerkleLeaves for [T; LEN]
233+
where T: CommitId<CommitmentId = MerkleHash>
234+
{
235+
type Leaf = T;
236+
fn merkle_leaves(&self) -> impl ExactSizeIterator<Item = &T> { self.iter() }
237+
}
238+
232239
impl<T, const MIN: usize> MerkleLeaves for Confined<Vec<T>, MIN, { u8::MAX as usize }>
233240
where T: CommitId<CommitmentId = MerkleHash>
234241
{

0 commit comments

Comments
 (0)