Skip to content

Commit ea6801d

Browse files
committed
get height blocks
1 parent 2436a7a commit ea6801d

File tree

14 files changed

+119
-2
lines changed

14 files changed

+119
-2
lines changed

chain/api/src/chain.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub trait ChainReader {
4343
reverse: bool,
4444
count: u64,
4545
) -> Result<Vec<Block>>;
46+
fn get_height_blocks(&self, number: BlockNumber) -> Result<Vec<Block>>;
4647
fn get_block(&self, hash: HashValue) -> Result<Option<Block>>;
4748
/// Get block hash by block number, if not exist, return None
4849
fn get_hash_by_number(&self, number: BlockNumber) -> Result<Option<HashValue>>;

chain/api/src/message.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ pub enum ChainRequest {
6060
access_path: Option<AccessPath>,
6161
},
6262
GetBlockInfos(Vec<HashValue>),
63+
GetHeightBlocks(BlockNumber),
6364
}
6465

6566
impl ServiceRequest for ChainRequest {

chain/api/src/service.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub trait ReadableChainService {
7272
) -> Result<Option<TransactionInfoWithProof>>;
7373

7474
fn get_block_infos(&self, ids: Vec<HashValue>) -> Result<Vec<Option<BlockInfo>>>;
75+
fn get_height_blocks(&self, number: BlockNumber) -> Result<Vec<Block>>;
7576
}
7677

7778
/// Writeable block chain service trait
@@ -106,6 +107,7 @@ pub trait ChainAsyncService:
106107
async fn main_head_header(&self) -> Result<BlockHeader>;
107108
async fn main_head_block(&self) -> Result<Block>;
108109
async fn main_block_by_number(&self, number: BlockNumber) -> Result<Option<Block>>;
110+
async fn get_height_blocks(&self, number: BlockNumber) -> Result<Vec<Block>>;
109111
async fn main_blocks_by_number(
110112
&self,
111113
number: Option<BlockNumber>,
@@ -310,6 +312,16 @@ where
310312
}
311313
}
312314

315+
async fn get_height_blocks(&self, number: BlockNumber) -> Result<Vec<Block>> {
316+
if let ChainResponse::BlockVec(blocks) =
317+
self.send(ChainRequest::GetHeightBlocks(number)).await??
318+
{
319+
Ok(blocks)
320+
} else {
321+
bail!("Get height blocks by number response error.")
322+
}
323+
}
324+
313325
async fn main_blocks_by_number(
314326
&self,
315327
number: Option<BlockNumber>,

chain/service/src/chain_service.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ impl ServiceHandler<Self, ChainRequest> for ChainReaderService {
232232
ChainRequest::GetBlockInfos(ids) => Ok(ChainResponse::BlockInfoVec(Box::new(
233233
self.inner.get_block_infos(ids)?,
234234
))),
235+
ChainRequest::GetHeightBlocks(number) => Ok(ChainResponse::BlockVec(
236+
self.inner.get_height_blocks(number)?,
237+
)),
235238
}
236239
}
237240
}
@@ -416,6 +419,10 @@ impl ReadableChainService for ChainReaderServiceInner {
416419
fn get_block_infos(&self, ids: Vec<HashValue>) -> Result<Vec<Option<BlockInfo>>> {
417420
self.storage.get_block_infos(ids)
418421
}
422+
423+
fn get_height_blocks(&self, number: BlockNumber) -> Result<Vec<Block>> {
424+
self.storage.get_height_blocks(number)
425+
}
419426
}
420427

421428
#[cfg(test)]

chain/src/chain.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,10 @@ impl ChainReader for BlockChain {
605605
Ok(blocks)
606606
}
607607

608+
fn get_height_blocks(&self, number: BlockNumber) -> Result<Vec<Block>> {
609+
self.storage.get_height_blocks(number)
610+
}
611+
608612
fn get_block(&self, hash: HashValue) -> Result<Option<Block>> {
609613
self.storage
610614
.get_block_by_hash(hash)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) The Starcoin Core Contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use crate::cli_state::CliState;
5+
use crate::StarcoinOpt;
6+
use anyhow::Result;
7+
use clap::Parser;
8+
use scmd::{CommandAction, ExecContext};
9+
use starcoin_rpc_api::types::BlockView;
10+
use starcoin_types::block::BlockNumber;
11+
12+
/// Get block by hash or number.
13+
#[derive(Debug, Parser)]
14+
#[clap(name = "get-height-blocks", alias = "get_height_blocks")]
15+
pub struct GetHeightBlocksOpt {
16+
#[clap(name = "number")]
17+
number: BlockNumber,
18+
}
19+
20+
pub struct GetHeightBlocksCommand;
21+
22+
impl CommandAction for GetHeightBlocksCommand {
23+
type State = CliState;
24+
type GlobalOpt = StarcoinOpt;
25+
type Opt = GetHeightBlocksOpt;
26+
type ReturnItem = Vec<BlockView>;
27+
28+
fn run(
29+
&self,
30+
ctx: &ExecContext<Self::State, Self::GlobalOpt, Self::Opt>,
31+
) -> Result<Self::ReturnItem> {
32+
let client = ctx.state().client();
33+
let opt = ctx.opt();
34+
let blocks = client.chain_get_height_blocks(opt.number)?;
35+
Ok(blocks)
36+
}
37+
}

cmd/starcoin/src/chain/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod epoch_info;
55
mod get_block_cmd;
66
mod get_block_info_cmd;
77
mod get_events_cmd;
8+
mod get_height_blocks_cmd;
89
mod get_txn_cmd;
910
mod get_txn_info_cmd;
1011
mod get_txn_info_list_cmd;
@@ -17,6 +18,7 @@ pub use epoch_info::*;
1718
pub use get_block_cmd::*;
1819
pub use get_block_info_cmd::*;
1920
pub use get_events_cmd::*;
21+
pub use get_height_blocks_cmd::*;
2022
pub use get_txn_cmd::*;
2123
pub use get_txn_info_cmd::*;
2224
pub use get_txn_info_list_cmd::*;

