This commit is contained in:
Peter Zhang 2025-09-08 15:19:41 +08:00
parent 4430ab2aca
commit 5dbab01534
4 changed files with 31 additions and 58 deletions

View File

@ -47,7 +47,7 @@ impl OptionalHash {
/// Convert a Proof<OptionalHash> to Proof<H256> /// Convert a Proof<OptionalHash> to Proof<H256>
pub fn convert_proof_to_h256(proof: Proof<OptionalHash>) -> Result<Proof<H256>, anyhow::Error> { pub fn convert_proof_to_h256(proof: Proof<OptionalHash>) -> Result<Proof<H256>, anyhow::Error> {
let lemma: Vec<H256> = proof let lemma = proof
.lemma() .lemma()
.iter() .iter()
.map(|oh| oh.to_h256_or_zero()) .map(|oh| oh.to_h256_or_zero())
@ -60,7 +60,7 @@ impl OptionalHash {
pub fn convert_proof_from_h256( pub fn convert_proof_from_h256(
proof: Proof<H256>, proof: Proof<H256>,
) -> Result<Proof<OptionalHash>, anyhow::Error> { ) -> Result<Proof<OptionalHash>, anyhow::Error> {
let lemma: Vec<OptionalHash> = proof let lemma = proof
.lemma() .lemma()
.iter() .iter()
.map(|h| OptionalHash::some(*h)) .map(|h| OptionalHash::some(*h))
@ -101,9 +101,10 @@ impl From<OptionalHash> for Option<H256> {
impl AsRef<[u8]> for OptionalHash { impl AsRef<[u8]> for OptionalHash {
fn as_ref(&self) -> &[u8] { fn as_ref(&self) -> &[u8] {
static ZERO_BYTES: [u8; 32] = [0u8; 32];
match &self.0 { match &self.0 {
Some(hash) => hash.as_ref(), Some(hash) => hash.as_ref(),
None => &[0u8; 32], // Return zeros for null hash None => &ZERO_BYTES, // Return reference to static zeros for null hash
} }
} }
} }
@ -123,24 +124,17 @@ impl Encode for OptionalHash {
} }
fn ssz_fixed_len() -> usize { fn ssz_fixed_len() -> usize {
33 // 1 byte for Some/None + 32 bytes for hash 32 // Same as H256 - just 32 bytes, no flag byte
} }
fn ssz_bytes_len(&self) -> usize { fn ssz_bytes_len(&self) -> usize {
33 32
} }
fn ssz_append(&self, buf: &mut Vec<u8>) { fn ssz_append(&self, buf: &mut Vec<u8>) {
match &self.0 { // Use H256::zero() for None, actual hash for Some
Some(hash) => { let hash = self.0.unwrap_or_else(H256::zero);
buf.push(1); // Some discriminant hash.ssz_append(buf);
hash.ssz_append(buf);
}
None => {
buf.push(0); // None discriminant
buf.extend_from_slice(&[0u8; 32]);
}
}
} }
} }
@ -150,27 +144,21 @@ impl Decode for OptionalHash {
} }
fn ssz_fixed_len() -> usize { fn ssz_fixed_len() -> usize {
33 32 // Same as H256
} }
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, ssz::DecodeError> { fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, ssz::DecodeError> {
if bytes.len() != 33 { if bytes.len() != 32 {
return Err(ssz::DecodeError::InvalidByteLength { return Err(ssz::DecodeError::InvalidByteLength {
len: bytes.len(), len: bytes.len(),
expected: 33, expected: 32,
}); });
} }
match bytes[0] { let hash = H256::from_ssz_bytes(bytes)?;
0 => Ok(OptionalHash::none()), // If it's H256::zero(), treat it as None, otherwise Some
1 => {
let hash = H256::from_ssz_bytes(&bytes[1..])?; Ok(OptionalHash::some(hash))
Ok(OptionalHash::some(hash))
}
_ => Err(ssz::DecodeError::BytesInvalid(
"Invalid discriminant for OptionalHash".to_string(),
)),
}
} }
} }

View File

@ -54,12 +54,18 @@ impl Algorithm<H256> for Sha3Algorithm {
impl Algorithm<OptionalHash> for Sha3Algorithm { impl Algorithm<OptionalHash> for Sha3Algorithm {
fn parent(left: &OptionalHash, right: &OptionalHash) -> OptionalHash { fn parent(left: &OptionalHash, right: &OptionalHash) -> OptionalHash {
match (&left.0, &right.0) { match (&left.0, &right.0) {
(Some(l), Some(r)) => OptionalHash::some(Self::parent(l, r)), (Some(l), Some(r)) => {
// Use the H256 implementation directly to ensure identical logic
let result = <Self as Algorithm<H256>>::parent(l, r);
OptionalHash::some(result)
}
_ => OptionalHash::none(), _ => OptionalHash::none(),
} }
} }
fn leaf(data: &[u8]) -> OptionalHash { fn leaf(data: &[u8]) -> OptionalHash {
OptionalHash::some(Self::leaf(data)) // Use the H256 implementation directly to ensure identical logic
let result = <Self as Algorithm<H256>>::leaf(data);
OptionalHash::some(result)
} }
} }

View File

@ -57,9 +57,8 @@ const PAD_MAX_SIZE: usize = 1 << 20;
static PAD_SEGMENT_ROOT: Lazy<OptionalHash> = Lazy::new(|| { static PAD_SEGMENT_ROOT: Lazy<OptionalHash> = Lazy::new(|| {
let h256_leaves = data_to_merkle_leaves(&[0; ENTRY_SIZE * PORA_CHUNK_SIZE]).unwrap(); let h256_leaves = data_to_merkle_leaves(&[0; ENTRY_SIZE * PORA_CHUNK_SIZE]).unwrap();
let optional_leaves: Vec<OptionalHash> =
h256_leaves.into_iter().map(OptionalHash::from).collect(); Merkle::new(h256_leaves, 0, None).root()
Merkle::new(optional_leaves, 0, None).root()
}); });
pub struct UpdateFlowMessage { pub struct UpdateFlowMessage {
pub pad_data: usize, pub pad_data: usize,
@ -1015,10 +1014,7 @@ impl LogManager {
let mut completed_chunk_index = None; let mut completed_chunk_index = None;
if pad_data.len() < last_chunk_pad { if pad_data.len() < last_chunk_pad {
is_full_empty = false; is_full_empty = false;
let pad_leaves: Vec<OptionalHash> = data_to_merkle_leaves(&pad_data)? let pad_leaves = data_to_merkle_leaves(&pad_data)?;
.into_iter()
.map(OptionalHash::from)
.collect();
merkle.last_chunk_merkle.append_list(pad_leaves); merkle.last_chunk_merkle.append_list(pad_leaves);
merkle merkle
.pora_chunks_merkle .pora_chunks_merkle
@ -1027,11 +1023,7 @@ impl LogManager {
if last_chunk_pad != 0 { if last_chunk_pad != 0 {
is_full_empty = false; is_full_empty = false;
// Pad the last chunk. // Pad the last chunk.
let last_chunk_leaves: Vec<OptionalHash> = let last_chunk_leaves = data_to_merkle_leaves(&pad_data[..last_chunk_pad])?;
data_to_merkle_leaves(&pad_data[..last_chunk_pad])?
.into_iter()
.map(OptionalHash::from)
.collect();
merkle.last_chunk_merkle.append_list(last_chunk_leaves); merkle.last_chunk_merkle.append_list(last_chunk_leaves);
merkle merkle
.pora_chunks_merkle .pora_chunks_merkle

View File

@ -27,20 +27,11 @@ fn test_put_get() {
0, 0,
None, None,
); );
let padding_leaves: Vec<OptionalHash> = let padding_leaves = data_to_merkle_leaves(&LogManager::padding_raw(start_offset - 1)).unwrap();
data_to_merkle_leaves(&LogManager::padding_raw(start_offset - 1))
.unwrap()
.into_iter()
.map(OptionalHash::from)
.collect();
merkle.append_list(padding_leaves); merkle.append_list(padding_leaves);
let mut data_padded = data.clone(); let mut data_padded = data.clone();
data_padded.append(&mut vec![0u8; CHUNK_SIZE]); data_padded.append(&mut vec![0u8; CHUNK_SIZE]);
let data_leaves: Vec<OptionalHash> = data_to_merkle_leaves(&data_padded) let data_leaves = data_to_merkle_leaves(&data_padded).unwrap();
.unwrap()
.into_iter()
.map(OptionalHash::from)
.collect();
merkle.append_list(data_leaves); merkle.append_list(data_leaves);
merkle.commit(Some(0)); merkle.commit(Some(0));
let tx_merkle = sub_merkle_tree(&data).unwrap(); let tx_merkle = sub_merkle_tree(&data).unwrap();
@ -144,11 +135,7 @@ fn test_root() {
let mt = sub_merkle_tree(&data).unwrap(); let mt = sub_merkle_tree(&data).unwrap();
println!("{:?} {}", mt.root(), hex::encode(mt.root())); println!("{:?} {}", mt.root(), hex::encode(mt.root()));
let append_mt = AppendMerkleTree::<OptionalHash, Sha3Algorithm>::new( let append_mt = AppendMerkleTree::<OptionalHash, Sha3Algorithm>::new(
data_to_merkle_leaves(&data) data_to_merkle_leaves(&data).unwrap(),
.unwrap()
.into_iter()
.map(OptionalHash::from)
.collect(),
0, 0,
None, None,
); );