Skip to content

Commit

Permalink
try: time wrap done
Browse files Browse the repository at this point in the history
  • Loading branch information
AurevoirXavier committed Jan 17, 2020
1 parent 037ca49 commit ce4ce7a
Show file tree
Hide file tree
Showing 12 changed files with 288 additions and 94 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

133 changes: 94 additions & 39 deletions core/client/db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1376,50 +1376,105 @@ where
Some(self.offchain_storage.clone())
}

fn revert(&self, n: NumberFor<Block>) -> ClientResult<NumberFor<Block>> {
let mut best = self.blockchain.info().best_number;
// fn revert(&self, n: NumberFor<Block>) -> ClientResult<NumberFor<Block>> {
fn revert(&self, n: NumberFor<Block>, revert_finalized: bool) -> ClientResult<NumberFor<Block>> {
// let mut best = self.blockchain.info().best_number;
let mut best_number = self.blockchain.info().best_number;
let mut best_hash = self.blockchain.info().best_hash;
let finalized = self.blockchain.info().finalized_number;
let revertible = best - finalized;
let n = if revertible < n { revertible } else { n };
// let revertible = best - finalized;
let revertible = best_number - finalized;
// let n = if revertible < n { revertible } else { n };
let n = if !revert_finalized && revertible < n {
revertible
} else {
n
};

for c in 0..n.saturated_into::<u64>() {
if best.is_zero() {
return Ok(c.saturated_into::<NumberFor<Block>>());
let mut revert_blocks = || -> ClientResult<NumberFor<Block>> {
for c in 0..n.saturated_into::<u64>() {
// if best.is_zero() {
if best_number.is_zero() {
return Ok(c.saturated_into::<NumberFor<Block>>());
}
let mut transaction = DBTransaction::new();
match self.storage.state_db.revert_one() {
Some(commit) => {
apply_state_commit(&mut transaction, commit);
// let removed = self.blockchain.header(BlockId::Number(best))?.ok_or_else(|| {
// client::error::Error::UnknownBlock(format!(
// "Error reverting to {}. Block hash not found.",
// best
// ))
// })?;
let removed = self.blockchain.header(BlockId::Number(best_number))?.ok_or_else(|| {
client::error::Error::UnknownBlock(format!(
"Error reverting to {}. Block hash not found.",
best_number
))
})?;

// best -= One::one(); // prev block
best_number -= One::one(); // prev block
// let hash = self.blockchain.hash(best)?.ok_or_else(|| {
// client::error::Error::UnknownBlock(format!(
// "Error reverting to {}. Block hash not found.",
// best
// ))
// })?;
best_hash = self.blockchain.hash(best_number)?.ok_or_else(|| {
client::error::Error::UnknownBlock(format!(
"Error reverting to {}. Block hash not found.",
best_number
))
})?;
let update_finalized = best_number < finalized;
// let key = utils::number_and_hash_to_lookup_key(best.clone(), &hash)?;
let key = utils::number_and_hash_to_lookup_key(best_number.clone(), &best_hash)?;
transaction.put(columns::META, meta_keys::BEST_BLOCK, &key);
if update_finalized {
transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &key);
}
transaction.delete(columns::KEY_LOOKUP, removed.hash().as_ref());
// children::remove_children(&mut transaction, columns::META, meta_keys::CHILDREN_PREFIX, hash);
children::remove_children(
&mut transaction,
columns::META,
meta_keys::CHILDREN_PREFIX,
best_hash,
);
self.storage.db.write(transaction).map_err(db_err)?;
// self.blockchain.update_meta(hash, best, true, false);
self.blockchain
.update_meta(best_hash, best_number, true, update_finalized);
// self.blockchain.leaves.write().revert(
// removed.hash().clone(),
// removed.number().clone(),
// removed.parent_hash().clone(),
// );
}
None => return Ok(c.saturated_into::<NumberFor<Block>>()),
}
}
Ok(n)
};

let reverted = revert_blocks()?;

let revert_leaves = || -> ClientResult<()> {
let mut transaction = DBTransaction::new();
match self.storage.state_db.revert_one() {
Some(commit) => {
apply_state_commit(&mut transaction, commit);
let removed = self.blockchain.header(BlockId::Number(best))?.ok_or_else(|| {
client::error::Error::UnknownBlock(format!(
"Error reverting to {}. Block hash not found.",
best
))
})?;
let mut leaves = self.blockchain.leaves.write();

best -= One::one(); // prev block
let hash = self.blockchain.hash(best)?.ok_or_else(|| {
client::error::Error::UnknownBlock(format!(
"Error reverting to {}. Block hash not found.",
best
))
})?;
let key = utils::number_and_hash_to_lookup_key(best.clone(), &hash)?;
transaction.put(columns::META, meta_keys::BEST_BLOCK, &key);
transaction.delete(columns::KEY_LOOKUP, removed.hash().as_ref());
children::remove_children(&mut transaction, columns::META, meta_keys::CHILDREN_PREFIX, hash);
self.storage.db.write(transaction).map_err(db_err)?;
self.blockchain.update_meta(hash, best, true, false);
self.blockchain.leaves.write().revert(
removed.hash().clone(),
removed.number().clone(),
removed.parent_hash().clone(),
);
}
None => return Ok(c.saturated_into::<NumberFor<Block>>()),
}
}
Ok(n)
leaves.revert(best_hash, best_number);
leaves.prepare_transaction(&mut transaction, columns::META, meta_keys::LEAF_PREFIX);
self.storage.db.write(transaction).map_err(db_err)?;

Ok(())
};

revert_leaves()?;

Ok(reverted)
}

fn blockchain(&self) -> &BlockchainDb<Block> {
Expand Down
3 changes: 2 additions & 1 deletion core/client/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,8 @@ where
/// Attempts to revert the chain by `n` blocks.
///
/// Returns the number of blocks that were successfully reverted.
fn revert(&self, n: NumberFor<Block>) -> error::Result<NumberFor<Block>>;
// fn revert(&self, n: NumberFor<Block>) -> error::Result<NumberFor<Block>>;
fn revert(&self, n: NumberFor<Block>, revert_finalized: bool) -> error::Result<NumberFor<Block>>;

/// Insert auxiliary data into key-value store.
fn insert_aux<
Expand Down
9 changes: 8 additions & 1 deletion core/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,14 @@ where
/// Attempts to revert the chain by `n` blocks. Returns the number of blocks that were
/// successfully reverted.
pub fn revert(&self, n: NumberFor<Block>) -> error::Result<NumberFor<Block>> {
Ok(self.backend.revert(n)?)
// Ok(self.backend.revert(n)?)
Ok(self.backend.revert(n, false)?)
}

/// Attempts to revert the chain by `n` blocks disregarding finality. Returns the number of
/// blocks that were successfully reverted.
pub fn unsafe_revert(&self, n: NumberFor<Block>) -> error::Result<NumberFor<Block>> {
Ok(self.backend.revert(n, true)?)
}

/// Get blockchain info.
Expand Down
3 changes: 2 additions & 1 deletion core/client/src/in_mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,8 @@ where
}
}

fn revert(&self, _n: NumberFor<Block>) -> error::Result<NumberFor<Block>> {
// fn revert(&self, _n: NumberFor<Block>) -> error::Result<NumberFor<Block>> {
fn revert(&self, _n: NumberFor<Block>, _revert_finalized: bool) -> error::Result<NumberFor<Block>> {
Ok(Zero::zero())
}

Expand Down
52 changes: 41 additions & 11 deletions core/client/src/leaves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,39 @@ where
Undo { inner: self }
}

/// currently since revert only affects the canonical chain
/// we assume that parent has no further children
/// and we add it as leaf again
pub fn revert(&mut self, hash: H, number: N, parent_hash: H) {
self.insert_leaf(Reverse(number.clone() - N::one()), parent_hash);
self.remove_leaf(&Reverse(number), &hash);
// /// currently since revert only affects the canonical chain
// /// we assume that parent has no further children
// /// and we add it as leaf again
// pub fn revert(&mut self, hash: H, number: N, parent_hash: H) {
// self.insert_leaf(Reverse(number.clone() - N::one()), parent_hash);
// self.remove_leaf(&Reverse(number), &hash);
// }
pub fn revert(&mut self, best_hash: H, best_number: N) {
let items = self
.storage
.iter()
.flat_map(|(number, hashes)| hashes.iter().map(move |h| (h.clone(), number.clone())))
.collect::<Vec<_>>();

for (hash, number) in &items {
if number.0 > best_number {
assert!(
self.remove_leaf(number, hash),
"item comes from an iterator over storage; qed",
);

self.pending_removed.push(hash.clone());
}
}

let best_number = Reverse(best_number);
if !self.contains(&best_number, &best_hash) {
self.insert_leaf(best_number.clone(), best_hash.clone());
self.pending_added.push(LeafSetItem {
hash: best_hash,
number: best_number,
});
}
}

/// returns an iterator over all hashes in the leaf set
Expand Down Expand Up @@ -198,11 +225,14 @@ where
}
}

#[cfg(test)]
fn contains(&self, number: N, hash: H) -> bool {
self.storage
.get(&Reverse(number))
.map_or(false, |hashes| hashes.contains(&hash))
// #[cfg(test)]
// fn contains(&self, number: N, hash: H) -> bool {
// self.storage
// .get(&Reverse(number))
// .map_or(false, |hashes| hashes.contains(&hash))
// }
fn contains(&self, number: &Reverse<N>, hash: &H) -> bool {
self.storage.get(&number).map_or(false, |hashes| hashes.contains(hash))
}

fn insert_leaf(&mut self, number: Reverse<N>, hash: H) {
Expand Down
3 changes: 2 additions & 1 deletion core/client/src/light/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ where
Ok(GenesisOrUnavailableState::Unavailable)
}

fn revert(&self, _n: NumberFor<Block>) -> ClientResult<NumberFor<Block>> {
// fn revert(&self, _n: NumberFor<Block>) -> ClientResult<NumberFor<Block>> {
fn revert(&self, _n: NumberFor<Block>, _revert_finalized: bool) -> ClientResult<NumberFor<Block>> {
Err(ClientError::NotAvailableOnLightClient)
}

Expand Down
2 changes: 2 additions & 0 deletions core/consensus/slots/src/slots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ impl SignedDuration {

/// Returns the duration until the next slot, based on current duration since
pub fn time_until_next(now: Duration, slot_duration: u64) -> Duration {
// ICEFROG HOTFIX: poll the slot 10 times as often since we might be in a time warp.
let slot_duration = slot_duration / 20;
let remaining_full_millis = slot_duration - (now.as_millis() as u64 % slot_duration) - 1;
Duration::from_millis(remaining_full_millis)
}
Expand Down
Loading

0 comments on commit ce4ce7a

Please sign in to comment.