diff --git a/core/src/rpc.rs b/core/src/rpc.rs index fb288a1b01..6dc85e4122 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -3233,9 +3233,9 @@ pub mod rpc_full { let mut slot = first_slot; for identity in slot_leaders { - slot += 1; if let Some(ref filter_by_identity) = filter_by_identity { if identity != *filter_by_identity { + slot += 1; continue; } } @@ -3245,6 +3245,7 @@ pub mod rpc_full { entry.1 += 1; // Increment blocks_produced } entry.0 += 1; // Increment leader_slots + slot += 1; } Ok(new_response( @@ -5813,6 +5814,83 @@ pub mod tests { assert_eq!(confirmed_block.rewards.unwrap(), vec![]); } + #[test] + fn test_get_block_production() { + let bob_pubkey = solana_sdk::pubkey::new_rand(); + let roots = vec![0, 1, 3, 4, 8]; + let RpcHandler { + io, + meta, + block_commitment_cache, + leader_pubkey, + .. + } = start_rpc_handler_with_tx_and_blockstore(&bob_pubkey, roots); + block_commitment_cache + .write() + .unwrap() + .set_highest_confirmed_root(8); + + let req = r#"{"jsonrpc":"2.0","id":1,"method":"getBlockProduction","params":[]}"#; + 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 block_production: RpcBlockProduction = + serde_json::from_value(result["result"]["value"].clone()).unwrap(); + assert_eq!( + block_production.by_identity.get(&leader_pubkey.to_string()), + Some(&(9, 5)) + ); + assert_eq!( + block_production.range, + RpcBlockProductionRange { + first_slot: 0, + last_slot: 8 + } + ); + + let req = format!( + r#"{{"jsonrpc":"2.0","id":1,"method":"getBlockProduction","params":[{{"identity": "{}"}}]}}"#, + leader_pubkey + ); + 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 block_production: RpcBlockProduction = + serde_json::from_value(result["result"]["value"].clone()).unwrap(); + assert_eq!( + block_production.by_identity.get(&leader_pubkey.to_string()), + Some(&(9, 5)) + ); + assert_eq!( + block_production.range, + RpcBlockProductionRange { + first_slot: 0, + last_slot: 8 + } + ); + + let req = format!( + r#"{{"jsonrpc":"2.0","id":1,"method":"getBlockProduction","params":[{{"range": {{"firstSlot": 0, "lastSlot": 4}}, "identity": "{}"}}]}}"#, + bob_pubkey + ); + let res = io.handle_request_sync(&req, meta); + let result: Value = serde_json::from_str(&res.expect("actual response")) + .expect("actual response deserialization"); + let block_production: RpcBlockProduction = + serde_json::from_value(result["result"]["value"].clone()).unwrap(); + assert_eq!( + block_production.by_identity.get(&leader_pubkey.to_string()), + None + ); + assert_eq!( + block_production.range, + RpcBlockProductionRange { + first_slot: 0, + last_slot: 4 + } + ); + } + #[test] fn test_get_blocks() { let bob_pubkey = solana_sdk::pubkey::new_rand(); diff --git a/docs/src/developing/clients/jsonrpc-api.md b/docs/src/developing/clients/jsonrpc-api.md index 63ddb991a6..375c38bbf4 100644 --- a/docs/src/developing/clients/jsonrpc-api.md +++ b/docs/src/developing/clients/jsonrpc-api.md @@ -595,7 +595,7 @@ The result will be an RpcResponse JSON object with `value` equal to: - `byIdentity: ` - a dictionary of validator identities, as base-58 encoded strings. Value is a two element array containing the number of leader slots and the number of blocks produced. - - `range: ` - Slot range to return block production for. If parameter not provided, defaults to current epoch. + - `range: ` - Block production slot range - `firstSlot: ` - first slot of the block production information (inclusive) - `lastSlot: ` - last slot of block production information (inclusive)