Skip to content

Commit 1b1bfd8

Browse files
min
1 parent 1542f9b commit 1b1bfd8

2 files changed

Lines changed: 30 additions & 93 deletions

File tree

storage/src/qmdb/current/ordered/db.rs

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::{
99
merkle::{self, hasher::Standard as StandardHasher, Location},
1010
qmdb::{
1111
any::{
12-
ordered::{Operation, Update},
12+
ordered::{self, Operation, Update},
1313
ValueEncoding,
1414
},
1515
current::proof::OperationProof,
@@ -61,32 +61,6 @@ impl<F: merkle::Graftable, K: Key, D: Digest, const N: usize> Read for KeyValueP
6161
}
6262
}
6363

64-
impl<F: merkle::Graftable, K: Key, D: Digest, const N: usize> KeyValueProof<F, K, D, N> {
65-
/// Return true if this proof authenticates `operation` as the active key-value update.
66-
///
67-
/// This also checks that the proof's embedded `next_key` matches the provided operation, which
68-
/// is required when the operation is decoded separately from the proof.
69-
pub fn verify_operation<H, V>(
70-
&self,
71-
hasher: &StandardHasher<H>,
72-
operation: Operation<F, K, V>,
73-
root: &D,
74-
) -> bool
75-
where
76-
H: Hasher<Digest = D>,
77-
V: ValueEncoding,
78-
Operation<F, K, V>: Codec,
79-
{
80-
match &operation {
81-
Operation::Update(update) if self.next_key == update.next_key => {}
82-
Operation::Update(_) => return false,
83-
_ => return false,
84-
}
85-
86-
self.proof.verify(hasher, operation, root)
87-
}
88-
}
89-
9064
#[cfg(feature = "arbitrary")]
9165
impl<F: merkle::Graftable, K: Key, D: Digest, const N: usize> arbitrary::Arbitrary<'_>
9266
for KeyValueProof<F, K, D, N>
@@ -139,7 +113,7 @@ where
139113
proof: &KeyValueProof<F, K, H::Digest, N>,
140114
root: &H::Digest,
141115
) -> bool {
142-
proof.verify_operation(
116+
proof.proof.verify(
143117
hasher,
144118
Operation::Update(Update {
145119
key,
@@ -176,7 +150,30 @@ where
176150
proof: &super::ExclusionProof<F, K, V, H::Digest, N>,
177151
root: &H::Digest,
178152
) -> bool {
179-
proof.verify_key(hasher, key, root)
153+
let (op_proof, operation) = match proof {
154+
super::ExclusionProof::KeyValue(op_proof, update) => {
155+
if update.key == *key {
156+
// The provided `key` is in the DB if it matches the start of the span.
157+
return false;
158+
}
159+
if !ordered::span_contains(&update.key, &update.next_key, key) {
160+
// If the key is not within the span, then this proof cannot prove its
161+
// exclusion.
162+
return false;
163+
}
164+
165+
(op_proof, Operation::Update(update.clone()))
166+
}
167+
super::ExclusionProof::Commit(op_proof, metadata) => {
168+
// Handle the case where the proof shows the db is empty, hence any key is proven
169+
// excluded. For the db to be empty, the floor must equal the commit operation's
170+
// location.
171+
let floor = op_proof.loc;
172+
(op_proof, Operation::CommitFloor(metadata.clone(), floor))
173+
}
174+
};
175+
176+
op_proof.verify(hasher, operation, root)
180177
}
181178
}
182179

storage/src/qmdb/current/ordered/mod.rs

Lines changed: 4 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@
99
//! - [variable]: Variant for values of variable size.
1010
1111
use crate::{
12-
merkle::{hasher::Standard as StandardHasher, Graftable},
12+
merkle::Graftable,
1313
qmdb::{
1414
any::{
15-
ordered::{self, Operation, Update},
15+
ordered::Update,
1616
ValueEncoding,
1717
},
1818
current::proof::OperationProof,
1919
operation::Key,
2020
},
2121
};
2222
use bytes::{Buf, BufMut};
23-
use commonware_codec::{Codec, EncodeSize, Read, ReadExt as _, Write};
24-
use commonware_cryptography::{Digest, Hasher};
23+
use commonware_codec::{EncodeSize, Read, ReadExt as _, Write};
24+
use commonware_cryptography::Digest;
2525

2626
pub mod db;
2727
pub mod fixed;
@@ -49,43 +49,6 @@ pub enum ExclusionProof<F: Graftable, K: Key, V: ValueEncoding, D: Digest, const
4949
Commit(OperationProof<F, D, N>, Option<V::Value>),
5050
}
5151

52-
impl<F: Graftable, K: Key, V: ValueEncoding, D: Digest, const N: usize>
53-
ExclusionProof<F, K, V, D, N>
54-
where
55-
Operation<F, K, V>: Codec,
56-
{
57-
/// Return true if this proof authenticates that `key` is not active at `root`.
58-
pub fn verify_key<H>(&self, hasher: &StandardHasher<H>, key: &K, root: &D) -> bool
59-
where
60-
H: Hasher<Digest = D>,
61-
{
62-
let (op_proof, operation) = match self {
63-
Self::KeyValue(op_proof, update) => {
64-
if update.key == *key {
65-
// The provided `key` is in the DB if it matches the start of the span.
66-
return false;
67-
}
68-
if !ordered::span_contains(&update.key, &update.next_key, key) {
69-
// If the key is not within the span, then this proof cannot prove its
70-
// exclusion.
71-
return false;
72-
}
73-
74-
(op_proof, Operation::Update(update.clone()))
75-
}
76-
Self::Commit(op_proof, metadata) => {
77-
// Handle the case where the proof shows the db is empty, hence any key is proven
78-
// excluded. For the db to be empty, the floor must equal the commit operation's
79-
// location.
80-
let floor = op_proof.loc;
81-
(op_proof, Operation::CommitFloor(metadata.clone(), floor))
82-
}
83-
};
84-
85-
op_proof.verify(hasher, operation, root)
86-
}
87-
}
88-
8952
const KEY_VALUE_CONTEXT: u8 = 0;
9053
const COMMIT_CONTEXT: u8 = 1;
9154

@@ -627,16 +590,6 @@ pub mod tests {
627590
assert!(TestDb::<F, C, V>::verify_key_value_proof(
628591
&hasher, key, value, &proof, &root
629592
));
630-
assert!(proof.verify_operation(
631-
&hasher,
632-
Operation::Update(Update {
633-
key,
634-
value,
635-
next_key: proof.next_key,
636-
}),
637-
&root
638-
));
639-
assert!(!proof.verify_operation(&hasher, Operation::Delete(key), &root));
640593
// Proof should fail against the wrong value. Use hash instead of fill to ensure
641594
// the value differs from any key/value created by TestKey::from_seed (which uses
642595
// fill patterns).
@@ -664,15 +617,6 @@ pub mod tests {
664617
assert!(!TestDb::<F, C, V>::verify_key_value_proof(
665618
&hasher, key, value, &bad_proof, &root,
666619
));
667-
assert!(!proof.verify_operation(
668-
&hasher,
669-
Operation::Update(Update {
670-
key,
671-
value,
672-
next_key: wrong_key,
673-
}),
674-
&root
675-
));
676620
}
677621

678622
db.destroy().await.unwrap();
@@ -764,7 +708,6 @@ pub mod tests {
764708
&empty_proof,
765709
&empty_root,
766710
));
767-
assert!(empty_proof.verify_key(&hasher, &key_exists_1, &empty_root));
768711

769712
// Add `key_exists_1` and test exclusion proving over the single-key database case.
770713
let v1 = Sha256::fill(0xA1);
@@ -797,7 +740,6 @@ pub mod tests {
797740
&proof,
798741
&root,
799742
));
800-
assert!(proof.verify_key(&hasher, &greater_key, &root));
801743
assert!(TestDb::<F, C, V>::verify_exclusion_proof(
802744
&hasher,
803745
&lesser_key,
@@ -811,7 +753,6 @@ pub mod tests {
811753
&proof,
812754
&root,
813755
));
814-
assert!(!proof.verify_key(&hasher, &key_exists_1, &root));
815756

816757
// Add a second key and test exclusion proving over the two-key database case.
817758
let key_exists_2 = Sha256::fill(0x30);
@@ -873,7 +814,6 @@ pub mod tests {
873814
&proof,
874815
&root,
875816
));
876-
assert!(proof.verify_key(&hasher, &middle_key, &root));
877817
assert!(!TestDb::<F, C, V>::verify_exclusion_proof(
878818
&hasher,
879819
&key_exists_2,

0 commit comments

Comments
 (0)