Skip to content

Commit

Permalink
support revert all state data when revert block (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
atenjin authored Jun 22, 2021
1 parent e86c1c7 commit 3a3a389
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
6 changes: 6 additions & 0 deletions client/api/src/statekv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ pub trait StateKv<Block: BlockT>: Send + Sync {
fn get_contract_tracing(&self, number: NumberFor<Block>, index: u32) -> Option<String>;
fn remove_contract_tracing(&self, number: NumberFor<Block>, index: u32) -> error::Result<()>;
fn remove_contract_tracings_by_number(&self, number: NumberFor<Block>) -> error::Result<()>;

fn revert_all(&self, number: NumberFor<Block>) -> error::Result<()>;
}

pub trait StateKvTransaction {
Expand Down Expand Up @@ -173,4 +175,8 @@ impl<Block: BlockT, T: StateKv<Block>> StateKv<Block> for Arc<T> {
fn remove_contract_tracings_by_number(&self, number: NumberFor<Block>) -> error::Result<()> {
(&**self).remove_contract_tracings_by_number(number)
}

fn revert_all(&self, number: NumberFor<Block>) -> error::Result<()> {
(&**self).remove_contract_tracings_by_number(number)
}
}
36 changes: 36 additions & 0 deletions client/db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,42 @@ impl<B: BlockT> ec_client_api::statekv::StateKv<B> for StateKv {
t.delete_prefix(columns::TRACING, prefix);
})
}

fn revert_all(&self, number: NumberFor<B>) -> error::Result<()> {
let hash = <Self as ec_client_api::statekv::StateKv<B>>::get_hash(self, number).ok_or(
error::DatabaseError(format!("No hash for this number:{}", number).into()),
)?;
// state
<Self as ec_client_api::statekv::StateKv<B>>::delete_kvs_by_hash(self, hash)?;

// child state
let prefix = hash.as_ref();
let hash_len = prefix.len();
let mut lookup_key = Vec::with_capacity(hash_len + 1);
lookup_key.extend(prefix);
lookup_key.push(SEPARATOR);

let mut t = DBTransaction::with_capacity(1);
t.delete_prefix(columns::STATE_CHILD_KV, &lookup_key);
self.state_kv_db
.write(t)
.map_err(|e| error::DatabaseError(Box::new(e)))?;

// extrinsic changes
let num_u64: u64 = number.saturated_into::<u64>();
let prefix = &num_u64.to_le_bytes()[..];
let mut t = DBTransaction::with_capacity(1);
t.delete_prefix(columns::EXTRINSIC_CHANGES, &prefix);
self.state_kv_db
.write(t)
.map_err(|e| error::DatabaseError(Box::new(e)))?;

// contract tracing
<Self as ec_client_api::statekv::StateKv<B>>::remove_contract_tracings_by_number(
self, number,
)?;
Ok(())
}
}

fn tracing_key(number: u64, index: u32) -> Vec<u8> {
Expand Down
16 changes: 14 additions & 2 deletions client/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ use jsonrpc_derive::rpc;

use sp_blockchain::HeaderBackend;
use sp_core::Bytes;
use sp_runtime::traits::{Block as BlockT, BlockIdTo, Header};
use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, BlockIdTo, Header},
SaturatedConversion,
};
use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender};

use ec_client_api::statekv;

use error::EuropaRpcError;
use sp_runtime::generic::BlockId;

pub enum Message<B: BlockT> {
Forward(NumberOf<B>),
Expand Down Expand Up @@ -128,6 +131,15 @@ where
self.backend
.revert(diff, true)
.map_err(error::client_err::<B>)?;
let state_kv = self.client.state_kv();
let mut current = best;
while current != height {
state_kv
.revert_all(current)
.map_err(|e| error::client_err::<B>(e.into()))?;
current -= 1_u64.saturated_into();
}

Ok(())
}
fn state_kvs(
Expand Down

0 comments on commit 3a3a389

Please sign in to comment.