This commit is contained in:
Peilun Li 2024-10-15 12:42:17 +08:00
parent 703d926a23
commit 005e28266a
5 changed files with 32 additions and 8 deletions

View File

@ -59,10 +59,12 @@ impl<E: HashElement, A: Algorithm<E>> AppendMerkleTree<E, A> {
}, },
); );
} }
merkle.node_manager.commit();
return merkle; return merkle;
} }
// Reconstruct the whole tree. // Reconstruct the whole tree.
merkle.recompute(0, 0, None); merkle.recompute(0, 0, None);
merkle.node_manager.commit();
// Commit the first version in memory. // Commit the first version in memory.
// TODO(zz): Check when the roots become available. // TODO(zz): Check when the roots become available.
merkle.commit(start_tx_seq); merkle.commit(start_tx_seq);
@ -116,6 +118,7 @@ impl<E: HashElement, A: Algorithm<E>> AppendMerkleTree<E, A> {
}, },
); );
} }
merkle.node_manager.commit();
merkle merkle
} else { } else {
let mut merkle = Self { let mut merkle = Self {
@ -134,6 +137,7 @@ impl<E: HashElement, A: Algorithm<E>> AppendMerkleTree<E, A> {
} }
// Reconstruct the whole tree. // Reconstruct the whole tree.
merkle.recompute(0, 0, None); merkle.recompute(0, 0, None);
merkle.node_manager.commit();
// Commit the first version in memory. // Commit the first version in memory.
merkle.commit(start_tx_seq); merkle.commit(start_tx_seq);
merkle merkle

View File

@ -115,8 +115,9 @@ impl<E: HashElement> NodeManager<E> {
} }
pub fn start_transaction(&mut self) { pub fn start_transaction(&mut self) {
if self.db_tx.is_none() { if self.db_tx.is_some() {
error!("start new tx before commit"); error!("start new tx before commit");
panic!("start new tx before commit");
} }
self.db_tx = Some(self.db.start_transaction()); self.db_tx = Some(self.db.start_transaction());
} }

View File

@ -651,8 +651,12 @@ impl LogManager {
.get_tx_by_seq_number(last_tx_seq)? .get_tx_by_seq_number(last_tx_seq)?
.expect("tx missing"); .expect("tx missing");
let current_len = pora_chunks_merkle.leaves(); let current_len = pora_chunks_merkle.leaves();
let expected_len = let expected_len = sector_to_segment(
sector_to_segment(last_tx.start_entry_index + last_tx.num_entries() as u64); last_tx.start_entry_index
+ last_tx.num_entries() as u64
+ PORA_CHUNK_SIZE as u64
- 1,
);
match expected_len.cmp(&(current_len)) { match expected_len.cmp(&(current_len)) {
Ordering::Less => { Ordering::Less => {
bail!( bail!(
@ -681,6 +685,8 @@ impl LogManager {
); );
if current_len > expected_len { if current_len > expected_len {
pora_chunks_merkle.revert_to_leaves(expected_len)?; pora_chunks_merkle.revert_to_leaves(expected_len)?;
} else {
assert_eq!(current_len, expected_len);
} }
start_tx_seq = Some(previous_tx.seq); start_tx_seq = Some(previous_tx.seq);
}; };
@ -691,10 +697,20 @@ impl LogManager {
let last_chunk_merkle = match start_tx_seq { let last_chunk_merkle = match start_tx_seq {
Some(tx_seq) => { Some(tx_seq) => {
tx_store.rebuild_last_chunk_merkle(pora_chunks_merkle.leaves(), tx_seq)? let tx = tx_store.get_tx_by_seq_number(tx_seq)?.expect("tx missing");
if (tx.start_entry_index() + tx.num_entries() as u64) % PORA_CHUNK_SIZE as u64 == 0
{
// The last chunk should be aligned, so it's empty.
Merkle::new_with_depth(vec![], log2_pow2(PORA_CHUNK_SIZE) + 1, None)
} else {
tx_store.rebuild_last_chunk_merkle(pora_chunks_merkle.leaves() - 1, tx_seq)?
}
} }
// Initialize // Initialize
None => Merkle::new_with_depth(vec![], 1, None), None => {
pora_chunks_merkle.reset();
Merkle::new_with_depth(vec![], 1, None)
}
}; };
debug!( debug!(
@ -704,10 +720,10 @@ impl LogManager {
last_chunk_merkle.leaves(), last_chunk_merkle.leaves(),
); );
if last_chunk_merkle.leaves() != 0 { if last_chunk_merkle.leaves() != 0 {
pora_chunks_merkle.append(last_chunk_merkle.root()); pora_chunks_merkle.update_last(last_chunk_merkle.root());
}
// update the merkle root // update the merkle root
pora_chunks_merkle.commit(start_tx_seq); pora_chunks_merkle.commit(start_tx_seq);
}
let merkle = RwLock::new(MerkleManager { let merkle = RwLock::new(MerkleManager {
pora_chunks_merkle, pora_chunks_merkle,
last_chunk_merkle, last_chunk_merkle,

View File

@ -292,6 +292,9 @@ impl TransactionStore {
match tx.start_entry_index.cmp(&last_chunk_start_index) { match tx.start_entry_index.cmp(&last_chunk_start_index) {
cmp::Ordering::Greater => { cmp::Ordering::Greater => {
tx_list.push((tx_seq, tx.merkle_nodes)); tx_list.push((tx_seq, tx.merkle_nodes));
if tx.start_entry_index >= last_chunk_start_index + PORA_CHUNK_SIZE as u64 {
break;
}
} }
cmp::Ordering::Equal => { cmp::Ordering::Equal => {
tx_list.push((tx_seq, tx.merkle_nodes)); tx_list.push((tx_seq, tx.merkle_nodes));

0
tests/crash_test.py Normal file → Executable file
View File