RPC: add option to exclude accounts from get_supply (#19270)
This commit is contained in:
parent
c167211611
commit
c053df143f
|
@ -116,6 +116,15 @@ pub struct RpcLargestAccountsConfig {
|
||||||
pub filter: Option<RpcLargestAccountsFilter>,
|
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)]
|
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct RpcEpochConfig {
|
pub struct RpcEpochConfig {
|
||||||
|
|
|
@ -2413,7 +2413,9 @@ Returns information about the current supply.
|
||||||
|
|
||||||
#### Parameters:
|
#### 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:
|
#### 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
|
- `total: <u64>` - Total supply in lamports
|
||||||
- `circulating: <u64>` - Circulating supply in lamports
|
- `circulating: <u64>` - Circulating supply in lamports
|
||||||
- `nonCirculating: <u64>` - Non-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:
|
#### Example:
|
||||||
|
|
||||||
|
|
|
@ -763,25 +763,32 @@ impl JsonRpcRequestProcessor {
|
||||||
|
|
||||||
fn get_supply(
|
fn get_supply(
|
||||||
&self,
|
&self,
|
||||||
commitment: Option<CommitmentConfig>,
|
config: Option<RpcSupplyConfig>,
|
||||||
) -> RpcCustomResult<RpcResponse<RpcSupply>> {
|
) -> RpcCustomResult<RpcResponse<RpcSupply>> {
|
||||||
let bank = self.bank(commitment);
|
let config = config.unwrap_or_default();
|
||||||
|
let bank = self.bank(config.commitment);
|
||||||
let non_circulating_supply =
|
let non_circulating_supply =
|
||||||
calculate_non_circulating_supply(&bank).map_err(|e| RpcCustomError::ScanError {
|
calculate_non_circulating_supply(&bank).map_err(|e| RpcCustomError::ScanError {
|
||||||
message: e.to_string(),
|
message: e.to_string(),
|
||||||
})?;
|
})?;
|
||||||
let total_supply = bank.capitalization();
|
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(
|
Ok(new_response(
|
||||||
&bank,
|
&bank,
|
||||||
RpcSupply {
|
RpcSupply {
|
||||||
total: total_supply,
|
total: total_supply,
|
||||||
circulating: total_supply - non_circulating_supply.lamports,
|
circulating: total_supply - non_circulating_supply.lamports,
|
||||||
non_circulating: non_circulating_supply.lamports,
|
non_circulating: non_circulating_supply.lamports,
|
||||||
non_circulating_accounts: non_circulating_supply
|
non_circulating_accounts,
|
||||||
.accounts
|
|
||||||
.iter()
|
|
||||||
.map(|pubkey| pubkey.to_string())
|
|
||||||
.collect(),
|
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -2702,7 +2709,7 @@ pub mod rpc_accounts {
|
||||||
fn get_supply(
|
fn get_supply(
|
||||||
&self,
|
&self,
|
||||||
meta: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
commitment: Option<CommitmentConfig>,
|
config: Option<RpcSupplyConfig>,
|
||||||
) -> Result<RpcResponse<RpcSupply>>;
|
) -> Result<RpcResponse<RpcSupply>>;
|
||||||
|
|
||||||
#[rpc(meta, name = "getStakeActivation")]
|
#[rpc(meta, name = "getStakeActivation")]
|
||||||
|
@ -2856,10 +2863,10 @@ pub mod rpc_accounts {
|
||||||
fn get_supply(
|
fn get_supply(
|
||||||
&self,
|
&self,
|
||||||
meta: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
commitment: Option<CommitmentConfig>,
|
config: Option<RpcSupplyConfig>,
|
||||||
) -> Result<RpcResponse<RpcSupply>> {
|
) -> Result<RpcResponse<RpcSupply>> {
|
||||||
debug!("get_supply rpc request received");
|
debug!("get_supply rpc request received");
|
||||||
Ok(meta.get_supply(commitment)?)
|
Ok(meta.get_supply(config)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_stake_activation(
|
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]
|
#[test]
|
||||||
fn test_get_largest_accounts() {
|
fn test_get_largest_accounts() {
|
||||||
let bob_pubkey = solana_sdk::pubkey::new_rand();
|
let bob_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
|
|
Loading…
Reference in New Issue