From b2b6111e17f98034d053a61ab8c417ad0e567b97 Mon Sep 17 00:00:00 2001 From: Ashok Menon Date: Wed, 12 Feb 2025 23:03:35 +0000 Subject: [PATCH] rpc-alt: redefine TransactionFilter ## Description Rather than re-using the base JSON-RPC `TransactionFilter` type and having to respond that certain filters are unsupported, define our own compatible type which only contains the variants we do support. This way we will still return an invalid params error if someone tries to use an unsupported filter, but the filters we advertise in the schema will match what we can return a non-error response for. ## Test plan Existing tests. --- .../transactions/query/unsupported.move | 18 ----- .../src/api/transactions/error.rs | 3 - .../src/api/transactions/filter.rs | 72 ++++++++++++------- .../src/api/transactions/mod.rs | 7 +- 4 files changed, 49 insertions(+), 51 deletions(-) delete mode 100644 crates/sui-indexer-alt-e2e-tests/tests/jsonrpc/transactions/query/unsupported.move diff --git a/crates/sui-indexer-alt-e2e-tests/tests/jsonrpc/transactions/query/unsupported.move b/crates/sui-indexer-alt-e2e-tests/tests/jsonrpc/transactions/query/unsupported.move deleted file mode 100644 index a785b205e81cb..0000000000000 --- a/crates/sui-indexer-alt-e2e-tests/tests/jsonrpc/transactions/query/unsupported.move +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Mysten Labs, Inc. -// SPDX-License-Identifier: Apache-2.0 - -//# init --protocol-version 70 --addresses test=0x0 --simulator - -//# create-checkpoint - -//# run-jsonrpc -{ - "method": "suix_queryTransactionBlocks", - "params": [ - { - "filter": { - "TransactionKind": "NotSupported" - } - } - ] -} diff --git a/crates/sui-indexer-alt-jsonrpc/src/api/transactions/error.rs b/crates/sui-indexer-alt-jsonrpc/src/api/transactions/error.rs index dc0a780afb238..e60d7818cd71f 100644 --- a/crates/sui-indexer-alt-jsonrpc/src/api/transactions/error.rs +++ b/crates/sui-indexer-alt-jsonrpc/src/api/transactions/error.rs @@ -22,7 +22,4 @@ pub(super) enum Error { .1.to_canonical_display(/* with_prefix */ true), )] PrunedObject(TransactionDigest, ObjectID, u64), - - #[error("{0}")] - Unsupported(&'static str), } diff --git a/crates/sui-indexer-alt-jsonrpc/src/api/transactions/filter.rs b/crates/sui-indexer-alt-jsonrpc/src/api/transactions/filter.rs index 1a1e748ab9e9f..0341ea2797ece 100644 --- a/crates/sui-indexer-alt-jsonrpc/src/api/transactions/filter.rs +++ b/crates/sui-indexer-alt-jsonrpc/src/api/transactions/filter.rs @@ -10,17 +10,21 @@ use diesel::{ }, pg::Pg, query_builder::{BoxedSelectStatement, FromClause, QueryFragment}, - sql_types::BigInt, + sql_types::BigInt as SqlBigInt, AppearsOnTable, Column, Expression, ExpressionMethods, QueryDsl, QuerySource, }; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use serde_with::serde_as; use sui_indexer_alt_schema::schema::{ tx_affected_addresses, tx_affected_objects, tx_calls, tx_digests, }; -use sui_json_rpc_types::{Page as PageResponse, TransactionFilter}; +use sui_json_rpc_types::{Page as PageResponse, SuiTransactionBlockResponseOptions}; use sui_types::{ base_types::{ObjectID, SuiAddress}, digests::TransactionDigest, - messages_checkpoint::{CheckpointContents, CheckpointSummary}, + messages_checkpoint::{CheckpointContents, CheckpointSequenceNumber, CheckpointSummary}, + sui_serde::{BigInt, Readable}, }; use crate::{ @@ -31,6 +35,44 @@ use crate::{ use super::{error::Error, Context, TransactionsConfig}; +#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, Default)] +#[serde( + rename_all = "camelCase", + rename = "TransactionBlockResponseQuery", + default +)] +pub(crate) struct SuiTransactionBlockResponseQuery { + /// If None, no filter will be applied. + pub filter: Option, + /// Configures which fields to include in the response, by default only digest is included. + pub options: Option, +} + +#[serde_as] +#[derive(Clone, Debug, JsonSchema, Serialize, Deserialize)] +pub(crate) enum TransactionFilter { + /// Query by checkpoint. + Checkpoint( + #[schemars(with = "BigInt")] + #[serde_as(as = "Readable, _>")] + CheckpointSequenceNumber, + ), + /// Query by move function. + MoveFunction { + package: ObjectID, + module: Option, + function: Option, + }, + /// Query for transactions that touch this object. + AffectedObject(ObjectID), + /// Query by sender address. + FromAddress(SuiAddress), + /// Query by sender and recipient address. + FromAndToAddress { from: SuiAddress, to: SuiAddress }, + /// Query transactions that have a given address as sender or recipient. + FromOrToAddress { addr: SuiAddress }, +} + type Cursor = JsonCursor; type Digests = PageResponse; @@ -74,22 +116,6 @@ pub(super) async fn transactions( } Some(F::FromOrToAddress { addr }) => tx_affected_addresses(ctx, &page, None, *addr).await, - - Some(F::TransactionKind(_) | F::TransactionKindIn(_)) => { - unsupported("TransactionKind filter is not supported") - } - - Some(F::InputObject(_)) => { - unsupported("InputObject filter is not supported, please use AffectedObject instead.") - } - - Some(F::ChangedObject(_)) => { - unsupported("ChangedObject filter is not supported, please use AffectedObject instead.") - } - - Some(F::ToAddress(_)) => { - unsupported("ToAddress filter is not supported, please use FromOrToAddress instead.") - } } } @@ -312,10 +338,10 @@ where TX: Copy + Send + Sync + 'q, TX: ValidGrouping<()> + QueryFragment, TX: Column + AppearsOnTable, - TX: ExpressionMethods + Expression, + TX: ExpressionMethods + Expression, TX::IsAggregate: MixedAggregates, { - query = query.filter(tx_sequence_number.ge(sql::(&format!( + query = query.filter(tx_sequence_number.ge(sql::(&format!( r#"COALESCE( ( SELECT @@ -421,7 +447,3 @@ fn from_digests(limit: i64, mut rows: Vec<(i64, Vec)>) -> Result(msg: &'static str) -> Result> { - Err(invalid_params(Error::Unsupported(msg))) -} diff --git a/crates/sui-indexer-alt-jsonrpc/src/api/transactions/mod.rs b/crates/sui-indexer-alt-jsonrpc/src/api/transactions/mod.rs index 750b4e5d6f25a..a0d8443fa25dc 100644 --- a/crates/sui-indexer-alt-jsonrpc/src/api/transactions/mod.rs +++ b/crates/sui-indexer-alt-jsonrpc/src/api/transactions/mod.rs @@ -4,15 +4,12 @@ use futures::future; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use serde::{Deserialize, Serialize}; -use sui_json_rpc_types::{ - Page, SuiTransactionBlockResponse, SuiTransactionBlockResponseOptions, - SuiTransactionBlockResponseQuery, -}; +use sui_json_rpc_types::{Page, SuiTransactionBlockResponse, SuiTransactionBlockResponseOptions}; use sui_open_rpc::Module; use sui_open_rpc_macros::open_rpc; use sui_types::digests::TransactionDigest; -use self::error::Error; +use self::{error::Error, filter::SuiTransactionBlockResponseQuery}; use crate::{ context::Context,