* Limit getProgramAccounts memcpy filter string to 128 bytes (cherry picked from commit65f1afe5e1
) * Limit the number of getProgramAccounts filters (cherry picked from commit4b0114b991
) Co-authored-by: Michael Vines <mvines@gmail.com>
This commit is contained in:
@ -16,10 +16,15 @@ impl RpcFilterType {
|
|||||||
match encoding {
|
match encoding {
|
||||||
MemcmpEncoding::Binary => {
|
MemcmpEncoding::Binary => {
|
||||||
let MemcmpEncodedBytes::Binary(bytes) = &compare.bytes;
|
let MemcmpEncodedBytes::Binary(bytes) = &compare.bytes;
|
||||||
bs58::decode(&bytes)
|
|
||||||
.into_vec()
|
if bytes.len() > 128 {
|
||||||
.map(|_| ())
|
Err(RpcFilterError::Base58DataTooLarge)
|
||||||
.map_err(|e| e.into())
|
} else {
|
||||||
|
bs58::decode(&bytes)
|
||||||
|
.into_vec()
|
||||||
|
.map(|_| ())
|
||||||
|
.map_err(|e| e.into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27,10 +32,12 @@ impl RpcFilterType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, PartialEq, Debug)]
|
||||||
pub enum RpcFilterError {
|
pub enum RpcFilterError {
|
||||||
#[error("bs58 decode error")]
|
#[error("bs58 decode error")]
|
||||||
DecodeError(#[from] bs58::decode::Error),
|
DecodeError(#[from] bs58::decode::Error),
|
||||||
|
#[error("encoded binary (base 58) data should be less than 129 bytes")]
|
||||||
|
Base58DataTooLarge,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
@ -140,4 +147,36 @@ mod tests {
|
|||||||
}
|
}
|
||||||
.bytes_match(&data));
|
.bytes_match(&data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_verify_memcmp() {
|
||||||
|
let base58_bytes = "\
|
||||||
|
1111111111111111111111111111111111111111111111111111111111111111\
|
||||||
|
1111111111111111111111111111111111111111111111111111111111111111";
|
||||||
|
assert_eq!(base58_bytes.len(), 128);
|
||||||
|
assert_eq!(
|
||||||
|
RpcFilterType::Memcmp(Memcmp {
|
||||||
|
offset: 0,
|
||||||
|
bytes: MemcmpEncodedBytes::Binary(base58_bytes.to_string()),
|
||||||
|
encoding: None,
|
||||||
|
})
|
||||||
|
.verify(),
|
||||||
|
Ok(())
|
||||||
|
);
|
||||||
|
|
||||||
|
let base58_bytes = "\
|
||||||
|
1111111111111111111111111111111111111111111111111111111111111111\
|
||||||
|
1111111111111111111111111111111111111111111111111111111111111111\
|
||||||
|
1";
|
||||||
|
assert_eq!(base58_bytes.len(), 129);
|
||||||
|
assert_eq!(
|
||||||
|
RpcFilterType::Memcmp(Memcmp {
|
||||||
|
offset: 0,
|
||||||
|
bytes: MemcmpEncodedBytes::Binary(base58_bytes.to_string()),
|
||||||
|
encoding: None,
|
||||||
|
})
|
||||||
|
.verify(),
|
||||||
|
Err(RpcFilterError::Base58DataTooLarge)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,7 @@ pub const MAX_GET_CONFIRMED_BLOCKS_RANGE: u64 = 500_000;
|
|||||||
pub const MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS2_LIMIT: usize = 1_000;
|
pub const MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS2_LIMIT: usize = 1_000;
|
||||||
pub const MAX_MULTIPLE_ACCOUNTS: usize = 100;
|
pub const MAX_MULTIPLE_ACCOUNTS: usize = 100;
|
||||||
pub const NUM_LARGEST_ACCOUNTS: usize = 20;
|
pub const NUM_LARGEST_ACCOUNTS: usize = 20;
|
||||||
|
pub const MAX_GET_PROGRAM_ACCOUNT_FILTERS: usize = 4;
|
||||||
|
|
||||||
// Validators that are this number of slots behind are considered delinquent
|
// Validators that are this number of slots behind are considered delinquent
|
||||||
pub const DELINQUENT_VALIDATOR_SLOT_DISTANCE: u64 = 128;
|
pub const DELINQUENT_VALIDATOR_SLOT_DISTANCE: u64 = 128;
|
||||||
|
@ -28,7 +28,7 @@ use solana_client::{
|
|||||||
rpc_request::{
|
rpc_request::{
|
||||||
TokenAccountsFilter, DELINQUENT_VALIDATOR_SLOT_DISTANCE, MAX_GET_CONFIRMED_BLOCKS_RANGE,
|
TokenAccountsFilter, DELINQUENT_VALIDATOR_SLOT_DISTANCE, MAX_GET_CONFIRMED_BLOCKS_RANGE,
|
||||||
MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS2_LIMIT,
|
MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS2_LIMIT,
|
||||||
MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS_SLOT_RANGE,
|
MAX_GET_CONFIRMED_SIGNATURES_FOR_ADDRESS_SLOT_RANGE, MAX_GET_PROGRAM_ACCOUNT_FILTERS,
|
||||||
MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS, MAX_MULTIPLE_ACCOUNTS, NUM_LARGEST_ACCOUNTS,
|
MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS, MAX_MULTIPLE_ACCOUNTS, NUM_LARGEST_ACCOUNTS,
|
||||||
},
|
},
|
||||||
rpc_response::Response as RpcResponse,
|
rpc_response::Response as RpcResponse,
|
||||||
@ -2223,6 +2223,12 @@ impl RpcSol for RpcSolImpl {
|
|||||||
} else {
|
} else {
|
||||||
(None, vec![])
|
(None, vec![])
|
||||||
};
|
};
|
||||||
|
if filters.len() > MAX_GET_PROGRAM_ACCOUNT_FILTERS {
|
||||||
|
return Err(Error::invalid_params(format!(
|
||||||
|
"Too many filters provided; max {}",
|
||||||
|
MAX_GET_PROGRAM_ACCOUNT_FILTERS
|
||||||
|
)));
|
||||||
|
}
|
||||||
for filter in &filters {
|
for filter in &filters {
|
||||||
verify_filter(filter)?;
|
verify_filter(filter)?;
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,7 @@ Returns all information associated with the account of provided Pubkey
|
|||||||
fields:
|
fields:
|
||||||
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
||||||
- `encoding: <string>` - encoding for Account data, either "base58" (*slow*), "base64", "base64+zstd", or "jsonParsed".
|
- `encoding: <string>` - encoding for Account data, either "base58" (*slow*), "base64", "base64+zstd", or "jsonParsed".
|
||||||
"base58" is limited to Account data of less than 128 bytes.
|
"base58" is limited to Account data of less than 129 bytes.
|
||||||
"base64" will return base64 encoded data for Account data of any size.
|
"base64" will return base64 encoded data for Account data of any size.
|
||||||
"base64+zstd" compresses the Account data using [Zstandard](https://facebook.github.io/zstd/) and base64-encodes the result.
|
"base64+zstd" compresses the Account data using [Zstandard](https://facebook.github.io/zstd/) and base64-encodes the result.
|
||||||
"jsonParsed" encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If "jsonParsed" is requested but a parser cannot be found, the field falls back to "base64" encoding, detectable when the `data` field is type `<string>`.
|
"jsonParsed" encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If "jsonParsed" is requested but a parser cannot be found, the field falls back to "base64" encoding, detectable when the `data` field is type `<string>`.
|
||||||
@ -1649,7 +1649,7 @@ Returns the account information for a list of Pubkeys
|
|||||||
- `<object>` - (optional) Configuration object containing the following optional fields:
|
- `<object>` - (optional) Configuration object containing the following optional fields:
|
||||||
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
||||||
- `encoding: <string>` - encoding for Account data, either "base58" (*slow*), "base64", "base64+zstd", or "jsonParsed".
|
- `encoding: <string>` - encoding for Account data, either "base58" (*slow*), "base64", "base64+zstd", or "jsonParsed".
|
||||||
"base58" is limited to Account data of less than 128 bytes.
|
"base58" is limited to Account data of less than 129 bytes.
|
||||||
"base64" will return base64 encoded data for Account data of any size.
|
"base64" will return base64 encoded data for Account data of any size.
|
||||||
"base64+zstd" compresses the Account data using [Zstandard](https://facebook.github.io/zstd/) and base64-encodes the result.
|
"base64+zstd" compresses the Account data using [Zstandard](https://facebook.github.io/zstd/) and base64-encodes the result.
|
||||||
"jsonParsed" encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If "jsonParsed" is requested but a parser cannot be found, the field falls back to "base64" encoding, detectable when the `data` field is type `<string>`.
|
"jsonParsed" encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If "jsonParsed" is requested but a parser cannot be found, the field falls back to "base64" encoding, detectable when the `data` field is type `<string>`.
|
||||||
@ -1796,7 +1796,7 @@ Returns all accounts owned by the provided program Pubkey
|
|||||||
- `<object>` - (optional) Configuration object containing the following optional fields:
|
- `<object>` - (optional) Configuration object containing the following optional fields:
|
||||||
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
- (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment)
|
||||||
- `encoding: <string>` - encoding for Account data, either "base58" (*slow*), "base64", "base64+zstd", or "jsonParsed".
|
- `encoding: <string>` - encoding for Account data, either "base58" (*slow*), "base64", "base64+zstd", or "jsonParsed".
|
||||||
"base58" is limited to Account data of less than 128 bytes.
|
"base58" is limited to Account data of less than 129 bytes.
|
||||||
"base64" will return base64 encoded data for Account data of any size.
|
"base64" will return base64 encoded data for Account data of any size.
|
||||||
"base64+zstd" compresses the Account data using [Zstandard](https://facebook.github.io/zstd/) and base64-encodes the result.
|
"base64+zstd" compresses the Account data using [Zstandard](https://facebook.github.io/zstd/) and base64-encodes the result.
|
||||||
"jsonParsed" encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If "jsonParsed" is requested but a parser cannot be found, the field falls back to "base64" encoding, detectable when the `data` field is type `<string>`.
|
"jsonParsed" encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data. If "jsonParsed" is requested but a parser cannot be found, the field falls back to "base64" encoding, detectable when the `data` field is type `<string>`.
|
||||||
@ -1806,7 +1806,7 @@ Returns all accounts owned by the provided program Pubkey
|
|||||||
##### Filters:
|
##### Filters:
|
||||||
- `memcmp: <object>` - compares a provided series of bytes with program account data at a particular offset. Fields:
|
- `memcmp: <object>` - compares a provided series of bytes with program account data at a particular offset. Fields:
|
||||||
- `offset: <usize>` - offset into program account data to start comparison
|
- `offset: <usize>` - offset into program account data to start comparison
|
||||||
- `bytes: <string>` - data to match, as base-58 encoded string
|
- `bytes: <string>` - data to match, as base-58 encoded string and limited to less than 129 bytes
|
||||||
|
|
||||||
- `dataSize: <u64>` - compares the program account data length with the provided data size
|
- `dataSize: <u64>` - compares the program account data length with the provided data size
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user