diff --git a/client/src/rpc_filter.rs b/client/src/rpc_filter.rs index 416742d591..500f74f9c0 100644 --- a/client/src/rpc_filter.rs +++ b/client/src/rpc_filter.rs @@ -16,10 +16,15 @@ impl RpcFilterType { match encoding { MemcmpEncoding::Binary => { let MemcmpEncodedBytes::Binary(bytes) = &compare.bytes; - bs58::decode(&bytes) - .into_vec() - .map(|_| ()) - .map_err(|e| e.into()) + + if bytes.len() > 128 { + Err(RpcFilterError::Base58DataTooLarge) + } 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 { #[error("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)] @@ -140,4 +147,36 @@ mod tests { } .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) + ); + } } diff --git a/docs/src/developing/clients/jsonrpc-api.md b/docs/src/developing/clients/jsonrpc-api.md index 093e9469c5..1fe1744816 100644 --- a/docs/src/developing/clients/jsonrpc-api.md +++ b/docs/src/developing/clients/jsonrpc-api.md @@ -207,7 +207,7 @@ Returns all information associated with the account of provided Pubkey fields: - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment) - `encoding: ` - 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+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 ``. @@ -1806,7 +1806,7 @@ Returns all accounts owned by the provided program Pubkey ##### Filters: - `memcmp: ` - compares a provided series of bytes with program account data at a particular offset. Fields: - `offset: ` - offset into program account data to start comparison - - `bytes: ` - data to match, as base-58 encoded string + - `bytes: ` - data to match, as base-58 encoded string and limited to less than 129 bytes - `dataSize: ` - compares the program account data length with the provided data size