diff --git a/client/src/rpc_request.rs b/client/src/rpc_request.rs index bd93bdd0ee..22c5d5e12b 100644 --- a/client/src/rpc_request.rs +++ b/client/src/rpc_request.rs @@ -102,6 +102,7 @@ impl fmt::Display for RpcRequest { pub const NUM_LARGEST_ACCOUNTS: usize = 20; pub const MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS: usize = 256; pub const MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS_SLOT_RANGE: u64 = 10_000; +pub const MAX_GET_CONFIRMED_BLOCKS_RANGE: u64 = 500_000; // Validators that are this number of slots behind are considered delinquent pub const DELINQUENT_VALIDATOR_SLOT_DISTANCE: u64 = 128; diff --git a/core/src/rpc.rs b/core/src/rpc.rs index d210c425c5..2c192076df 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -13,7 +13,8 @@ use solana_client::{ rpc_config::*, rpc_filter::RpcFilterType, rpc_request::{ - DELINQUENT_VALIDATOR_SLOT_DISTANCE, MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS_SLOT_RANGE, + DELINQUENT_VALIDATOR_SLOT_DISTANCE, MAX_GET_CONFIRMED_BLOCKS_RANGE, + MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS_SLOT_RANGE, MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS, NUM_LARGEST_ACCOUNTS, }, rpc_response::Response as RpcResponse, @@ -576,6 +577,12 @@ impl JsonRpcRequestProcessor { if end_slot < start_slot { return Ok(vec![]); } + if end_slot - start_slot > MAX_GET_CONFIRMED_BLOCKS_RANGE { + return Err(Error::invalid_params(format!( + "Slot range too large; max {}", + MAX_GET_CONFIRMED_BLOCKS_RANGE + ))); + } Ok(self .blockstore .rooted_slot_iterator(max(start_slot, self.blockstore.lowest_slot())) @@ -3552,11 +3559,37 @@ pub mod tests { assert_eq!(confirmed_blocks, vec![1, 3, 4]); let req = r#"{"jsonrpc":"2.0","id":1,"method":"getConfirmedBlocks","params":[9,11]}"#; - let res = io.handle_request_sync(&req, meta); + 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 = serde_json::from_value(result["result"].clone()).unwrap(); assert_eq!(confirmed_blocks, Vec::::new()); + + block_commitment_cache + .write() + .unwrap() + .set_largest_confirmed_root(std::u64::MAX); + let req = format!( + r#"{{"jsonrpc":"2.0","id":1,"method":"getConfirmedBlocks","params":[0,{}]}}"#, + MAX_GET_CONFIRMED_BLOCKS_RANGE + ); + 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 = serde_json::from_value(result["result"].clone()).unwrap(); + assert_eq!(confirmed_blocks, vec![1, 3, 4, 8]); + + let req = format!( + r#"{{"jsonrpc":"2.0","id":1,"method":"getConfirmedBlocks","params":[0,{}]}}"#, + MAX_GET_CONFIRMED_BLOCKS_RANGE + 1 + ); + let res = io.handle_request_sync(&req, meta); + assert_eq!( + res, + Some( + r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Slot range too large; max 500000"},"id":1}"#.to_string(), + ) + ); } #[test] diff --git a/docs/src/apps/jsonrpc-api.md b/docs/src/apps/jsonrpc-api.md index 2c992f5c80..7551979a26 100644 --- a/docs/src/apps/jsonrpc-api.md +++ b/docs/src/apps/jsonrpc-api.md @@ -363,8 +363,9 @@ Returns a list of confirmed blocks #### Results: The result field will be an array of u64 integers listing confirmed blocks -between start_slot and either end_slot, if provided, or latest confirmed block, -inclusive. +between `start_slot` and either `end_slot`, if provided, or latest confirmed block, +inclusive. Max range allowed is 500,000 slots. + #### Example: @@ -378,7 +379,8 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0","id":1,"m ### getConfirmedSignaturesForAddress -Returns a list of all the confirmed signatures for transactions involving an address, within a specified Slot range. Max range allowed is 10_000 Slots. +Returns a list of all the confirmed signatures for transactions involving an +address, within a specified Slot range. Max range allowed is 10,000 Slots #### Parameters: