RPC: add option to exclude accounts from get_supply (#19270)

This commit is contained in:
Justin Starry 2021-08-17 16:32:58 -07:00 committed by GitHub
parent c167211611
commit c053df143f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 12 deletions

View File

@ -116,6 +116,15 @@ pub struct RpcLargestAccountsConfig {
pub filter: Option<RpcLargestAccountsFilter>,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcSupplyConfig {
#[serde(flatten)]
pub commitment: Option<CommitmentConfig>,
#[serde(default)]
pub exclude_non_circulating_accounts_list: bool,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcEpochConfig {

View File

@ -2413,7 +2413,9 @@ Returns information about the current supply.
#### Parameters:
- `<object>` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
- `<object>` - (optional) Configuration object containing the following optional fields:
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
- (optional) `excludeNonCirculatingAccountsList: <bool>` - exclude non circulating accounts list from response
#### Results:
@ -2422,7 +2424,7 @@ The result will be an RpcResponse JSON object with `value` equal to a JSON objec
- `total: <u64>` - Total supply in lamports
- `circulating: <u64>` - Circulating supply in lamports
- `nonCirculating: <u64>` - Non-circulating supply in lamports
- `nonCirculatingAccounts: <array>` - an array of account addresses of non-circulating accounts, as strings
- `nonCirculatingAccounts: <array>` - an array of account addresses of non-circulating accounts, as strings. If `excludeNonCirculatingAccountsList` is enabled, the returned array will be empty.
#### Example:

View File

@ -763,25 +763,32 @@ impl JsonRpcRequestProcessor {
fn get_supply(
&self,
commitment: Option<CommitmentConfig>,
config: Option<RpcSupplyConfig>,
) -> RpcCustomResult<RpcResponse<RpcSupply>> {
let bank = self.bank(commitment);
let config = config.unwrap_or_default();
let bank = self.bank(config.commitment);
let non_circulating_supply =
calculate_non_circulating_supply(&bank).map_err(|e| RpcCustomError::ScanError {
message: e.to_string(),
})?;
let total_supply = bank.capitalization();
let non_circulating_accounts = if config.exclude_non_circulating_accounts_list {
vec![]
} else {
non_circulating_supply
.accounts
.iter()
.map(|pubkey| pubkey.to_string())
.collect()
};
Ok(new_response(
&bank,
RpcSupply {
total: total_supply,
circulating: total_supply - non_circulating_supply.lamports,
non_circulating: non_circulating_supply.lamports,
non_circulating_accounts: non_circulating_supply
.accounts
.iter()
.map(|pubkey| pubkey.to_string())
.collect(),
non_circulating_accounts,
},
))
}
@ -2702,7 +2709,7 @@ pub mod rpc_accounts {
fn get_supply(
&self,
meta: Self::Metadata,
commitment: Option<CommitmentConfig>,
config: Option<RpcSupplyConfig>,
) -> Result<RpcResponse<RpcSupply>>;
#[rpc(meta, name = "getStakeActivation")]
@ -2856,10 +2863,10 @@ pub mod rpc_accounts {
fn get_supply(
&self,
meta: Self::Metadata,
commitment: Option<CommitmentConfig>,
config: Option<RpcSupplyConfig>,
) -> Result<RpcResponse<RpcSupply>> {
debug!("get_supply rpc request received");
Ok(meta.get_supply(commitment)?)
Ok(meta.get_supply(config)?)
}
fn get_stake_activation(
@ -4655,6 +4662,21 @@ pub mod tests {
}
}
#[test]
fn test_get_supply_exclude_account_list() {
let bob_pubkey = solana_sdk::pubkey::new_rand();
let RpcHandler { io, meta, .. } = start_rpc_handler_with_tx(&bob_pubkey);
let req = r#"{"jsonrpc":"2.0","id":1,"method":"getSupply","params":[{"excludeNonCirculatingAccountsList":true}]}"#;
let res = io.handle_request_sync(req, meta);
let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
let supply: RpcSupply = serde_json::from_value(json["result"]["value"].clone())
.expect("actual response deserialization");
assert_eq!(supply.non_circulating, 20);
assert!(supply.circulating >= TEST_MINT_LAMPORTS);
assert!(supply.total >= TEST_MINT_LAMPORTS + 20);
assert!(supply.non_circulating_accounts.is_empty());
}
#[test]
fn test_get_largest_accounts() {
let bob_pubkey = solana_sdk::pubkey::new_rand();