From e9bc1c6b07ecc9e1c251ccad0633e338d5cca281 Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Wed, 26 May 2021 01:26:19 -0600 Subject: [PATCH] Add last valid block height to rpc Fees (#17506) * Add last_valid_block_height to fees rpc * Add getBlockHeight rpc * Update docs --- cli/src/cluster_query.rs | 4 +-- client/src/rpc_client.rs | 28 +++++++++++++++++++ client/src/rpc_request.rs | 2 ++ client/src/rpc_response.rs | 9 +++++++ core/src/rpc.rs | 25 +++++++++++++++++ docs/src/developing/clients/jsonrpc-api.md | 31 +++++++++++++++++++++- runtime/src/bank.rs | 10 +++++++ 7 files changed, 106 insertions(+), 3 deletions(-) diff --git a/cli/src/cluster_query.rs b/cli/src/cluster_query.rs index 9e7b57fa82..b4874b1b21 100644 --- a/cli/src/cluster_query.rs +++ b/cli/src/cluster_query.rs @@ -1093,8 +1093,8 @@ pub fn process_get_slot(rpc_client: &RpcClient, _config: &CliConfig) -> ProcessR } pub fn process_get_block_height(rpc_client: &RpcClient, _config: &CliConfig) -> ProcessResult { - let epoch_info = rpc_client.get_epoch_info()?; - Ok(epoch_info.block_height.to_string()) + let block_height = rpc_client.get_block_height()?; + Ok(block_height.to_string()) } pub fn parse_show_block_production(matches: &ArgMatches<'_>) -> Result { diff --git a/client/src/rpc_client.rs b/client/src/rpc_client.rs index 76db5a4499..c54ef4ad94 100644 --- a/client/src/rpc_client.rs +++ b/client/src/rpc_client.rs @@ -426,6 +426,20 @@ impl RpcClient { ) } + pub fn get_block_height(&self) -> ClientResult { + self.get_block_height_with_commitment(self.commitment_config) + } + + pub fn get_block_height_with_commitment( + &self, + commitment_config: CommitmentConfig, + ) -> ClientResult { + self.send( + RpcRequest::GetBlockHeight, + json!([self.maybe_map_commitment(commitment_config)?]), + ) + } + pub fn get_slot_leaders(&self, start_slot: Slot, limit: u64) -> ClientResult> { self.send(RpcRequest::GetSlotLeaders, json!([start_slot, limit])) .and_then(|slot_leaders: Vec| { @@ -1230,6 +1244,7 @@ impl RpcClient { blockhash, fee_calculator, last_valid_slot, + .. }, }) = self .send::>( @@ -1237,6 +1252,19 @@ impl RpcClient { json!([self.maybe_map_commitment(commitment_config)?]), ) { (context, blockhash, fee_calculator, last_valid_slot) + } else if let Ok(Response { + context, + value: + DeprecatedRpcFees { + blockhash, + fee_calculator, + last_valid_slot, + }, + }) = self.send::>( + RpcRequest::GetFees, + json!([self.maybe_map_commitment(commitment_config)?]), + ) { + (context, blockhash, fee_calculator, last_valid_slot) } else if let Ok(Response { context, value: diff --git a/client/src/rpc_request.rs b/client/src/rpc_request.rs index b57d153c61..25d76ff284 100644 --- a/client/src/rpc_request.rs +++ b/client/src/rpc_request.rs @@ -12,6 +12,7 @@ pub enum RpcRequest { GetAccountInfo, GetBalance, GetBlock, + GetBlockHeight, GetBlockProduction, GetBlocks, GetBlocksWithLimit, @@ -95,6 +96,7 @@ impl fmt::Display for RpcRequest { RpcRequest::GetAccountInfo => "getAccountInfo", RpcRequest::GetBalance => "getBalance", RpcRequest::GetBlock => "getBlock", + RpcRequest::GetBlockHeight => "getBlockHeight", RpcRequest::GetBlockProduction => "getBlockProduction", RpcRequest::GetBlocks => "getBlocks", RpcRequest::GetBlocksWithLimit => "getBlocksWithLimit", diff --git a/client/src/rpc_response.rs b/client/src/rpc_response.rs index 680e018d77..9e60266468 100644 --- a/client/src/rpc_response.rs +++ b/client/src/rpc_response.rs @@ -46,6 +46,15 @@ pub struct RpcFees { pub blockhash: String, pub fee_calculator: FeeCalculator, pub last_valid_slot: Slot, + pub last_valid_block_height: u64, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct DeprecatedRpcFees { + pub blockhash: String, + pub fee_calculator: FeeCalculator, + pub last_valid_slot: Slot, } #[derive(Serialize, Deserialize, Clone, Debug)] diff --git a/core/src/rpc.rs b/core/src/rpc.rs index d5d9bafe7a..c92d103f6e 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -545,12 +545,16 @@ impl JsonRpcRequestProcessor { let last_valid_slot = bank .get_blockhash_last_valid_slot(&blockhash) .expect("bank blockhash queue should contain blockhash"); + let last_valid_block_height = bank + .get_blockhash_last_valid_block_height(&blockhash) + .expect("bank blockhash queue should contain blockhash"); new_response( &bank, RpcFees { blockhash: blockhash.to_string(), fee_calculator, last_valid_slot, + last_valid_block_height, }, ) } @@ -606,6 +610,10 @@ impl JsonRpcRequestProcessor { self.bank(commitment).slot() } + fn get_block_height(&self, commitment: Option) -> u64 { + self.bank(commitment).block_height() + } + fn get_max_retransmit_slot(&self) -> Slot { self.max_slots.retransmit.load(Ordering::Relaxed) } @@ -2094,6 +2102,13 @@ pub mod rpc_minimal { commitment: Option, ) -> Result; + #[rpc(meta, name = "getBlockHeight")] + fn get_block_height( + &self, + meta: Self::Metadata, + commitment: Option, + ) -> Result; + #[rpc(meta, name = "getSnapshotSlot")] fn get_snapshot_slot(&self, meta: Self::Metadata) -> Result; @@ -2182,6 +2197,15 @@ pub mod rpc_minimal { Ok(meta.get_slot(commitment)) } + fn get_block_height( + &self, + meta: Self::Metadata, + commitment: Option, + ) -> Result { + debug!("get_block_height rpc request received"); + Ok(meta.get_block_height(commitment)) + } + fn get_snapshot_slot(&self, meta: Self::Metadata) -> Result { debug!("get_snapshot_slot rpc request received"); @@ -5215,6 +5239,7 @@ pub mod tests { "lamportsPerSignature": 0, }, "lastValidSlot": MAX_RECENT_BLOCKHASHES, + "lastValidBlockHeight": MAX_RECENT_BLOCKHASHES, }}, "id": 1 }); diff --git a/docs/src/developing/clients/jsonrpc-api.md b/docs/src/developing/clients/jsonrpc-api.md index a2bad32c65..b37bd3f6e9 100644 --- a/docs/src/developing/clients/jsonrpc-api.md +++ b/docs/src/developing/clients/jsonrpc-api.md @@ -21,6 +21,7 @@ gives a convenient interface for the RPC methods. - [getAccountInfo](jsonrpc-api.md#getaccountinfo) - [getBalance](jsonrpc-api.md#getbalance) - [getBlock](jsonrpc-api.md#getblock) +- [getBlockHeight](jsonrpc-api.md#getblockheight) - [getBlockProduction](jsonrpc-api.md#getblockproduction) - [getBlockCommitment](jsonrpc-api.md#getblockcommitment) - [getBlocks](jsonrpc-api.md#getblocks) @@ -578,6 +579,32 @@ The JSON structure of token balances is defined as a list of objects in the foll - `uiAmountString: ` - Token amount as a string, accounting for decimals. +### getBlockHeight + +Returns the current block height of the node + +#### Parameters: + +- `` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment) + +#### Results: + +- `` - Current block height + +#### Example: + +Request: +```bash +curl http://localhost:8899 -X POST -H "Content-Type: application/json" -d ' + {"jsonrpc":"2.0","id":1, "method":"getBlockHeight"} +' +``` + +Result: +```json +{"jsonrpc":"2.0","result":1233,"id":1} +``` + ### getBlockProduction Returns recent block production information from the current or previous epoch. @@ -1066,6 +1093,7 @@ The result will be an RpcResponse JSON object with `value` set to a JSON object - `blockhash: ` - a Hash as base-58 encoded string - `feeCalculator: ` - FeeCalculator object, the fee schedule for this block hash - `lastValidSlot: ` - DEPRECATED - this value is inaccurate and should not be relied upon +- `lastValidBlockHeight: ` - last [block height](../../terminology.md#block-height) at which a blockhash will be valid #### Example: @@ -1089,7 +1117,8 @@ Result: "feeCalculator": { "lamportsPerSignature": 5000 }, - "lastValidSlot": 297 + "lastValidSlot": 297, + "lastValidBlockHeight": 296 } }, "id": 1 diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index c3e2c08302..cf50ab5f2a 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -2415,6 +2415,7 @@ impl Bank { &self.fee_rate_governor } + // DEPRECATED pub fn get_blockhash_last_valid_slot(&self, blockhash: &Hash) -> Option { let blockhash_queue = self.blockhash_queue.read().unwrap(); // This calculation will need to be updated to consider epoch boundaries if BlockhashQueue @@ -2424,6 +2425,15 @@ impl Bank { .map(|age| self.slot + blockhash_queue.len() as u64 - age) } + pub fn get_blockhash_last_valid_block_height(&self, blockhash: &Hash) -> Option { + let blockhash_queue = self.blockhash_queue.read().unwrap(); + // This calculation will need to be updated to consider epoch boundaries if BlockhashQueue + // length is made variable by epoch + blockhash_queue + .get_hash_age(blockhash) + .map(|age| self.block_height + blockhash_queue.len() as u64 - age) + } + pub fn confirmed_last_blockhash(&self) -> (Hash, FeeCalculator) { const NUM_BLOCKHASH_CONFIRMATIONS: usize = 3;