Add GetConfirmedBlocksWithLimit RPC method
This commit is contained in:
parent
b2fc7f7caa
commit
75b621160e
|
@ -271,6 +271,17 @@ impl RpcClient {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_confirmed_blocks_with_limit(
|
||||||
|
&self,
|
||||||
|
start_slot: Slot,
|
||||||
|
limit: usize,
|
||||||
|
) -> ClientResult<Vec<Slot>> {
|
||||||
|
self.send(
|
||||||
|
RpcRequest::GetConfirmedBlocksWithLimit,
|
||||||
|
json!([start_slot, limit]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_confirmed_signatures_for_address(
|
pub fn get_confirmed_signatures_for_address(
|
||||||
&self,
|
&self,
|
||||||
address: &Pubkey,
|
address: &Pubkey,
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub enum RpcRequest {
|
||||||
GetClusterNodes,
|
GetClusterNodes,
|
||||||
GetConfirmedBlock,
|
GetConfirmedBlock,
|
||||||
GetConfirmedBlocks,
|
GetConfirmedBlocks,
|
||||||
|
GetConfirmedBlocksWithLimit,
|
||||||
GetConfirmedSignaturesForAddress,
|
GetConfirmedSignaturesForAddress,
|
||||||
GetConfirmedSignaturesForAddress2,
|
GetConfirmedSignaturesForAddress2,
|
||||||
GetConfirmedTransaction,
|
GetConfirmedTransaction,
|
||||||
|
@ -67,6 +68,7 @@ impl fmt::Display for RpcRequest {
|
||||||
RpcRequest::GetClusterNodes => "getClusterNodes",
|
RpcRequest::GetClusterNodes => "getClusterNodes",
|
||||||
RpcRequest::GetConfirmedBlock => "getConfirmedBlock",
|
RpcRequest::GetConfirmedBlock => "getConfirmedBlock",
|
||||||
RpcRequest::GetConfirmedBlocks => "getConfirmedBlocks",
|
RpcRequest::GetConfirmedBlocks => "getConfirmedBlocks",
|
||||||
|
RpcRequest::GetConfirmedBlocksWithLimit => "getConfirmedBlocksWithLimit",
|
||||||
RpcRequest::GetConfirmedSignaturesForAddress => "getConfirmedSignaturesForAddress",
|
RpcRequest::GetConfirmedSignaturesForAddress => "getConfirmedSignaturesForAddress",
|
||||||
RpcRequest::GetConfirmedSignaturesForAddress2 => "getConfirmedSignaturesForAddress2",
|
RpcRequest::GetConfirmedSignaturesForAddress2 => "getConfirmedSignaturesForAddress2",
|
||||||
RpcRequest::GetConfirmedTransaction => "getConfirmedTransaction",
|
RpcRequest::GetConfirmedTransaction => "getConfirmedTransaction",
|
||||||
|
|
125
core/src/rpc.rs
125
core/src/rpc.rs
|
@ -679,8 +679,8 @@ impl JsonRpcRequestProcessor {
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let lowest_slot = self.blockstore.lowest_slot();
|
let lowest_blockstore_slot = self.blockstore.lowest_slot();
|
||||||
if start_slot < lowest_slot {
|
if start_slot < lowest_blockstore_slot {
|
||||||
// If the starting slot is lower than what's available in blockstore assume the entire
|
// If the starting slot is lower than what's available in blockstore assume the entire
|
||||||
// [start_slot..end_slot] can be fetched from BigTable.
|
// [start_slot..end_slot] can be fetched from BigTable.
|
||||||
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
|
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
|
||||||
|
@ -696,12 +696,45 @@ impl JsonRpcRequestProcessor {
|
||||||
|
|
||||||
Ok(self
|
Ok(self
|
||||||
.blockstore
|
.blockstore
|
||||||
.rooted_slot_iterator(max(start_slot, lowest_slot))
|
.rooted_slot_iterator(max(start_slot, lowest_blockstore_slot))
|
||||||
.map_err(|_| Error::internal_error())?
|
.map_err(|_| Error::internal_error())?
|
||||||
.filter(|&slot| slot <= end_slot)
|
.filter(|&slot| slot <= end_slot)
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_confirmed_blocks_with_limit(
|
||||||
|
&self,
|
||||||
|
start_slot: Slot,
|
||||||
|
limit: usize,
|
||||||
|
) -> Result<Vec<Slot>> {
|
||||||
|
if limit > MAX_GET_CONFIRMED_BLOCKS_RANGE as usize {
|
||||||
|
return Err(Error::invalid_params(format!(
|
||||||
|
"Limit too large; max {}",
|
||||||
|
MAX_GET_CONFIRMED_BLOCKS_RANGE
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let lowest_blockstore_slot = self.blockstore.lowest_slot();
|
||||||
|
|
||||||
|
if start_slot < lowest_blockstore_slot {
|
||||||
|
// If the starting slot is lower than what's available in blockstore assume the entire
|
||||||
|
// range can be fetched from BigTable.
|
||||||
|
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
|
||||||
|
return Ok(self
|
||||||
|
.runtime_handle
|
||||||
|
.block_on(bigtable_ledger_storage.get_confirmed_blocks(start_slot, limit))
|
||||||
|
.unwrap_or_else(|_| vec![]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(self
|
||||||
|
.blockstore
|
||||||
|
.rooted_slot_iterator(max(start_slot, lowest_blockstore_slot))
|
||||||
|
.map_err(|_| Error::internal_error())?
|
||||||
|
.take(limit)
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_block_time(&self, slot: Slot) -> Result<Option<UnixTimestamp>> {
|
pub fn get_block_time(&self, slot: Slot) -> Result<Option<UnixTimestamp>> {
|
||||||
if slot
|
if slot
|
||||||
<= self
|
<= self
|
||||||
|
@ -1699,6 +1732,14 @@ pub trait RpcSol {
|
||||||
end_slot: Option<Slot>,
|
end_slot: Option<Slot>,
|
||||||
) -> Result<Vec<Slot>>;
|
) -> Result<Vec<Slot>>;
|
||||||
|
|
||||||
|
#[rpc(meta, name = "getConfirmedBlocksWithLimit")]
|
||||||
|
fn get_confirmed_blocks_with_limit(
|
||||||
|
&self,
|
||||||
|
meta: Self::Metadata,
|
||||||
|
start_slot: Slot,
|
||||||
|
limit: usize,
|
||||||
|
) -> Result<Vec<Slot>>;
|
||||||
|
|
||||||
#[rpc(meta, name = "getConfirmedTransaction")]
|
#[rpc(meta, name = "getConfirmedTransaction")]
|
||||||
fn get_confirmed_transaction(
|
fn get_confirmed_transaction(
|
||||||
&self,
|
&self,
|
||||||
|
@ -2366,12 +2407,25 @@ impl RpcSol for RpcSolImpl {
|
||||||
end_slot: Option<Slot>,
|
end_slot: Option<Slot>,
|
||||||
) -> Result<Vec<Slot>> {
|
) -> Result<Vec<Slot>> {
|
||||||
debug!(
|
debug!(
|
||||||
"get_confirmed_blocks rpc request received: {:?}-{:?}",
|
"get_confirmed_blocks rpc request received: {}-{:?}",
|
||||||
start_slot, end_slot
|
start_slot, end_slot
|
||||||
);
|
);
|
||||||
meta.get_confirmed_blocks(start_slot, end_slot)
|
meta.get_confirmed_blocks(start_slot, end_slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_confirmed_blocks_with_limit(
|
||||||
|
&self,
|
||||||
|
meta: Self::Metadata,
|
||||||
|
start_slot: Slot,
|
||||||
|
limit: usize,
|
||||||
|
) -> Result<Vec<Slot>> {
|
||||||
|
debug!(
|
||||||
|
"get_confirmed_blocks_with_limit rpc request received: {}-{}",
|
||||||
|
start_slot, limit,
|
||||||
|
);
|
||||||
|
meta.get_confirmed_blocks_with_limit(start_slot, limit)
|
||||||
|
}
|
||||||
|
|
||||||
fn get_block_time(&self, meta: Self::Metadata, slot: Slot) -> Result<Option<UnixTimestamp>> {
|
fn get_block_time(&self, meta: Self::Metadata, slot: Slot) -> Result<Option<UnixTimestamp>> {
|
||||||
meta.get_block_time(slot)
|
meta.get_block_time(slot)
|
||||||
}
|
}
|
||||||
|
@ -4733,6 +4787,69 @@ pub mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_confirmed_blocks_with_limit() {
|
||||||
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
|
let roots = vec![0, 1, 3, 4, 8];
|
||||||
|
let RpcHandler {
|
||||||
|
io,
|
||||||
|
meta,
|
||||||
|
block_commitment_cache,
|
||||||
|
..
|
||||||
|
} = start_rpc_handler_with_tx_and_blockstore(&bob_pubkey, roots, 0);
|
||||||
|
block_commitment_cache
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.set_highest_confirmed_root(8);
|
||||||
|
|
||||||
|
let req = r#"{"jsonrpc":"2.0","id":1,"method":"getConfirmedBlocksWithLimit","params":[0,500001]}"#;
|
||||||
|
let res = io.handle_request_sync(&req, meta.clone());
|
||||||
|
assert_eq!(
|
||||||
|
res,
|
||||||
|
Some(
|
||||||
|
r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Limit too large; max 500000"},"id":1}"#.to_string(),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
let req =
|
||||||
|
r#"{"jsonrpc":"2.0","id":1,"method":"getConfirmedBlocksWithLimit","params":[0,0]}"#;
|
||||||
|
let res = io.handle_request_sync(&req, meta.clone());
|
||||||
|
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||||
|
.expect("actual response deserialization");
|
||||||
|
let confirmed_blocks: Vec<Slot> = serde_json::from_value(result["result"].clone()).unwrap();
|
||||||
|
assert!(confirmed_blocks.is_empty());
|
||||||
|
|
||||||
|
let req =
|
||||||
|
r#"{"jsonrpc":"2.0","id":1,"method":"getConfirmedBlocksWithLimit","params":[2,2]}"#;
|
||||||
|
let res = io.handle_request_sync(&req, meta.clone());
|
||||||
|
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||||
|
.expect("actual response deserialization");
|
||||||
|
let confirmed_blocks: Vec<Slot> = serde_json::from_value(result["result"].clone()).unwrap();
|
||||||
|
assert_eq!(confirmed_blocks, vec![3, 4]);
|
||||||
|
|
||||||
|
let req =
|
||||||
|
r#"{"jsonrpc":"2.0","id":1,"method":"getConfirmedBlocksWithLimit","params":[2,3]}"#;
|
||||||
|
let res = io.handle_request_sync(&req, meta.clone());
|
||||||
|
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||||
|
.expect("actual response deserialization");
|
||||||
|
let confirmed_blocks: Vec<Slot> = serde_json::from_value(result["result"].clone()).unwrap();
|
||||||
|
assert_eq!(confirmed_blocks, vec![3, 4, 8]);
|
||||||
|
|
||||||
|
let req = r#"{"jsonrpc":"2.0","id":1,"method":"getConfirmedBlocksWithLimit","params":[2,500000]}"#;
|
||||||
|
let res = io.handle_request_sync(&req, meta.clone());
|
||||||
|
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||||
|
.expect("actual response deserialization");
|
||||||
|
let confirmed_blocks: Vec<Slot> = serde_json::from_value(result["result"].clone()).unwrap();
|
||||||
|
assert_eq!(confirmed_blocks, vec![3, 4, 8]);
|
||||||
|
|
||||||
|
let req = r#"{"jsonrpc":"2.0","id":1,"method":"getConfirmedBlocksWithLimit","params":[9,500000]}"#;
|
||||||
|
let res = io.handle_request_sync(&req, meta);
|
||||||
|
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||||
|
.expect("actual response deserialization");
|
||||||
|
let confirmed_blocks: Vec<Slot> = serde_json::from_value(result["result"].clone()).unwrap();
|
||||||
|
assert_eq!(confirmed_blocks, Vec::<Slot>::new());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_block_time() {
|
fn test_get_block_time() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
|
|
|
@ -23,6 +23,7 @@ To interact with a Solana node inside a JavaScript application, use the [solana-
|
||||||
- [getClusterNodes](jsonrpc-api.md#getclusternodes)
|
- [getClusterNodes](jsonrpc-api.md#getclusternodes)
|
||||||
- [getConfirmedBlock](jsonrpc-api.md#getconfirmedblock)
|
- [getConfirmedBlock](jsonrpc-api.md#getconfirmedblock)
|
||||||
- [getConfirmedBlocks](jsonrpc-api.md#getconfirmedblocks)
|
- [getConfirmedBlocks](jsonrpc-api.md#getconfirmedblocks)
|
||||||
|
- [getConfirmedBlocksWithLimit](jsonrpc-api.md#getconfirmedblockswithlimit)
|
||||||
- [getConfirmedSignaturesForAddress](jsonrpc-api.md#getconfirmedsignaturesforaddress)
|
- [getConfirmedSignaturesForAddress](jsonrpc-api.md#getconfirmedsignaturesforaddress)
|
||||||
- [getConfirmedSignaturesForAddress2](jsonrpc-api.md#getconfirmedsignaturesforaddress2)
|
- [getConfirmedSignaturesForAddress2](jsonrpc-api.md#getconfirmedsignaturesforaddress2)
|
||||||
- [getConfirmedTransaction](jsonrpc-api.md#getconfirmedtransaction)
|
- [getConfirmedTransaction](jsonrpc-api.md#getconfirmedtransaction)
|
||||||
|
@ -392,7 +393,7 @@ The JSON structure of inner instructions is defined as a list of objects in the
|
||||||
|
|
||||||
### getConfirmedBlocks
|
### getConfirmedBlocks
|
||||||
|
|
||||||
Returns a list of confirmed blocks
|
Returns a list of confirmed blocks between two slots
|
||||||
|
|
||||||
#### Parameters:
|
#### Parameters:
|
||||||
|
|
||||||
|
@ -416,6 +417,30 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"m
|
||||||
{"jsonrpc":"2.0","result":[5,6,7,8,9,10],"id":1}
|
{"jsonrpc":"2.0","result":[5,6,7,8,9,10],"id":1}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### getConfirmedBlocksWithLimit
|
||||||
|
|
||||||
|
Returns a list of confirmed blocks starting at the given slot
|
||||||
|
|
||||||
|
#### Parameters:
|
||||||
|
|
||||||
|
- `<u64>` - start_slot, as u64 integer
|
||||||
|
- `<u64>` - limit, as u64 integer
|
||||||
|
|
||||||
|
#### Results:
|
||||||
|
|
||||||
|
The result field will be an array of u64 integers listing confirmed blocks
|
||||||
|
starting at `start_slot` for up to `limit` blocks, inclusive.
|
||||||
|
|
||||||
|
#### Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
// Request
|
||||||
|
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlockWithLimit2","params":[5, 3]}' localhost:8899
|
||||||
|
|
||||||
|
// Result
|
||||||
|
{"jsonrpc":"2.0","result":[5,6,7],"id":1}
|
||||||
|
```
|
||||||
|
|
||||||
### getConfirmedSignaturesForAddress
|
### getConfirmedSignaturesForAddress
|
||||||
|
|
||||||
**DEPRECATED: Please use getConfirmedSignaturesForAddress2 instead**
|
**DEPRECATED: Please use getConfirmedSignaturesForAddress2 instead**
|
||||||
|
|
Loading…
Reference in New Issue