Skip to content

Commit

Permalink
fix: use mem pool state for “get block” RPCs
Browse files Browse the repository at this point in the history
  • Loading branch information
blckngm committed Nov 23, 2022
1 parent 5ffbeb4 commit 3b58239
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 10 deletions.
33 changes: 24 additions & 9 deletions crates/rpc-server/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -914,17 +914,29 @@ async fn get_block(
}))
}

// Why do we read from `MemPoolState` instead of `Store` for these “get block”
// RPCs:
//
// `MemPoolState` can fall behind `Store` (at the moment after a new block is
// inserted but mem pool state hasn't been updated). If we read from `Store`, we
// may get a block that is not in `MemPoolState` yet. If we then try to get
// scripts for accounts in the block, we may get an error response, because the
// `get_script` / `get_script_hash` RPCs use `MemPoolState`.
//
// Instead if we always read from `MemPoolState`, it is much less likely that we
// get an error response when getting scripts for accounts in the new block.

async fn get_block_by_number(
Params((block_number,)): Params<(gw_jsonrpc_types::ckb_jsonrpc_types::Uint64,)>,
store: Data<Store>,
mem_pool_state: Data<Arc<MemPoolState>>,
) -> Result<Option<L2BlockView>> {
let block_number = block_number.value();
let snap = store.get_snapshot();
let block_hash = match snap.get_block_hash_by_number(block_number)? {
let mem_store = mem_pool_state.load_mem_store();
let block_hash = match mem_store.get_block_hash_by_number(block_number)? {
Some(hash) => hash,
None => return Ok(None),
};
let block_opt = snap.get_block(&block_hash)?.map(|block| {
let block_opt = mem_store.get_block(&block_hash)?.map(|block| {
let block_view: L2BlockView = block.into();
block_view
});
Expand All @@ -933,16 +945,19 @@ async fn get_block_by_number(

async fn get_block_hash(
Params((block_number,)): Params<(gw_jsonrpc_types::ckb_jsonrpc_types::Uint64,)>,
store: Data<Store>,
mem_pool_state: Data<Arc<MemPoolState>>,
) -> Result<Option<JsonH256>> {
let block_number = block_number.value();
let db = store.get_snapshot();
let hash_opt = db.get_block_hash_by_number(block_number)?.map(to_jsonh256);
let mem_store = mem_pool_state.load_mem_store();
let hash_opt = mem_store
.get_block_hash_by_number(block_number)?
.map(to_jsonh256);
Ok(hash_opt)
}

async fn get_tip_block_hash(store: Data<Store>) -> Result<JsonH256> {
let tip_block_hash = store.get_last_valid_tip_block_hash()?;
async fn get_tip_block_hash(mem_pool_state: Data<Arc<MemPoolState>>) -> Result<JsonH256> {
let mem_store = mem_pool_state.load_mem_store();
let tip_block_hash = mem_store.get_last_valid_tip_block_hash()?;
Ok(to_jsonh256(tip_block_hash))
}

Expand Down
15 changes: 14 additions & 1 deletion crates/store/src/mem_pool_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use std::sync::{
use arc_swap::ArcSwap;
use gw_types::packed::{self, BlockInfo};

use crate::state::MemStateDB;
use crate::{
snapshot::StoreSnapshot,
state::{overlay::mem_store::MemStore, MemStateDB},
};

pub const META_MEM_BLOCK_INFO: &[u8] = b"MEM_BLOCK_INFO";
/// account SMT root
Expand Down Expand Up @@ -58,6 +61,16 @@ impl MemPoolState {
self.inner.load().mem_block.clone()
}

pub fn load_mem_store(&self) -> MemStore<StoreSnapshot> {
self.inner
.load()
.state_db
.inner_smt_tree()
.store()
.inner_store()
.clone()
}

/// Load shared
pub fn load_shared(&self) -> Shared {
Shared::clone(&self.inner.load())
Expand Down

0 comments on commit 3b58239

Please sign in to comment.