RPC: respect data slice config if account parsing fails (#28387)

* RPC: respect data slice config if account parsing fails

* Remove check_slice_and_encoding method
This commit is contained in:
Justin Starry 2022-10-19 16:49:12 +08:00 committed by GitHub
parent 491ec1e275
commit 58e27d45dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 44 deletions

View File

@ -117,7 +117,10 @@ impl UiAccount {
{
UiAccountData::Json(parsed_data)
} else {
UiAccountData::Binary(base64::encode(account.data()), UiAccountEncoding::Base64)
UiAccountData::Binary(
base64::encode(slice_data(account.data(), data_slice_config)),
UiAccountEncoding::Base64,
)
}
}
};

View File

@ -257,7 +257,7 @@ Returns all information associated with the account of provided Pubkey
"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](jsonrpc-api.md#parsed-responses) 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>`.
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "base58", "base64" or "base64+zstd" encodings.
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; has no effect on parsed account data.
- (optional) `minContextSlot: <number>` - set the minimum slot that the request can be evaluated at.
#### Results:
@ -1797,7 +1797,7 @@ Returns the account information for a list of Pubkeys.
"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](jsonrpc-api.md#parsed-responses) 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>`.
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "base58", "base64" or "base64+zstd" encodings.
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; has no effect on parsed account data.
- (optional) `minContextSlot: <number>` - set the minimum slot that the request can be evaluated at.
#### Results:
@ -1944,7 +1944,7 @@ Returns all accounts owned by the provided program Pubkey
"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](jsonrpc-api.md#parsed-responses) 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>`.
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "base58", "base64" or "base64+zstd" encodings.
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; has no effect on parsed account data.
- (optional) `filters: <array>` - filter results using up to 4 [filter objects](jsonrpc-api.md#filters); account must meet all filter criteria to be included in results
- (optional) `withContext: bool` - wrap the result in an RpcResponse JSON object.
- (optional) `minContextSlot: <number>` - set the minimum slot that the request can be evaluated at.
@ -2724,7 +2724,7 @@ Returns all SPL Token accounts by approved Delegate.
"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](jsonrpc-api.md#parsed-responses) 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>`.
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "base58", "base64" or "base64+zstd" encodings.
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; has no effect on parsed account data.
- (optional) `minContextSlot: <number>` - set the minimum slot that the request can be evaluated at.
#### Results:
@ -2831,7 +2831,7 @@ Returns all SPL Token accounts by token owner.
"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](jsonrpc-api.md#parsed-responses) 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>`.
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; only available for "base58", "base64" or "base64+zstd" encodings.
- (optional) `dataSlice: <object>` - limit the returned account data using the provided `offset: <usize>` and `length: <usize>` fields; has no effect on parsed account data.
- (optional) `minContextSlot: <number>` - set the minimum slot that the request can be evaluated at.
#### Results:

View File

@ -420,7 +420,6 @@ impl JsonRpcRequestProcessor {
min_context_slot,
})?;
let encoding = encoding.unwrap_or(UiAccountEncoding::Binary);
check_slice_and_encoding(&encoding, data_slice.is_some())?;
let response = get_encoded_account(&bank, pubkey, encoding, data_slice)?;
Ok(new_response(&bank, response))
@ -442,7 +441,6 @@ impl JsonRpcRequestProcessor {
min_context_slot,
})?;
let encoding = encoding.unwrap_or(UiAccountEncoding::Base64);
check_slice_and_encoding(&encoding, data_slice.is_some())?;
let accounts = pubkeys
.into_iter()
@ -478,7 +476,6 @@ impl JsonRpcRequestProcessor {
min_context_slot,
})?;
let encoding = encoding.unwrap_or(UiAccountEncoding::Binary);
check_slice_and_encoding(&encoding, data_slice_config.is_some())?;
optimize_filters(&mut filters);
let keyed_accounts = {
if let Some(owner) = get_spl_token_owner_filter(program_id, &filters) {
@ -1901,7 +1898,6 @@ impl JsonRpcRequestProcessor {
min_context_slot,
})?;
let encoding = encoding.unwrap_or(UiAccountEncoding::Binary);
check_slice_and_encoding(&encoding, data_slice_config.is_some())?;
let (token_program_id, mint) = get_token_program_id_and_mint(&bank, token_account_filter)?;
let mut filters = vec![];
@ -1952,7 +1948,6 @@ impl JsonRpcRequestProcessor {
min_context_slot,
})?;
let encoding = encoding.unwrap_or(UiAccountEncoding::Binary);
check_slice_and_encoding(&encoding, data_slice_config.is_some())?;
let (token_program_id, mint) = get_token_program_id_and_mint(&bank, token_account_filter)?;
let mut filters = vec![
@ -2291,29 +2286,6 @@ pub(crate) fn check_is_at_least_confirmed(commitment: CommitmentConfig) -> Resul
Ok(())
}
fn check_slice_and_encoding(encoding: &UiAccountEncoding, data_slice_is_some: bool) -> Result<()> {
match encoding {
UiAccountEncoding::JsonParsed => {
if data_slice_is_some {
let message =
"Sliced account data can only be encoded using binary (base 58) or base64 encoding."
.to_string();
Err(error::Error {
code: error::ErrorCode::InvalidRequest,
message,
data: None,
})
} else {
Ok(())
}
}
UiAccountEncoding::Binary
| UiAccountEncoding::Base58
| UiAccountEncoding::Base64
| UiAccountEncoding::Base64Zstd => Ok(()),
}
}
fn get_encoded_account(
bank: &Arc<Bank>,
pubkey: &Pubkey,
@ -5529,12 +5501,12 @@ pub mod tests {
json!([address, {"encoding": "jsonParsed", "dataSlice": {"length": 2, "offset": 1}}]),
),
);
let response = parse_failure_response(rpc.handle_request_sync(request));
let expected = (
ErrorCode::InvalidRequest.code(),
String::from("Sliced account data can only be encoded using binary (base 58) or base64 encoding."),
let result: Value = parse_success_result(rpc.handle_request_sync(request));
let expected = json!([base64::encode(&data[1..3]), "base64"]);
assert_eq!(
result["value"]["data"], expected,
"should use data slice if parsing fails"
);
assert_eq!(response, expected);
}
#[test]
@ -5625,12 +5597,28 @@ pub mod tests {
{"encoding": "jsonParsed", "dataSlice": {"length": 2, "offset": 1}},
])),
);
let response = parse_failure_response(rpc.handle_request_sync(request));
let expected = (
ErrorCode::InvalidRequest.code(),
String::from("Sliced account data can only be encoded using binary (base 58) or base64 encoding."),
let result: RpcResponse<Value> = parse_success_result(rpc.handle_request_sync(request));
let expected = json!([
{
"owner": "11111111111111111111111111111111",
"lamports": TEST_MINT_LAMPORTS,
"data": ["", "base64"],
"executable": false,
"rentEpoch": 0
},
null,
{
"owner": "11111111111111111111111111111111",
"lamports": 42,
"data": [base64::encode(&data[1..3]), "base64"],
"executable": false,
"rentEpoch": 0
}
]);
assert_eq!(
result.value, expected,
"should use data slice if parsing fails"
);
assert_eq!(response, expected);
}
#[test]