cmd/starcoin/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ pub fn add_command(
102102
.subcommand(chain::EpochInfoCommand)
103103
.subcommand(chain::GetTransactionInfoListCommand)
104104
.subcommand(chain::get_txn_proof_cmd::GetTransactionProofCommand)
105-
.subcommand(chain::GetBlockInfoCommand),
105+
.subcommand(chain::GetBlockInfoCommand)
106+
.subcommand(chain::GetHeightBlocksCommand),
106107
)
107108
.command(
108109
CustomCommand::with_name("txpool")

rpc/api/src/chain/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ pub trait ChainApi {
4747
count: u64,
4848
option: Option<GetBlocksOption>,
4949
) -> FutureResult<Vec<BlockView>>;
50+
51+
/// Get height `number` blocks.
52+
#[rpc(name = "chain.get_height_blocks")]
53+
fn get_height_blocks(&self, number: BlockNumber) -> FutureResult<Vec<BlockView>>;
54+
5055
#[rpc(name = "chain.get_block_info_by_number")]
5156
fn get_block_info_by_number(&self, number: BlockNumber) -> FutureResult<Option<BlockInfoView>>;
5257
/// Get chain transactions

rpc/client/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,11 @@ impl RpcClient {
799799
.map_err(map_err)
800800
}
801801

802+
pub fn chain_get_height_blocks(&self, number: BlockNumber) -> anyhow::Result<Vec<BlockView>> {
803+
self.call_rpc_blocking(|inner| inner.chain_client.get_height_blocks(number))
804+
.map_err(map_err)
805+
}
806+
802807
pub fn chain_get_transaction(
803808
&self,
804809
txn_id: HashValue,

rpc/server/src/module/chain_rpc.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,19 @@ where
171171
Box::pin(fut.boxed())
172172
}
173173

174+
fn get_height_blocks(&self, number: BlockNumber) -> FutureResult<Vec<BlockView>> {
175+
let service = self.service.clone();
176+
let fut = async move {
177+
let blocks = service.get_height_blocks(number).await?;
178+
blocks
179+
.into_iter()
180+
.map(|blk| BlockView::try_from_block(blk, true, false))
181+
.collect::<Result<Vec<_>, _>>()
182+
}
183+
.map_err(map_err);
184+
Box::pin(fut.boxed())
185+
}
186+
174187
fn get_block_info_by_number(&self, number: u64) -> FutureResult<Option<BlockInfoView>> {
175188
let service = self.service.clone();
176189

storage/src/block/mod.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use network_p2p_types::peer_id::PeerId;
1212
use serde::{Deserialize, Serialize};
1313
use starcoin_crypto::HashValue;
1414
use starcoin_logger::prelude::*;
15-
use starcoin_types::block::{Block, BlockBody, BlockHeader};
15+
use starcoin_types::block::{Block, BlockBody, BlockHeader, BlockNumber};
1616

1717
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
1818
pub struct OldFailedBlock {
@@ -314,4 +314,20 @@ impl BlockStorage {
314314
self.failed_block_storage
315315
.put_raw(block_id, old_block.encode_value()?)
316316
}
317+
318+
pub fn get_height_blocks(&self, number: BlockNumber) -> Result<Vec<Block>> {
319+
let mut blocks = vec![];
320+
let mut iter = self.header_store.iter()?;
321+
iter.seek_to_first();
322+
for item in iter {
323+
let (id, block_header) = item?;
324+
if block_header.number() == number {
325+
let block = self.get(id)?;
326+
if let Some(block) = block {
327+
blocks.push(block);
328+
}
329+
}
330+
}
331+
Ok(blocks)
332+
}
317333
}

storage/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use starcoin_types::{
3030
};
3131
//use starcoin_vm_types::state_store::table::{TableHandle, TableInfo};
3232
use starcoin_types::account_address::AccountAddress;
33+
use starcoin_types::block::BlockNumber;
3334
use starcoin_vm_types::state_store::table::{TableHandle, TableInfo};
3435
use std::collections::BTreeMap;
3536
use std::fmt::{Debug, Display, Formatter};
@@ -224,6 +225,7 @@ pub trait BlockStore {
224225

225226
fn get_snapshot_range(&self) -> Result<Option<SnapshotRange>>;
226227
fn save_snapshot_range(&self, snapshot_height: SnapshotRange) -> Result<()>;
228+
fn get_height_blocks(&self, number: BlockNumber) -> Result<Vec<Block>>;
227229
}
228230

229231
pub trait BlockTransactionInfoStore {
@@ -468,6 +470,10 @@ impl BlockStore for Storage {
468470
fn save_snapshot_range(&self, snapshot_range: SnapshotRange) -> Result<()> {
469471
self.chain_info_storage.save_snapshot_range(snapshot_range)
470472
}
473+
474+
fn get_height_blocks(&self, number: BlockNumber) -> Result<Vec<Block>> {
475+
self.block_storage.get_height_blocks(number)
476+
}
471477
}
472478

473479
impl BlockInfoStore for Storage {

vm/starcoin-transactional-test-harness/src/fork_chain.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,13 @@ impl ChainApi for MockChainApi {
307307
Box::pin(fut.boxed().map_err(map_err))
308308
}
309309

310+
fn get_height_blocks(&self, _number: BlockNumber) -> FutureResult<Vec<BlockView>> {
311+
let fut = async move {
312+
bail!("not implemented.");
313+
};
314+
Box::pin(fut.boxed().map_err(map_err))
315+
}
316+
310317
fn get_block_info_by_number(&self, number: BlockNumber) -> FutureResult<Option<BlockInfoView>> {
311318
let chain = self.chain.lock().unwrap();
312319
let client = chain.remote_chain_client();

0 commit comments

Comments
 (0)