Add Memcmp filter constructor and deprecate fields (#29923)
* Deprecate Memcmp inner fields * Add Memcmp::new * Replace some literal construction * Add convert_to_raw_bytes method and use * Make convert_to_raw_bytes fallible * Allow literal matches for complex cases
This commit is contained in:
parent
d6fbf3fb17
commit
e39153df51
|
@ -133,18 +133,35 @@ pub enum MemcmpEncodedBytes {
|
|||
#[serde(into = "RpcMemcmp", from = "RpcMemcmp")]
|
||||
pub struct Memcmp {
|
||||
/// Data offset to begin match
|
||||
#[deprecated(
|
||||
since = "1.15.0",
|
||||
note = "Field will be made private in future. Please use a constructor method instead."
|
||||
)]
|
||||
pub offset: usize,
|
||||
/// Bytes, encoded with specified encoding, or default Binary
|
||||
#[deprecated(
|
||||
since = "1.15.0",
|
||||
note = "Field will be made private in future. Please use a constructor method instead."
|
||||
)]
|
||||
pub bytes: MemcmpEncodedBytes,
|
||||
/// Optional encoding specification
|
||||
#[deprecated(
|
||||
since = "1.11.2",
|
||||
note = "Field has no server-side effect. Specify encoding with `MemcmpEncodedBytes` variant instead."
|
||||
note = "Field has no server-side effect. Specify encoding with `MemcmpEncodedBytes` variant instead. \
|
||||
Field will be made private in future. Please use a constructor method instead."
|
||||
)]
|
||||
pub encoding: Option<MemcmpEncoding>,
|
||||
}
|
||||
|
||||
impl Memcmp {
|
||||
pub fn new(offset: usize, encoded_bytes: MemcmpEncodedBytes) -> Self {
|
||||
Self {
|
||||
offset,
|
||||
bytes: encoded_bytes,
|
||||
encoding: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_raw_bytes(offset: usize, bytes: Vec<u8>) -> Self {
|
||||
Self {
|
||||
offset,
|
||||
|
@ -170,6 +187,23 @@ impl Memcmp {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn convert_to_raw_bytes(&mut self) -> Result<(), RpcFilterError> {
|
||||
use MemcmpEncodedBytes::*;
|
||||
match &self.bytes {
|
||||
Binary(bytes) | Base58(bytes) => {
|
||||
let bytes = bs58::decode(bytes).into_vec()?;
|
||||
self.bytes = Bytes(bytes);
|
||||
Ok(())
|
||||
}
|
||||
Base64(bytes) => {
|
||||
let bytes = base64::decode(bytes)?;
|
||||
self.bytes = Bytes(bytes);
|
||||
Ok(())
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bytes_match(&self, data: &[u8]) -> bool {
|
||||
match self.bytes() {
|
||||
Some(bytes) => {
|
||||
|
|
|
@ -4421,11 +4421,10 @@ impl RpcClient {
|
|||
/// # AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
|
||||
/// # AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
|
||||
/// # AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||
/// let memcmp = RpcFilterType::Memcmp(Memcmp {
|
||||
/// offset: 0,
|
||||
/// bytes: MemcmpEncodedBytes::Base64(base64_bytes.to_string()),
|
||||
/// encoding: None,
|
||||
/// });
|
||||
/// let memcmp = RpcFilterType::Memcmp(Memcmp::new(
|
||||
/// 0, // offset
|
||||
/// MemcmpEncodedBytes::Base64(base64_bytes.to_string()), // encoded bytes
|
||||
/// ));
|
||||
/// let config = RpcProgramAccountsConfig {
|
||||
/// filters: Some(vec![
|
||||
/// RpcFilterType::DataSize(128),
|
||||
|
|
|
@ -3600,11 +3600,10 @@ impl RpcClient {
|
|||
/// # AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
|
||||
/// # AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
|
||||
/// # AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||
/// let memcmp = RpcFilterType::Memcmp(Memcmp {
|
||||
/// offset: 0,
|
||||
/// bytes: MemcmpEncodedBytes::Base64(base64_bytes.to_string()),
|
||||
/// encoding: None,
|
||||
/// });
|
||||
/// let memcmp = RpcFilterType::Memcmp(Memcmp::new(
|
||||
/// 0, // offset
|
||||
/// MemcmpEncodedBytes::Base64(base64_bytes.to_string()), // encoded bytes
|
||||
/// ));
|
||||
/// let config = RpcProgramAccountsConfig {
|
||||
/// filters: Some(vec![
|
||||
/// RpcFilterType::DataSize(128),
|
||||
|
|
|
@ -2174,20 +2174,9 @@ impl JsonRpcRequestProcessor {
|
|||
fn optimize_filters(filters: &mut [RpcFilterType]) {
|
||||
filters.iter_mut().for_each(|filter_type| {
|
||||
if let RpcFilterType::Memcmp(compare) = filter_type {
|
||||
use MemcmpEncodedBytes::*;
|
||||
match &compare.bytes {
|
||||
#[allow(deprecated)]
|
||||
Binary(bytes) | Base58(bytes) => {
|
||||
if let Ok(bytes) = bs58::decode(bytes).into_vec() {
|
||||
compare.bytes = Bytes(bytes);
|
||||
}
|
||||
}
|
||||
Base64(bytes) => {
|
||||
if let Ok(bytes) = base64::decode(bytes) {
|
||||
compare.bytes = Bytes(bytes);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
if let Err(err) = compare.convert_to_raw_bytes() {
|
||||
// All filters should have been previously verified
|
||||
warn!("Invalid filter: bytes could not be decoded, {err}");
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -2338,6 +2327,7 @@ fn get_spl_token_owner_filter(program_id: &Pubkey, filters: &[RpcFilterType]) ->
|
|||
for filter in filters {
|
||||
match filter {
|
||||
RpcFilterType::DataSize(size) => data_size_filter = Some(*size),
|
||||
#[allow(deprecated)]
|
||||
RpcFilterType::Memcmp(Memcmp {
|
||||
offset,
|
||||
bytes: MemcmpEncodedBytes::Bytes(bytes),
|
||||
|
@ -2345,6 +2335,7 @@ fn get_spl_token_owner_filter(program_id: &Pubkey, filters: &[RpcFilterType]) ->
|
|||
}) if *offset == account_packed_len && *program_id == inline_spl_token_2022::id() => {
|
||||
memcmp_filter = Some(bytes)
|
||||
}
|
||||
#[allow(deprecated)]
|
||||
RpcFilterType::Memcmp(Memcmp {
|
||||
offset,
|
||||
bytes: MemcmpEncodedBytes::Bytes(bytes),
|
||||
|
@ -2394,6 +2385,7 @@ fn get_spl_token_mint_filter(program_id: &Pubkey, filters: &[RpcFilterType]) ->
|
|||
for filter in filters {
|
||||
match filter {
|
||||
RpcFilterType::DataSize(size) => data_size_filter = Some(*size),
|
||||
#[allow(deprecated)]
|
||||
RpcFilterType::Memcmp(Memcmp {
|
||||
offset,
|
||||
bytes: MemcmpEncodedBytes::Bytes(bytes),
|
||||
|
@ -2401,6 +2393,7 @@ fn get_spl_token_mint_filter(program_id: &Pubkey, filters: &[RpcFilterType]) ->
|
|||
}) if *offset == account_packed_len && *program_id == inline_spl_token_2022::id() => {
|
||||
memcmp_filter = Some(bytes)
|
||||
}
|
||||
#[allow(deprecated)]
|
||||
RpcFilterType::Memcmp(Memcmp {
|
||||
offset,
|
||||
bytes: MemcmpEncodedBytes::Bytes(bytes),
|
||||
|
@ -6531,22 +6524,16 @@ pub mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_rpc_verify_filter() {
|
||||
#[allow(deprecated)]
|
||||
let filter = RpcFilterType::Memcmp(Memcmp {
|
||||
offset: 0,
|
||||
bytes: MemcmpEncodedBytes::Base58(
|
||||
"13LeFbG6m2EP1fqCj9k66fcXsoTHMMtgr7c78AivUrYD".to_string(),
|
||||
),
|
||||
encoding: None,
|
||||
});
|
||||
let filter = RpcFilterType::Memcmp(Memcmp::new(
|
||||
0, // offset
|
||||
MemcmpEncodedBytes::Base58("13LeFbG6m2EP1fqCj9k66fcXsoTHMMtgr7c78AivUrYD".to_string()), // encoded bytes
|
||||
));
|
||||
assert_eq!(verify_filter(&filter), Ok(()));
|
||||
// Invalid base-58
|
||||
#[allow(deprecated)]
|
||||
let filter = RpcFilterType::Memcmp(Memcmp {
|
||||
offset: 0,
|
||||
bytes: MemcmpEncodedBytes::Base58("III".to_string()),
|
||||
encoding: None,
|
||||
});
|
||||
let filter = RpcFilterType::Memcmp(Memcmp::new(
|
||||
0, // offset
|
||||
MemcmpEncodedBytes::Base58("III".to_string()), // encoded bytes
|
||||
));
|
||||
assert!(verify_filter(&filter).is_err());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue