diff --git a/Makefile b/Makefile index 83c737d9..00764a52 100644 --- a/Makefile +++ b/Makefile @@ -122,7 +122,7 @@ proto: PASS=$${CLICKHOUSE_PASSWORD:-supersecret}; \ docker run --rm -v "$$(pwd):/workspace" \ --user "$$(id -u):$$(id -g)" \ - --network xatu_xatu-net \ + --network "$${XATU_CBT_PROJECT_NAME:-xatu-cbt-platform}_xatu-net" \ ethpandaops/clickhouse-proto-gen \ --dsn "clickhouse://$$USER:$$PASS@xatu-cbt-clickhouse-01:9000/$$NETWORK" \ --tables "admin_incremental,$$TABLES" \ diff --git a/migrations/101_int_transaction_mempool_observation_hourly.down.sql b/migrations/101_int_transaction_mempool_observation_hourly.down.sql new file mode 100644 index 00000000..f4343d3c --- /dev/null +++ b/migrations/101_int_transaction_mempool_observation_hourly.down.sql @@ -0,0 +1,2 @@ +DROP TABLE IF EXISTS int_transaction_mempool_observation_hourly ON CLUSTER '{cluster}'; +DROP TABLE IF EXISTS int_transaction_mempool_observation_hourly_local ON CLUSTER '{cluster}'; diff --git a/migrations/101_int_transaction_mempool_observation_hourly.up.sql b/migrations/101_int_transaction_mempool_observation_hourly.up.sql new file mode 100644 index 00000000..2e2912aa --- /dev/null +++ b/migrations/101_int_transaction_mempool_observation_hourly.up.sql @@ -0,0 +1,59 @@ +CREATE TABLE int_transaction_mempool_observation_hourly_local on cluster '{cluster}' ( + `updated_date_time` DateTime COMMENT 'Timestamp when the record was last updated' CODEC(DoubleDelta, ZSTD(1)), + `hour_start_date_time` DateTime COMMENT 'The start of the hour bucket the sightings fall in' CODEC(DoubleDelta, ZSTD(1)), + `hash` FixedString(66) COMMENT 'The transaction hash' CODEC(ZSTD(1)), + `first_seen_date_time` DateTime64(3) COMMENT 'Earliest sighting of the transaction by any sentry within this hour' CODEC(DoubleDelta, ZSTD(1)), + `last_seen_date_time` DateTime64(3) COMMENT 'Latest sighting of the transaction by any sentry within this hour' CODEC(DoubleDelta, ZSTD(1)), + `sighting_count` UInt32 COMMENT 'Number of sightings of the transaction within this hour across all sentries' CODEC(ZSTD(1)), + `unique_sentries` UInt32 COMMENT 'Number of distinct sentries that sighted the transaction within this hour' CODEC(ZSTD(1)), + `from` FixedString(42) COMMENT 'The address of the account that sent the transaction' CODEC(ZSTD(1)), + `to` Nullable(FixedString(42)) COMMENT 'The address of the transaction recipient, null for contract creation' CODEC(ZSTD(1)), + `nonce` UInt64 COMMENT 'The nonce of the sender account at the time of the transaction' CODEC(ZSTD(1)), + `type` Nullable(UInt8) COMMENT 'The type of the transaction' CODEC(ZSTD(1)), + `gas` UInt64 COMMENT 'The maximum gas provided for the transaction execution' CODEC(ZSTD(1)), + `gas_price` UInt128 COMMENT 'The gas price of the transaction in wei' CODEC(ZSTD(1)), + `gas_tip_cap` Nullable(UInt128) COMMENT 'The priority fee (tip) the user has set for the transaction in wei' CODEC(ZSTD(1)), + `gas_fee_cap` Nullable(UInt128) COMMENT 'The max fee the user has set for the transaction in wei' CODEC(ZSTD(1)), + `value` UInt128 COMMENT 'The value transferred with the transaction in wei' CODEC(ZSTD(1)), + `size` UInt32 COMMENT 'The size of the transaction data in bytes' CODEC(ZSTD(1)), + `call_data_size` UInt32 COMMENT 'The size of the call data of the transaction in bytes' CODEC(ZSTD(1)), + `blob_gas` Nullable(UInt64) COMMENT 'The maximum gas provided for the blob transaction execution' CODEC(ZSTD(1)), + `blob_gas_fee_cap` Nullable(UInt128) COMMENT 'The max blob fee the user has set for the transaction in wei' CODEC(ZSTD(1)), + `blob_hashes` Array(String) COMMENT 'The hashes of the blob commitments for blob transactions' CODEC(ZSTD(1)), + `is_cancel_shape` Bool COMMENT 'Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern' CODEC(ZSTD(1)), + `first_sentry_name` LowCardinality(String) COMMENT 'Name of the sentry with the earliest sighting this hour, ties broken by sentry name' CODEC(ZSTD(1)), + `first_sentry_geo_city` LowCardinality(String) COMMENT 'City of the first-sighting sentry' CODEC(ZSTD(1)), + `first_sentry_geo_country` LowCardinality(String) COMMENT 'Country of the first-sighting sentry' CODEC(ZSTD(1)), + `first_sentry_geo_country_code` LowCardinality(String) COMMENT 'Country code of the first-sighting sentry' CODEC(ZSTD(1)), + `first_sentry_geo_continent_code` LowCardinality(String) COMMENT 'Continent code of the first-sighting sentry' CODEC(ZSTD(1)) +) ENGINE = ReplicatedReplacingMergeTree( + '/clickhouse/{installation}/{cluster}/tables/{shard}/{database}/{table}', + '{replica}', + `updated_date_time` +) PARTITION BY toStartOfMonth(hour_start_date_time) +ORDER BY + (`hour_start_date_time`, `hash`) +SETTINGS + deduplicate_merge_projection_mode = 'rebuild' +COMMENT 'One row per transaction hash per hour in which it was sighted in the public mempool by at least one sentry. Rows summarise the sightings within that hour only. A transaction sighted across multiple hours has multiple rows'; + +CREATE TABLE int_transaction_mempool_observation_hourly ON CLUSTER '{cluster}' AS int_transaction_mempool_observation_hourly_local ENGINE = Distributed( + '{cluster}', + currentDatabase(), + int_transaction_mempool_observation_hourly_local, + cityHash64(`from`, `nonce`) +); + +ALTER TABLE int_transaction_mempool_observation_hourly_local ON CLUSTER '{cluster}' +ADD PROJECTION p_by_hash +( + SELECT * + ORDER BY (`hash`, `hour_start_date_time`) +); + +ALTER TABLE int_transaction_mempool_observation_hourly_local ON CLUSTER '{cluster}' +ADD PROJECTION p_by_nonce_group +( + SELECT * + ORDER BY (`from`, `nonce`, `hour_start_date_time`) +); diff --git a/migrations/102_fct_transaction_inclusion.down.sql b/migrations/102_fct_transaction_inclusion.down.sql new file mode 100644 index 00000000..053614c5 --- /dev/null +++ b/migrations/102_fct_transaction_inclusion.down.sql @@ -0,0 +1,2 @@ +DROP TABLE IF EXISTS fct_transaction_inclusion ON CLUSTER '{cluster}'; +DROP TABLE IF EXISTS fct_transaction_inclusion_local ON CLUSTER '{cluster}'; diff --git a/migrations/102_fct_transaction_inclusion.up.sql b/migrations/102_fct_transaction_inclusion.up.sql new file mode 100644 index 00000000..fd983c33 --- /dev/null +++ b/migrations/102_fct_transaction_inclusion.up.sql @@ -0,0 +1,57 @@ +CREATE TABLE fct_transaction_inclusion_local on cluster '{cluster}' ( + `updated_date_time` DateTime COMMENT 'Timestamp when the record was last updated' CODEC(DoubleDelta, ZSTD(1)), + `slot` UInt32 COMMENT 'The slot number of the beacon block containing the transaction' CODEC(DoubleDelta, ZSTD(1)), + `slot_start_date_time` DateTime COMMENT 'The wall clock time when the slot started' CODEC(DoubleDelta, ZSTD(1)), + `epoch` UInt32 COMMENT 'The epoch number containing the slot' CODEC(DoubleDelta, ZSTD(1)), + `epoch_start_date_time` DateTime COMMENT 'The wall clock time when the epoch started' CODEC(DoubleDelta, ZSTD(1)), + `block_root` FixedString(66) COMMENT 'The beacon block root hash' CODEC(ZSTD(1)), + `block_version` LowCardinality(String) COMMENT 'The beacon block version' CODEC(ZSTD(1)), + `block_number` Nullable(UInt64) COMMENT 'The execution block number, null when the block is not yet present in fct_block' CODEC(ZSTD(1)), + `position` UInt32 COMMENT 'The position of the transaction in the execution payload' CODEC(ZSTD(1)), + `hash` FixedString(66) COMMENT 'The transaction hash' CODEC(ZSTD(1)), + `from` FixedString(42) COMMENT 'The address of the account that sent the transaction' CODEC(ZSTD(1)), + `to` Nullable(FixedString(42)) COMMENT 'The address of the transaction recipient, null for contract creation' CODEC(ZSTD(1)), + `nonce` UInt64 COMMENT 'The nonce of the sender account at the time of the transaction' CODEC(ZSTD(1)), + `type` UInt8 COMMENT 'The type of the transaction' CODEC(ZSTD(1)), + `gas` UInt64 COMMENT 'The maximum gas provided for the transaction execution' CODEC(ZSTD(1)), + `gas_price` UInt128 COMMENT 'The gas price of the transaction in wei' CODEC(ZSTD(1)), + `gas_tip_cap` Nullable(UInt128) COMMENT 'The priority fee (tip) the user has set for the transaction in wei' CODEC(ZSTD(1)), + `gas_fee_cap` Nullable(UInt128) COMMENT 'The max fee the user has set for the transaction in wei' CODEC(ZSTD(1)), + `value` UInt128 COMMENT 'The value transferred with the transaction in wei' CODEC(ZSTD(1)), + `size` UInt32 COMMENT 'The size of the transaction data in bytes' CODEC(ZSTD(1)), + `call_data_size` UInt32 COMMENT 'The size of the call data of the transaction in bytes' CODEC(ZSTD(1)), + `blob_gas` Nullable(UInt64) COMMENT 'The maximum gas provided for the blob transaction execution' CODEC(ZSTD(1)), + `blob_gas_fee_cap` Nullable(UInt128) COMMENT 'The max blob fee the user has set for the transaction in wei' CODEC(ZSTD(1)), + `blob_hashes` Array(String) COMMENT 'The hashes of the blob commitments for blob transactions' CODEC(ZSTD(1)), + `is_cancel_shape` Bool COMMENT 'Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern' CODEC(ZSTD(1)) +) ENGINE = ReplicatedReplacingMergeTree( + '/clickhouse/{installation}/{cluster}/tables/{shard}/{database}/{table}', + '{replica}', + `updated_date_time` +) PARTITION BY toStartOfMonth(slot_start_date_time) +ORDER BY + (`slot_start_date_time`, `block_root`, `position`) +SETTINGS + deduplicate_merge_projection_mode = 'rebuild' +COMMENT 'One row per transaction included in a canonical beacon block execution payload. Carries no mempool or relay context so it can cover the full post-Merge history'; + +CREATE TABLE fct_transaction_inclusion ON CLUSTER '{cluster}' AS fct_transaction_inclusion_local ENGINE = Distributed( + '{cluster}', + currentDatabase(), + fct_transaction_inclusion_local, + cityHash64(`slot_start_date_time`, `block_root`) +); + +ALTER TABLE fct_transaction_inclusion_local ON CLUSTER '{cluster}' +ADD PROJECTION p_by_hash +( + SELECT * + ORDER BY (`hash`) +); + +ALTER TABLE fct_transaction_inclusion_local ON CLUSTER '{cluster}' +ADD PROJECTION p_by_nonce_group +( + SELECT * + ORDER BY (`from`, `nonce`, `slot_start_date_time`) +); diff --git a/migrations/103_fct_transaction_mempool_outcome_7d.down.sql b/migrations/103_fct_transaction_mempool_outcome_7d.down.sql new file mode 100644 index 00000000..b7af38f5 --- /dev/null +++ b/migrations/103_fct_transaction_mempool_outcome_7d.down.sql @@ -0,0 +1,2 @@ +DROP TABLE IF EXISTS fct_transaction_mempool_outcome_7d ON CLUSTER '{cluster}'; +DROP TABLE IF EXISTS fct_transaction_mempool_outcome_7d_local ON CLUSTER '{cluster}'; diff --git a/migrations/103_fct_transaction_mempool_outcome_7d.up.sql b/migrations/103_fct_transaction_mempool_outcome_7d.up.sql new file mode 100644 index 00000000..48f2aa39 --- /dev/null +++ b/migrations/103_fct_transaction_mempool_outcome_7d.up.sql @@ -0,0 +1,65 @@ +CREATE TABLE fct_transaction_mempool_outcome_7d_local on cluster '{cluster}' ( + `updated_date_time` DateTime COMMENT 'Timestamp when the record was last updated' CODEC(DoubleDelta, ZSTD(1)), + `first_seen_date_time` DateTime64(3) COMMENT 'Earliest sighting of the transaction within its observation episode, the anchor of the 7 day horizon' CODEC(DoubleDelta, ZSTD(1)), + `hash` FixedString(66) COMMENT 'The transaction hash' CODEC(ZSTD(1)), + `from` FixedString(42) COMMENT 'The address of the account that sent the transaction' CODEC(ZSTD(1)), + `to` Nullable(FixedString(42)) COMMENT 'The address of the transaction recipient, null for contract creation' CODEC(ZSTD(1)), + `nonce` UInt64 COMMENT 'The nonce of the sender account at the time of the transaction' CODEC(ZSTD(1)), + `type` Nullable(UInt8) COMMENT 'The type of the transaction' CODEC(ZSTD(1)), + `gas` UInt64 COMMENT 'The maximum gas provided for the transaction execution' CODEC(ZSTD(1)), + `gas_price` UInt128 COMMENT 'The gas price of the transaction in wei' CODEC(ZSTD(1)), + `gas_tip_cap` Nullable(UInt128) COMMENT 'The priority fee (tip) the user has set for the transaction in wei' CODEC(ZSTD(1)), + `gas_fee_cap` Nullable(UInt128) COMMENT 'The max fee the user has set for the transaction in wei' CODEC(ZSTD(1)), + `value` UInt128 COMMENT 'The value transferred with the transaction in wei' CODEC(ZSTD(1)), + `size` UInt32 COMMENT 'The size of the transaction data in bytes' CODEC(ZSTD(1)), + `call_data_size` UInt32 COMMENT 'The size of the call data of the transaction in bytes' CODEC(ZSTD(1)), + `blob_gas` Nullable(UInt64) COMMENT 'The maximum gas provided for the blob transaction execution' CODEC(ZSTD(1)), + `blob_gas_fee_cap` Nullable(UInt128) COMMENT 'The max blob fee the user has set for the transaction in wei' CODEC(ZSTD(1)), + `blob_hashes` Array(String) COMMENT 'The hashes of the blob commitments for blob transactions' CODEC(ZSTD(1)), + `is_cancel_shape` Bool COMMENT 'Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern' CODEC(ZSTD(1)), + `last_seen_date_time` DateTime64(3) COMMENT 'Latest sighting of the transaction within the 7 day horizon' CODEC(DoubleDelta, ZSTD(1)), + `sighting_count` UInt32 COMMENT 'Number of sightings within the 7 day horizon across all sentries' CODEC(ZSTD(1)), + `peak_hourly_unique_sentries` UInt32 COMMENT 'Peak number of distinct sentries sighting the transaction within any single hour of the horizon' CODEC(ZSTD(1)), + `outcome` LowCardinality(String) COMMENT 'Outcome within 7 days of first sighting: included, nonce_consumed (a different transaction with the same from and nonce was included) or unincluded. The statement is fixed to the horizon and remains true even if the transaction is included later' CODEC(ZSTD(1)), + `resolution_date_time` DateTime64(3) COMMENT 'When the outcome was determined: the inclusion slot start for included, the winner inclusion slot start for nonce_consumed, or first_seen_date_time plus 7 days for unincluded' CODEC(DoubleDelta, ZSTD(1)), + `included_slot` Nullable(UInt32) COMMENT 'The slot of the beacon block that included the transaction, when outcome is included' CODEC(ZSTD(1)), + `included_slot_start_date_time` Nullable(DateTime) COMMENT 'The wall clock time when the inclusion slot started, when outcome is included' CODEC(ZSTD(1)), + `included_block_root` Nullable(FixedString(66)) COMMENT 'The beacon block root of the including block, when outcome is included' CODEC(ZSTD(1)), + `included_position` Nullable(UInt32) COMMENT 'The position of the transaction in the execution payload, when outcome is included' CODEC(ZSTD(1)), + `wait_ms` Nullable(Int64) COMMENT 'Milliseconds from first sighting to the inclusion slot start, when outcome is included. Negative when the transaction was first sighted after its inclusion slot started' CODEC(ZSTD(1)), + `included_via_known_relay` Nullable(Bool) COMMENT 'Whether the including block matched a known relay payload-delivered record, when outcome is included. False is not proof the block was locally built' CODEC(ZSTD(1)), + `winner_hash` Nullable(FixedString(66)) COMMENT 'The hash of the transaction that consumed the nonce, when outcome is nonce_consumed' CODEC(ZSTD(1)), + `winner_slot_start_date_time` Nullable(DateTime) COMMENT 'The wall clock time when the winner inclusion slot started, when outcome is nonce_consumed' CODEC(ZSTD(1)), + `observed_after_nonce_consumed` Bool COMMENT 'Whether the transaction was first sighted after its nonce had already been consumed by another transaction' CODEC(ZSTD(1)), + `in_mempool_at_deadline` Bool COMMENT 'Whether a sighting occurred in the final hour before the 7 day deadline. Sensor evidence of continued circulation, only meaningful when outcome is unincluded' CODEC(ZSTD(1)) +) ENGINE = ReplicatedReplacingMergeTree( + '/clickhouse/{installation}/{cluster}/tables/{shard}/{database}/{table}', + '{replica}', + `updated_date_time` +) PARTITION BY toStartOfMonth(first_seen_date_time) +ORDER BY + (`first_seen_date_time`, `hash`) +SETTINGS + deduplicate_merge_projection_mode = 'rebuild' +COMMENT 'One immutable row per transaction hash observed in the public mempool, stating its fixed-horizon outcome within 7 days of first sighting. An observation episode starts when a hash is sighted with no sightings in the preceding 7 days. A hash re-sighted after more than 7 days of silence starts a new episode and a new row'; + +CREATE TABLE fct_transaction_mempool_outcome_7d ON CLUSTER '{cluster}' AS fct_transaction_mempool_outcome_7d_local ENGINE = Distributed( + '{cluster}', + currentDatabase(), + fct_transaction_mempool_outcome_7d_local, + cityHash64(`from`, `nonce`) +); + +ALTER TABLE fct_transaction_mempool_outcome_7d_local ON CLUSTER '{cluster}' +ADD PROJECTION p_by_hash +( + SELECT * + ORDER BY (`hash`) +); + +ALTER TABLE fct_transaction_mempool_outcome_7d_local ON CLUSTER '{cluster}' +ADD PROJECTION p_by_nonce_group +( + SELECT * + ORDER BY (`from`, `nonce`, `first_seen_date_time`) +); diff --git a/migrations/104_fct_transaction_replacement.down.sql b/migrations/104_fct_transaction_replacement.down.sql new file mode 100644 index 00000000..d8fc3f31 --- /dev/null +++ b/migrations/104_fct_transaction_replacement.down.sql @@ -0,0 +1,2 @@ +DROP TABLE IF EXISTS fct_transaction_replacement ON CLUSTER '{cluster}'; +DROP TABLE IF EXISTS fct_transaction_replacement_local ON CLUSTER '{cluster}'; diff --git a/migrations/104_fct_transaction_replacement.up.sql b/migrations/104_fct_transaction_replacement.up.sql new file mode 100644 index 00000000..7da1b6f2 --- /dev/null +++ b/migrations/104_fct_transaction_replacement.up.sql @@ -0,0 +1,55 @@ +CREATE TABLE fct_transaction_replacement_local on cluster '{cluster}' ( + `updated_date_time` DateTime COMMENT 'Timestamp when the record was last updated' CODEC(DoubleDelta, ZSTD(1)), + `group_first_seen_date_time` DateTime64(3) COMMENT 'Earliest sighting of any attempt in the nonce group, the anchor of the group window' CODEC(DoubleDelta, ZSTD(1)), + `from` FixedString(42) COMMENT 'The address of the account that sent the attempts' CODEC(ZSTD(1)), + `nonce` UInt64 COMMENT 'The nonce the attempts compete for' CODEC(ZSTD(1)), + `hash` FixedString(66) COMMENT 'The transaction hash of this attempt' CODEC(ZSTD(1)), + `attempt_index` UInt16 COMMENT 'The 1-based rank of this attempt within the group, ordered by first sighting with ties broken by hash' CODEC(ZSTD(1)), + `group_attempt_count` UInt16 COMMENT 'Total number of publicly observed attempts in the group window' CODEC(ZSTD(1)), + `first_seen_date_time` DateTime64(3) COMMENT 'Earliest sighting of this attempt' CODEC(DoubleDelta, ZSTD(1)), + `previous_hash` Nullable(FixedString(66)) COMMENT 'The hash of the attempt immediately before this one in the group, null for the first attempt' CODEC(ZSTD(1)), + `to` Nullable(FixedString(42)) COMMENT 'The address of the attempt recipient, null for contract creation' CODEC(ZSTD(1)), + `type` Nullable(UInt8) COMMENT 'The type of the transaction' CODEC(ZSTD(1)), + `gas_price` UInt128 COMMENT 'The gas price of the attempt in wei' CODEC(ZSTD(1)), + `gas_tip_cap` Nullable(UInt128) COMMENT 'The priority fee (tip) of the attempt in wei' CODEC(ZSTD(1)), + `gas_fee_cap` Nullable(UInt128) COMMENT 'The max fee of the attempt in wei' CODEC(ZSTD(1)), + `value` UInt128 COMMENT 'The value transferred with the attempt in wei' CODEC(ZSTD(1)), + `gas_tip_cap_delta` Nullable(Int128) COMMENT 'This attempt gas_tip_cap minus the previous attempt gas_tip_cap, null for the first attempt or when either side is null' CODEC(ZSTD(1)), + `gas_fee_cap_delta` Nullable(Int128) COMMENT 'This attempt gas_fee_cap minus the previous attempt gas_fee_cap, null for the first attempt or when either side is null' CODEC(ZSTD(1)), + `is_cancel_shape` Bool COMMENT 'Whether the attempt is a self-transfer of zero value, the common wallet cancellation pattern' CODEC(ZSTD(1)), + `is_winner` Bool COMMENT 'Whether this attempt is the one that was included on chain' CODEC(ZSTD(1)), + `group_outcome` LowCardinality(String) COMMENT 'Outcome of the nonce group within 7 days of the group anchor: included or unincluded' CODEC(ZSTD(1)), + `winner_hash` Nullable(FixedString(66)) COMMENT 'The hash of the included attempt, null when the group resolved unincluded' CODEC(ZSTD(1)), + `resolution_date_time` DateTime64(3) COMMENT 'When the group resolved: the winner inclusion slot start, or the group anchor plus 7 days when unincluded' CODEC(DoubleDelta, ZSTD(1)), + `observed_after_resolution` Bool COMMENT 'Whether this attempt was first sighted after the group had already resolved' CODEC(ZSTD(1)) +) ENGINE = ReplicatedReplacingMergeTree( + '/clickhouse/{installation}/{cluster}/tables/{shard}/{database}/{table}', + '{replica}', + `updated_date_time` +) PARTITION BY toStartOfMonth(group_first_seen_date_time) +ORDER BY + (`group_first_seen_date_time`, `from`, `nonce`, `hash`) +SETTINGS + deduplicate_merge_projection_mode = 'rebuild' +COMMENT 'One row per publicly observed attempt in nonce groups with at least two attempts, emitted when the group resolves. A nonce group is all transactions sharing a from address and nonce whose first sightings fall within 7 days of the group anchor'; + +CREATE TABLE fct_transaction_replacement ON CLUSTER '{cluster}' AS fct_transaction_replacement_local ENGINE = Distributed( + '{cluster}', + currentDatabase(), + fct_transaction_replacement_local, + cityHash64(`from`, `nonce`) +); + +ALTER TABLE fct_transaction_replacement_local ON CLUSTER '{cluster}' +ADD PROJECTION p_by_hash +( + SELECT * + ORDER BY (`hash`) +); + +ALTER TABLE fct_transaction_replacement_local ON CLUSTER '{cluster}' +ADD PROJECTION p_by_nonce_group +( + SELECT * + ORDER BY (`from`, `nonce`, `group_first_seen_date_time`) +); diff --git a/migrations/105_fct_transaction_inclusion_hourly.down.sql b/migrations/105_fct_transaction_inclusion_hourly.down.sql new file mode 100644 index 00000000..d2799019 --- /dev/null +++ b/migrations/105_fct_transaction_inclusion_hourly.down.sql @@ -0,0 +1,2 @@ +DROP TABLE IF EXISTS fct_transaction_inclusion_hourly ON CLUSTER '{cluster}'; +DROP TABLE IF EXISTS fct_transaction_inclusion_hourly_local ON CLUSTER '{cluster}'; diff --git a/migrations/105_fct_transaction_inclusion_hourly.up.sql b/migrations/105_fct_transaction_inclusion_hourly.up.sql new file mode 100644 index 00000000..875e9d17 --- /dev/null +++ b/migrations/105_fct_transaction_inclusion_hourly.up.sql @@ -0,0 +1,33 @@ +CREATE TABLE fct_transaction_inclusion_hourly_local on cluster '{cluster}' ( + `updated_date_time` DateTime COMMENT 'Timestamp when the record was last updated' CODEC(DoubleDelta, ZSTD(1)), + `hour_start_date_time` DateTime COMMENT 'Start of the hour period, bucketed by inclusion slot time' CODEC(DoubleDelta, ZSTD(1)), + `included_count` UInt64 COMMENT 'Number of transactions included in canonical blocks this hour' CODEC(ZSTD(1)), + `relay_delivered_count` UInt64 COMMENT 'Included transactions whose block matched a known relay payload-delivered record' CODEC(ZSTD(1)), + `unknown_build_count` UInt64 COMMENT 'Included transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built' CODEC(ZSTD(1)), + `type0_count` UInt64 COMMENT 'Included legacy type 0 transactions' CODEC(ZSTD(1)), + `type1_count` UInt64 COMMENT 'Included access list type 1 transactions' CODEC(ZSTD(1)), + `type2_count` UInt64 COMMENT 'Included dynamic fee type 2 transactions' CODEC(ZSTD(1)), + `type3_count` UInt64 COMMENT 'Included blob type 3 transactions' CODEC(ZSTD(1)), + `type4_count` UInt64 COMMENT 'Included set code type 4 transactions' CODEC(ZSTD(1)), + `type_other_count` UInt64 COMMENT 'Included transactions of any other type' CODEC(ZSTD(1)), + `blob_count` UInt64 COMMENT 'Total blob commitments across included transactions this hour' CODEC(ZSTD(1)), + `contract_creation_count` UInt64 COMMENT 'Included transactions with no recipient address' CODEC(ZSTD(1)), + `cancel_shape_count` UInt64 COMMENT 'Included transactions that are self-transfers of zero value, the common wallet cancellation pattern' CODEC(ZSTD(1)), + `unique_senders` UInt64 COMMENT 'Distinct sender addresses across included transactions this hour' CODEC(ZSTD(1)) +) ENGINE = ReplicatedReplacingMergeTree( + '/clickhouse/{installation}/{cluster}/tables/{shard}/{database}/{table}', + '{replica}', + `updated_date_time` +) PARTITION BY toStartOfMonth(hour_start_date_time) +ORDER BY + (`hour_start_date_time`) +SETTINGS + deduplicate_merge_projection_mode = 'rebuild' +COMMENT 'Hourly counts of transactions included in canonical blocks, split by build path and transaction type'; + +CREATE TABLE fct_transaction_inclusion_hourly ON CLUSTER '{cluster}' AS fct_transaction_inclusion_hourly_local ENGINE = Distributed( + '{cluster}', + currentDatabase(), + fct_transaction_inclusion_hourly_local, + cityHash64(`hour_start_date_time`) +); diff --git a/migrations/106_fct_transaction_inclusion_daily.down.sql b/migrations/106_fct_transaction_inclusion_daily.down.sql new file mode 100644 index 00000000..d579e4d3 --- /dev/null +++ b/migrations/106_fct_transaction_inclusion_daily.down.sql @@ -0,0 +1,2 @@ +DROP TABLE IF EXISTS fct_transaction_inclusion_daily ON CLUSTER '{cluster}'; +DROP TABLE IF EXISTS fct_transaction_inclusion_daily_local ON CLUSTER '{cluster}'; diff --git a/migrations/106_fct_transaction_inclusion_daily.up.sql b/migrations/106_fct_transaction_inclusion_daily.up.sql new file mode 100644 index 00000000..08668328 --- /dev/null +++ b/migrations/106_fct_transaction_inclusion_daily.up.sql @@ -0,0 +1,33 @@ +CREATE TABLE fct_transaction_inclusion_daily_local on cluster '{cluster}' ( + `updated_date_time` DateTime COMMENT 'Timestamp when the record was last updated' CODEC(DoubleDelta, ZSTD(1)), + `day_start_date` Date COMMENT 'Start of the day period, bucketed by inclusion slot time' CODEC(DoubleDelta, ZSTD(1)), + `included_count` UInt64 COMMENT 'Number of transactions included in canonical blocks this day' CODEC(ZSTD(1)), + `relay_delivered_count` UInt64 COMMENT 'Included transactions whose block matched a known relay payload-delivered record' CODEC(ZSTD(1)), + `unknown_build_count` UInt64 COMMENT 'Included transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built' CODEC(ZSTD(1)), + `type0_count` UInt64 COMMENT 'Included legacy type 0 transactions' CODEC(ZSTD(1)), + `type1_count` UInt64 COMMENT 'Included access list type 1 transactions' CODEC(ZSTD(1)), + `type2_count` UInt64 COMMENT 'Included dynamic fee type 2 transactions' CODEC(ZSTD(1)), + `type3_count` UInt64 COMMENT 'Included blob type 3 transactions' CODEC(ZSTD(1)), + `type4_count` UInt64 COMMENT 'Included set code type 4 transactions' CODEC(ZSTD(1)), + `type_other_count` UInt64 COMMENT 'Included transactions of any other type' CODEC(ZSTD(1)), + `blob_count` UInt64 COMMENT 'Total blob commitments across included transactions this day' CODEC(ZSTD(1)), + `contract_creation_count` UInt64 COMMENT 'Included transactions with no recipient address' CODEC(ZSTD(1)), + `cancel_shape_count` UInt64 COMMENT 'Included transactions that are self-transfers of zero value, the common wallet cancellation pattern' CODEC(ZSTD(1)), + `unique_senders` UInt64 COMMENT 'Distinct sender addresses across included transactions this day' CODEC(ZSTD(1)) +) ENGINE = ReplicatedReplacingMergeTree( + '/clickhouse/{installation}/{cluster}/tables/{shard}/{database}/{table}', + '{replica}', + `updated_date_time` +) PARTITION BY toStartOfMonth(day_start_date) +ORDER BY + (`day_start_date`) +SETTINGS + deduplicate_merge_projection_mode = 'rebuild' +COMMENT 'Daily counts of transactions included in canonical blocks, split by build path and transaction type'; + +CREATE TABLE fct_transaction_inclusion_daily ON CLUSTER '{cluster}' AS fct_transaction_inclusion_daily_local ENGINE = Distributed( + '{cluster}', + currentDatabase(), + fct_transaction_inclusion_daily_local, + cityHash64(`day_start_date`) +); diff --git a/migrations/107_fct_transaction_mempool_outcome_hourly.down.sql b/migrations/107_fct_transaction_mempool_outcome_hourly.down.sql new file mode 100644 index 00000000..bf311504 --- /dev/null +++ b/migrations/107_fct_transaction_mempool_outcome_hourly.down.sql @@ -0,0 +1,2 @@ +DROP TABLE IF EXISTS fct_transaction_mempool_outcome_hourly ON CLUSTER '{cluster}'; +DROP TABLE IF EXISTS fct_transaction_mempool_outcome_hourly_local ON CLUSTER '{cluster}'; diff --git a/migrations/107_fct_transaction_mempool_outcome_hourly.up.sql b/migrations/107_fct_transaction_mempool_outcome_hourly.up.sql new file mode 100644 index 00000000..35c287b0 --- /dev/null +++ b/migrations/107_fct_transaction_mempool_outcome_hourly.up.sql @@ -0,0 +1,42 @@ +CREATE TABLE fct_transaction_mempool_outcome_hourly_local on cluster '{cluster}' ( + `updated_date_time` DateTime COMMENT 'Timestamp when the record was last updated' CODEC(DoubleDelta, ZSTD(1)), + `hour_start_date_time` DateTime COMMENT 'Start of the hour period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the hour has been processed and never change afterwards' CODEC(DoubleDelta, ZSTD(1)), + `observed_count` UInt64 COMMENT 'Transactions first sighted in the public mempool this hour' CODEC(ZSTD(1)), + `included_count` UInt64 COMMENT 'Observed transactions included within 7 days of first sighting' CODEC(ZSTD(1)), + `nonce_consumed_count` UInt64 COMMENT 'Observed transactions whose nonce was consumed by a different transaction within 7 days' CODEC(ZSTD(1)), + `unincluded_count` UInt64 COMMENT 'Observed transactions with no inclusion of their nonce within 7 days' CODEC(ZSTD(1)), + `included_relay_delivered_count` UInt64 COMMENT 'Included observed transactions whose block matched a known relay payload-delivered record' CODEC(ZSTD(1)), + `included_unknown_build_count` UInt64 COMMENT 'Included observed transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built' CODEC(ZSTD(1)), + `in_mempool_at_deadline_count` UInt64 COMMENT 'Unincluded transactions with a sighting in the final hour before the 7 day deadline' CODEC(ZSTD(1)), + `cancel_shape_count` UInt64 COMMENT 'Observed transactions that are self-transfers of zero value, the common wallet cancellation pattern' CODEC(ZSTD(1)), + `observed_after_nonce_consumed_count` UInt64 COMMENT 'Observed transactions first sighted after their nonce had already been consumed' CODEC(ZSTD(1)), + `wait_ms_p50` Nullable(Float64) COMMENT 'Median milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits' CODEC(ZSTD(1)), + `wait_ms_p90` Nullable(Float64) COMMENT 'p90 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits' CODEC(ZSTD(1)), + `wait_ms_p99` Nullable(Float64) COMMENT 'p99 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits' CODEC(ZSTD(1)), + `wait_sample_count` UInt64 COMMENT 'Number of included transactions contributing to the wait quantiles' CODEC(ZSTD(1)), + `negative_wait_count` UInt64 COMMENT 'Included transactions first sighted after their inclusion slot started, excluded from the wait quantiles' CODEC(ZSTD(1)), + `blob_observed_count` UInt64 COMMENT 'Observed blob type 3 transactions first sighted this hour' CODEC(ZSTD(1)), + `blob_wait_ms_p50` Nullable(Float64) COMMENT 'Median wait milliseconds over included blob transactions with non-negative waits' CODEC(ZSTD(1)), + `blob_wait_ms_p90` Nullable(Float64) COMMENT 'p90 wait milliseconds over included blob transactions with non-negative waits' CODEC(ZSTD(1)), + `blob_wait_ms_p99` Nullable(Float64) COMMENT 'p99 wait milliseconds over included blob transactions with non-negative waits' CODEC(ZSTD(1)), + `blob_wait_sample_count` UInt64 COMMENT 'Number of included blob transactions contributing to the blob wait quantiles' CODEC(ZSTD(1)), + `nonce_group_count` UInt64 COMMENT 'Distinct from and nonce pairs across transactions first sighted this hour' CODEC(ZSTD(1)), + `multi_attempt_nonce_group_count` UInt64 COMMENT 'Nonce groups with at least two observed attempts, anchored to this hour by their earliest attempt sighting' CODEC(ZSTD(1)), + `replaced_attempt_count` UInt64 COMMENT 'Non-winning attempts across multi-attempt nonce groups anchored to this hour' CODEC(ZSTD(1)) +) ENGINE = ReplicatedReplacingMergeTree( + '/clickhouse/{installation}/{cluster}/tables/{shard}/{database}/{table}', + '{replica}', + `updated_date_time` +) PARTITION BY toStartOfMonth(hour_start_date_time) +ORDER BY + (`hour_start_date_time`) +SETTINGS + deduplicate_merge_projection_mode = 'rebuild' +COMMENT 'Hourly cohort outcomes for transactions first sighted in the public mempool, resolved at the fixed 7 day horizon'; + +CREATE TABLE fct_transaction_mempool_outcome_hourly ON CLUSTER '{cluster}' AS fct_transaction_mempool_outcome_hourly_local ENGINE = Distributed( + '{cluster}', + currentDatabase(), + fct_transaction_mempool_outcome_hourly_local, + cityHash64(`hour_start_date_time`) +); diff --git a/migrations/108_fct_transaction_mempool_outcome_daily.down.sql b/migrations/108_fct_transaction_mempool_outcome_daily.down.sql new file mode 100644 index 00000000..33ab9a74 --- /dev/null +++ b/migrations/108_fct_transaction_mempool_outcome_daily.down.sql @@ -0,0 +1,2 @@ +DROP TABLE IF EXISTS fct_transaction_mempool_outcome_daily ON CLUSTER '{cluster}'; +DROP TABLE IF EXISTS fct_transaction_mempool_outcome_daily_local ON CLUSTER '{cluster}'; diff --git a/migrations/108_fct_transaction_mempool_outcome_daily.up.sql b/migrations/108_fct_transaction_mempool_outcome_daily.up.sql new file mode 100644 index 00000000..8a6ac94d --- /dev/null +++ b/migrations/108_fct_transaction_mempool_outcome_daily.up.sql @@ -0,0 +1,42 @@ +CREATE TABLE fct_transaction_mempool_outcome_daily_local on cluster '{cluster}' ( + `updated_date_time` DateTime COMMENT 'Timestamp when the record was last updated' CODEC(DoubleDelta, ZSTD(1)), + `day_start_date` Date COMMENT 'Start of the day period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the day has been processed and never change afterwards' CODEC(DoubleDelta, ZSTD(1)), + `observed_count` UInt64 COMMENT 'Transactions first sighted in the public mempool this day' CODEC(ZSTD(1)), + `included_count` UInt64 COMMENT 'Observed transactions included within 7 days of first sighting' CODEC(ZSTD(1)), + `nonce_consumed_count` UInt64 COMMENT 'Observed transactions whose nonce was consumed by a different transaction within 7 days' CODEC(ZSTD(1)), + `unincluded_count` UInt64 COMMENT 'Observed transactions with no inclusion of their nonce within 7 days' CODEC(ZSTD(1)), + `included_relay_delivered_count` UInt64 COMMENT 'Included observed transactions whose block matched a known relay payload-delivered record' CODEC(ZSTD(1)), + `included_unknown_build_count` UInt64 COMMENT 'Included observed transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built' CODEC(ZSTD(1)), + `in_mempool_at_deadline_count` UInt64 COMMENT 'Unincluded transactions with a sighting in the final hour before the 7 day deadline' CODEC(ZSTD(1)), + `cancel_shape_count` UInt64 COMMENT 'Observed transactions that are self-transfers of zero value, the common wallet cancellation pattern' CODEC(ZSTD(1)), + `observed_after_nonce_consumed_count` UInt64 COMMENT 'Observed transactions first sighted after their nonce had already been consumed' CODEC(ZSTD(1)), + `wait_ms_p50` Nullable(Float64) COMMENT 'Median milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits' CODEC(ZSTD(1)), + `wait_ms_p90` Nullable(Float64) COMMENT 'p90 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits' CODEC(ZSTD(1)), + `wait_ms_p99` Nullable(Float64) COMMENT 'p99 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits' CODEC(ZSTD(1)), + `wait_sample_count` UInt64 COMMENT 'Number of included transactions contributing to the wait quantiles' CODEC(ZSTD(1)), + `negative_wait_count` UInt64 COMMENT 'Included transactions first sighted after their inclusion slot started, excluded from the wait quantiles' CODEC(ZSTD(1)), + `blob_observed_count` UInt64 COMMENT 'Observed blob type 3 transactions first sighted this day' CODEC(ZSTD(1)), + `blob_wait_ms_p50` Nullable(Float64) COMMENT 'Median wait milliseconds over included blob transactions with non-negative waits' CODEC(ZSTD(1)), + `blob_wait_ms_p90` Nullable(Float64) COMMENT 'p90 wait milliseconds over included blob transactions with non-negative waits' CODEC(ZSTD(1)), + `blob_wait_ms_p99` Nullable(Float64) COMMENT 'p99 wait milliseconds over included blob transactions with non-negative waits' CODEC(ZSTD(1)), + `blob_wait_sample_count` UInt64 COMMENT 'Number of included blob transactions contributing to the blob wait quantiles' CODEC(ZSTD(1)), + `nonce_group_count` UInt64 COMMENT 'Distinct from and nonce pairs across transactions first sighted this day' CODEC(ZSTD(1)), + `multi_attempt_nonce_group_count` UInt64 COMMENT 'Nonce groups with at least two observed attempts, anchored to this day by their earliest attempt sighting' CODEC(ZSTD(1)), + `replaced_attempt_count` UInt64 COMMENT 'Non-winning attempts across multi-attempt nonce groups anchored to this day' CODEC(ZSTD(1)) +) ENGINE = ReplicatedReplacingMergeTree( + '/clickhouse/{installation}/{cluster}/tables/{shard}/{database}/{table}', + '{replica}', + `updated_date_time` +) PARTITION BY toStartOfMonth(day_start_date) +ORDER BY + (`day_start_date`) +SETTINGS + deduplicate_merge_projection_mode = 'rebuild' +COMMENT 'Daily cohort outcomes for transactions first sighted in the public mempool, resolved at the fixed 7 day horizon'; + +CREATE TABLE fct_transaction_mempool_outcome_daily ON CLUSTER '{cluster}' AS fct_transaction_mempool_outcome_daily_local ENGINE = Distributed( + '{cluster}', + currentDatabase(), + fct_transaction_mempool_outcome_daily_local, + cityHash64(`day_start_date`) +); diff --git a/models/external/canonical_beacon_block_execution_transaction.sql b/models/external/canonical_beacon_block_execution_transaction.sql new file mode 100644 index 00000000..55b4a3ee --- /dev/null +++ b/models/external/canonical_beacon_block_execution_transaction.sql @@ -0,0 +1,31 @@ +--- +table: canonical_beacon_block_execution_transaction +cache: + incremental_scan_interval: 1m + full_scan_interval: 24h +interval: + type: slot +lag: 1920 +--- +SELECT + {{ if .cache.is_incremental_scan }} + '{{ .cache.previous_min }}' as min, + {{ else }} + toUnixTimestamp(min(slot_start_date_time)) as min, + {{ end }} + toUnixTimestamp(max(slot_start_date_time)) as max +FROM {{ .self.helpers.from }} +WHERE + meta_network_name = '{{ .env.NETWORK }}' + + -- previous_max if incremental scan and is set, otherwise default/env + {{- $ts := default "0" .env.EXTERNAL_MODEL_MIN_TIMESTAMP -}} + {{- if .cache.is_incremental_scan -}} + {{- if .cache.previous_max -}} + {{- $ts = .cache.previous_max -}} + {{- end -}} + {{- end }} + AND slot_start_date_time >= fromUnixTimestamp({{ $ts }}) + {{- if .cache.is_incremental_scan }} + AND slot_start_date_time <= fromUnixTimestamp({{ $ts }}) + {{ default "100000" .env.EXTERNAL_MODEL_SCAN_SIZE_TIMESTAMP }} + {{- end }} diff --git a/models/external/mempool_transaction.sql b/models/external/mempool_transaction.sql new file mode 100644 index 00000000..d87ccec6 --- /dev/null +++ b/models/external/mempool_transaction.sql @@ -0,0 +1,31 @@ +--- +table: mempool_transaction +cache: + incremental_scan_interval: 1m + full_scan_interval: 24h +interval: + type: slot +lag: 300 +--- +SELECT + {{ if .cache.is_incremental_scan }} + '{{ .cache.previous_min }}' as min, + {{ else }} + toUnixTimestamp(min(event_date_time)) as min, + {{ end }} + toUnixTimestamp(max(event_date_time)) as max +FROM {{ .self.helpers.from }} +WHERE + meta_network_name = '{{ .env.NETWORK }}' + + -- previous_max if incremental scan and is set, otherwise default/env + {{- $ts := default "0" .env.EXTERNAL_MODEL_MIN_TIMESTAMP -}} + {{- if .cache.is_incremental_scan -}} + {{- if .cache.previous_max -}} + {{- $ts = .cache.previous_max -}} + {{- end -}} + {{- end }} + AND event_date_time >= fromUnixTimestamp({{ $ts }}) + {{- if .cache.is_incremental_scan }} + AND event_date_time <= fromUnixTimestamp({{ $ts }}) + {{ default "100000" .env.EXTERNAL_MODEL_SCAN_SIZE_TIMESTAMP }} + {{- end }} diff --git a/models/transformations/fct_transaction_inclusion.sql b/models/transformations/fct_transaction_inclusion.sql new file mode 100644 index 00000000..56fa7afe --- /dev/null +++ b/models/transformations/fct_transaction_inclusion.sql @@ -0,0 +1,64 @@ +--- +table: fct_transaction_inclusion +type: incremental +interval: + type: slot + max: 21600 +schedules: + forwardfill: "@every 30s" + backfill: "@every 1m" +tags: + - slot + - transaction + - execution + - canonical +dependencies: + - "{{external}}.canonical_beacon_block_execution_transaction" + - "{{transformation}}.fct_block" +--- +-- One row per transaction included in a canonical beacon block execution payload. +-- Carries no mempool or relay context so its processable range is not gated by +-- mempool coverage and it can span the full post-Merge history. +INSERT INTO `{{ .self.database }}`.`{{ .self.table }}` +WITH blocks AS ( + SELECT + slot_start_date_time, + block_root, + execution_payload_block_number + FROM {{ index .dep "{{transformation}}" "fct_block" "helpers" "from" }} FINAL + WHERE slot_start_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) AND fromUnixTimestamp({{ .bounds.end }}) + AND status = 'canonical' +) +SELECT + fromUnixTimestamp({{ .task.start }}) AS updated_date_time, + tx.slot AS slot, + tx.slot_start_date_time AS slot_start_date_time, + tx.epoch AS epoch, + tx.epoch_start_date_time AS epoch_start_date_time, + tx.block_root AS block_root, + tx.block_version AS block_version, + CAST(b.execution_payload_block_number AS Nullable(UInt64)) AS block_number, + tx.position AS position, + tx.hash AS hash, + tx.`from` AS `from`, + tx.`to` AS `to`, + tx.nonce AS nonce, + tx.type AS type, + tx.gas AS gas, + tx.gas_price AS gas_price, + tx.gas_tip_cap AS gas_tip_cap, + tx.gas_fee_cap AS gas_fee_cap, + tx.value AS value, + tx.size AS size, + tx.call_data_size AS call_data_size, + tx.blob_gas AS blob_gas, + tx.blob_gas_fee_cap AS blob_gas_fee_cap, + tx.blob_hashes AS blob_hashes, + ifNull(tx.`to` = tx.`from`, 0) AND (tx.value = 0) AS is_cancel_shape +FROM {{ index .dep "{{external}}" "canonical_beacon_block_execution_transaction" "helpers" "from" }} tx +GLOBAL LEFT JOIN blocks b + ON b.slot_start_date_time = tx.slot_start_date_time AND b.block_root = tx.block_root +WHERE + tx.meta_network_name = '{{ .env.NETWORK }}' + AND tx.slot_start_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) AND fromUnixTimestamp({{ .bounds.end }}) +SETTINGS join_use_nulls = 1 diff --git a/models/transformations/fct_transaction_inclusion_daily.sql b/models/transformations/fct_transaction_inclusion_daily.sql new file mode 100644 index 00000000..32be2b12 --- /dev/null +++ b/models/transformations/fct_transaction_inclusion_daily.sql @@ -0,0 +1,67 @@ +--- +table: fct_transaction_inclusion_daily +type: incremental +interval: + type: slot + max: 604800 +schedules: + forwardfill: "@every 1h" + backfill: "@every 30s" +tags: + - daily + - transaction + - execution + - canonical +dependencies: + - "{{transformation}}.fct_transaction_inclusion" + - "{{transformation}}.fct_block_mev" +--- +-- Daily counts of transactions included in canonical blocks, split by build path +-- and transaction type. The scan expands to complete day boundaries so partial +-- boundary days from a previous run get re-aggregated and replaced. +INSERT INTO `{{ .self.database }}`.`{{ .self.table }}` +WITH txs AS ( + SELECT + slot_start_date_time, + block_root, + type, + blob_hashes, + `to`, + `from`, + is_cancel_shape + FROM {{ index .dep "{{transformation}}" "fct_transaction_inclusion" "helpers" "from" }} FINAL + WHERE slot_start_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 25 HOUR + AND fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 25 HOUR + AND toDate(slot_start_date_time) >= toDate(fromUnixTimestamp({{ .bounds.start }})) + AND toDate(slot_start_date_time) <= toDate(fromUnixTimestamp({{ .bounds.end }})) +), +mev AS ( + SELECT DISTINCT + slot_start_date_time, + block_root + FROM {{ index .dep "{{transformation}}" "fct_block_mev" "helpers" "from" }} FINAL + WHERE slot_start_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 25 HOUR + AND fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 25 HOUR + AND status = 'canonical' +) +SELECT + fromUnixTimestamp({{ .task.start }}) AS updated_date_time, + toDate(t.slot_start_date_time) AS day_start_date, + count() AS included_count, + countIf(m.block_root IS NOT NULL) AS relay_delivered_count, + countIf(m.block_root IS NULL) AS unknown_build_count, + countIf(t.type = 0) AS type0_count, + countIf(t.type = 1) AS type1_count, + countIf(t.type = 2) AS type2_count, + countIf(t.type = 3) AS type3_count, + countIf(t.type = 4) AS type4_count, + countIf(t.type > 4) AS type_other_count, + sum(length(t.blob_hashes)) AS blob_count, + countIf(t.`to` IS NULL) AS contract_creation_count, + countIf(t.is_cancel_shape) AS cancel_shape_count, + uniqExact(t.`from`) AS unique_senders +FROM txs t +GLOBAL LEFT JOIN mev m + ON m.slot_start_date_time = t.slot_start_date_time AND m.block_root = t.block_root +GROUP BY day_start_date +SETTINGS join_use_nulls = 1 diff --git a/models/transformations/fct_transaction_inclusion_hourly.sql b/models/transformations/fct_transaction_inclusion_hourly.sql new file mode 100644 index 00000000..bf9b892c --- /dev/null +++ b/models/transformations/fct_transaction_inclusion_hourly.sql @@ -0,0 +1,67 @@ +--- +table: fct_transaction_inclusion_hourly +type: incremental +interval: + type: slot + max: 25200 +schedules: + forwardfill: "@every 5m" + backfill: "@every 30s" +tags: + - hourly + - transaction + - execution + - canonical +dependencies: + - "{{transformation}}.fct_transaction_inclusion" + - "{{transformation}}.fct_block_mev" +--- +-- Hourly counts of transactions included in canonical blocks, split by build path +-- and transaction type. The scan expands to complete hour boundaries so partial +-- boundary hours from a previous run get re-aggregated and replaced. +INSERT INTO `{{ .self.database }}`.`{{ .self.table }}` +WITH txs AS ( + SELECT + slot_start_date_time, + block_root, + type, + blob_hashes, + `to`, + `from`, + is_cancel_shape + FROM {{ index .dep "{{transformation}}" "fct_transaction_inclusion" "helpers" "from" }} FINAL + WHERE slot_start_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 65 MINUTE + AND fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 65 MINUTE + AND toStartOfHour(slot_start_date_time) >= toStartOfHour(fromUnixTimestamp({{ .bounds.start }})) + AND toStartOfHour(slot_start_date_time) <= toStartOfHour(fromUnixTimestamp({{ .bounds.end }})) +), +mev AS ( + SELECT DISTINCT + slot_start_date_time, + block_root + FROM {{ index .dep "{{transformation}}" "fct_block_mev" "helpers" "from" }} FINAL + WHERE slot_start_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 65 MINUTE + AND fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 65 MINUTE + AND status = 'canonical' +) +SELECT + fromUnixTimestamp({{ .task.start }}) AS updated_date_time, + toStartOfHour(t.slot_start_date_time) AS hour_start_date_time, + count() AS included_count, + countIf(m.block_root IS NOT NULL) AS relay_delivered_count, + countIf(m.block_root IS NULL) AS unknown_build_count, + countIf(t.type = 0) AS type0_count, + countIf(t.type = 1) AS type1_count, + countIf(t.type = 2) AS type2_count, + countIf(t.type = 3) AS type3_count, + countIf(t.type = 4) AS type4_count, + countIf(t.type > 4) AS type_other_count, + sum(length(t.blob_hashes)) AS blob_count, + countIf(t.`to` IS NULL) AS contract_creation_count, + countIf(t.is_cancel_shape) AS cancel_shape_count, + uniqExact(t.`from`) AS unique_senders +FROM txs t +GLOBAL LEFT JOIN mev m + ON m.slot_start_date_time = t.slot_start_date_time AND m.block_root = t.block_root +GROUP BY hour_start_date_time +SETTINGS join_use_nulls = 1 diff --git a/models/transformations/fct_transaction_mempool_outcome_7d.sql b/models/transformations/fct_transaction_mempool_outcome_7d.sql new file mode 100644 index 00000000..00f5ad4b --- /dev/null +++ b/models/transformations/fct_transaction_mempool_outcome_7d.sql @@ -0,0 +1,204 @@ +--- +table: fct_transaction_mempool_outcome_7d +type: incremental +interval: + type: slot + max: 21600 +schedules: + forwardfill: "@every 30s" + backfill: "@every 1m" +fill: + buffer: 612000 +tags: + - slot + - transaction + - mempool + - execution +dependencies: + - "{{transformation}}.int_transaction_mempool_observation_hourly" + - "{{transformation}}.fct_transaction_inclusion" + - "{{transformation}}.fct_block_mev" +--- +-- One immutable row per transaction hash observed in the public mempool, stating its +-- fixed-horizon outcome within 7 days of first sighting. The fill buffer keeps this +-- model 612000 seconds (7 days plus slack) behind its dependencies so the full horizon +-- of observation and inclusion data exists before a chunk is processed. +-- An observation episode starts when a hash is sighted with no sightings in the +-- preceding 7 days. The outcome statement is fixed to the horizon and remains true +-- even if the transaction is included later. +INSERT INTO `{{ .self.database }}`.`{{ .self.table }}` +WITH obs AS ( + SELECT + hash, + first_seen_date_time, + last_seen_date_time, + sighting_count, + unique_sentries, + `from`, + `to`, + nonce, + type, + gas, + gas_price, + gas_tip_cap, + gas_fee_cap, + value, + size, + call_data_size, + blob_gas, + blob_gas_fee_cap, + blob_hashes, + is_cancel_shape + FROM {{ index .dep "{{transformation}}" "int_transaction_mempool_observation_hourly" "helpers" "from" }} FINAL + WHERE hour_start_date_time BETWEEN toStartOfHour(fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 7 DAY) + AND toStartOfHour(fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 7 DAY) +), +-- earliest sighting per hash within the anchor window +anchor_first AS ( + SELECT + hash, + min(first_seen_date_time) AS first_seen + FROM obs + WHERE first_seen_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) AND fromUnixTimestamp({{ .bounds.end }}) + GROUP BY hash +), +-- keep only hashes with no sighting in the 7 days before their anchor sighting +episodes AS ( + SELECT + a.hash AS hash, + a.first_seen AS first_seen + FROM anchor_first a + GLOBAL LEFT JOIN obs o ON o.hash = a.hash + GROUP BY a.hash, a.first_seen + HAVING countIf(o.first_seen_date_time < a.first_seen + AND o.first_seen_date_time >= a.first_seen - INTERVAL 7 DAY) = 0 +), +-- summarise each episode over its 7 day horizon +horizon AS ( + SELECT + e.hash AS hash, + e.first_seen AS first_seen, + max(o.last_seen_date_time) AS last_seen, + toUInt32(sum(o.sighting_count)) AS sighting_count, + max(o.unique_sentries) AS peak_hourly_unique_sentries, + argMin(o.`from`, o.first_seen_date_time) AS `from`, + argMin(o.`to`, o.first_seen_date_time) AS `to`, + argMin(o.nonce, o.first_seen_date_time) AS nonce, + argMin(o.type, o.first_seen_date_time) AS type, + argMin(o.gas, o.first_seen_date_time) AS gas, + argMin(o.gas_price, o.first_seen_date_time) AS gas_price, + argMin(o.gas_tip_cap, o.first_seen_date_time) AS gas_tip_cap, + argMin(o.gas_fee_cap, o.first_seen_date_time) AS gas_fee_cap, + argMin(o.value, o.first_seen_date_time) AS value, + argMin(o.size, o.first_seen_date_time) AS size, + argMin(o.call_data_size, o.first_seen_date_time) AS call_data_size, + argMin(o.blob_gas, o.first_seen_date_time) AS blob_gas, + argMin(o.blob_gas_fee_cap, o.first_seen_date_time) AS blob_gas_fee_cap, + argMin(o.blob_hashes, o.first_seen_date_time) AS blob_hashes, + argMin(o.is_cancel_shape, o.first_seen_date_time) AS is_cancel_shape, + max(if(o.last_seen_date_time >= e.first_seen + INTERVAL 167 HOUR, 1, 0)) AS in_deadline_hour + FROM episodes e + GLOBAL INNER JOIN obs o ON o.hash = e.hash + WHERE o.first_seen_date_time >= e.first_seen + AND o.first_seen_date_time <= e.first_seen + INTERVAL 7 DAY + GROUP BY e.hash, e.first_seen +), +-- inclusions of the observed nonce groups, wide enough to catch consumption before sighting +incl AS ( + SELECT + hash, + `from`, + nonce, + slot, + slot_start_date_time, + block_root, + position + FROM {{ index .dep "{{transformation}}" "fct_transaction_inclusion" "helpers" "from" }} FINAL + WHERE slot_start_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 14 DAY + AND fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 7 DAY + AND (`from`, nonce) GLOBAL IN (SELECT `from`, nonce FROM horizon) +), +-- this hash included within its horizon +own AS ( + SELECT + h.hash AS hash, + min(i.slot_start_date_time) AS islot_time, + argMin(i.slot, i.slot_start_date_time) AS islot, + argMin(i.block_root, i.slot_start_date_time) AS iroot, + argMin(i.position, i.slot_start_date_time) AS ipos + FROM horizon h + GLOBAL INNER JOIN incl i ON i.hash = h.hash + WHERE i.slot_start_date_time <= h.first_seen + INTERVAL 7 DAY + GROUP BY h.hash +), +-- earliest inclusion of the nonce group within the horizon, any hash +winner AS ( + SELECT + h.hash AS hash, + argMin(i.hash, i.slot_start_date_time) AS whash, + min(i.slot_start_date_time) AS wslot_time + FROM horizon h + GLOBAL INNER JOIN incl i ON i.`from` = h.`from` AND i.nonce = h.nonce + WHERE i.slot_start_date_time <= h.first_seen + INTERVAL 7 DAY + GROUP BY h.hash +), +-- relay evidence for including blocks +mev AS ( + SELECT DISTINCT + slot_start_date_time, + block_root + FROM {{ index .dep "{{transformation}}" "fct_block_mev" "helpers" "from" }} FINAL + WHERE slot_start_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 14 DAY + AND fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 7 DAY + AND status = 'canonical' +) +SELECT + fromUnixTimestamp({{ .task.start }}) AS updated_date_time, + h.first_seen AS first_seen_date_time, + h.hash AS hash, + h.`from` AS `from`, + h.`to` AS `to`, + h.nonce AS nonce, + h.type AS type, + h.gas AS gas, + h.gas_price AS gas_price, + h.gas_tip_cap AS gas_tip_cap, + h.gas_fee_cap AS gas_fee_cap, + h.value AS value, + h.size AS size, + h.call_data_size AS call_data_size, + h.blob_gas AS blob_gas, + h.blob_gas_fee_cap AS blob_gas_fee_cap, + h.blob_hashes AS blob_hashes, + h.is_cancel_shape AS is_cancel_shape, + h.last_seen AS last_seen_date_time, + h.sighting_count AS sighting_count, + h.peak_hourly_unique_sentries AS peak_hourly_unique_sentries, + multiIf( + o.islot_time IS NOT NULL, 'included', + w.wslot_time IS NOT NULL, 'nonce_consumed', + 'unincluded' + ) AS outcome, + multiIf( + o.islot_time IS NOT NULL, toDateTime64(o.islot_time, 3), + w.wslot_time IS NOT NULL, toDateTime64(w.wslot_time, 3), + h.first_seen + INTERVAL 7 DAY + ) AS resolution_date_time, + o.islot AS included_slot, + o.islot_time AS included_slot_start_date_time, + o.iroot AS included_block_root, + o.ipos AS included_position, + if(o.islot_time IS NOT NULL, + dateDiff('millisecond', h.first_seen, toDateTime64(o.islot_time, 3)), + NULL + ) AS wait_ms, + if(o.islot_time IS NOT NULL, m.block_root IS NOT NULL, NULL) AS included_via_known_relay, + if(outcome = 'nonce_consumed', w.whash, NULL) AS winner_hash, + if(outcome = 'nonce_consumed', w.wslot_time, NULL) AS winner_slot_start_date_time, + ifNull(outcome = 'nonce_consumed' AND w.wslot_time < h.first_seen, 0) AS observed_after_nonce_consumed, + if(outcome = 'unincluded', h.in_deadline_hour, 0) AS in_mempool_at_deadline +FROM horizon h +GLOBAL LEFT JOIN own o ON o.hash = h.hash +GLOBAL LEFT JOIN winner w ON w.hash = h.hash +GLOBAL LEFT JOIN mev m ON m.slot_start_date_time = o.islot_time AND m.block_root = o.iroot +SETTINGS join_use_nulls = 1 diff --git a/models/transformations/fct_transaction_mempool_outcome_daily.sql b/models/transformations/fct_transaction_mempool_outcome_daily.sql new file mode 100644 index 00000000..e6a4360f --- /dev/null +++ b/models/transformations/fct_transaction_mempool_outcome_daily.sql @@ -0,0 +1,93 @@ +--- +table: fct_transaction_mempool_outcome_daily +type: incremental +interval: + type: slot + max: 604800 +schedules: + forwardfill: "@every 1h" + backfill: "@every 30s" +tags: + - daily + - transaction + - mempool + - execution +dependencies: + - "{{transformation}}.fct_transaction_mempool_outcome_7d" + - "{{transformation}}.fct_transaction_replacement" +--- +-- Daily cohort outcomes for transactions first sighted in the public mempool, +-- bucketed by first sighting time. Buckets are complete once the upstream 7 day +-- horizon has been processed and never change afterwards. The scan expands to +-- complete day boundaries so partial boundary days get re-aggregated and replaced. +INSERT INTO `{{ .self.database }}`.`{{ .self.table }}` +WITH outcomes AS ( + SELECT + toDate(first_seen_date_time) AS day_start_date, + count() AS observed_count, + countIf(outcome = 'included') AS included_count, + countIf(outcome = 'nonce_consumed') AS nonce_consumed_count, + countIf(outcome = 'unincluded') AS unincluded_count, + countIf(outcome = 'included' AND ifNull(included_via_known_relay, 0)) AS included_relay_delivered_count, + countIf(outcome = 'included' AND NOT ifNull(included_via_known_relay, 1)) AS included_unknown_build_count, + countIf(in_mempool_at_deadline) AS in_mempool_at_deadline_count, + countIf(is_cancel_shape) AS cancel_shape_count, + countIf(observed_after_nonce_consumed) AS observed_after_nonce_consumed_count, + countIf(outcome = 'included' AND wait_ms >= 0) AS wait_sample_count, + if(wait_sample_count > 0, quantileIf(0.50)(wait_ms, outcome = 'included' AND wait_ms >= 0), NULL) AS wait_ms_p50, + if(wait_sample_count > 0, quantileIf(0.90)(wait_ms, outcome = 'included' AND wait_ms >= 0), NULL) AS wait_ms_p90, + if(wait_sample_count > 0, quantileIf(0.99)(wait_ms, outcome = 'included' AND wait_ms >= 0), NULL) AS wait_ms_p99, + countIf(outcome = 'included' AND wait_ms < 0) AS negative_wait_count, + countIf(type = 3) AS blob_observed_count, + countIf(type = 3 AND outcome = 'included' AND wait_ms >= 0) AS blob_wait_sample_count, + if(blob_wait_sample_count > 0, quantileIf(0.50)(wait_ms, type = 3 AND outcome = 'included' AND wait_ms >= 0), NULL) AS blob_wait_ms_p50, + if(blob_wait_sample_count > 0, quantileIf(0.90)(wait_ms, type = 3 AND outcome = 'included' AND wait_ms >= 0), NULL) AS blob_wait_ms_p90, + if(blob_wait_sample_count > 0, quantileIf(0.99)(wait_ms, type = 3 AND outcome = 'included' AND wait_ms >= 0), NULL) AS blob_wait_ms_p99, + uniqExact(`from`, nonce) AS nonce_group_count + FROM {{ index .dep "{{transformation}}" "fct_transaction_mempool_outcome_7d" "helpers" "from" }} FINAL + WHERE first_seen_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 25 HOUR + AND fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 25 HOUR + AND toDate(first_seen_date_time) >= toDate(fromUnixTimestamp({{ .bounds.start }})) + AND toDate(first_seen_date_time) <= toDate(fromUnixTimestamp({{ .bounds.end }})) + GROUP BY day_start_date +), +replacements AS ( + SELECT + toDate(group_first_seen_date_time) AS day_start_date, + uniqExact(`from`, nonce) AS multi_attempt_nonce_group_count, + countIf(NOT is_winner) AS replaced_attempt_count + FROM {{ index .dep "{{transformation}}" "fct_transaction_replacement" "helpers" "from" }} FINAL + WHERE group_first_seen_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 25 HOUR + AND fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 25 HOUR + AND toDate(group_first_seen_date_time) >= toDate(fromUnixTimestamp({{ .bounds.start }})) + AND toDate(group_first_seen_date_time) <= toDate(fromUnixTimestamp({{ .bounds.end }})) + GROUP BY day_start_date +) +SELECT + fromUnixTimestamp({{ .task.start }}) AS updated_date_time, + o.day_start_date AS day_start_date, + o.observed_count AS observed_count, + o.included_count AS included_count, + o.nonce_consumed_count AS nonce_consumed_count, + o.unincluded_count AS unincluded_count, + o.included_relay_delivered_count AS included_relay_delivered_count, + o.included_unknown_build_count AS included_unknown_build_count, + o.in_mempool_at_deadline_count AS in_mempool_at_deadline_count, + o.cancel_shape_count AS cancel_shape_count, + o.observed_after_nonce_consumed_count AS observed_after_nonce_consumed_count, + o.wait_ms_p50 AS wait_ms_p50, + o.wait_ms_p90 AS wait_ms_p90, + o.wait_ms_p99 AS wait_ms_p99, + o.wait_sample_count AS wait_sample_count, + o.negative_wait_count AS negative_wait_count, + o.blob_observed_count AS blob_observed_count, + o.blob_wait_ms_p50 AS blob_wait_ms_p50, + o.blob_wait_ms_p90 AS blob_wait_ms_p90, + o.blob_wait_ms_p99 AS blob_wait_ms_p99, + o.blob_wait_sample_count AS blob_wait_sample_count, + o.nonce_group_count AS nonce_group_count, + ifNull(r.multi_attempt_nonce_group_count, 0) AS multi_attempt_nonce_group_count, + ifNull(r.replaced_attempt_count, 0) AS replaced_attempt_count +FROM outcomes o +GLOBAL LEFT JOIN replacements r ON r.day_start_date = o.day_start_date +SETTINGS join_use_nulls = 1 diff --git a/models/transformations/fct_transaction_mempool_outcome_hourly.sql b/models/transformations/fct_transaction_mempool_outcome_hourly.sql new file mode 100644 index 00000000..42485e94 --- /dev/null +++ b/models/transformations/fct_transaction_mempool_outcome_hourly.sql @@ -0,0 +1,93 @@ +--- +table: fct_transaction_mempool_outcome_hourly +type: incremental +interval: + type: slot + max: 25200 +schedules: + forwardfill: "@every 5m" + backfill: "@every 30s" +tags: + - hourly + - transaction + - mempool + - execution +dependencies: + - "{{transformation}}.fct_transaction_mempool_outcome_7d" + - "{{transformation}}.fct_transaction_replacement" +--- +-- Hourly cohort outcomes for transactions first sighted in the public mempool, +-- bucketed by first sighting time. Buckets are complete once the upstream 7 day +-- horizon has been processed and never change afterwards. The scan expands to +-- complete hour boundaries so partial boundary hours get re-aggregated and replaced. +INSERT INTO `{{ .self.database }}`.`{{ .self.table }}` +WITH outcomes AS ( + SELECT + toStartOfHour(first_seen_date_time) AS hour_start_date_time, + count() AS observed_count, + countIf(outcome = 'included') AS included_count, + countIf(outcome = 'nonce_consumed') AS nonce_consumed_count, + countIf(outcome = 'unincluded') AS unincluded_count, + countIf(outcome = 'included' AND ifNull(included_via_known_relay, 0)) AS included_relay_delivered_count, + countIf(outcome = 'included' AND NOT ifNull(included_via_known_relay, 1)) AS included_unknown_build_count, + countIf(in_mempool_at_deadline) AS in_mempool_at_deadline_count, + countIf(is_cancel_shape) AS cancel_shape_count, + countIf(observed_after_nonce_consumed) AS observed_after_nonce_consumed_count, + countIf(outcome = 'included' AND wait_ms >= 0) AS wait_sample_count, + if(wait_sample_count > 0, quantileIf(0.50)(wait_ms, outcome = 'included' AND wait_ms >= 0), NULL) AS wait_ms_p50, + if(wait_sample_count > 0, quantileIf(0.90)(wait_ms, outcome = 'included' AND wait_ms >= 0), NULL) AS wait_ms_p90, + if(wait_sample_count > 0, quantileIf(0.99)(wait_ms, outcome = 'included' AND wait_ms >= 0), NULL) AS wait_ms_p99, + countIf(outcome = 'included' AND wait_ms < 0) AS negative_wait_count, + countIf(type = 3) AS blob_observed_count, + countIf(type = 3 AND outcome = 'included' AND wait_ms >= 0) AS blob_wait_sample_count, + if(blob_wait_sample_count > 0, quantileIf(0.50)(wait_ms, type = 3 AND outcome = 'included' AND wait_ms >= 0), NULL) AS blob_wait_ms_p50, + if(blob_wait_sample_count > 0, quantileIf(0.90)(wait_ms, type = 3 AND outcome = 'included' AND wait_ms >= 0), NULL) AS blob_wait_ms_p90, + if(blob_wait_sample_count > 0, quantileIf(0.99)(wait_ms, type = 3 AND outcome = 'included' AND wait_ms >= 0), NULL) AS blob_wait_ms_p99, + uniqExact(`from`, nonce) AS nonce_group_count + FROM {{ index .dep "{{transformation}}" "fct_transaction_mempool_outcome_7d" "helpers" "from" }} FINAL + WHERE first_seen_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 65 MINUTE + AND fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 65 MINUTE + AND toStartOfHour(first_seen_date_time) >= toStartOfHour(fromUnixTimestamp({{ .bounds.start }})) + AND toStartOfHour(first_seen_date_time) <= toStartOfHour(fromUnixTimestamp({{ .bounds.end }})) + GROUP BY hour_start_date_time +), +replacements AS ( + SELECT + toStartOfHour(group_first_seen_date_time) AS hour_start_date_time, + uniqExact(`from`, nonce) AS multi_attempt_nonce_group_count, + countIf(NOT is_winner) AS replaced_attempt_count + FROM {{ index .dep "{{transformation}}" "fct_transaction_replacement" "helpers" "from" }} FINAL + WHERE group_first_seen_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 65 MINUTE + AND fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 65 MINUTE + AND toStartOfHour(group_first_seen_date_time) >= toStartOfHour(fromUnixTimestamp({{ .bounds.start }})) + AND toStartOfHour(group_first_seen_date_time) <= toStartOfHour(fromUnixTimestamp({{ .bounds.end }})) + GROUP BY hour_start_date_time +) +SELECT + fromUnixTimestamp({{ .task.start }}) AS updated_date_time, + o.hour_start_date_time AS hour_start_date_time, + o.observed_count AS observed_count, + o.included_count AS included_count, + o.nonce_consumed_count AS nonce_consumed_count, + o.unincluded_count AS unincluded_count, + o.included_relay_delivered_count AS included_relay_delivered_count, + o.included_unknown_build_count AS included_unknown_build_count, + o.in_mempool_at_deadline_count AS in_mempool_at_deadline_count, + o.cancel_shape_count AS cancel_shape_count, + o.observed_after_nonce_consumed_count AS observed_after_nonce_consumed_count, + o.wait_ms_p50 AS wait_ms_p50, + o.wait_ms_p90 AS wait_ms_p90, + o.wait_ms_p99 AS wait_ms_p99, + o.wait_sample_count AS wait_sample_count, + o.negative_wait_count AS negative_wait_count, + o.blob_observed_count AS blob_observed_count, + o.blob_wait_ms_p50 AS blob_wait_ms_p50, + o.blob_wait_ms_p90 AS blob_wait_ms_p90, + o.blob_wait_ms_p99 AS blob_wait_ms_p99, + o.blob_wait_sample_count AS blob_wait_sample_count, + o.nonce_group_count AS nonce_group_count, + ifNull(r.multi_attempt_nonce_group_count, 0) AS multi_attempt_nonce_group_count, + ifNull(r.replaced_attempt_count, 0) AS replaced_attempt_count +FROM outcomes o +GLOBAL LEFT JOIN replacements r ON r.hour_start_date_time = o.hour_start_date_time +SETTINGS join_use_nulls = 1 diff --git a/models/transformations/fct_transaction_replacement.sql b/models/transformations/fct_transaction_replacement.sql new file mode 100644 index 00000000..ddb1097f --- /dev/null +++ b/models/transformations/fct_transaction_replacement.sql @@ -0,0 +1,173 @@ +--- +table: fct_transaction_replacement +type: incremental +interval: + type: slot + max: 21600 +schedules: + forwardfill: "@every 30s" + backfill: "@every 1m" +fill: + buffer: 612000 +tags: + - slot + - transaction + - mempool + - execution +dependencies: + - "{{transformation}}.int_transaction_mempool_observation_hourly" + - "{{transformation}}.fct_transaction_inclusion" +--- +-- One row per publicly observed attempt in nonce groups with at least two attempts, +-- emitted when the group resolves. A nonce group is all transactions sharing a from +-- address and nonce whose first sightings fall within 7 days of the group anchor +-- (the earliest attempt sighting). The fill buffer keeps this model 612000 seconds +-- behind its dependencies so the full group window exists before a chunk is processed. +-- Attempts are ordered deterministically by (first sighting, hash). +INSERT INTO `{{ .self.database }}`.`{{ .self.table }}` +WITH obs AS ( + SELECT + hash, + first_seen_date_time, + `from`, + `to`, + nonce, + type, + gas_price, + gas_tip_cap, + gas_fee_cap, + value, + is_cancel_shape + FROM {{ index .dep "{{transformation}}" "int_transaction_mempool_observation_hourly" "helpers" "from" }} FINAL + WHERE hour_start_date_time BETWEEN toStartOfHour(fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 7 DAY) + AND toStartOfHour(fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 7 DAY) +), +-- earliest attempt sighting per nonce group within the anchor window +anchor_groups AS ( + SELECT + `from`, + nonce, + min(first_seen_date_time) AS gfs + FROM obs + WHERE first_seen_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) AND fromUnixTimestamp({{ .bounds.end }}) + GROUP BY `from`, nonce +), +-- keep only groups with no attempt sighting in the 7 days before their anchor +group_episodes AS ( + SELECT + a.`from` AS `from`, + a.nonce AS nonce, + a.gfs AS gfs + FROM anchor_groups a + GLOBAL LEFT JOIN obs o ON o.`from` = a.`from` AND o.nonce = a.nonce + GROUP BY a.`from`, a.nonce, a.gfs + HAVING countIf(o.first_seen_date_time < a.gfs + AND o.first_seen_date_time >= a.gfs - INTERVAL 7 DAY) = 0 +), +-- one row per attempt hash within the group window +attempts AS ( + SELECT + g.`from` AS `from`, + g.nonce AS nonce, + g.gfs AS gfs, + o.hash AS hash, + min(o.first_seen_date_time) AS afs, + argMin(o.`to`, o.first_seen_date_time) AS `to`, + argMin(o.type, o.first_seen_date_time) AS type, + argMin(o.gas_price, o.first_seen_date_time) AS gas_price, + argMin(o.gas_tip_cap, o.first_seen_date_time) AS gas_tip_cap, + argMin(o.gas_fee_cap, o.first_seen_date_time) AS gas_fee_cap, + argMin(o.value, o.first_seen_date_time) AS value, + argMin(o.is_cancel_shape, o.first_seen_date_time) AS is_cancel_shape + FROM group_episodes g + GLOBAL INNER JOIN obs o ON o.`from` = g.`from` AND o.nonce = g.nonce + WHERE o.first_seen_date_time >= g.gfs + AND o.first_seen_date_time <= g.gfs + INTERVAL 7 DAY + GROUP BY g.`from`, g.nonce, g.gfs, o.hash +), +-- nonce groups with at least two observed attempts +multi_groups AS ( + SELECT + `from`, + nonce + FROM attempts + GROUP BY `from`, nonce + HAVING uniqExact(hash) >= 2 +), +-- inclusions of the qualifying groups, wide enough to catch consumption before sighting +incl AS ( + SELECT + hash, + `from`, + nonce, + slot_start_date_time + FROM {{ index .dep "{{transformation}}" "fct_transaction_inclusion" "helpers" "from" }} FINAL + WHERE slot_start_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 14 DAY + AND fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 7 DAY + AND (`from`, nonce) GLOBAL IN (SELECT `from`, nonce FROM multi_groups) +), +-- earliest inclusion of each group within the group window +winners AS ( + SELECT + g.`from` AS `from`, + g.nonce AS nonce, + argMin(i.hash, i.slot_start_date_time) AS whash, + min(i.slot_start_date_time) AS wslot + FROM group_episodes g + GLOBAL INNER JOIN incl i ON i.`from` = g.`from` AND i.nonce = g.nonce + WHERE i.slot_start_date_time <= g.gfs + INTERVAL 7 DAY + GROUP BY g.`from`, g.nonce +), +indexed AS ( + SELECT + a.`from` AS `from`, + a.nonce AS nonce, + a.gfs AS gfs, + a.hash AS hash, + a.afs AS afs, + a.`to` AS `to`, + a.type AS type, + a.gas_price AS gas_price, + a.gas_tip_cap AS gas_tip_cap, + a.gas_fee_cap AS gas_fee_cap, + a.value AS value, + a.is_cancel_shape AS is_cancel_shape, + toUInt16(row_number() OVER w) AS attempt_index, + toUInt16(count(*) OVER (PARTITION BY a.`from`, a.nonce)) AS group_attempt_count, + lagInFrame(a.hash) OVER w AS prev_hash_raw, + lagInFrame(a.gas_tip_cap) OVER w AS prev_gas_tip_cap, + lagInFrame(a.gas_fee_cap) OVER w AS prev_gas_fee_cap + FROM attempts a + WHERE (a.`from`, a.nonce) GLOBAL IN (SELECT `from`, nonce FROM multi_groups) + WINDOW w AS (PARTITION BY a.`from`, a.nonce ORDER BY a.afs ASC, a.hash ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) +) +SELECT + fromUnixTimestamp({{ .task.start }}) AS updated_date_time, + x.gfs AS group_first_seen_date_time, + x.`from` AS `from`, + x.nonce AS nonce, + x.hash AS hash, + x.attempt_index AS attempt_index, + x.group_attempt_count AS group_attempt_count, + x.afs AS first_seen_date_time, + if(x.attempt_index = 1, NULL, x.prev_hash_raw) AS previous_hash, + x.`to` AS `to`, + x.type AS type, + x.gas_price AS gas_price, + x.gas_tip_cap AS gas_tip_cap, + x.gas_fee_cap AS gas_fee_cap, + x.value AS value, + if(x.attempt_index = 1, NULL, toInt128(x.gas_tip_cap) - toInt128(x.prev_gas_tip_cap)) AS gas_tip_cap_delta, + if(x.attempt_index = 1, NULL, toInt128(x.gas_fee_cap) - toInt128(x.prev_gas_fee_cap)) AS gas_fee_cap_delta, + x.is_cancel_shape AS is_cancel_shape, + ifNull(x.hash = wn.whash, 0) AS is_winner, + if(wn.wslot IS NOT NULL, 'included', 'unincluded') AS group_outcome, + wn.whash AS winner_hash, + multiIf( + wn.wslot IS NOT NULL, toDateTime64(wn.wslot, 3), + x.gfs + INTERVAL 7 DAY + ) AS resolution_date_time, + x.afs > resolution_date_time AS observed_after_resolution +FROM indexed x +GLOBAL LEFT JOIN winners wn ON wn.`from` = x.`from` AND wn.nonce = x.nonce +SETTINGS join_use_nulls = 1 diff --git a/models/transformations/int_transaction_mempool_observation_hourly.sql b/models/transformations/int_transaction_mempool_observation_hourly.sql new file mode 100644 index 00000000..fa701b23 --- /dev/null +++ b/models/transformations/int_transaction_mempool_observation_hourly.sql @@ -0,0 +1,60 @@ +--- +table: int_transaction_mempool_observation_hourly +type: incremental +interval: + type: slot + max: 3600 +schedules: + forwardfill: "@every 30s" + backfill: "@every 30s" +tags: + - hourly + - transaction + - mempool + - execution +dependencies: + - "{{external}}.mempool_transaction" +--- +-- One row per transaction hash per hour in which it was sighted in the public mempool. +-- Each raw sighting is scanned exactly once per processed hour. The scan expands to +-- complete hour boundaries so partial boundary hours from a previous run get +-- re-aggregated with complete data and replaced via ReplacingMergeTree. +-- Identity fields are constant per hash so any() is safe. The first observer is +-- chosen deterministically by (event_date_time, meta_client_name). +INSERT INTO `{{ .self.database }}`.`{{ .self.table }}` +SELECT + fromUnixTimestamp({{ .task.start }}) AS updated_date_time, + toStartOfHour(event_date_time) AS hour_start_date_time, + hash, + min(event_date_time) AS first_seen_date_time, + max(event_date_time) AS last_seen_date_time, + toUInt32(count()) AS sighting_count, + toUInt32(uniqExact(meta_client_name)) AS unique_sentries, + any(`from`) AS `from`, + any(`to`) AS `to`, + any(nonce) AS nonce, + any(type) AS type, + any(gas) AS gas, + any(gas_price) AS gas_price, + any(gas_tip_cap) AS gas_tip_cap, + any(gas_fee_cap) AS gas_fee_cap, + any(value) AS value, + any(size) AS size, + any(call_data_size) AS call_data_size, + any(blob_gas) AS blob_gas, + any(blob_gas_fee_cap) AS blob_gas_fee_cap, + any(blob_hashes) AS blob_hashes, + any(ifNull(m.`to` = m.`from`, 0) AND (m.value = 0)) AS is_cancel_shape, + argMin(meta_client_name, (event_date_time, meta_client_name)) AS first_sentry_name, + argMin(meta_client_geo_city, (event_date_time, meta_client_name)) AS first_sentry_geo_city, + argMin(meta_client_geo_country, (event_date_time, meta_client_name)) AS first_sentry_geo_country, + argMin(meta_client_geo_country_code, (event_date_time, meta_client_name)) AS first_sentry_geo_country_code, + argMin(meta_client_geo_continent_code, (event_date_time, meta_client_name)) AS first_sentry_geo_continent_code +FROM {{ index .dep "{{external}}" "mempool_transaction" "helpers" "from" }} m +WHERE + meta_network_name = '{{ .env.NETWORK }}' + AND event_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) - INTERVAL 65 MINUTE + AND fromUnixTimestamp({{ .bounds.end }}) + INTERVAL 65 MINUTE + AND toStartOfHour(event_date_time) >= toStartOfHour(fromUnixTimestamp({{ .bounds.start }})) + AND toStartOfHour(event_date_time) <= toStartOfHour(fromUnixTimestamp({{ .bounds.end }})) +GROUP BY hour_start_date_time, hash diff --git a/pkg/proto/clickhouse/fct_transaction_inclusion.go b/pkg/proto/clickhouse/fct_transaction_inclusion.go new file mode 100644 index 00000000..9ca69ace --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_inclusion.go @@ -0,0 +1,870 @@ +// Code generated by clickhouse-proto-gen. DO NOT EDIT. +// SQL query builder for fct_transaction_inclusion + +package clickhouse + +import ( + "fmt" +) + +// BuildListFctTransactionInclusionQuery constructs a parameterized SQL query from a ListFctTransactionInclusionRequest +// +// Available projections: +// - p_by_hash (primary key: hash) +// - p_by_nonce_group (primary key: from) +// +// Use WithProjection() option to select a specific projection. +func BuildListFctTransactionInclusionQuery(req *ListFctTransactionInclusionRequest, options ...QueryOption) (SQLQuery, error) { + // Validate that at least one primary key is provided + // Primary keys can come from base table or projections + if req.From == nil && req.Hash == nil && req.SlotStartDateTime == nil { + return SQLQuery{}, fmt.Errorf("at least one primary key field is required: from, hash, slot_start_date_time") + } + + // Build query using QueryBuilder + qb := NewQueryBuilder() + + // Add primary key filter + if req.SlotStartDateTime != nil { + switch filter := req.SlotStartDateTime.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("slot_start_date_time", "=", DateTimeValue{filter.Eq}) + case *UInt32Filter_Ne: + qb.AddCondition("slot_start_date_time", "!=", DateTimeValue{filter.Ne}) + case *UInt32Filter_Lt: + qb.AddCondition("slot_start_date_time", "<", DateTimeValue{filter.Lt}) + case *UInt32Filter_Lte: + qb.AddCondition("slot_start_date_time", "<=", DateTimeValue{filter.Lte}) + case *UInt32Filter_Gt: + qb.AddCondition("slot_start_date_time", ">", DateTimeValue{filter.Gt}) + case *UInt32Filter_Gte: + qb.AddCondition("slot_start_date_time", ">=", DateTimeValue{filter.Gte}) + case *UInt32Filter_Between: + qb.AddBetweenCondition("slot_start_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("slot_start_date_time", converted) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("slot_start_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: updated_date_time + if req.UpdatedDateTime != nil { + switch filter := req.UpdatedDateTime.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("updated_date_time", "=", DateTimeValue{filter.Eq}) + case *UInt32Filter_Ne: + qb.AddCondition("updated_date_time", "!=", DateTimeValue{filter.Ne}) + case *UInt32Filter_Lt: + qb.AddCondition("updated_date_time", "<", DateTimeValue{filter.Lt}) + case *UInt32Filter_Lte: + qb.AddCondition("updated_date_time", "<=", DateTimeValue{filter.Lte}) + case *UInt32Filter_Gt: + qb.AddCondition("updated_date_time", ">", DateTimeValue{filter.Gt}) + case *UInt32Filter_Gte: + qb.AddCondition("updated_date_time", ">=", DateTimeValue{filter.Gte}) + case *UInt32Filter_Between: + qb.AddBetweenCondition("updated_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("updated_date_time", converted) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("updated_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: slot + if req.Slot != nil { + switch filter := req.Slot.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("slot", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("slot", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("slot", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("slot", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("slot", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("slot", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("slot", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("slot", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("slot", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: epoch + if req.Epoch != nil { + switch filter := req.Epoch.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("epoch", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("epoch", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("epoch", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("epoch", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("epoch", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("epoch", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("epoch", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("epoch", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("epoch", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: epoch_start_date_time + if req.EpochStartDateTime != nil { + switch filter := req.EpochStartDateTime.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("epoch_start_date_time", "=", DateTimeValue{filter.Eq}) + case *UInt32Filter_Ne: + qb.AddCondition("epoch_start_date_time", "!=", DateTimeValue{filter.Ne}) + case *UInt32Filter_Lt: + qb.AddCondition("epoch_start_date_time", "<", DateTimeValue{filter.Lt}) + case *UInt32Filter_Lte: + qb.AddCondition("epoch_start_date_time", "<=", DateTimeValue{filter.Lte}) + case *UInt32Filter_Gt: + qb.AddCondition("epoch_start_date_time", ">", DateTimeValue{filter.Gt}) + case *UInt32Filter_Gte: + qb.AddCondition("epoch_start_date_time", ">=", DateTimeValue{filter.Gte}) + case *UInt32Filter_Between: + qb.AddBetweenCondition("epoch_start_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("epoch_start_date_time", converted) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("epoch_start_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: block_root + if req.BlockRoot != nil { + switch filter := req.BlockRoot.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("block_root", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("block_root", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("block_root", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("block_root", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("block_root", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("block_root", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("block_root", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("block_root", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("block_root", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: block_version + if req.BlockVersion != nil { + switch filter := req.BlockVersion.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("block_version", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("block_version", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("block_version", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("block_version", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("block_version", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("block_version", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("block_version", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("block_version", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("block_version", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: block_number + if req.BlockNumber != nil { + switch filter := req.BlockNumber.Filter.(type) { + case *NullableUInt64Filter_Eq: + qb.AddCondition("block_number", "=", filter.Eq) + case *NullableUInt64Filter_Ne: + qb.AddCondition("block_number", "!=", filter.Ne) + case *NullableUInt64Filter_Lt: + qb.AddCondition("block_number", "<", filter.Lt) + case *NullableUInt64Filter_Lte: + qb.AddCondition("block_number", "<=", filter.Lte) + case *NullableUInt64Filter_Gt: + qb.AddCondition("block_number", ">", filter.Gt) + case *NullableUInt64Filter_Gte: + qb.AddCondition("block_number", ">=", filter.Gte) + case *NullableUInt64Filter_Between: + qb.AddBetweenCondition("block_number", filter.Between.Min, filter.Between.Max.GetValue()) + case *NullableUInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("block_number", UInt64SliceToInterface(filter.In.Values)) + } + case *NullableUInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("block_number", UInt64SliceToInterface(filter.NotIn.Values)) + } + case *NullableUInt64Filter_IsNull: + qb.AddIsNullCondition("block_number") + case *NullableUInt64Filter_IsNotNull: + qb.AddIsNotNullCondition("block_number") + default: + // Unsupported filter type + } + } + + // Add filter for column: position + if req.Position != nil { + switch filter := req.Position.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("position", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("position", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("position", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("position", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("position", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("position", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("position", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("position", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("position", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: hash + if req.Hash != nil { + switch filter := req.Hash.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("hash", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("hash", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("hash", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("hash", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("hash", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("hash", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("hash", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("hash", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("hash", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: from + if req.From != nil { + switch filter := req.From.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("from", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("from", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("from", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("from", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("from", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("from", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("from", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("from", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("from", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: to + if req.To != nil { + switch filter := req.To.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("to", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("to", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("to", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("to", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("to", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("to", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("to", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("to", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("to", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("to") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("to") + default: + // Unsupported filter type + } + } + + // Add filter for column: nonce + if req.Nonce != nil { + switch filter := req.Nonce.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("nonce", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("nonce", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("nonce", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("nonce", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("nonce", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("nonce", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("nonce", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("nonce", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("nonce", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type + if req.Type != nil { + switch filter := req.Type.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("type", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("type", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("type", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("type", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("type", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("type", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("type", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: gas + if req.Gas != nil { + switch filter := req.Gas.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("gas", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("gas", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("gas", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("gas", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("gas", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("gas", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("gas", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_price + if req.GasPrice != nil { + switch filter := req.GasPrice.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("gas_price", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("gas_price", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("gas_price", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("gas_price", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("gas_price", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("gas_price", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("gas_price", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_price", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_price", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_tip_cap + if req.GasTipCap != nil { + switch filter := req.GasTipCap.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("gas_tip_cap", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("gas_tip_cap", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("gas_tip_cap", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("gas_tip_cap", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("gas_tip_cap", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("gas_tip_cap", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("gas_tip_cap", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_tip_cap", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_tip_cap", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("gas_tip_cap") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("gas_tip_cap") + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_fee_cap + if req.GasFeeCap != nil { + switch filter := req.GasFeeCap.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("gas_fee_cap", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("gas_fee_cap", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("gas_fee_cap", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("gas_fee_cap", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("gas_fee_cap", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("gas_fee_cap", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("gas_fee_cap", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_fee_cap", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_fee_cap", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("gas_fee_cap") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("gas_fee_cap") + default: + // Unsupported filter type + } + } + + // Add filter for column: value + if req.Value != nil { + switch filter := req.Value.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("value", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("value", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("value", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("value", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("value", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("value", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("value", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("value", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("value", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: size + if req.Size != nil { + switch filter := req.Size.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("size", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("size", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("size", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("size", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("size", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("size", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("size", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("size", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("size", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: call_data_size + if req.CallDataSize != nil { + switch filter := req.CallDataSize.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("call_data_size", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("call_data_size", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("call_data_size", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("call_data_size", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("call_data_size", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("call_data_size", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("call_data_size", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("call_data_size", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("call_data_size", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_gas + if req.BlobGas != nil { + switch filter := req.BlobGas.Filter.(type) { + case *NullableUInt64Filter_Eq: + qb.AddCondition("blob_gas", "=", filter.Eq) + case *NullableUInt64Filter_Ne: + qb.AddCondition("blob_gas", "!=", filter.Ne) + case *NullableUInt64Filter_Lt: + qb.AddCondition("blob_gas", "<", filter.Lt) + case *NullableUInt64Filter_Lte: + qb.AddCondition("blob_gas", "<=", filter.Lte) + case *NullableUInt64Filter_Gt: + qb.AddCondition("blob_gas", ">", filter.Gt) + case *NullableUInt64Filter_Gte: + qb.AddCondition("blob_gas", ">=", filter.Gte) + case *NullableUInt64Filter_Between: + qb.AddBetweenCondition("blob_gas", filter.Between.Min, filter.Between.Max.GetValue()) + case *NullableUInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("blob_gas", UInt64SliceToInterface(filter.In.Values)) + } + case *NullableUInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("blob_gas", UInt64SliceToInterface(filter.NotIn.Values)) + } + case *NullableUInt64Filter_IsNull: + qb.AddIsNullCondition("blob_gas") + case *NullableUInt64Filter_IsNotNull: + qb.AddIsNotNullCondition("blob_gas") + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_gas_fee_cap + if req.BlobGasFeeCap != nil { + switch filter := req.BlobGasFeeCap.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("blob_gas_fee_cap", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("blob_gas_fee_cap", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("blob_gas_fee_cap", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("blob_gas_fee_cap", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("blob_gas_fee_cap", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("blob_gas_fee_cap", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("blob_gas_fee_cap", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("blob_gas_fee_cap", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("blob_gas_fee_cap", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("blob_gas_fee_cap") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("blob_gas_fee_cap") + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_hashes + if req.BlobHashes != nil { + switch filter := req.BlobHashes.Filter.(type) { + case *ArrayStringFilter_Has: + qb.AddArrayHasCondition("blob_hashes", filter.Has) + case *ArrayStringFilter_HasAll: + if len(filter.HasAll.Values) > 0 { + qb.AddArrayHasAllCondition("blob_hashes", StringSliceToInterface(filter.HasAll.Values)) + } + case *ArrayStringFilter_HasAny: + if len(filter.HasAny.Values) > 0 { + qb.AddArrayHasAnyCondition("blob_hashes", StringSliceToInterface(filter.HasAny.Values)) + } + case *ArrayStringFilter_LengthEq: + qb.AddArrayLengthCondition("blob_hashes", "=", filter.LengthEq) + case *ArrayStringFilter_LengthGt: + qb.AddArrayLengthCondition("blob_hashes", ">", filter.LengthGt) + case *ArrayStringFilter_LengthGte: + qb.AddArrayLengthCondition("blob_hashes", ">=", filter.LengthGte) + case *ArrayStringFilter_LengthLt: + qb.AddArrayLengthCondition("blob_hashes", "<", filter.LengthLt) + case *ArrayStringFilter_LengthLte: + qb.AddArrayLengthCondition("blob_hashes", "<=", filter.LengthLte) + case *ArrayStringFilter_IsEmpty: + qb.AddArrayIsEmptyCondition("blob_hashes") + case *ArrayStringFilter_IsNotEmpty: + qb.AddArrayIsNotEmptyCondition("blob_hashes") + default: + // Unsupported filter type + } + } + + // Add filter for column: is_cancel_shape + if req.IsCancelShape != nil { + switch filter := req.IsCancelShape.Filter.(type) { + case *BoolFilter_Eq: + qb.AddCondition("is_cancel_shape", "=", filter.Eq) + case *BoolFilter_Ne: + qb.AddCondition("is_cancel_shape", "!=", filter.Ne) + default: + // Unsupported filter type + } + } + + // Handle pagination per AIP-132 + // Validate page size + if req.PageSize < 0 { + return SQLQuery{}, fmt.Errorf("page_size must be non-negative, got %d", req.PageSize) + } + if req.PageSize > 10000 { + return SQLQuery{}, fmt.Errorf("page_size must not exceed %d, got %d", 10000, req.PageSize) + } + + var limit, offset uint32 + limit = 100 // Default page size + if req.PageSize > 0 { + limit = uint32(req.PageSize) + } + if req.PageToken != "" { + decodedOffset, err := DecodePageToken(req.PageToken) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid page_token: %w", err) + } + offset = decodedOffset + } + + // Handle custom ordering if provided + var orderByClause string + if req.OrderBy != "" { + validFields := []string{"updated_date_time", "slot", "slot_start_date_time", "epoch", "epoch_start_date_time", "block_root", "block_version", "block_number", "position", "hash", "from", "to", "nonce", "type", "gas", "gas_price", "gas_tip_cap", "gas_fee_cap", "value", "size", "call_data_size", "blob_gas", "blob_gas_fee_cap", "blob_hashes", "is_cancel_shape"} + orderFields, err := ParseOrderBy(req.OrderBy, validFields) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid order_by: %w", err) + } + orderByClause = BuildOrderByClause(orderFields) + } else { + // Default sorting by primary key + orderByClause = " ORDER BY slot_start_date_time" + ", block_root" + ", position" + } + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "slot", "toUnixTimestamp(`slot_start_date_time`) AS `slot_start_date_time`", "epoch", "toUnixTimestamp(`epoch_start_date_time`) AS `epoch_start_date_time`", "NULLIF(`block_root`, repeat('\x00', 66)) AS `block_root`", "block_version", "block_number", "position", "NULLIF(`hash`, repeat('\x00', 66)) AS `hash`", "NULLIF(`from`, repeat('\x00', 42)) AS `from`", "NULLIF(`to`, repeat('\x00', 42)) AS `to`", "nonce", "toUInt32(`type`) AS `type`", "gas", "toString(`gas_price`) AS `gas_price`", "toString(`gas_tip_cap`) AS `gas_tip_cap`", "toString(`gas_fee_cap`) AS `gas_fee_cap`", "toString(`value`) AS `value`", "size", "call_data_size", "blob_gas", "toString(`blob_gas_fee_cap`) AS `blob_gas_fee_cap`", "blob_hashes", "is_cancel_shape"} + + return BuildParameterizedQuery("fct_transaction_inclusion", columns, qb, orderByClause, limit, offset, options...) +} + +// BuildGetFctTransactionInclusionQuery constructs a parameterized SQL query from a GetFctTransactionInclusionRequest +func BuildGetFctTransactionInclusionQuery(req *GetFctTransactionInclusionRequest, options ...QueryOption) (SQLQuery, error) { + // Validate primary key is provided + if req.SlotStartDateTime == 0 { + return SQLQuery{}, fmt.Errorf("primary key field slot_start_date_time is required") + } + + // Build query with primary key condition + qb := NewQueryBuilder() + qb.AddCondition("slot_start_date_time", "=", req.SlotStartDateTime) + + // Build ORDER BY clause + orderByClause := " ORDER BY slot_start_date_time, block_root, position" + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "slot", "toUnixTimestamp(`slot_start_date_time`) AS `slot_start_date_time`", "epoch", "toUnixTimestamp(`epoch_start_date_time`) AS `epoch_start_date_time`", "NULLIF(`block_root`, repeat('\x00', 66)) AS `block_root`", "block_version", "block_number", "position", "NULLIF(`hash`, repeat('\x00', 66)) AS `hash`", "NULLIF(`from`, repeat('\x00', 42)) AS `from`", "NULLIF(`to`, repeat('\x00', 42)) AS `to`", "nonce", "toUInt32(`type`) AS `type`", "gas", "toString(`gas_price`) AS `gas_price`", "toString(`gas_tip_cap`) AS `gas_tip_cap`", "toString(`gas_fee_cap`) AS `gas_fee_cap`", "toString(`value`) AS `value`", "size", "call_data_size", "blob_gas", "toString(`blob_gas_fee_cap`) AS `blob_gas_fee_cap`", "blob_hashes", "is_cancel_shape"} + + // Return single record + return BuildParameterizedQuery("fct_transaction_inclusion", columns, qb, orderByClause, 1, 0, options...) +} diff --git a/pkg/proto/clickhouse/fct_transaction_inclusion.pb.go b/pkg/proto/clickhouse/fct_transaction_inclusion.pb.go new file mode 100644 index 00000000..2d702cb8 --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_inclusion.pb.go @@ -0,0 +1,1129 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc (unknown) +// source: fct_transaction_inclusion.proto + +package clickhouse + +import ( + _ "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse/clickhouse" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type FctTransactionInclusion struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Timestamp when the record was last updated + UpdatedDateTime uint32 `protobuf:"varint,11,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // The slot number of the beacon block containing the transaction + Slot uint32 `protobuf:"varint,12,opt,name=slot,proto3" json:"slot,omitempty"` + // The wall clock time when the slot started + SlotStartDateTime uint32 `protobuf:"varint,13,opt,name=slot_start_date_time,json=slotStartDateTime,proto3" json:"slot_start_date_time,omitempty"` + // The epoch number containing the slot + Epoch uint32 `protobuf:"varint,14,opt,name=epoch,proto3" json:"epoch,omitempty"` + // The wall clock time when the epoch started + EpochStartDateTime uint32 `protobuf:"varint,15,opt,name=epoch_start_date_time,json=epochStartDateTime,proto3" json:"epoch_start_date_time,omitempty"` + // The beacon block root hash + BlockRoot string `protobuf:"bytes,16,opt,name=block_root,json=blockRoot,proto3" json:"block_root,omitempty"` + // The beacon block version + BlockVersion string `protobuf:"bytes,17,opt,name=block_version,json=blockVersion,proto3" json:"block_version,omitempty"` + // The execution block number, null when the block is not yet present in fct_block + BlockNumber *wrapperspb.UInt64Value `protobuf:"bytes,18,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"` + // The position of the transaction in the execution payload + Position uint32 `protobuf:"varint,19,opt,name=position,proto3" json:"position,omitempty"` + // The transaction hash + Hash string `protobuf:"bytes,20,opt,name=hash,proto3" json:"hash,omitempty"` + // The address of the account that sent the transaction + From string `protobuf:"bytes,21,opt,name=from,proto3" json:"from,omitempty"` + // The address of the transaction recipient, null for contract creation + To *wrapperspb.StringValue `protobuf:"bytes,22,opt,name=to,proto3" json:"to,omitempty"` + // The nonce of the sender account at the time of the transaction + Nonce uint64 `protobuf:"varint,23,opt,name=nonce,proto3" json:"nonce,omitempty"` + // The type of the transaction + Type uint32 `protobuf:"varint,24,opt,name=type,proto3" json:"type,omitempty"` + // The maximum gas provided for the transaction execution + Gas uint64 `protobuf:"varint,25,opt,name=gas,proto3" json:"gas,omitempty"` + // The gas price of the transaction in wei + GasPrice string `protobuf:"bytes,26,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` + // The priority fee (tip) the user has set for the transaction in wei + GasTipCap *wrapperspb.StringValue `protobuf:"bytes,27,opt,name=gas_tip_cap,json=gasTipCap,proto3" json:"gas_tip_cap,omitempty"` + // The max fee the user has set for the transaction in wei + GasFeeCap *wrapperspb.StringValue `protobuf:"bytes,28,opt,name=gas_fee_cap,json=gasFeeCap,proto3" json:"gas_fee_cap,omitempty"` + // The value transferred with the transaction in wei + Value string `protobuf:"bytes,29,opt,name=value,proto3" json:"value,omitempty"` + // The size of the transaction data in bytes + Size uint32 `protobuf:"varint,30,opt,name=size,proto3" json:"size,omitempty"` + // The size of the call data of the transaction in bytes + CallDataSize uint32 `protobuf:"varint,31,opt,name=call_data_size,json=callDataSize,proto3" json:"call_data_size,omitempty"` + // The maximum gas provided for the blob transaction execution + BlobGas *wrapperspb.UInt64Value `protobuf:"bytes,32,opt,name=blob_gas,json=blobGas,proto3" json:"blob_gas,omitempty"` + // The max blob fee the user has set for the transaction in wei + BlobGasFeeCap *wrapperspb.StringValue `protobuf:"bytes,33,opt,name=blob_gas_fee_cap,json=blobGasFeeCap,proto3" json:"blob_gas_fee_cap,omitempty"` + // The hashes of the blob commitments for blob transactions + BlobHashes []string `protobuf:"bytes,34,rep,name=blob_hashes,json=blobHashes,proto3" json:"blob_hashes,omitempty"` + // Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern + IsCancelShape bool `protobuf:"varint,35,opt,name=is_cancel_shape,json=isCancelShape,proto3" json:"is_cancel_shape,omitempty"` +} + +func (x *FctTransactionInclusion) Reset() { + *x = FctTransactionInclusion{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FctTransactionInclusion) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FctTransactionInclusion) ProtoMessage() {} + +func (x *FctTransactionInclusion) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FctTransactionInclusion.ProtoReflect.Descriptor instead. +func (*FctTransactionInclusion) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_proto_rawDescGZIP(), []int{0} +} + +func (x *FctTransactionInclusion) GetUpdatedDateTime() uint32 { + if x != nil { + return x.UpdatedDateTime + } + return 0 +} + +func (x *FctTransactionInclusion) GetSlot() uint32 { + if x != nil { + return x.Slot + } + return 0 +} + +func (x *FctTransactionInclusion) GetSlotStartDateTime() uint32 { + if x != nil { + return x.SlotStartDateTime + } + return 0 +} + +func (x *FctTransactionInclusion) GetEpoch() uint32 { + if x != nil { + return x.Epoch + } + return 0 +} + +func (x *FctTransactionInclusion) GetEpochStartDateTime() uint32 { + if x != nil { + return x.EpochStartDateTime + } + return 0 +} + +func (x *FctTransactionInclusion) GetBlockRoot() string { + if x != nil { + return x.BlockRoot + } + return "" +} + +func (x *FctTransactionInclusion) GetBlockVersion() string { + if x != nil { + return x.BlockVersion + } + return "" +} + +func (x *FctTransactionInclusion) GetBlockNumber() *wrapperspb.UInt64Value { + if x != nil { + return x.BlockNumber + } + return nil +} + +func (x *FctTransactionInclusion) GetPosition() uint32 { + if x != nil { + return x.Position + } + return 0 +} + +func (x *FctTransactionInclusion) GetHash() string { + if x != nil { + return x.Hash + } + return "" +} + +func (x *FctTransactionInclusion) GetFrom() string { + if x != nil { + return x.From + } + return "" +} + +func (x *FctTransactionInclusion) GetTo() *wrapperspb.StringValue { + if x != nil { + return x.To + } + return nil +} + +func (x *FctTransactionInclusion) GetNonce() uint64 { + if x != nil { + return x.Nonce + } + return 0 +} + +func (x *FctTransactionInclusion) GetType() uint32 { + if x != nil { + return x.Type + } + return 0 +} + +func (x *FctTransactionInclusion) GetGas() uint64 { + if x != nil { + return x.Gas + } + return 0 +} + +func (x *FctTransactionInclusion) GetGasPrice() string { + if x != nil { + return x.GasPrice + } + return "" +} + +func (x *FctTransactionInclusion) GetGasTipCap() *wrapperspb.StringValue { + if x != nil { + return x.GasTipCap + } + return nil +} + +func (x *FctTransactionInclusion) GetGasFeeCap() *wrapperspb.StringValue { + if x != nil { + return x.GasFeeCap + } + return nil +} + +func (x *FctTransactionInclusion) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *FctTransactionInclusion) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *FctTransactionInclusion) GetCallDataSize() uint32 { + if x != nil { + return x.CallDataSize + } + return 0 +} + +func (x *FctTransactionInclusion) GetBlobGas() *wrapperspb.UInt64Value { + if x != nil { + return x.BlobGas + } + return nil +} + +func (x *FctTransactionInclusion) GetBlobGasFeeCap() *wrapperspb.StringValue { + if x != nil { + return x.BlobGasFeeCap + } + return nil +} + +func (x *FctTransactionInclusion) GetBlobHashes() []string { + if x != nil { + return x.BlobHashes + } + return nil +} + +func (x *FctTransactionInclusion) GetIsCancelShape() bool { + if x != nil { + return x.IsCancelShape + } + return false +} + +// Request for listing fct_transaction_inclusion records +type ListFctTransactionInclusionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Filter by slot_start_date_time - The wall clock time when the slot started (PRIMARY KEY - required unless using alternatives: hash, from) + SlotStartDateTime *UInt32Filter `protobuf:"bytes,1,opt,name=slot_start_date_time,json=slotStartDateTime,proto3" json:"slot_start_date_time,omitempty"` + // Filter by block_root - The beacon block root hash (ORDER BY column 2 - optional) + BlockRoot *StringFilter `protobuf:"bytes,2,opt,name=block_root,json=blockRoot,proto3" json:"block_root,omitempty"` + // Filter by position - The position of the transaction in the execution payload (ORDER BY column 3 - optional) + Position *UInt32Filter `protobuf:"bytes,3,opt,name=position,proto3" json:"position,omitempty"` + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UpdatedDateTime *UInt32Filter `protobuf:"bytes,4,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Filter by slot - The slot number of the beacon block containing the transaction (optional) + Slot *UInt32Filter `protobuf:"bytes,5,opt,name=slot,proto3" json:"slot,omitempty"` + // Filter by epoch - The epoch number containing the slot (optional) + Epoch *UInt32Filter `protobuf:"bytes,6,opt,name=epoch,proto3" json:"epoch,omitempty"` + // Filter by epoch_start_date_time - The wall clock time when the epoch started (optional) + EpochStartDateTime *UInt32Filter `protobuf:"bytes,7,opt,name=epoch_start_date_time,json=epochStartDateTime,proto3" json:"epoch_start_date_time,omitempty"` + // Filter by block_version - The beacon block version (optional) + BlockVersion *StringFilter `protobuf:"bytes,8,opt,name=block_version,json=blockVersion,proto3" json:"block_version,omitempty"` + // Filter by block_number - The execution block number, null when the block is not yet present in fct_block (optional) + BlockNumber *NullableUInt64Filter `protobuf:"bytes,9,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"` + // Filter by hash - The transaction hash (PROJECTION: p_by_hash - alternative to slot_start_date_time) + Hash *StringFilter `protobuf:"bytes,10,opt,name=hash,proto3" json:"hash,omitempty"` + // Filter by from - The address of the account that sent the transaction (PROJECTION: p_by_nonce_group - alternative to slot_start_date_time) + From *StringFilter `protobuf:"bytes,11,opt,name=from,proto3" json:"from,omitempty"` + // Filter by to - The address of the transaction recipient, null for contract creation (optional) + To *NullableStringFilter `protobuf:"bytes,12,opt,name=to,proto3" json:"to,omitempty"` + // Filter by nonce - The nonce of the sender account at the time of the transaction (optional) + Nonce *UInt64Filter `protobuf:"bytes,13,opt,name=nonce,proto3" json:"nonce,omitempty"` + // Filter by type - The type of the transaction (optional) + Type *UInt32Filter `protobuf:"bytes,14,opt,name=type,proto3" json:"type,omitempty"` + // Filter by gas - The maximum gas provided for the transaction execution (optional) + Gas *UInt64Filter `protobuf:"bytes,15,opt,name=gas,proto3" json:"gas,omitempty"` + // Filter by gas_price - The gas price of the transaction in wei (optional) + GasPrice *StringFilter `protobuf:"bytes,16,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` + // Filter by gas_tip_cap - The priority fee (tip) the user has set for the transaction in wei (optional) + GasTipCap *NullableStringFilter `protobuf:"bytes,17,opt,name=gas_tip_cap,json=gasTipCap,proto3" json:"gas_tip_cap,omitempty"` + // Filter by gas_fee_cap - The max fee the user has set for the transaction in wei (optional) + GasFeeCap *NullableStringFilter `protobuf:"bytes,18,opt,name=gas_fee_cap,json=gasFeeCap,proto3" json:"gas_fee_cap,omitempty"` + // Filter by value - The value transferred with the transaction in wei (optional) + Value *StringFilter `protobuf:"bytes,19,opt,name=value,proto3" json:"value,omitempty"` + // Filter by size - The size of the transaction data in bytes (optional) + Size *UInt32Filter `protobuf:"bytes,20,opt,name=size,proto3" json:"size,omitempty"` + // Filter by call_data_size - The size of the call data of the transaction in bytes (optional) + CallDataSize *UInt32Filter `protobuf:"bytes,21,opt,name=call_data_size,json=callDataSize,proto3" json:"call_data_size,omitempty"` + // Filter by blob_gas - The maximum gas provided for the blob transaction execution (optional) + BlobGas *NullableUInt64Filter `protobuf:"bytes,22,opt,name=blob_gas,json=blobGas,proto3" json:"blob_gas,omitempty"` + // Filter by blob_gas_fee_cap - The max blob fee the user has set for the transaction in wei (optional) + BlobGasFeeCap *NullableStringFilter `protobuf:"bytes,23,opt,name=blob_gas_fee_cap,json=blobGasFeeCap,proto3" json:"blob_gas_fee_cap,omitempty"` + // Filter by blob_hashes - The hashes of the blob commitments for blob transactions (optional) + BlobHashes *ArrayStringFilter `protobuf:"bytes,24,opt,name=blob_hashes,json=blobHashes,proto3" json:"blob_hashes,omitempty"` + // Filter by is_cancel_shape - Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern (optional) + IsCancelShape *BoolFilter `protobuf:"bytes,25,opt,name=is_cancel_shape,json=isCancelShape,proto3" json:"is_cancel_shape,omitempty"` + // The maximum number of fct_transaction_inclusion to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + PageSize int32 `protobuf:"varint,26,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // A page token, received from a previous `ListFctTransactionInclusion` call. + // Provide this to retrieve the subsequent page. + PageToken string `protobuf:"bytes,27,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + OrderBy string `protobuf:"bytes,28,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"` +} + +func (x *ListFctTransactionInclusionRequest) Reset() { + *x = ListFctTransactionInclusionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionInclusionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionInclusionRequest) ProtoMessage() {} + +func (x *ListFctTransactionInclusionRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionInclusionRequest.ProtoReflect.Descriptor instead. +func (*ListFctTransactionInclusionRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_proto_rawDescGZIP(), []int{1} +} + +func (x *ListFctTransactionInclusionRequest) GetSlotStartDateTime() *UInt32Filter { + if x != nil { + return x.SlotStartDateTime + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetBlockRoot() *StringFilter { + if x != nil { + return x.BlockRoot + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetPosition() *UInt32Filter { + if x != nil { + return x.Position + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetUpdatedDateTime() *UInt32Filter { + if x != nil { + return x.UpdatedDateTime + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetSlot() *UInt32Filter { + if x != nil { + return x.Slot + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetEpoch() *UInt32Filter { + if x != nil { + return x.Epoch + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetEpochStartDateTime() *UInt32Filter { + if x != nil { + return x.EpochStartDateTime + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetBlockVersion() *StringFilter { + if x != nil { + return x.BlockVersion + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetBlockNumber() *NullableUInt64Filter { + if x != nil { + return x.BlockNumber + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetHash() *StringFilter { + if x != nil { + return x.Hash + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetFrom() *StringFilter { + if x != nil { + return x.From + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetTo() *NullableStringFilter { + if x != nil { + return x.To + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetNonce() *UInt64Filter { + if x != nil { + return x.Nonce + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetType() *UInt32Filter { + if x != nil { + return x.Type + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetGas() *UInt64Filter { + if x != nil { + return x.Gas + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetGasPrice() *StringFilter { + if x != nil { + return x.GasPrice + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetGasTipCap() *NullableStringFilter { + if x != nil { + return x.GasTipCap + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetGasFeeCap() *NullableStringFilter { + if x != nil { + return x.GasFeeCap + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetValue() *StringFilter { + if x != nil { + return x.Value + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetSize() *UInt32Filter { + if x != nil { + return x.Size + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetCallDataSize() *UInt32Filter { + if x != nil { + return x.CallDataSize + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetBlobGas() *NullableUInt64Filter { + if x != nil { + return x.BlobGas + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetBlobGasFeeCap() *NullableStringFilter { + if x != nil { + return x.BlobGasFeeCap + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetBlobHashes() *ArrayStringFilter { + if x != nil { + return x.BlobHashes + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetIsCancelShape() *BoolFilter { + if x != nil { + return x.IsCancelShape + } + return nil +} + +func (x *ListFctTransactionInclusionRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListFctTransactionInclusionRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +func (x *ListFctTransactionInclusionRequest) GetOrderBy() string { + if x != nil { + return x.OrderBy + } + return "" +} + +// Response for listing fct_transaction_inclusion records +type ListFctTransactionInclusionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of fct_transaction_inclusion. + FctTransactionInclusion []*FctTransactionInclusion `protobuf:"bytes,1,rep,name=fct_transaction_inclusion,json=fctTransactionInclusion,proto3" json:"fct_transaction_inclusion,omitempty"` + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` +} + +func (x *ListFctTransactionInclusionResponse) Reset() { + *x = ListFctTransactionInclusionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionInclusionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionInclusionResponse) ProtoMessage() {} + +func (x *ListFctTransactionInclusionResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionInclusionResponse.ProtoReflect.Descriptor instead. +func (*ListFctTransactionInclusionResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_proto_rawDescGZIP(), []int{2} +} + +func (x *ListFctTransactionInclusionResponse) GetFctTransactionInclusion() []*FctTransactionInclusion { + if x != nil { + return x.FctTransactionInclusion + } + return nil +} + +func (x *ListFctTransactionInclusionResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +// Request for getting a single fct_transaction_inclusion record by primary key +type GetFctTransactionInclusionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The wall clock time when the slot started + SlotStartDateTime uint32 `protobuf:"varint,1,opt,name=slot_start_date_time,json=slotStartDateTime,proto3" json:"slot_start_date_time,omitempty"` // Primary key (required) +} + +func (x *GetFctTransactionInclusionRequest) Reset() { + *x = GetFctTransactionInclusionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionInclusionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionInclusionRequest) ProtoMessage() {} + +func (x *GetFctTransactionInclusionRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionInclusionRequest.ProtoReflect.Descriptor instead. +func (*GetFctTransactionInclusionRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_proto_rawDescGZIP(), []int{3} +} + +func (x *GetFctTransactionInclusionRequest) GetSlotStartDateTime() uint32 { + if x != nil { + return x.SlotStartDateTime + } + return 0 +} + +// Response for getting a single fct_transaction_inclusion record +type GetFctTransactionInclusionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *FctTransactionInclusion `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *GetFctTransactionInclusionResponse) Reset() { + *x = GetFctTransactionInclusionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionInclusionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionInclusionResponse) ProtoMessage() {} + +func (x *GetFctTransactionInclusionResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionInclusionResponse.ProtoReflect.Descriptor instead. +func (*GetFctTransactionInclusionResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_proto_rawDescGZIP(), []int{4} +} + +func (x *GetFctTransactionInclusionResponse) GetItem() *FctTransactionInclusion { + if x != nil { + return x.Item + } + return nil +} + +var File_fct_transaction_inclusion_proto protoreflect.FileDescriptor + +var file_fct_transaction_inclusion_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x03, 0x63, 0x62, 0x74, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x2f, + 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0xb8, 0x07, 0x0a, 0x17, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, + 0x11, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6c, 0x6f, + 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x2f, 0x0a, + 0x14, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x73, 0x6c, 0x6f, + 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x65, + 0x70, 0x6f, 0x63, 0x68, 0x12, 0x31, 0x0a, 0x15, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x5f, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0f, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x12, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, + 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x0c, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, + 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, + 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, + 0x12, 0x2c, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x14, + 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, + 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x18, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, + 0x19, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, + 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, + 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x74, + 0x69, 0x70, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x67, 0x61, 0x73, 0x54, + 0x69, 0x70, 0x43, 0x61, 0x70, 0x12, 0x3c, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, + 0x5f, 0x63, 0x61, 0x70, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x67, 0x61, 0x73, 0x46, 0x65, 0x65, + 0x43, 0x61, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x1d, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x24, 0x0a, + 0x0e, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x1f, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x63, 0x61, 0x6c, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x53, + 0x69, 0x7a, 0x65, 0x12, 0x37, 0x0a, 0x08, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x18, + 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x12, 0x45, 0x0a, 0x10, + 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x63, 0x61, 0x70, + 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x46, 0x65, 0x65, + 0x43, 0x61, 0x70, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x65, 0x73, 0x18, 0x22, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x62, 0x48, 0x61, + 0x73, 0x68, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x73, 0x5f, 0x63, 0x61, 0x6e, 0x63, 0x65, + 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x18, 0x23, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, + 0x73, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x70, 0x65, 0x22, 0xfe, 0x0c, 0x0a, + 0x22, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x14, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x42, 0x12, 0xe0, 0x41, 0x01, 0x9a, 0xb5, 0x18, 0x0b, 0x70, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x52, 0x11, 0x73, 0x6c, 0x6f, 0x74, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0a, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, + 0x6f, 0x74, 0x12, 0x32, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, + 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x11, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x73, 0x6c, + 0x6f, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, + 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, + 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x2c, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x05, 0x65, + 0x70, 0x6f, 0x63, 0x68, 0x12, 0x49, 0x0a, 0x15, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x5f, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x12, 0x65, 0x70, 0x6f, + 0x63, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x3b, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0c, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0c, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, + 0x41, 0x01, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, + 0x5e, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x42, 0x37, 0xe0, 0x41, 0x01, 0x8a, 0xb5, 0x18, 0x14, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x92, 0xb5, 0x18, + 0x09, 0x70, 0x5f, 0x62, 0x79, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x9a, 0xb5, 0x18, 0x0b, 0x70, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, + 0x65, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x42, 0x3e, 0xe0, 0x41, 0x01, 0x8a, 0xb5, 0x18, 0x14, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x92, 0xb5, 0x18, + 0x10, 0x70, 0x5f, 0x62, 0x79, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x9a, 0xb5, 0x18, 0x0b, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, + 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x2e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, + 0x41, 0x01, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x2c, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, + 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x05, 0x6e, + 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x28, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x33, 0x0a, 0x09, 0x67, 0x61, + 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, + 0x3e, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x70, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, + 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x67, 0x61, 0x73, 0x54, 0x69, 0x70, 0x43, 0x61, 0x70, 0x12, + 0x3e, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x12, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, + 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x67, 0x61, 0x73, 0x46, 0x65, 0x65, 0x43, 0x61, 0x70, 0x12, + 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, + 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x63, 0x61, 0x6c, + 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0c, 0x63, 0x61, 0x6c, 0x6c, 0x44, + 0x61, 0x74, 0x61, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x62, 0x6c, 0x6f, 0x62, 0x5f, + 0x67, 0x61, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, + 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x62, 0x47, + 0x61, 0x73, 0x12, 0x47, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x66, + 0x65, 0x65, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, + 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x62, 0x6c, + 0x6f, 0x62, 0x47, 0x61, 0x73, 0x46, 0x65, 0x65, 0x43, 0x61, 0x70, 0x12, 0x3c, 0x0a, 0x0b, 0x62, + 0x6c, 0x6f, 0x62, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x41, 0x72, 0x72, 0x61, 0x79, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x62, + 0x6c, 0x6f, 0x62, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x0f, 0x69, 0x73, 0x5f, + 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x18, 0x19, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x69, 0x73, 0x43, 0x61, 0x6e, 0x63, + 0x65, 0x6c, 0x53, 0x68, 0x61, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0a, 0x70, 0x61, 0x67, + 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, + 0x41, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1e, 0x0a, + 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, 0xa7, 0x01, + 0x0a, 0x23, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x19, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x46, + 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, + 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x17, 0x66, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, + 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x54, 0x0a, 0x21, 0x47, 0x65, 0x74, 0x46, 0x63, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, + 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x14, + 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x73, 0x6c, 0x6f, 0x74, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x56, 0x0a, + 0x22, 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0xc2, 0x02, 0x0a, 0x1e, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, + 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x84, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x27, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, 0x12, 0x21, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x98, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x26, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x47, 0x65, + 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x27, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x40, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3a, + 0x12, 0x38, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, + 0x69, 0x6f, 0x6e, 0x2f, 0x7b, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, + 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x7d, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x70, 0x61, 0x6e, 0x64, + 0x61, 0x6f, 0x70, 0x73, 0x2f, 0x78, 0x61, 0x74, 0x75, 0x2d, 0x63, 0x62, 0x74, 0x2f, 0x70, 0x6b, + 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x68, 0x6f, 0x75, + 0x73, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_fct_transaction_inclusion_proto_rawDescOnce sync.Once + file_fct_transaction_inclusion_proto_rawDescData = file_fct_transaction_inclusion_proto_rawDesc +) + +func file_fct_transaction_inclusion_proto_rawDescGZIP() []byte { + file_fct_transaction_inclusion_proto_rawDescOnce.Do(func() { + file_fct_transaction_inclusion_proto_rawDescData = protoimpl.X.CompressGZIP(file_fct_transaction_inclusion_proto_rawDescData) + }) + return file_fct_transaction_inclusion_proto_rawDescData +} + +var file_fct_transaction_inclusion_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_fct_transaction_inclusion_proto_goTypes = []any{ + (*FctTransactionInclusion)(nil), // 0: cbt.FctTransactionInclusion + (*ListFctTransactionInclusionRequest)(nil), // 1: cbt.ListFctTransactionInclusionRequest + (*ListFctTransactionInclusionResponse)(nil), // 2: cbt.ListFctTransactionInclusionResponse + (*GetFctTransactionInclusionRequest)(nil), // 3: cbt.GetFctTransactionInclusionRequest + (*GetFctTransactionInclusionResponse)(nil), // 4: cbt.GetFctTransactionInclusionResponse + (*wrapperspb.UInt64Value)(nil), // 5: google.protobuf.UInt64Value + (*wrapperspb.StringValue)(nil), // 6: google.protobuf.StringValue + (*UInt32Filter)(nil), // 7: cbt.UInt32Filter + (*StringFilter)(nil), // 8: cbt.StringFilter + (*NullableUInt64Filter)(nil), // 9: cbt.NullableUInt64Filter + (*NullableStringFilter)(nil), // 10: cbt.NullableStringFilter + (*UInt64Filter)(nil), // 11: cbt.UInt64Filter + (*ArrayStringFilter)(nil), // 12: cbt.ArrayStringFilter + (*BoolFilter)(nil), // 13: cbt.BoolFilter +} +var file_fct_transaction_inclusion_proto_depIdxs = []int32{ + 5, // 0: cbt.FctTransactionInclusion.block_number:type_name -> google.protobuf.UInt64Value + 6, // 1: cbt.FctTransactionInclusion.to:type_name -> google.protobuf.StringValue + 6, // 2: cbt.FctTransactionInclusion.gas_tip_cap:type_name -> google.protobuf.StringValue + 6, // 3: cbt.FctTransactionInclusion.gas_fee_cap:type_name -> google.protobuf.StringValue + 5, // 4: cbt.FctTransactionInclusion.blob_gas:type_name -> google.protobuf.UInt64Value + 6, // 5: cbt.FctTransactionInclusion.blob_gas_fee_cap:type_name -> google.protobuf.StringValue + 7, // 6: cbt.ListFctTransactionInclusionRequest.slot_start_date_time:type_name -> cbt.UInt32Filter + 8, // 7: cbt.ListFctTransactionInclusionRequest.block_root:type_name -> cbt.StringFilter + 7, // 8: cbt.ListFctTransactionInclusionRequest.position:type_name -> cbt.UInt32Filter + 7, // 9: cbt.ListFctTransactionInclusionRequest.updated_date_time:type_name -> cbt.UInt32Filter + 7, // 10: cbt.ListFctTransactionInclusionRequest.slot:type_name -> cbt.UInt32Filter + 7, // 11: cbt.ListFctTransactionInclusionRequest.epoch:type_name -> cbt.UInt32Filter + 7, // 12: cbt.ListFctTransactionInclusionRequest.epoch_start_date_time:type_name -> cbt.UInt32Filter + 8, // 13: cbt.ListFctTransactionInclusionRequest.block_version:type_name -> cbt.StringFilter + 9, // 14: cbt.ListFctTransactionInclusionRequest.block_number:type_name -> cbt.NullableUInt64Filter + 8, // 15: cbt.ListFctTransactionInclusionRequest.hash:type_name -> cbt.StringFilter + 8, // 16: cbt.ListFctTransactionInclusionRequest.from:type_name -> cbt.StringFilter + 10, // 17: cbt.ListFctTransactionInclusionRequest.to:type_name -> cbt.NullableStringFilter + 11, // 18: cbt.ListFctTransactionInclusionRequest.nonce:type_name -> cbt.UInt64Filter + 7, // 19: cbt.ListFctTransactionInclusionRequest.type:type_name -> cbt.UInt32Filter + 11, // 20: cbt.ListFctTransactionInclusionRequest.gas:type_name -> cbt.UInt64Filter + 8, // 21: cbt.ListFctTransactionInclusionRequest.gas_price:type_name -> cbt.StringFilter + 10, // 22: cbt.ListFctTransactionInclusionRequest.gas_tip_cap:type_name -> cbt.NullableStringFilter + 10, // 23: cbt.ListFctTransactionInclusionRequest.gas_fee_cap:type_name -> cbt.NullableStringFilter + 8, // 24: cbt.ListFctTransactionInclusionRequest.value:type_name -> cbt.StringFilter + 7, // 25: cbt.ListFctTransactionInclusionRequest.size:type_name -> cbt.UInt32Filter + 7, // 26: cbt.ListFctTransactionInclusionRequest.call_data_size:type_name -> cbt.UInt32Filter + 9, // 27: cbt.ListFctTransactionInclusionRequest.blob_gas:type_name -> cbt.NullableUInt64Filter + 10, // 28: cbt.ListFctTransactionInclusionRequest.blob_gas_fee_cap:type_name -> cbt.NullableStringFilter + 12, // 29: cbt.ListFctTransactionInclusionRequest.blob_hashes:type_name -> cbt.ArrayStringFilter + 13, // 30: cbt.ListFctTransactionInclusionRequest.is_cancel_shape:type_name -> cbt.BoolFilter + 0, // 31: cbt.ListFctTransactionInclusionResponse.fct_transaction_inclusion:type_name -> cbt.FctTransactionInclusion + 0, // 32: cbt.GetFctTransactionInclusionResponse.item:type_name -> cbt.FctTransactionInclusion + 1, // 33: cbt.FctTransactionInclusionService.List:input_type -> cbt.ListFctTransactionInclusionRequest + 3, // 34: cbt.FctTransactionInclusionService.Get:input_type -> cbt.GetFctTransactionInclusionRequest + 2, // 35: cbt.FctTransactionInclusionService.List:output_type -> cbt.ListFctTransactionInclusionResponse + 4, // 36: cbt.FctTransactionInclusionService.Get:output_type -> cbt.GetFctTransactionInclusionResponse + 35, // [35:37] is the sub-list for method output_type + 33, // [33:35] is the sub-list for method input_type + 33, // [33:33] is the sub-list for extension type_name + 33, // [33:33] is the sub-list for extension extendee + 0, // [0:33] is the sub-list for field type_name +} + +func init() { file_fct_transaction_inclusion_proto_init() } +func file_fct_transaction_inclusion_proto_init() { + if File_fct_transaction_inclusion_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_fct_transaction_inclusion_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*FctTransactionInclusion); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_inclusion_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionInclusionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_inclusion_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionInclusionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_inclusion_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionInclusionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_inclusion_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionInclusionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_fct_transaction_inclusion_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_fct_transaction_inclusion_proto_goTypes, + DependencyIndexes: file_fct_transaction_inclusion_proto_depIdxs, + MessageInfos: file_fct_transaction_inclusion_proto_msgTypes, + }.Build() + File_fct_transaction_inclusion_proto = out.File + file_fct_transaction_inclusion_proto_rawDesc = nil + file_fct_transaction_inclusion_proto_goTypes = nil + file_fct_transaction_inclusion_proto_depIdxs = nil +} diff --git a/pkg/proto/clickhouse/fct_transaction_inclusion.proto b/pkg/proto/clickhouse/fct_transaction_inclusion.proto new file mode 100644 index 00000000..f0dcfab3 --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_inclusion.proto @@ -0,0 +1,170 @@ +syntax = "proto3"; + +package cbt; + +import "common.proto"; +import "google/protobuf/wrappers.proto"; +import "google/api/annotations.proto"; +import "google/api/field_behavior.proto"; +import "clickhouse/annotations.proto"; + +option go_package = "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse"; +// One row per transaction included in a canonical beacon block execution payload. Carries no mempool or relay context so it can cover the full post-Merge history + +message FctTransactionInclusion { + // Timestamp when the record was last updated + uint32 updated_date_time = 11; + // The slot number of the beacon block containing the transaction + uint32 slot = 12; + // The wall clock time when the slot started + uint32 slot_start_date_time = 13; + // The epoch number containing the slot + uint32 epoch = 14; + // The wall clock time when the epoch started + uint32 epoch_start_date_time = 15; + // The beacon block root hash + string block_root = 16; + // The beacon block version + string block_version = 17; + // The execution block number, null when the block is not yet present in fct_block + google.protobuf.UInt64Value block_number = 18; + // The position of the transaction in the execution payload + uint32 position = 19; + // The transaction hash + string hash = 20; + // The address of the account that sent the transaction + string from = 21; + // The address of the transaction recipient, null for contract creation + google.protobuf.StringValue to = 22; + // The nonce of the sender account at the time of the transaction + uint64 nonce = 23; + // The type of the transaction + uint32 type = 24; + // The maximum gas provided for the transaction execution + uint64 gas = 25; + // The gas price of the transaction in wei + string gas_price = 26; + // The priority fee (tip) the user has set for the transaction in wei + google.protobuf.StringValue gas_tip_cap = 27; + // The max fee the user has set for the transaction in wei + google.protobuf.StringValue gas_fee_cap = 28; + // The value transferred with the transaction in wei + string value = 29; + // The size of the transaction data in bytes + uint32 size = 30; + // The size of the call data of the transaction in bytes + uint32 call_data_size = 31; + // The maximum gas provided for the blob transaction execution + google.protobuf.UInt64Value blob_gas = 32; + // The max blob fee the user has set for the transaction in wei + google.protobuf.StringValue blob_gas_fee_cap = 33; + // The hashes of the blob commitments for blob transactions + repeated string blob_hashes = 34; + // Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern + bool is_cancel_shape = 35; +} + +// Request for listing fct_transaction_inclusion records +message ListFctTransactionInclusionRequest { + // Filter by slot_start_date_time - The wall clock time when the slot started (PRIMARY KEY - required unless using alternatives: hash, from) + UInt32Filter slot_start_date_time = 1 [(google.api.field_behavior) = OPTIONAL, (clickhouse.v1.required_group) = "primary_key"]; + + // Filter by block_root - The beacon block root hash (ORDER BY column 2 - optional) + StringFilter block_root = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Filter by position - The position of the transaction in the execution payload (ORDER BY column 3 - optional) + UInt32Filter position = 3 [(google.api.field_behavior) = OPTIONAL]; + + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UInt32Filter updated_date_time = 4 [(google.api.field_behavior) = OPTIONAL]; + // Filter by slot - The slot number of the beacon block containing the transaction (optional) + UInt32Filter slot = 5 [(google.api.field_behavior) = OPTIONAL]; + // Filter by epoch - The epoch number containing the slot (optional) + UInt32Filter epoch = 6 [(google.api.field_behavior) = OPTIONAL]; + // Filter by epoch_start_date_time - The wall clock time when the epoch started (optional) + UInt32Filter epoch_start_date_time = 7 [(google.api.field_behavior) = OPTIONAL]; + // Filter by block_version - The beacon block version (optional) + StringFilter block_version = 8 [(google.api.field_behavior) = OPTIONAL]; + // Filter by block_number - The execution block number, null when the block is not yet present in fct_block (optional) + NullableUInt64Filter block_number = 9 [(google.api.field_behavior) = OPTIONAL]; + // Filter by hash - The transaction hash (PROJECTION: p_by_hash - alternative to slot_start_date_time) + StringFilter hash = 10 [(google.api.field_behavior) = OPTIONAL, (clickhouse.v1.projection_name) = "p_by_hash", (clickhouse.v1.projection_alternative_for) = "slot_start_date_time", (clickhouse.v1.required_group) = "primary_key"]; + // Filter by from - The address of the account that sent the transaction (PROJECTION: p_by_nonce_group - alternative to slot_start_date_time) + StringFilter from = 11 [(google.api.field_behavior) = OPTIONAL, (clickhouse.v1.projection_name) = "p_by_nonce_group", (clickhouse.v1.projection_alternative_for) = "slot_start_date_time", (clickhouse.v1.required_group) = "primary_key"]; + // Filter by to - The address of the transaction recipient, null for contract creation (optional) + NullableStringFilter to = 12 [(google.api.field_behavior) = OPTIONAL]; + // Filter by nonce - The nonce of the sender account at the time of the transaction (optional) + UInt64Filter nonce = 13 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type - The type of the transaction (optional) + UInt32Filter type = 14 [(google.api.field_behavior) = OPTIONAL]; + // Filter by gas - The maximum gas provided for the transaction execution (optional) + UInt64Filter gas = 15 [(google.api.field_behavior) = OPTIONAL]; + // Filter by gas_price - The gas price of the transaction in wei (optional) + StringFilter gas_price = 16 [(google.api.field_behavior) = OPTIONAL]; + // Filter by gas_tip_cap - The priority fee (tip) the user has set for the transaction in wei (optional) + NullableStringFilter gas_tip_cap = 17 [(google.api.field_behavior) = OPTIONAL]; + // Filter by gas_fee_cap - The max fee the user has set for the transaction in wei (optional) + NullableStringFilter gas_fee_cap = 18 [(google.api.field_behavior) = OPTIONAL]; + // Filter by value - The value transferred with the transaction in wei (optional) + StringFilter value = 19 [(google.api.field_behavior) = OPTIONAL]; + // Filter by size - The size of the transaction data in bytes (optional) + UInt32Filter size = 20 [(google.api.field_behavior) = OPTIONAL]; + // Filter by call_data_size - The size of the call data of the transaction in bytes (optional) + UInt32Filter call_data_size = 21 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_gas - The maximum gas provided for the blob transaction execution (optional) + NullableUInt64Filter blob_gas = 22 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_gas_fee_cap - The max blob fee the user has set for the transaction in wei (optional) + NullableStringFilter blob_gas_fee_cap = 23 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_hashes - The hashes of the blob commitments for blob transactions (optional) + ArrayStringFilter blob_hashes = 24 [(google.api.field_behavior) = OPTIONAL]; + // Filter by is_cancel_shape - Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern (optional) + BoolFilter is_cancel_shape = 25 [(google.api.field_behavior) = OPTIONAL]; + + // The maximum number of fct_transaction_inclusion to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + int32 page_size = 26 [(google.api.field_behavior) = OPTIONAL]; + // A page token, received from a previous `ListFctTransactionInclusion` call. + // Provide this to retrieve the subsequent page. + string page_token = 27 [(google.api.field_behavior) = OPTIONAL]; + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + string order_by = 28 [(google.api.field_behavior) = OPTIONAL]; +} + +// Response for listing fct_transaction_inclusion records +message ListFctTransactionInclusionResponse { + // The list of fct_transaction_inclusion. + repeated FctTransactionInclusion fct_transaction_inclusion = 1; + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; +} + +// Request for getting a single fct_transaction_inclusion record by primary key +message GetFctTransactionInclusionRequest { + // The wall clock time when the slot started + uint32 slot_start_date_time = 1; // Primary key (required) +} + +// Response for getting a single fct_transaction_inclusion record +message GetFctTransactionInclusionResponse { + FctTransactionInclusion item = 1; +} + +// Query fct_transaction_inclusion data +service FctTransactionInclusionService { + // List records | Retrieve paginated results with optional filtering + rpc List(ListFctTransactionInclusionRequest) returns (ListFctTransactionInclusionResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_inclusion" + }; + } + // Get record | Retrieve a single record by slot_start_date_time + rpc Get(GetFctTransactionInclusionRequest) returns (GetFctTransactionInclusionResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_inclusion/{slot_start_date_time}" + }; + } +} diff --git a/pkg/proto/clickhouse/fct_transaction_inclusion_daily.go b/pkg/proto/clickhouse/fct_transaction_inclusion_daily.go new file mode 100644 index 00000000..1665fa6a --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_inclusion_daily.go @@ -0,0 +1,538 @@ +// Code generated by clickhouse-proto-gen. DO NOT EDIT. +// SQL query builder for fct_transaction_inclusion_daily + +package clickhouse + +import ( + "fmt" +) + +// BuildListFctTransactionInclusionDailyQuery constructs a parameterized SQL query from a ListFctTransactionInclusionDailyRequest +func BuildListFctTransactionInclusionDailyQuery(req *ListFctTransactionInclusionDailyRequest, options ...QueryOption) (SQLQuery, error) { + // Validate that at least one primary key is provided + // Primary keys can come from base table or projections + if req.DayStartDate == nil { + return SQLQuery{}, fmt.Errorf("primary key field day_start_date is required") + } + + // Build query using QueryBuilder + qb := NewQueryBuilder() + + // Add primary key filter + switch filter := req.DayStartDate.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("day_start_date", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("day_start_date", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("day_start_date", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("day_start_date", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("day_start_date", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("day_start_date", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("day_start_date", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("day_start_date", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("day_start_date", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + + // Add filter for column: updated_date_time + if req.UpdatedDateTime != nil { + switch filter := req.UpdatedDateTime.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("updated_date_time", "=", DateTimeValue{filter.Eq}) + case *UInt32Filter_Ne: + qb.AddCondition("updated_date_time", "!=", DateTimeValue{filter.Ne}) + case *UInt32Filter_Lt: + qb.AddCondition("updated_date_time", "<", DateTimeValue{filter.Lt}) + case *UInt32Filter_Lte: + qb.AddCondition("updated_date_time", "<=", DateTimeValue{filter.Lte}) + case *UInt32Filter_Gt: + qb.AddCondition("updated_date_time", ">", DateTimeValue{filter.Gt}) + case *UInt32Filter_Gte: + qb.AddCondition("updated_date_time", ">=", DateTimeValue{filter.Gte}) + case *UInt32Filter_Between: + qb.AddBetweenCondition("updated_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("updated_date_time", converted) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("updated_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: included_count + if req.IncludedCount != nil { + switch filter := req.IncludedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("included_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("included_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("included_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("included_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("included_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("included_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("included_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("included_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("included_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: relay_delivered_count + if req.RelayDeliveredCount != nil { + switch filter := req.RelayDeliveredCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("relay_delivered_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("relay_delivered_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("relay_delivered_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("relay_delivered_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("relay_delivered_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("relay_delivered_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("relay_delivered_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("relay_delivered_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("relay_delivered_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: unknown_build_count + if req.UnknownBuildCount != nil { + switch filter := req.UnknownBuildCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("unknown_build_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("unknown_build_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("unknown_build_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("unknown_build_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("unknown_build_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("unknown_build_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("unknown_build_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("unknown_build_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("unknown_build_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type0_count + if req.Type0Count != nil { + switch filter := req.Type0Count.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("type0_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("type0_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("type0_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("type0_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("type0_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("type0_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("type0_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type0_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type0_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type1_count + if req.Type1Count != nil { + switch filter := req.Type1Count.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("type1_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("type1_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("type1_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("type1_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("type1_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("type1_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("type1_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type1_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type1_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type2_count + if req.Type2Count != nil { + switch filter := req.Type2Count.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("type2_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("type2_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("type2_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("type2_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("type2_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("type2_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("type2_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type2_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type2_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type3_count + if req.Type3Count != nil { + switch filter := req.Type3Count.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("type3_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("type3_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("type3_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("type3_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("type3_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("type3_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("type3_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type3_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type3_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type4_count + if req.Type4Count != nil { + switch filter := req.Type4Count.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("type4_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("type4_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("type4_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("type4_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("type4_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("type4_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("type4_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type4_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type4_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type_other_count + if req.TypeOtherCount != nil { + switch filter := req.TypeOtherCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("type_other_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("type_other_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("type_other_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("type_other_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("type_other_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("type_other_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("type_other_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type_other_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type_other_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_count + if req.BlobCount != nil { + switch filter := req.BlobCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("blob_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("blob_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("blob_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("blob_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("blob_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("blob_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("blob_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("blob_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("blob_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: contract_creation_count + if req.ContractCreationCount != nil { + switch filter := req.ContractCreationCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("contract_creation_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("contract_creation_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("contract_creation_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("contract_creation_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("contract_creation_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("contract_creation_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("contract_creation_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("contract_creation_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("contract_creation_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: cancel_shape_count + if req.CancelShapeCount != nil { + switch filter := req.CancelShapeCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("cancel_shape_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("cancel_shape_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("cancel_shape_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("cancel_shape_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("cancel_shape_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("cancel_shape_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("cancel_shape_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("cancel_shape_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("cancel_shape_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: unique_senders + if req.UniqueSenders != nil { + switch filter := req.UniqueSenders.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("unique_senders", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("unique_senders", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("unique_senders", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("unique_senders", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("unique_senders", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("unique_senders", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("unique_senders", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("unique_senders", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("unique_senders", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Handle pagination per AIP-132 + // Validate page size + if req.PageSize < 0 { + return SQLQuery{}, fmt.Errorf("page_size must be non-negative, got %d", req.PageSize) + } + if req.PageSize > 10000 { + return SQLQuery{}, fmt.Errorf("page_size must not exceed %d, got %d", 10000, req.PageSize) + } + + var limit, offset uint32 + limit = 100 // Default page size + if req.PageSize > 0 { + limit = uint32(req.PageSize) + } + if req.PageToken != "" { + decodedOffset, err := DecodePageToken(req.PageToken) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid page_token: %w", err) + } + offset = decodedOffset + } + + // Handle custom ordering if provided + var orderByClause string + if req.OrderBy != "" { + validFields := []string{"updated_date_time", "day_start_date", "included_count", "relay_delivered_count", "unknown_build_count", "type0_count", "type1_count", "type2_count", "type3_count", "type4_count", "type_other_count", "blob_count", "contract_creation_count", "cancel_shape_count", "unique_senders"} + orderFields, err := ParseOrderBy(req.OrderBy, validFields) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid order_by: %w", err) + } + orderByClause = BuildOrderByClause(orderFields) + } else { + // Default sorting by primary key + orderByClause = " ORDER BY day_start_date" + } + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toString(`day_start_date`) AS `day_start_date`", "included_count", "relay_delivered_count", "unknown_build_count", "type0_count", "type1_count", "type2_count", "type3_count", "type4_count", "type_other_count", "blob_count", "contract_creation_count", "cancel_shape_count", "unique_senders"} + + return BuildParameterizedQuery("fct_transaction_inclusion_daily", columns, qb, orderByClause, limit, offset, options...) +} + +// BuildGetFctTransactionInclusionDailyQuery constructs a parameterized SQL query from a GetFctTransactionInclusionDailyRequest +func BuildGetFctTransactionInclusionDailyQuery(req *GetFctTransactionInclusionDailyRequest, options ...QueryOption) (SQLQuery, error) { + // Validate primary key is provided + if req.DayStartDate == "" { + return SQLQuery{}, fmt.Errorf("primary key field day_start_date is required") + } + + // Build query with primary key condition + qb := NewQueryBuilder() + qb.AddCondition("day_start_date", "=", req.DayStartDate) + + // Build ORDER BY clause + orderByClause := " ORDER BY day_start_date" + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toString(`day_start_date`) AS `day_start_date`", "included_count", "relay_delivered_count", "unknown_build_count", "type0_count", "type1_count", "type2_count", "type3_count", "type4_count", "type_other_count", "blob_count", "contract_creation_count", "cancel_shape_count", "unique_senders"} + + // Return single record + return BuildParameterizedQuery("fct_transaction_inclusion_daily", columns, qb, orderByClause, 1, 0, options...) +} diff --git a/pkg/proto/clickhouse/fct_transaction_inclusion_daily.pb.go b/pkg/proto/clickhouse/fct_transaction_inclusion_daily.pb.go new file mode 100644 index 00000000..d7dacb02 --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_inclusion_daily.pb.go @@ -0,0 +1,874 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc (unknown) +// source: fct_transaction_inclusion_daily.proto + +package clickhouse + +import ( + _ "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse/clickhouse" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type FctTransactionInclusionDaily struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Timestamp when the record was last updated + UpdatedDateTime uint32 `protobuf:"varint,11,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Start of the day period, bucketed by inclusion slot time + DayStartDate string `protobuf:"bytes,12,opt,name=day_start_date,json=dayStartDate,proto3" json:"day_start_date,omitempty"` + // Number of transactions included in canonical blocks this day + IncludedCount uint64 `protobuf:"varint,13,opt,name=included_count,json=includedCount,proto3" json:"included_count,omitempty"` + // Included transactions whose block matched a known relay payload-delivered record + RelayDeliveredCount uint64 `protobuf:"varint,14,opt,name=relay_delivered_count,json=relayDeliveredCount,proto3" json:"relay_delivered_count,omitempty"` + // Included transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built + UnknownBuildCount uint64 `protobuf:"varint,15,opt,name=unknown_build_count,json=unknownBuildCount,proto3" json:"unknown_build_count,omitempty"` + // Included legacy type 0 transactions + Type0Count uint64 `protobuf:"varint,16,opt,name=type0_count,json=type0Count,proto3" json:"type0_count,omitempty"` + // Included access list type 1 transactions + Type1Count uint64 `protobuf:"varint,17,opt,name=type1_count,json=type1Count,proto3" json:"type1_count,omitempty"` + // Included dynamic fee type 2 transactions + Type2Count uint64 `protobuf:"varint,18,opt,name=type2_count,json=type2Count,proto3" json:"type2_count,omitempty"` + // Included blob type 3 transactions + Type3Count uint64 `protobuf:"varint,19,opt,name=type3_count,json=type3Count,proto3" json:"type3_count,omitempty"` + // Included set code type 4 transactions + Type4Count uint64 `protobuf:"varint,20,opt,name=type4_count,json=type4Count,proto3" json:"type4_count,omitempty"` + // Included transactions of any other type + TypeOtherCount uint64 `protobuf:"varint,21,opt,name=type_other_count,json=typeOtherCount,proto3" json:"type_other_count,omitempty"` + // Total blob commitments across included transactions this day + BlobCount uint64 `protobuf:"varint,22,opt,name=blob_count,json=blobCount,proto3" json:"blob_count,omitempty"` + // Included transactions with no recipient address + ContractCreationCount uint64 `protobuf:"varint,23,opt,name=contract_creation_count,json=contractCreationCount,proto3" json:"contract_creation_count,omitempty"` + // Included transactions that are self-transfers of zero value, the common wallet cancellation pattern + CancelShapeCount uint64 `protobuf:"varint,24,opt,name=cancel_shape_count,json=cancelShapeCount,proto3" json:"cancel_shape_count,omitempty"` + // Distinct sender addresses across included transactions this day + UniqueSenders uint64 `protobuf:"varint,25,opt,name=unique_senders,json=uniqueSenders,proto3" json:"unique_senders,omitempty"` +} + +func (x *FctTransactionInclusionDaily) Reset() { + *x = FctTransactionInclusionDaily{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_daily_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FctTransactionInclusionDaily) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FctTransactionInclusionDaily) ProtoMessage() {} + +func (x *FctTransactionInclusionDaily) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_daily_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FctTransactionInclusionDaily.ProtoReflect.Descriptor instead. +func (*FctTransactionInclusionDaily) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_daily_proto_rawDescGZIP(), []int{0} +} + +func (x *FctTransactionInclusionDaily) GetUpdatedDateTime() uint32 { + if x != nil { + return x.UpdatedDateTime + } + return 0 +} + +func (x *FctTransactionInclusionDaily) GetDayStartDate() string { + if x != nil { + return x.DayStartDate + } + return "" +} + +func (x *FctTransactionInclusionDaily) GetIncludedCount() uint64 { + if x != nil { + return x.IncludedCount + } + return 0 +} + +func (x *FctTransactionInclusionDaily) GetRelayDeliveredCount() uint64 { + if x != nil { + return x.RelayDeliveredCount + } + return 0 +} + +func (x *FctTransactionInclusionDaily) GetUnknownBuildCount() uint64 { + if x != nil { + return x.UnknownBuildCount + } + return 0 +} + +func (x *FctTransactionInclusionDaily) GetType0Count() uint64 { + if x != nil { + return x.Type0Count + } + return 0 +} + +func (x *FctTransactionInclusionDaily) GetType1Count() uint64 { + if x != nil { + return x.Type1Count + } + return 0 +} + +func (x *FctTransactionInclusionDaily) GetType2Count() uint64 { + if x != nil { + return x.Type2Count + } + return 0 +} + +func (x *FctTransactionInclusionDaily) GetType3Count() uint64 { + if x != nil { + return x.Type3Count + } + return 0 +} + +func (x *FctTransactionInclusionDaily) GetType4Count() uint64 { + if x != nil { + return x.Type4Count + } + return 0 +} + +func (x *FctTransactionInclusionDaily) GetTypeOtherCount() uint64 { + if x != nil { + return x.TypeOtherCount + } + return 0 +} + +func (x *FctTransactionInclusionDaily) GetBlobCount() uint64 { + if x != nil { + return x.BlobCount + } + return 0 +} + +func (x *FctTransactionInclusionDaily) GetContractCreationCount() uint64 { + if x != nil { + return x.ContractCreationCount + } + return 0 +} + +func (x *FctTransactionInclusionDaily) GetCancelShapeCount() uint64 { + if x != nil { + return x.CancelShapeCount + } + return 0 +} + +func (x *FctTransactionInclusionDaily) GetUniqueSenders() uint64 { + if x != nil { + return x.UniqueSenders + } + return 0 +} + +// Request for listing fct_transaction_inclusion_daily records +type ListFctTransactionInclusionDailyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Filter by day_start_date - Start of the day period, bucketed by inclusion slot time (PRIMARY KEY - required) + DayStartDate *StringFilter `protobuf:"bytes,1,opt,name=day_start_date,json=dayStartDate,proto3" json:"day_start_date,omitempty"` + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UpdatedDateTime *UInt32Filter `protobuf:"bytes,2,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Filter by included_count - Number of transactions included in canonical blocks this day (optional) + IncludedCount *UInt64Filter `protobuf:"bytes,3,opt,name=included_count,json=includedCount,proto3" json:"included_count,omitempty"` + // Filter by relay_delivered_count - Included transactions whose block matched a known relay payload-delivered record (optional) + RelayDeliveredCount *UInt64Filter `protobuf:"bytes,4,opt,name=relay_delivered_count,json=relayDeliveredCount,proto3" json:"relay_delivered_count,omitempty"` + // Filter by unknown_build_count - Included transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built (optional) + UnknownBuildCount *UInt64Filter `protobuf:"bytes,5,opt,name=unknown_build_count,json=unknownBuildCount,proto3" json:"unknown_build_count,omitempty"` + // Filter by type0_count - Included legacy type 0 transactions (optional) + Type0Count *UInt64Filter `protobuf:"bytes,6,opt,name=type0_count,json=type0Count,proto3" json:"type0_count,omitempty"` + // Filter by type1_count - Included access list type 1 transactions (optional) + Type1Count *UInt64Filter `protobuf:"bytes,7,opt,name=type1_count,json=type1Count,proto3" json:"type1_count,omitempty"` + // Filter by type2_count - Included dynamic fee type 2 transactions (optional) + Type2Count *UInt64Filter `protobuf:"bytes,8,opt,name=type2_count,json=type2Count,proto3" json:"type2_count,omitempty"` + // Filter by type3_count - Included blob type 3 transactions (optional) + Type3Count *UInt64Filter `protobuf:"bytes,9,opt,name=type3_count,json=type3Count,proto3" json:"type3_count,omitempty"` + // Filter by type4_count - Included set code type 4 transactions (optional) + Type4Count *UInt64Filter `protobuf:"bytes,10,opt,name=type4_count,json=type4Count,proto3" json:"type4_count,omitempty"` + // Filter by type_other_count - Included transactions of any other type (optional) + TypeOtherCount *UInt64Filter `protobuf:"bytes,11,opt,name=type_other_count,json=typeOtherCount,proto3" json:"type_other_count,omitempty"` + // Filter by blob_count - Total blob commitments across included transactions this day (optional) + BlobCount *UInt64Filter `protobuf:"bytes,12,opt,name=blob_count,json=blobCount,proto3" json:"blob_count,omitempty"` + // Filter by contract_creation_count - Included transactions with no recipient address (optional) + ContractCreationCount *UInt64Filter `protobuf:"bytes,13,opt,name=contract_creation_count,json=contractCreationCount,proto3" json:"contract_creation_count,omitempty"` + // Filter by cancel_shape_count - Included transactions that are self-transfers of zero value, the common wallet cancellation pattern (optional) + CancelShapeCount *UInt64Filter `protobuf:"bytes,14,opt,name=cancel_shape_count,json=cancelShapeCount,proto3" json:"cancel_shape_count,omitempty"` + // Filter by unique_senders - Distinct sender addresses across included transactions this day (optional) + UniqueSenders *UInt64Filter `protobuf:"bytes,15,opt,name=unique_senders,json=uniqueSenders,proto3" json:"unique_senders,omitempty"` + // The maximum number of fct_transaction_inclusion_daily to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + PageSize int32 `protobuf:"varint,16,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // A page token, received from a previous `ListFctTransactionInclusionDaily` call. + // Provide this to retrieve the subsequent page. + PageToken string `protobuf:"bytes,17,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + OrderBy string `protobuf:"bytes,18,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"` +} + +func (x *ListFctTransactionInclusionDailyRequest) Reset() { + *x = ListFctTransactionInclusionDailyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_daily_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionInclusionDailyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionInclusionDailyRequest) ProtoMessage() {} + +func (x *ListFctTransactionInclusionDailyRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_daily_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionInclusionDailyRequest.ProtoReflect.Descriptor instead. +func (*ListFctTransactionInclusionDailyRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_daily_proto_rawDescGZIP(), []int{1} +} + +func (x *ListFctTransactionInclusionDailyRequest) GetDayStartDate() *StringFilter { + if x != nil { + return x.DayStartDate + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetUpdatedDateTime() *UInt32Filter { + if x != nil { + return x.UpdatedDateTime + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetIncludedCount() *UInt64Filter { + if x != nil { + return x.IncludedCount + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetRelayDeliveredCount() *UInt64Filter { + if x != nil { + return x.RelayDeliveredCount + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetUnknownBuildCount() *UInt64Filter { + if x != nil { + return x.UnknownBuildCount + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetType0Count() *UInt64Filter { + if x != nil { + return x.Type0Count + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetType1Count() *UInt64Filter { + if x != nil { + return x.Type1Count + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetType2Count() *UInt64Filter { + if x != nil { + return x.Type2Count + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetType3Count() *UInt64Filter { + if x != nil { + return x.Type3Count + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetType4Count() *UInt64Filter { + if x != nil { + return x.Type4Count + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetTypeOtherCount() *UInt64Filter { + if x != nil { + return x.TypeOtherCount + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetBlobCount() *UInt64Filter { + if x != nil { + return x.BlobCount + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetContractCreationCount() *UInt64Filter { + if x != nil { + return x.ContractCreationCount + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetCancelShapeCount() *UInt64Filter { + if x != nil { + return x.CancelShapeCount + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetUniqueSenders() *UInt64Filter { + if x != nil { + return x.UniqueSenders + } + return nil +} + +func (x *ListFctTransactionInclusionDailyRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListFctTransactionInclusionDailyRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +func (x *ListFctTransactionInclusionDailyRequest) GetOrderBy() string { + if x != nil { + return x.OrderBy + } + return "" +} + +// Response for listing fct_transaction_inclusion_daily records +type ListFctTransactionInclusionDailyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of fct_transaction_inclusion_daily. + FctTransactionInclusionDaily []*FctTransactionInclusionDaily `protobuf:"bytes,1,rep,name=fct_transaction_inclusion_daily,json=fctTransactionInclusionDaily,proto3" json:"fct_transaction_inclusion_daily,omitempty"` + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` +} + +func (x *ListFctTransactionInclusionDailyResponse) Reset() { + *x = ListFctTransactionInclusionDailyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_daily_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionInclusionDailyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionInclusionDailyResponse) ProtoMessage() {} + +func (x *ListFctTransactionInclusionDailyResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_daily_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionInclusionDailyResponse.ProtoReflect.Descriptor instead. +func (*ListFctTransactionInclusionDailyResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_daily_proto_rawDescGZIP(), []int{2} +} + +func (x *ListFctTransactionInclusionDailyResponse) GetFctTransactionInclusionDaily() []*FctTransactionInclusionDaily { + if x != nil { + return x.FctTransactionInclusionDaily + } + return nil +} + +func (x *ListFctTransactionInclusionDailyResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +// Request for getting a single fct_transaction_inclusion_daily record by primary key +type GetFctTransactionInclusionDailyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Start of the day period, bucketed by inclusion slot time + DayStartDate string `protobuf:"bytes,1,opt,name=day_start_date,json=dayStartDate,proto3" json:"day_start_date,omitempty"` // Primary key (required) +} + +func (x *GetFctTransactionInclusionDailyRequest) Reset() { + *x = GetFctTransactionInclusionDailyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_daily_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionInclusionDailyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionInclusionDailyRequest) ProtoMessage() {} + +func (x *GetFctTransactionInclusionDailyRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_daily_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionInclusionDailyRequest.ProtoReflect.Descriptor instead. +func (*GetFctTransactionInclusionDailyRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_daily_proto_rawDescGZIP(), []int{3} +} + +func (x *GetFctTransactionInclusionDailyRequest) GetDayStartDate() string { + if x != nil { + return x.DayStartDate + } + return "" +} + +// Response for getting a single fct_transaction_inclusion_daily record +type GetFctTransactionInclusionDailyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *FctTransactionInclusionDaily `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *GetFctTransactionInclusionDailyResponse) Reset() { + *x = GetFctTransactionInclusionDailyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_daily_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionInclusionDailyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionInclusionDailyResponse) ProtoMessage() {} + +func (x *GetFctTransactionInclusionDailyResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_daily_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionInclusionDailyResponse.ProtoReflect.Descriptor instead. +func (*GetFctTransactionInclusionDailyResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_daily_proto_rawDescGZIP(), []int{4} +} + +func (x *GetFctTransactionInclusionDailyResponse) GetItem() *FctTransactionInclusionDaily { + if x != nil { + return x.Item + } + return nil +} + +var File_fct_transaction_inclusion_daily_proto protoreflect.FileDescriptor + +var file_fct_transaction_inclusion_daily_proto_rawDesc = []byte{ + 0x0a, 0x25, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x69, 0x6c, + 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x63, 0x62, 0x74, 0x1a, 0x0c, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, + 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x63, 0x6c, 0x69, 0x63, 0x6b, + 0x68, 0x6f, 0x75, 0x73, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf6, 0x04, 0x0a, 0x1c, 0x46, 0x63, 0x74, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, + 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x61, + 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x32, 0x0a, 0x15, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x64, 0x65, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x13, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, 0x64, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x11, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x75, 0x69, 0x6c, 0x64, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x30, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, + 0x30, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x31, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x79, 0x70, + 0x65, 0x31, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x32, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x79, + 0x70, 0x65, 0x32, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, + 0x33, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, + 0x79, 0x70, 0x65, 0x33, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x79, 0x70, + 0x65, 0x34, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, + 0x74, 0x79, 0x70, 0x65, 0x34, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x15, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x74, 0x79, 0x70, 0x65, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x62, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x17, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x63, + 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x18, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, + 0x68, 0x61, 0x70, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x75, 0x6e, 0x69, + 0x71, 0x75, 0x65, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0d, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x73, + 0x22, 0xde, 0x08, 0x0a, 0x27, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, + 0x44, 0x61, 0x69, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x0e, + 0x64, 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x12, 0xe0, 0x41, 0x02, 0x9a, 0xb5, 0x18, 0x0b, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x52, 0x0c, 0x64, 0x61, 0x79, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, 0x42, 0x0a, 0x11, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, + 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0f, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3d, 0x0a, + 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4a, 0x0a, 0x15, + 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, 0x64, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x13, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x46, 0x0a, 0x13, 0x75, 0x6e, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x11, 0x75, + 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x37, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x30, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x74, + 0x79, 0x70, 0x65, 0x30, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x74, 0x79, 0x70, + 0x65, 0x31, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x31, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x32, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, + 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x0a, 0x74, 0x79, 0x70, 0x65, 0x32, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x74, + 0x79, 0x70, 0x65, 0x33, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x33, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x34, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, + 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, + 0x01, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x34, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x40, 0x0a, + 0x10, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, + 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x0e, 0x74, 0x79, 0x70, 0x65, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x35, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x62, 0x6c, 0x6f, + 0x62, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4e, 0x0a, 0x17, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x63, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, + 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x15, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x44, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, + 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x10, 0x63, 0x61, 0x6e, 0x63, + 0x65, 0x6c, 0x53, 0x68, 0x61, 0x70, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x0e, + 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x18, 0x0f, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, + 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x75, 0x6e, + 0x69, 0x71, 0x75, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x12, 0x20, 0x0a, 0x09, 0x70, + 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, + 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x1e, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x12, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, + 0x79, 0x22, 0xbc, 0x01, 0x0a, 0x28, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, + 0x6e, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, + 0x0a, 0x1f, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x69, 0x6c, + 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x46, 0x63, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, + 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x52, 0x1c, 0x66, 0x63, 0x74, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, + 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, + 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x22, 0x4e, 0x0a, 0x26, 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, + 0x69, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x61, + 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x64, 0x61, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, + 0x22, 0x60, 0x0a, 0x27, 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, + 0x69, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x69, + 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x62, 0x74, 0x2e, + 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, + 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x52, 0x04, 0x69, 0x74, + 0x65, 0x6d, 0x32, 0xe1, 0x02, 0x0a, 0x23, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, + 0x69, 0x6c, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x94, 0x01, 0x0a, 0x04, 0x4c, + 0x69, 0x73, 0x74, 0x12, 0x2c, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, + 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2d, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, + 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x31, 0x2f, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x69, 0x6c, + 0x79, 0x12, 0xa2, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x2b, 0x2e, 0x63, 0x62, 0x74, 0x2e, + 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x47, 0x65, 0x74, + 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, + 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x40, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3a, 0x12, 0x38, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, + 0x64, 0x61, 0x69, 0x6c, 0x79, 0x2f, 0x7b, 0x64, 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5f, 0x64, 0x61, 0x74, 0x65, 0x7d, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x70, 0x61, 0x6e, 0x64, 0x61, 0x6f, 0x70, 0x73, + 0x2f, 0x78, 0x61, 0x74, 0x75, 0x2d, 0x63, 0x62, 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_fct_transaction_inclusion_daily_proto_rawDescOnce sync.Once + file_fct_transaction_inclusion_daily_proto_rawDescData = file_fct_transaction_inclusion_daily_proto_rawDesc +) + +func file_fct_transaction_inclusion_daily_proto_rawDescGZIP() []byte { + file_fct_transaction_inclusion_daily_proto_rawDescOnce.Do(func() { + file_fct_transaction_inclusion_daily_proto_rawDescData = protoimpl.X.CompressGZIP(file_fct_transaction_inclusion_daily_proto_rawDescData) + }) + return file_fct_transaction_inclusion_daily_proto_rawDescData +} + +var file_fct_transaction_inclusion_daily_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_fct_transaction_inclusion_daily_proto_goTypes = []any{ + (*FctTransactionInclusionDaily)(nil), // 0: cbt.FctTransactionInclusionDaily + (*ListFctTransactionInclusionDailyRequest)(nil), // 1: cbt.ListFctTransactionInclusionDailyRequest + (*ListFctTransactionInclusionDailyResponse)(nil), // 2: cbt.ListFctTransactionInclusionDailyResponse + (*GetFctTransactionInclusionDailyRequest)(nil), // 3: cbt.GetFctTransactionInclusionDailyRequest + (*GetFctTransactionInclusionDailyResponse)(nil), // 4: cbt.GetFctTransactionInclusionDailyResponse + (*StringFilter)(nil), // 5: cbt.StringFilter + (*UInt32Filter)(nil), // 6: cbt.UInt32Filter + (*UInt64Filter)(nil), // 7: cbt.UInt64Filter +} +var file_fct_transaction_inclusion_daily_proto_depIdxs = []int32{ + 5, // 0: cbt.ListFctTransactionInclusionDailyRequest.day_start_date:type_name -> cbt.StringFilter + 6, // 1: cbt.ListFctTransactionInclusionDailyRequest.updated_date_time:type_name -> cbt.UInt32Filter + 7, // 2: cbt.ListFctTransactionInclusionDailyRequest.included_count:type_name -> cbt.UInt64Filter + 7, // 3: cbt.ListFctTransactionInclusionDailyRequest.relay_delivered_count:type_name -> cbt.UInt64Filter + 7, // 4: cbt.ListFctTransactionInclusionDailyRequest.unknown_build_count:type_name -> cbt.UInt64Filter + 7, // 5: cbt.ListFctTransactionInclusionDailyRequest.type0_count:type_name -> cbt.UInt64Filter + 7, // 6: cbt.ListFctTransactionInclusionDailyRequest.type1_count:type_name -> cbt.UInt64Filter + 7, // 7: cbt.ListFctTransactionInclusionDailyRequest.type2_count:type_name -> cbt.UInt64Filter + 7, // 8: cbt.ListFctTransactionInclusionDailyRequest.type3_count:type_name -> cbt.UInt64Filter + 7, // 9: cbt.ListFctTransactionInclusionDailyRequest.type4_count:type_name -> cbt.UInt64Filter + 7, // 10: cbt.ListFctTransactionInclusionDailyRequest.type_other_count:type_name -> cbt.UInt64Filter + 7, // 11: cbt.ListFctTransactionInclusionDailyRequest.blob_count:type_name -> cbt.UInt64Filter + 7, // 12: cbt.ListFctTransactionInclusionDailyRequest.contract_creation_count:type_name -> cbt.UInt64Filter + 7, // 13: cbt.ListFctTransactionInclusionDailyRequest.cancel_shape_count:type_name -> cbt.UInt64Filter + 7, // 14: cbt.ListFctTransactionInclusionDailyRequest.unique_senders:type_name -> cbt.UInt64Filter + 0, // 15: cbt.ListFctTransactionInclusionDailyResponse.fct_transaction_inclusion_daily:type_name -> cbt.FctTransactionInclusionDaily + 0, // 16: cbt.GetFctTransactionInclusionDailyResponse.item:type_name -> cbt.FctTransactionInclusionDaily + 1, // 17: cbt.FctTransactionInclusionDailyService.List:input_type -> cbt.ListFctTransactionInclusionDailyRequest + 3, // 18: cbt.FctTransactionInclusionDailyService.Get:input_type -> cbt.GetFctTransactionInclusionDailyRequest + 2, // 19: cbt.FctTransactionInclusionDailyService.List:output_type -> cbt.ListFctTransactionInclusionDailyResponse + 4, // 20: cbt.FctTransactionInclusionDailyService.Get:output_type -> cbt.GetFctTransactionInclusionDailyResponse + 19, // [19:21] is the sub-list for method output_type + 17, // [17:19] is the sub-list for method input_type + 17, // [17:17] is the sub-list for extension type_name + 17, // [17:17] is the sub-list for extension extendee + 0, // [0:17] is the sub-list for field type_name +} + +func init() { file_fct_transaction_inclusion_daily_proto_init() } +func file_fct_transaction_inclusion_daily_proto_init() { + if File_fct_transaction_inclusion_daily_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_fct_transaction_inclusion_daily_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*FctTransactionInclusionDaily); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_inclusion_daily_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionInclusionDailyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_inclusion_daily_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionInclusionDailyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_inclusion_daily_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionInclusionDailyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_inclusion_daily_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionInclusionDailyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_fct_transaction_inclusion_daily_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_fct_transaction_inclusion_daily_proto_goTypes, + DependencyIndexes: file_fct_transaction_inclusion_daily_proto_depIdxs, + MessageInfos: file_fct_transaction_inclusion_daily_proto_msgTypes, + }.Build() + File_fct_transaction_inclusion_daily_proto = out.File + file_fct_transaction_inclusion_daily_proto_rawDesc = nil + file_fct_transaction_inclusion_daily_proto_goTypes = nil + file_fct_transaction_inclusion_daily_proto_depIdxs = nil +} diff --git a/pkg/proto/clickhouse/fct_transaction_inclusion_daily.proto b/pkg/proto/clickhouse/fct_transaction_inclusion_daily.proto new file mode 100644 index 00000000..43ffafe8 --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_inclusion_daily.proto @@ -0,0 +1,127 @@ +syntax = "proto3"; + +package cbt; + +import "common.proto"; +import "google/api/annotations.proto"; +import "google/api/field_behavior.proto"; +import "clickhouse/annotations.proto"; + +option go_package = "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse"; +// Daily counts of transactions included in canonical blocks, split by build path and transaction type + +message FctTransactionInclusionDaily { + // Timestamp when the record was last updated + uint32 updated_date_time = 11; + // Start of the day period, bucketed by inclusion slot time + string day_start_date = 12; + // Number of transactions included in canonical blocks this day + uint64 included_count = 13; + // Included transactions whose block matched a known relay payload-delivered record + uint64 relay_delivered_count = 14; + // Included transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built + uint64 unknown_build_count = 15; + // Included legacy type 0 transactions + uint64 type0_count = 16; + // Included access list type 1 transactions + uint64 type1_count = 17; + // Included dynamic fee type 2 transactions + uint64 type2_count = 18; + // Included blob type 3 transactions + uint64 type3_count = 19; + // Included set code type 4 transactions + uint64 type4_count = 20; + // Included transactions of any other type + uint64 type_other_count = 21; + // Total blob commitments across included transactions this day + uint64 blob_count = 22; + // Included transactions with no recipient address + uint64 contract_creation_count = 23; + // Included transactions that are self-transfers of zero value, the common wallet cancellation pattern + uint64 cancel_shape_count = 24; + // Distinct sender addresses across included transactions this day + uint64 unique_senders = 25; +} + +// Request for listing fct_transaction_inclusion_daily records +message ListFctTransactionInclusionDailyRequest { + // Filter by day_start_date - Start of the day period, bucketed by inclusion slot time (PRIMARY KEY - required) + StringFilter day_start_date = 1 [(google.api.field_behavior) = REQUIRED, (clickhouse.v1.required_group) = "primary_key"]; + + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UInt32Filter updated_date_time = 2 [(google.api.field_behavior) = OPTIONAL]; + // Filter by included_count - Number of transactions included in canonical blocks this day (optional) + UInt64Filter included_count = 3 [(google.api.field_behavior) = OPTIONAL]; + // Filter by relay_delivered_count - Included transactions whose block matched a known relay payload-delivered record (optional) + UInt64Filter relay_delivered_count = 4 [(google.api.field_behavior) = OPTIONAL]; + // Filter by unknown_build_count - Included transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built (optional) + UInt64Filter unknown_build_count = 5 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type0_count - Included legacy type 0 transactions (optional) + UInt64Filter type0_count = 6 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type1_count - Included access list type 1 transactions (optional) + UInt64Filter type1_count = 7 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type2_count - Included dynamic fee type 2 transactions (optional) + UInt64Filter type2_count = 8 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type3_count - Included blob type 3 transactions (optional) + UInt64Filter type3_count = 9 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type4_count - Included set code type 4 transactions (optional) + UInt64Filter type4_count = 10 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type_other_count - Included transactions of any other type (optional) + UInt64Filter type_other_count = 11 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_count - Total blob commitments across included transactions this day (optional) + UInt64Filter blob_count = 12 [(google.api.field_behavior) = OPTIONAL]; + // Filter by contract_creation_count - Included transactions with no recipient address (optional) + UInt64Filter contract_creation_count = 13 [(google.api.field_behavior) = OPTIONAL]; + // Filter by cancel_shape_count - Included transactions that are self-transfers of zero value, the common wallet cancellation pattern (optional) + UInt64Filter cancel_shape_count = 14 [(google.api.field_behavior) = OPTIONAL]; + // Filter by unique_senders - Distinct sender addresses across included transactions this day (optional) + UInt64Filter unique_senders = 15 [(google.api.field_behavior) = OPTIONAL]; + + // The maximum number of fct_transaction_inclusion_daily to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + int32 page_size = 16 [(google.api.field_behavior) = OPTIONAL]; + // A page token, received from a previous `ListFctTransactionInclusionDaily` call. + // Provide this to retrieve the subsequent page. + string page_token = 17 [(google.api.field_behavior) = OPTIONAL]; + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + string order_by = 18 [(google.api.field_behavior) = OPTIONAL]; +} + +// Response for listing fct_transaction_inclusion_daily records +message ListFctTransactionInclusionDailyResponse { + // The list of fct_transaction_inclusion_daily. + repeated FctTransactionInclusionDaily fct_transaction_inclusion_daily = 1; + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; +} + +// Request for getting a single fct_transaction_inclusion_daily record by primary key +message GetFctTransactionInclusionDailyRequest { + // Start of the day period, bucketed by inclusion slot time + string day_start_date = 1; // Primary key (required) +} + +// Response for getting a single fct_transaction_inclusion_daily record +message GetFctTransactionInclusionDailyResponse { + FctTransactionInclusionDaily item = 1; +} + +// Query fct_transaction_inclusion_daily data +service FctTransactionInclusionDailyService { + // List records | Retrieve paginated results with optional filtering + rpc List(ListFctTransactionInclusionDailyRequest) returns (ListFctTransactionInclusionDailyResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_inclusion_daily" + }; + } + // Get record | Retrieve a single record by day_start_date + rpc Get(GetFctTransactionInclusionDailyRequest) returns (GetFctTransactionInclusionDailyResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_inclusion_daily/{day_start_date}" + }; + } +} diff --git a/pkg/proto/clickhouse/fct_transaction_inclusion_hourly.go b/pkg/proto/clickhouse/fct_transaction_inclusion_hourly.go new file mode 100644 index 00000000..57c8bd99 --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_inclusion_hourly.go @@ -0,0 +1,546 @@ +// Code generated by clickhouse-proto-gen. DO NOT EDIT. +// SQL query builder for fct_transaction_inclusion_hourly + +package clickhouse + +import ( + "fmt" +) + +// BuildListFctTransactionInclusionHourlyQuery constructs a parameterized SQL query from a ListFctTransactionInclusionHourlyRequest +func BuildListFctTransactionInclusionHourlyQuery(req *ListFctTransactionInclusionHourlyRequest, options ...QueryOption) (SQLQuery, error) { + // Validate that at least one primary key is provided + // Primary keys can come from base table or projections + if req.HourStartDateTime == nil { + return SQLQuery{}, fmt.Errorf("primary key field hour_start_date_time is required") + } + + // Build query using QueryBuilder + qb := NewQueryBuilder() + + // Add primary key filter + switch filter := req.HourStartDateTime.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("hour_start_date_time", "=", DateTimeValue{filter.Eq}) + case *UInt32Filter_Ne: + qb.AddCondition("hour_start_date_time", "!=", DateTimeValue{filter.Ne}) + case *UInt32Filter_Lt: + qb.AddCondition("hour_start_date_time", "<", DateTimeValue{filter.Lt}) + case *UInt32Filter_Lte: + qb.AddCondition("hour_start_date_time", "<=", DateTimeValue{filter.Lte}) + case *UInt32Filter_Gt: + qb.AddCondition("hour_start_date_time", ">", DateTimeValue{filter.Gt}) + case *UInt32Filter_Gte: + qb.AddCondition("hour_start_date_time", ">=", DateTimeValue{filter.Gte}) + case *UInt32Filter_Between: + qb.AddBetweenCondition("hour_start_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("hour_start_date_time", converted) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("hour_start_date_time", converted) + } + default: + // Unsupported filter type + } + + // Add filter for column: updated_date_time + if req.UpdatedDateTime != nil { + switch filter := req.UpdatedDateTime.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("updated_date_time", "=", DateTimeValue{filter.Eq}) + case *UInt32Filter_Ne: + qb.AddCondition("updated_date_time", "!=", DateTimeValue{filter.Ne}) + case *UInt32Filter_Lt: + qb.AddCondition("updated_date_time", "<", DateTimeValue{filter.Lt}) + case *UInt32Filter_Lte: + qb.AddCondition("updated_date_time", "<=", DateTimeValue{filter.Lte}) + case *UInt32Filter_Gt: + qb.AddCondition("updated_date_time", ">", DateTimeValue{filter.Gt}) + case *UInt32Filter_Gte: + qb.AddCondition("updated_date_time", ">=", DateTimeValue{filter.Gte}) + case *UInt32Filter_Between: + qb.AddBetweenCondition("updated_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("updated_date_time", converted) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("updated_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: included_count + if req.IncludedCount != nil { + switch filter := req.IncludedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("included_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("included_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("included_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("included_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("included_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("included_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("included_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("included_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("included_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: relay_delivered_count + if req.RelayDeliveredCount != nil { + switch filter := req.RelayDeliveredCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("relay_delivered_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("relay_delivered_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("relay_delivered_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("relay_delivered_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("relay_delivered_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("relay_delivered_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("relay_delivered_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("relay_delivered_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("relay_delivered_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: unknown_build_count + if req.UnknownBuildCount != nil { + switch filter := req.UnknownBuildCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("unknown_build_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("unknown_build_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("unknown_build_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("unknown_build_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("unknown_build_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("unknown_build_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("unknown_build_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("unknown_build_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("unknown_build_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type0_count + if req.Type0Count != nil { + switch filter := req.Type0Count.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("type0_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("type0_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("type0_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("type0_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("type0_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("type0_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("type0_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type0_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type0_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type1_count + if req.Type1Count != nil { + switch filter := req.Type1Count.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("type1_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("type1_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("type1_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("type1_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("type1_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("type1_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("type1_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type1_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type1_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type2_count + if req.Type2Count != nil { + switch filter := req.Type2Count.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("type2_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("type2_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("type2_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("type2_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("type2_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("type2_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("type2_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type2_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type2_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type3_count + if req.Type3Count != nil { + switch filter := req.Type3Count.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("type3_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("type3_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("type3_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("type3_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("type3_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("type3_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("type3_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type3_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type3_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type4_count + if req.Type4Count != nil { + switch filter := req.Type4Count.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("type4_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("type4_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("type4_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("type4_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("type4_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("type4_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("type4_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type4_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type4_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type_other_count + if req.TypeOtherCount != nil { + switch filter := req.TypeOtherCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("type_other_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("type_other_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("type_other_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("type_other_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("type_other_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("type_other_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("type_other_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type_other_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type_other_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_count + if req.BlobCount != nil { + switch filter := req.BlobCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("blob_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("blob_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("blob_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("blob_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("blob_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("blob_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("blob_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("blob_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("blob_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: contract_creation_count + if req.ContractCreationCount != nil { + switch filter := req.ContractCreationCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("contract_creation_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("contract_creation_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("contract_creation_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("contract_creation_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("contract_creation_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("contract_creation_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("contract_creation_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("contract_creation_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("contract_creation_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: cancel_shape_count + if req.CancelShapeCount != nil { + switch filter := req.CancelShapeCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("cancel_shape_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("cancel_shape_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("cancel_shape_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("cancel_shape_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("cancel_shape_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("cancel_shape_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("cancel_shape_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("cancel_shape_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("cancel_shape_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: unique_senders + if req.UniqueSenders != nil { + switch filter := req.UniqueSenders.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("unique_senders", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("unique_senders", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("unique_senders", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("unique_senders", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("unique_senders", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("unique_senders", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("unique_senders", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("unique_senders", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("unique_senders", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Handle pagination per AIP-132 + // Validate page size + if req.PageSize < 0 { + return SQLQuery{}, fmt.Errorf("page_size must be non-negative, got %d", req.PageSize) + } + if req.PageSize > 10000 { + return SQLQuery{}, fmt.Errorf("page_size must not exceed %d, got %d", 10000, req.PageSize) + } + + var limit, offset uint32 + limit = 100 // Default page size + if req.PageSize > 0 { + limit = uint32(req.PageSize) + } + if req.PageToken != "" { + decodedOffset, err := DecodePageToken(req.PageToken) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid page_token: %w", err) + } + offset = decodedOffset + } + + // Handle custom ordering if provided + var orderByClause string + if req.OrderBy != "" { + validFields := []string{"updated_date_time", "hour_start_date_time", "included_count", "relay_delivered_count", "unknown_build_count", "type0_count", "type1_count", "type2_count", "type3_count", "type4_count", "type_other_count", "blob_count", "contract_creation_count", "cancel_shape_count", "unique_senders"} + orderFields, err := ParseOrderBy(req.OrderBy, validFields) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid order_by: %w", err) + } + orderByClause = BuildOrderByClause(orderFields) + } else { + // Default sorting by primary key + orderByClause = " ORDER BY hour_start_date_time" + } + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toUnixTimestamp(`hour_start_date_time`) AS `hour_start_date_time`", "included_count", "relay_delivered_count", "unknown_build_count", "type0_count", "type1_count", "type2_count", "type3_count", "type4_count", "type_other_count", "blob_count", "contract_creation_count", "cancel_shape_count", "unique_senders"} + + return BuildParameterizedQuery("fct_transaction_inclusion_hourly", columns, qb, orderByClause, limit, offset, options...) +} + +// BuildGetFctTransactionInclusionHourlyQuery constructs a parameterized SQL query from a GetFctTransactionInclusionHourlyRequest +func BuildGetFctTransactionInclusionHourlyQuery(req *GetFctTransactionInclusionHourlyRequest, options ...QueryOption) (SQLQuery, error) { + // Validate primary key is provided + if req.HourStartDateTime == 0 { + return SQLQuery{}, fmt.Errorf("primary key field hour_start_date_time is required") + } + + // Build query with primary key condition + qb := NewQueryBuilder() + qb.AddCondition("hour_start_date_time", "=", req.HourStartDateTime) + + // Build ORDER BY clause + orderByClause := " ORDER BY hour_start_date_time" + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toUnixTimestamp(`hour_start_date_time`) AS `hour_start_date_time`", "included_count", "relay_delivered_count", "unknown_build_count", "type0_count", "type1_count", "type2_count", "type3_count", "type4_count", "type_other_count", "blob_count", "contract_creation_count", "cancel_shape_count", "unique_senders"} + + // Return single record + return BuildParameterizedQuery("fct_transaction_inclusion_hourly", columns, qb, orderByClause, 1, 0, options...) +} diff --git a/pkg/proto/clickhouse/fct_transaction_inclusion_hourly.pb.go b/pkg/proto/clickhouse/fct_transaction_inclusion_hourly.pb.go new file mode 100644 index 00000000..9f077e3c --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_inclusion_hourly.pb.go @@ -0,0 +1,876 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc (unknown) +// source: fct_transaction_inclusion_hourly.proto + +package clickhouse + +import ( + _ "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse/clickhouse" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type FctTransactionInclusionHourly struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Timestamp when the record was last updated + UpdatedDateTime uint32 `protobuf:"varint,11,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Start of the hour period, bucketed by inclusion slot time + HourStartDateTime uint32 `protobuf:"varint,12,opt,name=hour_start_date_time,json=hourStartDateTime,proto3" json:"hour_start_date_time,omitempty"` + // Number of transactions included in canonical blocks this hour + IncludedCount uint64 `protobuf:"varint,13,opt,name=included_count,json=includedCount,proto3" json:"included_count,omitempty"` + // Included transactions whose block matched a known relay payload-delivered record + RelayDeliveredCount uint64 `protobuf:"varint,14,opt,name=relay_delivered_count,json=relayDeliveredCount,proto3" json:"relay_delivered_count,omitempty"` + // Included transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built + UnknownBuildCount uint64 `protobuf:"varint,15,opt,name=unknown_build_count,json=unknownBuildCount,proto3" json:"unknown_build_count,omitempty"` + // Included legacy type 0 transactions + Type0Count uint64 `protobuf:"varint,16,opt,name=type0_count,json=type0Count,proto3" json:"type0_count,omitempty"` + // Included access list type 1 transactions + Type1Count uint64 `protobuf:"varint,17,opt,name=type1_count,json=type1Count,proto3" json:"type1_count,omitempty"` + // Included dynamic fee type 2 transactions + Type2Count uint64 `protobuf:"varint,18,opt,name=type2_count,json=type2Count,proto3" json:"type2_count,omitempty"` + // Included blob type 3 transactions + Type3Count uint64 `protobuf:"varint,19,opt,name=type3_count,json=type3Count,proto3" json:"type3_count,omitempty"` + // Included set code type 4 transactions + Type4Count uint64 `protobuf:"varint,20,opt,name=type4_count,json=type4Count,proto3" json:"type4_count,omitempty"` + // Included transactions of any other type + TypeOtherCount uint64 `protobuf:"varint,21,opt,name=type_other_count,json=typeOtherCount,proto3" json:"type_other_count,omitempty"` + // Total blob commitments across included transactions this hour + BlobCount uint64 `protobuf:"varint,22,opt,name=blob_count,json=blobCount,proto3" json:"blob_count,omitempty"` + // Included transactions with no recipient address + ContractCreationCount uint64 `protobuf:"varint,23,opt,name=contract_creation_count,json=contractCreationCount,proto3" json:"contract_creation_count,omitempty"` + // Included transactions that are self-transfers of zero value, the common wallet cancellation pattern + CancelShapeCount uint64 `protobuf:"varint,24,opt,name=cancel_shape_count,json=cancelShapeCount,proto3" json:"cancel_shape_count,omitempty"` + // Distinct sender addresses across included transactions this hour + UniqueSenders uint64 `protobuf:"varint,25,opt,name=unique_senders,json=uniqueSenders,proto3" json:"unique_senders,omitempty"` +} + +func (x *FctTransactionInclusionHourly) Reset() { + *x = FctTransactionInclusionHourly{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_hourly_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FctTransactionInclusionHourly) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FctTransactionInclusionHourly) ProtoMessage() {} + +func (x *FctTransactionInclusionHourly) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_hourly_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FctTransactionInclusionHourly.ProtoReflect.Descriptor instead. +func (*FctTransactionInclusionHourly) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_hourly_proto_rawDescGZIP(), []int{0} +} + +func (x *FctTransactionInclusionHourly) GetUpdatedDateTime() uint32 { + if x != nil { + return x.UpdatedDateTime + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetHourStartDateTime() uint32 { + if x != nil { + return x.HourStartDateTime + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetIncludedCount() uint64 { + if x != nil { + return x.IncludedCount + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetRelayDeliveredCount() uint64 { + if x != nil { + return x.RelayDeliveredCount + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetUnknownBuildCount() uint64 { + if x != nil { + return x.UnknownBuildCount + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetType0Count() uint64 { + if x != nil { + return x.Type0Count + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetType1Count() uint64 { + if x != nil { + return x.Type1Count + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetType2Count() uint64 { + if x != nil { + return x.Type2Count + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetType3Count() uint64 { + if x != nil { + return x.Type3Count + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetType4Count() uint64 { + if x != nil { + return x.Type4Count + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetTypeOtherCount() uint64 { + if x != nil { + return x.TypeOtherCount + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetBlobCount() uint64 { + if x != nil { + return x.BlobCount + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetContractCreationCount() uint64 { + if x != nil { + return x.ContractCreationCount + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetCancelShapeCount() uint64 { + if x != nil { + return x.CancelShapeCount + } + return 0 +} + +func (x *FctTransactionInclusionHourly) GetUniqueSenders() uint64 { + if x != nil { + return x.UniqueSenders + } + return 0 +} + +// Request for listing fct_transaction_inclusion_hourly records +type ListFctTransactionInclusionHourlyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Filter by hour_start_date_time - Start of the hour period, bucketed by inclusion slot time (PRIMARY KEY - required) + HourStartDateTime *UInt32Filter `protobuf:"bytes,1,opt,name=hour_start_date_time,json=hourStartDateTime,proto3" json:"hour_start_date_time,omitempty"` + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UpdatedDateTime *UInt32Filter `protobuf:"bytes,2,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Filter by included_count - Number of transactions included in canonical blocks this hour (optional) + IncludedCount *UInt64Filter `protobuf:"bytes,3,opt,name=included_count,json=includedCount,proto3" json:"included_count,omitempty"` + // Filter by relay_delivered_count - Included transactions whose block matched a known relay payload-delivered record (optional) + RelayDeliveredCount *UInt64Filter `protobuf:"bytes,4,opt,name=relay_delivered_count,json=relayDeliveredCount,proto3" json:"relay_delivered_count,omitempty"` + // Filter by unknown_build_count - Included transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built (optional) + UnknownBuildCount *UInt64Filter `protobuf:"bytes,5,opt,name=unknown_build_count,json=unknownBuildCount,proto3" json:"unknown_build_count,omitempty"` + // Filter by type0_count - Included legacy type 0 transactions (optional) + Type0Count *UInt64Filter `protobuf:"bytes,6,opt,name=type0_count,json=type0Count,proto3" json:"type0_count,omitempty"` + // Filter by type1_count - Included access list type 1 transactions (optional) + Type1Count *UInt64Filter `protobuf:"bytes,7,opt,name=type1_count,json=type1Count,proto3" json:"type1_count,omitempty"` + // Filter by type2_count - Included dynamic fee type 2 transactions (optional) + Type2Count *UInt64Filter `protobuf:"bytes,8,opt,name=type2_count,json=type2Count,proto3" json:"type2_count,omitempty"` + // Filter by type3_count - Included blob type 3 transactions (optional) + Type3Count *UInt64Filter `protobuf:"bytes,9,opt,name=type3_count,json=type3Count,proto3" json:"type3_count,omitempty"` + // Filter by type4_count - Included set code type 4 transactions (optional) + Type4Count *UInt64Filter `protobuf:"bytes,10,opt,name=type4_count,json=type4Count,proto3" json:"type4_count,omitempty"` + // Filter by type_other_count - Included transactions of any other type (optional) + TypeOtherCount *UInt64Filter `protobuf:"bytes,11,opt,name=type_other_count,json=typeOtherCount,proto3" json:"type_other_count,omitempty"` + // Filter by blob_count - Total blob commitments across included transactions this hour (optional) + BlobCount *UInt64Filter `protobuf:"bytes,12,opt,name=blob_count,json=blobCount,proto3" json:"blob_count,omitempty"` + // Filter by contract_creation_count - Included transactions with no recipient address (optional) + ContractCreationCount *UInt64Filter `protobuf:"bytes,13,opt,name=contract_creation_count,json=contractCreationCount,proto3" json:"contract_creation_count,omitempty"` + // Filter by cancel_shape_count - Included transactions that are self-transfers of zero value, the common wallet cancellation pattern (optional) + CancelShapeCount *UInt64Filter `protobuf:"bytes,14,opt,name=cancel_shape_count,json=cancelShapeCount,proto3" json:"cancel_shape_count,omitempty"` + // Filter by unique_senders - Distinct sender addresses across included transactions this hour (optional) + UniqueSenders *UInt64Filter `protobuf:"bytes,15,opt,name=unique_senders,json=uniqueSenders,proto3" json:"unique_senders,omitempty"` + // The maximum number of fct_transaction_inclusion_hourly to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + PageSize int32 `protobuf:"varint,16,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // A page token, received from a previous `ListFctTransactionInclusionHourly` call. + // Provide this to retrieve the subsequent page. + PageToken string `protobuf:"bytes,17,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + OrderBy string `protobuf:"bytes,18,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"` +} + +func (x *ListFctTransactionInclusionHourlyRequest) Reset() { + *x = ListFctTransactionInclusionHourlyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_hourly_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionInclusionHourlyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionInclusionHourlyRequest) ProtoMessage() {} + +func (x *ListFctTransactionInclusionHourlyRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_hourly_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionInclusionHourlyRequest.ProtoReflect.Descriptor instead. +func (*ListFctTransactionInclusionHourlyRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_hourly_proto_rawDescGZIP(), []int{1} +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetHourStartDateTime() *UInt32Filter { + if x != nil { + return x.HourStartDateTime + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetUpdatedDateTime() *UInt32Filter { + if x != nil { + return x.UpdatedDateTime + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetIncludedCount() *UInt64Filter { + if x != nil { + return x.IncludedCount + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetRelayDeliveredCount() *UInt64Filter { + if x != nil { + return x.RelayDeliveredCount + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetUnknownBuildCount() *UInt64Filter { + if x != nil { + return x.UnknownBuildCount + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetType0Count() *UInt64Filter { + if x != nil { + return x.Type0Count + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetType1Count() *UInt64Filter { + if x != nil { + return x.Type1Count + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetType2Count() *UInt64Filter { + if x != nil { + return x.Type2Count + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetType3Count() *UInt64Filter { + if x != nil { + return x.Type3Count + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetType4Count() *UInt64Filter { + if x != nil { + return x.Type4Count + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetTypeOtherCount() *UInt64Filter { + if x != nil { + return x.TypeOtherCount + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetBlobCount() *UInt64Filter { + if x != nil { + return x.BlobCount + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetContractCreationCount() *UInt64Filter { + if x != nil { + return x.ContractCreationCount + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetCancelShapeCount() *UInt64Filter { + if x != nil { + return x.CancelShapeCount + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetUniqueSenders() *UInt64Filter { + if x != nil { + return x.UniqueSenders + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +func (x *ListFctTransactionInclusionHourlyRequest) GetOrderBy() string { + if x != nil { + return x.OrderBy + } + return "" +} + +// Response for listing fct_transaction_inclusion_hourly records +type ListFctTransactionInclusionHourlyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of fct_transaction_inclusion_hourly. + FctTransactionInclusionHourly []*FctTransactionInclusionHourly `protobuf:"bytes,1,rep,name=fct_transaction_inclusion_hourly,json=fctTransactionInclusionHourly,proto3" json:"fct_transaction_inclusion_hourly,omitempty"` + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` +} + +func (x *ListFctTransactionInclusionHourlyResponse) Reset() { + *x = ListFctTransactionInclusionHourlyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_hourly_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionInclusionHourlyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionInclusionHourlyResponse) ProtoMessage() {} + +func (x *ListFctTransactionInclusionHourlyResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_hourly_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionInclusionHourlyResponse.ProtoReflect.Descriptor instead. +func (*ListFctTransactionInclusionHourlyResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_hourly_proto_rawDescGZIP(), []int{2} +} + +func (x *ListFctTransactionInclusionHourlyResponse) GetFctTransactionInclusionHourly() []*FctTransactionInclusionHourly { + if x != nil { + return x.FctTransactionInclusionHourly + } + return nil +} + +func (x *ListFctTransactionInclusionHourlyResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +// Request for getting a single fct_transaction_inclusion_hourly record by primary key +type GetFctTransactionInclusionHourlyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Start of the hour period, bucketed by inclusion slot time + HourStartDateTime uint32 `protobuf:"varint,1,opt,name=hour_start_date_time,json=hourStartDateTime,proto3" json:"hour_start_date_time,omitempty"` // Primary key (required) +} + +func (x *GetFctTransactionInclusionHourlyRequest) Reset() { + *x = GetFctTransactionInclusionHourlyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_hourly_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionInclusionHourlyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionInclusionHourlyRequest) ProtoMessage() {} + +func (x *GetFctTransactionInclusionHourlyRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_hourly_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionInclusionHourlyRequest.ProtoReflect.Descriptor instead. +func (*GetFctTransactionInclusionHourlyRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_hourly_proto_rawDescGZIP(), []int{3} +} + +func (x *GetFctTransactionInclusionHourlyRequest) GetHourStartDateTime() uint32 { + if x != nil { + return x.HourStartDateTime + } + return 0 +} + +// Response for getting a single fct_transaction_inclusion_hourly record +type GetFctTransactionInclusionHourlyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *FctTransactionInclusionHourly `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *GetFctTransactionInclusionHourlyResponse) Reset() { + *x = GetFctTransactionInclusionHourlyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_inclusion_hourly_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionInclusionHourlyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionInclusionHourlyResponse) ProtoMessage() {} + +func (x *GetFctTransactionInclusionHourlyResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_inclusion_hourly_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionInclusionHourlyResponse.ProtoReflect.Descriptor instead. +func (*GetFctTransactionInclusionHourlyResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_inclusion_hourly_proto_rawDescGZIP(), []int{4} +} + +func (x *GetFctTransactionInclusionHourlyResponse) GetItem() *FctTransactionInclusionHourly { + if x != nil { + return x.Item + } + return nil +} + +var File_fct_transaction_inclusion_hourly_proto protoreflect.FileDescriptor + +var file_fct_transaction_inclusion_hourly_proto_rawDesc = []byte{ + 0x0a, 0x26, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, 0x75, 0x72, + 0x6c, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x63, 0x62, 0x74, 0x1a, 0x0c, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, + 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x63, 0x6c, 0x69, 0x63, + 0x6b, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x82, 0x05, 0x0a, 0x1d, 0x46, 0x63, 0x74, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, + 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, + 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x14, 0x68, 0x6f, 0x75, 0x72, 0x5f, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x68, 0x6f, 0x75, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, + 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x32, + 0x0a, 0x15, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, + 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x72, + 0x65, 0x6c, 0x61, 0x79, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, 0x64, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x62, 0x75, + 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x11, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x30, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x30, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x31, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x31, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x32, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x32, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x33, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, + 0x33, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x34, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x79, 0x70, + 0x65, 0x34, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x79, 0x70, 0x65, 0x5f, + 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0e, 0x74, 0x79, 0x70, 0x65, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x16, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x62, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x15, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, + 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x18, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x70, + 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, + 0x5f, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, + 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x22, 0xea, 0x08, + 0x0a, 0x28, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, + 0x72, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x14, 0x68, 0x6f, + 0x75, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, + 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x12, 0xe0, 0x41, 0x02, + 0x9a, 0xb5, 0x18, 0x0b, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x52, + 0x11, 0x68, 0x6f, 0x75, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x42, 0x0a, 0x11, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, + 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, + 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4a, 0x0a, 0x15, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x64, + 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, + 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x13, 0x72, 0x65, + 0x6c, 0x61, 0x79, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x46, 0x0a, 0x13, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x11, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, + 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x74, 0x79, 0x70, + 0x65, 0x30, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x30, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x31, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, + 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x0a, 0x74, 0x79, 0x70, 0x65, 0x31, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x74, + 0x79, 0x70, 0x65, 0x32, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x32, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x33, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, + 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, + 0x01, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x33, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, 0x0a, + 0x0b, 0x74, 0x79, 0x70, 0x65, 0x34, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, + 0x34, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x10, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0e, 0x74, 0x79, 0x70, 0x65, 0x4f, 0x74, + 0x68, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x62, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, + 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, + 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x62, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x4e, 0x0a, 0x17, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x15, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x63, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x44, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x10, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x70, 0x65, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x0e, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, + 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x53, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x73, 0x12, 0x20, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x70, 0x61, + 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1e, 0x0a, 0x08, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, + 0x01, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, 0xc0, 0x01, 0x0a, 0x29, 0x4c, + 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x20, 0x66, 0x63, 0x74, 0x5f, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x63, 0x6c, + 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, + 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x1d, 0x66, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x48, + 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x5a, 0x0a, + 0x27, 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x14, 0x68, 0x6f, 0x75, 0x72, + 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x68, 0x6f, 0x75, 0x72, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x62, 0x0a, 0x28, 0x47, 0x65, 0x74, + 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, + 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, + 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0xee, 0x02, + 0x0a, 0x24, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x2d, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, + 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, + 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, + 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, + 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, + 0x12, 0xab, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x2c, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x47, + 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x47, 0x65, 0x74, + 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, + 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x47, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x41, 0x12, 0x3f, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, + 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x2f, 0x7b, 0x68, 0x6f, 0x75, 0x72, 0x5f, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x7d, 0x42, 0x36, + 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, + 0x70, 0x61, 0x6e, 0x64, 0x61, 0x6f, 0x70, 0x73, 0x2f, 0x78, 0x61, 0x74, 0x75, 0x2d, 0x63, 0x62, + 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x63, + 0x6b, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_fct_transaction_inclusion_hourly_proto_rawDescOnce sync.Once + file_fct_transaction_inclusion_hourly_proto_rawDescData = file_fct_transaction_inclusion_hourly_proto_rawDesc +) + +func file_fct_transaction_inclusion_hourly_proto_rawDescGZIP() []byte { + file_fct_transaction_inclusion_hourly_proto_rawDescOnce.Do(func() { + file_fct_transaction_inclusion_hourly_proto_rawDescData = protoimpl.X.CompressGZIP(file_fct_transaction_inclusion_hourly_proto_rawDescData) + }) + return file_fct_transaction_inclusion_hourly_proto_rawDescData +} + +var file_fct_transaction_inclusion_hourly_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_fct_transaction_inclusion_hourly_proto_goTypes = []any{ + (*FctTransactionInclusionHourly)(nil), // 0: cbt.FctTransactionInclusionHourly + (*ListFctTransactionInclusionHourlyRequest)(nil), // 1: cbt.ListFctTransactionInclusionHourlyRequest + (*ListFctTransactionInclusionHourlyResponse)(nil), // 2: cbt.ListFctTransactionInclusionHourlyResponse + (*GetFctTransactionInclusionHourlyRequest)(nil), // 3: cbt.GetFctTransactionInclusionHourlyRequest + (*GetFctTransactionInclusionHourlyResponse)(nil), // 4: cbt.GetFctTransactionInclusionHourlyResponse + (*UInt32Filter)(nil), // 5: cbt.UInt32Filter + (*UInt64Filter)(nil), // 6: cbt.UInt64Filter +} +var file_fct_transaction_inclusion_hourly_proto_depIdxs = []int32{ + 5, // 0: cbt.ListFctTransactionInclusionHourlyRequest.hour_start_date_time:type_name -> cbt.UInt32Filter + 5, // 1: cbt.ListFctTransactionInclusionHourlyRequest.updated_date_time:type_name -> cbt.UInt32Filter + 6, // 2: cbt.ListFctTransactionInclusionHourlyRequest.included_count:type_name -> cbt.UInt64Filter + 6, // 3: cbt.ListFctTransactionInclusionHourlyRequest.relay_delivered_count:type_name -> cbt.UInt64Filter + 6, // 4: cbt.ListFctTransactionInclusionHourlyRequest.unknown_build_count:type_name -> cbt.UInt64Filter + 6, // 5: cbt.ListFctTransactionInclusionHourlyRequest.type0_count:type_name -> cbt.UInt64Filter + 6, // 6: cbt.ListFctTransactionInclusionHourlyRequest.type1_count:type_name -> cbt.UInt64Filter + 6, // 7: cbt.ListFctTransactionInclusionHourlyRequest.type2_count:type_name -> cbt.UInt64Filter + 6, // 8: cbt.ListFctTransactionInclusionHourlyRequest.type3_count:type_name -> cbt.UInt64Filter + 6, // 9: cbt.ListFctTransactionInclusionHourlyRequest.type4_count:type_name -> cbt.UInt64Filter + 6, // 10: cbt.ListFctTransactionInclusionHourlyRequest.type_other_count:type_name -> cbt.UInt64Filter + 6, // 11: cbt.ListFctTransactionInclusionHourlyRequest.blob_count:type_name -> cbt.UInt64Filter + 6, // 12: cbt.ListFctTransactionInclusionHourlyRequest.contract_creation_count:type_name -> cbt.UInt64Filter + 6, // 13: cbt.ListFctTransactionInclusionHourlyRequest.cancel_shape_count:type_name -> cbt.UInt64Filter + 6, // 14: cbt.ListFctTransactionInclusionHourlyRequest.unique_senders:type_name -> cbt.UInt64Filter + 0, // 15: cbt.ListFctTransactionInclusionHourlyResponse.fct_transaction_inclusion_hourly:type_name -> cbt.FctTransactionInclusionHourly + 0, // 16: cbt.GetFctTransactionInclusionHourlyResponse.item:type_name -> cbt.FctTransactionInclusionHourly + 1, // 17: cbt.FctTransactionInclusionHourlyService.List:input_type -> cbt.ListFctTransactionInclusionHourlyRequest + 3, // 18: cbt.FctTransactionInclusionHourlyService.Get:input_type -> cbt.GetFctTransactionInclusionHourlyRequest + 2, // 19: cbt.FctTransactionInclusionHourlyService.List:output_type -> cbt.ListFctTransactionInclusionHourlyResponse + 4, // 20: cbt.FctTransactionInclusionHourlyService.Get:output_type -> cbt.GetFctTransactionInclusionHourlyResponse + 19, // [19:21] is the sub-list for method output_type + 17, // [17:19] is the sub-list for method input_type + 17, // [17:17] is the sub-list for extension type_name + 17, // [17:17] is the sub-list for extension extendee + 0, // [0:17] is the sub-list for field type_name +} + +func init() { file_fct_transaction_inclusion_hourly_proto_init() } +func file_fct_transaction_inclusion_hourly_proto_init() { + if File_fct_transaction_inclusion_hourly_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_fct_transaction_inclusion_hourly_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*FctTransactionInclusionHourly); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_inclusion_hourly_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionInclusionHourlyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_inclusion_hourly_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionInclusionHourlyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_inclusion_hourly_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionInclusionHourlyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_inclusion_hourly_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionInclusionHourlyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_fct_transaction_inclusion_hourly_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_fct_transaction_inclusion_hourly_proto_goTypes, + DependencyIndexes: file_fct_transaction_inclusion_hourly_proto_depIdxs, + MessageInfos: file_fct_transaction_inclusion_hourly_proto_msgTypes, + }.Build() + File_fct_transaction_inclusion_hourly_proto = out.File + file_fct_transaction_inclusion_hourly_proto_rawDesc = nil + file_fct_transaction_inclusion_hourly_proto_goTypes = nil + file_fct_transaction_inclusion_hourly_proto_depIdxs = nil +} diff --git a/pkg/proto/clickhouse/fct_transaction_inclusion_hourly.proto b/pkg/proto/clickhouse/fct_transaction_inclusion_hourly.proto new file mode 100644 index 00000000..8bd49b2c --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_inclusion_hourly.proto @@ -0,0 +1,127 @@ +syntax = "proto3"; + +package cbt; + +import "common.proto"; +import "google/api/annotations.proto"; +import "google/api/field_behavior.proto"; +import "clickhouse/annotations.proto"; + +option go_package = "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse"; +// Hourly counts of transactions included in canonical blocks, split by build path and transaction type + +message FctTransactionInclusionHourly { + // Timestamp when the record was last updated + uint32 updated_date_time = 11; + // Start of the hour period, bucketed by inclusion slot time + uint32 hour_start_date_time = 12; + // Number of transactions included in canonical blocks this hour + uint64 included_count = 13; + // Included transactions whose block matched a known relay payload-delivered record + uint64 relay_delivered_count = 14; + // Included transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built + uint64 unknown_build_count = 15; + // Included legacy type 0 transactions + uint64 type0_count = 16; + // Included access list type 1 transactions + uint64 type1_count = 17; + // Included dynamic fee type 2 transactions + uint64 type2_count = 18; + // Included blob type 3 transactions + uint64 type3_count = 19; + // Included set code type 4 transactions + uint64 type4_count = 20; + // Included transactions of any other type + uint64 type_other_count = 21; + // Total blob commitments across included transactions this hour + uint64 blob_count = 22; + // Included transactions with no recipient address + uint64 contract_creation_count = 23; + // Included transactions that are self-transfers of zero value, the common wallet cancellation pattern + uint64 cancel_shape_count = 24; + // Distinct sender addresses across included transactions this hour + uint64 unique_senders = 25; +} + +// Request for listing fct_transaction_inclusion_hourly records +message ListFctTransactionInclusionHourlyRequest { + // Filter by hour_start_date_time - Start of the hour period, bucketed by inclusion slot time (PRIMARY KEY - required) + UInt32Filter hour_start_date_time = 1 [(google.api.field_behavior) = REQUIRED, (clickhouse.v1.required_group) = "primary_key"]; + + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UInt32Filter updated_date_time = 2 [(google.api.field_behavior) = OPTIONAL]; + // Filter by included_count - Number of transactions included in canonical blocks this hour (optional) + UInt64Filter included_count = 3 [(google.api.field_behavior) = OPTIONAL]; + // Filter by relay_delivered_count - Included transactions whose block matched a known relay payload-delivered record (optional) + UInt64Filter relay_delivered_count = 4 [(google.api.field_behavior) = OPTIONAL]; + // Filter by unknown_build_count - Included transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built (optional) + UInt64Filter unknown_build_count = 5 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type0_count - Included legacy type 0 transactions (optional) + UInt64Filter type0_count = 6 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type1_count - Included access list type 1 transactions (optional) + UInt64Filter type1_count = 7 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type2_count - Included dynamic fee type 2 transactions (optional) + UInt64Filter type2_count = 8 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type3_count - Included blob type 3 transactions (optional) + UInt64Filter type3_count = 9 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type4_count - Included set code type 4 transactions (optional) + UInt64Filter type4_count = 10 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type_other_count - Included transactions of any other type (optional) + UInt64Filter type_other_count = 11 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_count - Total blob commitments across included transactions this hour (optional) + UInt64Filter blob_count = 12 [(google.api.field_behavior) = OPTIONAL]; + // Filter by contract_creation_count - Included transactions with no recipient address (optional) + UInt64Filter contract_creation_count = 13 [(google.api.field_behavior) = OPTIONAL]; + // Filter by cancel_shape_count - Included transactions that are self-transfers of zero value, the common wallet cancellation pattern (optional) + UInt64Filter cancel_shape_count = 14 [(google.api.field_behavior) = OPTIONAL]; + // Filter by unique_senders - Distinct sender addresses across included transactions this hour (optional) + UInt64Filter unique_senders = 15 [(google.api.field_behavior) = OPTIONAL]; + + // The maximum number of fct_transaction_inclusion_hourly to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + int32 page_size = 16 [(google.api.field_behavior) = OPTIONAL]; + // A page token, received from a previous `ListFctTransactionInclusionHourly` call. + // Provide this to retrieve the subsequent page. + string page_token = 17 [(google.api.field_behavior) = OPTIONAL]; + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + string order_by = 18 [(google.api.field_behavior) = OPTIONAL]; +} + +// Response for listing fct_transaction_inclusion_hourly records +message ListFctTransactionInclusionHourlyResponse { + // The list of fct_transaction_inclusion_hourly. + repeated FctTransactionInclusionHourly fct_transaction_inclusion_hourly = 1; + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; +} + +// Request for getting a single fct_transaction_inclusion_hourly record by primary key +message GetFctTransactionInclusionHourlyRequest { + // Start of the hour period, bucketed by inclusion slot time + uint32 hour_start_date_time = 1; // Primary key (required) +} + +// Response for getting a single fct_transaction_inclusion_hourly record +message GetFctTransactionInclusionHourlyResponse { + FctTransactionInclusionHourly item = 1; +} + +// Query fct_transaction_inclusion_hourly data +service FctTransactionInclusionHourlyService { + // List records | Retrieve paginated results with optional filtering + rpc List(ListFctTransactionInclusionHourlyRequest) returns (ListFctTransactionInclusionHourlyResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_inclusion_hourly" + }; + } + // Get record | Retrieve a single record by hour_start_date_time + rpc Get(GetFctTransactionInclusionHourlyRequest) returns (GetFctTransactionInclusionHourlyResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_inclusion_hourly/{hour_start_date_time}" + }; + } +} diff --git a/pkg/proto/clickhouse/fct_transaction_mempool_outcome_7d.go b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_7d.go new file mode 100644 index 00000000..6959d944 --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_7d.go @@ -0,0 +1,1112 @@ +// Code generated by clickhouse-proto-gen. DO NOT EDIT. +// SQL query builder for fct_transaction_mempool_outcome_7d + +package clickhouse + +import ( + "fmt" +) + +// BuildListFctTransactionMempoolOutcome7DQuery constructs a parameterized SQL query from a ListFctTransactionMempoolOutcome7DRequest +// +// Available projections: +// - p_by_hash (primary key: hash) +// - p_by_nonce_group (primary key: from) +// +// Use WithProjection() option to select a specific projection. +func BuildListFctTransactionMempoolOutcome7DQuery(req *ListFctTransactionMempoolOutcome7DRequest, options ...QueryOption) (SQLQuery, error) { + // Validate that at least one primary key is provided + // Primary keys can come from base table or projections + if req.FirstSeenDateTime == nil && req.From == nil && req.Hash == nil { + return SQLQuery{}, fmt.Errorf("at least one primary key field is required: first_seen_date_time, from, hash") + } + + // Build query using QueryBuilder + qb := NewQueryBuilder() + + // Add primary key filter + if req.FirstSeenDateTime != nil { + switch filter := req.FirstSeenDateTime.Filter.(type) { + case *Int64Filter_Eq: + qb.AddCondition("first_seen_date_time", "=", DateTime64Value{uint64(filter.Eq)}) + case *Int64Filter_Ne: + qb.AddCondition("first_seen_date_time", "!=", DateTime64Value{uint64(filter.Ne)}) + case *Int64Filter_Lt: + qb.AddCondition("first_seen_date_time", "<", DateTime64Value{uint64(filter.Lt)}) + case *Int64Filter_Lte: + qb.AddCondition("first_seen_date_time", "<=", DateTime64Value{uint64(filter.Lte)}) + case *Int64Filter_Gt: + qb.AddCondition("first_seen_date_time", ">", DateTime64Value{uint64(filter.Gt)}) + case *Int64Filter_Gte: + qb.AddCondition("first_seen_date_time", ">=", DateTime64Value{uint64(filter.Gte)}) + case *Int64Filter_Between: + qb.AddBetweenCondition("first_seen_date_time", DateTime64Value{uint64(filter.Between.Min)}, DateTime64Value{uint64(filter.Between.Max.GetValue())}) + case *Int64Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddInCondition("first_seen_date_time", converted) + } + case *Int64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddNotInCondition("first_seen_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: updated_date_time + if req.UpdatedDateTime != nil { + switch filter := req.UpdatedDateTime.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("updated_date_time", "=", DateTimeValue{filter.Eq}) + case *UInt32Filter_Ne: + qb.AddCondition("updated_date_time", "!=", DateTimeValue{filter.Ne}) + case *UInt32Filter_Lt: + qb.AddCondition("updated_date_time", "<", DateTimeValue{filter.Lt}) + case *UInt32Filter_Lte: + qb.AddCondition("updated_date_time", "<=", DateTimeValue{filter.Lte}) + case *UInt32Filter_Gt: + qb.AddCondition("updated_date_time", ">", DateTimeValue{filter.Gt}) + case *UInt32Filter_Gte: + qb.AddCondition("updated_date_time", ">=", DateTimeValue{filter.Gte}) + case *UInt32Filter_Between: + qb.AddBetweenCondition("updated_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("updated_date_time", converted) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("updated_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: hash + if req.Hash != nil { + switch filter := req.Hash.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("hash", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("hash", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("hash", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("hash", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("hash", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("hash", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("hash", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("hash", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("hash", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: from + if req.From != nil { + switch filter := req.From.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("from", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("from", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("from", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("from", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("from", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("from", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("from", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("from", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("from", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: to + if req.To != nil { + switch filter := req.To.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("to", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("to", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("to", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("to", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("to", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("to", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("to", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("to", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("to", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("to") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("to") + default: + // Unsupported filter type + } + } + + // Add filter for column: nonce + if req.Nonce != nil { + switch filter := req.Nonce.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("nonce", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("nonce", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("nonce", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("nonce", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("nonce", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("nonce", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("nonce", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("nonce", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("nonce", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type + if req.Type != nil { + switch filter := req.Type.Filter.(type) { + case *NullableUInt32Filter_Eq: + qb.AddCondition("type", "=", filter.Eq) + case *NullableUInt32Filter_Ne: + qb.AddCondition("type", "!=", filter.Ne) + case *NullableUInt32Filter_Lt: + qb.AddCondition("type", "<", filter.Lt) + case *NullableUInt32Filter_Lte: + qb.AddCondition("type", "<=", filter.Lte) + case *NullableUInt32Filter_Gt: + qb.AddCondition("type", ">", filter.Gt) + case *NullableUInt32Filter_Gte: + qb.AddCondition("type", ">=", filter.Gte) + case *NullableUInt32Filter_Between: + qb.AddBetweenCondition("type", filter.Between.Min, filter.Between.Max.GetValue()) + case *NullableUInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type", UInt32SliceToInterface(filter.In.Values)) + } + case *NullableUInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type", UInt32SliceToInterface(filter.NotIn.Values)) + } + case *NullableUInt32Filter_IsNull: + qb.AddIsNullCondition("type") + case *NullableUInt32Filter_IsNotNull: + qb.AddIsNotNullCondition("type") + default: + // Unsupported filter type + } + } + + // Add filter for column: gas + if req.Gas != nil { + switch filter := req.Gas.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("gas", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("gas", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("gas", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("gas", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("gas", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("gas", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("gas", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_price + if req.GasPrice != nil { + switch filter := req.GasPrice.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("gas_price", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("gas_price", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("gas_price", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("gas_price", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("gas_price", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("gas_price", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("gas_price", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_price", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_price", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_tip_cap + if req.GasTipCap != nil { + switch filter := req.GasTipCap.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("gas_tip_cap", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("gas_tip_cap", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("gas_tip_cap", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("gas_tip_cap", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("gas_tip_cap", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("gas_tip_cap", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("gas_tip_cap", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_tip_cap", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_tip_cap", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("gas_tip_cap") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("gas_tip_cap") + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_fee_cap + if req.GasFeeCap != nil { + switch filter := req.GasFeeCap.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("gas_fee_cap", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("gas_fee_cap", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("gas_fee_cap", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("gas_fee_cap", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("gas_fee_cap", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("gas_fee_cap", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("gas_fee_cap", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_fee_cap", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_fee_cap", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("gas_fee_cap") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("gas_fee_cap") + default: + // Unsupported filter type + } + } + + // Add filter for column: value + if req.Value != nil { + switch filter := req.Value.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("value", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("value", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("value", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("value", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("value", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("value", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("value", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("value", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("value", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: size + if req.Size != nil { + switch filter := req.Size.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("size", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("size", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("size", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("size", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("size", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("size", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("size", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("size", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("size", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: call_data_size + if req.CallDataSize != nil { + switch filter := req.CallDataSize.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("call_data_size", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("call_data_size", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("call_data_size", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("call_data_size", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("call_data_size", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("call_data_size", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("call_data_size", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("call_data_size", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("call_data_size", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_gas + if req.BlobGas != nil { + switch filter := req.BlobGas.Filter.(type) { + case *NullableUInt64Filter_Eq: + qb.AddCondition("blob_gas", "=", filter.Eq) + case *NullableUInt64Filter_Ne: + qb.AddCondition("blob_gas", "!=", filter.Ne) + case *NullableUInt64Filter_Lt: + qb.AddCondition("blob_gas", "<", filter.Lt) + case *NullableUInt64Filter_Lte: + qb.AddCondition("blob_gas", "<=", filter.Lte) + case *NullableUInt64Filter_Gt: + qb.AddCondition("blob_gas", ">", filter.Gt) + case *NullableUInt64Filter_Gte: + qb.AddCondition("blob_gas", ">=", filter.Gte) + case *NullableUInt64Filter_Between: + qb.AddBetweenCondition("blob_gas", filter.Between.Min, filter.Between.Max.GetValue()) + case *NullableUInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("blob_gas", UInt64SliceToInterface(filter.In.Values)) + } + case *NullableUInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("blob_gas", UInt64SliceToInterface(filter.NotIn.Values)) + } + case *NullableUInt64Filter_IsNull: + qb.AddIsNullCondition("blob_gas") + case *NullableUInt64Filter_IsNotNull: + qb.AddIsNotNullCondition("blob_gas") + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_gas_fee_cap + if req.BlobGasFeeCap != nil { + switch filter := req.BlobGasFeeCap.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("blob_gas_fee_cap", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("blob_gas_fee_cap", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("blob_gas_fee_cap", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("blob_gas_fee_cap", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("blob_gas_fee_cap", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("blob_gas_fee_cap", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("blob_gas_fee_cap", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("blob_gas_fee_cap", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("blob_gas_fee_cap", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("blob_gas_fee_cap") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("blob_gas_fee_cap") + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_hashes + if req.BlobHashes != nil { + switch filter := req.BlobHashes.Filter.(type) { + case *ArrayStringFilter_Has: + qb.AddArrayHasCondition("blob_hashes", filter.Has) + case *ArrayStringFilter_HasAll: + if len(filter.HasAll.Values) > 0 { + qb.AddArrayHasAllCondition("blob_hashes", StringSliceToInterface(filter.HasAll.Values)) + } + case *ArrayStringFilter_HasAny: + if len(filter.HasAny.Values) > 0 { + qb.AddArrayHasAnyCondition("blob_hashes", StringSliceToInterface(filter.HasAny.Values)) + } + case *ArrayStringFilter_LengthEq: + qb.AddArrayLengthCondition("blob_hashes", "=", filter.LengthEq) + case *ArrayStringFilter_LengthGt: + qb.AddArrayLengthCondition("blob_hashes", ">", filter.LengthGt) + case *ArrayStringFilter_LengthGte: + qb.AddArrayLengthCondition("blob_hashes", ">=", filter.LengthGte) + case *ArrayStringFilter_LengthLt: + qb.AddArrayLengthCondition("blob_hashes", "<", filter.LengthLt) + case *ArrayStringFilter_LengthLte: + qb.AddArrayLengthCondition("blob_hashes", "<=", filter.LengthLte) + case *ArrayStringFilter_IsEmpty: + qb.AddArrayIsEmptyCondition("blob_hashes") + case *ArrayStringFilter_IsNotEmpty: + qb.AddArrayIsNotEmptyCondition("blob_hashes") + default: + // Unsupported filter type + } + } + + // Add filter for column: is_cancel_shape + if req.IsCancelShape != nil { + switch filter := req.IsCancelShape.Filter.(type) { + case *BoolFilter_Eq: + qb.AddCondition("is_cancel_shape", "=", filter.Eq) + case *BoolFilter_Ne: + qb.AddCondition("is_cancel_shape", "!=", filter.Ne) + default: + // Unsupported filter type + } + } + + // Add filter for column: last_seen_date_time + if req.LastSeenDateTime != nil { + switch filter := req.LastSeenDateTime.Filter.(type) { + case *Int64Filter_Eq: + qb.AddCondition("last_seen_date_time", "=", DateTime64Value{uint64(filter.Eq)}) + case *Int64Filter_Ne: + qb.AddCondition("last_seen_date_time", "!=", DateTime64Value{uint64(filter.Ne)}) + case *Int64Filter_Lt: + qb.AddCondition("last_seen_date_time", "<", DateTime64Value{uint64(filter.Lt)}) + case *Int64Filter_Lte: + qb.AddCondition("last_seen_date_time", "<=", DateTime64Value{uint64(filter.Lte)}) + case *Int64Filter_Gt: + qb.AddCondition("last_seen_date_time", ">", DateTime64Value{uint64(filter.Gt)}) + case *Int64Filter_Gte: + qb.AddCondition("last_seen_date_time", ">=", DateTime64Value{uint64(filter.Gte)}) + case *Int64Filter_Between: + qb.AddBetweenCondition("last_seen_date_time", DateTime64Value{uint64(filter.Between.Min)}, DateTime64Value{uint64(filter.Between.Max.GetValue())}) + case *Int64Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddInCondition("last_seen_date_time", converted) + } + case *Int64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddNotInCondition("last_seen_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: sighting_count + if req.SightingCount != nil { + switch filter := req.SightingCount.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("sighting_count", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("sighting_count", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("sighting_count", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("sighting_count", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("sighting_count", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("sighting_count", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("sighting_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("sighting_count", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("sighting_count", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: peak_hourly_unique_sentries + if req.PeakHourlyUniqueSentries != nil { + switch filter := req.PeakHourlyUniqueSentries.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("peak_hourly_unique_sentries", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("peak_hourly_unique_sentries", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("peak_hourly_unique_sentries", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("peak_hourly_unique_sentries", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("peak_hourly_unique_sentries", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("peak_hourly_unique_sentries", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("peak_hourly_unique_sentries", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("peak_hourly_unique_sentries", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("peak_hourly_unique_sentries", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: outcome + if req.Outcome != nil { + switch filter := req.Outcome.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("outcome", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("outcome", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("outcome", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("outcome", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("outcome", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("outcome", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("outcome", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("outcome", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("outcome", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: resolution_date_time + if req.ResolutionDateTime != nil { + switch filter := req.ResolutionDateTime.Filter.(type) { + case *Int64Filter_Eq: + qb.AddCondition("resolution_date_time", "=", DateTime64Value{uint64(filter.Eq)}) + case *Int64Filter_Ne: + qb.AddCondition("resolution_date_time", "!=", DateTime64Value{uint64(filter.Ne)}) + case *Int64Filter_Lt: + qb.AddCondition("resolution_date_time", "<", DateTime64Value{uint64(filter.Lt)}) + case *Int64Filter_Lte: + qb.AddCondition("resolution_date_time", "<=", DateTime64Value{uint64(filter.Lte)}) + case *Int64Filter_Gt: + qb.AddCondition("resolution_date_time", ">", DateTime64Value{uint64(filter.Gt)}) + case *Int64Filter_Gte: + qb.AddCondition("resolution_date_time", ">=", DateTime64Value{uint64(filter.Gte)}) + case *Int64Filter_Between: + qb.AddBetweenCondition("resolution_date_time", DateTime64Value{uint64(filter.Between.Min)}, DateTime64Value{uint64(filter.Between.Max.GetValue())}) + case *Int64Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddInCondition("resolution_date_time", converted) + } + case *Int64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddNotInCondition("resolution_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: included_slot + if req.IncludedSlot != nil { + switch filter := req.IncludedSlot.Filter.(type) { + case *NullableUInt32Filter_Eq: + qb.AddCondition("included_slot", "=", filter.Eq) + case *NullableUInt32Filter_Ne: + qb.AddCondition("included_slot", "!=", filter.Ne) + case *NullableUInt32Filter_Lt: + qb.AddCondition("included_slot", "<", filter.Lt) + case *NullableUInt32Filter_Lte: + qb.AddCondition("included_slot", "<=", filter.Lte) + case *NullableUInt32Filter_Gt: + qb.AddCondition("included_slot", ">", filter.Gt) + case *NullableUInt32Filter_Gte: + qb.AddCondition("included_slot", ">=", filter.Gte) + case *NullableUInt32Filter_Between: + qb.AddBetweenCondition("included_slot", filter.Between.Min, filter.Between.Max.GetValue()) + case *NullableUInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("included_slot", UInt32SliceToInterface(filter.In.Values)) + } + case *NullableUInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("included_slot", UInt32SliceToInterface(filter.NotIn.Values)) + } + case *NullableUInt32Filter_IsNull: + qb.AddIsNullCondition("included_slot") + case *NullableUInt32Filter_IsNotNull: + qb.AddIsNotNullCondition("included_slot") + default: + // Unsupported filter type + } + } + + // Add filter for column: included_slot_start_date_time + if req.IncludedSlotStartDateTime != nil { + switch filter := req.IncludedSlotStartDateTime.Filter.(type) { + case *NullableUInt32Filter_IsNull: + qb.AddIsNullCondition("included_slot_start_date_time") + case *NullableUInt32Filter_IsNotNull: + qb.AddIsNotNullCondition("included_slot_start_date_time") + case *NullableUInt32Filter_Eq: + qb.AddCondition("included_slot_start_date_time", "=", DateTimeValue{filter.Eq}) + case *NullableUInt32Filter_Ne: + qb.AddCondition("included_slot_start_date_time", "!=", DateTimeValue{filter.Ne}) + case *NullableUInt32Filter_Lt: + qb.AddCondition("included_slot_start_date_time", "<", DateTimeValue{filter.Lt}) + case *NullableUInt32Filter_Lte: + qb.AddCondition("included_slot_start_date_time", "<=", DateTimeValue{filter.Lte}) + case *NullableUInt32Filter_Gt: + qb.AddCondition("included_slot_start_date_time", ">", DateTimeValue{filter.Gt}) + case *NullableUInt32Filter_Gte: + qb.AddCondition("included_slot_start_date_time", ">=", DateTimeValue{filter.Gte}) + case *NullableUInt32Filter_Between: + qb.AddBetweenCondition("included_slot_start_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *NullableUInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("included_slot_start_date_time", converted) + } + case *NullableUInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("included_slot_start_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: included_block_root + if req.IncludedBlockRoot != nil { + switch filter := req.IncludedBlockRoot.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("included_block_root", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("included_block_root", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("included_block_root", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("included_block_root", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("included_block_root", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("included_block_root", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("included_block_root", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("included_block_root", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("included_block_root", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("included_block_root") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("included_block_root") + default: + // Unsupported filter type + } + } + + // Add filter for column: included_position + if req.IncludedPosition != nil { + switch filter := req.IncludedPosition.Filter.(type) { + case *NullableUInt32Filter_Eq: + qb.AddCondition("included_position", "=", filter.Eq) + case *NullableUInt32Filter_Ne: + qb.AddCondition("included_position", "!=", filter.Ne) + case *NullableUInt32Filter_Lt: + qb.AddCondition("included_position", "<", filter.Lt) + case *NullableUInt32Filter_Lte: + qb.AddCondition("included_position", "<=", filter.Lte) + case *NullableUInt32Filter_Gt: + qb.AddCondition("included_position", ">", filter.Gt) + case *NullableUInt32Filter_Gte: + qb.AddCondition("included_position", ">=", filter.Gte) + case *NullableUInt32Filter_Between: + qb.AddBetweenCondition("included_position", filter.Between.Min, filter.Between.Max.GetValue()) + case *NullableUInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("included_position", UInt32SliceToInterface(filter.In.Values)) + } + case *NullableUInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("included_position", UInt32SliceToInterface(filter.NotIn.Values)) + } + case *NullableUInt32Filter_IsNull: + qb.AddIsNullCondition("included_position") + case *NullableUInt32Filter_IsNotNull: + qb.AddIsNotNullCondition("included_position") + default: + // Unsupported filter type + } + } + + // Add filter for column: wait_ms + if req.WaitMs != nil { + switch filter := req.WaitMs.Filter.(type) { + case *NullableInt64Filter_Eq: + qb.AddCondition("wait_ms", "=", filter.Eq) + case *NullableInt64Filter_Ne: + qb.AddCondition("wait_ms", "!=", filter.Ne) + case *NullableInt64Filter_Lt: + qb.AddCondition("wait_ms", "<", filter.Lt) + case *NullableInt64Filter_Lte: + qb.AddCondition("wait_ms", "<=", filter.Lte) + case *NullableInt64Filter_Gt: + qb.AddCondition("wait_ms", ">", filter.Gt) + case *NullableInt64Filter_Gte: + qb.AddCondition("wait_ms", ">=", filter.Gte) + case *NullableInt64Filter_Between: + qb.AddBetweenCondition("wait_ms", filter.Between.Min, filter.Between.Max.GetValue()) + case *NullableInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("wait_ms", Int64SliceToInterface(filter.In.Values)) + } + case *NullableInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("wait_ms", Int64SliceToInterface(filter.NotIn.Values)) + } + case *NullableInt64Filter_IsNull: + qb.AddIsNullCondition("wait_ms") + case *NullableInt64Filter_IsNotNull: + qb.AddIsNotNullCondition("wait_ms") + default: + // Unsupported filter type + } + } + + // Add filter for column: included_via_known_relay + if req.IncludedViaKnownRelay != nil { + switch filter := req.IncludedViaKnownRelay.Filter.(type) { + case *NullableBoolFilter_Eq: + qb.AddCondition("included_via_known_relay", "=", filter.Eq) + case *NullableBoolFilter_Ne: + qb.AddCondition("included_via_known_relay", "!=", filter.Ne) + case *NullableBoolFilter_IsNull: + qb.AddIsNullCondition("included_via_known_relay") + case *NullableBoolFilter_IsNotNull: + qb.AddIsNotNullCondition("included_via_known_relay") + default: + // Unsupported filter type + } + } + + // Add filter for column: winner_hash + if req.WinnerHash != nil { + switch filter := req.WinnerHash.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("winner_hash", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("winner_hash", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("winner_hash", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("winner_hash", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("winner_hash", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("winner_hash", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("winner_hash", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("winner_hash", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("winner_hash", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("winner_hash") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("winner_hash") + default: + // Unsupported filter type + } + } + + // Add filter for column: winner_slot_start_date_time + if req.WinnerSlotStartDateTime != nil { + switch filter := req.WinnerSlotStartDateTime.Filter.(type) { + case *NullableUInt32Filter_IsNull: + qb.AddIsNullCondition("winner_slot_start_date_time") + case *NullableUInt32Filter_IsNotNull: + qb.AddIsNotNullCondition("winner_slot_start_date_time") + case *NullableUInt32Filter_Eq: + qb.AddCondition("winner_slot_start_date_time", "=", DateTimeValue{filter.Eq}) + case *NullableUInt32Filter_Ne: + qb.AddCondition("winner_slot_start_date_time", "!=", DateTimeValue{filter.Ne}) + case *NullableUInt32Filter_Lt: + qb.AddCondition("winner_slot_start_date_time", "<", DateTimeValue{filter.Lt}) + case *NullableUInt32Filter_Lte: + qb.AddCondition("winner_slot_start_date_time", "<=", DateTimeValue{filter.Lte}) + case *NullableUInt32Filter_Gt: + qb.AddCondition("winner_slot_start_date_time", ">", DateTimeValue{filter.Gt}) + case *NullableUInt32Filter_Gte: + qb.AddCondition("winner_slot_start_date_time", ">=", DateTimeValue{filter.Gte}) + case *NullableUInt32Filter_Between: + qb.AddBetweenCondition("winner_slot_start_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *NullableUInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("winner_slot_start_date_time", converted) + } + case *NullableUInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("winner_slot_start_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: observed_after_nonce_consumed + if req.ObservedAfterNonceConsumed != nil { + switch filter := req.ObservedAfterNonceConsumed.Filter.(type) { + case *BoolFilter_Eq: + qb.AddCondition("observed_after_nonce_consumed", "=", filter.Eq) + case *BoolFilter_Ne: + qb.AddCondition("observed_after_nonce_consumed", "!=", filter.Ne) + default: + // Unsupported filter type + } + } + + // Add filter for column: in_mempool_at_deadline + if req.InMempoolAtDeadline != nil { + switch filter := req.InMempoolAtDeadline.Filter.(type) { + case *BoolFilter_Eq: + qb.AddCondition("in_mempool_at_deadline", "=", filter.Eq) + case *BoolFilter_Ne: + qb.AddCondition("in_mempool_at_deadline", "!=", filter.Ne) + default: + // Unsupported filter type + } + } + + // Handle pagination per AIP-132 + // Validate page size + if req.PageSize < 0 { + return SQLQuery{}, fmt.Errorf("page_size must be non-negative, got %d", req.PageSize) + } + if req.PageSize > 10000 { + return SQLQuery{}, fmt.Errorf("page_size must not exceed %d, got %d", 10000, req.PageSize) + } + + var limit, offset uint32 + limit = 100 // Default page size + if req.PageSize > 0 { + limit = uint32(req.PageSize) + } + if req.PageToken != "" { + decodedOffset, err := DecodePageToken(req.PageToken) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid page_token: %w", err) + } + offset = decodedOffset + } + + // Handle custom ordering if provided + var orderByClause string + if req.OrderBy != "" { + validFields := []string{"updated_date_time", "first_seen_date_time", "hash", "from", "to", "nonce", "type", "gas", "gas_price", "gas_tip_cap", "gas_fee_cap", "value", "size", "call_data_size", "blob_gas", "blob_gas_fee_cap", "blob_hashes", "is_cancel_shape", "last_seen_date_time", "sighting_count", "peak_hourly_unique_sentries", "outcome", "resolution_date_time", "included_slot", "included_slot_start_date_time", "included_block_root", "included_position", "wait_ms", "included_via_known_relay", "winner_hash", "winner_slot_start_date_time", "observed_after_nonce_consumed", "in_mempool_at_deadline"} + orderFields, err := ParseOrderBy(req.OrderBy, validFields) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid order_by: %w", err) + } + orderByClause = BuildOrderByClause(orderFields) + } else { + // Default sorting by primary key + orderByClause = " ORDER BY first_seen_date_time" + ", hash" + } + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toUnixTimestamp64Micro(`first_seen_date_time`) AS `first_seen_date_time`", "NULLIF(`hash`, repeat('\x00', 66)) AS `hash`", "NULLIF(`from`, repeat('\x00', 42)) AS `from`", "NULLIF(`to`, repeat('\x00', 42)) AS `to`", "nonce", "toUInt32(`type`) AS `type`", "gas", "toString(`gas_price`) AS `gas_price`", "toString(`gas_tip_cap`) AS `gas_tip_cap`", "toString(`gas_fee_cap`) AS `gas_fee_cap`", "toString(`value`) AS `value`", "size", "call_data_size", "blob_gas", "toString(`blob_gas_fee_cap`) AS `blob_gas_fee_cap`", "blob_hashes", "is_cancel_shape", "toUnixTimestamp64Micro(`last_seen_date_time`) AS `last_seen_date_time`", "sighting_count", "peak_hourly_unique_sentries", "outcome", "toUnixTimestamp64Micro(`resolution_date_time`) AS `resolution_date_time`", "included_slot", "toUnixTimestamp(`included_slot_start_date_time`) AS `included_slot_start_date_time`", "NULLIF(`included_block_root`, repeat('\x00', 66)) AS `included_block_root`", "included_position", "wait_ms", "included_via_known_relay", "NULLIF(`winner_hash`, repeat('\x00', 66)) AS `winner_hash`", "toUnixTimestamp(`winner_slot_start_date_time`) AS `winner_slot_start_date_time`", "observed_after_nonce_consumed", "in_mempool_at_deadline"} + + return BuildParameterizedQuery("fct_transaction_mempool_outcome_7d", columns, qb, orderByClause, limit, offset, options...) +} + +// BuildGetFctTransactionMempoolOutcome7DQuery constructs a parameterized SQL query from a GetFctTransactionMempoolOutcome7DRequest +func BuildGetFctTransactionMempoolOutcome7DQuery(req *GetFctTransactionMempoolOutcome7DRequest, options ...QueryOption) (SQLQuery, error) { + // Validate primary key is provided + if req.FirstSeenDateTime == 0 { + return SQLQuery{}, fmt.Errorf("primary key field first_seen_date_time is required") + } + + // Build query with primary key condition + qb := NewQueryBuilder() + qb.AddCondition("first_seen_date_time", "=", req.FirstSeenDateTime) + + // Build ORDER BY clause + orderByClause := " ORDER BY first_seen_date_time, hash" + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toUnixTimestamp64Micro(`first_seen_date_time`) AS `first_seen_date_time`", "NULLIF(`hash`, repeat('\x00', 66)) AS `hash`", "NULLIF(`from`, repeat('\x00', 42)) AS `from`", "NULLIF(`to`, repeat('\x00', 42)) AS `to`", "nonce", "toUInt32(`type`) AS `type`", "gas", "toString(`gas_price`) AS `gas_price`", "toString(`gas_tip_cap`) AS `gas_tip_cap`", "toString(`gas_fee_cap`) AS `gas_fee_cap`", "toString(`value`) AS `value`", "size", "call_data_size", "blob_gas", "toString(`blob_gas_fee_cap`) AS `blob_gas_fee_cap`", "blob_hashes", "is_cancel_shape", "toUnixTimestamp64Micro(`last_seen_date_time`) AS `last_seen_date_time`", "sighting_count", "peak_hourly_unique_sentries", "outcome", "toUnixTimestamp64Micro(`resolution_date_time`) AS `resolution_date_time`", "included_slot", "toUnixTimestamp(`included_slot_start_date_time`) AS `included_slot_start_date_time`", "NULLIF(`included_block_root`, repeat('\x00', 66)) AS `included_block_root`", "included_position", "wait_ms", "included_via_known_relay", "NULLIF(`winner_hash`, repeat('\x00', 66)) AS `winner_hash`", "toUnixTimestamp(`winner_slot_start_date_time`) AS `winner_slot_start_date_time`", "observed_after_nonce_consumed", "in_mempool_at_deadline"} + + // Return single record + return BuildParameterizedQuery("fct_transaction_mempool_outcome_7d", columns, qb, orderByClause, 1, 0, options...) +} diff --git a/pkg/proto/clickhouse/fct_transaction_mempool_outcome_7d.pb.go b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_7d.pb.go new file mode 100644 index 00000000..cd3dda04 --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_7d.pb.go @@ -0,0 +1,1393 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc (unknown) +// source: fct_transaction_mempool_outcome_7d.proto + +package clickhouse + +import ( + _ "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse/clickhouse" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type FctTransactionMempoolOutcome7D struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Timestamp when the record was last updated + UpdatedDateTime uint32 `protobuf:"varint,11,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Earliest sighting of the transaction within its observation episode, the anchor of the 7 day horizon + FirstSeenDateTime int64 `protobuf:"varint,12,opt,name=first_seen_date_time,json=firstSeenDateTime,proto3" json:"first_seen_date_time,omitempty"` + // The transaction hash + Hash string `protobuf:"bytes,13,opt,name=hash,proto3" json:"hash,omitempty"` + // The address of the account that sent the transaction + From string `protobuf:"bytes,14,opt,name=from,proto3" json:"from,omitempty"` + // The address of the transaction recipient, null for contract creation + To *wrapperspb.StringValue `protobuf:"bytes,15,opt,name=to,proto3" json:"to,omitempty"` + // The nonce of the sender account at the time of the transaction + Nonce uint64 `protobuf:"varint,16,opt,name=nonce,proto3" json:"nonce,omitempty"` + // The type of the transaction + Type *wrapperspb.UInt32Value `protobuf:"bytes,17,opt,name=type,proto3" json:"type,omitempty"` + // The maximum gas provided for the transaction execution + Gas uint64 `protobuf:"varint,18,opt,name=gas,proto3" json:"gas,omitempty"` + // The gas price of the transaction in wei + GasPrice string `protobuf:"bytes,19,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` + // The priority fee (tip) the user has set for the transaction in wei + GasTipCap *wrapperspb.StringValue `protobuf:"bytes,20,opt,name=gas_tip_cap,json=gasTipCap,proto3" json:"gas_tip_cap,omitempty"` + // The max fee the user has set for the transaction in wei + GasFeeCap *wrapperspb.StringValue `protobuf:"bytes,21,opt,name=gas_fee_cap,json=gasFeeCap,proto3" json:"gas_fee_cap,omitempty"` + // The value transferred with the transaction in wei + Value string `protobuf:"bytes,22,opt,name=value,proto3" json:"value,omitempty"` + // The size of the transaction data in bytes + Size uint32 `protobuf:"varint,23,opt,name=size,proto3" json:"size,omitempty"` + // The size of the call data of the transaction in bytes + CallDataSize uint32 `protobuf:"varint,24,opt,name=call_data_size,json=callDataSize,proto3" json:"call_data_size,omitempty"` + // The maximum gas provided for the blob transaction execution + BlobGas *wrapperspb.UInt64Value `protobuf:"bytes,25,opt,name=blob_gas,json=blobGas,proto3" json:"blob_gas,omitempty"` + // The max blob fee the user has set for the transaction in wei + BlobGasFeeCap *wrapperspb.StringValue `protobuf:"bytes,26,opt,name=blob_gas_fee_cap,json=blobGasFeeCap,proto3" json:"blob_gas_fee_cap,omitempty"` + // The hashes of the blob commitments for blob transactions + BlobHashes []string `protobuf:"bytes,27,rep,name=blob_hashes,json=blobHashes,proto3" json:"blob_hashes,omitempty"` + // Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern + IsCancelShape bool `protobuf:"varint,28,opt,name=is_cancel_shape,json=isCancelShape,proto3" json:"is_cancel_shape,omitempty"` + // Latest sighting of the transaction within the 7 day horizon + LastSeenDateTime int64 `protobuf:"varint,29,opt,name=last_seen_date_time,json=lastSeenDateTime,proto3" json:"last_seen_date_time,omitempty"` + // Number of sightings within the 7 day horizon across all sentries + SightingCount uint32 `protobuf:"varint,30,opt,name=sighting_count,json=sightingCount,proto3" json:"sighting_count,omitempty"` + // Peak number of distinct sentries sighting the transaction within any single hour of the horizon + PeakHourlyUniqueSentries uint32 `protobuf:"varint,31,opt,name=peak_hourly_unique_sentries,json=peakHourlyUniqueSentries,proto3" json:"peak_hourly_unique_sentries,omitempty"` + // Outcome within 7 days of first sighting: included, nonce_consumed (a different transaction with the same from and nonce was included) or unincluded. The statement is fixed to the horizon and remains true even if the transaction is included later + Outcome string `protobuf:"bytes,32,opt,name=outcome,proto3" json:"outcome,omitempty"` + // When the outcome was determined: the inclusion slot start for included, the winner inclusion slot start for nonce_consumed, or first_seen_date_time plus 7 days for unincluded + ResolutionDateTime int64 `protobuf:"varint,33,opt,name=resolution_date_time,json=resolutionDateTime,proto3" json:"resolution_date_time,omitempty"` + // The slot of the beacon block that included the transaction, when outcome is included + IncludedSlot *wrapperspb.UInt32Value `protobuf:"bytes,34,opt,name=included_slot,json=includedSlot,proto3" json:"included_slot,omitempty"` + // The wall clock time when the inclusion slot started, when outcome is included + IncludedSlotStartDateTime *wrapperspb.UInt32Value `protobuf:"bytes,35,opt,name=included_slot_start_date_time,json=includedSlotStartDateTime,proto3" json:"included_slot_start_date_time,omitempty"` + // The beacon block root of the including block, when outcome is included + IncludedBlockRoot *wrapperspb.StringValue `protobuf:"bytes,36,opt,name=included_block_root,json=includedBlockRoot,proto3" json:"included_block_root,omitempty"` + // The position of the transaction in the execution payload, when outcome is included + IncludedPosition *wrapperspb.UInt32Value `protobuf:"bytes,37,opt,name=included_position,json=includedPosition,proto3" json:"included_position,omitempty"` + // Milliseconds from first sighting to the inclusion slot start, when outcome is included. Negative when the transaction was first sighted after its inclusion slot started + WaitMs *wrapperspb.Int64Value `protobuf:"bytes,38,opt,name=wait_ms,json=waitMs,proto3" json:"wait_ms,omitempty"` + // Whether the including block matched a known relay payload-delivered record, when outcome is included. False is not proof the block was locally built + IncludedViaKnownRelay *wrapperspb.BoolValue `protobuf:"bytes,39,opt,name=included_via_known_relay,json=includedViaKnownRelay,proto3" json:"included_via_known_relay,omitempty"` + // The hash of the transaction that consumed the nonce, when outcome is nonce_consumed + WinnerHash *wrapperspb.StringValue `protobuf:"bytes,40,opt,name=winner_hash,json=winnerHash,proto3" json:"winner_hash,omitempty"` + // The wall clock time when the winner inclusion slot started, when outcome is nonce_consumed + WinnerSlotStartDateTime *wrapperspb.UInt32Value `protobuf:"bytes,41,opt,name=winner_slot_start_date_time,json=winnerSlotStartDateTime,proto3" json:"winner_slot_start_date_time,omitempty"` + // Whether the transaction was first sighted after its nonce had already been consumed by another transaction + ObservedAfterNonceConsumed bool `protobuf:"varint,42,opt,name=observed_after_nonce_consumed,json=observedAfterNonceConsumed,proto3" json:"observed_after_nonce_consumed,omitempty"` + // Whether a sighting occurred in the final hour before the 7 day deadline. Sensor evidence of continued circulation, only meaningful when outcome is unincluded + InMempoolAtDeadline bool `protobuf:"varint,43,opt,name=in_mempool_at_deadline,json=inMempoolAtDeadline,proto3" json:"in_mempool_at_deadline,omitempty"` +} + +func (x *FctTransactionMempoolOutcome7D) Reset() { + *x = FctTransactionMempoolOutcome7D{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_7d_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FctTransactionMempoolOutcome7D) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FctTransactionMempoolOutcome7D) ProtoMessage() {} + +func (x *FctTransactionMempoolOutcome7D) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_7d_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FctTransactionMempoolOutcome7D.ProtoReflect.Descriptor instead. +func (*FctTransactionMempoolOutcome7D) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_7d_proto_rawDescGZIP(), []int{0} +} + +func (x *FctTransactionMempoolOutcome7D) GetUpdatedDateTime() uint32 { + if x != nil { + return x.UpdatedDateTime + } + return 0 +} + +func (x *FctTransactionMempoolOutcome7D) GetFirstSeenDateTime() int64 { + if x != nil { + return x.FirstSeenDateTime + } + return 0 +} + +func (x *FctTransactionMempoolOutcome7D) GetHash() string { + if x != nil { + return x.Hash + } + return "" +} + +func (x *FctTransactionMempoolOutcome7D) GetFrom() string { + if x != nil { + return x.From + } + return "" +} + +func (x *FctTransactionMempoolOutcome7D) GetTo() *wrapperspb.StringValue { + if x != nil { + return x.To + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetNonce() uint64 { + if x != nil { + return x.Nonce + } + return 0 +} + +func (x *FctTransactionMempoolOutcome7D) GetType() *wrapperspb.UInt32Value { + if x != nil { + return x.Type + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetGas() uint64 { + if x != nil { + return x.Gas + } + return 0 +} + +func (x *FctTransactionMempoolOutcome7D) GetGasPrice() string { + if x != nil { + return x.GasPrice + } + return "" +} + +func (x *FctTransactionMempoolOutcome7D) GetGasTipCap() *wrapperspb.StringValue { + if x != nil { + return x.GasTipCap + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetGasFeeCap() *wrapperspb.StringValue { + if x != nil { + return x.GasFeeCap + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *FctTransactionMempoolOutcome7D) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *FctTransactionMempoolOutcome7D) GetCallDataSize() uint32 { + if x != nil { + return x.CallDataSize + } + return 0 +} + +func (x *FctTransactionMempoolOutcome7D) GetBlobGas() *wrapperspb.UInt64Value { + if x != nil { + return x.BlobGas + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetBlobGasFeeCap() *wrapperspb.StringValue { + if x != nil { + return x.BlobGasFeeCap + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetBlobHashes() []string { + if x != nil { + return x.BlobHashes + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetIsCancelShape() bool { + if x != nil { + return x.IsCancelShape + } + return false +} + +func (x *FctTransactionMempoolOutcome7D) GetLastSeenDateTime() int64 { + if x != nil { + return x.LastSeenDateTime + } + return 0 +} + +func (x *FctTransactionMempoolOutcome7D) GetSightingCount() uint32 { + if x != nil { + return x.SightingCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcome7D) GetPeakHourlyUniqueSentries() uint32 { + if x != nil { + return x.PeakHourlyUniqueSentries + } + return 0 +} + +func (x *FctTransactionMempoolOutcome7D) GetOutcome() string { + if x != nil { + return x.Outcome + } + return "" +} + +func (x *FctTransactionMempoolOutcome7D) GetResolutionDateTime() int64 { + if x != nil { + return x.ResolutionDateTime + } + return 0 +} + +func (x *FctTransactionMempoolOutcome7D) GetIncludedSlot() *wrapperspb.UInt32Value { + if x != nil { + return x.IncludedSlot + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetIncludedSlotStartDateTime() *wrapperspb.UInt32Value { + if x != nil { + return x.IncludedSlotStartDateTime + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetIncludedBlockRoot() *wrapperspb.StringValue { + if x != nil { + return x.IncludedBlockRoot + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetIncludedPosition() *wrapperspb.UInt32Value { + if x != nil { + return x.IncludedPosition + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetWaitMs() *wrapperspb.Int64Value { + if x != nil { + return x.WaitMs + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetIncludedViaKnownRelay() *wrapperspb.BoolValue { + if x != nil { + return x.IncludedViaKnownRelay + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetWinnerHash() *wrapperspb.StringValue { + if x != nil { + return x.WinnerHash + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetWinnerSlotStartDateTime() *wrapperspb.UInt32Value { + if x != nil { + return x.WinnerSlotStartDateTime + } + return nil +} + +func (x *FctTransactionMempoolOutcome7D) GetObservedAfterNonceConsumed() bool { + if x != nil { + return x.ObservedAfterNonceConsumed + } + return false +} + +func (x *FctTransactionMempoolOutcome7D) GetInMempoolAtDeadline() bool { + if x != nil { + return x.InMempoolAtDeadline + } + return false +} + +// Request for listing fct_transaction_mempool_outcome_7d records +type ListFctTransactionMempoolOutcome7DRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Filter by first_seen_date_time - Earliest sighting of the transaction within its observation episode, the anchor of the 7 day horizon (PRIMARY KEY - required unless using alternatives: hash, from) + FirstSeenDateTime *Int64Filter `protobuf:"bytes,1,opt,name=first_seen_date_time,json=firstSeenDateTime,proto3" json:"first_seen_date_time,omitempty"` + // Filter by hash - The transaction hash (ORDER BY column 2 - optional) + Hash *StringFilter `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UpdatedDateTime *UInt32Filter `protobuf:"bytes,3,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Filter by from - The address of the account that sent the transaction (PROJECTION: p_by_nonce_group - alternative to first_seen_date_time) + From *StringFilter `protobuf:"bytes,4,opt,name=from,proto3" json:"from,omitempty"` + // Filter by to - The address of the transaction recipient, null for contract creation (optional) + To *NullableStringFilter `protobuf:"bytes,5,opt,name=to,proto3" json:"to,omitempty"` + // Filter by nonce - The nonce of the sender account at the time of the transaction (optional) + Nonce *UInt64Filter `protobuf:"bytes,6,opt,name=nonce,proto3" json:"nonce,omitempty"` + // Filter by type - The type of the transaction (optional) + Type *NullableUInt32Filter `protobuf:"bytes,7,opt,name=type,proto3" json:"type,omitempty"` + // Filter by gas - The maximum gas provided for the transaction execution (optional) + Gas *UInt64Filter `protobuf:"bytes,8,opt,name=gas,proto3" json:"gas,omitempty"` + // Filter by gas_price - The gas price of the transaction in wei (optional) + GasPrice *StringFilter `protobuf:"bytes,9,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` + // Filter by gas_tip_cap - The priority fee (tip) the user has set for the transaction in wei (optional) + GasTipCap *NullableStringFilter `protobuf:"bytes,10,opt,name=gas_tip_cap,json=gasTipCap,proto3" json:"gas_tip_cap,omitempty"` + // Filter by gas_fee_cap - The max fee the user has set for the transaction in wei (optional) + GasFeeCap *NullableStringFilter `protobuf:"bytes,11,opt,name=gas_fee_cap,json=gasFeeCap,proto3" json:"gas_fee_cap,omitempty"` + // Filter by value - The value transferred with the transaction in wei (optional) + Value *StringFilter `protobuf:"bytes,12,opt,name=value,proto3" json:"value,omitempty"` + // Filter by size - The size of the transaction data in bytes (optional) + Size *UInt32Filter `protobuf:"bytes,13,opt,name=size,proto3" json:"size,omitempty"` + // Filter by call_data_size - The size of the call data of the transaction in bytes (optional) + CallDataSize *UInt32Filter `protobuf:"bytes,14,opt,name=call_data_size,json=callDataSize,proto3" json:"call_data_size,omitempty"` + // Filter by blob_gas - The maximum gas provided for the blob transaction execution (optional) + BlobGas *NullableUInt64Filter `protobuf:"bytes,15,opt,name=blob_gas,json=blobGas,proto3" json:"blob_gas,omitempty"` + // Filter by blob_gas_fee_cap - The max blob fee the user has set for the transaction in wei (optional) + BlobGasFeeCap *NullableStringFilter `protobuf:"bytes,16,opt,name=blob_gas_fee_cap,json=blobGasFeeCap,proto3" json:"blob_gas_fee_cap,omitempty"` + // Filter by blob_hashes - The hashes of the blob commitments for blob transactions (optional) + BlobHashes *ArrayStringFilter `protobuf:"bytes,17,opt,name=blob_hashes,json=blobHashes,proto3" json:"blob_hashes,omitempty"` + // Filter by is_cancel_shape - Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern (optional) + IsCancelShape *BoolFilter `protobuf:"bytes,18,opt,name=is_cancel_shape,json=isCancelShape,proto3" json:"is_cancel_shape,omitempty"` + // Filter by last_seen_date_time - Latest sighting of the transaction within the 7 day horizon (optional) + LastSeenDateTime *Int64Filter `protobuf:"bytes,19,opt,name=last_seen_date_time,json=lastSeenDateTime,proto3" json:"last_seen_date_time,omitempty"` + // Filter by sighting_count - Number of sightings within the 7 day horizon across all sentries (optional) + SightingCount *UInt32Filter `protobuf:"bytes,20,opt,name=sighting_count,json=sightingCount,proto3" json:"sighting_count,omitempty"` + // Filter by peak_hourly_unique_sentries - Peak number of distinct sentries sighting the transaction within any single hour of the horizon (optional) + PeakHourlyUniqueSentries *UInt32Filter `protobuf:"bytes,21,opt,name=peak_hourly_unique_sentries,json=peakHourlyUniqueSentries,proto3" json:"peak_hourly_unique_sentries,omitempty"` + // Filter by outcome - Outcome within 7 days of first sighting: included, nonce_consumed (a different transaction with the same from and nonce was included) or unincluded. The statement is fixed to the horizon and remains true even if the transaction is included later (optional) + Outcome *StringFilter `protobuf:"bytes,22,opt,name=outcome,proto3" json:"outcome,omitempty"` + // Filter by resolution_date_time - When the outcome was determined: the inclusion slot start for included, the winner inclusion slot start for nonce_consumed, or first_seen_date_time plus 7 days for unincluded (optional) + ResolutionDateTime *Int64Filter `protobuf:"bytes,23,opt,name=resolution_date_time,json=resolutionDateTime,proto3" json:"resolution_date_time,omitempty"` + // Filter by included_slot - The slot of the beacon block that included the transaction, when outcome is included (optional) + IncludedSlot *NullableUInt32Filter `protobuf:"bytes,24,opt,name=included_slot,json=includedSlot,proto3" json:"included_slot,omitempty"` + // Filter by included_slot_start_date_time - The wall clock time when the inclusion slot started, when outcome is included (optional) + IncludedSlotStartDateTime *NullableUInt32Filter `protobuf:"bytes,25,opt,name=included_slot_start_date_time,json=includedSlotStartDateTime,proto3" json:"included_slot_start_date_time,omitempty"` + // Filter by included_block_root - The beacon block root of the including block, when outcome is included (optional) + IncludedBlockRoot *NullableStringFilter `protobuf:"bytes,26,opt,name=included_block_root,json=includedBlockRoot,proto3" json:"included_block_root,omitempty"` + // Filter by included_position - The position of the transaction in the execution payload, when outcome is included (optional) + IncludedPosition *NullableUInt32Filter `protobuf:"bytes,27,opt,name=included_position,json=includedPosition,proto3" json:"included_position,omitempty"` + // Filter by wait_ms - Milliseconds from first sighting to the inclusion slot start, when outcome is included. Negative when the transaction was first sighted after its inclusion slot started (optional) + WaitMs *NullableInt64Filter `protobuf:"bytes,28,opt,name=wait_ms,json=waitMs,proto3" json:"wait_ms,omitempty"` + // Filter by included_via_known_relay - Whether the including block matched a known relay payload-delivered record, when outcome is included. False is not proof the block was locally built (optional) + IncludedViaKnownRelay *NullableBoolFilter `protobuf:"bytes,29,opt,name=included_via_known_relay,json=includedViaKnownRelay,proto3" json:"included_via_known_relay,omitempty"` + // Filter by winner_hash - The hash of the transaction that consumed the nonce, when outcome is nonce_consumed (optional) + WinnerHash *NullableStringFilter `protobuf:"bytes,30,opt,name=winner_hash,json=winnerHash,proto3" json:"winner_hash,omitempty"` + // Filter by winner_slot_start_date_time - The wall clock time when the winner inclusion slot started, when outcome is nonce_consumed (optional) + WinnerSlotStartDateTime *NullableUInt32Filter `protobuf:"bytes,31,opt,name=winner_slot_start_date_time,json=winnerSlotStartDateTime,proto3" json:"winner_slot_start_date_time,omitempty"` + // Filter by observed_after_nonce_consumed - Whether the transaction was first sighted after its nonce had already been consumed by another transaction (optional) + ObservedAfterNonceConsumed *BoolFilter `protobuf:"bytes,32,opt,name=observed_after_nonce_consumed,json=observedAfterNonceConsumed,proto3" json:"observed_after_nonce_consumed,omitempty"` + // Filter by in_mempool_at_deadline - Whether a sighting occurred in the final hour before the 7 day deadline. Sensor evidence of continued circulation, only meaningful when outcome is unincluded (optional) + InMempoolAtDeadline *BoolFilter `protobuf:"bytes,33,opt,name=in_mempool_at_deadline,json=inMempoolAtDeadline,proto3" json:"in_mempool_at_deadline,omitempty"` + // The maximum number of fct_transaction_mempool_outcome_7d to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + PageSize int32 `protobuf:"varint,34,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // A page token, received from a previous `ListFctTransactionMempoolOutcome7d` call. + // Provide this to retrieve the subsequent page. + PageToken string `protobuf:"bytes,35,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + OrderBy string `protobuf:"bytes,36,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"` +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) Reset() { + *x = ListFctTransactionMempoolOutcome7DRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_7d_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionMempoolOutcome7DRequest) ProtoMessage() {} + +func (x *ListFctTransactionMempoolOutcome7DRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_7d_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionMempoolOutcome7DRequest.ProtoReflect.Descriptor instead. +func (*ListFctTransactionMempoolOutcome7DRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_7d_proto_rawDescGZIP(), []int{1} +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetFirstSeenDateTime() *Int64Filter { + if x != nil { + return x.FirstSeenDateTime + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetHash() *StringFilter { + if x != nil { + return x.Hash + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetUpdatedDateTime() *UInt32Filter { + if x != nil { + return x.UpdatedDateTime + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetFrom() *StringFilter { + if x != nil { + return x.From + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetTo() *NullableStringFilter { + if x != nil { + return x.To + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetNonce() *UInt64Filter { + if x != nil { + return x.Nonce + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetType() *NullableUInt32Filter { + if x != nil { + return x.Type + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetGas() *UInt64Filter { + if x != nil { + return x.Gas + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetGasPrice() *StringFilter { + if x != nil { + return x.GasPrice + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetGasTipCap() *NullableStringFilter { + if x != nil { + return x.GasTipCap + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetGasFeeCap() *NullableStringFilter { + if x != nil { + return x.GasFeeCap + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetValue() *StringFilter { + if x != nil { + return x.Value + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetSize() *UInt32Filter { + if x != nil { + return x.Size + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetCallDataSize() *UInt32Filter { + if x != nil { + return x.CallDataSize + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetBlobGas() *NullableUInt64Filter { + if x != nil { + return x.BlobGas + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetBlobGasFeeCap() *NullableStringFilter { + if x != nil { + return x.BlobGasFeeCap + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetBlobHashes() *ArrayStringFilter { + if x != nil { + return x.BlobHashes + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetIsCancelShape() *BoolFilter { + if x != nil { + return x.IsCancelShape + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetLastSeenDateTime() *Int64Filter { + if x != nil { + return x.LastSeenDateTime + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetSightingCount() *UInt32Filter { + if x != nil { + return x.SightingCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetPeakHourlyUniqueSentries() *UInt32Filter { + if x != nil { + return x.PeakHourlyUniqueSentries + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetOutcome() *StringFilter { + if x != nil { + return x.Outcome + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetResolutionDateTime() *Int64Filter { + if x != nil { + return x.ResolutionDateTime + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetIncludedSlot() *NullableUInt32Filter { + if x != nil { + return x.IncludedSlot + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetIncludedSlotStartDateTime() *NullableUInt32Filter { + if x != nil { + return x.IncludedSlotStartDateTime + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetIncludedBlockRoot() *NullableStringFilter { + if x != nil { + return x.IncludedBlockRoot + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetIncludedPosition() *NullableUInt32Filter { + if x != nil { + return x.IncludedPosition + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetWaitMs() *NullableInt64Filter { + if x != nil { + return x.WaitMs + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetIncludedViaKnownRelay() *NullableBoolFilter { + if x != nil { + return x.IncludedViaKnownRelay + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetWinnerHash() *NullableStringFilter { + if x != nil { + return x.WinnerHash + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetWinnerSlotStartDateTime() *NullableUInt32Filter { + if x != nil { + return x.WinnerSlotStartDateTime + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetObservedAfterNonceConsumed() *BoolFilter { + if x != nil { + return x.ObservedAfterNonceConsumed + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetInMempoolAtDeadline() *BoolFilter { + if x != nil { + return x.InMempoolAtDeadline + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +func (x *ListFctTransactionMempoolOutcome7DRequest) GetOrderBy() string { + if x != nil { + return x.OrderBy + } + return "" +} + +// Response for listing fct_transaction_mempool_outcome_7d records +type ListFctTransactionMempoolOutcome7DResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of fct_transaction_mempool_outcome_7d. + FctTransactionMempoolOutcome_7D []*FctTransactionMempoolOutcome7D `protobuf:"bytes,1,rep,name=fct_transaction_mempool_outcome_7d,json=fctTransactionMempoolOutcome7d,proto3" json:"fct_transaction_mempool_outcome_7d,omitempty"` + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` +} + +func (x *ListFctTransactionMempoolOutcome7DResponse) Reset() { + *x = ListFctTransactionMempoolOutcome7DResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_7d_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionMempoolOutcome7DResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionMempoolOutcome7DResponse) ProtoMessage() {} + +func (x *ListFctTransactionMempoolOutcome7DResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_7d_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionMempoolOutcome7DResponse.ProtoReflect.Descriptor instead. +func (*ListFctTransactionMempoolOutcome7DResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_7d_proto_rawDescGZIP(), []int{2} +} + +func (x *ListFctTransactionMempoolOutcome7DResponse) GetFctTransactionMempoolOutcome_7D() []*FctTransactionMempoolOutcome7D { + if x != nil { + return x.FctTransactionMempoolOutcome_7D + } + return nil +} + +func (x *ListFctTransactionMempoolOutcome7DResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +// Request for getting a single fct_transaction_mempool_outcome_7d record by primary key +type GetFctTransactionMempoolOutcome7DRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Earliest sighting of the transaction within its observation episode, the anchor of the 7 day horizon + FirstSeenDateTime int64 `protobuf:"varint,1,opt,name=first_seen_date_time,json=firstSeenDateTime,proto3" json:"first_seen_date_time,omitempty"` // Primary key (required) +} + +func (x *GetFctTransactionMempoolOutcome7DRequest) Reset() { + *x = GetFctTransactionMempoolOutcome7DRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_7d_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionMempoolOutcome7DRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionMempoolOutcome7DRequest) ProtoMessage() {} + +func (x *GetFctTransactionMempoolOutcome7DRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_7d_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionMempoolOutcome7DRequest.ProtoReflect.Descriptor instead. +func (*GetFctTransactionMempoolOutcome7DRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_7d_proto_rawDescGZIP(), []int{3} +} + +func (x *GetFctTransactionMempoolOutcome7DRequest) GetFirstSeenDateTime() int64 { + if x != nil { + return x.FirstSeenDateTime + } + return 0 +} + +// Response for getting a single fct_transaction_mempool_outcome_7d record +type GetFctTransactionMempoolOutcome7DResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *FctTransactionMempoolOutcome7D `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *GetFctTransactionMempoolOutcome7DResponse) Reset() { + *x = GetFctTransactionMempoolOutcome7DResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_7d_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionMempoolOutcome7DResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionMempoolOutcome7DResponse) ProtoMessage() {} + +func (x *GetFctTransactionMempoolOutcome7DResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_7d_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionMempoolOutcome7DResponse.ProtoReflect.Descriptor instead. +func (*GetFctTransactionMempoolOutcome7DResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_7d_proto_rawDescGZIP(), []int{4} +} + +func (x *GetFctTransactionMempoolOutcome7DResponse) GetItem() *FctTransactionMempoolOutcome7D { + if x != nil { + return x.Item + } + return nil +} + +var File_fct_transaction_mempool_outcome_7d_proto protoreflect.FileDescriptor + +var file_fct_transaction_mempool_outcome_7d_proto_rawDesc = []byte{ + 0x0a, 0x28, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, + 0x65, 0x5f, 0x37, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x63, 0x62, 0x74, 0x1a, + 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, + 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, + 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x63, 0x6c, + 0x69, 0x63, 0x6b, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9a, 0x0d, 0x0a, 0x1e, 0x46, + 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, + 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x37, 0x64, 0x12, 0x2a, 0x0a, + 0x11, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x14, 0x66, 0x69, 0x72, + 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, + 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x12, + 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, + 0x6f, 0x6d, 0x12, 0x2c, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x02, 0x74, 0x6f, + 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, + 0x12, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, + 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, + 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x74, + 0x69, 0x70, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x67, 0x61, 0x73, 0x54, + 0x69, 0x70, 0x43, 0x61, 0x70, 0x12, 0x3c, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, + 0x5f, 0x63, 0x61, 0x70, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x67, 0x61, 0x73, 0x46, 0x65, 0x65, + 0x43, 0x61, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x16, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x24, 0x0a, + 0x0e, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x18, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x63, 0x61, 0x6c, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x53, + 0x69, 0x7a, 0x65, 0x12, 0x37, 0x0a, 0x08, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x18, + 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x12, 0x45, 0x0a, 0x10, + 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x63, 0x61, 0x70, + 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x46, 0x65, 0x65, + 0x43, 0x61, 0x70, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x65, 0x73, 0x18, 0x1b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x62, 0x48, 0x61, + 0x73, 0x68, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x73, 0x5f, 0x63, 0x61, 0x6e, 0x63, 0x65, + 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, + 0x73, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x70, 0x65, 0x12, 0x2d, 0x0a, 0x13, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x53, + 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, + 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x1e, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x1b, 0x70, 0x65, 0x61, 0x6b, 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x6c, + 0x79, 0x5f, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, + 0x73, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x18, 0x70, 0x65, 0x61, 0x6b, 0x48, 0x6f, 0x75, + 0x72, 0x6c, 0x79, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x53, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, + 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x18, 0x20, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x72, + 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x21, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x41, 0x0a, + 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x22, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x53, 0x6c, 0x6f, 0x74, + 0x12, 0x5e, 0x0a, 0x1d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x73, 0x6c, 0x6f, + 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x19, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x53, + 0x6c, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, + 0x12, 0x4c, 0x0a, 0x13, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x24, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x49, + 0x0a, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x25, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x64, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x07, 0x77, 0x61, 0x69, + 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, + 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x77, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x12, + 0x53, 0x0a, 0x18, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x76, 0x69, 0x61, 0x5f, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x27, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x15, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x56, 0x69, 0x61, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x52, + 0x65, 0x6c, 0x61, 0x79, 0x12, 0x3d, 0x0a, 0x0b, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, + 0x61, 0x73, 0x68, 0x12, 0x5a, 0x0a, 0x1b, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x73, 0x6c, + 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, + 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x17, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x53, 0x6c, + 0x6f, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x41, 0x0a, 0x1d, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x66, 0x74, 0x65, + 0x72, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, + 0x18, 0x2a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x41, 0x66, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, + 0x65, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x69, 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, + 0x5f, 0x61, 0x74, 0x5f, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x2b, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x13, 0x69, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x41, 0x74, 0x44, + 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0xb5, 0x12, 0x0a, 0x29, 0x4c, 0x69, 0x73, 0x74, + 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, + 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x37, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x55, 0x0a, 0x14, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, + 0x65, 0x65, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x12, 0xe0, 0x41, 0x01, 0x9a, 0xb5, 0x18, 0x0b, 0x70, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x52, 0x11, 0x66, 0x69, 0x72, 0x73, 0x74, + 0x53, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x04, + 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, + 0x41, 0x01, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x42, 0x0a, 0x11, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x65, 0x0a, 0x04, + 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x3e, 0xe0, + 0x41, 0x01, 0x8a, 0xb5, 0x18, 0x14, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, + 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x92, 0xb5, 0x18, 0x10, 0x70, 0x5f, + 0x62, 0x79, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x9a, 0xb5, + 0x18, 0x0b, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x52, 0x04, 0x66, + 0x72, 0x6f, 0x6d, 0x12, 0x2e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x02, 0x74, 0x6f, 0x12, 0x2c, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, + 0x65, 0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x49, + 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, + 0x33, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, + 0x72, 0x69, 0x63, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x70, 0x5f, + 0x63, 0x61, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, + 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x67, 0x61, 0x73, 0x54, 0x69, + 0x70, 0x43, 0x61, 0x70, 0x12, 0x3e, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, 0x5f, + 0x63, 0x61, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, + 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x67, 0x61, 0x73, 0x46, 0x65, + 0x65, 0x43, 0x61, 0x70, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x3c, + 0x0a, 0x0e, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, + 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0c, + 0x63, 0x61, 0x6c, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x39, 0x0a, 0x08, + 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x49, 0x6e, + 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, + 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x12, 0x47, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, + 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, + 0x01, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x46, 0x65, 0x65, 0x43, 0x61, 0x70, + 0x12, 0x3c, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x41, 0x72, 0x72, 0x61, + 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, + 0x41, 0x01, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x62, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x3c, + 0x0a, 0x0f, 0x69, 0x73, 0x5f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x70, + 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x42, 0x6f, + 0x6f, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x69, + 0x73, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x70, 0x65, 0x12, 0x44, 0x0a, 0x13, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x62, 0x74, 0x2e, + 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, + 0x52, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, + 0x41, 0x01, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x55, 0x0a, 0x1b, 0x70, 0x65, 0x61, 0x6b, 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, + 0x5f, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, + 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x18, + 0x70, 0x65, 0x61, 0x6b, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, + 0x53, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x63, + 0x6f, 0x6d, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, + 0x01, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x12, 0x47, 0x0a, 0x14, 0x72, 0x65, + 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x49, + 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, + 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0c, 0x69, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x64, 0x53, 0x6c, 0x6f, 0x74, 0x12, 0x60, 0x0a, 0x1d, 0x69, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x64, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, + 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x49, + 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x19, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x53, 0x6c, 0x6f, 0x74, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f, + 0x74, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, + 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x4b, 0x0a, 0x11, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, + 0x61, 0x62, 0x6c, 0x65, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x50, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x07, 0x77, 0x61, 0x69, 0x74, 0x5f, + 0x6d, 0x73, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, + 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x06, 0x77, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x12, + 0x55, 0x0a, 0x18, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x76, 0x69, 0x61, 0x5f, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x1d, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, + 0x42, 0x6f, 0x6f, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x15, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x56, 0x69, 0x61, 0x4b, 0x6e, 0x6f, 0x77, + 0x6e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x3f, 0x0a, 0x0b, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x77, 0x69, 0x6e, + 0x6e, 0x65, 0x72, 0x48, 0x61, 0x73, 0x68, 0x12, 0x5c, 0x0a, 0x1b, 0x77, 0x69, 0x6e, 0x6e, 0x65, + 0x72, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, + 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, + 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x49, 0x6e, 0x74, 0x33, + 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x17, 0x77, 0x69, + 0x6e, 0x6e, 0x65, 0x72, 0x53, 0x6c, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x57, 0x0a, 0x1d, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, + 0x62, 0x74, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, + 0x41, 0x01, 0x52, 0x1a, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, + 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x12, 0x49, + 0x0a, 0x16, 0x69, 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x61, 0x74, 0x5f, + 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, + 0x03, 0xe0, 0x41, 0x01, 0x52, 0x13, 0x69, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x41, + 0x74, 0x44, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x20, 0x0a, 0x09, 0x70, 0x61, 0x67, + 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x22, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0xe0, 0x41, + 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0a, 0x70, + 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x23, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, + 0x1e, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x24, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, + 0xc5, 0x01, 0x0a, 0x2a, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, + 0x63, 0x6f, 0x6d, 0x65, 0x37, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, + 0x0a, 0x22, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, + 0x65, 0x5f, 0x37, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x37, 0x64, 0x52, + 0x1e, 0x66, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x37, 0x64, 0x12, + 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, + 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x5b, 0x0a, 0x28, 0x47, 0x65, 0x74, 0x46, 0x63, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, + 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x37, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x14, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, + 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x11, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, + 0x54, 0x69, 0x6d, 0x65, 0x22, 0x64, 0x0a, 0x29, 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, + 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x37, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x37, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x23, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, + 0x6d, 0x65, 0x37, 0x64, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0xf7, 0x02, 0x0a, 0x25, 0x46, + 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, + 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x37, 0x64, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x9b, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2e, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, + 0x63, 0x6f, 0x6d, 0x65, 0x37, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, + 0x63, 0x6f, 0x6d, 0x65, 0x37, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, + 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x5f, + 0x37, 0x64, 0x12, 0xaf, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x2d, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, + 0x37, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x62, 0x74, 0x2e, + 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x37, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x49, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x43, 0x12, 0x41, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x63, 0x74, 0x5f, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, + 0x6f, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x37, 0x64, 0x2f, 0x7b, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x7d, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x70, 0x61, 0x6e, 0x64, 0x61, 0x6f, 0x70, 0x73, 0x2f, 0x78, + 0x61, 0x74, 0x75, 0x2d, 0x63, 0x62, 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_fct_transaction_mempool_outcome_7d_proto_rawDescOnce sync.Once + file_fct_transaction_mempool_outcome_7d_proto_rawDescData = file_fct_transaction_mempool_outcome_7d_proto_rawDesc +) + +func file_fct_transaction_mempool_outcome_7d_proto_rawDescGZIP() []byte { + file_fct_transaction_mempool_outcome_7d_proto_rawDescOnce.Do(func() { + file_fct_transaction_mempool_outcome_7d_proto_rawDescData = protoimpl.X.CompressGZIP(file_fct_transaction_mempool_outcome_7d_proto_rawDescData) + }) + return file_fct_transaction_mempool_outcome_7d_proto_rawDescData +} + +var file_fct_transaction_mempool_outcome_7d_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_fct_transaction_mempool_outcome_7d_proto_goTypes = []any{ + (*FctTransactionMempoolOutcome7D)(nil), // 0: cbt.FctTransactionMempoolOutcome7d + (*ListFctTransactionMempoolOutcome7DRequest)(nil), // 1: cbt.ListFctTransactionMempoolOutcome7dRequest + (*ListFctTransactionMempoolOutcome7DResponse)(nil), // 2: cbt.ListFctTransactionMempoolOutcome7dResponse + (*GetFctTransactionMempoolOutcome7DRequest)(nil), // 3: cbt.GetFctTransactionMempoolOutcome7dRequest + (*GetFctTransactionMempoolOutcome7DResponse)(nil), // 4: cbt.GetFctTransactionMempoolOutcome7dResponse + (*wrapperspb.StringValue)(nil), // 5: google.protobuf.StringValue + (*wrapperspb.UInt32Value)(nil), // 6: google.protobuf.UInt32Value + (*wrapperspb.UInt64Value)(nil), // 7: google.protobuf.UInt64Value + (*wrapperspb.Int64Value)(nil), // 8: google.protobuf.Int64Value + (*wrapperspb.BoolValue)(nil), // 9: google.protobuf.BoolValue + (*Int64Filter)(nil), // 10: cbt.Int64Filter + (*StringFilter)(nil), // 11: cbt.StringFilter + (*UInt32Filter)(nil), // 12: cbt.UInt32Filter + (*NullableStringFilter)(nil), // 13: cbt.NullableStringFilter + (*UInt64Filter)(nil), // 14: cbt.UInt64Filter + (*NullableUInt32Filter)(nil), // 15: cbt.NullableUInt32Filter + (*NullableUInt64Filter)(nil), // 16: cbt.NullableUInt64Filter + (*ArrayStringFilter)(nil), // 17: cbt.ArrayStringFilter + (*BoolFilter)(nil), // 18: cbt.BoolFilter + (*NullableInt64Filter)(nil), // 19: cbt.NullableInt64Filter + (*NullableBoolFilter)(nil), // 20: cbt.NullableBoolFilter +} +var file_fct_transaction_mempool_outcome_7d_proto_depIdxs = []int32{ + 5, // 0: cbt.FctTransactionMempoolOutcome7d.to:type_name -> google.protobuf.StringValue + 6, // 1: cbt.FctTransactionMempoolOutcome7d.type:type_name -> google.protobuf.UInt32Value + 5, // 2: cbt.FctTransactionMempoolOutcome7d.gas_tip_cap:type_name -> google.protobuf.StringValue + 5, // 3: cbt.FctTransactionMempoolOutcome7d.gas_fee_cap:type_name -> google.protobuf.StringValue + 7, // 4: cbt.FctTransactionMempoolOutcome7d.blob_gas:type_name -> google.protobuf.UInt64Value + 5, // 5: cbt.FctTransactionMempoolOutcome7d.blob_gas_fee_cap:type_name -> google.protobuf.StringValue + 6, // 6: cbt.FctTransactionMempoolOutcome7d.included_slot:type_name -> google.protobuf.UInt32Value + 6, // 7: cbt.FctTransactionMempoolOutcome7d.included_slot_start_date_time:type_name -> google.protobuf.UInt32Value + 5, // 8: cbt.FctTransactionMempoolOutcome7d.included_block_root:type_name -> google.protobuf.StringValue + 6, // 9: cbt.FctTransactionMempoolOutcome7d.included_position:type_name -> google.protobuf.UInt32Value + 8, // 10: cbt.FctTransactionMempoolOutcome7d.wait_ms:type_name -> google.protobuf.Int64Value + 9, // 11: cbt.FctTransactionMempoolOutcome7d.included_via_known_relay:type_name -> google.protobuf.BoolValue + 5, // 12: cbt.FctTransactionMempoolOutcome7d.winner_hash:type_name -> google.protobuf.StringValue + 6, // 13: cbt.FctTransactionMempoolOutcome7d.winner_slot_start_date_time:type_name -> google.protobuf.UInt32Value + 10, // 14: cbt.ListFctTransactionMempoolOutcome7dRequest.first_seen_date_time:type_name -> cbt.Int64Filter + 11, // 15: cbt.ListFctTransactionMempoolOutcome7dRequest.hash:type_name -> cbt.StringFilter + 12, // 16: cbt.ListFctTransactionMempoolOutcome7dRequest.updated_date_time:type_name -> cbt.UInt32Filter + 11, // 17: cbt.ListFctTransactionMempoolOutcome7dRequest.from:type_name -> cbt.StringFilter + 13, // 18: cbt.ListFctTransactionMempoolOutcome7dRequest.to:type_name -> cbt.NullableStringFilter + 14, // 19: cbt.ListFctTransactionMempoolOutcome7dRequest.nonce:type_name -> cbt.UInt64Filter + 15, // 20: cbt.ListFctTransactionMempoolOutcome7dRequest.type:type_name -> cbt.NullableUInt32Filter + 14, // 21: cbt.ListFctTransactionMempoolOutcome7dRequest.gas:type_name -> cbt.UInt64Filter + 11, // 22: cbt.ListFctTransactionMempoolOutcome7dRequest.gas_price:type_name -> cbt.StringFilter + 13, // 23: cbt.ListFctTransactionMempoolOutcome7dRequest.gas_tip_cap:type_name -> cbt.NullableStringFilter + 13, // 24: cbt.ListFctTransactionMempoolOutcome7dRequest.gas_fee_cap:type_name -> cbt.NullableStringFilter + 11, // 25: cbt.ListFctTransactionMempoolOutcome7dRequest.value:type_name -> cbt.StringFilter + 12, // 26: cbt.ListFctTransactionMempoolOutcome7dRequest.size:type_name -> cbt.UInt32Filter + 12, // 27: cbt.ListFctTransactionMempoolOutcome7dRequest.call_data_size:type_name -> cbt.UInt32Filter + 16, // 28: cbt.ListFctTransactionMempoolOutcome7dRequest.blob_gas:type_name -> cbt.NullableUInt64Filter + 13, // 29: cbt.ListFctTransactionMempoolOutcome7dRequest.blob_gas_fee_cap:type_name -> cbt.NullableStringFilter + 17, // 30: cbt.ListFctTransactionMempoolOutcome7dRequest.blob_hashes:type_name -> cbt.ArrayStringFilter + 18, // 31: cbt.ListFctTransactionMempoolOutcome7dRequest.is_cancel_shape:type_name -> cbt.BoolFilter + 10, // 32: cbt.ListFctTransactionMempoolOutcome7dRequest.last_seen_date_time:type_name -> cbt.Int64Filter + 12, // 33: cbt.ListFctTransactionMempoolOutcome7dRequest.sighting_count:type_name -> cbt.UInt32Filter + 12, // 34: cbt.ListFctTransactionMempoolOutcome7dRequest.peak_hourly_unique_sentries:type_name -> cbt.UInt32Filter + 11, // 35: cbt.ListFctTransactionMempoolOutcome7dRequest.outcome:type_name -> cbt.StringFilter + 10, // 36: cbt.ListFctTransactionMempoolOutcome7dRequest.resolution_date_time:type_name -> cbt.Int64Filter + 15, // 37: cbt.ListFctTransactionMempoolOutcome7dRequest.included_slot:type_name -> cbt.NullableUInt32Filter + 15, // 38: cbt.ListFctTransactionMempoolOutcome7dRequest.included_slot_start_date_time:type_name -> cbt.NullableUInt32Filter + 13, // 39: cbt.ListFctTransactionMempoolOutcome7dRequest.included_block_root:type_name -> cbt.NullableStringFilter + 15, // 40: cbt.ListFctTransactionMempoolOutcome7dRequest.included_position:type_name -> cbt.NullableUInt32Filter + 19, // 41: cbt.ListFctTransactionMempoolOutcome7dRequest.wait_ms:type_name -> cbt.NullableInt64Filter + 20, // 42: cbt.ListFctTransactionMempoolOutcome7dRequest.included_via_known_relay:type_name -> cbt.NullableBoolFilter + 13, // 43: cbt.ListFctTransactionMempoolOutcome7dRequest.winner_hash:type_name -> cbt.NullableStringFilter + 15, // 44: cbt.ListFctTransactionMempoolOutcome7dRequest.winner_slot_start_date_time:type_name -> cbt.NullableUInt32Filter + 18, // 45: cbt.ListFctTransactionMempoolOutcome7dRequest.observed_after_nonce_consumed:type_name -> cbt.BoolFilter + 18, // 46: cbt.ListFctTransactionMempoolOutcome7dRequest.in_mempool_at_deadline:type_name -> cbt.BoolFilter + 0, // 47: cbt.ListFctTransactionMempoolOutcome7dResponse.fct_transaction_mempool_outcome_7d:type_name -> cbt.FctTransactionMempoolOutcome7d + 0, // 48: cbt.GetFctTransactionMempoolOutcome7dResponse.item:type_name -> cbt.FctTransactionMempoolOutcome7d + 1, // 49: cbt.FctTransactionMempoolOutcome7dService.List:input_type -> cbt.ListFctTransactionMempoolOutcome7dRequest + 3, // 50: cbt.FctTransactionMempoolOutcome7dService.Get:input_type -> cbt.GetFctTransactionMempoolOutcome7dRequest + 2, // 51: cbt.FctTransactionMempoolOutcome7dService.List:output_type -> cbt.ListFctTransactionMempoolOutcome7dResponse + 4, // 52: cbt.FctTransactionMempoolOutcome7dService.Get:output_type -> cbt.GetFctTransactionMempoolOutcome7dResponse + 51, // [51:53] is the sub-list for method output_type + 49, // [49:51] is the sub-list for method input_type + 49, // [49:49] is the sub-list for extension type_name + 49, // [49:49] is the sub-list for extension extendee + 0, // [0:49] is the sub-list for field type_name +} + +func init() { file_fct_transaction_mempool_outcome_7d_proto_init() } +func file_fct_transaction_mempool_outcome_7d_proto_init() { + if File_fct_transaction_mempool_outcome_7d_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_fct_transaction_mempool_outcome_7d_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*FctTransactionMempoolOutcome7D); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_mempool_outcome_7d_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionMempoolOutcome7DRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_mempool_outcome_7d_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionMempoolOutcome7DResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_mempool_outcome_7d_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionMempoolOutcome7DRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_mempool_outcome_7d_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionMempoolOutcome7DResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_fct_transaction_mempool_outcome_7d_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_fct_transaction_mempool_outcome_7d_proto_goTypes, + DependencyIndexes: file_fct_transaction_mempool_outcome_7d_proto_depIdxs, + MessageInfos: file_fct_transaction_mempool_outcome_7d_proto_msgTypes, + }.Build() + File_fct_transaction_mempool_outcome_7d_proto = out.File + file_fct_transaction_mempool_outcome_7d_proto_rawDesc = nil + file_fct_transaction_mempool_outcome_7d_proto_goTypes = nil + file_fct_transaction_mempool_outcome_7d_proto_depIdxs = nil +} diff --git a/pkg/proto/clickhouse/fct_transaction_mempool_outcome_7d.proto b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_7d.proto new file mode 100644 index 00000000..01646d19 --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_7d.proto @@ -0,0 +1,201 @@ +syntax = "proto3"; + +package cbt; + +import "common.proto"; +import "google/protobuf/wrappers.proto"; +import "google/api/annotations.proto"; +import "google/api/field_behavior.proto"; +import "clickhouse/annotations.proto"; + +option go_package = "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse"; +// One immutable row per transaction hash observed in the public mempool, stating its fixed-horizon outcome within 7 days of first sighting. An observation episode starts when a hash is sighted with no sightings in the preceding 7 days. A hash re-sighted after more than 7 days of silence starts a new episode and a new row + +message FctTransactionMempoolOutcome7d { + // Timestamp when the record was last updated + uint32 updated_date_time = 11; + // Earliest sighting of the transaction within its observation episode, the anchor of the 7 day horizon + int64 first_seen_date_time = 12; + // The transaction hash + string hash = 13; + // The address of the account that sent the transaction + string from = 14; + // The address of the transaction recipient, null for contract creation + google.protobuf.StringValue to = 15; + // The nonce of the sender account at the time of the transaction + uint64 nonce = 16; + // The type of the transaction + google.protobuf.UInt32Value type = 17; + // The maximum gas provided for the transaction execution + uint64 gas = 18; + // The gas price of the transaction in wei + string gas_price = 19; + // The priority fee (tip) the user has set for the transaction in wei + google.protobuf.StringValue gas_tip_cap = 20; + // The max fee the user has set for the transaction in wei + google.protobuf.StringValue gas_fee_cap = 21; + // The value transferred with the transaction in wei + string value = 22; + // The size of the transaction data in bytes + uint32 size = 23; + // The size of the call data of the transaction in bytes + uint32 call_data_size = 24; + // The maximum gas provided for the blob transaction execution + google.protobuf.UInt64Value blob_gas = 25; + // The max blob fee the user has set for the transaction in wei + google.protobuf.StringValue blob_gas_fee_cap = 26; + // The hashes of the blob commitments for blob transactions + repeated string blob_hashes = 27; + // Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern + bool is_cancel_shape = 28; + // Latest sighting of the transaction within the 7 day horizon + int64 last_seen_date_time = 29; + // Number of sightings within the 7 day horizon across all sentries + uint32 sighting_count = 30; + // Peak number of distinct sentries sighting the transaction within any single hour of the horizon + uint32 peak_hourly_unique_sentries = 31; + // Outcome within 7 days of first sighting: included, nonce_consumed (a different transaction with the same from and nonce was included) or unincluded. The statement is fixed to the horizon and remains true even if the transaction is included later + string outcome = 32; + // When the outcome was determined: the inclusion slot start for included, the winner inclusion slot start for nonce_consumed, or first_seen_date_time plus 7 days for unincluded + int64 resolution_date_time = 33; + // The slot of the beacon block that included the transaction, when outcome is included + google.protobuf.UInt32Value included_slot = 34; + // The wall clock time when the inclusion slot started, when outcome is included + google.protobuf.UInt32Value included_slot_start_date_time = 35; + // The beacon block root of the including block, when outcome is included + google.protobuf.StringValue included_block_root = 36; + // The position of the transaction in the execution payload, when outcome is included + google.protobuf.UInt32Value included_position = 37; + // Milliseconds from first sighting to the inclusion slot start, when outcome is included. Negative when the transaction was first sighted after its inclusion slot started + google.protobuf.Int64Value wait_ms = 38; + // Whether the including block matched a known relay payload-delivered record, when outcome is included. False is not proof the block was locally built + google.protobuf.BoolValue included_via_known_relay = 39; + // The hash of the transaction that consumed the nonce, when outcome is nonce_consumed + google.protobuf.StringValue winner_hash = 40; + // The wall clock time when the winner inclusion slot started, when outcome is nonce_consumed + google.protobuf.UInt32Value winner_slot_start_date_time = 41; + // Whether the transaction was first sighted after its nonce had already been consumed by another transaction + bool observed_after_nonce_consumed = 42; + // Whether a sighting occurred in the final hour before the 7 day deadline. Sensor evidence of continued circulation, only meaningful when outcome is unincluded + bool in_mempool_at_deadline = 43; +} + +// Request for listing fct_transaction_mempool_outcome_7d records +message ListFctTransactionMempoolOutcome7dRequest { + // Filter by first_seen_date_time - Earliest sighting of the transaction within its observation episode, the anchor of the 7 day horizon (PRIMARY KEY - required unless using alternatives: hash, from) + Int64Filter first_seen_date_time = 1 [(google.api.field_behavior) = OPTIONAL, (clickhouse.v1.required_group) = "primary_key"]; + + // Filter by hash - The transaction hash (ORDER BY column 2 - optional) + StringFilter hash = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UInt32Filter updated_date_time = 3 [(google.api.field_behavior) = OPTIONAL]; + // Filter by from - The address of the account that sent the transaction (PROJECTION: p_by_nonce_group - alternative to first_seen_date_time) + StringFilter from = 4 [(google.api.field_behavior) = OPTIONAL, (clickhouse.v1.projection_name) = "p_by_nonce_group", (clickhouse.v1.projection_alternative_for) = "first_seen_date_time", (clickhouse.v1.required_group) = "primary_key"]; + // Filter by to - The address of the transaction recipient, null for contract creation (optional) + NullableStringFilter to = 5 [(google.api.field_behavior) = OPTIONAL]; + // Filter by nonce - The nonce of the sender account at the time of the transaction (optional) + UInt64Filter nonce = 6 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type - The type of the transaction (optional) + NullableUInt32Filter type = 7 [(google.api.field_behavior) = OPTIONAL]; + // Filter by gas - The maximum gas provided for the transaction execution (optional) + UInt64Filter gas = 8 [(google.api.field_behavior) = OPTIONAL]; + // Filter by gas_price - The gas price of the transaction in wei (optional) + StringFilter gas_price = 9 [(google.api.field_behavior) = OPTIONAL]; + // Filter by gas_tip_cap - The priority fee (tip) the user has set for the transaction in wei (optional) + NullableStringFilter gas_tip_cap = 10 [(google.api.field_behavior) = OPTIONAL]; + // Filter by gas_fee_cap - The max fee the user has set for the transaction in wei (optional) + NullableStringFilter gas_fee_cap = 11 [(google.api.field_behavior) = OPTIONAL]; + // Filter by value - The value transferred with the transaction in wei (optional) + StringFilter value = 12 [(google.api.field_behavior) = OPTIONAL]; + // Filter by size - The size of the transaction data in bytes (optional) + UInt32Filter size = 13 [(google.api.field_behavior) = OPTIONAL]; + // Filter by call_data_size - The size of the call data of the transaction in bytes (optional) + UInt32Filter call_data_size = 14 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_gas - The maximum gas provided for the blob transaction execution (optional) + NullableUInt64Filter blob_gas = 15 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_gas_fee_cap - The max blob fee the user has set for the transaction in wei (optional) + NullableStringFilter blob_gas_fee_cap = 16 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_hashes - The hashes of the blob commitments for blob transactions (optional) + ArrayStringFilter blob_hashes = 17 [(google.api.field_behavior) = OPTIONAL]; + // Filter by is_cancel_shape - Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern (optional) + BoolFilter is_cancel_shape = 18 [(google.api.field_behavior) = OPTIONAL]; + // Filter by last_seen_date_time - Latest sighting of the transaction within the 7 day horizon (optional) + Int64Filter last_seen_date_time = 19 [(google.api.field_behavior) = OPTIONAL]; + // Filter by sighting_count - Number of sightings within the 7 day horizon across all sentries (optional) + UInt32Filter sighting_count = 20 [(google.api.field_behavior) = OPTIONAL]; + // Filter by peak_hourly_unique_sentries - Peak number of distinct sentries sighting the transaction within any single hour of the horizon (optional) + UInt32Filter peak_hourly_unique_sentries = 21 [(google.api.field_behavior) = OPTIONAL]; + // Filter by outcome - Outcome within 7 days of first sighting: included, nonce_consumed (a different transaction with the same from and nonce was included) or unincluded. The statement is fixed to the horizon and remains true even if the transaction is included later (optional) + StringFilter outcome = 22 [(google.api.field_behavior) = OPTIONAL]; + // Filter by resolution_date_time - When the outcome was determined: the inclusion slot start for included, the winner inclusion slot start for nonce_consumed, or first_seen_date_time plus 7 days for unincluded (optional) + Int64Filter resolution_date_time = 23 [(google.api.field_behavior) = OPTIONAL]; + // Filter by included_slot - The slot of the beacon block that included the transaction, when outcome is included (optional) + NullableUInt32Filter included_slot = 24 [(google.api.field_behavior) = OPTIONAL]; + // Filter by included_slot_start_date_time - The wall clock time when the inclusion slot started, when outcome is included (optional) + NullableUInt32Filter included_slot_start_date_time = 25 [(google.api.field_behavior) = OPTIONAL]; + // Filter by included_block_root - The beacon block root of the including block, when outcome is included (optional) + NullableStringFilter included_block_root = 26 [(google.api.field_behavior) = OPTIONAL]; + // Filter by included_position - The position of the transaction in the execution payload, when outcome is included (optional) + NullableUInt32Filter included_position = 27 [(google.api.field_behavior) = OPTIONAL]; + // Filter by wait_ms - Milliseconds from first sighting to the inclusion slot start, when outcome is included. Negative when the transaction was first sighted after its inclusion slot started (optional) + NullableInt64Filter wait_ms = 28 [(google.api.field_behavior) = OPTIONAL]; + // Filter by included_via_known_relay - Whether the including block matched a known relay payload-delivered record, when outcome is included. False is not proof the block was locally built (optional) + NullableBoolFilter included_via_known_relay = 29 [(google.api.field_behavior) = OPTIONAL]; + // Filter by winner_hash - The hash of the transaction that consumed the nonce, when outcome is nonce_consumed (optional) + NullableStringFilter winner_hash = 30 [(google.api.field_behavior) = OPTIONAL]; + // Filter by winner_slot_start_date_time - The wall clock time when the winner inclusion slot started, when outcome is nonce_consumed (optional) + NullableUInt32Filter winner_slot_start_date_time = 31 [(google.api.field_behavior) = OPTIONAL]; + // Filter by observed_after_nonce_consumed - Whether the transaction was first sighted after its nonce had already been consumed by another transaction (optional) + BoolFilter observed_after_nonce_consumed = 32 [(google.api.field_behavior) = OPTIONAL]; + // Filter by in_mempool_at_deadline - Whether a sighting occurred in the final hour before the 7 day deadline. Sensor evidence of continued circulation, only meaningful when outcome is unincluded (optional) + BoolFilter in_mempool_at_deadline = 33 [(google.api.field_behavior) = OPTIONAL]; + + // The maximum number of fct_transaction_mempool_outcome_7d to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + int32 page_size = 34 [(google.api.field_behavior) = OPTIONAL]; + // A page token, received from a previous `ListFctTransactionMempoolOutcome7d` call. + // Provide this to retrieve the subsequent page. + string page_token = 35 [(google.api.field_behavior) = OPTIONAL]; + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + string order_by = 36 [(google.api.field_behavior) = OPTIONAL]; +} + +// Response for listing fct_transaction_mempool_outcome_7d records +message ListFctTransactionMempoolOutcome7dResponse { + // The list of fct_transaction_mempool_outcome_7d. + repeated FctTransactionMempoolOutcome7d fct_transaction_mempool_outcome_7d = 1; + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; +} + +// Request for getting a single fct_transaction_mempool_outcome_7d record by primary key +message GetFctTransactionMempoolOutcome7dRequest { + // Earliest sighting of the transaction within its observation episode, the anchor of the 7 day horizon + int64 first_seen_date_time = 1; // Primary key (required) +} + +// Response for getting a single fct_transaction_mempool_outcome_7d record +message GetFctTransactionMempoolOutcome7dResponse { + FctTransactionMempoolOutcome7d item = 1; +} + +// Query fct_transaction_mempool_outcome_7d data +service FctTransactionMempoolOutcome7dService { + // List records | Retrieve paginated results with optional filtering + rpc List(ListFctTransactionMempoolOutcome7dRequest) returns (ListFctTransactionMempoolOutcome7dResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_mempool_outcome_7d" + }; + } + // Get record | Retrieve a single record by first_seen_date_time + rpc Get(GetFctTransactionMempoolOutcome7dRequest) returns (GetFctTransactionMempoolOutcome7dResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_mempool_outcome_7d/{first_seen_date_time}" + }; + } +} diff --git a/pkg/proto/clickhouse/fct_transaction_mempool_outcome_daily.go b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_daily.go new file mode 100644 index 00000000..13fb76d7 --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_daily.go @@ -0,0 +1,640 @@ +// Code generated by clickhouse-proto-gen. DO NOT EDIT. +// SQL query builder for fct_transaction_mempool_outcome_daily + +package clickhouse + +import ( + "fmt" +) + +// BuildListFctTransactionMempoolOutcomeDailyQuery constructs a parameterized SQL query from a ListFctTransactionMempoolOutcomeDailyRequest +func BuildListFctTransactionMempoolOutcomeDailyQuery(req *ListFctTransactionMempoolOutcomeDailyRequest, options ...QueryOption) (SQLQuery, error) { + // Validate that at least one primary key is provided + // Primary keys can come from base table or projections + if req.DayStartDate == nil { + return SQLQuery{}, fmt.Errorf("primary key field day_start_date is required") + } + + // Build query using QueryBuilder + qb := NewQueryBuilder() + + // Add primary key filter + switch filter := req.DayStartDate.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("day_start_date", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("day_start_date", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("day_start_date", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("day_start_date", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("day_start_date", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("day_start_date", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("day_start_date", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("day_start_date", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("day_start_date", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + + // Add filter for column: updated_date_time + if req.UpdatedDateTime != nil { + switch filter := req.UpdatedDateTime.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("updated_date_time", "=", DateTimeValue{filter.Eq}) + case *UInt32Filter_Ne: + qb.AddCondition("updated_date_time", "!=", DateTimeValue{filter.Ne}) + case *UInt32Filter_Lt: + qb.AddCondition("updated_date_time", "<", DateTimeValue{filter.Lt}) + case *UInt32Filter_Lte: + qb.AddCondition("updated_date_time", "<=", DateTimeValue{filter.Lte}) + case *UInt32Filter_Gt: + qb.AddCondition("updated_date_time", ">", DateTimeValue{filter.Gt}) + case *UInt32Filter_Gte: + qb.AddCondition("updated_date_time", ">=", DateTimeValue{filter.Gte}) + case *UInt32Filter_Between: + qb.AddBetweenCondition("updated_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("updated_date_time", converted) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("updated_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: observed_count + if req.ObservedCount != nil { + switch filter := req.ObservedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("observed_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("observed_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("observed_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("observed_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("observed_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("observed_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("observed_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("observed_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("observed_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: included_count + if req.IncludedCount != nil { + switch filter := req.IncludedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("included_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("included_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("included_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("included_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("included_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("included_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("included_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("included_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("included_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: nonce_consumed_count + if req.NonceConsumedCount != nil { + switch filter := req.NonceConsumedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("nonce_consumed_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("nonce_consumed_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("nonce_consumed_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("nonce_consumed_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("nonce_consumed_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("nonce_consumed_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("nonce_consumed_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("nonce_consumed_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("nonce_consumed_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: unincluded_count + if req.UnincludedCount != nil { + switch filter := req.UnincludedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("unincluded_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("unincluded_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("unincluded_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("unincluded_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("unincluded_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("unincluded_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("unincluded_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("unincluded_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("unincluded_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: included_relay_delivered_count + if req.IncludedRelayDeliveredCount != nil { + switch filter := req.IncludedRelayDeliveredCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("included_relay_delivered_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("included_relay_delivered_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("included_relay_delivered_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("included_relay_delivered_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("included_relay_delivered_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("included_relay_delivered_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("included_relay_delivered_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("included_relay_delivered_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("included_relay_delivered_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: included_unknown_build_count + if req.IncludedUnknownBuildCount != nil { + switch filter := req.IncludedUnknownBuildCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("included_unknown_build_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("included_unknown_build_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("included_unknown_build_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("included_unknown_build_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("included_unknown_build_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("included_unknown_build_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("included_unknown_build_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("included_unknown_build_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("included_unknown_build_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: in_mempool_at_deadline_count + if req.InMempoolAtDeadlineCount != nil { + switch filter := req.InMempoolAtDeadlineCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("in_mempool_at_deadline_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("in_mempool_at_deadline_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("in_mempool_at_deadline_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("in_mempool_at_deadline_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("in_mempool_at_deadline_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("in_mempool_at_deadline_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("in_mempool_at_deadline_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("in_mempool_at_deadline_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("in_mempool_at_deadline_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: cancel_shape_count + if req.CancelShapeCount != nil { + switch filter := req.CancelShapeCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("cancel_shape_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("cancel_shape_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("cancel_shape_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("cancel_shape_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("cancel_shape_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("cancel_shape_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("cancel_shape_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("cancel_shape_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("cancel_shape_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: observed_after_nonce_consumed_count + if req.ObservedAfterNonceConsumedCount != nil { + switch filter := req.ObservedAfterNonceConsumedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("observed_after_nonce_consumed_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("observed_after_nonce_consumed_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("observed_after_nonce_consumed_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("observed_after_nonce_consumed_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("observed_after_nonce_consumed_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("observed_after_nonce_consumed_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("observed_after_nonce_consumed_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("observed_after_nonce_consumed_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("observed_after_nonce_consumed_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: wait_ms_p50 + + // Add filter for column: wait_ms_p90 + + // Add filter for column: wait_ms_p99 + + // Add filter for column: wait_sample_count + if req.WaitSampleCount != nil { + switch filter := req.WaitSampleCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("wait_sample_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("wait_sample_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("wait_sample_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("wait_sample_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("wait_sample_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("wait_sample_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("wait_sample_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("wait_sample_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("wait_sample_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: negative_wait_count + if req.NegativeWaitCount != nil { + switch filter := req.NegativeWaitCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("negative_wait_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("negative_wait_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("negative_wait_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("negative_wait_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("negative_wait_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("negative_wait_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("negative_wait_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("negative_wait_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("negative_wait_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_observed_count + if req.BlobObservedCount != nil { + switch filter := req.BlobObservedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("blob_observed_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("blob_observed_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("blob_observed_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("blob_observed_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("blob_observed_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("blob_observed_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("blob_observed_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("blob_observed_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("blob_observed_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_wait_ms_p50 + + // Add filter for column: blob_wait_ms_p90 + + // Add filter for column: blob_wait_ms_p99 + + // Add filter for column: blob_wait_sample_count + if req.BlobWaitSampleCount != nil { + switch filter := req.BlobWaitSampleCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("blob_wait_sample_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("blob_wait_sample_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("blob_wait_sample_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("blob_wait_sample_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("blob_wait_sample_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("blob_wait_sample_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("blob_wait_sample_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("blob_wait_sample_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("blob_wait_sample_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: nonce_group_count + if req.NonceGroupCount != nil { + switch filter := req.NonceGroupCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("nonce_group_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("nonce_group_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("nonce_group_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("nonce_group_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("nonce_group_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("nonce_group_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("nonce_group_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("nonce_group_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("nonce_group_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: multi_attempt_nonce_group_count + if req.MultiAttemptNonceGroupCount != nil { + switch filter := req.MultiAttemptNonceGroupCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("multi_attempt_nonce_group_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("multi_attempt_nonce_group_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("multi_attempt_nonce_group_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("multi_attempt_nonce_group_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("multi_attempt_nonce_group_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("multi_attempt_nonce_group_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("multi_attempt_nonce_group_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("multi_attempt_nonce_group_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("multi_attempt_nonce_group_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: replaced_attempt_count + if req.ReplacedAttemptCount != nil { + switch filter := req.ReplacedAttemptCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("replaced_attempt_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("replaced_attempt_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("replaced_attempt_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("replaced_attempt_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("replaced_attempt_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("replaced_attempt_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("replaced_attempt_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("replaced_attempt_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("replaced_attempt_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Handle pagination per AIP-132 + // Validate page size + if req.PageSize < 0 { + return SQLQuery{}, fmt.Errorf("page_size must be non-negative, got %d", req.PageSize) + } + if req.PageSize > 10000 { + return SQLQuery{}, fmt.Errorf("page_size must not exceed %d, got %d", 10000, req.PageSize) + } + + var limit, offset uint32 + limit = 100 // Default page size + if req.PageSize > 0 { + limit = uint32(req.PageSize) + } + if req.PageToken != "" { + decodedOffset, err := DecodePageToken(req.PageToken) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid page_token: %w", err) + } + offset = decodedOffset + } + + // Handle custom ordering if provided + var orderByClause string + if req.OrderBy != "" { + validFields := []string{"updated_date_time", "day_start_date", "observed_count", "included_count", "nonce_consumed_count", "unincluded_count", "included_relay_delivered_count", "included_unknown_build_count", "in_mempool_at_deadline_count", "cancel_shape_count", "observed_after_nonce_consumed_count", "wait_ms_p50", "wait_ms_p90", "wait_ms_p99", "wait_sample_count", "negative_wait_count", "blob_observed_count", "blob_wait_ms_p50", "blob_wait_ms_p90", "blob_wait_ms_p99", "blob_wait_sample_count", "nonce_group_count", "multi_attempt_nonce_group_count", "replaced_attempt_count"} + orderFields, err := ParseOrderBy(req.OrderBy, validFields) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid order_by: %w", err) + } + orderByClause = BuildOrderByClause(orderFields) + } else { + // Default sorting by primary key + orderByClause = " ORDER BY day_start_date" + } + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toString(`day_start_date`) AS `day_start_date`", "observed_count", "included_count", "nonce_consumed_count", "unincluded_count", "included_relay_delivered_count", "included_unknown_build_count", "in_mempool_at_deadline_count", "cancel_shape_count", "observed_after_nonce_consumed_count", "wait_ms_p50", "wait_ms_p90", "wait_ms_p99", "wait_sample_count", "negative_wait_count", "blob_observed_count", "blob_wait_ms_p50", "blob_wait_ms_p90", "blob_wait_ms_p99", "blob_wait_sample_count", "nonce_group_count", "multi_attempt_nonce_group_count", "replaced_attempt_count"} + + return BuildParameterizedQuery("fct_transaction_mempool_outcome_daily", columns, qb, orderByClause, limit, offset, options...) +} + +// BuildGetFctTransactionMempoolOutcomeDailyQuery constructs a parameterized SQL query from a GetFctTransactionMempoolOutcomeDailyRequest +func BuildGetFctTransactionMempoolOutcomeDailyQuery(req *GetFctTransactionMempoolOutcomeDailyRequest, options ...QueryOption) (SQLQuery, error) { + // Validate primary key is provided + if req.DayStartDate == "" { + return SQLQuery{}, fmt.Errorf("primary key field day_start_date is required") + } + + // Build query with primary key condition + qb := NewQueryBuilder() + qb.AddCondition("day_start_date", "=", req.DayStartDate) + + // Build ORDER BY clause + orderByClause := " ORDER BY day_start_date" + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toString(`day_start_date`) AS `day_start_date`", "observed_count", "included_count", "nonce_consumed_count", "unincluded_count", "included_relay_delivered_count", "included_unknown_build_count", "in_mempool_at_deadline_count", "cancel_shape_count", "observed_after_nonce_consumed_count", "wait_ms_p50", "wait_ms_p90", "wait_ms_p99", "wait_sample_count", "negative_wait_count", "blob_observed_count", "blob_wait_ms_p50", "blob_wait_ms_p90", "blob_wait_ms_p99", "blob_wait_sample_count", "nonce_group_count", "multi_attempt_nonce_group_count", "replaced_attempt_count"} + + // Return single record + return BuildParameterizedQuery("fct_transaction_mempool_outcome_daily", columns, qb, orderByClause, 1, 0, options...) +} diff --git a/pkg/proto/clickhouse/fct_transaction_mempool_outcome_daily.pb.go b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_daily.pb.go new file mode 100644 index 00000000..9a1b2a8a --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_daily.pb.go @@ -0,0 +1,1159 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc (unknown) +// source: fct_transaction_mempool_outcome_daily.proto + +package clickhouse + +import ( + _ "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse/clickhouse" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type FctTransactionMempoolOutcomeDaily struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Timestamp when the record was last updated + UpdatedDateTime uint32 `protobuf:"varint,11,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Start of the day period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the day has been processed and never change afterwards + DayStartDate string `protobuf:"bytes,12,opt,name=day_start_date,json=dayStartDate,proto3" json:"day_start_date,omitempty"` + // Transactions first sighted in the public mempool this day + ObservedCount uint64 `protobuf:"varint,13,opt,name=observed_count,json=observedCount,proto3" json:"observed_count,omitempty"` + // Observed transactions included within 7 days of first sighting + IncludedCount uint64 `protobuf:"varint,14,opt,name=included_count,json=includedCount,proto3" json:"included_count,omitempty"` + // Observed transactions whose nonce was consumed by a different transaction within 7 days + NonceConsumedCount uint64 `protobuf:"varint,15,opt,name=nonce_consumed_count,json=nonceConsumedCount,proto3" json:"nonce_consumed_count,omitempty"` + // Observed transactions with no inclusion of their nonce within 7 days + UnincludedCount uint64 `protobuf:"varint,16,opt,name=unincluded_count,json=unincludedCount,proto3" json:"unincluded_count,omitempty"` + // Included observed transactions whose block matched a known relay payload-delivered record + IncludedRelayDeliveredCount uint64 `protobuf:"varint,17,opt,name=included_relay_delivered_count,json=includedRelayDeliveredCount,proto3" json:"included_relay_delivered_count,omitempty"` + // Included observed transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built + IncludedUnknownBuildCount uint64 `protobuf:"varint,18,opt,name=included_unknown_build_count,json=includedUnknownBuildCount,proto3" json:"included_unknown_build_count,omitempty"` + // Unincluded transactions with a sighting in the final hour before the 7 day deadline + InMempoolAtDeadlineCount uint64 `protobuf:"varint,19,opt,name=in_mempool_at_deadline_count,json=inMempoolAtDeadlineCount,proto3" json:"in_mempool_at_deadline_count,omitempty"` + // Observed transactions that are self-transfers of zero value, the common wallet cancellation pattern + CancelShapeCount uint64 `protobuf:"varint,20,opt,name=cancel_shape_count,json=cancelShapeCount,proto3" json:"cancel_shape_count,omitempty"` + // Observed transactions first sighted after their nonce had already been consumed + ObservedAfterNonceConsumedCount uint64 `protobuf:"varint,21,opt,name=observed_after_nonce_consumed_count,json=observedAfterNonceConsumedCount,proto3" json:"observed_after_nonce_consumed_count,omitempty"` + // Median milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits + WaitMsP50 *wrapperspb.DoubleValue `protobuf:"bytes,22,opt,name=wait_ms_p50,json=waitMsP50,proto3" json:"wait_ms_p50,omitempty"` + // p90 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits + WaitMsP90 *wrapperspb.DoubleValue `protobuf:"bytes,23,opt,name=wait_ms_p90,json=waitMsP90,proto3" json:"wait_ms_p90,omitempty"` + // p99 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits + WaitMsP99 *wrapperspb.DoubleValue `protobuf:"bytes,24,opt,name=wait_ms_p99,json=waitMsP99,proto3" json:"wait_ms_p99,omitempty"` + // Number of included transactions contributing to the wait quantiles + WaitSampleCount uint64 `protobuf:"varint,25,opt,name=wait_sample_count,json=waitSampleCount,proto3" json:"wait_sample_count,omitempty"` + // Included transactions first sighted after their inclusion slot started, excluded from the wait quantiles + NegativeWaitCount uint64 `protobuf:"varint,26,opt,name=negative_wait_count,json=negativeWaitCount,proto3" json:"negative_wait_count,omitempty"` + // Observed blob type 3 transactions first sighted this day + BlobObservedCount uint64 `protobuf:"varint,27,opt,name=blob_observed_count,json=blobObservedCount,proto3" json:"blob_observed_count,omitempty"` + // Median wait milliseconds over included blob transactions with non-negative waits + BlobWaitMsP50 *wrapperspb.DoubleValue `protobuf:"bytes,28,opt,name=blob_wait_ms_p50,json=blobWaitMsP50,proto3" json:"blob_wait_ms_p50,omitempty"` + // p90 wait milliseconds over included blob transactions with non-negative waits + BlobWaitMsP90 *wrapperspb.DoubleValue `protobuf:"bytes,29,opt,name=blob_wait_ms_p90,json=blobWaitMsP90,proto3" json:"blob_wait_ms_p90,omitempty"` + // p99 wait milliseconds over included blob transactions with non-negative waits + BlobWaitMsP99 *wrapperspb.DoubleValue `protobuf:"bytes,30,opt,name=blob_wait_ms_p99,json=blobWaitMsP99,proto3" json:"blob_wait_ms_p99,omitempty"` + // Number of included blob transactions contributing to the blob wait quantiles + BlobWaitSampleCount uint64 `protobuf:"varint,31,opt,name=blob_wait_sample_count,json=blobWaitSampleCount,proto3" json:"blob_wait_sample_count,omitempty"` + // Distinct from and nonce pairs across transactions first sighted this day + NonceGroupCount uint64 `protobuf:"varint,32,opt,name=nonce_group_count,json=nonceGroupCount,proto3" json:"nonce_group_count,omitempty"` + // Nonce groups with at least two observed attempts, anchored to this day by their earliest attempt sighting + MultiAttemptNonceGroupCount uint64 `protobuf:"varint,33,opt,name=multi_attempt_nonce_group_count,json=multiAttemptNonceGroupCount,proto3" json:"multi_attempt_nonce_group_count,omitempty"` + // Non-winning attempts across multi-attempt nonce groups anchored to this day + ReplacedAttemptCount uint64 `protobuf:"varint,34,opt,name=replaced_attempt_count,json=replacedAttemptCount,proto3" json:"replaced_attempt_count,omitempty"` +} + +func (x *FctTransactionMempoolOutcomeDaily) Reset() { + *x = FctTransactionMempoolOutcomeDaily{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_daily_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FctTransactionMempoolOutcomeDaily) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FctTransactionMempoolOutcomeDaily) ProtoMessage() {} + +func (x *FctTransactionMempoolOutcomeDaily) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_daily_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FctTransactionMempoolOutcomeDaily.ProtoReflect.Descriptor instead. +func (*FctTransactionMempoolOutcomeDaily) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_daily_proto_rawDescGZIP(), []int{0} +} + +func (x *FctTransactionMempoolOutcomeDaily) GetUpdatedDateTime() uint32 { + if x != nil { + return x.UpdatedDateTime + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetDayStartDate() string { + if x != nil { + return x.DayStartDate + } + return "" +} + +func (x *FctTransactionMempoolOutcomeDaily) GetObservedCount() uint64 { + if x != nil { + return x.ObservedCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetIncludedCount() uint64 { + if x != nil { + return x.IncludedCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetNonceConsumedCount() uint64 { + if x != nil { + return x.NonceConsumedCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetUnincludedCount() uint64 { + if x != nil { + return x.UnincludedCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetIncludedRelayDeliveredCount() uint64 { + if x != nil { + return x.IncludedRelayDeliveredCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetIncludedUnknownBuildCount() uint64 { + if x != nil { + return x.IncludedUnknownBuildCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetInMempoolAtDeadlineCount() uint64 { + if x != nil { + return x.InMempoolAtDeadlineCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetCancelShapeCount() uint64 { + if x != nil { + return x.CancelShapeCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetObservedAfterNonceConsumedCount() uint64 { + if x != nil { + return x.ObservedAfterNonceConsumedCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetWaitMsP50() *wrapperspb.DoubleValue { + if x != nil { + return x.WaitMsP50 + } + return nil +} + +func (x *FctTransactionMempoolOutcomeDaily) GetWaitMsP90() *wrapperspb.DoubleValue { + if x != nil { + return x.WaitMsP90 + } + return nil +} + +func (x *FctTransactionMempoolOutcomeDaily) GetWaitMsP99() *wrapperspb.DoubleValue { + if x != nil { + return x.WaitMsP99 + } + return nil +} + +func (x *FctTransactionMempoolOutcomeDaily) GetWaitSampleCount() uint64 { + if x != nil { + return x.WaitSampleCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetNegativeWaitCount() uint64 { + if x != nil { + return x.NegativeWaitCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetBlobObservedCount() uint64 { + if x != nil { + return x.BlobObservedCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetBlobWaitMsP50() *wrapperspb.DoubleValue { + if x != nil { + return x.BlobWaitMsP50 + } + return nil +} + +func (x *FctTransactionMempoolOutcomeDaily) GetBlobWaitMsP90() *wrapperspb.DoubleValue { + if x != nil { + return x.BlobWaitMsP90 + } + return nil +} + +func (x *FctTransactionMempoolOutcomeDaily) GetBlobWaitMsP99() *wrapperspb.DoubleValue { + if x != nil { + return x.BlobWaitMsP99 + } + return nil +} + +func (x *FctTransactionMempoolOutcomeDaily) GetBlobWaitSampleCount() uint64 { + if x != nil { + return x.BlobWaitSampleCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetNonceGroupCount() uint64 { + if x != nil { + return x.NonceGroupCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetMultiAttemptNonceGroupCount() uint64 { + if x != nil { + return x.MultiAttemptNonceGroupCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeDaily) GetReplacedAttemptCount() uint64 { + if x != nil { + return x.ReplacedAttemptCount + } + return 0 +} + +// Request for listing fct_transaction_mempool_outcome_daily records +type ListFctTransactionMempoolOutcomeDailyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Filter by day_start_date - Start of the day period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the day has been processed and never change afterwards (PRIMARY KEY - required) + DayStartDate *StringFilter `protobuf:"bytes,1,opt,name=day_start_date,json=dayStartDate,proto3" json:"day_start_date,omitempty"` + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UpdatedDateTime *UInt32Filter `protobuf:"bytes,2,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Filter by observed_count - Transactions first sighted in the public mempool this day (optional) + ObservedCount *UInt64Filter `protobuf:"bytes,3,opt,name=observed_count,json=observedCount,proto3" json:"observed_count,omitempty"` + // Filter by included_count - Observed transactions included within 7 days of first sighting (optional) + IncludedCount *UInt64Filter `protobuf:"bytes,4,opt,name=included_count,json=includedCount,proto3" json:"included_count,omitempty"` + // Filter by nonce_consumed_count - Observed transactions whose nonce was consumed by a different transaction within 7 days (optional) + NonceConsumedCount *UInt64Filter `protobuf:"bytes,5,opt,name=nonce_consumed_count,json=nonceConsumedCount,proto3" json:"nonce_consumed_count,omitempty"` + // Filter by unincluded_count - Observed transactions with no inclusion of their nonce within 7 days (optional) + UnincludedCount *UInt64Filter `protobuf:"bytes,6,opt,name=unincluded_count,json=unincludedCount,proto3" json:"unincluded_count,omitempty"` + // Filter by included_relay_delivered_count - Included observed transactions whose block matched a known relay payload-delivered record (optional) + IncludedRelayDeliveredCount *UInt64Filter `protobuf:"bytes,7,opt,name=included_relay_delivered_count,json=includedRelayDeliveredCount,proto3" json:"included_relay_delivered_count,omitempty"` + // Filter by included_unknown_build_count - Included observed transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built (optional) + IncludedUnknownBuildCount *UInt64Filter `protobuf:"bytes,8,opt,name=included_unknown_build_count,json=includedUnknownBuildCount,proto3" json:"included_unknown_build_count,omitempty"` + // Filter by in_mempool_at_deadline_count - Unincluded transactions with a sighting in the final hour before the 7 day deadline (optional) + InMempoolAtDeadlineCount *UInt64Filter `protobuf:"bytes,9,opt,name=in_mempool_at_deadline_count,json=inMempoolAtDeadlineCount,proto3" json:"in_mempool_at_deadline_count,omitempty"` + // Filter by cancel_shape_count - Observed transactions that are self-transfers of zero value, the common wallet cancellation pattern (optional) + CancelShapeCount *UInt64Filter `protobuf:"bytes,10,opt,name=cancel_shape_count,json=cancelShapeCount,proto3" json:"cancel_shape_count,omitempty"` + // Filter by observed_after_nonce_consumed_count - Observed transactions first sighted after their nonce had already been consumed (optional) + ObservedAfterNonceConsumedCount *UInt64Filter `protobuf:"bytes,11,opt,name=observed_after_nonce_consumed_count,json=observedAfterNonceConsumedCount,proto3" json:"observed_after_nonce_consumed_count,omitempty"` + // Filter by wait_ms_p50 - Median milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits (optional) + WaitMsP50 *wrapperspb.DoubleValue `protobuf:"bytes,12,opt,name=wait_ms_p50,json=waitMsP50,proto3" json:"wait_ms_p50,omitempty"` + // Filter by wait_ms_p90 - p90 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits (optional) + WaitMsP90 *wrapperspb.DoubleValue `protobuf:"bytes,13,opt,name=wait_ms_p90,json=waitMsP90,proto3" json:"wait_ms_p90,omitempty"` + // Filter by wait_ms_p99 - p99 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits (optional) + WaitMsP99 *wrapperspb.DoubleValue `protobuf:"bytes,14,opt,name=wait_ms_p99,json=waitMsP99,proto3" json:"wait_ms_p99,omitempty"` + // Filter by wait_sample_count - Number of included transactions contributing to the wait quantiles (optional) + WaitSampleCount *UInt64Filter `protobuf:"bytes,15,opt,name=wait_sample_count,json=waitSampleCount,proto3" json:"wait_sample_count,omitempty"` + // Filter by negative_wait_count - Included transactions first sighted after their inclusion slot started, excluded from the wait quantiles (optional) + NegativeWaitCount *UInt64Filter `protobuf:"bytes,16,opt,name=negative_wait_count,json=negativeWaitCount,proto3" json:"negative_wait_count,omitempty"` + // Filter by blob_observed_count - Observed blob type 3 transactions first sighted this day (optional) + BlobObservedCount *UInt64Filter `protobuf:"bytes,17,opt,name=blob_observed_count,json=blobObservedCount,proto3" json:"blob_observed_count,omitempty"` + // Filter by blob_wait_ms_p50 - Median wait milliseconds over included blob transactions with non-negative waits (optional) + BlobWaitMsP50 *wrapperspb.DoubleValue `protobuf:"bytes,18,opt,name=blob_wait_ms_p50,json=blobWaitMsP50,proto3" json:"blob_wait_ms_p50,omitempty"` + // Filter by blob_wait_ms_p90 - p90 wait milliseconds over included blob transactions with non-negative waits (optional) + BlobWaitMsP90 *wrapperspb.DoubleValue `protobuf:"bytes,19,opt,name=blob_wait_ms_p90,json=blobWaitMsP90,proto3" json:"blob_wait_ms_p90,omitempty"` + // Filter by blob_wait_ms_p99 - p99 wait milliseconds over included blob transactions with non-negative waits (optional) + BlobWaitMsP99 *wrapperspb.DoubleValue `protobuf:"bytes,20,opt,name=blob_wait_ms_p99,json=blobWaitMsP99,proto3" json:"blob_wait_ms_p99,omitempty"` + // Filter by blob_wait_sample_count - Number of included blob transactions contributing to the blob wait quantiles (optional) + BlobWaitSampleCount *UInt64Filter `protobuf:"bytes,21,opt,name=blob_wait_sample_count,json=blobWaitSampleCount,proto3" json:"blob_wait_sample_count,omitempty"` + // Filter by nonce_group_count - Distinct from and nonce pairs across transactions first sighted this day (optional) + NonceGroupCount *UInt64Filter `protobuf:"bytes,22,opt,name=nonce_group_count,json=nonceGroupCount,proto3" json:"nonce_group_count,omitempty"` + // Filter by multi_attempt_nonce_group_count - Nonce groups with at least two observed attempts, anchored to this day by their earliest attempt sighting (optional) + MultiAttemptNonceGroupCount *UInt64Filter `protobuf:"bytes,23,opt,name=multi_attempt_nonce_group_count,json=multiAttemptNonceGroupCount,proto3" json:"multi_attempt_nonce_group_count,omitempty"` + // Filter by replaced_attempt_count - Non-winning attempts across multi-attempt nonce groups anchored to this day (optional) + ReplacedAttemptCount *UInt64Filter `protobuf:"bytes,24,opt,name=replaced_attempt_count,json=replacedAttemptCount,proto3" json:"replaced_attempt_count,omitempty"` + // The maximum number of fct_transaction_mempool_outcome_daily to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + PageSize int32 `protobuf:"varint,25,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // A page token, received from a previous `ListFctTransactionMempoolOutcomeDaily` call. + // Provide this to retrieve the subsequent page. + PageToken string `protobuf:"bytes,26,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + OrderBy string `protobuf:"bytes,27,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"` +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) Reset() { + *x = ListFctTransactionMempoolOutcomeDailyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_daily_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionMempoolOutcomeDailyRequest) ProtoMessage() {} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_daily_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionMempoolOutcomeDailyRequest.ProtoReflect.Descriptor instead. +func (*ListFctTransactionMempoolOutcomeDailyRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_daily_proto_rawDescGZIP(), []int{1} +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetDayStartDate() *StringFilter { + if x != nil { + return x.DayStartDate + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetUpdatedDateTime() *UInt32Filter { + if x != nil { + return x.UpdatedDateTime + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetObservedCount() *UInt64Filter { + if x != nil { + return x.ObservedCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetIncludedCount() *UInt64Filter { + if x != nil { + return x.IncludedCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetNonceConsumedCount() *UInt64Filter { + if x != nil { + return x.NonceConsumedCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetUnincludedCount() *UInt64Filter { + if x != nil { + return x.UnincludedCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetIncludedRelayDeliveredCount() *UInt64Filter { + if x != nil { + return x.IncludedRelayDeliveredCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetIncludedUnknownBuildCount() *UInt64Filter { + if x != nil { + return x.IncludedUnknownBuildCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetInMempoolAtDeadlineCount() *UInt64Filter { + if x != nil { + return x.InMempoolAtDeadlineCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetCancelShapeCount() *UInt64Filter { + if x != nil { + return x.CancelShapeCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetObservedAfterNonceConsumedCount() *UInt64Filter { + if x != nil { + return x.ObservedAfterNonceConsumedCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetWaitMsP50() *wrapperspb.DoubleValue { + if x != nil { + return x.WaitMsP50 + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetWaitMsP90() *wrapperspb.DoubleValue { + if x != nil { + return x.WaitMsP90 + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetWaitMsP99() *wrapperspb.DoubleValue { + if x != nil { + return x.WaitMsP99 + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetWaitSampleCount() *UInt64Filter { + if x != nil { + return x.WaitSampleCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetNegativeWaitCount() *UInt64Filter { + if x != nil { + return x.NegativeWaitCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetBlobObservedCount() *UInt64Filter { + if x != nil { + return x.BlobObservedCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetBlobWaitMsP50() *wrapperspb.DoubleValue { + if x != nil { + return x.BlobWaitMsP50 + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetBlobWaitMsP90() *wrapperspb.DoubleValue { + if x != nil { + return x.BlobWaitMsP90 + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetBlobWaitMsP99() *wrapperspb.DoubleValue { + if x != nil { + return x.BlobWaitMsP99 + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetBlobWaitSampleCount() *UInt64Filter { + if x != nil { + return x.BlobWaitSampleCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetNonceGroupCount() *UInt64Filter { + if x != nil { + return x.NonceGroupCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetMultiAttemptNonceGroupCount() *UInt64Filter { + if x != nil { + return x.MultiAttemptNonceGroupCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetReplacedAttemptCount() *UInt64Filter { + if x != nil { + return x.ReplacedAttemptCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +func (x *ListFctTransactionMempoolOutcomeDailyRequest) GetOrderBy() string { + if x != nil { + return x.OrderBy + } + return "" +} + +// Response for listing fct_transaction_mempool_outcome_daily records +type ListFctTransactionMempoolOutcomeDailyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of fct_transaction_mempool_outcome_daily. + FctTransactionMempoolOutcomeDaily []*FctTransactionMempoolOutcomeDaily `protobuf:"bytes,1,rep,name=fct_transaction_mempool_outcome_daily,json=fctTransactionMempoolOutcomeDaily,proto3" json:"fct_transaction_mempool_outcome_daily,omitempty"` + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` +} + +func (x *ListFctTransactionMempoolOutcomeDailyResponse) Reset() { + *x = ListFctTransactionMempoolOutcomeDailyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_daily_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionMempoolOutcomeDailyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionMempoolOutcomeDailyResponse) ProtoMessage() {} + +func (x *ListFctTransactionMempoolOutcomeDailyResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_daily_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionMempoolOutcomeDailyResponse.ProtoReflect.Descriptor instead. +func (*ListFctTransactionMempoolOutcomeDailyResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_daily_proto_rawDescGZIP(), []int{2} +} + +func (x *ListFctTransactionMempoolOutcomeDailyResponse) GetFctTransactionMempoolOutcomeDaily() []*FctTransactionMempoolOutcomeDaily { + if x != nil { + return x.FctTransactionMempoolOutcomeDaily + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeDailyResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +// Request for getting a single fct_transaction_mempool_outcome_daily record by primary key +type GetFctTransactionMempoolOutcomeDailyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Start of the day period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the day has been processed and never change afterwards + DayStartDate string `protobuf:"bytes,1,opt,name=day_start_date,json=dayStartDate,proto3" json:"day_start_date,omitempty"` // Primary key (required) +} + +func (x *GetFctTransactionMempoolOutcomeDailyRequest) Reset() { + *x = GetFctTransactionMempoolOutcomeDailyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_daily_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionMempoolOutcomeDailyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionMempoolOutcomeDailyRequest) ProtoMessage() {} + +func (x *GetFctTransactionMempoolOutcomeDailyRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_daily_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionMempoolOutcomeDailyRequest.ProtoReflect.Descriptor instead. +func (*GetFctTransactionMempoolOutcomeDailyRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_daily_proto_rawDescGZIP(), []int{3} +} + +func (x *GetFctTransactionMempoolOutcomeDailyRequest) GetDayStartDate() string { + if x != nil { + return x.DayStartDate + } + return "" +} + +// Response for getting a single fct_transaction_mempool_outcome_daily record +type GetFctTransactionMempoolOutcomeDailyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *FctTransactionMempoolOutcomeDaily `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *GetFctTransactionMempoolOutcomeDailyResponse) Reset() { + *x = GetFctTransactionMempoolOutcomeDailyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_daily_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionMempoolOutcomeDailyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionMempoolOutcomeDailyResponse) ProtoMessage() {} + +func (x *GetFctTransactionMempoolOutcomeDailyResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_daily_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionMempoolOutcomeDailyResponse.ProtoReflect.Descriptor instead. +func (*GetFctTransactionMempoolOutcomeDailyResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_daily_proto_rawDescGZIP(), []int{4} +} + +func (x *GetFctTransactionMempoolOutcomeDailyResponse) GetItem() *FctTransactionMempoolOutcomeDaily { + if x != nil { + return x.Item + } + return nil +} + +var File_fct_transaction_mempool_outcome_daily_proto protoreflect.FileDescriptor + +var file_fct_transaction_mempool_outcome_daily_proto_rawDesc = []byte{ + 0x0a, 0x2b, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, + 0x65, 0x5f, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x63, + 0x62, 0x74, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x1c, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xda, 0x0a, + 0x0a, 0x21, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x44, 0x61, + 0x69, 0x6c, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, + 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x24, 0x0a, 0x0e, 0x64, 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, + 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x61, 0x79, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6f, + 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x14, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6d, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x12, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x75, 0x6e, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0f, 0x75, 0x6e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x43, 0x0a, 0x1e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x6c, + 0x61, 0x79, 0x5f, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x64, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, 0x64, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x1c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x64, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x04, 0x52, 0x19, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x64, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x75, 0x69, 0x6c, + 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3e, 0x0a, 0x1c, 0x69, 0x6e, 0x5f, 0x6d, 0x65, 0x6d, + 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x61, 0x74, 0x5f, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x18, 0x69, 0x6e, + 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x41, 0x74, 0x44, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, + 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, + 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x14, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x10, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x70, 0x65, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4c, 0x0a, 0x23, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6d, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x1f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, + 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0b, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x35, + 0x30, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x77, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x35, 0x30, + 0x12, 0x3c, 0x0a, 0x0b, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x39, 0x30, 0x18, + 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x09, 0x77, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x39, 0x30, 0x12, 0x3c, + 0x0a, 0x0b, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x39, 0x39, 0x18, 0x18, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x09, 0x77, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x39, 0x39, 0x12, 0x2a, 0x0a, 0x11, + 0x77, 0x61, 0x69, 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x77, 0x61, 0x69, 0x74, 0x53, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x6e, 0x65, 0x67, 0x61, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x1a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x57, + 0x61, 0x69, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x62, 0x6c, 0x6f, 0x62, + 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x1b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x62, 0x6c, 0x6f, 0x62, 0x4f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, + 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x35, 0x30, 0x18, 0x1c, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x57, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x35, 0x30, 0x12, + 0x45, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, + 0x70, 0x39, 0x30, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, + 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x57, 0x61, 0x69, + 0x74, 0x4d, 0x73, 0x50, 0x39, 0x30, 0x12, 0x45, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x77, + 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x39, 0x39, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0d, + 0x62, 0x6c, 0x6f, 0x62, 0x57, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x39, 0x39, 0x12, 0x33, 0x0a, + 0x16, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x62, + 0x6c, 0x6f, 0x62, 0x57, 0x61, 0x69, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x20, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6e, + 0x6f, 0x6e, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x44, + 0x0a, 0x1f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x5f, + 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x21, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x41, 0x74, + 0x74, 0x65, 0x6d, 0x70, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x22, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x41, 0x74, + 0x74, 0x65, 0x6d, 0x70, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xa8, 0x0f, 0x0a, 0x2c, 0x4c, + 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x44, + 0x61, 0x69, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x0e, 0x64, + 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x12, 0xe0, 0x41, 0x02, 0x9a, 0xb5, 0x18, 0x0b, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x52, 0x0c, 0x64, 0x61, 0x79, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, 0x42, 0x0a, 0x11, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x0e, + 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, + 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x6f, 0x62, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x0e, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x48, 0x0a, 0x14, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, + 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, + 0x52, 0x12, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x10, 0x75, 0x6e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0f, 0x75, 0x6e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x5b, 0x0a, 0x1e, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x1b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x64, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, 0x64, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x57, 0x0a, 0x1c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, + 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, + 0x41, 0x01, 0x52, 0x19, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x55, 0x6e, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x56, 0x0a, + 0x1c, 0x69, 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x61, 0x74, 0x5f, 0x64, + 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x18, 0x69, 0x6e, 0x4d, + 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x41, 0x74, 0x44, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x44, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, + 0x73, 0x68, 0x61, 0x70, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x10, 0x63, 0x61, 0x6e, 0x63, 0x65, + 0x6c, 0x53, 0x68, 0x61, 0x70, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x64, 0x0a, 0x23, 0x6f, + 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, + 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, + 0x52, 0x1f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x4e, + 0x6f, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x41, 0x0a, 0x0b, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x35, 0x30, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x77, 0x61, 0x69, 0x74, 0x4d, + 0x73, 0x50, 0x35, 0x30, 0x12, 0x41, 0x0a, 0x0b, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, + 0x70, 0x39, 0x30, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, + 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x77, 0x61, + 0x69, 0x74, 0x4d, 0x73, 0x50, 0x39, 0x30, 0x12, 0x41, 0x0a, 0x0b, 0x77, 0x61, 0x69, 0x74, 0x5f, + 0x6d, 0x73, 0x5f, 0x70, 0x39, 0x39, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, + 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x09, 0x77, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x39, 0x39, 0x12, 0x42, 0x0a, 0x11, 0x77, 0x61, + 0x69, 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0f, 0x77, + 0x61, 0x69, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x46, + 0x0a, 0x13, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x11, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x57, 0x61, 0x69, + 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x46, 0x0a, 0x13, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x6f, + 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x11, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x11, 0x62, 0x6c, 0x6f, + 0x62, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4a, + 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, + 0x35, 0x30, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, + 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x62, 0x6c, 0x6f, + 0x62, 0x57, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x35, 0x30, 0x12, 0x4a, 0x0a, 0x10, 0x62, 0x6c, + 0x6f, 0x62, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x39, 0x30, 0x18, 0x13, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x57, 0x61, 0x69, + 0x74, 0x4d, 0x73, 0x50, 0x39, 0x30, 0x12, 0x4a, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x77, + 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x39, 0x39, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x57, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, + 0x39, 0x39, 0x12, 0x4b, 0x0a, 0x16, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, + 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x13, 0x62, 0x6c, 0x6f, 0x62, + 0x57, 0x61, 0x69, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x42, 0x0a, 0x11, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, + 0x41, 0x01, 0x52, 0x0f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x5c, 0x0a, 0x1f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x61, 0x74, 0x74, + 0x65, 0x6d, 0x70, 0x74, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, + 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, + 0x03, 0xe0, 0x41, 0x01, 0x52, 0x1b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x41, 0x74, 0x74, 0x65, 0x6d, + 0x70, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x4c, 0x0a, 0x16, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x74, 0x65, 0x6d, 0x70, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x18, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x14, 0x72, 0x65, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x64, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x20, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x19, 0x20, 0x01, + 0x28, 0x05, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, + 0x65, 0x12, 0x22, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x1a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1e, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, + 0x79, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, 0xd1, 0x01, 0x0a, 0x2d, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, + 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x25, 0x66, 0x63, 0x74, 0x5f, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, + 0x6f, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x64, 0x61, 0x69, 0x6c, 0x79, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x46, 0x63, 0x74, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, + 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x52, 0x21, + 0x66, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, + 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x44, 0x61, 0x69, 0x6c, + 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, + 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x53, 0x0a, 0x2b, 0x47, 0x65, 0x74, + 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, + 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x44, 0x61, 0x69, 0x6c, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x64, 0x61, 0x79, 0x5f, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x64, 0x61, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x22, 0x6a, + 0x0a, 0x2c, 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, + 0x65, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, + 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, + 0x62, 0x74, 0x2e, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x44, + 0x61, 0x69, 0x6c, 0x79, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0x86, 0x03, 0x0a, 0x28, 0x46, + 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, + 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x44, 0x61, 0x69, 0x6c, 0x79, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xa4, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, + 0x12, 0x31, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, + 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, + 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x12, + 0x2d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, + 0x5f, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x12, 0xb2, + 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x30, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x47, 0x65, 0x74, + 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, + 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x44, 0x61, 0x69, 0x6c, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x47, + 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x44, 0x61, + 0x69, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x40, 0x12, 0x3e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x63, 0x74, + 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x6d, + 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x64, 0x61, 0x69, + 0x6c, 0x79, 0x2f, 0x7b, 0x64, 0x61, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, + 0x74, 0x65, 0x7d, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x70, 0x61, 0x6e, 0x64, 0x61, 0x6f, 0x70, 0x73, 0x2f, 0x78, 0x61, + 0x74, 0x75, 0x2d, 0x63, 0x62, 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_fct_transaction_mempool_outcome_daily_proto_rawDescOnce sync.Once + file_fct_transaction_mempool_outcome_daily_proto_rawDescData = file_fct_transaction_mempool_outcome_daily_proto_rawDesc +) + +func file_fct_transaction_mempool_outcome_daily_proto_rawDescGZIP() []byte { + file_fct_transaction_mempool_outcome_daily_proto_rawDescOnce.Do(func() { + file_fct_transaction_mempool_outcome_daily_proto_rawDescData = protoimpl.X.CompressGZIP(file_fct_transaction_mempool_outcome_daily_proto_rawDescData) + }) + return file_fct_transaction_mempool_outcome_daily_proto_rawDescData +} + +var file_fct_transaction_mempool_outcome_daily_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_fct_transaction_mempool_outcome_daily_proto_goTypes = []any{ + (*FctTransactionMempoolOutcomeDaily)(nil), // 0: cbt.FctTransactionMempoolOutcomeDaily + (*ListFctTransactionMempoolOutcomeDailyRequest)(nil), // 1: cbt.ListFctTransactionMempoolOutcomeDailyRequest + (*ListFctTransactionMempoolOutcomeDailyResponse)(nil), // 2: cbt.ListFctTransactionMempoolOutcomeDailyResponse + (*GetFctTransactionMempoolOutcomeDailyRequest)(nil), // 3: cbt.GetFctTransactionMempoolOutcomeDailyRequest + (*GetFctTransactionMempoolOutcomeDailyResponse)(nil), // 4: cbt.GetFctTransactionMempoolOutcomeDailyResponse + (*wrapperspb.DoubleValue)(nil), // 5: google.protobuf.DoubleValue + (*StringFilter)(nil), // 6: cbt.StringFilter + (*UInt32Filter)(nil), // 7: cbt.UInt32Filter + (*UInt64Filter)(nil), // 8: cbt.UInt64Filter +} +var file_fct_transaction_mempool_outcome_daily_proto_depIdxs = []int32{ + 5, // 0: cbt.FctTransactionMempoolOutcomeDaily.wait_ms_p50:type_name -> google.protobuf.DoubleValue + 5, // 1: cbt.FctTransactionMempoolOutcomeDaily.wait_ms_p90:type_name -> google.protobuf.DoubleValue + 5, // 2: cbt.FctTransactionMempoolOutcomeDaily.wait_ms_p99:type_name -> google.protobuf.DoubleValue + 5, // 3: cbt.FctTransactionMempoolOutcomeDaily.blob_wait_ms_p50:type_name -> google.protobuf.DoubleValue + 5, // 4: cbt.FctTransactionMempoolOutcomeDaily.blob_wait_ms_p90:type_name -> google.protobuf.DoubleValue + 5, // 5: cbt.FctTransactionMempoolOutcomeDaily.blob_wait_ms_p99:type_name -> google.protobuf.DoubleValue + 6, // 6: cbt.ListFctTransactionMempoolOutcomeDailyRequest.day_start_date:type_name -> cbt.StringFilter + 7, // 7: cbt.ListFctTransactionMempoolOutcomeDailyRequest.updated_date_time:type_name -> cbt.UInt32Filter + 8, // 8: cbt.ListFctTransactionMempoolOutcomeDailyRequest.observed_count:type_name -> cbt.UInt64Filter + 8, // 9: cbt.ListFctTransactionMempoolOutcomeDailyRequest.included_count:type_name -> cbt.UInt64Filter + 8, // 10: cbt.ListFctTransactionMempoolOutcomeDailyRequest.nonce_consumed_count:type_name -> cbt.UInt64Filter + 8, // 11: cbt.ListFctTransactionMempoolOutcomeDailyRequest.unincluded_count:type_name -> cbt.UInt64Filter + 8, // 12: cbt.ListFctTransactionMempoolOutcomeDailyRequest.included_relay_delivered_count:type_name -> cbt.UInt64Filter + 8, // 13: cbt.ListFctTransactionMempoolOutcomeDailyRequest.included_unknown_build_count:type_name -> cbt.UInt64Filter + 8, // 14: cbt.ListFctTransactionMempoolOutcomeDailyRequest.in_mempool_at_deadline_count:type_name -> cbt.UInt64Filter + 8, // 15: cbt.ListFctTransactionMempoolOutcomeDailyRequest.cancel_shape_count:type_name -> cbt.UInt64Filter + 8, // 16: cbt.ListFctTransactionMempoolOutcomeDailyRequest.observed_after_nonce_consumed_count:type_name -> cbt.UInt64Filter + 5, // 17: cbt.ListFctTransactionMempoolOutcomeDailyRequest.wait_ms_p50:type_name -> google.protobuf.DoubleValue + 5, // 18: cbt.ListFctTransactionMempoolOutcomeDailyRequest.wait_ms_p90:type_name -> google.protobuf.DoubleValue + 5, // 19: cbt.ListFctTransactionMempoolOutcomeDailyRequest.wait_ms_p99:type_name -> google.protobuf.DoubleValue + 8, // 20: cbt.ListFctTransactionMempoolOutcomeDailyRequest.wait_sample_count:type_name -> cbt.UInt64Filter + 8, // 21: cbt.ListFctTransactionMempoolOutcomeDailyRequest.negative_wait_count:type_name -> cbt.UInt64Filter + 8, // 22: cbt.ListFctTransactionMempoolOutcomeDailyRequest.blob_observed_count:type_name -> cbt.UInt64Filter + 5, // 23: cbt.ListFctTransactionMempoolOutcomeDailyRequest.blob_wait_ms_p50:type_name -> google.protobuf.DoubleValue + 5, // 24: cbt.ListFctTransactionMempoolOutcomeDailyRequest.blob_wait_ms_p90:type_name -> google.protobuf.DoubleValue + 5, // 25: cbt.ListFctTransactionMempoolOutcomeDailyRequest.blob_wait_ms_p99:type_name -> google.protobuf.DoubleValue + 8, // 26: cbt.ListFctTransactionMempoolOutcomeDailyRequest.blob_wait_sample_count:type_name -> cbt.UInt64Filter + 8, // 27: cbt.ListFctTransactionMempoolOutcomeDailyRequest.nonce_group_count:type_name -> cbt.UInt64Filter + 8, // 28: cbt.ListFctTransactionMempoolOutcomeDailyRequest.multi_attempt_nonce_group_count:type_name -> cbt.UInt64Filter + 8, // 29: cbt.ListFctTransactionMempoolOutcomeDailyRequest.replaced_attempt_count:type_name -> cbt.UInt64Filter + 0, // 30: cbt.ListFctTransactionMempoolOutcomeDailyResponse.fct_transaction_mempool_outcome_daily:type_name -> cbt.FctTransactionMempoolOutcomeDaily + 0, // 31: cbt.GetFctTransactionMempoolOutcomeDailyResponse.item:type_name -> cbt.FctTransactionMempoolOutcomeDaily + 1, // 32: cbt.FctTransactionMempoolOutcomeDailyService.List:input_type -> cbt.ListFctTransactionMempoolOutcomeDailyRequest + 3, // 33: cbt.FctTransactionMempoolOutcomeDailyService.Get:input_type -> cbt.GetFctTransactionMempoolOutcomeDailyRequest + 2, // 34: cbt.FctTransactionMempoolOutcomeDailyService.List:output_type -> cbt.ListFctTransactionMempoolOutcomeDailyResponse + 4, // 35: cbt.FctTransactionMempoolOutcomeDailyService.Get:output_type -> cbt.GetFctTransactionMempoolOutcomeDailyResponse + 34, // [34:36] is the sub-list for method output_type + 32, // [32:34] is the sub-list for method input_type + 32, // [32:32] is the sub-list for extension type_name + 32, // [32:32] is the sub-list for extension extendee + 0, // [0:32] is the sub-list for field type_name +} + +func init() { file_fct_transaction_mempool_outcome_daily_proto_init() } +func file_fct_transaction_mempool_outcome_daily_proto_init() { + if File_fct_transaction_mempool_outcome_daily_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_fct_transaction_mempool_outcome_daily_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*FctTransactionMempoolOutcomeDaily); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_mempool_outcome_daily_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionMempoolOutcomeDailyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_mempool_outcome_daily_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionMempoolOutcomeDailyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_mempool_outcome_daily_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionMempoolOutcomeDailyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_mempool_outcome_daily_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionMempoolOutcomeDailyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_fct_transaction_mempool_outcome_daily_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_fct_transaction_mempool_outcome_daily_proto_goTypes, + DependencyIndexes: file_fct_transaction_mempool_outcome_daily_proto_depIdxs, + MessageInfos: file_fct_transaction_mempool_outcome_daily_proto_msgTypes, + }.Build() + File_fct_transaction_mempool_outcome_daily_proto = out.File + file_fct_transaction_mempool_outcome_daily_proto_rawDesc = nil + file_fct_transaction_mempool_outcome_daily_proto_goTypes = nil + file_fct_transaction_mempool_outcome_daily_proto_depIdxs = nil +} diff --git a/pkg/proto/clickhouse/fct_transaction_mempool_outcome_daily.proto b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_daily.proto new file mode 100644 index 00000000..0d042a8e --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_daily.proto @@ -0,0 +1,164 @@ +syntax = "proto3"; + +package cbt; + +import "common.proto"; +import "google/protobuf/wrappers.proto"; +import "google/api/annotations.proto"; +import "google/api/field_behavior.proto"; +import "clickhouse/annotations.proto"; + +option go_package = "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse"; +// Daily cohort outcomes for transactions first sighted in the public mempool, resolved at the fixed 7 day horizon + +message FctTransactionMempoolOutcomeDaily { + // Timestamp when the record was last updated + uint32 updated_date_time = 11; + // Start of the day period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the day has been processed and never change afterwards + string day_start_date = 12; + // Transactions first sighted in the public mempool this day + uint64 observed_count = 13; + // Observed transactions included within 7 days of first sighting + uint64 included_count = 14; + // Observed transactions whose nonce was consumed by a different transaction within 7 days + uint64 nonce_consumed_count = 15; + // Observed transactions with no inclusion of their nonce within 7 days + uint64 unincluded_count = 16; + // Included observed transactions whose block matched a known relay payload-delivered record + uint64 included_relay_delivered_count = 17; + // Included observed transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built + uint64 included_unknown_build_count = 18; + // Unincluded transactions with a sighting in the final hour before the 7 day deadline + uint64 in_mempool_at_deadline_count = 19; + // Observed transactions that are self-transfers of zero value, the common wallet cancellation pattern + uint64 cancel_shape_count = 20; + // Observed transactions first sighted after their nonce had already been consumed + uint64 observed_after_nonce_consumed_count = 21; + // Median milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits + google.protobuf.DoubleValue wait_ms_p50 = 22; + // p90 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits + google.protobuf.DoubleValue wait_ms_p90 = 23; + // p99 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits + google.protobuf.DoubleValue wait_ms_p99 = 24; + // Number of included transactions contributing to the wait quantiles + uint64 wait_sample_count = 25; + // Included transactions first sighted after their inclusion slot started, excluded from the wait quantiles + uint64 negative_wait_count = 26; + // Observed blob type 3 transactions first sighted this day + uint64 blob_observed_count = 27; + // Median wait milliseconds over included blob transactions with non-negative waits + google.protobuf.DoubleValue blob_wait_ms_p50 = 28; + // p90 wait milliseconds over included blob transactions with non-negative waits + google.protobuf.DoubleValue blob_wait_ms_p90 = 29; + // p99 wait milliseconds over included blob transactions with non-negative waits + google.protobuf.DoubleValue blob_wait_ms_p99 = 30; + // Number of included blob transactions contributing to the blob wait quantiles + uint64 blob_wait_sample_count = 31; + // Distinct from and nonce pairs across transactions first sighted this day + uint64 nonce_group_count = 32; + // Nonce groups with at least two observed attempts, anchored to this day by their earliest attempt sighting + uint64 multi_attempt_nonce_group_count = 33; + // Non-winning attempts across multi-attempt nonce groups anchored to this day + uint64 replaced_attempt_count = 34; +} + +// Request for listing fct_transaction_mempool_outcome_daily records +message ListFctTransactionMempoolOutcomeDailyRequest { + // Filter by day_start_date - Start of the day period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the day has been processed and never change afterwards (PRIMARY KEY - required) + StringFilter day_start_date = 1 [(google.api.field_behavior) = REQUIRED, (clickhouse.v1.required_group) = "primary_key"]; + + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UInt32Filter updated_date_time = 2 [(google.api.field_behavior) = OPTIONAL]; + // Filter by observed_count - Transactions first sighted in the public mempool this day (optional) + UInt64Filter observed_count = 3 [(google.api.field_behavior) = OPTIONAL]; + // Filter by included_count - Observed transactions included within 7 days of first sighting (optional) + UInt64Filter included_count = 4 [(google.api.field_behavior) = OPTIONAL]; + // Filter by nonce_consumed_count - Observed transactions whose nonce was consumed by a different transaction within 7 days (optional) + UInt64Filter nonce_consumed_count = 5 [(google.api.field_behavior) = OPTIONAL]; + // Filter by unincluded_count - Observed transactions with no inclusion of their nonce within 7 days (optional) + UInt64Filter unincluded_count = 6 [(google.api.field_behavior) = OPTIONAL]; + // Filter by included_relay_delivered_count - Included observed transactions whose block matched a known relay payload-delivered record (optional) + UInt64Filter included_relay_delivered_count = 7 [(google.api.field_behavior) = OPTIONAL]; + // Filter by included_unknown_build_count - Included observed transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built (optional) + UInt64Filter included_unknown_build_count = 8 [(google.api.field_behavior) = OPTIONAL]; + // Filter by in_mempool_at_deadline_count - Unincluded transactions with a sighting in the final hour before the 7 day deadline (optional) + UInt64Filter in_mempool_at_deadline_count = 9 [(google.api.field_behavior) = OPTIONAL]; + // Filter by cancel_shape_count - Observed transactions that are self-transfers of zero value, the common wallet cancellation pattern (optional) + UInt64Filter cancel_shape_count = 10 [(google.api.field_behavior) = OPTIONAL]; + // Filter by observed_after_nonce_consumed_count - Observed transactions first sighted after their nonce had already been consumed (optional) + UInt64Filter observed_after_nonce_consumed_count = 11 [(google.api.field_behavior) = OPTIONAL]; + // Filter by wait_ms_p50 - Median milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits (optional) + google.protobuf.DoubleValue wait_ms_p50 = 12 [(google.api.field_behavior) = OPTIONAL]; + // Filter by wait_ms_p90 - p90 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits (optional) + google.protobuf.DoubleValue wait_ms_p90 = 13 [(google.api.field_behavior) = OPTIONAL]; + // Filter by wait_ms_p99 - p99 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits (optional) + google.protobuf.DoubleValue wait_ms_p99 = 14 [(google.api.field_behavior) = OPTIONAL]; + // Filter by wait_sample_count - Number of included transactions contributing to the wait quantiles (optional) + UInt64Filter wait_sample_count = 15 [(google.api.field_behavior) = OPTIONAL]; + // Filter by negative_wait_count - Included transactions first sighted after their inclusion slot started, excluded from the wait quantiles (optional) + UInt64Filter negative_wait_count = 16 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_observed_count - Observed blob type 3 transactions first sighted this day (optional) + UInt64Filter blob_observed_count = 17 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_wait_ms_p50 - Median wait milliseconds over included blob transactions with non-negative waits (optional) + google.protobuf.DoubleValue blob_wait_ms_p50 = 18 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_wait_ms_p90 - p90 wait milliseconds over included blob transactions with non-negative waits (optional) + google.protobuf.DoubleValue blob_wait_ms_p90 = 19 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_wait_ms_p99 - p99 wait milliseconds over included blob transactions with non-negative waits (optional) + google.protobuf.DoubleValue blob_wait_ms_p99 = 20 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_wait_sample_count - Number of included blob transactions contributing to the blob wait quantiles (optional) + UInt64Filter blob_wait_sample_count = 21 [(google.api.field_behavior) = OPTIONAL]; + // Filter by nonce_group_count - Distinct from and nonce pairs across transactions first sighted this day (optional) + UInt64Filter nonce_group_count = 22 [(google.api.field_behavior) = OPTIONAL]; + // Filter by multi_attempt_nonce_group_count - Nonce groups with at least two observed attempts, anchored to this day by their earliest attempt sighting (optional) + UInt64Filter multi_attempt_nonce_group_count = 23 [(google.api.field_behavior) = OPTIONAL]; + // Filter by replaced_attempt_count - Non-winning attempts across multi-attempt nonce groups anchored to this day (optional) + UInt64Filter replaced_attempt_count = 24 [(google.api.field_behavior) = OPTIONAL]; + + // The maximum number of fct_transaction_mempool_outcome_daily to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + int32 page_size = 25 [(google.api.field_behavior) = OPTIONAL]; + // A page token, received from a previous `ListFctTransactionMempoolOutcomeDaily` call. + // Provide this to retrieve the subsequent page. + string page_token = 26 [(google.api.field_behavior) = OPTIONAL]; + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + string order_by = 27 [(google.api.field_behavior) = OPTIONAL]; +} + +// Response for listing fct_transaction_mempool_outcome_daily records +message ListFctTransactionMempoolOutcomeDailyResponse { + // The list of fct_transaction_mempool_outcome_daily. + repeated FctTransactionMempoolOutcomeDaily fct_transaction_mempool_outcome_daily = 1; + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; +} + +// Request for getting a single fct_transaction_mempool_outcome_daily record by primary key +message GetFctTransactionMempoolOutcomeDailyRequest { + // Start of the day period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the day has been processed and never change afterwards + string day_start_date = 1; // Primary key (required) +} + +// Response for getting a single fct_transaction_mempool_outcome_daily record +message GetFctTransactionMempoolOutcomeDailyResponse { + FctTransactionMempoolOutcomeDaily item = 1; +} + +// Query fct_transaction_mempool_outcome_daily data +service FctTransactionMempoolOutcomeDailyService { + // List records | Retrieve paginated results with optional filtering + rpc List(ListFctTransactionMempoolOutcomeDailyRequest) returns (ListFctTransactionMempoolOutcomeDailyResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_mempool_outcome_daily" + }; + } + // Get record | Retrieve a single record by day_start_date + rpc Get(GetFctTransactionMempoolOutcomeDailyRequest) returns (GetFctTransactionMempoolOutcomeDailyResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_mempool_outcome_daily/{day_start_date}" + }; + } +} diff --git a/pkg/proto/clickhouse/fct_transaction_mempool_outcome_hourly.go b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_hourly.go new file mode 100644 index 00000000..de0968ba --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_hourly.go @@ -0,0 +1,648 @@ +// Code generated by clickhouse-proto-gen. DO NOT EDIT. +// SQL query builder for fct_transaction_mempool_outcome_hourly + +package clickhouse + +import ( + "fmt" +) + +// BuildListFctTransactionMempoolOutcomeHourlyQuery constructs a parameterized SQL query from a ListFctTransactionMempoolOutcomeHourlyRequest +func BuildListFctTransactionMempoolOutcomeHourlyQuery(req *ListFctTransactionMempoolOutcomeHourlyRequest, options ...QueryOption) (SQLQuery, error) { + // Validate that at least one primary key is provided + // Primary keys can come from base table or projections + if req.HourStartDateTime == nil { + return SQLQuery{}, fmt.Errorf("primary key field hour_start_date_time is required") + } + + // Build query using QueryBuilder + qb := NewQueryBuilder() + + // Add primary key filter + switch filter := req.HourStartDateTime.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("hour_start_date_time", "=", DateTimeValue{filter.Eq}) + case *UInt32Filter_Ne: + qb.AddCondition("hour_start_date_time", "!=", DateTimeValue{filter.Ne}) + case *UInt32Filter_Lt: + qb.AddCondition("hour_start_date_time", "<", DateTimeValue{filter.Lt}) + case *UInt32Filter_Lte: + qb.AddCondition("hour_start_date_time", "<=", DateTimeValue{filter.Lte}) + case *UInt32Filter_Gt: + qb.AddCondition("hour_start_date_time", ">", DateTimeValue{filter.Gt}) + case *UInt32Filter_Gte: + qb.AddCondition("hour_start_date_time", ">=", DateTimeValue{filter.Gte}) + case *UInt32Filter_Between: + qb.AddBetweenCondition("hour_start_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("hour_start_date_time", converted) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("hour_start_date_time", converted) + } + default: + // Unsupported filter type + } + + // Add filter for column: updated_date_time + if req.UpdatedDateTime != nil { + switch filter := req.UpdatedDateTime.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("updated_date_time", "=", DateTimeValue{filter.Eq}) + case *UInt32Filter_Ne: + qb.AddCondition("updated_date_time", "!=", DateTimeValue{filter.Ne}) + case *UInt32Filter_Lt: + qb.AddCondition("updated_date_time", "<", DateTimeValue{filter.Lt}) + case *UInt32Filter_Lte: + qb.AddCondition("updated_date_time", "<=", DateTimeValue{filter.Lte}) + case *UInt32Filter_Gt: + qb.AddCondition("updated_date_time", ">", DateTimeValue{filter.Gt}) + case *UInt32Filter_Gte: + qb.AddCondition("updated_date_time", ">=", DateTimeValue{filter.Gte}) + case *UInt32Filter_Between: + qb.AddBetweenCondition("updated_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("updated_date_time", converted) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("updated_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: observed_count + if req.ObservedCount != nil { + switch filter := req.ObservedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("observed_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("observed_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("observed_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("observed_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("observed_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("observed_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("observed_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("observed_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("observed_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: included_count + if req.IncludedCount != nil { + switch filter := req.IncludedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("included_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("included_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("included_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("included_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("included_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("included_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("included_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("included_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("included_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: nonce_consumed_count + if req.NonceConsumedCount != nil { + switch filter := req.NonceConsumedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("nonce_consumed_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("nonce_consumed_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("nonce_consumed_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("nonce_consumed_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("nonce_consumed_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("nonce_consumed_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("nonce_consumed_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("nonce_consumed_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("nonce_consumed_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: unincluded_count + if req.UnincludedCount != nil { + switch filter := req.UnincludedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("unincluded_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("unincluded_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("unincluded_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("unincluded_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("unincluded_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("unincluded_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("unincluded_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("unincluded_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("unincluded_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: included_relay_delivered_count + if req.IncludedRelayDeliveredCount != nil { + switch filter := req.IncludedRelayDeliveredCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("included_relay_delivered_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("included_relay_delivered_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("included_relay_delivered_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("included_relay_delivered_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("included_relay_delivered_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("included_relay_delivered_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("included_relay_delivered_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("included_relay_delivered_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("included_relay_delivered_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: included_unknown_build_count + if req.IncludedUnknownBuildCount != nil { + switch filter := req.IncludedUnknownBuildCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("included_unknown_build_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("included_unknown_build_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("included_unknown_build_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("included_unknown_build_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("included_unknown_build_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("included_unknown_build_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("included_unknown_build_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("included_unknown_build_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("included_unknown_build_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: in_mempool_at_deadline_count + if req.InMempoolAtDeadlineCount != nil { + switch filter := req.InMempoolAtDeadlineCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("in_mempool_at_deadline_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("in_mempool_at_deadline_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("in_mempool_at_deadline_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("in_mempool_at_deadline_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("in_mempool_at_deadline_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("in_mempool_at_deadline_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("in_mempool_at_deadline_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("in_mempool_at_deadline_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("in_mempool_at_deadline_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: cancel_shape_count + if req.CancelShapeCount != nil { + switch filter := req.CancelShapeCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("cancel_shape_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("cancel_shape_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("cancel_shape_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("cancel_shape_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("cancel_shape_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("cancel_shape_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("cancel_shape_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("cancel_shape_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("cancel_shape_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: observed_after_nonce_consumed_count + if req.ObservedAfterNonceConsumedCount != nil { + switch filter := req.ObservedAfterNonceConsumedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("observed_after_nonce_consumed_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("observed_after_nonce_consumed_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("observed_after_nonce_consumed_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("observed_after_nonce_consumed_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("observed_after_nonce_consumed_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("observed_after_nonce_consumed_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("observed_after_nonce_consumed_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("observed_after_nonce_consumed_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("observed_after_nonce_consumed_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: wait_ms_p50 + + // Add filter for column: wait_ms_p90 + + // Add filter for column: wait_ms_p99 + + // Add filter for column: wait_sample_count + if req.WaitSampleCount != nil { + switch filter := req.WaitSampleCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("wait_sample_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("wait_sample_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("wait_sample_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("wait_sample_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("wait_sample_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("wait_sample_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("wait_sample_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("wait_sample_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("wait_sample_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: negative_wait_count + if req.NegativeWaitCount != nil { + switch filter := req.NegativeWaitCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("negative_wait_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("negative_wait_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("negative_wait_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("negative_wait_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("negative_wait_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("negative_wait_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("negative_wait_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("negative_wait_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("negative_wait_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_observed_count + if req.BlobObservedCount != nil { + switch filter := req.BlobObservedCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("blob_observed_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("blob_observed_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("blob_observed_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("blob_observed_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("blob_observed_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("blob_observed_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("blob_observed_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("blob_observed_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("blob_observed_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_wait_ms_p50 + + // Add filter for column: blob_wait_ms_p90 + + // Add filter for column: blob_wait_ms_p99 + + // Add filter for column: blob_wait_sample_count + if req.BlobWaitSampleCount != nil { + switch filter := req.BlobWaitSampleCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("blob_wait_sample_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("blob_wait_sample_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("blob_wait_sample_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("blob_wait_sample_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("blob_wait_sample_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("blob_wait_sample_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("blob_wait_sample_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("blob_wait_sample_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("blob_wait_sample_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: nonce_group_count + if req.NonceGroupCount != nil { + switch filter := req.NonceGroupCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("nonce_group_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("nonce_group_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("nonce_group_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("nonce_group_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("nonce_group_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("nonce_group_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("nonce_group_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("nonce_group_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("nonce_group_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: multi_attempt_nonce_group_count + if req.MultiAttemptNonceGroupCount != nil { + switch filter := req.MultiAttemptNonceGroupCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("multi_attempt_nonce_group_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("multi_attempt_nonce_group_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("multi_attempt_nonce_group_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("multi_attempt_nonce_group_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("multi_attempt_nonce_group_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("multi_attempt_nonce_group_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("multi_attempt_nonce_group_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("multi_attempt_nonce_group_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("multi_attempt_nonce_group_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: replaced_attempt_count + if req.ReplacedAttemptCount != nil { + switch filter := req.ReplacedAttemptCount.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("replaced_attempt_count", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("replaced_attempt_count", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("replaced_attempt_count", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("replaced_attempt_count", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("replaced_attempt_count", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("replaced_attempt_count", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("replaced_attempt_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("replaced_attempt_count", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("replaced_attempt_count", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Handle pagination per AIP-132 + // Validate page size + if req.PageSize < 0 { + return SQLQuery{}, fmt.Errorf("page_size must be non-negative, got %d", req.PageSize) + } + if req.PageSize > 10000 { + return SQLQuery{}, fmt.Errorf("page_size must not exceed %d, got %d", 10000, req.PageSize) + } + + var limit, offset uint32 + limit = 100 // Default page size + if req.PageSize > 0 { + limit = uint32(req.PageSize) + } + if req.PageToken != "" { + decodedOffset, err := DecodePageToken(req.PageToken) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid page_token: %w", err) + } + offset = decodedOffset + } + + // Handle custom ordering if provided + var orderByClause string + if req.OrderBy != "" { + validFields := []string{"updated_date_time", "hour_start_date_time", "observed_count", "included_count", "nonce_consumed_count", "unincluded_count", "included_relay_delivered_count", "included_unknown_build_count", "in_mempool_at_deadline_count", "cancel_shape_count", "observed_after_nonce_consumed_count", "wait_ms_p50", "wait_ms_p90", "wait_ms_p99", "wait_sample_count", "negative_wait_count", "blob_observed_count", "blob_wait_ms_p50", "blob_wait_ms_p90", "blob_wait_ms_p99", "blob_wait_sample_count", "nonce_group_count", "multi_attempt_nonce_group_count", "replaced_attempt_count"} + orderFields, err := ParseOrderBy(req.OrderBy, validFields) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid order_by: %w", err) + } + orderByClause = BuildOrderByClause(orderFields) + } else { + // Default sorting by primary key + orderByClause = " ORDER BY hour_start_date_time" + } + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toUnixTimestamp(`hour_start_date_time`) AS `hour_start_date_time`", "observed_count", "included_count", "nonce_consumed_count", "unincluded_count", "included_relay_delivered_count", "included_unknown_build_count", "in_mempool_at_deadline_count", "cancel_shape_count", "observed_after_nonce_consumed_count", "wait_ms_p50", "wait_ms_p90", "wait_ms_p99", "wait_sample_count", "negative_wait_count", "blob_observed_count", "blob_wait_ms_p50", "blob_wait_ms_p90", "blob_wait_ms_p99", "blob_wait_sample_count", "nonce_group_count", "multi_attempt_nonce_group_count", "replaced_attempt_count"} + + return BuildParameterizedQuery("fct_transaction_mempool_outcome_hourly", columns, qb, orderByClause, limit, offset, options...) +} + +// BuildGetFctTransactionMempoolOutcomeHourlyQuery constructs a parameterized SQL query from a GetFctTransactionMempoolOutcomeHourlyRequest +func BuildGetFctTransactionMempoolOutcomeHourlyQuery(req *GetFctTransactionMempoolOutcomeHourlyRequest, options ...QueryOption) (SQLQuery, error) { + // Validate primary key is provided + if req.HourStartDateTime == 0 { + return SQLQuery{}, fmt.Errorf("primary key field hour_start_date_time is required") + } + + // Build query with primary key condition + qb := NewQueryBuilder() + qb.AddCondition("hour_start_date_time", "=", req.HourStartDateTime) + + // Build ORDER BY clause + orderByClause := " ORDER BY hour_start_date_time" + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toUnixTimestamp(`hour_start_date_time`) AS `hour_start_date_time`", "observed_count", "included_count", "nonce_consumed_count", "unincluded_count", "included_relay_delivered_count", "included_unknown_build_count", "in_mempool_at_deadline_count", "cancel_shape_count", "observed_after_nonce_consumed_count", "wait_ms_p50", "wait_ms_p90", "wait_ms_p99", "wait_sample_count", "negative_wait_count", "blob_observed_count", "blob_wait_ms_p50", "blob_wait_ms_p90", "blob_wait_ms_p99", "blob_wait_sample_count", "nonce_group_count", "multi_attempt_nonce_group_count", "replaced_attempt_count"} + + // Return single record + return BuildParameterizedQuery("fct_transaction_mempool_outcome_hourly", columns, qb, orderByClause, 1, 0, options...) +} diff --git a/pkg/proto/clickhouse/fct_transaction_mempool_outcome_hourly.pb.go b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_hourly.pb.go new file mode 100644 index 00000000..823e122e --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_hourly.pb.go @@ -0,0 +1,1161 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc (unknown) +// source: fct_transaction_mempool_outcome_hourly.proto + +package clickhouse + +import ( + _ "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse/clickhouse" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type FctTransactionMempoolOutcomeHourly struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Timestamp when the record was last updated + UpdatedDateTime uint32 `protobuf:"varint,11,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Start of the hour period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the hour has been processed and never change afterwards + HourStartDateTime uint32 `protobuf:"varint,12,opt,name=hour_start_date_time,json=hourStartDateTime,proto3" json:"hour_start_date_time,omitempty"` + // Transactions first sighted in the public mempool this hour + ObservedCount uint64 `protobuf:"varint,13,opt,name=observed_count,json=observedCount,proto3" json:"observed_count,omitempty"` + // Observed transactions included within 7 days of first sighting + IncludedCount uint64 `protobuf:"varint,14,opt,name=included_count,json=includedCount,proto3" json:"included_count,omitempty"` + // Observed transactions whose nonce was consumed by a different transaction within 7 days + NonceConsumedCount uint64 `protobuf:"varint,15,opt,name=nonce_consumed_count,json=nonceConsumedCount,proto3" json:"nonce_consumed_count,omitempty"` + // Observed transactions with no inclusion of their nonce within 7 days + UnincludedCount uint64 `protobuf:"varint,16,opt,name=unincluded_count,json=unincludedCount,proto3" json:"unincluded_count,omitempty"` + // Included observed transactions whose block matched a known relay payload-delivered record + IncludedRelayDeliveredCount uint64 `protobuf:"varint,17,opt,name=included_relay_delivered_count,json=includedRelayDeliveredCount,proto3" json:"included_relay_delivered_count,omitempty"` + // Included observed transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built + IncludedUnknownBuildCount uint64 `protobuf:"varint,18,opt,name=included_unknown_build_count,json=includedUnknownBuildCount,proto3" json:"included_unknown_build_count,omitempty"` + // Unincluded transactions with a sighting in the final hour before the 7 day deadline + InMempoolAtDeadlineCount uint64 `protobuf:"varint,19,opt,name=in_mempool_at_deadline_count,json=inMempoolAtDeadlineCount,proto3" json:"in_mempool_at_deadline_count,omitempty"` + // Observed transactions that are self-transfers of zero value, the common wallet cancellation pattern + CancelShapeCount uint64 `protobuf:"varint,20,opt,name=cancel_shape_count,json=cancelShapeCount,proto3" json:"cancel_shape_count,omitempty"` + // Observed transactions first sighted after their nonce had already been consumed + ObservedAfterNonceConsumedCount uint64 `protobuf:"varint,21,opt,name=observed_after_nonce_consumed_count,json=observedAfterNonceConsumedCount,proto3" json:"observed_after_nonce_consumed_count,omitempty"` + // Median milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits + WaitMsP50 *wrapperspb.DoubleValue `protobuf:"bytes,22,opt,name=wait_ms_p50,json=waitMsP50,proto3" json:"wait_ms_p50,omitempty"` + // p90 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits + WaitMsP90 *wrapperspb.DoubleValue `protobuf:"bytes,23,opt,name=wait_ms_p90,json=waitMsP90,proto3" json:"wait_ms_p90,omitempty"` + // p99 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits + WaitMsP99 *wrapperspb.DoubleValue `protobuf:"bytes,24,opt,name=wait_ms_p99,json=waitMsP99,proto3" json:"wait_ms_p99,omitempty"` + // Number of included transactions contributing to the wait quantiles + WaitSampleCount uint64 `protobuf:"varint,25,opt,name=wait_sample_count,json=waitSampleCount,proto3" json:"wait_sample_count,omitempty"` + // Included transactions first sighted after their inclusion slot started, excluded from the wait quantiles + NegativeWaitCount uint64 `protobuf:"varint,26,opt,name=negative_wait_count,json=negativeWaitCount,proto3" json:"negative_wait_count,omitempty"` + // Observed blob type 3 transactions first sighted this hour + BlobObservedCount uint64 `protobuf:"varint,27,opt,name=blob_observed_count,json=blobObservedCount,proto3" json:"blob_observed_count,omitempty"` + // Median wait milliseconds over included blob transactions with non-negative waits + BlobWaitMsP50 *wrapperspb.DoubleValue `protobuf:"bytes,28,opt,name=blob_wait_ms_p50,json=blobWaitMsP50,proto3" json:"blob_wait_ms_p50,omitempty"` + // p90 wait milliseconds over included blob transactions with non-negative waits + BlobWaitMsP90 *wrapperspb.DoubleValue `protobuf:"bytes,29,opt,name=blob_wait_ms_p90,json=blobWaitMsP90,proto3" json:"blob_wait_ms_p90,omitempty"` + // p99 wait milliseconds over included blob transactions with non-negative waits + BlobWaitMsP99 *wrapperspb.DoubleValue `protobuf:"bytes,30,opt,name=blob_wait_ms_p99,json=blobWaitMsP99,proto3" json:"blob_wait_ms_p99,omitempty"` + // Number of included blob transactions contributing to the blob wait quantiles + BlobWaitSampleCount uint64 `protobuf:"varint,31,opt,name=blob_wait_sample_count,json=blobWaitSampleCount,proto3" json:"blob_wait_sample_count,omitempty"` + // Distinct from and nonce pairs across transactions first sighted this hour + NonceGroupCount uint64 `protobuf:"varint,32,opt,name=nonce_group_count,json=nonceGroupCount,proto3" json:"nonce_group_count,omitempty"` + // Nonce groups with at least two observed attempts, anchored to this hour by their earliest attempt sighting + MultiAttemptNonceGroupCount uint64 `protobuf:"varint,33,opt,name=multi_attempt_nonce_group_count,json=multiAttemptNonceGroupCount,proto3" json:"multi_attempt_nonce_group_count,omitempty"` + // Non-winning attempts across multi-attempt nonce groups anchored to this hour + ReplacedAttemptCount uint64 `protobuf:"varint,34,opt,name=replaced_attempt_count,json=replacedAttemptCount,proto3" json:"replaced_attempt_count,omitempty"` +} + +func (x *FctTransactionMempoolOutcomeHourly) Reset() { + *x = FctTransactionMempoolOutcomeHourly{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FctTransactionMempoolOutcomeHourly) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FctTransactionMempoolOutcomeHourly) ProtoMessage() {} + +func (x *FctTransactionMempoolOutcomeHourly) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FctTransactionMempoolOutcomeHourly.ProtoReflect.Descriptor instead. +func (*FctTransactionMempoolOutcomeHourly) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_hourly_proto_rawDescGZIP(), []int{0} +} + +func (x *FctTransactionMempoolOutcomeHourly) GetUpdatedDateTime() uint32 { + if x != nil { + return x.UpdatedDateTime + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetHourStartDateTime() uint32 { + if x != nil { + return x.HourStartDateTime + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetObservedCount() uint64 { + if x != nil { + return x.ObservedCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetIncludedCount() uint64 { + if x != nil { + return x.IncludedCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetNonceConsumedCount() uint64 { + if x != nil { + return x.NonceConsumedCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetUnincludedCount() uint64 { + if x != nil { + return x.UnincludedCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetIncludedRelayDeliveredCount() uint64 { + if x != nil { + return x.IncludedRelayDeliveredCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetIncludedUnknownBuildCount() uint64 { + if x != nil { + return x.IncludedUnknownBuildCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetInMempoolAtDeadlineCount() uint64 { + if x != nil { + return x.InMempoolAtDeadlineCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetCancelShapeCount() uint64 { + if x != nil { + return x.CancelShapeCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetObservedAfterNonceConsumedCount() uint64 { + if x != nil { + return x.ObservedAfterNonceConsumedCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetWaitMsP50() *wrapperspb.DoubleValue { + if x != nil { + return x.WaitMsP50 + } + return nil +} + +func (x *FctTransactionMempoolOutcomeHourly) GetWaitMsP90() *wrapperspb.DoubleValue { + if x != nil { + return x.WaitMsP90 + } + return nil +} + +func (x *FctTransactionMempoolOutcomeHourly) GetWaitMsP99() *wrapperspb.DoubleValue { + if x != nil { + return x.WaitMsP99 + } + return nil +} + +func (x *FctTransactionMempoolOutcomeHourly) GetWaitSampleCount() uint64 { + if x != nil { + return x.WaitSampleCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetNegativeWaitCount() uint64 { + if x != nil { + return x.NegativeWaitCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetBlobObservedCount() uint64 { + if x != nil { + return x.BlobObservedCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetBlobWaitMsP50() *wrapperspb.DoubleValue { + if x != nil { + return x.BlobWaitMsP50 + } + return nil +} + +func (x *FctTransactionMempoolOutcomeHourly) GetBlobWaitMsP90() *wrapperspb.DoubleValue { + if x != nil { + return x.BlobWaitMsP90 + } + return nil +} + +func (x *FctTransactionMempoolOutcomeHourly) GetBlobWaitMsP99() *wrapperspb.DoubleValue { + if x != nil { + return x.BlobWaitMsP99 + } + return nil +} + +func (x *FctTransactionMempoolOutcomeHourly) GetBlobWaitSampleCount() uint64 { + if x != nil { + return x.BlobWaitSampleCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetNonceGroupCount() uint64 { + if x != nil { + return x.NonceGroupCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetMultiAttemptNonceGroupCount() uint64 { + if x != nil { + return x.MultiAttemptNonceGroupCount + } + return 0 +} + +func (x *FctTransactionMempoolOutcomeHourly) GetReplacedAttemptCount() uint64 { + if x != nil { + return x.ReplacedAttemptCount + } + return 0 +} + +// Request for listing fct_transaction_mempool_outcome_hourly records +type ListFctTransactionMempoolOutcomeHourlyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Filter by hour_start_date_time - Start of the hour period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the hour has been processed and never change afterwards (PRIMARY KEY - required) + HourStartDateTime *UInt32Filter `protobuf:"bytes,1,opt,name=hour_start_date_time,json=hourStartDateTime,proto3" json:"hour_start_date_time,omitempty"` + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UpdatedDateTime *UInt32Filter `protobuf:"bytes,2,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Filter by observed_count - Transactions first sighted in the public mempool this hour (optional) + ObservedCount *UInt64Filter `protobuf:"bytes,3,opt,name=observed_count,json=observedCount,proto3" json:"observed_count,omitempty"` + // Filter by included_count - Observed transactions included within 7 days of first sighting (optional) + IncludedCount *UInt64Filter `protobuf:"bytes,4,opt,name=included_count,json=includedCount,proto3" json:"included_count,omitempty"` + // Filter by nonce_consumed_count - Observed transactions whose nonce was consumed by a different transaction within 7 days (optional) + NonceConsumedCount *UInt64Filter `protobuf:"bytes,5,opt,name=nonce_consumed_count,json=nonceConsumedCount,proto3" json:"nonce_consumed_count,omitempty"` + // Filter by unincluded_count - Observed transactions with no inclusion of their nonce within 7 days (optional) + UnincludedCount *UInt64Filter `protobuf:"bytes,6,opt,name=unincluded_count,json=unincludedCount,proto3" json:"unincluded_count,omitempty"` + // Filter by included_relay_delivered_count - Included observed transactions whose block matched a known relay payload-delivered record (optional) + IncludedRelayDeliveredCount *UInt64Filter `protobuf:"bytes,7,opt,name=included_relay_delivered_count,json=includedRelayDeliveredCount,proto3" json:"included_relay_delivered_count,omitempty"` + // Filter by included_unknown_build_count - Included observed transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built (optional) + IncludedUnknownBuildCount *UInt64Filter `protobuf:"bytes,8,opt,name=included_unknown_build_count,json=includedUnknownBuildCount,proto3" json:"included_unknown_build_count,omitempty"` + // Filter by in_mempool_at_deadline_count - Unincluded transactions with a sighting in the final hour before the 7 day deadline (optional) + InMempoolAtDeadlineCount *UInt64Filter `protobuf:"bytes,9,opt,name=in_mempool_at_deadline_count,json=inMempoolAtDeadlineCount,proto3" json:"in_mempool_at_deadline_count,omitempty"` + // Filter by cancel_shape_count - Observed transactions that are self-transfers of zero value, the common wallet cancellation pattern (optional) + CancelShapeCount *UInt64Filter `protobuf:"bytes,10,opt,name=cancel_shape_count,json=cancelShapeCount,proto3" json:"cancel_shape_count,omitempty"` + // Filter by observed_after_nonce_consumed_count - Observed transactions first sighted after their nonce had already been consumed (optional) + ObservedAfterNonceConsumedCount *UInt64Filter `protobuf:"bytes,11,opt,name=observed_after_nonce_consumed_count,json=observedAfterNonceConsumedCount,proto3" json:"observed_after_nonce_consumed_count,omitempty"` + // Filter by wait_ms_p50 - Median milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits (optional) + WaitMsP50 *wrapperspb.DoubleValue `protobuf:"bytes,12,opt,name=wait_ms_p50,json=waitMsP50,proto3" json:"wait_ms_p50,omitempty"` + // Filter by wait_ms_p90 - p90 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits (optional) + WaitMsP90 *wrapperspb.DoubleValue `protobuf:"bytes,13,opt,name=wait_ms_p90,json=waitMsP90,proto3" json:"wait_ms_p90,omitempty"` + // Filter by wait_ms_p99 - p99 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits (optional) + WaitMsP99 *wrapperspb.DoubleValue `protobuf:"bytes,14,opt,name=wait_ms_p99,json=waitMsP99,proto3" json:"wait_ms_p99,omitempty"` + // Filter by wait_sample_count - Number of included transactions contributing to the wait quantiles (optional) + WaitSampleCount *UInt64Filter `protobuf:"bytes,15,opt,name=wait_sample_count,json=waitSampleCount,proto3" json:"wait_sample_count,omitempty"` + // Filter by negative_wait_count - Included transactions first sighted after their inclusion slot started, excluded from the wait quantiles (optional) + NegativeWaitCount *UInt64Filter `protobuf:"bytes,16,opt,name=negative_wait_count,json=negativeWaitCount,proto3" json:"negative_wait_count,omitempty"` + // Filter by blob_observed_count - Observed blob type 3 transactions first sighted this hour (optional) + BlobObservedCount *UInt64Filter `protobuf:"bytes,17,opt,name=blob_observed_count,json=blobObservedCount,proto3" json:"blob_observed_count,omitempty"` + // Filter by blob_wait_ms_p50 - Median wait milliseconds over included blob transactions with non-negative waits (optional) + BlobWaitMsP50 *wrapperspb.DoubleValue `protobuf:"bytes,18,opt,name=blob_wait_ms_p50,json=blobWaitMsP50,proto3" json:"blob_wait_ms_p50,omitempty"` + // Filter by blob_wait_ms_p90 - p90 wait milliseconds over included blob transactions with non-negative waits (optional) + BlobWaitMsP90 *wrapperspb.DoubleValue `protobuf:"bytes,19,opt,name=blob_wait_ms_p90,json=blobWaitMsP90,proto3" json:"blob_wait_ms_p90,omitempty"` + // Filter by blob_wait_ms_p99 - p99 wait milliseconds over included blob transactions with non-negative waits (optional) + BlobWaitMsP99 *wrapperspb.DoubleValue `protobuf:"bytes,20,opt,name=blob_wait_ms_p99,json=blobWaitMsP99,proto3" json:"blob_wait_ms_p99,omitempty"` + // Filter by blob_wait_sample_count - Number of included blob transactions contributing to the blob wait quantiles (optional) + BlobWaitSampleCount *UInt64Filter `protobuf:"bytes,21,opt,name=blob_wait_sample_count,json=blobWaitSampleCount,proto3" json:"blob_wait_sample_count,omitempty"` + // Filter by nonce_group_count - Distinct from and nonce pairs across transactions first sighted this hour (optional) + NonceGroupCount *UInt64Filter `protobuf:"bytes,22,opt,name=nonce_group_count,json=nonceGroupCount,proto3" json:"nonce_group_count,omitempty"` + // Filter by multi_attempt_nonce_group_count - Nonce groups with at least two observed attempts, anchored to this hour by their earliest attempt sighting (optional) + MultiAttemptNonceGroupCount *UInt64Filter `protobuf:"bytes,23,opt,name=multi_attempt_nonce_group_count,json=multiAttemptNonceGroupCount,proto3" json:"multi_attempt_nonce_group_count,omitempty"` + // Filter by replaced_attempt_count - Non-winning attempts across multi-attempt nonce groups anchored to this hour (optional) + ReplacedAttemptCount *UInt64Filter `protobuf:"bytes,24,opt,name=replaced_attempt_count,json=replacedAttemptCount,proto3" json:"replaced_attempt_count,omitempty"` + // The maximum number of fct_transaction_mempool_outcome_hourly to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + PageSize int32 `protobuf:"varint,25,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // A page token, received from a previous `ListFctTransactionMempoolOutcomeHourly` call. + // Provide this to retrieve the subsequent page. + PageToken string `protobuf:"bytes,26,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + OrderBy string `protobuf:"bytes,27,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"` +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) Reset() { + *x = ListFctTransactionMempoolOutcomeHourlyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionMempoolOutcomeHourlyRequest) ProtoMessage() {} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionMempoolOutcomeHourlyRequest.ProtoReflect.Descriptor instead. +func (*ListFctTransactionMempoolOutcomeHourlyRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_hourly_proto_rawDescGZIP(), []int{1} +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetHourStartDateTime() *UInt32Filter { + if x != nil { + return x.HourStartDateTime + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetUpdatedDateTime() *UInt32Filter { + if x != nil { + return x.UpdatedDateTime + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetObservedCount() *UInt64Filter { + if x != nil { + return x.ObservedCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetIncludedCount() *UInt64Filter { + if x != nil { + return x.IncludedCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetNonceConsumedCount() *UInt64Filter { + if x != nil { + return x.NonceConsumedCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetUnincludedCount() *UInt64Filter { + if x != nil { + return x.UnincludedCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetIncludedRelayDeliveredCount() *UInt64Filter { + if x != nil { + return x.IncludedRelayDeliveredCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetIncludedUnknownBuildCount() *UInt64Filter { + if x != nil { + return x.IncludedUnknownBuildCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetInMempoolAtDeadlineCount() *UInt64Filter { + if x != nil { + return x.InMempoolAtDeadlineCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetCancelShapeCount() *UInt64Filter { + if x != nil { + return x.CancelShapeCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetObservedAfterNonceConsumedCount() *UInt64Filter { + if x != nil { + return x.ObservedAfterNonceConsumedCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetWaitMsP50() *wrapperspb.DoubleValue { + if x != nil { + return x.WaitMsP50 + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetWaitMsP90() *wrapperspb.DoubleValue { + if x != nil { + return x.WaitMsP90 + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetWaitMsP99() *wrapperspb.DoubleValue { + if x != nil { + return x.WaitMsP99 + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetWaitSampleCount() *UInt64Filter { + if x != nil { + return x.WaitSampleCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetNegativeWaitCount() *UInt64Filter { + if x != nil { + return x.NegativeWaitCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetBlobObservedCount() *UInt64Filter { + if x != nil { + return x.BlobObservedCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetBlobWaitMsP50() *wrapperspb.DoubleValue { + if x != nil { + return x.BlobWaitMsP50 + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetBlobWaitMsP90() *wrapperspb.DoubleValue { + if x != nil { + return x.BlobWaitMsP90 + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetBlobWaitMsP99() *wrapperspb.DoubleValue { + if x != nil { + return x.BlobWaitMsP99 + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetBlobWaitSampleCount() *UInt64Filter { + if x != nil { + return x.BlobWaitSampleCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetNonceGroupCount() *UInt64Filter { + if x != nil { + return x.NonceGroupCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetMultiAttemptNonceGroupCount() *UInt64Filter { + if x != nil { + return x.MultiAttemptNonceGroupCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetReplacedAttemptCount() *UInt64Filter { + if x != nil { + return x.ReplacedAttemptCount + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +func (x *ListFctTransactionMempoolOutcomeHourlyRequest) GetOrderBy() string { + if x != nil { + return x.OrderBy + } + return "" +} + +// Response for listing fct_transaction_mempool_outcome_hourly records +type ListFctTransactionMempoolOutcomeHourlyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of fct_transaction_mempool_outcome_hourly. + FctTransactionMempoolOutcomeHourly []*FctTransactionMempoolOutcomeHourly `protobuf:"bytes,1,rep,name=fct_transaction_mempool_outcome_hourly,json=fctTransactionMempoolOutcomeHourly,proto3" json:"fct_transaction_mempool_outcome_hourly,omitempty"` + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` +} + +func (x *ListFctTransactionMempoolOutcomeHourlyResponse) Reset() { + *x = ListFctTransactionMempoolOutcomeHourlyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionMempoolOutcomeHourlyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionMempoolOutcomeHourlyResponse) ProtoMessage() {} + +func (x *ListFctTransactionMempoolOutcomeHourlyResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionMempoolOutcomeHourlyResponse.ProtoReflect.Descriptor instead. +func (*ListFctTransactionMempoolOutcomeHourlyResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_hourly_proto_rawDescGZIP(), []int{2} +} + +func (x *ListFctTransactionMempoolOutcomeHourlyResponse) GetFctTransactionMempoolOutcomeHourly() []*FctTransactionMempoolOutcomeHourly { + if x != nil { + return x.FctTransactionMempoolOutcomeHourly + } + return nil +} + +func (x *ListFctTransactionMempoolOutcomeHourlyResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +// Request for getting a single fct_transaction_mempool_outcome_hourly record by primary key +type GetFctTransactionMempoolOutcomeHourlyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Start of the hour period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the hour has been processed and never change afterwards + HourStartDateTime uint32 `protobuf:"varint,1,opt,name=hour_start_date_time,json=hourStartDateTime,proto3" json:"hour_start_date_time,omitempty"` // Primary key (required) +} + +func (x *GetFctTransactionMempoolOutcomeHourlyRequest) Reset() { + *x = GetFctTransactionMempoolOutcomeHourlyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionMempoolOutcomeHourlyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionMempoolOutcomeHourlyRequest) ProtoMessage() {} + +func (x *GetFctTransactionMempoolOutcomeHourlyRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionMempoolOutcomeHourlyRequest.ProtoReflect.Descriptor instead. +func (*GetFctTransactionMempoolOutcomeHourlyRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_hourly_proto_rawDescGZIP(), []int{3} +} + +func (x *GetFctTransactionMempoolOutcomeHourlyRequest) GetHourStartDateTime() uint32 { + if x != nil { + return x.HourStartDateTime + } + return 0 +} + +// Response for getting a single fct_transaction_mempool_outcome_hourly record +type GetFctTransactionMempoolOutcomeHourlyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *FctTransactionMempoolOutcomeHourly `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *GetFctTransactionMempoolOutcomeHourlyResponse) Reset() { + *x = GetFctTransactionMempoolOutcomeHourlyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionMempoolOutcomeHourlyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionMempoolOutcomeHourlyResponse) ProtoMessage() {} + +func (x *GetFctTransactionMempoolOutcomeHourlyResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionMempoolOutcomeHourlyResponse.ProtoReflect.Descriptor instead. +func (*GetFctTransactionMempoolOutcomeHourlyResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_mempool_outcome_hourly_proto_rawDescGZIP(), []int{4} +} + +func (x *GetFctTransactionMempoolOutcomeHourlyResponse) GetItem() *FctTransactionMempoolOutcomeHourly { + if x != nil { + return x.Item + } + return nil +} + +var File_fct_transaction_mempool_outcome_hourly_proto protoreflect.FileDescriptor + +var file_fct_transaction_mempool_outcome_hourly_proto_rawDesc = []byte{ + 0x0a, 0x2c, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, + 0x65, 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, + 0x63, 0x62, 0x74, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1c, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x2f, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe6, + 0x0a, 0x0a, 0x22, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x48, + 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x2f, 0x0a, 0x14, 0x68, 0x6f, 0x75, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, + 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x11, 0x68, 0x6f, 0x75, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x30, 0x0a, 0x14, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, + 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, + 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x75, 0x6e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x75, 0x6e, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x43, 0x0a, + 0x1e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, + 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x52, + 0x65, 0x6c, 0x61, 0x79, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, 0x64, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x1c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x75, + 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x04, 0x52, 0x19, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x64, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x3e, 0x0a, 0x1c, 0x69, 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, + 0x6c, 0x5f, 0x61, 0x74, 0x5f, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x18, 0x69, 0x6e, 0x4d, 0x65, 0x6d, + 0x70, 0x6f, 0x6f, 0x6c, 0x41, 0x74, 0x44, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x73, 0x68, + 0x61, 0x70, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x10, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x70, 0x65, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x4c, 0x0a, 0x23, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x66, + 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, + 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1f, + 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e, + 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x3c, 0x0a, 0x0b, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x35, 0x30, 0x18, 0x16, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x09, 0x77, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x35, 0x30, 0x12, 0x3c, 0x0a, + 0x0b, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x39, 0x30, 0x18, 0x17, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x09, 0x77, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x39, 0x30, 0x12, 0x3c, 0x0a, 0x0b, 0x77, + 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x39, 0x39, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, + 0x77, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x39, 0x39, 0x12, 0x2a, 0x0a, 0x11, 0x77, 0x61, 0x69, + 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x19, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x77, 0x61, 0x69, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, + 0x65, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x1a, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x11, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x57, 0x61, 0x69, 0x74, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x6f, 0x62, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x1b, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x11, 0x62, 0x6c, 0x6f, 0x62, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x77, 0x61, + 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x35, 0x30, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0d, 0x62, + 0x6c, 0x6f, 0x62, 0x57, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x35, 0x30, 0x12, 0x45, 0x0a, 0x10, + 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x39, 0x30, + 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x57, 0x61, 0x69, 0x74, 0x4d, 0x73, + 0x50, 0x39, 0x30, 0x12, 0x45, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x77, 0x61, 0x69, 0x74, + 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x39, 0x39, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0d, 0x62, 0x6c, 0x6f, + 0x62, 0x57, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x39, 0x39, 0x12, 0x33, 0x0a, 0x16, 0x62, 0x6c, + 0x6f, 0x62, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x62, 0x6c, 0x6f, 0x62, + 0x57, 0x61, 0x69, 0x74, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x2a, 0x0a, 0x11, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x20, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6e, 0x6f, 0x6e, 0x63, + 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x44, 0x0a, 0x1f, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x5f, 0x6e, 0x6f, 0x6e, + 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x21, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x1b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x41, 0x74, 0x74, 0x65, 0x6d, + 0x70, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x34, 0x0a, 0x16, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x74, 0x65, 0x6d, 0x70, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x22, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x14, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x41, 0x74, 0x74, 0x65, 0x6d, + 0x70, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xb4, 0x0f, 0x0a, 0x2d, 0x4c, 0x69, 0x73, 0x74, + 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, + 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x48, 0x6f, 0x75, 0x72, + 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x14, 0x68, 0x6f, 0x75, + 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, + 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x12, 0xe0, 0x41, 0x02, 0x9a, + 0xb5, 0x18, 0x0b, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x52, 0x11, + 0x68, 0x6f, 0x75, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x42, 0x0a, 0x11, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, + 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, + 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, + 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, + 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, + 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x48, 0x0a, 0x14, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6d, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x12, 0x6e, 0x6f, 0x6e, 0x63, 0x65, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x41, 0x0a, + 0x10, 0x75, 0x6e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, + 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x0f, 0x75, 0x6e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x5b, 0x0a, 0x1e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x6c, + 0x61, 0x79, 0x5f, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, + 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, + 0x52, 0x1b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x44, + 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x57, 0x0a, + 0x1c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x19, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x64, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x75, 0x69, 0x6c, + 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x56, 0x0a, 0x1c, 0x69, 0x6e, 0x5f, 0x6d, 0x65, 0x6d, + 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x61, 0x74, 0x5f, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, + 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, + 0x03, 0xe0, 0x41, 0x01, 0x52, 0x18, 0x69, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x41, + 0x74, 0x44, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x44, + 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, + 0x41, 0x01, 0x52, 0x10, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x70, 0x65, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x64, 0x0a, 0x23, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6d, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x1f, 0x6f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, + 0x73, 0x75, 0x6d, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x0b, 0x77, 0x61, + 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x35, 0x30, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x03, 0xe0, + 0x41, 0x01, 0x52, 0x09, 0x77, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x35, 0x30, 0x12, 0x41, 0x0a, + 0x0b, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x39, 0x30, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x77, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x39, 0x30, + 0x12, 0x41, 0x0a, 0x0b, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x39, 0x39, 0x18, + 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x77, 0x61, 0x69, 0x74, 0x4d, 0x73, + 0x50, 0x39, 0x39, 0x12, 0x42, 0x0a, 0x11, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0f, 0x77, 0x61, 0x69, 0x74, 0x53, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x46, 0x0a, 0x13, 0x6e, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x10, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, + 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x11, 0x6e, 0x65, + 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x57, 0x61, 0x69, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x46, 0x0a, 0x13, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, + 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, + 0x03, 0xe0, 0x41, 0x01, 0x52, 0x11, 0x62, 0x6c, 0x6f, 0x62, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4a, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, + 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x35, 0x30, 0x18, 0x12, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, + 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x57, 0x61, 0x69, 0x74, 0x4d, 0x73, + 0x50, 0x35, 0x30, 0x12, 0x4a, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x77, 0x61, 0x69, 0x74, + 0x5f, 0x6d, 0x73, 0x5f, 0x70, 0x39, 0x30, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x01, + 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x57, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x39, 0x30, 0x12, + 0x4a, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x6d, 0x73, 0x5f, + 0x70, 0x39, 0x39, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, + 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x62, 0x6c, + 0x6f, 0x62, 0x57, 0x61, 0x69, 0x74, 0x4d, 0x73, 0x50, 0x39, 0x39, 0x12, 0x4b, 0x0a, 0x16, 0x62, + 0x6c, 0x6f, 0x62, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x13, 0x62, 0x6c, 0x6f, 0x62, 0x57, 0x61, 0x69, 0x74, 0x53, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x11, 0x6e, 0x6f, 0x6e, 0x63, + 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x16, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0f, 0x6e, 0x6f, 0x6e, + 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x5c, 0x0a, 0x1f, + 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x5f, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x1b, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4c, 0x0a, 0x16, 0x72, 0x65, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, + 0x41, 0x01, 0x52, 0x14, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x41, 0x74, 0x74, 0x65, + 0x6d, 0x70, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0xe0, 0x41, 0x01, + 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0a, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1e, + 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, 0xd5, + 0x01, 0x0a, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, + 0x6f, 0x6d, 0x65, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x7b, 0x0a, 0x26, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6f, 0x75, 0x74, + 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, + 0x63, 0x6f, 0x6d, 0x65, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x22, 0x66, 0x63, 0x74, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, + 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x12, 0x26, + 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, + 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x5f, 0x0a, 0x2c, 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, + 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x14, 0x68, 0x6f, 0x75, 0x72, 0x5f, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x68, 0x6f, 0x75, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, + 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x6c, 0x0a, 0x2d, 0x47, 0x65, 0x74, 0x46, 0x63, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, + 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x46, 0x63, 0x74, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, + 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, + 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0x93, 0x03, 0x0a, 0x29, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, + 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0xa7, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x32, 0x2e, 0x63, + 0x62, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, + 0x6f, 0x6d, 0x65, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x33, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, + 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x12, 0x2e, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6f, + 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x12, 0xbb, 0x01, + 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x31, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x46, + 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, + 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x48, 0x6f, 0x75, 0x72, 0x6c, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x47, + 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x48, 0x6f, + 0x75, 0x72, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x47, 0x12, 0x45, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x63, + 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, + 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x68, 0x6f, + 0x75, 0x72, 0x6c, 0x79, 0x2f, 0x7b, 0x68, 0x6f, 0x75, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x7d, 0x42, 0x36, 0x5a, 0x34, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x70, 0x61, 0x6e, + 0x64, 0x61, 0x6f, 0x70, 0x73, 0x2f, 0x78, 0x61, 0x74, 0x75, 0x2d, 0x63, 0x62, 0x74, 0x2f, 0x70, + 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x68, 0x6f, + 0x75, 0x73, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_fct_transaction_mempool_outcome_hourly_proto_rawDescOnce sync.Once + file_fct_transaction_mempool_outcome_hourly_proto_rawDescData = file_fct_transaction_mempool_outcome_hourly_proto_rawDesc +) + +func file_fct_transaction_mempool_outcome_hourly_proto_rawDescGZIP() []byte { + file_fct_transaction_mempool_outcome_hourly_proto_rawDescOnce.Do(func() { + file_fct_transaction_mempool_outcome_hourly_proto_rawDescData = protoimpl.X.CompressGZIP(file_fct_transaction_mempool_outcome_hourly_proto_rawDescData) + }) + return file_fct_transaction_mempool_outcome_hourly_proto_rawDescData +} + +var file_fct_transaction_mempool_outcome_hourly_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_fct_transaction_mempool_outcome_hourly_proto_goTypes = []any{ + (*FctTransactionMempoolOutcomeHourly)(nil), // 0: cbt.FctTransactionMempoolOutcomeHourly + (*ListFctTransactionMempoolOutcomeHourlyRequest)(nil), // 1: cbt.ListFctTransactionMempoolOutcomeHourlyRequest + (*ListFctTransactionMempoolOutcomeHourlyResponse)(nil), // 2: cbt.ListFctTransactionMempoolOutcomeHourlyResponse + (*GetFctTransactionMempoolOutcomeHourlyRequest)(nil), // 3: cbt.GetFctTransactionMempoolOutcomeHourlyRequest + (*GetFctTransactionMempoolOutcomeHourlyResponse)(nil), // 4: cbt.GetFctTransactionMempoolOutcomeHourlyResponse + (*wrapperspb.DoubleValue)(nil), // 5: google.protobuf.DoubleValue + (*UInt32Filter)(nil), // 6: cbt.UInt32Filter + (*UInt64Filter)(nil), // 7: cbt.UInt64Filter +} +var file_fct_transaction_mempool_outcome_hourly_proto_depIdxs = []int32{ + 5, // 0: cbt.FctTransactionMempoolOutcomeHourly.wait_ms_p50:type_name -> google.protobuf.DoubleValue + 5, // 1: cbt.FctTransactionMempoolOutcomeHourly.wait_ms_p90:type_name -> google.protobuf.DoubleValue + 5, // 2: cbt.FctTransactionMempoolOutcomeHourly.wait_ms_p99:type_name -> google.protobuf.DoubleValue + 5, // 3: cbt.FctTransactionMempoolOutcomeHourly.blob_wait_ms_p50:type_name -> google.protobuf.DoubleValue + 5, // 4: cbt.FctTransactionMempoolOutcomeHourly.blob_wait_ms_p90:type_name -> google.protobuf.DoubleValue + 5, // 5: cbt.FctTransactionMempoolOutcomeHourly.blob_wait_ms_p99:type_name -> google.protobuf.DoubleValue + 6, // 6: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.hour_start_date_time:type_name -> cbt.UInt32Filter + 6, // 7: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.updated_date_time:type_name -> cbt.UInt32Filter + 7, // 8: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.observed_count:type_name -> cbt.UInt64Filter + 7, // 9: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.included_count:type_name -> cbt.UInt64Filter + 7, // 10: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.nonce_consumed_count:type_name -> cbt.UInt64Filter + 7, // 11: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.unincluded_count:type_name -> cbt.UInt64Filter + 7, // 12: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.included_relay_delivered_count:type_name -> cbt.UInt64Filter + 7, // 13: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.included_unknown_build_count:type_name -> cbt.UInt64Filter + 7, // 14: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.in_mempool_at_deadline_count:type_name -> cbt.UInt64Filter + 7, // 15: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.cancel_shape_count:type_name -> cbt.UInt64Filter + 7, // 16: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.observed_after_nonce_consumed_count:type_name -> cbt.UInt64Filter + 5, // 17: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.wait_ms_p50:type_name -> google.protobuf.DoubleValue + 5, // 18: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.wait_ms_p90:type_name -> google.protobuf.DoubleValue + 5, // 19: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.wait_ms_p99:type_name -> google.protobuf.DoubleValue + 7, // 20: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.wait_sample_count:type_name -> cbt.UInt64Filter + 7, // 21: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.negative_wait_count:type_name -> cbt.UInt64Filter + 7, // 22: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.blob_observed_count:type_name -> cbt.UInt64Filter + 5, // 23: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.blob_wait_ms_p50:type_name -> google.protobuf.DoubleValue + 5, // 24: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.blob_wait_ms_p90:type_name -> google.protobuf.DoubleValue + 5, // 25: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.blob_wait_ms_p99:type_name -> google.protobuf.DoubleValue + 7, // 26: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.blob_wait_sample_count:type_name -> cbt.UInt64Filter + 7, // 27: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.nonce_group_count:type_name -> cbt.UInt64Filter + 7, // 28: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.multi_attempt_nonce_group_count:type_name -> cbt.UInt64Filter + 7, // 29: cbt.ListFctTransactionMempoolOutcomeHourlyRequest.replaced_attempt_count:type_name -> cbt.UInt64Filter + 0, // 30: cbt.ListFctTransactionMempoolOutcomeHourlyResponse.fct_transaction_mempool_outcome_hourly:type_name -> cbt.FctTransactionMempoolOutcomeHourly + 0, // 31: cbt.GetFctTransactionMempoolOutcomeHourlyResponse.item:type_name -> cbt.FctTransactionMempoolOutcomeHourly + 1, // 32: cbt.FctTransactionMempoolOutcomeHourlyService.List:input_type -> cbt.ListFctTransactionMempoolOutcomeHourlyRequest + 3, // 33: cbt.FctTransactionMempoolOutcomeHourlyService.Get:input_type -> cbt.GetFctTransactionMempoolOutcomeHourlyRequest + 2, // 34: cbt.FctTransactionMempoolOutcomeHourlyService.List:output_type -> cbt.ListFctTransactionMempoolOutcomeHourlyResponse + 4, // 35: cbt.FctTransactionMempoolOutcomeHourlyService.Get:output_type -> cbt.GetFctTransactionMempoolOutcomeHourlyResponse + 34, // [34:36] is the sub-list for method output_type + 32, // [32:34] is the sub-list for method input_type + 32, // [32:32] is the sub-list for extension type_name + 32, // [32:32] is the sub-list for extension extendee + 0, // [0:32] is the sub-list for field type_name +} + +func init() { file_fct_transaction_mempool_outcome_hourly_proto_init() } +func file_fct_transaction_mempool_outcome_hourly_proto_init() { + if File_fct_transaction_mempool_outcome_hourly_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*FctTransactionMempoolOutcomeHourly); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionMempoolOutcomeHourlyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionMempoolOutcomeHourlyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionMempoolOutcomeHourlyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_mempool_outcome_hourly_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionMempoolOutcomeHourlyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_fct_transaction_mempool_outcome_hourly_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_fct_transaction_mempool_outcome_hourly_proto_goTypes, + DependencyIndexes: file_fct_transaction_mempool_outcome_hourly_proto_depIdxs, + MessageInfos: file_fct_transaction_mempool_outcome_hourly_proto_msgTypes, + }.Build() + File_fct_transaction_mempool_outcome_hourly_proto = out.File + file_fct_transaction_mempool_outcome_hourly_proto_rawDesc = nil + file_fct_transaction_mempool_outcome_hourly_proto_goTypes = nil + file_fct_transaction_mempool_outcome_hourly_proto_depIdxs = nil +} diff --git a/pkg/proto/clickhouse/fct_transaction_mempool_outcome_hourly.proto b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_hourly.proto new file mode 100644 index 00000000..eb654e54 --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_mempool_outcome_hourly.proto @@ -0,0 +1,164 @@ +syntax = "proto3"; + +package cbt; + +import "common.proto"; +import "google/protobuf/wrappers.proto"; +import "google/api/annotations.proto"; +import "google/api/field_behavior.proto"; +import "clickhouse/annotations.proto"; + +option go_package = "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse"; +// Hourly cohort outcomes for transactions first sighted in the public mempool, resolved at the fixed 7 day horizon + +message FctTransactionMempoolOutcomeHourly { + // Timestamp when the record was last updated + uint32 updated_date_time = 11; + // Start of the hour period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the hour has been processed and never change afterwards + uint32 hour_start_date_time = 12; + // Transactions first sighted in the public mempool this hour + uint64 observed_count = 13; + // Observed transactions included within 7 days of first sighting + uint64 included_count = 14; + // Observed transactions whose nonce was consumed by a different transaction within 7 days + uint64 nonce_consumed_count = 15; + // Observed transactions with no inclusion of their nonce within 7 days + uint64 unincluded_count = 16; + // Included observed transactions whose block matched a known relay payload-delivered record + uint64 included_relay_delivered_count = 17; + // Included observed transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built + uint64 included_unknown_build_count = 18; + // Unincluded transactions with a sighting in the final hour before the 7 day deadline + uint64 in_mempool_at_deadline_count = 19; + // Observed transactions that are self-transfers of zero value, the common wallet cancellation pattern + uint64 cancel_shape_count = 20; + // Observed transactions first sighted after their nonce had already been consumed + uint64 observed_after_nonce_consumed_count = 21; + // Median milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits + google.protobuf.DoubleValue wait_ms_p50 = 22; + // p90 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits + google.protobuf.DoubleValue wait_ms_p90 = 23; + // p99 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits + google.protobuf.DoubleValue wait_ms_p99 = 24; + // Number of included transactions contributing to the wait quantiles + uint64 wait_sample_count = 25; + // Included transactions first sighted after their inclusion slot started, excluded from the wait quantiles + uint64 negative_wait_count = 26; + // Observed blob type 3 transactions first sighted this hour + uint64 blob_observed_count = 27; + // Median wait milliseconds over included blob transactions with non-negative waits + google.protobuf.DoubleValue blob_wait_ms_p50 = 28; + // p90 wait milliseconds over included blob transactions with non-negative waits + google.protobuf.DoubleValue blob_wait_ms_p90 = 29; + // p99 wait milliseconds over included blob transactions with non-negative waits + google.protobuf.DoubleValue blob_wait_ms_p99 = 30; + // Number of included blob transactions contributing to the blob wait quantiles + uint64 blob_wait_sample_count = 31; + // Distinct from and nonce pairs across transactions first sighted this hour + uint64 nonce_group_count = 32; + // Nonce groups with at least two observed attempts, anchored to this hour by their earliest attempt sighting + uint64 multi_attempt_nonce_group_count = 33; + // Non-winning attempts across multi-attempt nonce groups anchored to this hour + uint64 replaced_attempt_count = 34; +} + +// Request for listing fct_transaction_mempool_outcome_hourly records +message ListFctTransactionMempoolOutcomeHourlyRequest { + // Filter by hour_start_date_time - Start of the hour period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the hour has been processed and never change afterwards (PRIMARY KEY - required) + UInt32Filter hour_start_date_time = 1 [(google.api.field_behavior) = REQUIRED, (clickhouse.v1.required_group) = "primary_key"]; + + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UInt32Filter updated_date_time = 2 [(google.api.field_behavior) = OPTIONAL]; + // Filter by observed_count - Transactions first sighted in the public mempool this hour (optional) + UInt64Filter observed_count = 3 [(google.api.field_behavior) = OPTIONAL]; + // Filter by included_count - Observed transactions included within 7 days of first sighting (optional) + UInt64Filter included_count = 4 [(google.api.field_behavior) = OPTIONAL]; + // Filter by nonce_consumed_count - Observed transactions whose nonce was consumed by a different transaction within 7 days (optional) + UInt64Filter nonce_consumed_count = 5 [(google.api.field_behavior) = OPTIONAL]; + // Filter by unincluded_count - Observed transactions with no inclusion of their nonce within 7 days (optional) + UInt64Filter unincluded_count = 6 [(google.api.field_behavior) = OPTIONAL]; + // Filter by included_relay_delivered_count - Included observed transactions whose block matched a known relay payload-delivered record (optional) + UInt64Filter included_relay_delivered_count = 7 [(google.api.field_behavior) = OPTIONAL]; + // Filter by included_unknown_build_count - Included observed transactions whose block matched no known relay payload-delivered record. Not proof the block was locally built (optional) + UInt64Filter included_unknown_build_count = 8 [(google.api.field_behavior) = OPTIONAL]; + // Filter by in_mempool_at_deadline_count - Unincluded transactions with a sighting in the final hour before the 7 day deadline (optional) + UInt64Filter in_mempool_at_deadline_count = 9 [(google.api.field_behavior) = OPTIONAL]; + // Filter by cancel_shape_count - Observed transactions that are self-transfers of zero value, the common wallet cancellation pattern (optional) + UInt64Filter cancel_shape_count = 10 [(google.api.field_behavior) = OPTIONAL]; + // Filter by observed_after_nonce_consumed_count - Observed transactions first sighted after their nonce had already been consumed (optional) + UInt64Filter observed_after_nonce_consumed_count = 11 [(google.api.field_behavior) = OPTIONAL]; + // Filter by wait_ms_p50 - Median milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits (optional) + google.protobuf.DoubleValue wait_ms_p50 = 12 [(google.api.field_behavior) = OPTIONAL]; + // Filter by wait_ms_p90 - p90 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits (optional) + google.protobuf.DoubleValue wait_ms_p90 = 13 [(google.api.field_behavior) = OPTIONAL]; + // Filter by wait_ms_p99 - p99 milliseconds from first sighting to inclusion slot start, over included transactions with non-negative waits (optional) + google.protobuf.DoubleValue wait_ms_p99 = 14 [(google.api.field_behavior) = OPTIONAL]; + // Filter by wait_sample_count - Number of included transactions contributing to the wait quantiles (optional) + UInt64Filter wait_sample_count = 15 [(google.api.field_behavior) = OPTIONAL]; + // Filter by negative_wait_count - Included transactions first sighted after their inclusion slot started, excluded from the wait quantiles (optional) + UInt64Filter negative_wait_count = 16 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_observed_count - Observed blob type 3 transactions first sighted this hour (optional) + UInt64Filter blob_observed_count = 17 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_wait_ms_p50 - Median wait milliseconds over included blob transactions with non-negative waits (optional) + google.protobuf.DoubleValue blob_wait_ms_p50 = 18 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_wait_ms_p90 - p90 wait milliseconds over included blob transactions with non-negative waits (optional) + google.protobuf.DoubleValue blob_wait_ms_p90 = 19 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_wait_ms_p99 - p99 wait milliseconds over included blob transactions with non-negative waits (optional) + google.protobuf.DoubleValue blob_wait_ms_p99 = 20 [(google.api.field_behavior) = OPTIONAL]; + // Filter by blob_wait_sample_count - Number of included blob transactions contributing to the blob wait quantiles (optional) + UInt64Filter blob_wait_sample_count = 21 [(google.api.field_behavior) = OPTIONAL]; + // Filter by nonce_group_count - Distinct from and nonce pairs across transactions first sighted this hour (optional) + UInt64Filter nonce_group_count = 22 [(google.api.field_behavior) = OPTIONAL]; + // Filter by multi_attempt_nonce_group_count - Nonce groups with at least two observed attempts, anchored to this hour by their earliest attempt sighting (optional) + UInt64Filter multi_attempt_nonce_group_count = 23 [(google.api.field_behavior) = OPTIONAL]; + // Filter by replaced_attempt_count - Non-winning attempts across multi-attempt nonce groups anchored to this hour (optional) + UInt64Filter replaced_attempt_count = 24 [(google.api.field_behavior) = OPTIONAL]; + + // The maximum number of fct_transaction_mempool_outcome_hourly to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + int32 page_size = 25 [(google.api.field_behavior) = OPTIONAL]; + // A page token, received from a previous `ListFctTransactionMempoolOutcomeHourly` call. + // Provide this to retrieve the subsequent page. + string page_token = 26 [(google.api.field_behavior) = OPTIONAL]; + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + string order_by = 27 [(google.api.field_behavior) = OPTIONAL]; +} + +// Response for listing fct_transaction_mempool_outcome_hourly records +message ListFctTransactionMempoolOutcomeHourlyResponse { + // The list of fct_transaction_mempool_outcome_hourly. + repeated FctTransactionMempoolOutcomeHourly fct_transaction_mempool_outcome_hourly = 1; + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; +} + +// Request for getting a single fct_transaction_mempool_outcome_hourly record by primary key +message GetFctTransactionMempoolOutcomeHourlyRequest { + // Start of the hour period, bucketed by first sighting time. Rows are complete once the 7 day horizon for the hour has been processed and never change afterwards + uint32 hour_start_date_time = 1; // Primary key (required) +} + +// Response for getting a single fct_transaction_mempool_outcome_hourly record +message GetFctTransactionMempoolOutcomeHourlyResponse { + FctTransactionMempoolOutcomeHourly item = 1; +} + +// Query fct_transaction_mempool_outcome_hourly data +service FctTransactionMempoolOutcomeHourlyService { + // List records | Retrieve paginated results with optional filtering + rpc List(ListFctTransactionMempoolOutcomeHourlyRequest) returns (ListFctTransactionMempoolOutcomeHourlyResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_mempool_outcome_hourly" + }; + } + // Get record | Retrieve a single record by hour_start_date_time + rpc Get(GetFctTransactionMempoolOutcomeHourlyRequest) returns (GetFctTransactionMempoolOutcomeHourlyResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_mempool_outcome_hourly/{hour_start_date_time}" + }; + } +} diff --git a/pkg/proto/clickhouse/fct_transaction_replacement.go b/pkg/proto/clickhouse/fct_transaction_replacement.go new file mode 100644 index 00000000..33b2510b --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_replacement.go @@ -0,0 +1,788 @@ +// Code generated by clickhouse-proto-gen. DO NOT EDIT. +// SQL query builder for fct_transaction_replacement + +package clickhouse + +import ( + "fmt" +) + +// BuildListFctTransactionReplacementQuery constructs a parameterized SQL query from a ListFctTransactionReplacementRequest +// +// Available projections: +// - p_by_hash (primary key: hash) +// - p_by_nonce_group (primary key: from) +// +// Use WithProjection() option to select a specific projection. +func BuildListFctTransactionReplacementQuery(req *ListFctTransactionReplacementRequest, options ...QueryOption) (SQLQuery, error) { + // Validate that at least one primary key is provided + // Primary keys can come from base table or projections + if req.From == nil && req.GroupFirstSeenDateTime == nil && req.Hash == nil { + return SQLQuery{}, fmt.Errorf("at least one primary key field is required: from, group_first_seen_date_time, hash") + } + + // Build query using QueryBuilder + qb := NewQueryBuilder() + + // Add primary key filter + if req.GroupFirstSeenDateTime != nil { + switch filter := req.GroupFirstSeenDateTime.Filter.(type) { + case *Int64Filter_Eq: + qb.AddCondition("group_first_seen_date_time", "=", DateTime64Value{uint64(filter.Eq)}) + case *Int64Filter_Ne: + qb.AddCondition("group_first_seen_date_time", "!=", DateTime64Value{uint64(filter.Ne)}) + case *Int64Filter_Lt: + qb.AddCondition("group_first_seen_date_time", "<", DateTime64Value{uint64(filter.Lt)}) + case *Int64Filter_Lte: + qb.AddCondition("group_first_seen_date_time", "<=", DateTime64Value{uint64(filter.Lte)}) + case *Int64Filter_Gt: + qb.AddCondition("group_first_seen_date_time", ">", DateTime64Value{uint64(filter.Gt)}) + case *Int64Filter_Gte: + qb.AddCondition("group_first_seen_date_time", ">=", DateTime64Value{uint64(filter.Gte)}) + case *Int64Filter_Between: + qb.AddBetweenCondition("group_first_seen_date_time", DateTime64Value{uint64(filter.Between.Min)}, DateTime64Value{uint64(filter.Between.Max.GetValue())}) + case *Int64Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddInCondition("group_first_seen_date_time", converted) + } + case *Int64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddNotInCondition("group_first_seen_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: updated_date_time + if req.UpdatedDateTime != nil { + switch filter := req.UpdatedDateTime.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("updated_date_time", "=", DateTimeValue{filter.Eq}) + case *UInt32Filter_Ne: + qb.AddCondition("updated_date_time", "!=", DateTimeValue{filter.Ne}) + case *UInt32Filter_Lt: + qb.AddCondition("updated_date_time", "<", DateTimeValue{filter.Lt}) + case *UInt32Filter_Lte: + qb.AddCondition("updated_date_time", "<=", DateTimeValue{filter.Lte}) + case *UInt32Filter_Gt: + qb.AddCondition("updated_date_time", ">", DateTimeValue{filter.Gt}) + case *UInt32Filter_Gte: + qb.AddCondition("updated_date_time", ">=", DateTimeValue{filter.Gte}) + case *UInt32Filter_Between: + qb.AddBetweenCondition("updated_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("updated_date_time", converted) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("updated_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: from + if req.From != nil { + switch filter := req.From.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("from", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("from", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("from", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("from", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("from", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("from", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("from", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("from", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("from", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: nonce + if req.Nonce != nil { + switch filter := req.Nonce.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("nonce", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("nonce", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("nonce", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("nonce", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("nonce", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("nonce", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("nonce", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("nonce", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("nonce", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: hash + if req.Hash != nil { + switch filter := req.Hash.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("hash", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("hash", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("hash", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("hash", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("hash", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("hash", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("hash", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("hash", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("hash", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: attempt_index + if req.AttemptIndex != nil { + switch filter := req.AttemptIndex.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("attempt_index", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("attempt_index", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("attempt_index", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("attempt_index", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("attempt_index", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("attempt_index", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("attempt_index", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("attempt_index", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("attempt_index", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: group_attempt_count + if req.GroupAttemptCount != nil { + switch filter := req.GroupAttemptCount.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("group_attempt_count", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("group_attempt_count", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("group_attempt_count", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("group_attempt_count", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("group_attempt_count", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("group_attempt_count", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("group_attempt_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("group_attempt_count", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("group_attempt_count", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: first_seen_date_time + if req.FirstSeenDateTime != nil { + switch filter := req.FirstSeenDateTime.Filter.(type) { + case *Int64Filter_Eq: + qb.AddCondition("first_seen_date_time", "=", DateTime64Value{uint64(filter.Eq)}) + case *Int64Filter_Ne: + qb.AddCondition("first_seen_date_time", "!=", DateTime64Value{uint64(filter.Ne)}) + case *Int64Filter_Lt: + qb.AddCondition("first_seen_date_time", "<", DateTime64Value{uint64(filter.Lt)}) + case *Int64Filter_Lte: + qb.AddCondition("first_seen_date_time", "<=", DateTime64Value{uint64(filter.Lte)}) + case *Int64Filter_Gt: + qb.AddCondition("first_seen_date_time", ">", DateTime64Value{uint64(filter.Gt)}) + case *Int64Filter_Gte: + qb.AddCondition("first_seen_date_time", ">=", DateTime64Value{uint64(filter.Gte)}) + case *Int64Filter_Between: + qb.AddBetweenCondition("first_seen_date_time", DateTime64Value{uint64(filter.Between.Min)}, DateTime64Value{uint64(filter.Between.Max.GetValue())}) + case *Int64Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddInCondition("first_seen_date_time", converted) + } + case *Int64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddNotInCondition("first_seen_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: previous_hash + if req.PreviousHash != nil { + switch filter := req.PreviousHash.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("previous_hash", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("previous_hash", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("previous_hash", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("previous_hash", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("previous_hash", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("previous_hash", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("previous_hash", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("previous_hash", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("previous_hash", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("previous_hash") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("previous_hash") + default: + // Unsupported filter type + } + } + + // Add filter for column: to + if req.To != nil { + switch filter := req.To.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("to", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("to", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("to", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("to", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("to", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("to", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("to", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("to", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("to", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("to") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("to") + default: + // Unsupported filter type + } + } + + // Add filter for column: type + if req.Type != nil { + switch filter := req.Type.Filter.(type) { + case *NullableUInt32Filter_Eq: + qb.AddCondition("type", "=", filter.Eq) + case *NullableUInt32Filter_Ne: + qb.AddCondition("type", "!=", filter.Ne) + case *NullableUInt32Filter_Lt: + qb.AddCondition("type", "<", filter.Lt) + case *NullableUInt32Filter_Lte: + qb.AddCondition("type", "<=", filter.Lte) + case *NullableUInt32Filter_Gt: + qb.AddCondition("type", ">", filter.Gt) + case *NullableUInt32Filter_Gte: + qb.AddCondition("type", ">=", filter.Gte) + case *NullableUInt32Filter_Between: + qb.AddBetweenCondition("type", filter.Between.Min, filter.Between.Max.GetValue()) + case *NullableUInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type", UInt32SliceToInterface(filter.In.Values)) + } + case *NullableUInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type", UInt32SliceToInterface(filter.NotIn.Values)) + } + case *NullableUInt32Filter_IsNull: + qb.AddIsNullCondition("type") + case *NullableUInt32Filter_IsNotNull: + qb.AddIsNotNullCondition("type") + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_price + if req.GasPrice != nil { + switch filter := req.GasPrice.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("gas_price", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("gas_price", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("gas_price", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("gas_price", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("gas_price", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("gas_price", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("gas_price", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_price", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_price", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_tip_cap + if req.GasTipCap != nil { + switch filter := req.GasTipCap.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("gas_tip_cap", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("gas_tip_cap", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("gas_tip_cap", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("gas_tip_cap", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("gas_tip_cap", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("gas_tip_cap", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("gas_tip_cap", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_tip_cap", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_tip_cap", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("gas_tip_cap") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("gas_tip_cap") + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_fee_cap + if req.GasFeeCap != nil { + switch filter := req.GasFeeCap.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("gas_fee_cap", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("gas_fee_cap", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("gas_fee_cap", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("gas_fee_cap", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("gas_fee_cap", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("gas_fee_cap", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("gas_fee_cap", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_fee_cap", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_fee_cap", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("gas_fee_cap") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("gas_fee_cap") + default: + // Unsupported filter type + } + } + + // Add filter for column: value + if req.Value != nil { + switch filter := req.Value.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("value", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("value", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("value", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("value", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("value", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("value", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("value", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("value", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("value", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_tip_cap_delta + if req.GasTipCapDelta != nil { + switch filter := req.GasTipCapDelta.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("gas_tip_cap_delta", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("gas_tip_cap_delta", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("gas_tip_cap_delta", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("gas_tip_cap_delta", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("gas_tip_cap_delta", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("gas_tip_cap_delta", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("gas_tip_cap_delta", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_tip_cap_delta", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_tip_cap_delta", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("gas_tip_cap_delta") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("gas_tip_cap_delta") + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_fee_cap_delta + if req.GasFeeCapDelta != nil { + switch filter := req.GasFeeCapDelta.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("gas_fee_cap_delta", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("gas_fee_cap_delta", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("gas_fee_cap_delta", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("gas_fee_cap_delta", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("gas_fee_cap_delta", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("gas_fee_cap_delta", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("gas_fee_cap_delta", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_fee_cap_delta", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_fee_cap_delta", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("gas_fee_cap_delta") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("gas_fee_cap_delta") + default: + // Unsupported filter type + } + } + + // Add filter for column: is_cancel_shape + if req.IsCancelShape != nil { + switch filter := req.IsCancelShape.Filter.(type) { + case *BoolFilter_Eq: + qb.AddCondition("is_cancel_shape", "=", filter.Eq) + case *BoolFilter_Ne: + qb.AddCondition("is_cancel_shape", "!=", filter.Ne) + default: + // Unsupported filter type + } + } + + // Add filter for column: is_winner + if req.IsWinner != nil { + switch filter := req.IsWinner.Filter.(type) { + case *BoolFilter_Eq: + qb.AddCondition("is_winner", "=", filter.Eq) + case *BoolFilter_Ne: + qb.AddCondition("is_winner", "!=", filter.Ne) + default: + // Unsupported filter type + } + } + + // Add filter for column: group_outcome + if req.GroupOutcome != nil { + switch filter := req.GroupOutcome.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("group_outcome", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("group_outcome", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("group_outcome", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("group_outcome", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("group_outcome", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("group_outcome", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("group_outcome", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("group_outcome", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("group_outcome", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: winner_hash + if req.WinnerHash != nil { + switch filter := req.WinnerHash.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("winner_hash", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("winner_hash", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("winner_hash", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("winner_hash", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("winner_hash", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("winner_hash", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("winner_hash", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("winner_hash", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("winner_hash", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("winner_hash") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("winner_hash") + default: + // Unsupported filter type + } + } + + // Add filter for column: resolution_date_time + if req.ResolutionDateTime != nil { + switch filter := req.ResolutionDateTime.Filter.(type) { + case *Int64Filter_Eq: + qb.AddCondition("resolution_date_time", "=", DateTime64Value{uint64(filter.Eq)}) + case *Int64Filter_Ne: + qb.AddCondition("resolution_date_time", "!=", DateTime64Value{uint64(filter.Ne)}) + case *Int64Filter_Lt: + qb.AddCondition("resolution_date_time", "<", DateTime64Value{uint64(filter.Lt)}) + case *Int64Filter_Lte: + qb.AddCondition("resolution_date_time", "<=", DateTime64Value{uint64(filter.Lte)}) + case *Int64Filter_Gt: + qb.AddCondition("resolution_date_time", ">", DateTime64Value{uint64(filter.Gt)}) + case *Int64Filter_Gte: + qb.AddCondition("resolution_date_time", ">=", DateTime64Value{uint64(filter.Gte)}) + case *Int64Filter_Between: + qb.AddBetweenCondition("resolution_date_time", DateTime64Value{uint64(filter.Between.Min)}, DateTime64Value{uint64(filter.Between.Max.GetValue())}) + case *Int64Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddInCondition("resolution_date_time", converted) + } + case *Int64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddNotInCondition("resolution_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: observed_after_resolution + if req.ObservedAfterResolution != nil { + switch filter := req.ObservedAfterResolution.Filter.(type) { + case *BoolFilter_Eq: + qb.AddCondition("observed_after_resolution", "=", filter.Eq) + case *BoolFilter_Ne: + qb.AddCondition("observed_after_resolution", "!=", filter.Ne) + default: + // Unsupported filter type + } + } + + // Handle pagination per AIP-132 + // Validate page size + if req.PageSize < 0 { + return SQLQuery{}, fmt.Errorf("page_size must be non-negative, got %d", req.PageSize) + } + if req.PageSize > 10000 { + return SQLQuery{}, fmt.Errorf("page_size must not exceed %d, got %d", 10000, req.PageSize) + } + + var limit, offset uint32 + limit = 100 // Default page size + if req.PageSize > 0 { + limit = uint32(req.PageSize) + } + if req.PageToken != "" { + decodedOffset, err := DecodePageToken(req.PageToken) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid page_token: %w", err) + } + offset = decodedOffset + } + + // Handle custom ordering if provided + var orderByClause string + if req.OrderBy != "" { + validFields := []string{"updated_date_time", "group_first_seen_date_time", "from", "nonce", "hash", "attempt_index", "group_attempt_count", "first_seen_date_time", "previous_hash", "to", "type", "gas_price", "gas_tip_cap", "gas_fee_cap", "value", "gas_tip_cap_delta", "gas_fee_cap_delta", "is_cancel_shape", "is_winner", "group_outcome", "winner_hash", "resolution_date_time", "observed_after_resolution"} + orderFields, err := ParseOrderBy(req.OrderBy, validFields) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid order_by: %w", err) + } + orderByClause = BuildOrderByClause(orderFields) + } else { + // Default sorting by primary key + orderByClause = " ORDER BY group_first_seen_date_time" + ", from" + ", nonce" + ", hash" + } + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toUnixTimestamp64Micro(`group_first_seen_date_time`) AS `group_first_seen_date_time`", "NULLIF(`from`, repeat('\x00', 42)) AS `from`", "nonce", "NULLIF(`hash`, repeat('\x00', 66)) AS `hash`", "toUInt32(`attempt_index`) AS `attempt_index`", "toUInt32(`group_attempt_count`) AS `group_attempt_count`", "toUnixTimestamp64Micro(`first_seen_date_time`) AS `first_seen_date_time`", "NULLIF(`previous_hash`, repeat('\x00', 66)) AS `previous_hash`", "NULLIF(`to`, repeat('\x00', 42)) AS `to`", "toUInt32(`type`) AS `type`", "toString(`gas_price`) AS `gas_price`", "toString(`gas_tip_cap`) AS `gas_tip_cap`", "toString(`gas_fee_cap`) AS `gas_fee_cap`", "toString(`value`) AS `value`", "toString(`gas_tip_cap_delta`) AS `gas_tip_cap_delta`", "toString(`gas_fee_cap_delta`) AS `gas_fee_cap_delta`", "is_cancel_shape", "is_winner", "group_outcome", "NULLIF(`winner_hash`, repeat('\x00', 66)) AS `winner_hash`", "toUnixTimestamp64Micro(`resolution_date_time`) AS `resolution_date_time`", "observed_after_resolution"} + + return BuildParameterizedQuery("fct_transaction_replacement", columns, qb, orderByClause, limit, offset, options...) +} + +// BuildGetFctTransactionReplacementQuery constructs a parameterized SQL query from a GetFctTransactionReplacementRequest +func BuildGetFctTransactionReplacementQuery(req *GetFctTransactionReplacementRequest, options ...QueryOption) (SQLQuery, error) { + // Validate primary key is provided + if req.GroupFirstSeenDateTime == 0 { + return SQLQuery{}, fmt.Errorf("primary key field group_first_seen_date_time is required") + } + + // Build query with primary key condition + qb := NewQueryBuilder() + qb.AddCondition("group_first_seen_date_time", "=", req.GroupFirstSeenDateTime) + + // Build ORDER BY clause + orderByClause := " ORDER BY group_first_seen_date_time, from, nonce, hash" + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toUnixTimestamp64Micro(`group_first_seen_date_time`) AS `group_first_seen_date_time`", "NULLIF(`from`, repeat('\x00', 42)) AS `from`", "nonce", "NULLIF(`hash`, repeat('\x00', 66)) AS `hash`", "toUInt32(`attempt_index`) AS `attempt_index`", "toUInt32(`group_attempt_count`) AS `group_attempt_count`", "toUnixTimestamp64Micro(`first_seen_date_time`) AS `first_seen_date_time`", "NULLIF(`previous_hash`, repeat('\x00', 66)) AS `previous_hash`", "NULLIF(`to`, repeat('\x00', 42)) AS `to`", "toUInt32(`type`) AS `type`", "toString(`gas_price`) AS `gas_price`", "toString(`gas_tip_cap`) AS `gas_tip_cap`", "toString(`gas_fee_cap`) AS `gas_fee_cap`", "toString(`value`) AS `value`", "toString(`gas_tip_cap_delta`) AS `gas_tip_cap_delta`", "toString(`gas_fee_cap_delta`) AS `gas_fee_cap_delta`", "is_cancel_shape", "is_winner", "group_outcome", "NULLIF(`winner_hash`, repeat('\x00', 66)) AS `winner_hash`", "toUnixTimestamp64Micro(`resolution_date_time`) AS `resolution_date_time`", "observed_after_resolution"} + + // Return single record + return BuildParameterizedQuery("fct_transaction_replacement", columns, qb, orderByClause, 1, 0, options...) +} diff --git a/pkg/proto/clickhouse/fct_transaction_replacement.pb.go b/pkg/proto/clickhouse/fct_transaction_replacement.pb.go new file mode 100644 index 00000000..1a7b58e3 --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_replacement.pb.go @@ -0,0 +1,1100 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc (unknown) +// source: fct_transaction_replacement.proto + +package clickhouse + +import ( + _ "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse/clickhouse" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type FctTransactionReplacement struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Timestamp when the record was last updated + UpdatedDateTime uint32 `protobuf:"varint,11,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Earliest sighting of any attempt in the nonce group, the anchor of the group window + GroupFirstSeenDateTime int64 `protobuf:"varint,12,opt,name=group_first_seen_date_time,json=groupFirstSeenDateTime,proto3" json:"group_first_seen_date_time,omitempty"` + // The address of the account that sent the attempts + From string `protobuf:"bytes,13,opt,name=from,proto3" json:"from,omitempty"` + // The nonce the attempts compete for + Nonce uint64 `protobuf:"varint,14,opt,name=nonce,proto3" json:"nonce,omitempty"` + // The transaction hash of this attempt + Hash string `protobuf:"bytes,15,opt,name=hash,proto3" json:"hash,omitempty"` + // The 1-based rank of this attempt within the group, ordered by first sighting with ties broken by hash + AttemptIndex uint32 `protobuf:"varint,16,opt,name=attempt_index,json=attemptIndex,proto3" json:"attempt_index,omitempty"` + // Total number of publicly observed attempts in the group window + GroupAttemptCount uint32 `protobuf:"varint,17,opt,name=group_attempt_count,json=groupAttemptCount,proto3" json:"group_attempt_count,omitempty"` + // Earliest sighting of this attempt + FirstSeenDateTime int64 `protobuf:"varint,18,opt,name=first_seen_date_time,json=firstSeenDateTime,proto3" json:"first_seen_date_time,omitempty"` + // The hash of the attempt immediately before this one in the group, null for the first attempt + PreviousHash *wrapperspb.StringValue `protobuf:"bytes,19,opt,name=previous_hash,json=previousHash,proto3" json:"previous_hash,omitempty"` + // The address of the attempt recipient, null for contract creation + To *wrapperspb.StringValue `protobuf:"bytes,20,opt,name=to,proto3" json:"to,omitempty"` + // The type of the transaction + Type *wrapperspb.UInt32Value `protobuf:"bytes,21,opt,name=type,proto3" json:"type,omitempty"` + // The gas price of the attempt in wei + GasPrice string `protobuf:"bytes,22,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` + // The priority fee (tip) of the attempt in wei + GasTipCap *wrapperspb.StringValue `protobuf:"bytes,23,opt,name=gas_tip_cap,json=gasTipCap,proto3" json:"gas_tip_cap,omitempty"` + // The max fee of the attempt in wei + GasFeeCap *wrapperspb.StringValue `protobuf:"bytes,24,opt,name=gas_fee_cap,json=gasFeeCap,proto3" json:"gas_fee_cap,omitempty"` + // The value transferred with the attempt in wei + Value string `protobuf:"bytes,25,opt,name=value,proto3" json:"value,omitempty"` + // This attempt gas_tip_cap minus the previous attempt gas_tip_cap, null for the first attempt or when either side is null + GasTipCapDelta *wrapperspb.StringValue `protobuf:"bytes,26,opt,name=gas_tip_cap_delta,json=gasTipCapDelta,proto3" json:"gas_tip_cap_delta,omitempty"` + // This attempt gas_fee_cap minus the previous attempt gas_fee_cap, null for the first attempt or when either side is null + GasFeeCapDelta *wrapperspb.StringValue `protobuf:"bytes,27,opt,name=gas_fee_cap_delta,json=gasFeeCapDelta,proto3" json:"gas_fee_cap_delta,omitempty"` + // Whether the attempt is a self-transfer of zero value, the common wallet cancellation pattern + IsCancelShape bool `protobuf:"varint,28,opt,name=is_cancel_shape,json=isCancelShape,proto3" json:"is_cancel_shape,omitempty"` + // Whether this attempt is the one that was included on chain + IsWinner bool `protobuf:"varint,29,opt,name=is_winner,json=isWinner,proto3" json:"is_winner,omitempty"` + // Outcome of the nonce group within 7 days of the group anchor: included or unincluded + GroupOutcome string `protobuf:"bytes,30,opt,name=group_outcome,json=groupOutcome,proto3" json:"group_outcome,omitempty"` + // The hash of the included attempt, null when the group resolved unincluded + WinnerHash *wrapperspb.StringValue `protobuf:"bytes,31,opt,name=winner_hash,json=winnerHash,proto3" json:"winner_hash,omitempty"` + // When the group resolved: the winner inclusion slot start, or the group anchor plus 7 days when unincluded + ResolutionDateTime int64 `protobuf:"varint,32,opt,name=resolution_date_time,json=resolutionDateTime,proto3" json:"resolution_date_time,omitempty"` + // Whether this attempt was first sighted after the group had already resolved + ObservedAfterResolution bool `protobuf:"varint,33,opt,name=observed_after_resolution,json=observedAfterResolution,proto3" json:"observed_after_resolution,omitempty"` +} + +func (x *FctTransactionReplacement) Reset() { + *x = FctTransactionReplacement{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_replacement_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FctTransactionReplacement) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FctTransactionReplacement) ProtoMessage() {} + +func (x *FctTransactionReplacement) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_replacement_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FctTransactionReplacement.ProtoReflect.Descriptor instead. +func (*FctTransactionReplacement) Descriptor() ([]byte, []int) { + return file_fct_transaction_replacement_proto_rawDescGZIP(), []int{0} +} + +func (x *FctTransactionReplacement) GetUpdatedDateTime() uint32 { + if x != nil { + return x.UpdatedDateTime + } + return 0 +} + +func (x *FctTransactionReplacement) GetGroupFirstSeenDateTime() int64 { + if x != nil { + return x.GroupFirstSeenDateTime + } + return 0 +} + +func (x *FctTransactionReplacement) GetFrom() string { + if x != nil { + return x.From + } + return "" +} + +func (x *FctTransactionReplacement) GetNonce() uint64 { + if x != nil { + return x.Nonce + } + return 0 +} + +func (x *FctTransactionReplacement) GetHash() string { + if x != nil { + return x.Hash + } + return "" +} + +func (x *FctTransactionReplacement) GetAttemptIndex() uint32 { + if x != nil { + return x.AttemptIndex + } + return 0 +} + +func (x *FctTransactionReplacement) GetGroupAttemptCount() uint32 { + if x != nil { + return x.GroupAttemptCount + } + return 0 +} + +func (x *FctTransactionReplacement) GetFirstSeenDateTime() int64 { + if x != nil { + return x.FirstSeenDateTime + } + return 0 +} + +func (x *FctTransactionReplacement) GetPreviousHash() *wrapperspb.StringValue { + if x != nil { + return x.PreviousHash + } + return nil +} + +func (x *FctTransactionReplacement) GetTo() *wrapperspb.StringValue { + if x != nil { + return x.To + } + return nil +} + +func (x *FctTransactionReplacement) GetType() *wrapperspb.UInt32Value { + if x != nil { + return x.Type + } + return nil +} + +func (x *FctTransactionReplacement) GetGasPrice() string { + if x != nil { + return x.GasPrice + } + return "" +} + +func (x *FctTransactionReplacement) GetGasTipCap() *wrapperspb.StringValue { + if x != nil { + return x.GasTipCap + } + return nil +} + +func (x *FctTransactionReplacement) GetGasFeeCap() *wrapperspb.StringValue { + if x != nil { + return x.GasFeeCap + } + return nil +} + +func (x *FctTransactionReplacement) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *FctTransactionReplacement) GetGasTipCapDelta() *wrapperspb.StringValue { + if x != nil { + return x.GasTipCapDelta + } + return nil +} + +func (x *FctTransactionReplacement) GetGasFeeCapDelta() *wrapperspb.StringValue { + if x != nil { + return x.GasFeeCapDelta + } + return nil +} + +func (x *FctTransactionReplacement) GetIsCancelShape() bool { + if x != nil { + return x.IsCancelShape + } + return false +} + +func (x *FctTransactionReplacement) GetIsWinner() bool { + if x != nil { + return x.IsWinner + } + return false +} + +func (x *FctTransactionReplacement) GetGroupOutcome() string { + if x != nil { + return x.GroupOutcome + } + return "" +} + +func (x *FctTransactionReplacement) GetWinnerHash() *wrapperspb.StringValue { + if x != nil { + return x.WinnerHash + } + return nil +} + +func (x *FctTransactionReplacement) GetResolutionDateTime() int64 { + if x != nil { + return x.ResolutionDateTime + } + return 0 +} + +func (x *FctTransactionReplacement) GetObservedAfterResolution() bool { + if x != nil { + return x.ObservedAfterResolution + } + return false +} + +// Request for listing fct_transaction_replacement records +type ListFctTransactionReplacementRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Filter by group_first_seen_date_time - Earliest sighting of any attempt in the nonce group, the anchor of the group window (PRIMARY KEY - required unless using alternatives: hash, from) + GroupFirstSeenDateTime *Int64Filter `protobuf:"bytes,1,opt,name=group_first_seen_date_time,json=groupFirstSeenDateTime,proto3" json:"group_first_seen_date_time,omitempty"` + // Filter by from - The address of the account that sent the attempts (ORDER BY column 2 - optional) + From *StringFilter `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` + // Filter by nonce - The nonce the attempts compete for (ORDER BY column 3 - optional) + Nonce *UInt64Filter `protobuf:"bytes,3,opt,name=nonce,proto3" json:"nonce,omitempty"` + // Filter by hash - The transaction hash of this attempt (ORDER BY column 4 - optional) + Hash *StringFilter `protobuf:"bytes,4,opt,name=hash,proto3" json:"hash,omitempty"` + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UpdatedDateTime *UInt32Filter `protobuf:"bytes,5,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Filter by attempt_index - The 1-based rank of this attempt within the group, ordered by first sighting with ties broken by hash (optional) + AttemptIndex *UInt32Filter `protobuf:"bytes,6,opt,name=attempt_index,json=attemptIndex,proto3" json:"attempt_index,omitempty"` + // Filter by group_attempt_count - Total number of publicly observed attempts in the group window (optional) + GroupAttemptCount *UInt32Filter `protobuf:"bytes,7,opt,name=group_attempt_count,json=groupAttemptCount,proto3" json:"group_attempt_count,omitempty"` + // Filter by first_seen_date_time - Earliest sighting of this attempt (optional) + FirstSeenDateTime *Int64Filter `protobuf:"bytes,8,opt,name=first_seen_date_time,json=firstSeenDateTime,proto3" json:"first_seen_date_time,omitempty"` + // Filter by previous_hash - The hash of the attempt immediately before this one in the group, null for the first attempt (optional) + PreviousHash *NullableStringFilter `protobuf:"bytes,9,opt,name=previous_hash,json=previousHash,proto3" json:"previous_hash,omitempty"` + // Filter by to - The address of the attempt recipient, null for contract creation (optional) + To *NullableStringFilter `protobuf:"bytes,10,opt,name=to,proto3" json:"to,omitempty"` + // Filter by type - The type of the transaction (optional) + Type *NullableUInt32Filter `protobuf:"bytes,11,opt,name=type,proto3" json:"type,omitempty"` + // Filter by gas_price - The gas price of the attempt in wei (optional) + GasPrice *StringFilter `protobuf:"bytes,12,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` + // Filter by gas_tip_cap - The priority fee (tip) of the attempt in wei (optional) + GasTipCap *NullableStringFilter `protobuf:"bytes,13,opt,name=gas_tip_cap,json=gasTipCap,proto3" json:"gas_tip_cap,omitempty"` + // Filter by gas_fee_cap - The max fee of the attempt in wei (optional) + GasFeeCap *NullableStringFilter `protobuf:"bytes,14,opt,name=gas_fee_cap,json=gasFeeCap,proto3" json:"gas_fee_cap,omitempty"` + // Filter by value - The value transferred with the attempt in wei (optional) + Value *StringFilter `protobuf:"bytes,15,opt,name=value,proto3" json:"value,omitempty"` + // Filter by gas_tip_cap_delta - This attempt gas_tip_cap minus the previous attempt gas_tip_cap, null for the first attempt or when either side is null (optional) + GasTipCapDelta *NullableStringFilter `protobuf:"bytes,16,opt,name=gas_tip_cap_delta,json=gasTipCapDelta,proto3" json:"gas_tip_cap_delta,omitempty"` + // Filter by gas_fee_cap_delta - This attempt gas_fee_cap minus the previous attempt gas_fee_cap, null for the first attempt or when either side is null (optional) + GasFeeCapDelta *NullableStringFilter `protobuf:"bytes,17,opt,name=gas_fee_cap_delta,json=gasFeeCapDelta,proto3" json:"gas_fee_cap_delta,omitempty"` + // Filter by is_cancel_shape - Whether the attempt is a self-transfer of zero value, the common wallet cancellation pattern (optional) + IsCancelShape *BoolFilter `protobuf:"bytes,18,opt,name=is_cancel_shape,json=isCancelShape,proto3" json:"is_cancel_shape,omitempty"` + // Filter by is_winner - Whether this attempt is the one that was included on chain (optional) + IsWinner *BoolFilter `protobuf:"bytes,19,opt,name=is_winner,json=isWinner,proto3" json:"is_winner,omitempty"` + // Filter by group_outcome - Outcome of the nonce group within 7 days of the group anchor: included or unincluded (optional) + GroupOutcome *StringFilter `protobuf:"bytes,20,opt,name=group_outcome,json=groupOutcome,proto3" json:"group_outcome,omitempty"` + // Filter by winner_hash - The hash of the included attempt, null when the group resolved unincluded (optional) + WinnerHash *NullableStringFilter `protobuf:"bytes,21,opt,name=winner_hash,json=winnerHash,proto3" json:"winner_hash,omitempty"` + // Filter by resolution_date_time - When the group resolved: the winner inclusion slot start, or the group anchor plus 7 days when unincluded (optional) + ResolutionDateTime *Int64Filter `protobuf:"bytes,22,opt,name=resolution_date_time,json=resolutionDateTime,proto3" json:"resolution_date_time,omitempty"` + // Filter by observed_after_resolution - Whether this attempt was first sighted after the group had already resolved (optional) + ObservedAfterResolution *BoolFilter `protobuf:"bytes,23,opt,name=observed_after_resolution,json=observedAfterResolution,proto3" json:"observed_after_resolution,omitempty"` + // The maximum number of fct_transaction_replacement to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + PageSize int32 `protobuf:"varint,24,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // A page token, received from a previous `ListFctTransactionReplacement` call. + // Provide this to retrieve the subsequent page. + PageToken string `protobuf:"bytes,25,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + OrderBy string `protobuf:"bytes,26,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"` +} + +func (x *ListFctTransactionReplacementRequest) Reset() { + *x = ListFctTransactionReplacementRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_replacement_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionReplacementRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionReplacementRequest) ProtoMessage() {} + +func (x *ListFctTransactionReplacementRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_replacement_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionReplacementRequest.ProtoReflect.Descriptor instead. +func (*ListFctTransactionReplacementRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_replacement_proto_rawDescGZIP(), []int{1} +} + +func (x *ListFctTransactionReplacementRequest) GetGroupFirstSeenDateTime() *Int64Filter { + if x != nil { + return x.GroupFirstSeenDateTime + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetFrom() *StringFilter { + if x != nil { + return x.From + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetNonce() *UInt64Filter { + if x != nil { + return x.Nonce + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetHash() *StringFilter { + if x != nil { + return x.Hash + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetUpdatedDateTime() *UInt32Filter { + if x != nil { + return x.UpdatedDateTime + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetAttemptIndex() *UInt32Filter { + if x != nil { + return x.AttemptIndex + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetGroupAttemptCount() *UInt32Filter { + if x != nil { + return x.GroupAttemptCount + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetFirstSeenDateTime() *Int64Filter { + if x != nil { + return x.FirstSeenDateTime + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetPreviousHash() *NullableStringFilter { + if x != nil { + return x.PreviousHash + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetTo() *NullableStringFilter { + if x != nil { + return x.To + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetType() *NullableUInt32Filter { + if x != nil { + return x.Type + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetGasPrice() *StringFilter { + if x != nil { + return x.GasPrice + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetGasTipCap() *NullableStringFilter { + if x != nil { + return x.GasTipCap + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetGasFeeCap() *NullableStringFilter { + if x != nil { + return x.GasFeeCap + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetValue() *StringFilter { + if x != nil { + return x.Value + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetGasTipCapDelta() *NullableStringFilter { + if x != nil { + return x.GasTipCapDelta + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetGasFeeCapDelta() *NullableStringFilter { + if x != nil { + return x.GasFeeCapDelta + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetIsCancelShape() *BoolFilter { + if x != nil { + return x.IsCancelShape + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetIsWinner() *BoolFilter { + if x != nil { + return x.IsWinner + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetGroupOutcome() *StringFilter { + if x != nil { + return x.GroupOutcome + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetWinnerHash() *NullableStringFilter { + if x != nil { + return x.WinnerHash + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetResolutionDateTime() *Int64Filter { + if x != nil { + return x.ResolutionDateTime + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetObservedAfterResolution() *BoolFilter { + if x != nil { + return x.ObservedAfterResolution + } + return nil +} + +func (x *ListFctTransactionReplacementRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListFctTransactionReplacementRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +func (x *ListFctTransactionReplacementRequest) GetOrderBy() string { + if x != nil { + return x.OrderBy + } + return "" +} + +// Response for listing fct_transaction_replacement records +type ListFctTransactionReplacementResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of fct_transaction_replacement. + FctTransactionReplacement []*FctTransactionReplacement `protobuf:"bytes,1,rep,name=fct_transaction_replacement,json=fctTransactionReplacement,proto3" json:"fct_transaction_replacement,omitempty"` + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` +} + +func (x *ListFctTransactionReplacementResponse) Reset() { + *x = ListFctTransactionReplacementResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_replacement_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListFctTransactionReplacementResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListFctTransactionReplacementResponse) ProtoMessage() {} + +func (x *ListFctTransactionReplacementResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_replacement_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListFctTransactionReplacementResponse.ProtoReflect.Descriptor instead. +func (*ListFctTransactionReplacementResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_replacement_proto_rawDescGZIP(), []int{2} +} + +func (x *ListFctTransactionReplacementResponse) GetFctTransactionReplacement() []*FctTransactionReplacement { + if x != nil { + return x.FctTransactionReplacement + } + return nil +} + +func (x *ListFctTransactionReplacementResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +// Request for getting a single fct_transaction_replacement record by primary key +type GetFctTransactionReplacementRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Earliest sighting of any attempt in the nonce group, the anchor of the group window + GroupFirstSeenDateTime int64 `protobuf:"varint,1,opt,name=group_first_seen_date_time,json=groupFirstSeenDateTime,proto3" json:"group_first_seen_date_time,omitempty"` // Primary key (required) +} + +func (x *GetFctTransactionReplacementRequest) Reset() { + *x = GetFctTransactionReplacementRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_replacement_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionReplacementRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionReplacementRequest) ProtoMessage() {} + +func (x *GetFctTransactionReplacementRequest) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_replacement_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionReplacementRequest.ProtoReflect.Descriptor instead. +func (*GetFctTransactionReplacementRequest) Descriptor() ([]byte, []int) { + return file_fct_transaction_replacement_proto_rawDescGZIP(), []int{3} +} + +func (x *GetFctTransactionReplacementRequest) GetGroupFirstSeenDateTime() int64 { + if x != nil { + return x.GroupFirstSeenDateTime + } + return 0 +} + +// Response for getting a single fct_transaction_replacement record +type GetFctTransactionReplacementResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *FctTransactionReplacement `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *GetFctTransactionReplacementResponse) Reset() { + *x = GetFctTransactionReplacementResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_fct_transaction_replacement_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFctTransactionReplacementResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFctTransactionReplacementResponse) ProtoMessage() {} + +func (x *GetFctTransactionReplacementResponse) ProtoReflect() protoreflect.Message { + mi := &file_fct_transaction_replacement_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFctTransactionReplacementResponse.ProtoReflect.Descriptor instead. +func (*GetFctTransactionReplacementResponse) Descriptor() ([]byte, []int) { + return file_fct_transaction_replacement_proto_rawDescGZIP(), []int{4} +} + +func (x *GetFctTransactionReplacementResponse) GetItem() *FctTransactionReplacement { + if x != nil { + return x.Item + } + return nil +} + +var File_fct_transaction_replacement_proto protoreflect.FileDescriptor + +var file_fct_transaction_replacement_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x63, 0x62, 0x74, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x68, 0x6f, 0x75, 0x73, + 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0xc2, 0x08, 0x0a, 0x19, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, + 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3a, 0x0a, + 0x1a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, + 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x16, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x46, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x65, + 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, + 0x6d, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x14, 0x0a, + 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x74, 0x74, 0x65, 0x6d, + 0x70, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, + 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2e, 0x0a, 0x13, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x14, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x53, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x41, 0x0a, + 0x0d, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x13, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x48, 0x61, 0x73, 0x68, + 0x12, 0x2c, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x30, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, + 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x16, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x3c, 0x0a, + 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x70, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x17, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x09, 0x67, 0x61, 0x73, 0x54, 0x69, 0x70, 0x43, 0x61, 0x70, 0x12, 0x3c, 0x0a, 0x0b, 0x67, + 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, + 0x67, 0x61, 0x73, 0x46, 0x65, 0x65, 0x43, 0x61, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x47, 0x0a, 0x11, 0x67, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x70, 0x5f, 0x63, 0x61, 0x70, 0x5f, 0x64, + 0x65, 0x6c, 0x74, 0x61, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x67, 0x61, 0x73, 0x54, 0x69, 0x70, + 0x43, 0x61, 0x70, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x47, 0x0a, 0x11, 0x67, 0x61, 0x73, 0x5f, + 0x66, 0x65, 0x65, 0x5f, 0x63, 0x61, 0x70, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x1b, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x0e, 0x67, 0x61, 0x73, 0x46, 0x65, 0x65, 0x43, 0x61, 0x70, 0x44, 0x65, 0x6c, 0x74, + 0x61, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x73, 0x5f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x73, + 0x68, 0x61, 0x70, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x73, 0x43, 0x61, + 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, + 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, + 0x57, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, + 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x77, + 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, + 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x61, 0x73, 0x68, 0x12, 0x30, 0x0a, 0x14, 0x72, 0x65, + 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x20, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x19, + 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x72, + 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x17, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb1, 0x0c, 0x0a, 0x24, 0x4c, 0x69, 0x73, + 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x60, 0x0a, 0x1a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, + 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x36, + 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x12, 0xe0, 0x41, 0x01, 0x9a, 0xb5, 0x18, 0x0b, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x52, 0x16, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x46, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, + 0x2c, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x2a, 0x0a, + 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x42, 0x0a, 0x11, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, + 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0f, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3b, 0x0a, + 0x0d, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, + 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0c, 0x61, 0x74, + 0x74, 0x65, 0x6d, 0x70, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x46, 0x0a, 0x13, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, + 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x11, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x46, 0x0a, 0x14, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, + 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x11, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, + 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x0d, 0x70, 0x72, + 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, + 0x01, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x48, 0x61, 0x73, 0x68, 0x12, + 0x2e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x02, 0x74, 0x6f, 0x12, + 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x49, 0x6e, 0x74, + 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x33, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, + 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, + 0x74, 0x69, 0x70, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x67, + 0x61, 0x73, 0x54, 0x69, 0x70, 0x43, 0x61, 0x70, 0x12, 0x3e, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, + 0x66, 0x65, 0x65, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x67, + 0x61, 0x73, 0x46, 0x65, 0x65, 0x43, 0x61, 0x70, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x49, 0x0a, 0x11, 0x67, 0x61, 0x73, 0x5f, 0x74, 0x69, + 0x70, 0x5f, 0x63, 0x61, 0x70, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, + 0x01, 0x52, 0x0e, 0x67, 0x61, 0x73, 0x54, 0x69, 0x70, 0x43, 0x61, 0x70, 0x44, 0x65, 0x6c, 0x74, + 0x61, 0x12, 0x49, 0x0a, 0x11, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x63, 0x61, 0x70, + 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, + 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0e, 0x67, 0x61, + 0x73, 0x46, 0x65, 0x65, 0x43, 0x61, 0x70, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x3c, 0x0a, 0x0f, + 0x69, 0x73, 0x5f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x18, + 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0d, 0x69, 0x73, 0x43, + 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x70, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x69, 0x73, + 0x5f, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x08, 0x69, 0x73, 0x57, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x3b, 0x0a, + 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x18, 0x14, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0c, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x4f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x0b, 0x77, 0x69, + 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x0a, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x61, 0x73, 0x68, 0x12, 0x47, 0x0a, 0x14, 0x72, + 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x62, 0x74, 0x2e, + 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, + 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x65, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x19, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x42, 0x6f, + 0x6f, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x17, 0x6f, + 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x41, 0x66, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, + 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, + 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, + 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1e, 0x0a, 0x08, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, 0xaf, 0x01, 0x0a, + 0x25, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x1b, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x19, 0x66, 0x63, 0x74, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, + 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x61, + 0x0a, 0x23, 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x1a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x16, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x46, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, + 0x65, 0x22, 0x5a, 0x0a, 0x24, 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x04, 0x69, 0x74, 0x65, + 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x46, 0x63, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0xd6, 0x02, + 0x0a, 0x20, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x8a, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x29, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x12, 0x23, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x63, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0xa4, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x28, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x47, 0x65, + 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x29, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x63, 0x74, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x48, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x42, 0x12, 0x40, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x63, + 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x7b, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x7d, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x70, 0x61, 0x6e, 0x64, 0x61, 0x6f, 0x70, 0x73, + 0x2f, 0x78, 0x61, 0x74, 0x75, 0x2d, 0x63, 0x62, 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_fct_transaction_replacement_proto_rawDescOnce sync.Once + file_fct_transaction_replacement_proto_rawDescData = file_fct_transaction_replacement_proto_rawDesc +) + +func file_fct_transaction_replacement_proto_rawDescGZIP() []byte { + file_fct_transaction_replacement_proto_rawDescOnce.Do(func() { + file_fct_transaction_replacement_proto_rawDescData = protoimpl.X.CompressGZIP(file_fct_transaction_replacement_proto_rawDescData) + }) + return file_fct_transaction_replacement_proto_rawDescData +} + +var file_fct_transaction_replacement_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_fct_transaction_replacement_proto_goTypes = []any{ + (*FctTransactionReplacement)(nil), // 0: cbt.FctTransactionReplacement + (*ListFctTransactionReplacementRequest)(nil), // 1: cbt.ListFctTransactionReplacementRequest + (*ListFctTransactionReplacementResponse)(nil), // 2: cbt.ListFctTransactionReplacementResponse + (*GetFctTransactionReplacementRequest)(nil), // 3: cbt.GetFctTransactionReplacementRequest + (*GetFctTransactionReplacementResponse)(nil), // 4: cbt.GetFctTransactionReplacementResponse + (*wrapperspb.StringValue)(nil), // 5: google.protobuf.StringValue + (*wrapperspb.UInt32Value)(nil), // 6: google.protobuf.UInt32Value + (*Int64Filter)(nil), // 7: cbt.Int64Filter + (*StringFilter)(nil), // 8: cbt.StringFilter + (*UInt64Filter)(nil), // 9: cbt.UInt64Filter + (*UInt32Filter)(nil), // 10: cbt.UInt32Filter + (*NullableStringFilter)(nil), // 11: cbt.NullableStringFilter + (*NullableUInt32Filter)(nil), // 12: cbt.NullableUInt32Filter + (*BoolFilter)(nil), // 13: cbt.BoolFilter +} +var file_fct_transaction_replacement_proto_depIdxs = []int32{ + 5, // 0: cbt.FctTransactionReplacement.previous_hash:type_name -> google.protobuf.StringValue + 5, // 1: cbt.FctTransactionReplacement.to:type_name -> google.protobuf.StringValue + 6, // 2: cbt.FctTransactionReplacement.type:type_name -> google.protobuf.UInt32Value + 5, // 3: cbt.FctTransactionReplacement.gas_tip_cap:type_name -> google.protobuf.StringValue + 5, // 4: cbt.FctTransactionReplacement.gas_fee_cap:type_name -> google.protobuf.StringValue + 5, // 5: cbt.FctTransactionReplacement.gas_tip_cap_delta:type_name -> google.protobuf.StringValue + 5, // 6: cbt.FctTransactionReplacement.gas_fee_cap_delta:type_name -> google.protobuf.StringValue + 5, // 7: cbt.FctTransactionReplacement.winner_hash:type_name -> google.protobuf.StringValue + 7, // 8: cbt.ListFctTransactionReplacementRequest.group_first_seen_date_time:type_name -> cbt.Int64Filter + 8, // 9: cbt.ListFctTransactionReplacementRequest.from:type_name -> cbt.StringFilter + 9, // 10: cbt.ListFctTransactionReplacementRequest.nonce:type_name -> cbt.UInt64Filter + 8, // 11: cbt.ListFctTransactionReplacementRequest.hash:type_name -> cbt.StringFilter + 10, // 12: cbt.ListFctTransactionReplacementRequest.updated_date_time:type_name -> cbt.UInt32Filter + 10, // 13: cbt.ListFctTransactionReplacementRequest.attempt_index:type_name -> cbt.UInt32Filter + 10, // 14: cbt.ListFctTransactionReplacementRequest.group_attempt_count:type_name -> cbt.UInt32Filter + 7, // 15: cbt.ListFctTransactionReplacementRequest.first_seen_date_time:type_name -> cbt.Int64Filter + 11, // 16: cbt.ListFctTransactionReplacementRequest.previous_hash:type_name -> cbt.NullableStringFilter + 11, // 17: cbt.ListFctTransactionReplacementRequest.to:type_name -> cbt.NullableStringFilter + 12, // 18: cbt.ListFctTransactionReplacementRequest.type:type_name -> cbt.NullableUInt32Filter + 8, // 19: cbt.ListFctTransactionReplacementRequest.gas_price:type_name -> cbt.StringFilter + 11, // 20: cbt.ListFctTransactionReplacementRequest.gas_tip_cap:type_name -> cbt.NullableStringFilter + 11, // 21: cbt.ListFctTransactionReplacementRequest.gas_fee_cap:type_name -> cbt.NullableStringFilter + 8, // 22: cbt.ListFctTransactionReplacementRequest.value:type_name -> cbt.StringFilter + 11, // 23: cbt.ListFctTransactionReplacementRequest.gas_tip_cap_delta:type_name -> cbt.NullableStringFilter + 11, // 24: cbt.ListFctTransactionReplacementRequest.gas_fee_cap_delta:type_name -> cbt.NullableStringFilter + 13, // 25: cbt.ListFctTransactionReplacementRequest.is_cancel_shape:type_name -> cbt.BoolFilter + 13, // 26: cbt.ListFctTransactionReplacementRequest.is_winner:type_name -> cbt.BoolFilter + 8, // 27: cbt.ListFctTransactionReplacementRequest.group_outcome:type_name -> cbt.StringFilter + 11, // 28: cbt.ListFctTransactionReplacementRequest.winner_hash:type_name -> cbt.NullableStringFilter + 7, // 29: cbt.ListFctTransactionReplacementRequest.resolution_date_time:type_name -> cbt.Int64Filter + 13, // 30: cbt.ListFctTransactionReplacementRequest.observed_after_resolution:type_name -> cbt.BoolFilter + 0, // 31: cbt.ListFctTransactionReplacementResponse.fct_transaction_replacement:type_name -> cbt.FctTransactionReplacement + 0, // 32: cbt.GetFctTransactionReplacementResponse.item:type_name -> cbt.FctTransactionReplacement + 1, // 33: cbt.FctTransactionReplacementService.List:input_type -> cbt.ListFctTransactionReplacementRequest + 3, // 34: cbt.FctTransactionReplacementService.Get:input_type -> cbt.GetFctTransactionReplacementRequest + 2, // 35: cbt.FctTransactionReplacementService.List:output_type -> cbt.ListFctTransactionReplacementResponse + 4, // 36: cbt.FctTransactionReplacementService.Get:output_type -> cbt.GetFctTransactionReplacementResponse + 35, // [35:37] is the sub-list for method output_type + 33, // [33:35] is the sub-list for method input_type + 33, // [33:33] is the sub-list for extension type_name + 33, // [33:33] is the sub-list for extension extendee + 0, // [0:33] is the sub-list for field type_name +} + +func init() { file_fct_transaction_replacement_proto_init() } +func file_fct_transaction_replacement_proto_init() { + if File_fct_transaction_replacement_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_fct_transaction_replacement_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*FctTransactionReplacement); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_replacement_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionReplacementRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_replacement_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*ListFctTransactionReplacementResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_replacement_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionReplacementRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_fct_transaction_replacement_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*GetFctTransactionReplacementResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_fct_transaction_replacement_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_fct_transaction_replacement_proto_goTypes, + DependencyIndexes: file_fct_transaction_replacement_proto_depIdxs, + MessageInfos: file_fct_transaction_replacement_proto_msgTypes, + }.Build() + File_fct_transaction_replacement_proto = out.File + file_fct_transaction_replacement_proto_rawDesc = nil + file_fct_transaction_replacement_proto_goTypes = nil + file_fct_transaction_replacement_proto_depIdxs = nil +} diff --git a/pkg/proto/clickhouse/fct_transaction_replacement.proto b/pkg/proto/clickhouse/fct_transaction_replacement.proto new file mode 100644 index 00000000..3cbcfa61 --- /dev/null +++ b/pkg/proto/clickhouse/fct_transaction_replacement.proto @@ -0,0 +1,163 @@ +syntax = "proto3"; + +package cbt; + +import "common.proto"; +import "google/protobuf/wrappers.proto"; +import "google/api/annotations.proto"; +import "google/api/field_behavior.proto"; +import "clickhouse/annotations.proto"; + +option go_package = "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse"; +// One row per publicly observed attempt in nonce groups with at least two attempts, emitted when the group resolves. A nonce group is all transactions sharing a from address and nonce whose first sightings fall within 7 days of the group anchor + +message FctTransactionReplacement { + // Timestamp when the record was last updated + uint32 updated_date_time = 11; + // Earliest sighting of any attempt in the nonce group, the anchor of the group window + int64 group_first_seen_date_time = 12; + // The address of the account that sent the attempts + string from = 13; + // The nonce the attempts compete for + uint64 nonce = 14; + // The transaction hash of this attempt + string hash = 15; + // The 1-based rank of this attempt within the group, ordered by first sighting with ties broken by hash + uint32 attempt_index = 16; + // Total number of publicly observed attempts in the group window + uint32 group_attempt_count = 17; + // Earliest sighting of this attempt + int64 first_seen_date_time = 18; + // The hash of the attempt immediately before this one in the group, null for the first attempt + google.protobuf.StringValue previous_hash = 19; + // The address of the attempt recipient, null for contract creation + google.protobuf.StringValue to = 20; + // The type of the transaction + google.protobuf.UInt32Value type = 21; + // The gas price of the attempt in wei + string gas_price = 22; + // The priority fee (tip) of the attempt in wei + google.protobuf.StringValue gas_tip_cap = 23; + // The max fee of the attempt in wei + google.protobuf.StringValue gas_fee_cap = 24; + // The value transferred with the attempt in wei + string value = 25; + // This attempt gas_tip_cap minus the previous attempt gas_tip_cap, null for the first attempt or when either side is null + google.protobuf.StringValue gas_tip_cap_delta = 26; + // This attempt gas_fee_cap minus the previous attempt gas_fee_cap, null for the first attempt or when either side is null + google.protobuf.StringValue gas_fee_cap_delta = 27; + // Whether the attempt is a self-transfer of zero value, the common wallet cancellation pattern + bool is_cancel_shape = 28; + // Whether this attempt is the one that was included on chain + bool is_winner = 29; + // Outcome of the nonce group within 7 days of the group anchor: included or unincluded + string group_outcome = 30; + // The hash of the included attempt, null when the group resolved unincluded + google.protobuf.StringValue winner_hash = 31; + // When the group resolved: the winner inclusion slot start, or the group anchor plus 7 days when unincluded + int64 resolution_date_time = 32; + // Whether this attempt was first sighted after the group had already resolved + bool observed_after_resolution = 33; +} + +// Request for listing fct_transaction_replacement records +message ListFctTransactionReplacementRequest { + // Filter by group_first_seen_date_time - Earliest sighting of any attempt in the nonce group, the anchor of the group window (PRIMARY KEY - required unless using alternatives: hash, from) + Int64Filter group_first_seen_date_time = 1 [(google.api.field_behavior) = OPTIONAL, (clickhouse.v1.required_group) = "primary_key"]; + + // Filter by from - The address of the account that sent the attempts (ORDER BY column 2 - optional) + StringFilter from = 2 [(google.api.field_behavior) = OPTIONAL]; + + // Filter by nonce - The nonce the attempts compete for (ORDER BY column 3 - optional) + UInt64Filter nonce = 3 [(google.api.field_behavior) = OPTIONAL]; + + // Filter by hash - The transaction hash of this attempt (ORDER BY column 4 - optional) + StringFilter hash = 4 [(google.api.field_behavior) = OPTIONAL]; + + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UInt32Filter updated_date_time = 5 [(google.api.field_behavior) = OPTIONAL]; + // Filter by attempt_index - The 1-based rank of this attempt within the group, ordered by first sighting with ties broken by hash (optional) + UInt32Filter attempt_index = 6 [(google.api.field_behavior) = OPTIONAL]; + // Filter by group_attempt_count - Total number of publicly observed attempts in the group window (optional) + UInt32Filter group_attempt_count = 7 [(google.api.field_behavior) = OPTIONAL]; + // Filter by first_seen_date_time - Earliest sighting of this attempt (optional) + Int64Filter first_seen_date_time = 8 [(google.api.field_behavior) = OPTIONAL]; + // Filter by previous_hash - The hash of the attempt immediately before this one in the group, null for the first attempt (optional) + NullableStringFilter previous_hash = 9 [(google.api.field_behavior) = OPTIONAL]; + // Filter by to - The address of the attempt recipient, null for contract creation (optional) + NullableStringFilter to = 10 [(google.api.field_behavior) = OPTIONAL]; + // Filter by type - The type of the transaction (optional) + NullableUInt32Filter type = 11 [(google.api.field_behavior) = OPTIONAL]; + // Filter by gas_price - The gas price of the attempt in wei (optional) + StringFilter gas_price = 12 [(google.api.field_behavior) = OPTIONAL]; + // Filter by gas_tip_cap - The priority fee (tip) of the attempt in wei (optional) + NullableStringFilter gas_tip_cap = 13 [(google.api.field_behavior) = OPTIONAL]; + // Filter by gas_fee_cap - The max fee of the attempt in wei (optional) + NullableStringFilter gas_fee_cap = 14 [(google.api.field_behavior) = OPTIONAL]; + // Filter by value - The value transferred with the attempt in wei (optional) + StringFilter value = 15 [(google.api.field_behavior) = OPTIONAL]; + // Filter by gas_tip_cap_delta - This attempt gas_tip_cap minus the previous attempt gas_tip_cap, null for the first attempt or when either side is null (optional) + NullableStringFilter gas_tip_cap_delta = 16 [(google.api.field_behavior) = OPTIONAL]; + // Filter by gas_fee_cap_delta - This attempt gas_fee_cap minus the previous attempt gas_fee_cap, null for the first attempt or when either side is null (optional) + NullableStringFilter gas_fee_cap_delta = 17 [(google.api.field_behavior) = OPTIONAL]; + // Filter by is_cancel_shape - Whether the attempt is a self-transfer of zero value, the common wallet cancellation pattern (optional) + BoolFilter is_cancel_shape = 18 [(google.api.field_behavior) = OPTIONAL]; + // Filter by is_winner - Whether this attempt is the one that was included on chain (optional) + BoolFilter is_winner = 19 [(google.api.field_behavior) = OPTIONAL]; + // Filter by group_outcome - Outcome of the nonce group within 7 days of the group anchor: included or unincluded (optional) + StringFilter group_outcome = 20 [(google.api.field_behavior) = OPTIONAL]; + // Filter by winner_hash - The hash of the included attempt, null when the group resolved unincluded (optional) + NullableStringFilter winner_hash = 21 [(google.api.field_behavior) = OPTIONAL]; + // Filter by resolution_date_time - When the group resolved: the winner inclusion slot start, or the group anchor plus 7 days when unincluded (optional) + Int64Filter resolution_date_time = 22 [(google.api.field_behavior) = OPTIONAL]; + // Filter by observed_after_resolution - Whether this attempt was first sighted after the group had already resolved (optional) + BoolFilter observed_after_resolution = 23 [(google.api.field_behavior) = OPTIONAL]; + + // The maximum number of fct_transaction_replacement to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + int32 page_size = 24 [(google.api.field_behavior) = OPTIONAL]; + // A page token, received from a previous `ListFctTransactionReplacement` call. + // Provide this to retrieve the subsequent page. + string page_token = 25 [(google.api.field_behavior) = OPTIONAL]; + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + string order_by = 26 [(google.api.field_behavior) = OPTIONAL]; +} + +// Response for listing fct_transaction_replacement records +message ListFctTransactionReplacementResponse { + // The list of fct_transaction_replacement. + repeated FctTransactionReplacement fct_transaction_replacement = 1; + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; +} + +// Request for getting a single fct_transaction_replacement record by primary key +message GetFctTransactionReplacementRequest { + // Earliest sighting of any attempt in the nonce group, the anchor of the group window + int64 group_first_seen_date_time = 1; // Primary key (required) +} + +// Response for getting a single fct_transaction_replacement record +message GetFctTransactionReplacementResponse { + FctTransactionReplacement item = 1; +} + +// Query fct_transaction_replacement data +service FctTransactionReplacementService { + // List records | Retrieve paginated results with optional filtering + rpc List(ListFctTransactionReplacementRequest) returns (ListFctTransactionReplacementResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_replacement" + }; + } + // Get record | Retrieve a single record by group_first_seen_date_time + rpc Get(GetFctTransactionReplacementRequest) returns (GetFctTransactionReplacementResponse) { + option (google.api.http) = { + get: "/api/v1/fct_transaction_replacement/{group_first_seen_date_time}" + }; + } +} diff --git a/pkg/proto/clickhouse/int_transaction_mempool_observation_hourly.go b/pkg/proto/clickhouse/int_transaction_mempool_observation_hourly.go new file mode 100644 index 00000000..daba2fb5 --- /dev/null +++ b/pkg/proto/clickhouse/int_transaction_mempool_observation_hourly.go @@ -0,0 +1,938 @@ +// Code generated by clickhouse-proto-gen. DO NOT EDIT. +// SQL query builder for int_transaction_mempool_observation_hourly + +package clickhouse + +import ( + "fmt" +) + +// BuildListIntTransactionMempoolObservationHourlyQuery constructs a parameterized SQL query from a ListIntTransactionMempoolObservationHourlyRequest +// +// Available projections: +// - p_by_hash (primary key: hash) +// - p_by_nonce_group (primary key: from) +// +// Use WithProjection() option to select a specific projection. +func BuildListIntTransactionMempoolObservationHourlyQuery(req *ListIntTransactionMempoolObservationHourlyRequest, options ...QueryOption) (SQLQuery, error) { + // Validate that at least one primary key is provided + // Primary keys can come from base table or projections + if req.From == nil && req.Hash == nil && req.HourStartDateTime == nil { + return SQLQuery{}, fmt.Errorf("at least one primary key field is required: from, hash, hour_start_date_time") + } + + // Build query using QueryBuilder + qb := NewQueryBuilder() + + // Add primary key filter + if req.HourStartDateTime != nil { + switch filter := req.HourStartDateTime.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("hour_start_date_time", "=", DateTimeValue{filter.Eq}) + case *UInt32Filter_Ne: + qb.AddCondition("hour_start_date_time", "!=", DateTimeValue{filter.Ne}) + case *UInt32Filter_Lt: + qb.AddCondition("hour_start_date_time", "<", DateTimeValue{filter.Lt}) + case *UInt32Filter_Lte: + qb.AddCondition("hour_start_date_time", "<=", DateTimeValue{filter.Lte}) + case *UInt32Filter_Gt: + qb.AddCondition("hour_start_date_time", ">", DateTimeValue{filter.Gt}) + case *UInt32Filter_Gte: + qb.AddCondition("hour_start_date_time", ">=", DateTimeValue{filter.Gte}) + case *UInt32Filter_Between: + qb.AddBetweenCondition("hour_start_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("hour_start_date_time", converted) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("hour_start_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: updated_date_time + if req.UpdatedDateTime != nil { + switch filter := req.UpdatedDateTime.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("updated_date_time", "=", DateTimeValue{filter.Eq}) + case *UInt32Filter_Ne: + qb.AddCondition("updated_date_time", "!=", DateTimeValue{filter.Ne}) + case *UInt32Filter_Lt: + qb.AddCondition("updated_date_time", "<", DateTimeValue{filter.Lt}) + case *UInt32Filter_Lte: + qb.AddCondition("updated_date_time", "<=", DateTimeValue{filter.Lte}) + case *UInt32Filter_Gt: + qb.AddCondition("updated_date_time", ">", DateTimeValue{filter.Gt}) + case *UInt32Filter_Gte: + qb.AddCondition("updated_date_time", ">=", DateTimeValue{filter.Gte}) + case *UInt32Filter_Between: + qb.AddBetweenCondition("updated_date_time", DateTimeValue{filter.Between.Min}, DateTimeValue{filter.Between.Max.GetValue()}) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTimeValue{v} + } + qb.AddInCondition("updated_date_time", converted) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTimeValue{v} + } + qb.AddNotInCondition("updated_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: hash + if req.Hash != nil { + switch filter := req.Hash.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("hash", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("hash", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("hash", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("hash", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("hash", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("hash", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("hash", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("hash", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("hash", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: first_seen_date_time + if req.FirstSeenDateTime != nil { + switch filter := req.FirstSeenDateTime.Filter.(type) { + case *Int64Filter_Eq: + qb.AddCondition("first_seen_date_time", "=", DateTime64Value{uint64(filter.Eq)}) + case *Int64Filter_Ne: + qb.AddCondition("first_seen_date_time", "!=", DateTime64Value{uint64(filter.Ne)}) + case *Int64Filter_Lt: + qb.AddCondition("first_seen_date_time", "<", DateTime64Value{uint64(filter.Lt)}) + case *Int64Filter_Lte: + qb.AddCondition("first_seen_date_time", "<=", DateTime64Value{uint64(filter.Lte)}) + case *Int64Filter_Gt: + qb.AddCondition("first_seen_date_time", ">", DateTime64Value{uint64(filter.Gt)}) + case *Int64Filter_Gte: + qb.AddCondition("first_seen_date_time", ">=", DateTime64Value{uint64(filter.Gte)}) + case *Int64Filter_Between: + qb.AddBetweenCondition("first_seen_date_time", DateTime64Value{uint64(filter.Between.Min)}, DateTime64Value{uint64(filter.Between.Max.GetValue())}) + case *Int64Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddInCondition("first_seen_date_time", converted) + } + case *Int64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddNotInCondition("first_seen_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: last_seen_date_time + if req.LastSeenDateTime != nil { + switch filter := req.LastSeenDateTime.Filter.(type) { + case *Int64Filter_Eq: + qb.AddCondition("last_seen_date_time", "=", DateTime64Value{uint64(filter.Eq)}) + case *Int64Filter_Ne: + qb.AddCondition("last_seen_date_time", "!=", DateTime64Value{uint64(filter.Ne)}) + case *Int64Filter_Lt: + qb.AddCondition("last_seen_date_time", "<", DateTime64Value{uint64(filter.Lt)}) + case *Int64Filter_Lte: + qb.AddCondition("last_seen_date_time", "<=", DateTime64Value{uint64(filter.Lte)}) + case *Int64Filter_Gt: + qb.AddCondition("last_seen_date_time", ">", DateTime64Value{uint64(filter.Gt)}) + case *Int64Filter_Gte: + qb.AddCondition("last_seen_date_time", ">=", DateTime64Value{uint64(filter.Gte)}) + case *Int64Filter_Between: + qb.AddBetweenCondition("last_seen_date_time", DateTime64Value{uint64(filter.Between.Min)}, DateTime64Value{uint64(filter.Between.Max.GetValue())}) + case *Int64Filter_In: + if len(filter.In.Values) > 0 { + converted := make([]interface{}, len(filter.In.Values)) + for i, v := range filter.In.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddInCondition("last_seen_date_time", converted) + } + case *Int64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + converted := make([]interface{}, len(filter.NotIn.Values)) + for i, v := range filter.NotIn.Values { + converted[i] = DateTime64Value{uint64(v)} + } + qb.AddNotInCondition("last_seen_date_time", converted) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: sighting_count + if req.SightingCount != nil { + switch filter := req.SightingCount.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("sighting_count", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("sighting_count", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("sighting_count", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("sighting_count", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("sighting_count", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("sighting_count", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("sighting_count", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("sighting_count", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("sighting_count", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: unique_sentries + if req.UniqueSentries != nil { + switch filter := req.UniqueSentries.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("unique_sentries", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("unique_sentries", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("unique_sentries", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("unique_sentries", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("unique_sentries", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("unique_sentries", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("unique_sentries", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("unique_sentries", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("unique_sentries", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: from + if req.From != nil { + switch filter := req.From.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("from", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("from", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("from", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("from", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("from", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("from", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("from", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("from", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("from", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: to + if req.To != nil { + switch filter := req.To.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("to", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("to", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("to", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("to", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("to", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("to", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("to", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("to", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("to", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("to") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("to") + default: + // Unsupported filter type + } + } + + // Add filter for column: nonce + if req.Nonce != nil { + switch filter := req.Nonce.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("nonce", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("nonce", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("nonce", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("nonce", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("nonce", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("nonce", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("nonce", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("nonce", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("nonce", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: type + if req.Type != nil { + switch filter := req.Type.Filter.(type) { + case *NullableUInt32Filter_Eq: + qb.AddCondition("type", "=", filter.Eq) + case *NullableUInt32Filter_Ne: + qb.AddCondition("type", "!=", filter.Ne) + case *NullableUInt32Filter_Lt: + qb.AddCondition("type", "<", filter.Lt) + case *NullableUInt32Filter_Lte: + qb.AddCondition("type", "<=", filter.Lte) + case *NullableUInt32Filter_Gt: + qb.AddCondition("type", ">", filter.Gt) + case *NullableUInt32Filter_Gte: + qb.AddCondition("type", ">=", filter.Gte) + case *NullableUInt32Filter_Between: + qb.AddBetweenCondition("type", filter.Between.Min, filter.Between.Max.GetValue()) + case *NullableUInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("type", UInt32SliceToInterface(filter.In.Values)) + } + case *NullableUInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("type", UInt32SliceToInterface(filter.NotIn.Values)) + } + case *NullableUInt32Filter_IsNull: + qb.AddIsNullCondition("type") + case *NullableUInt32Filter_IsNotNull: + qb.AddIsNotNullCondition("type") + default: + // Unsupported filter type + } + } + + // Add filter for column: gas + if req.Gas != nil { + switch filter := req.Gas.Filter.(type) { + case *UInt64Filter_Eq: + qb.AddCondition("gas", "=", filter.Eq) + case *UInt64Filter_Ne: + qb.AddCondition("gas", "!=", filter.Ne) + case *UInt64Filter_Lt: + qb.AddCondition("gas", "<", filter.Lt) + case *UInt64Filter_Lte: + qb.AddCondition("gas", "<=", filter.Lte) + case *UInt64Filter_Gt: + qb.AddCondition("gas", ">", filter.Gt) + case *UInt64Filter_Gte: + qb.AddCondition("gas", ">=", filter.Gte) + case *UInt64Filter_Between: + qb.AddBetweenCondition("gas", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas", UInt64SliceToInterface(filter.In.Values)) + } + case *UInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas", UInt64SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_price + if req.GasPrice != nil { + switch filter := req.GasPrice.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("gas_price", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("gas_price", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("gas_price", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("gas_price", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("gas_price", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("gas_price", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("gas_price", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_price", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_price", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_tip_cap + if req.GasTipCap != nil { + switch filter := req.GasTipCap.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("gas_tip_cap", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("gas_tip_cap", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("gas_tip_cap", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("gas_tip_cap", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("gas_tip_cap", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("gas_tip_cap", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("gas_tip_cap", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_tip_cap", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_tip_cap", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("gas_tip_cap") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("gas_tip_cap") + default: + // Unsupported filter type + } + } + + // Add filter for column: gas_fee_cap + if req.GasFeeCap != nil { + switch filter := req.GasFeeCap.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("gas_fee_cap", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("gas_fee_cap", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("gas_fee_cap", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("gas_fee_cap", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("gas_fee_cap", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("gas_fee_cap", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("gas_fee_cap", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("gas_fee_cap", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("gas_fee_cap", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("gas_fee_cap") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("gas_fee_cap") + default: + // Unsupported filter type + } + } + + // Add filter for column: value + if req.Value != nil { + switch filter := req.Value.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("value", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("value", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("value", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("value", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("value", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("value", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("value", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("value", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("value", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: size + if req.Size != nil { + switch filter := req.Size.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("size", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("size", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("size", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("size", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("size", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("size", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("size", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("size", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("size", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: call_data_size + if req.CallDataSize != nil { + switch filter := req.CallDataSize.Filter.(type) { + case *UInt32Filter_Eq: + qb.AddCondition("call_data_size", "=", filter.Eq) + case *UInt32Filter_Ne: + qb.AddCondition("call_data_size", "!=", filter.Ne) + case *UInt32Filter_Lt: + qb.AddCondition("call_data_size", "<", filter.Lt) + case *UInt32Filter_Lte: + qb.AddCondition("call_data_size", "<=", filter.Lte) + case *UInt32Filter_Gt: + qb.AddCondition("call_data_size", ">", filter.Gt) + case *UInt32Filter_Gte: + qb.AddCondition("call_data_size", ">=", filter.Gte) + case *UInt32Filter_Between: + qb.AddBetweenCondition("call_data_size", filter.Between.Min, filter.Between.Max.GetValue()) + case *UInt32Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("call_data_size", UInt32SliceToInterface(filter.In.Values)) + } + case *UInt32Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("call_data_size", UInt32SliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_gas + if req.BlobGas != nil { + switch filter := req.BlobGas.Filter.(type) { + case *NullableUInt64Filter_Eq: + qb.AddCondition("blob_gas", "=", filter.Eq) + case *NullableUInt64Filter_Ne: + qb.AddCondition("blob_gas", "!=", filter.Ne) + case *NullableUInt64Filter_Lt: + qb.AddCondition("blob_gas", "<", filter.Lt) + case *NullableUInt64Filter_Lte: + qb.AddCondition("blob_gas", "<=", filter.Lte) + case *NullableUInt64Filter_Gt: + qb.AddCondition("blob_gas", ">", filter.Gt) + case *NullableUInt64Filter_Gte: + qb.AddCondition("blob_gas", ">=", filter.Gte) + case *NullableUInt64Filter_Between: + qb.AddBetweenCondition("blob_gas", filter.Between.Min, filter.Between.Max.GetValue()) + case *NullableUInt64Filter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("blob_gas", UInt64SliceToInterface(filter.In.Values)) + } + case *NullableUInt64Filter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("blob_gas", UInt64SliceToInterface(filter.NotIn.Values)) + } + case *NullableUInt64Filter_IsNull: + qb.AddIsNullCondition("blob_gas") + case *NullableUInt64Filter_IsNotNull: + qb.AddIsNotNullCondition("blob_gas") + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_gas_fee_cap + if req.BlobGasFeeCap != nil { + switch filter := req.BlobGasFeeCap.Filter.(type) { + case *NullableStringFilter_Eq: + qb.AddCondition("blob_gas_fee_cap", "=", filter.Eq) + case *NullableStringFilter_Ne: + qb.AddCondition("blob_gas_fee_cap", "!=", filter.Ne) + case *NullableStringFilter_Contains: + qb.AddLikeCondition("blob_gas_fee_cap", "%" + filter.Contains + "%") + case *NullableStringFilter_StartsWith: + qb.AddLikeCondition("blob_gas_fee_cap", filter.StartsWith + "%") + case *NullableStringFilter_EndsWith: + qb.AddLikeCondition("blob_gas_fee_cap", "%" + filter.EndsWith) + case *NullableStringFilter_Like: + qb.AddLikeCondition("blob_gas_fee_cap", filter.Like) + case *NullableStringFilter_NotLike: + qb.AddNotLikeCondition("blob_gas_fee_cap", filter.NotLike) + case *NullableStringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("blob_gas_fee_cap", StringSliceToInterface(filter.In.Values)) + } + case *NullableStringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("blob_gas_fee_cap", StringSliceToInterface(filter.NotIn.Values)) + } + case *NullableStringFilter_IsNull: + qb.AddIsNullCondition("blob_gas_fee_cap") + case *NullableStringFilter_IsNotNull: + qb.AddIsNotNullCondition("blob_gas_fee_cap") + default: + // Unsupported filter type + } + } + + // Add filter for column: blob_hashes + if req.BlobHashes != nil { + switch filter := req.BlobHashes.Filter.(type) { + case *ArrayStringFilter_Has: + qb.AddArrayHasCondition("blob_hashes", filter.Has) + case *ArrayStringFilter_HasAll: + if len(filter.HasAll.Values) > 0 { + qb.AddArrayHasAllCondition("blob_hashes", StringSliceToInterface(filter.HasAll.Values)) + } + case *ArrayStringFilter_HasAny: + if len(filter.HasAny.Values) > 0 { + qb.AddArrayHasAnyCondition("blob_hashes", StringSliceToInterface(filter.HasAny.Values)) + } + case *ArrayStringFilter_LengthEq: + qb.AddArrayLengthCondition("blob_hashes", "=", filter.LengthEq) + case *ArrayStringFilter_LengthGt: + qb.AddArrayLengthCondition("blob_hashes", ">", filter.LengthGt) + case *ArrayStringFilter_LengthGte: + qb.AddArrayLengthCondition("blob_hashes", ">=", filter.LengthGte) + case *ArrayStringFilter_LengthLt: + qb.AddArrayLengthCondition("blob_hashes", "<", filter.LengthLt) + case *ArrayStringFilter_LengthLte: + qb.AddArrayLengthCondition("blob_hashes", "<=", filter.LengthLte) + case *ArrayStringFilter_IsEmpty: + qb.AddArrayIsEmptyCondition("blob_hashes") + case *ArrayStringFilter_IsNotEmpty: + qb.AddArrayIsNotEmptyCondition("blob_hashes") + default: + // Unsupported filter type + } + } + + // Add filter for column: is_cancel_shape + if req.IsCancelShape != nil { + switch filter := req.IsCancelShape.Filter.(type) { + case *BoolFilter_Eq: + qb.AddCondition("is_cancel_shape", "=", filter.Eq) + case *BoolFilter_Ne: + qb.AddCondition("is_cancel_shape", "!=", filter.Ne) + default: + // Unsupported filter type + } + } + + // Add filter for column: first_sentry_name + if req.FirstSentryName != nil { + switch filter := req.FirstSentryName.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("first_sentry_name", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("first_sentry_name", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("first_sentry_name", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("first_sentry_name", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("first_sentry_name", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("first_sentry_name", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("first_sentry_name", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("first_sentry_name", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("first_sentry_name", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: first_sentry_geo_city + if req.FirstSentryGeoCity != nil { + switch filter := req.FirstSentryGeoCity.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("first_sentry_geo_city", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("first_sentry_geo_city", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("first_sentry_geo_city", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("first_sentry_geo_city", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("first_sentry_geo_city", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("first_sentry_geo_city", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("first_sentry_geo_city", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("first_sentry_geo_city", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("first_sentry_geo_city", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: first_sentry_geo_country + if req.FirstSentryGeoCountry != nil { + switch filter := req.FirstSentryGeoCountry.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("first_sentry_geo_country", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("first_sentry_geo_country", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("first_sentry_geo_country", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("first_sentry_geo_country", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("first_sentry_geo_country", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("first_sentry_geo_country", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("first_sentry_geo_country", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("first_sentry_geo_country", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("first_sentry_geo_country", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: first_sentry_geo_country_code + if req.FirstSentryGeoCountryCode != nil { + switch filter := req.FirstSentryGeoCountryCode.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("first_sentry_geo_country_code", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("first_sentry_geo_country_code", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("first_sentry_geo_country_code", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("first_sentry_geo_country_code", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("first_sentry_geo_country_code", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("first_sentry_geo_country_code", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("first_sentry_geo_country_code", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("first_sentry_geo_country_code", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("first_sentry_geo_country_code", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Add filter for column: first_sentry_geo_continent_code + if req.FirstSentryGeoContinentCode != nil { + switch filter := req.FirstSentryGeoContinentCode.Filter.(type) { + case *StringFilter_Eq: + qb.AddCondition("first_sentry_geo_continent_code", "=", filter.Eq) + case *StringFilter_Ne: + qb.AddCondition("first_sentry_geo_continent_code", "!=", filter.Ne) + case *StringFilter_Contains: + qb.AddLikeCondition("first_sentry_geo_continent_code", "%" + filter.Contains + "%") + case *StringFilter_StartsWith: + qb.AddLikeCondition("first_sentry_geo_continent_code", filter.StartsWith + "%") + case *StringFilter_EndsWith: + qb.AddLikeCondition("first_sentry_geo_continent_code", "%" + filter.EndsWith) + case *StringFilter_Like: + qb.AddLikeCondition("first_sentry_geo_continent_code", filter.Like) + case *StringFilter_NotLike: + qb.AddNotLikeCondition("first_sentry_geo_continent_code", filter.NotLike) + case *StringFilter_In: + if len(filter.In.Values) > 0 { + qb.AddInCondition("first_sentry_geo_continent_code", StringSliceToInterface(filter.In.Values)) + } + case *StringFilter_NotIn: + if len(filter.NotIn.Values) > 0 { + qb.AddNotInCondition("first_sentry_geo_continent_code", StringSliceToInterface(filter.NotIn.Values)) + } + default: + // Unsupported filter type + } + } + + // Handle pagination per AIP-132 + // Validate page size + if req.PageSize < 0 { + return SQLQuery{}, fmt.Errorf("page_size must be non-negative, got %d", req.PageSize) + } + if req.PageSize > 10000 { + return SQLQuery{}, fmt.Errorf("page_size must not exceed %d, got %d", 10000, req.PageSize) + } + + var limit, offset uint32 + limit = 100 // Default page size + if req.PageSize > 0 { + limit = uint32(req.PageSize) + } + if req.PageToken != "" { + decodedOffset, err := DecodePageToken(req.PageToken) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid page_token: %w", err) + } + offset = decodedOffset + } + + // Handle custom ordering if provided + var orderByClause string + if req.OrderBy != "" { + validFields := []string{"updated_date_time", "hour_start_date_time", "hash", "first_seen_date_time", "last_seen_date_time", "sighting_count", "unique_sentries", "from", "to", "nonce", "type", "gas", "gas_price", "gas_tip_cap", "gas_fee_cap", "value", "size", "call_data_size", "blob_gas", "blob_gas_fee_cap", "blob_hashes", "is_cancel_shape", "first_sentry_name", "first_sentry_geo_city", "first_sentry_geo_country", "first_sentry_geo_country_code", "first_sentry_geo_continent_code"} + orderFields, err := ParseOrderBy(req.OrderBy, validFields) + if err != nil { + return SQLQuery{}, fmt.Errorf("invalid order_by: %w", err) + } + orderByClause = BuildOrderByClause(orderFields) + } else { + // Default sorting by primary key + orderByClause = " ORDER BY hour_start_date_time" + ", hash" + } + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toUnixTimestamp(`hour_start_date_time`) AS `hour_start_date_time`", "NULLIF(`hash`, repeat('\x00', 66)) AS `hash`", "toUnixTimestamp64Micro(`first_seen_date_time`) AS `first_seen_date_time`", "toUnixTimestamp64Micro(`last_seen_date_time`) AS `last_seen_date_time`", "sighting_count", "unique_sentries", "NULLIF(`from`, repeat('\x00', 42)) AS `from`", "NULLIF(`to`, repeat('\x00', 42)) AS `to`", "nonce", "toUInt32(`type`) AS `type`", "gas", "toString(`gas_price`) AS `gas_price`", "toString(`gas_tip_cap`) AS `gas_tip_cap`", "toString(`gas_fee_cap`) AS `gas_fee_cap`", "toString(`value`) AS `value`", "size", "call_data_size", "blob_gas", "toString(`blob_gas_fee_cap`) AS `blob_gas_fee_cap`", "blob_hashes", "is_cancel_shape", "first_sentry_name", "first_sentry_geo_city", "first_sentry_geo_country", "first_sentry_geo_country_code", "first_sentry_geo_continent_code"} + + return BuildParameterizedQuery("int_transaction_mempool_observation_hourly", columns, qb, orderByClause, limit, offset, options...) +} + +// BuildGetIntTransactionMempoolObservationHourlyQuery constructs a parameterized SQL query from a GetIntTransactionMempoolObservationHourlyRequest +func BuildGetIntTransactionMempoolObservationHourlyQuery(req *GetIntTransactionMempoolObservationHourlyRequest, options ...QueryOption) (SQLQuery, error) { + // Validate primary key is provided + if req.HourStartDateTime == 0 { + return SQLQuery{}, fmt.Errorf("primary key field hour_start_date_time is required") + } + + // Build query with primary key condition + qb := NewQueryBuilder() + qb.AddCondition("hour_start_date_time", "=", req.HourStartDateTime) + + // Build ORDER BY clause + orderByClause := " ORDER BY hour_start_date_time, hash" + + // Build column list + columns := []string{"toUnixTimestamp(`updated_date_time`) AS `updated_date_time`", "toUnixTimestamp(`hour_start_date_time`) AS `hour_start_date_time`", "NULLIF(`hash`, repeat('\x00', 66)) AS `hash`", "toUnixTimestamp64Micro(`first_seen_date_time`) AS `first_seen_date_time`", "toUnixTimestamp64Micro(`last_seen_date_time`) AS `last_seen_date_time`", "sighting_count", "unique_sentries", "NULLIF(`from`, repeat('\x00', 42)) AS `from`", "NULLIF(`to`, repeat('\x00', 42)) AS `to`", "nonce", "toUInt32(`type`) AS `type`", "gas", "toString(`gas_price`) AS `gas_price`", "toString(`gas_tip_cap`) AS `gas_tip_cap`", "toString(`gas_fee_cap`) AS `gas_fee_cap`", "toString(`value`) AS `value`", "size", "call_data_size", "blob_gas", "toString(`blob_gas_fee_cap`) AS `blob_gas_fee_cap`", "blob_hashes", "is_cancel_shape", "first_sentry_name", "first_sentry_geo_city", "first_sentry_geo_country", "first_sentry_geo_country_code", "first_sentry_geo_continent_code"} + + // Return single record + return BuildParameterizedQuery("int_transaction_mempool_observation_hourly", columns, qb, orderByClause, 1, 0, options...) +} diff --git a/pkg/proto/clickhouse/int_transaction_mempool_observation_hourly.pb.go b/pkg/proto/clickhouse/int_transaction_mempool_observation_hourly.pb.go new file mode 100644 index 00000000..f0fad768 --- /dev/null +++ b/pkg/proto/clickhouse/int_transaction_mempool_observation_hourly.pb.go @@ -0,0 +1,1185 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc (unknown) +// source: int_transaction_mempool_observation_hourly.proto + +package clickhouse + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type IntTransactionMempoolObservationHourly struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Timestamp when the record was last updated + UpdatedDateTime uint32 `protobuf:"varint,11,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // The start of the hour bucket the sightings fall in + HourStartDateTime uint32 `protobuf:"varint,12,opt,name=hour_start_date_time,json=hourStartDateTime,proto3" json:"hour_start_date_time,omitempty"` + // The transaction hash + Hash string `protobuf:"bytes,13,opt,name=hash,proto3" json:"hash,omitempty"` + // Earliest sighting of the transaction by any sentry within this hour + FirstSeenDateTime int64 `protobuf:"varint,14,opt,name=first_seen_date_time,json=firstSeenDateTime,proto3" json:"first_seen_date_time,omitempty"` + // Latest sighting of the transaction by any sentry within this hour + LastSeenDateTime int64 `protobuf:"varint,15,opt,name=last_seen_date_time,json=lastSeenDateTime,proto3" json:"last_seen_date_time,omitempty"` + // Number of sightings of the transaction within this hour across all sentries + SightingCount uint32 `protobuf:"varint,16,opt,name=sighting_count,json=sightingCount,proto3" json:"sighting_count,omitempty"` + // Number of distinct sentries that sighted the transaction within this hour + UniqueSentries uint32 `protobuf:"varint,17,opt,name=unique_sentries,json=uniqueSentries,proto3" json:"unique_sentries,omitempty"` + // The address of the account that sent the transaction + From string `protobuf:"bytes,18,opt,name=from,proto3" json:"from,omitempty"` + // The address of the transaction recipient, null for contract creation + To *wrapperspb.StringValue `protobuf:"bytes,19,opt,name=to,proto3" json:"to,omitempty"` + // The nonce of the sender account at the time of the transaction + Nonce uint64 `protobuf:"varint,20,opt,name=nonce,proto3" json:"nonce,omitempty"` + // The type of the transaction + Type *wrapperspb.UInt32Value `protobuf:"bytes,21,opt,name=type,proto3" json:"type,omitempty"` + // The maximum gas provided for the transaction execution + Gas uint64 `protobuf:"varint,22,opt,name=gas,proto3" json:"gas,omitempty"` + // The gas price of the transaction in wei + GasPrice string `protobuf:"bytes,23,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` + // The priority fee (tip) the user has set for the transaction in wei + GasTipCap *wrapperspb.StringValue `protobuf:"bytes,24,opt,name=gas_tip_cap,json=gasTipCap,proto3" json:"gas_tip_cap,omitempty"` + // The max fee the user has set for the transaction in wei + GasFeeCap *wrapperspb.StringValue `protobuf:"bytes,25,opt,name=gas_fee_cap,json=gasFeeCap,proto3" json:"gas_fee_cap,omitempty"` + // The value transferred with the transaction in wei + Value string `protobuf:"bytes,26,opt,name=value,proto3" json:"value,omitempty"` + // The size of the transaction data in bytes + Size uint32 `protobuf:"varint,27,opt,name=size,proto3" json:"size,omitempty"` + // The size of the call data of the transaction in bytes + CallDataSize uint32 `protobuf:"varint,28,opt,name=call_data_size,json=callDataSize,proto3" json:"call_data_size,omitempty"` + // The maximum gas provided for the blob transaction execution + BlobGas *wrapperspb.UInt64Value `protobuf:"bytes,29,opt,name=blob_gas,json=blobGas,proto3" json:"blob_gas,omitempty"` + // The max blob fee the user has set for the transaction in wei + BlobGasFeeCap *wrapperspb.StringValue `protobuf:"bytes,30,opt,name=blob_gas_fee_cap,json=blobGasFeeCap,proto3" json:"blob_gas_fee_cap,omitempty"` + // The hashes of the blob commitments for blob transactions + BlobHashes []string `protobuf:"bytes,31,rep,name=blob_hashes,json=blobHashes,proto3" json:"blob_hashes,omitempty"` + // Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern + IsCancelShape bool `protobuf:"varint,32,opt,name=is_cancel_shape,json=isCancelShape,proto3" json:"is_cancel_shape,omitempty"` + // Name of the sentry with the earliest sighting this hour, ties broken by sentry name + FirstSentryName string `protobuf:"bytes,33,opt,name=first_sentry_name,json=firstSentryName,proto3" json:"first_sentry_name,omitempty"` + // City of the first-sighting sentry + FirstSentryGeoCity string `protobuf:"bytes,34,opt,name=first_sentry_geo_city,json=firstSentryGeoCity,proto3" json:"first_sentry_geo_city,omitempty"` + // Country of the first-sighting sentry + FirstSentryGeoCountry string `protobuf:"bytes,35,opt,name=first_sentry_geo_country,json=firstSentryGeoCountry,proto3" json:"first_sentry_geo_country,omitempty"` + // Country code of the first-sighting sentry + FirstSentryGeoCountryCode string `protobuf:"bytes,36,opt,name=first_sentry_geo_country_code,json=firstSentryGeoCountryCode,proto3" json:"first_sentry_geo_country_code,omitempty"` + // Continent code of the first-sighting sentry + FirstSentryGeoContinentCode string `protobuf:"bytes,37,opt,name=first_sentry_geo_continent_code,json=firstSentryGeoContinentCode,proto3" json:"first_sentry_geo_continent_code,omitempty"` +} + +func (x *IntTransactionMempoolObservationHourly) Reset() { + *x = IntTransactionMempoolObservationHourly{} + if protoimpl.UnsafeEnabled { + mi := &file_int_transaction_mempool_observation_hourly_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IntTransactionMempoolObservationHourly) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IntTransactionMempoolObservationHourly) ProtoMessage() {} + +func (x *IntTransactionMempoolObservationHourly) ProtoReflect() protoreflect.Message { + mi := &file_int_transaction_mempool_observation_hourly_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IntTransactionMempoolObservationHourly.ProtoReflect.Descriptor instead. +func (*IntTransactionMempoolObservationHourly) Descriptor() ([]byte, []int) { + return file_int_transaction_mempool_observation_hourly_proto_rawDescGZIP(), []int{0} +} + +func (x *IntTransactionMempoolObservationHourly) GetUpdatedDateTime() uint32 { + if x != nil { + return x.UpdatedDateTime + } + return 0 +} + +func (x *IntTransactionMempoolObservationHourly) GetHourStartDateTime() uint32 { + if x != nil { + return x.HourStartDateTime + } + return 0 +} + +func (x *IntTransactionMempoolObservationHourly) GetHash() string { + if x != nil { + return x.Hash + } + return "" +} + +func (x *IntTransactionMempoolObservationHourly) GetFirstSeenDateTime() int64 { + if x != nil { + return x.FirstSeenDateTime + } + return 0 +} + +func (x *IntTransactionMempoolObservationHourly) GetLastSeenDateTime() int64 { + if x != nil { + return x.LastSeenDateTime + } + return 0 +} + +func (x *IntTransactionMempoolObservationHourly) GetSightingCount() uint32 { + if x != nil { + return x.SightingCount + } + return 0 +} + +func (x *IntTransactionMempoolObservationHourly) GetUniqueSentries() uint32 { + if x != nil { + return x.UniqueSentries + } + return 0 +} + +func (x *IntTransactionMempoolObservationHourly) GetFrom() string { + if x != nil { + return x.From + } + return "" +} + +func (x *IntTransactionMempoolObservationHourly) GetTo() *wrapperspb.StringValue { + if x != nil { + return x.To + } + return nil +} + +func (x *IntTransactionMempoolObservationHourly) GetNonce() uint64 { + if x != nil { + return x.Nonce + } + return 0 +} + +func (x *IntTransactionMempoolObservationHourly) GetType() *wrapperspb.UInt32Value { + if x != nil { + return x.Type + } + return nil +} + +func (x *IntTransactionMempoolObservationHourly) GetGas() uint64 { + if x != nil { + return x.Gas + } + return 0 +} + +func (x *IntTransactionMempoolObservationHourly) GetGasPrice() string { + if x != nil { + return x.GasPrice + } + return "" +} + +func (x *IntTransactionMempoolObservationHourly) GetGasTipCap() *wrapperspb.StringValue { + if x != nil { + return x.GasTipCap + } + return nil +} + +func (x *IntTransactionMempoolObservationHourly) GetGasFeeCap() *wrapperspb.StringValue { + if x != nil { + return x.GasFeeCap + } + return nil +} + +func (x *IntTransactionMempoolObservationHourly) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *IntTransactionMempoolObservationHourly) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *IntTransactionMempoolObservationHourly) GetCallDataSize() uint32 { + if x != nil { + return x.CallDataSize + } + return 0 +} + +func (x *IntTransactionMempoolObservationHourly) GetBlobGas() *wrapperspb.UInt64Value { + if x != nil { + return x.BlobGas + } + return nil +} + +func (x *IntTransactionMempoolObservationHourly) GetBlobGasFeeCap() *wrapperspb.StringValue { + if x != nil { + return x.BlobGasFeeCap + } + return nil +} + +func (x *IntTransactionMempoolObservationHourly) GetBlobHashes() []string { + if x != nil { + return x.BlobHashes + } + return nil +} + +func (x *IntTransactionMempoolObservationHourly) GetIsCancelShape() bool { + if x != nil { + return x.IsCancelShape + } + return false +} + +func (x *IntTransactionMempoolObservationHourly) GetFirstSentryName() string { + if x != nil { + return x.FirstSentryName + } + return "" +} + +func (x *IntTransactionMempoolObservationHourly) GetFirstSentryGeoCity() string { + if x != nil { + return x.FirstSentryGeoCity + } + return "" +} + +func (x *IntTransactionMempoolObservationHourly) GetFirstSentryGeoCountry() string { + if x != nil { + return x.FirstSentryGeoCountry + } + return "" +} + +func (x *IntTransactionMempoolObservationHourly) GetFirstSentryGeoCountryCode() string { + if x != nil { + return x.FirstSentryGeoCountryCode + } + return "" +} + +func (x *IntTransactionMempoolObservationHourly) GetFirstSentryGeoContinentCode() string { + if x != nil { + return x.FirstSentryGeoContinentCode + } + return "" +} + +// Request for listing int_transaction_mempool_observation_hourly records +type ListIntTransactionMempoolObservationHourlyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Filter by hour_start_date_time - The start of the hour bucket the sightings fall in (PRIMARY KEY - required unless using alternatives: hash, from) + HourStartDateTime *UInt32Filter `protobuf:"bytes,1,opt,name=hour_start_date_time,json=hourStartDateTime,proto3" json:"hour_start_date_time,omitempty"` + // Filter by hash - The transaction hash (ORDER BY column 2 - optional) + Hash *StringFilter `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UpdatedDateTime *UInt32Filter `protobuf:"bytes,3,opt,name=updated_date_time,json=updatedDateTime,proto3" json:"updated_date_time,omitempty"` + // Filter by first_seen_date_time - Earliest sighting of the transaction by any sentry within this hour (optional) + FirstSeenDateTime *Int64Filter `protobuf:"bytes,4,opt,name=first_seen_date_time,json=firstSeenDateTime,proto3" json:"first_seen_date_time,omitempty"` + // Filter by last_seen_date_time - Latest sighting of the transaction by any sentry within this hour (optional) + LastSeenDateTime *Int64Filter `protobuf:"bytes,5,opt,name=last_seen_date_time,json=lastSeenDateTime,proto3" json:"last_seen_date_time,omitempty"` + // Filter by sighting_count - Number of sightings of the transaction within this hour across all sentries (optional) + SightingCount *UInt32Filter `protobuf:"bytes,6,opt,name=sighting_count,json=sightingCount,proto3" json:"sighting_count,omitempty"` + // Filter by unique_sentries - Number of distinct sentries that sighted the transaction within this hour (optional) + UniqueSentries *UInt32Filter `protobuf:"bytes,7,opt,name=unique_sentries,json=uniqueSentries,proto3" json:"unique_sentries,omitempty"` + // Filter by from - The address of the account that sent the transaction (PROJECTION: p_by_nonce_group - alternative to hour_start_date_time) + From *StringFilter `protobuf:"bytes,8,opt,name=from,proto3" json:"from,omitempty"` + // Filter by to - The address of the transaction recipient, null for contract creation (optional) + To *NullableStringFilter `protobuf:"bytes,9,opt,name=to,proto3" json:"to,omitempty"` + // Filter by nonce - The nonce of the sender account at the time of the transaction (optional) + Nonce *UInt64Filter `protobuf:"bytes,10,opt,name=nonce,proto3" json:"nonce,omitempty"` + // Filter by type - The type of the transaction (optional) + Type *NullableUInt32Filter `protobuf:"bytes,11,opt,name=type,proto3" json:"type,omitempty"` + // Filter by gas - The maximum gas provided for the transaction execution (optional) + Gas *UInt64Filter `protobuf:"bytes,12,opt,name=gas,proto3" json:"gas,omitempty"` + // Filter by gas_price - The gas price of the transaction in wei (optional) + GasPrice *StringFilter `protobuf:"bytes,13,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` + // Filter by gas_tip_cap - The priority fee (tip) the user has set for the transaction in wei (optional) + GasTipCap *NullableStringFilter `protobuf:"bytes,14,opt,name=gas_tip_cap,json=gasTipCap,proto3" json:"gas_tip_cap,omitempty"` + // Filter by gas_fee_cap - The max fee the user has set for the transaction in wei (optional) + GasFeeCap *NullableStringFilter `protobuf:"bytes,15,opt,name=gas_fee_cap,json=gasFeeCap,proto3" json:"gas_fee_cap,omitempty"` + // Filter by value - The value transferred with the transaction in wei (optional) + Value *StringFilter `protobuf:"bytes,16,opt,name=value,proto3" json:"value,omitempty"` + // Filter by size - The size of the transaction data in bytes (optional) + Size *UInt32Filter `protobuf:"bytes,17,opt,name=size,proto3" json:"size,omitempty"` + // Filter by call_data_size - The size of the call data of the transaction in bytes (optional) + CallDataSize *UInt32Filter `protobuf:"bytes,18,opt,name=call_data_size,json=callDataSize,proto3" json:"call_data_size,omitempty"` + // Filter by blob_gas - The maximum gas provided for the blob transaction execution (optional) + BlobGas *NullableUInt64Filter `protobuf:"bytes,19,opt,name=blob_gas,json=blobGas,proto3" json:"blob_gas,omitempty"` + // Filter by blob_gas_fee_cap - The max blob fee the user has set for the transaction in wei (optional) + BlobGasFeeCap *NullableStringFilter `protobuf:"bytes,20,opt,name=blob_gas_fee_cap,json=blobGasFeeCap,proto3" json:"blob_gas_fee_cap,omitempty"` + // Filter by blob_hashes - The hashes of the blob commitments for blob transactions (optional) + BlobHashes *ArrayStringFilter `protobuf:"bytes,21,opt,name=blob_hashes,json=blobHashes,proto3" json:"blob_hashes,omitempty"` + // Filter by is_cancel_shape - Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern (optional) + IsCancelShape *BoolFilter `protobuf:"bytes,22,opt,name=is_cancel_shape,json=isCancelShape,proto3" json:"is_cancel_shape,omitempty"` + // Filter by first_sentry_name - Name of the sentry with the earliest sighting this hour, ties broken by sentry name (optional) + FirstSentryName *StringFilter `protobuf:"bytes,23,opt,name=first_sentry_name,json=firstSentryName,proto3" json:"first_sentry_name,omitempty"` + // Filter by first_sentry_geo_city - City of the first-sighting sentry (optional) + FirstSentryGeoCity *StringFilter `protobuf:"bytes,24,opt,name=first_sentry_geo_city,json=firstSentryGeoCity,proto3" json:"first_sentry_geo_city,omitempty"` + // Filter by first_sentry_geo_country - Country of the first-sighting sentry (optional) + FirstSentryGeoCountry *StringFilter `protobuf:"bytes,25,opt,name=first_sentry_geo_country,json=firstSentryGeoCountry,proto3" json:"first_sentry_geo_country,omitempty"` + // Filter by first_sentry_geo_country_code - Country code of the first-sighting sentry (optional) + FirstSentryGeoCountryCode *StringFilter `protobuf:"bytes,26,opt,name=first_sentry_geo_country_code,json=firstSentryGeoCountryCode,proto3" json:"first_sentry_geo_country_code,omitempty"` + // Filter by first_sentry_geo_continent_code - Continent code of the first-sighting sentry (optional) + FirstSentryGeoContinentCode *StringFilter `protobuf:"bytes,27,opt,name=first_sentry_geo_continent_code,json=firstSentryGeoContinentCode,proto3" json:"first_sentry_geo_continent_code,omitempty"` + // The maximum number of int_transaction_mempool_observation_hourly to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + PageSize int32 `protobuf:"varint,28,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // A page token, received from a previous `ListIntTransactionMempoolObservationHourly` call. + // Provide this to retrieve the subsequent page. + PageToken string `protobuf:"bytes,29,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + OrderBy string `protobuf:"bytes,30,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"` +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) Reset() { + *x = ListIntTransactionMempoolObservationHourlyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_int_transaction_mempool_observation_hourly_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListIntTransactionMempoolObservationHourlyRequest) ProtoMessage() {} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) ProtoReflect() protoreflect.Message { + mi := &file_int_transaction_mempool_observation_hourly_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListIntTransactionMempoolObservationHourlyRequest.ProtoReflect.Descriptor instead. +func (*ListIntTransactionMempoolObservationHourlyRequest) Descriptor() ([]byte, []int) { + return file_int_transaction_mempool_observation_hourly_proto_rawDescGZIP(), []int{1} +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetHourStartDateTime() *UInt32Filter { + if x != nil { + return x.HourStartDateTime + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetHash() *StringFilter { + if x != nil { + return x.Hash + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetUpdatedDateTime() *UInt32Filter { + if x != nil { + return x.UpdatedDateTime + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetFirstSeenDateTime() *Int64Filter { + if x != nil { + return x.FirstSeenDateTime + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetLastSeenDateTime() *Int64Filter { + if x != nil { + return x.LastSeenDateTime + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetSightingCount() *UInt32Filter { + if x != nil { + return x.SightingCount + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetUniqueSentries() *UInt32Filter { + if x != nil { + return x.UniqueSentries + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetFrom() *StringFilter { + if x != nil { + return x.From + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetTo() *NullableStringFilter { + if x != nil { + return x.To + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetNonce() *UInt64Filter { + if x != nil { + return x.Nonce + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetType() *NullableUInt32Filter { + if x != nil { + return x.Type + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetGas() *UInt64Filter { + if x != nil { + return x.Gas + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetGasPrice() *StringFilter { + if x != nil { + return x.GasPrice + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetGasTipCap() *NullableStringFilter { + if x != nil { + return x.GasTipCap + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetGasFeeCap() *NullableStringFilter { + if x != nil { + return x.GasFeeCap + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetValue() *StringFilter { + if x != nil { + return x.Value + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetSize() *UInt32Filter { + if x != nil { + return x.Size + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetCallDataSize() *UInt32Filter { + if x != nil { + return x.CallDataSize + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetBlobGas() *NullableUInt64Filter { + if x != nil { + return x.BlobGas + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetBlobGasFeeCap() *NullableStringFilter { + if x != nil { + return x.BlobGasFeeCap + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetBlobHashes() *ArrayStringFilter { + if x != nil { + return x.BlobHashes + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetIsCancelShape() *BoolFilter { + if x != nil { + return x.IsCancelShape + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetFirstSentryName() *StringFilter { + if x != nil { + return x.FirstSentryName + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetFirstSentryGeoCity() *StringFilter { + if x != nil { + return x.FirstSentryGeoCity + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetFirstSentryGeoCountry() *StringFilter { + if x != nil { + return x.FirstSentryGeoCountry + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetFirstSentryGeoCountryCode() *StringFilter { + if x != nil { + return x.FirstSentryGeoCountryCode + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetFirstSentryGeoContinentCode() *StringFilter { + if x != nil { + return x.FirstSentryGeoContinentCode + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +func (x *ListIntTransactionMempoolObservationHourlyRequest) GetOrderBy() string { + if x != nil { + return x.OrderBy + } + return "" +} + +// Response for listing int_transaction_mempool_observation_hourly records +type ListIntTransactionMempoolObservationHourlyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of int_transaction_mempool_observation_hourly. + IntTransactionMempoolObservationHourly []*IntTransactionMempoolObservationHourly `protobuf:"bytes,1,rep,name=int_transaction_mempool_observation_hourly,json=intTransactionMempoolObservationHourly,proto3" json:"int_transaction_mempool_observation_hourly,omitempty"` + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` +} + +func (x *ListIntTransactionMempoolObservationHourlyResponse) Reset() { + *x = ListIntTransactionMempoolObservationHourlyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_int_transaction_mempool_observation_hourly_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListIntTransactionMempoolObservationHourlyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListIntTransactionMempoolObservationHourlyResponse) ProtoMessage() {} + +func (x *ListIntTransactionMempoolObservationHourlyResponse) ProtoReflect() protoreflect.Message { + mi := &file_int_transaction_mempool_observation_hourly_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListIntTransactionMempoolObservationHourlyResponse.ProtoReflect.Descriptor instead. +func (*ListIntTransactionMempoolObservationHourlyResponse) Descriptor() ([]byte, []int) { + return file_int_transaction_mempool_observation_hourly_proto_rawDescGZIP(), []int{2} +} + +func (x *ListIntTransactionMempoolObservationHourlyResponse) GetIntTransactionMempoolObservationHourly() []*IntTransactionMempoolObservationHourly { + if x != nil { + return x.IntTransactionMempoolObservationHourly + } + return nil +} + +func (x *ListIntTransactionMempoolObservationHourlyResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +// Request for getting a single int_transaction_mempool_observation_hourly record by primary key +type GetIntTransactionMempoolObservationHourlyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The start of the hour bucket the sightings fall in + HourStartDateTime uint32 `protobuf:"varint,1,opt,name=hour_start_date_time,json=hourStartDateTime,proto3" json:"hour_start_date_time,omitempty"` // Primary key (required) +} + +func (x *GetIntTransactionMempoolObservationHourlyRequest) Reset() { + *x = GetIntTransactionMempoolObservationHourlyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_int_transaction_mempool_observation_hourly_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetIntTransactionMempoolObservationHourlyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetIntTransactionMempoolObservationHourlyRequest) ProtoMessage() {} + +func (x *GetIntTransactionMempoolObservationHourlyRequest) ProtoReflect() protoreflect.Message { + mi := &file_int_transaction_mempool_observation_hourly_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetIntTransactionMempoolObservationHourlyRequest.ProtoReflect.Descriptor instead. +func (*GetIntTransactionMempoolObservationHourlyRequest) Descriptor() ([]byte, []int) { + return file_int_transaction_mempool_observation_hourly_proto_rawDescGZIP(), []int{3} +} + +func (x *GetIntTransactionMempoolObservationHourlyRequest) GetHourStartDateTime() uint32 { + if x != nil { + return x.HourStartDateTime + } + return 0 +} + +// Response for getting a single int_transaction_mempool_observation_hourly record +type GetIntTransactionMempoolObservationHourlyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Item *IntTransactionMempoolObservationHourly `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` +} + +func (x *GetIntTransactionMempoolObservationHourlyResponse) Reset() { + *x = GetIntTransactionMempoolObservationHourlyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_int_transaction_mempool_observation_hourly_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetIntTransactionMempoolObservationHourlyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetIntTransactionMempoolObservationHourlyResponse) ProtoMessage() {} + +func (x *GetIntTransactionMempoolObservationHourlyResponse) ProtoReflect() protoreflect.Message { + mi := &file_int_transaction_mempool_observation_hourly_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetIntTransactionMempoolObservationHourlyResponse.ProtoReflect.Descriptor instead. +func (*GetIntTransactionMempoolObservationHourlyResponse) Descriptor() ([]byte, []int) { + return file_int_transaction_mempool_observation_hourly_proto_rawDescGZIP(), []int{4} +} + +func (x *GetIntTransactionMempoolObservationHourlyResponse) GetItem() *IntTransactionMempoolObservationHourly { + if x != nil { + return x.Item + } + return nil +} + +var File_int_transaction_mempool_observation_hourly_proto protoreflect.FileDescriptor + +var file_int_transaction_mempool_observation_hourly_proto_rawDesc = []byte{ + 0x0a, 0x30, 0x69, 0x6e, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x03, 0x63, 0x62, 0x74, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb7, 0x09, 0x0a, 0x26, 0x49, 0x6e, 0x74, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, + 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, + 0x12, 0x2a, 0x0a, 0x11, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x14, + 0x68, 0x6f, 0x75, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x68, 0x6f, 0x75, 0x72, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, + 0x68, 0x12, 0x2f, 0x0a, 0x14, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, + 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x11, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, + 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x10, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x68, 0x74, + 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x75, 0x6e, 0x69, 0x71, + 0x75, 0x65, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0e, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x53, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, + 0x73, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x2c, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x13, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x02, 0x74, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x14, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x67, + 0x61, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x1b, 0x0a, + 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x67, 0x61, + 0x73, 0x5f, 0x74, 0x69, 0x70, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x67, + 0x61, 0x73, 0x54, 0x69, 0x70, 0x43, 0x61, 0x70, 0x12, 0x3c, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, + 0x66, 0x65, 0x65, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x67, 0x61, 0x73, + 0x46, 0x65, 0x65, 0x43, 0x61, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x1a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, + 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x69, + 0x7a, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x63, 0x61, 0x6c, 0x6c, 0x44, 0x61, + 0x74, 0x61, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x37, 0x0a, 0x08, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, + 0x61, 0x73, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, + 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x12, + 0x45, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, 0x5f, + 0x63, 0x61, 0x70, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, + 0x46, 0x65, 0x65, 0x43, 0x61, 0x70, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x1f, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x6c, 0x6f, + 0x62, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x73, 0x5f, 0x63, 0x61, + 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x18, 0x20, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0d, 0x69, 0x73, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x68, 0x61, 0x70, 0x65, 0x12, + 0x2a, 0x0a, 0x11, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x21, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x53, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x15, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x67, 0x65, 0x6f, 0x5f, + 0x63, 0x69, 0x74, 0x79, 0x18, 0x22, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x53, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x47, 0x65, 0x6f, 0x43, 0x69, 0x74, 0x79, 0x12, 0x37, + 0x0a, 0x18, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x67, + 0x65, 0x6f, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x23, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x15, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x47, 0x65, 0x6f, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x40, 0x0a, 0x1d, 0x66, 0x69, 0x72, 0x73, 0x74, + 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x67, 0x65, 0x6f, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x24, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x47, 0x65, 0x6f, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x44, 0x0a, 0x1f, 0x66, 0x69, 0x72, + 0x73, 0x74, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x67, 0x65, 0x6f, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x25, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x1b, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x47, + 0x65, 0x6f, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x22, + 0x97, 0x0d, 0x0a, 0x31, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x62, 0x73, + 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x14, 0x68, 0x6f, 0x75, 0x72, 0x5f, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x11, 0x68, 0x6f, 0x75, 0x72, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x68, 0x61, 0x73, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, + 0x12, 0x3d, 0x0a, 0x11, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0f, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x41, 0x0a, 0x14, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x64, 0x61, + 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, + 0x11, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, + 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x52, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0d, + 0x73, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3a, 0x0a, + 0x0f, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, + 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0e, 0x75, 0x6e, 0x69, 0x71, 0x75, + 0x65, 0x53, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x04, 0x66, 0x72, 0x6f, + 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, + 0x12, 0x29, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, + 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x27, 0x0a, 0x05, 0x6e, + 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x05, 0x6e, + 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, + 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x08, + 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, + 0x74, 0x69, 0x70, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x09, 0x67, 0x61, 0x73, 0x54, 0x69, 0x70, + 0x43, 0x61, 0x70, 0x12, 0x39, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x63, + 0x61, 0x70, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, + 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x52, 0x09, 0x67, 0x61, 0x73, 0x46, 0x65, 0x65, 0x43, 0x61, 0x70, 0x12, 0x27, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x37, + 0x0a, 0x0e, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x55, 0x49, 0x6e, + 0x74, 0x33, 0x32, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x61, 0x6c, 0x6c, 0x44, + 0x61, 0x74, 0x61, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x34, 0x0a, 0x08, 0x62, 0x6c, 0x6f, 0x62, 0x5f, + 0x67, 0x61, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, + 0x4e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x12, 0x42, 0x0a, + 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x63, 0x61, + 0x70, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4e, 0x75, + 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x46, 0x65, 0x65, 0x43, 0x61, + 0x70, 0x12, 0x37, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, + 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x41, 0x72, 0x72, + 0x61, 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0a, + 0x62, 0x6c, 0x6f, 0x62, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0f, 0x69, 0x73, + 0x5f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x18, 0x16, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0d, 0x69, 0x73, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x53, 0x68, + 0x61, 0x70, 0x65, 0x12, 0x3d, 0x0a, 0x11, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x52, 0x0f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x44, 0x0a, 0x15, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x6e, 0x74, + 0x72, 0x79, 0x5f, 0x67, 0x65, 0x6f, 0x5f, 0x63, 0x69, 0x74, 0x79, 0x18, 0x18, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x52, 0x12, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x47, 0x65, 0x6f, 0x43, 0x69, 0x74, 0x79, 0x12, 0x4a, 0x0a, 0x18, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x67, 0x65, 0x6f, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x72, 0x79, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x15, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x47, 0x65, 0x6f, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x53, 0x0a, 0x1d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x67, 0x65, 0x6f, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, + 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, + 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x19, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x47, 0x65, 0x6f, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x57, 0x0a, 0x1f, 0x66, 0x69, 0x72, + 0x73, 0x74, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x67, 0x65, 0x6f, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x1b, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x1b, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x6e, 0x74, + 0x72, 0x79, 0x47, 0x65, 0x6f, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, + 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x1c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, + 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x1d, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x19, + 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, 0xe6, 0x01, 0x0a, 0x32, 0x4c, 0x69, + 0x73, 0x74, 0x49, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x87, 0x01, 0x0a, 0x2a, 0x69, 0x6e, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6f, 0x62, 0x73, + 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, + 0x6c, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, + 0x6c, 0x79, 0x52, 0x26, 0x69, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, + 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x22, 0x63, 0x0a, 0x30, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x62, + 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x14, 0x68, 0x6f, 0x75, 0x72, 0x5f, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x68, 0x6f, 0x75, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, + 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x74, 0x0a, 0x31, 0x47, 0x65, 0x74, 0x49, 0x6e, + 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, + 0x6f, 0x6f, 0x6c, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, + 0x75, 0x72, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x04, + 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x62, 0x74, + 0x2e, 0x49, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0x9e, 0x02, + 0x0a, 0x2d, 0x49, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x77, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x36, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x49, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x37, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x74, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, + 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, + 0x35, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x62, + 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x63, 0x62, 0x74, 0x2e, 0x47, 0x65, 0x74, + 0x49, 0x6e, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, + 0x6d, 0x70, 0x6f, 0x6f, 0x6c, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x36, + 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, + 0x70, 0x61, 0x6e, 0x64, 0x61, 0x6f, 0x70, 0x73, 0x2f, 0x78, 0x61, 0x74, 0x75, 0x2d, 0x63, 0x62, + 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x63, + 0x6b, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_int_transaction_mempool_observation_hourly_proto_rawDescOnce sync.Once + file_int_transaction_mempool_observation_hourly_proto_rawDescData = file_int_transaction_mempool_observation_hourly_proto_rawDesc +) + +func file_int_transaction_mempool_observation_hourly_proto_rawDescGZIP() []byte { + file_int_transaction_mempool_observation_hourly_proto_rawDescOnce.Do(func() { + file_int_transaction_mempool_observation_hourly_proto_rawDescData = protoimpl.X.CompressGZIP(file_int_transaction_mempool_observation_hourly_proto_rawDescData) + }) + return file_int_transaction_mempool_observation_hourly_proto_rawDescData +} + +var file_int_transaction_mempool_observation_hourly_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_int_transaction_mempool_observation_hourly_proto_goTypes = []any{ + (*IntTransactionMempoolObservationHourly)(nil), // 0: cbt.IntTransactionMempoolObservationHourly + (*ListIntTransactionMempoolObservationHourlyRequest)(nil), // 1: cbt.ListIntTransactionMempoolObservationHourlyRequest + (*ListIntTransactionMempoolObservationHourlyResponse)(nil), // 2: cbt.ListIntTransactionMempoolObservationHourlyResponse + (*GetIntTransactionMempoolObservationHourlyRequest)(nil), // 3: cbt.GetIntTransactionMempoolObservationHourlyRequest + (*GetIntTransactionMempoolObservationHourlyResponse)(nil), // 4: cbt.GetIntTransactionMempoolObservationHourlyResponse + (*wrapperspb.StringValue)(nil), // 5: google.protobuf.StringValue + (*wrapperspb.UInt32Value)(nil), // 6: google.protobuf.UInt32Value + (*wrapperspb.UInt64Value)(nil), // 7: google.protobuf.UInt64Value + (*UInt32Filter)(nil), // 8: cbt.UInt32Filter + (*StringFilter)(nil), // 9: cbt.StringFilter + (*Int64Filter)(nil), // 10: cbt.Int64Filter + (*NullableStringFilter)(nil), // 11: cbt.NullableStringFilter + (*UInt64Filter)(nil), // 12: cbt.UInt64Filter + (*NullableUInt32Filter)(nil), // 13: cbt.NullableUInt32Filter + (*NullableUInt64Filter)(nil), // 14: cbt.NullableUInt64Filter + (*ArrayStringFilter)(nil), // 15: cbt.ArrayStringFilter + (*BoolFilter)(nil), // 16: cbt.BoolFilter +} +var file_int_transaction_mempool_observation_hourly_proto_depIdxs = []int32{ + 5, // 0: cbt.IntTransactionMempoolObservationHourly.to:type_name -> google.protobuf.StringValue + 6, // 1: cbt.IntTransactionMempoolObservationHourly.type:type_name -> google.protobuf.UInt32Value + 5, // 2: cbt.IntTransactionMempoolObservationHourly.gas_tip_cap:type_name -> google.protobuf.StringValue + 5, // 3: cbt.IntTransactionMempoolObservationHourly.gas_fee_cap:type_name -> google.protobuf.StringValue + 7, // 4: cbt.IntTransactionMempoolObservationHourly.blob_gas:type_name -> google.protobuf.UInt64Value + 5, // 5: cbt.IntTransactionMempoolObservationHourly.blob_gas_fee_cap:type_name -> google.protobuf.StringValue + 8, // 6: cbt.ListIntTransactionMempoolObservationHourlyRequest.hour_start_date_time:type_name -> cbt.UInt32Filter + 9, // 7: cbt.ListIntTransactionMempoolObservationHourlyRequest.hash:type_name -> cbt.StringFilter + 8, // 8: cbt.ListIntTransactionMempoolObservationHourlyRequest.updated_date_time:type_name -> cbt.UInt32Filter + 10, // 9: cbt.ListIntTransactionMempoolObservationHourlyRequest.first_seen_date_time:type_name -> cbt.Int64Filter + 10, // 10: cbt.ListIntTransactionMempoolObservationHourlyRequest.last_seen_date_time:type_name -> cbt.Int64Filter + 8, // 11: cbt.ListIntTransactionMempoolObservationHourlyRequest.sighting_count:type_name -> cbt.UInt32Filter + 8, // 12: cbt.ListIntTransactionMempoolObservationHourlyRequest.unique_sentries:type_name -> cbt.UInt32Filter + 9, // 13: cbt.ListIntTransactionMempoolObservationHourlyRequest.from:type_name -> cbt.StringFilter + 11, // 14: cbt.ListIntTransactionMempoolObservationHourlyRequest.to:type_name -> cbt.NullableStringFilter + 12, // 15: cbt.ListIntTransactionMempoolObservationHourlyRequest.nonce:type_name -> cbt.UInt64Filter + 13, // 16: cbt.ListIntTransactionMempoolObservationHourlyRequest.type:type_name -> cbt.NullableUInt32Filter + 12, // 17: cbt.ListIntTransactionMempoolObservationHourlyRequest.gas:type_name -> cbt.UInt64Filter + 9, // 18: cbt.ListIntTransactionMempoolObservationHourlyRequest.gas_price:type_name -> cbt.StringFilter + 11, // 19: cbt.ListIntTransactionMempoolObservationHourlyRequest.gas_tip_cap:type_name -> cbt.NullableStringFilter + 11, // 20: cbt.ListIntTransactionMempoolObservationHourlyRequest.gas_fee_cap:type_name -> cbt.NullableStringFilter + 9, // 21: cbt.ListIntTransactionMempoolObservationHourlyRequest.value:type_name -> cbt.StringFilter + 8, // 22: cbt.ListIntTransactionMempoolObservationHourlyRequest.size:type_name -> cbt.UInt32Filter + 8, // 23: cbt.ListIntTransactionMempoolObservationHourlyRequest.call_data_size:type_name -> cbt.UInt32Filter + 14, // 24: cbt.ListIntTransactionMempoolObservationHourlyRequest.blob_gas:type_name -> cbt.NullableUInt64Filter + 11, // 25: cbt.ListIntTransactionMempoolObservationHourlyRequest.blob_gas_fee_cap:type_name -> cbt.NullableStringFilter + 15, // 26: cbt.ListIntTransactionMempoolObservationHourlyRequest.blob_hashes:type_name -> cbt.ArrayStringFilter + 16, // 27: cbt.ListIntTransactionMempoolObservationHourlyRequest.is_cancel_shape:type_name -> cbt.BoolFilter + 9, // 28: cbt.ListIntTransactionMempoolObservationHourlyRequest.first_sentry_name:type_name -> cbt.StringFilter + 9, // 29: cbt.ListIntTransactionMempoolObservationHourlyRequest.first_sentry_geo_city:type_name -> cbt.StringFilter + 9, // 30: cbt.ListIntTransactionMempoolObservationHourlyRequest.first_sentry_geo_country:type_name -> cbt.StringFilter + 9, // 31: cbt.ListIntTransactionMempoolObservationHourlyRequest.first_sentry_geo_country_code:type_name -> cbt.StringFilter + 9, // 32: cbt.ListIntTransactionMempoolObservationHourlyRequest.first_sentry_geo_continent_code:type_name -> cbt.StringFilter + 0, // 33: cbt.ListIntTransactionMempoolObservationHourlyResponse.int_transaction_mempool_observation_hourly:type_name -> cbt.IntTransactionMempoolObservationHourly + 0, // 34: cbt.GetIntTransactionMempoolObservationHourlyResponse.item:type_name -> cbt.IntTransactionMempoolObservationHourly + 1, // 35: cbt.IntTransactionMempoolObservationHourlyService.List:input_type -> cbt.ListIntTransactionMempoolObservationHourlyRequest + 3, // 36: cbt.IntTransactionMempoolObservationHourlyService.Get:input_type -> cbt.GetIntTransactionMempoolObservationHourlyRequest + 2, // 37: cbt.IntTransactionMempoolObservationHourlyService.List:output_type -> cbt.ListIntTransactionMempoolObservationHourlyResponse + 4, // 38: cbt.IntTransactionMempoolObservationHourlyService.Get:output_type -> cbt.GetIntTransactionMempoolObservationHourlyResponse + 37, // [37:39] is the sub-list for method output_type + 35, // [35:37] is the sub-list for method input_type + 35, // [35:35] is the sub-list for extension type_name + 35, // [35:35] is the sub-list for extension extendee + 0, // [0:35] is the sub-list for field type_name +} + +func init() { file_int_transaction_mempool_observation_hourly_proto_init() } +func file_int_transaction_mempool_observation_hourly_proto_init() { + if File_int_transaction_mempool_observation_hourly_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_int_transaction_mempool_observation_hourly_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*IntTransactionMempoolObservationHourly); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_int_transaction_mempool_observation_hourly_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*ListIntTransactionMempoolObservationHourlyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_int_transaction_mempool_observation_hourly_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*ListIntTransactionMempoolObservationHourlyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_int_transaction_mempool_observation_hourly_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*GetIntTransactionMempoolObservationHourlyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_int_transaction_mempool_observation_hourly_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*GetIntTransactionMempoolObservationHourlyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_int_transaction_mempool_observation_hourly_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_int_transaction_mempool_observation_hourly_proto_goTypes, + DependencyIndexes: file_int_transaction_mempool_observation_hourly_proto_depIdxs, + MessageInfos: file_int_transaction_mempool_observation_hourly_proto_msgTypes, + }.Build() + File_int_transaction_mempool_observation_hourly_proto = out.File + file_int_transaction_mempool_observation_hourly_proto_rawDesc = nil + file_int_transaction_mempool_observation_hourly_proto_goTypes = nil + file_int_transaction_mempool_observation_hourly_proto_depIdxs = nil +} diff --git a/pkg/proto/clickhouse/int_transaction_mempool_observation_hourly.proto b/pkg/proto/clickhouse/int_transaction_mempool_observation_hourly.proto new file mode 100644 index 00000000..11f5b7e8 --- /dev/null +++ b/pkg/proto/clickhouse/int_transaction_mempool_observation_hourly.proto @@ -0,0 +1,166 @@ +syntax = "proto3"; + +package cbt; + +import "common.proto"; +import "google/protobuf/wrappers.proto"; + +option go_package = "github.com/ethpandaops/xatu-cbt/pkg/proto/clickhouse"; +// One row per transaction hash per hour in which it was sighted in the public mempool by at least one sentry. Rows summarise the sightings within that hour only. A transaction sighted across multiple hours has multiple rows + +message IntTransactionMempoolObservationHourly { + // Timestamp when the record was last updated + uint32 updated_date_time = 11; + // The start of the hour bucket the sightings fall in + uint32 hour_start_date_time = 12; + // The transaction hash + string hash = 13; + // Earliest sighting of the transaction by any sentry within this hour + int64 first_seen_date_time = 14; + // Latest sighting of the transaction by any sentry within this hour + int64 last_seen_date_time = 15; + // Number of sightings of the transaction within this hour across all sentries + uint32 sighting_count = 16; + // Number of distinct sentries that sighted the transaction within this hour + uint32 unique_sentries = 17; + // The address of the account that sent the transaction + string from = 18; + // The address of the transaction recipient, null for contract creation + google.protobuf.StringValue to = 19; + // The nonce of the sender account at the time of the transaction + uint64 nonce = 20; + // The type of the transaction + google.protobuf.UInt32Value type = 21; + // The maximum gas provided for the transaction execution + uint64 gas = 22; + // The gas price of the transaction in wei + string gas_price = 23; + // The priority fee (tip) the user has set for the transaction in wei + google.protobuf.StringValue gas_tip_cap = 24; + // The max fee the user has set for the transaction in wei + google.protobuf.StringValue gas_fee_cap = 25; + // The value transferred with the transaction in wei + string value = 26; + // The size of the transaction data in bytes + uint32 size = 27; + // The size of the call data of the transaction in bytes + uint32 call_data_size = 28; + // The maximum gas provided for the blob transaction execution + google.protobuf.UInt64Value blob_gas = 29; + // The max blob fee the user has set for the transaction in wei + google.protobuf.StringValue blob_gas_fee_cap = 30; + // The hashes of the blob commitments for blob transactions + repeated string blob_hashes = 31; + // Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern + bool is_cancel_shape = 32; + // Name of the sentry with the earliest sighting this hour, ties broken by sentry name + string first_sentry_name = 33; + // City of the first-sighting sentry + string first_sentry_geo_city = 34; + // Country of the first-sighting sentry + string first_sentry_geo_country = 35; + // Country code of the first-sighting sentry + string first_sentry_geo_country_code = 36; + // Continent code of the first-sighting sentry + string first_sentry_geo_continent_code = 37; +} + +// Request for listing int_transaction_mempool_observation_hourly records +message ListIntTransactionMempoolObservationHourlyRequest { + // Filter by hour_start_date_time - The start of the hour bucket the sightings fall in (PRIMARY KEY - required unless using alternatives: hash, from) + UInt32Filter hour_start_date_time = 1; + + // Filter by hash - The transaction hash (ORDER BY column 2 - optional) + StringFilter hash = 2; + + // Filter by updated_date_time - Timestamp when the record was last updated (optional) + UInt32Filter updated_date_time = 3; + // Filter by first_seen_date_time - Earliest sighting of the transaction by any sentry within this hour (optional) + Int64Filter first_seen_date_time = 4; + // Filter by last_seen_date_time - Latest sighting of the transaction by any sentry within this hour (optional) + Int64Filter last_seen_date_time = 5; + // Filter by sighting_count - Number of sightings of the transaction within this hour across all sentries (optional) + UInt32Filter sighting_count = 6; + // Filter by unique_sentries - Number of distinct sentries that sighted the transaction within this hour (optional) + UInt32Filter unique_sentries = 7; + // Filter by from - The address of the account that sent the transaction (PROJECTION: p_by_nonce_group - alternative to hour_start_date_time) + StringFilter from = 8; + // Filter by to - The address of the transaction recipient, null for contract creation (optional) + NullableStringFilter to = 9; + // Filter by nonce - The nonce of the sender account at the time of the transaction (optional) + UInt64Filter nonce = 10; + // Filter by type - The type of the transaction (optional) + NullableUInt32Filter type = 11; + // Filter by gas - The maximum gas provided for the transaction execution (optional) + UInt64Filter gas = 12; + // Filter by gas_price - The gas price of the transaction in wei (optional) + StringFilter gas_price = 13; + // Filter by gas_tip_cap - The priority fee (tip) the user has set for the transaction in wei (optional) + NullableStringFilter gas_tip_cap = 14; + // Filter by gas_fee_cap - The max fee the user has set for the transaction in wei (optional) + NullableStringFilter gas_fee_cap = 15; + // Filter by value - The value transferred with the transaction in wei (optional) + StringFilter value = 16; + // Filter by size - The size of the transaction data in bytes (optional) + UInt32Filter size = 17; + // Filter by call_data_size - The size of the call data of the transaction in bytes (optional) + UInt32Filter call_data_size = 18; + // Filter by blob_gas - The maximum gas provided for the blob transaction execution (optional) + NullableUInt64Filter blob_gas = 19; + // Filter by blob_gas_fee_cap - The max blob fee the user has set for the transaction in wei (optional) + NullableStringFilter blob_gas_fee_cap = 20; + // Filter by blob_hashes - The hashes of the blob commitments for blob transactions (optional) + ArrayStringFilter blob_hashes = 21; + // Filter by is_cancel_shape - Whether the transaction is a self-transfer of zero value, the common wallet cancellation pattern (optional) + BoolFilter is_cancel_shape = 22; + // Filter by first_sentry_name - Name of the sentry with the earliest sighting this hour, ties broken by sentry name (optional) + StringFilter first_sentry_name = 23; + // Filter by first_sentry_geo_city - City of the first-sighting sentry (optional) + StringFilter first_sentry_geo_city = 24; + // Filter by first_sentry_geo_country - Country of the first-sighting sentry (optional) + StringFilter first_sentry_geo_country = 25; + // Filter by first_sentry_geo_country_code - Country code of the first-sighting sentry (optional) + StringFilter first_sentry_geo_country_code = 26; + // Filter by first_sentry_geo_continent_code - Continent code of the first-sighting sentry (optional) + StringFilter first_sentry_geo_continent_code = 27; + + // The maximum number of int_transaction_mempool_observation_hourly to return. + // If unspecified, at most 100 items will be returned. + // The maximum value is 10000; values above 10000 will be coerced to 10000. + int32 page_size = 28; + // A page token, received from a previous `ListIntTransactionMempoolObservationHourly` call. + // Provide this to retrieve the subsequent page. + string page_token = 29; + // The order of results. Format: comma-separated list of fields. + // Example: "foo,bar" or "foo desc,bar" for descending order on foo. + // If unspecified, results will be returned in the default order. + string order_by = 30; +} + +// Response for listing int_transaction_mempool_observation_hourly records +message ListIntTransactionMempoolObservationHourlyResponse { + // The list of int_transaction_mempool_observation_hourly. + repeated IntTransactionMempoolObservationHourly int_transaction_mempool_observation_hourly = 1; + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; +} + +// Request for getting a single int_transaction_mempool_observation_hourly record by primary key +message GetIntTransactionMempoolObservationHourlyRequest { + // The start of the hour bucket the sightings fall in + uint32 hour_start_date_time = 1; // Primary key (required) +} + +// Response for getting a single int_transaction_mempool_observation_hourly record +message GetIntTransactionMempoolObservationHourlyResponse { + IntTransactionMempoolObservationHourly item = 1; +} + +// Query int_transaction_mempool_observation_hourly data +service IntTransactionMempoolObservationHourlyService { + // List records | Retrieve paginated results with optional filtering + rpc List(ListIntTransactionMempoolObservationHourlyRequest) returns (ListIntTransactionMempoolObservationHourlyResponse); + // Get record | Retrieve a single record by primary key + rpc Get(GetIntTransactionMempoolObservationHourlyRequest) returns (GetIntTransactionMempoolObservationHourlyResponse); +} diff --git a/tests/mainnet/models/fct_transaction_inclusion.yaml b/tests/mainnet/models/fct_transaction_inclusion.yaml new file mode 100644 index 00000000..1a978c68 --- /dev/null +++ b/tests/mainnet/models/fct_transaction_inclusion.yaml @@ -0,0 +1,19 @@ +model: fct_transaction_inclusion +network: mainnet +external_data: + beacon_api_eth_v2_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_inclusion_beacon_api_eth_v2_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_inclusion_canonical_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block_execution_transaction: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_inclusion_canonical_beacon_block_execution_transaction.parquet + network_column: meta_network_name +assertions: + - name: Row count should be greater than zero + sql: SELECT COUNT(*) AS count FROM fct_transaction_inclusion FINAL + assertions: + - type: greater_than + column: count + value: 0 diff --git a/tests/mainnet/models/fct_transaction_inclusion_daily.yaml b/tests/mainnet/models/fct_transaction_inclusion_daily.yaml new file mode 100644 index 00000000..7ec1b2ce --- /dev/null +++ b/tests/mainnet/models/fct_transaction_inclusion_daily.yaml @@ -0,0 +1,25 @@ +model: fct_transaction_inclusion_daily +network: mainnet +external_data: + beacon_api_eth_v2_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_inclusion_daily_beacon_api_eth_v2_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_inclusion_daily_canonical_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block_execution_transaction: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_inclusion_daily_canonical_beacon_block_execution_transaction.parquet + network_column: meta_network_name + mev_relay_bid_trace: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_inclusion_daily_mev_relay_bid_trace.parquet + network_column: meta_network_name + mev_relay_proposer_payload_delivered: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_inclusion_daily_mev_relay_proposer_payload_delivered.parquet + network_column: meta_network_name +assertions: + - name: Row count should be greater than zero + sql: SELECT COUNT(*) AS count FROM fct_transaction_inclusion_daily FINAL + assertions: + - type: greater_than + column: count + value: 0 diff --git a/tests/mainnet/models/fct_transaction_inclusion_hourly.yaml b/tests/mainnet/models/fct_transaction_inclusion_hourly.yaml new file mode 100644 index 00000000..b66bc407 --- /dev/null +++ b/tests/mainnet/models/fct_transaction_inclusion_hourly.yaml @@ -0,0 +1,25 @@ +model: fct_transaction_inclusion_hourly +network: mainnet +external_data: + beacon_api_eth_v2_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_inclusion_hourly_beacon_api_eth_v2_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_inclusion_hourly_canonical_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block_execution_transaction: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_inclusion_hourly_canonical_beacon_block_execution_transaction.parquet + network_column: meta_network_name + mev_relay_bid_trace: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_inclusion_hourly_mev_relay_bid_trace.parquet + network_column: meta_network_name + mev_relay_proposer_payload_delivered: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_inclusion_hourly_mev_relay_proposer_payload_delivered.parquet + network_column: meta_network_name +assertions: + - name: Row count should be greater than zero + sql: SELECT COUNT(*) AS count FROM fct_transaction_inclusion_hourly FINAL + assertions: + - type: greater_than + column: count + value: 0 diff --git a/tests/mainnet/models/fct_transaction_mempool_outcome_7d.yaml b/tests/mainnet/models/fct_transaction_mempool_outcome_7d.yaml new file mode 100644 index 00000000..f55d6bbe --- /dev/null +++ b/tests/mainnet/models/fct_transaction_mempool_outcome_7d.yaml @@ -0,0 +1,28 @@ +model: fct_transaction_mempool_outcome_7d +network: mainnet +external_data: + beacon_api_eth_v2_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_7d_beacon_api_eth_v2_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_7d_canonical_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block_execution_transaction: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_7d_canonical_beacon_block_execution_transaction.parquet + network_column: meta_network_name + mempool_transaction: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_7d_mempool_transaction.parquet + network_column: meta_network_name + mev_relay_bid_trace: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_7d_mev_relay_bid_trace.parquet + network_column: meta_network_name + mev_relay_proposer_payload_delivered: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_7d_mev_relay_proposer_payload_delivered.parquet + network_column: meta_network_name +assertions: + - name: Row count should be non-negative (model may be empty in short CI seed windows due to the 7 day fill buffer) + sql: SELECT COUNT(*) AS count FROM fct_transaction_mempool_outcome_7d FINAL + assertions: + - type: greater_than_or_equal + column: count + value: 0 diff --git a/tests/mainnet/models/fct_transaction_mempool_outcome_daily.yaml b/tests/mainnet/models/fct_transaction_mempool_outcome_daily.yaml new file mode 100644 index 00000000..6f5c1a51 --- /dev/null +++ b/tests/mainnet/models/fct_transaction_mempool_outcome_daily.yaml @@ -0,0 +1,124 @@ +model: fct_transaction_mempool_outcome_daily +network: mainnet +external_data: + beacon_api_eth_v2_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_daily_beacon_api_eth_v2_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_daily_canonical_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block_execution_transaction: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_daily_canonical_beacon_block_execution_transaction.parquet + network_column: meta_network_name + mempool_transaction: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_daily_mempool_transaction.parquet + network_column: meta_network_name + mev_relay_bid_trace: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_daily_mev_relay_bid_trace.parquet + network_column: meta_network_name + mev_relay_proposer_payload_delivered: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_daily_mev_relay_proposer_payload_delivered.parquet + network_column: meta_network_name +assertions: + - name: Row count should be non-negative (model may be empty in short CI seed windows due to the 7 day fill buffer) + sql: | + SELECT COUNT(*) AS count FROM fct_transaction_mempool_outcome_daily FINAL + assertions: + - type: greater_than_or_equal + column: count + value: 0 + - name: Observed count should always be positive + sql: | + SELECT countIf(observed_count <= 0) AS bad_rows FROM fct_transaction_mempool_outcome_daily FINAL + assertions: + - type: equals + column: bad_rows + value: 0 + - name: Outcome buckets should sum to observed count + sql: | + SELECT count() AS mismatch_rows + FROM fct_transaction_mempool_outcome_daily FINAL + WHERE included_count + nonce_consumed_count + unincluded_count != observed_count + assertions: + - type: equals + column: mismatch_rows + value: 0 + - name: Relay-delivered and unknown-build should sum to included count + sql: | + SELECT count() AS mismatch_rows + FROM fct_transaction_mempool_outcome_daily FINAL + WHERE included_relay_delivered_count + included_unknown_build_count != included_count + assertions: + - type: equals + column: mismatch_rows + value: 0 + - name: No negative counts in any count column + sql: | + SELECT count() AS bad_rows + FROM fct_transaction_mempool_outcome_daily FINAL + WHERE observed_count < 0 + OR included_count < 0 + OR nonce_consumed_count < 0 + OR unincluded_count < 0 + OR included_relay_delivered_count < 0 + OR included_unknown_build_count < 0 + OR in_mempool_at_deadline_count < 0 + OR cancel_shape_count < 0 + OR observed_after_nonce_consumed_count < 0 + OR wait_sample_count < 0 + OR negative_wait_count < 0 + OR blob_observed_count < 0 + OR blob_wait_sample_count < 0 + OR nonce_group_count < 0 + OR multi_attempt_nonce_group_count < 0 + OR replaced_attempt_count < 0 + assertions: + - type: equals + column: bad_rows + value: 0 + - name: Wait sample count should not exceed included count + sql: | + SELECT count() AS bad_rows + FROM fct_transaction_mempool_outcome_daily FINAL + WHERE wait_sample_count > included_count + assertions: + - type: equals + column: bad_rows + value: 0 + - name: Blob wait sample count should not exceed blob observed count + sql: | + SELECT count() AS bad_rows + FROM fct_transaction_mempool_outcome_daily FINAL + WHERE blob_wait_sample_count > blob_observed_count + assertions: + - type: equals + column: bad_rows + value: 0 + - name: Blob observed count should not exceed observed count + sql: | + SELECT count() AS bad_rows + FROM fct_transaction_mempool_outcome_daily FINAL + WHERE blob_observed_count > observed_count + assertions: + - type: equals + column: bad_rows + value: 0 + - name: Wait latency percentiles should be monotonically ordered + sql: | + SELECT count() AS bad_rows + FROM fct_transaction_mempool_outcome_daily FINAL + WHERE wait_sample_count > 0 + AND (wait_ms_p50 > wait_ms_p90 OR wait_ms_p90 > wait_ms_p99) + assertions: + - type: equals + column: bad_rows + value: 0 + - name: Multi-attempt nonce groups should not exceed total nonce groups + sql: | + SELECT count() AS bad_rows + FROM fct_transaction_mempool_outcome_daily FINAL + WHERE multi_attempt_nonce_group_count > nonce_group_count + assertions: + - type: equals + column: bad_rows + value: 0 diff --git a/tests/mainnet/models/fct_transaction_mempool_outcome_hourly.yaml b/tests/mainnet/models/fct_transaction_mempool_outcome_hourly.yaml new file mode 100644 index 00000000..699384ec --- /dev/null +++ b/tests/mainnet/models/fct_transaction_mempool_outcome_hourly.yaml @@ -0,0 +1,28 @@ +model: fct_transaction_mempool_outcome_hourly +network: mainnet +external_data: + beacon_api_eth_v2_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_hourly_beacon_api_eth_v2_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_hourly_canonical_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block_execution_transaction: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_hourly_canonical_beacon_block_execution_transaction.parquet + network_column: meta_network_name + mempool_transaction: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_hourly_mempool_transaction.parquet + network_column: meta_network_name + mev_relay_bid_trace: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_hourly_mev_relay_bid_trace.parquet + network_column: meta_network_name + mev_relay_proposer_payload_delivered: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_mempool_outcome_hourly_mev_relay_proposer_payload_delivered.parquet + network_column: meta_network_name +assertions: + - name: Row count should be non-negative (model may be empty in short CI seed windows due to the 7 day fill buffer) + sql: SELECT COUNT(*) AS count FROM fct_transaction_mempool_outcome_hourly FINAL + assertions: + - type: greater_than_or_equal + column: count + value: 0 diff --git a/tests/mainnet/models/fct_transaction_replacement.yaml b/tests/mainnet/models/fct_transaction_replacement.yaml new file mode 100644 index 00000000..4467a22f --- /dev/null +++ b/tests/mainnet/models/fct_transaction_replacement.yaml @@ -0,0 +1,79 @@ +model: fct_transaction_replacement +network: mainnet +external_data: + beacon_api_eth_v2_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_replacement_beacon_api_eth_v2_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_replacement_canonical_beacon_block.parquet + network_column: meta_network_name + canonical_beacon_block_execution_transaction: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_replacement_canonical_beacon_block_execution_transaction.parquet + network_column: meta_network_name + mempool_transaction: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/fct_transaction_replacement_mempool_transaction.parquet + network_column: meta_network_name +assertions: + - name: Row count should be non-negative (model may be empty in short CI seed windows due to the 7 day fill buffer) + sql: | + SELECT COUNT(*) AS count FROM fct_transaction_replacement FINAL + assertions: + - type: greater_than_or_equal + column: count + value: 0 + - name: Attempt index is always at least 1 + sql: | + SELECT countIf(attempt_index < 1) AS bad_rows FROM fct_transaction_replacement FINAL + assertions: + - type: equals + column: bad_rows + value: 0 + - name: Group attempt count is at least 2 for every emitted row + sql: | + SELECT countIf(group_attempt_count < 2) AS bad_rows FROM fct_transaction_replacement FINAL + assertions: + - type: equals + column: bad_rows + value: 0 + - name: Attempt index never exceeds the group attempt count + sql: | + SELECT countIf(attempt_index > group_attempt_count) AS invalid_index_count FROM fct_transaction_replacement FINAL + assertions: + - type: equals + column: invalid_index_count + value: 0 + - name: First attempt in a group must have no previous_hash + sql: | + SELECT countIf(attempt_index = 1 AND previous_hash IS NOT NULL) AS bad_previous_hash FROM fct_transaction_replacement FINAL + assertions: + - type: equals + column: bad_previous_hash + value: 0 + - name: First attempt in a group must have null gas cap deltas + sql: | + SELECT countIf(attempt_index = 1 AND (gas_tip_cap_delta IS NOT NULL OR gas_fee_cap_delta IS NOT NULL)) AS bad_deltas FROM fct_transaction_replacement FINAL + assertions: + - type: equals + column: bad_deltas + value: 0 + - name: Non-first attempts must carry a previous_hash + sql: | + SELECT countIf(attempt_index > 1 AND previous_hash IS NULL) AS missing_previous_hash FROM fct_transaction_replacement FINAL + assertions: + - type: equals + column: missing_previous_hash + value: 0 + - name: group_outcome only takes the two expected values + sql: | + SELECT countIf(group_outcome NOT IN ('included', 'unincluded')) AS invalid_outcome_count FROM fct_transaction_replacement FINAL + assertions: + - type: equals + column: invalid_outcome_count + value: 0 + - name: Every included group has exactly one winner and a winner_hash + sql: | + SELECT countIf(group_outcome = 'included' AND winner_hash IS NULL) AS included_without_winner FROM fct_transaction_replacement FINAL + assertions: + - type: equals + column: included_without_winner + value: 0 diff --git a/tests/mainnet/models/int_transaction_mempool_observation_hourly.yaml b/tests/mainnet/models/int_transaction_mempool_observation_hourly.yaml new file mode 100644 index 00000000..f1f25087 --- /dev/null +++ b/tests/mainnet/models/int_transaction_mempool_observation_hourly.yaml @@ -0,0 +1,13 @@ +model: int_transaction_mempool_observation_hourly +network: mainnet +external_data: + mempool_transaction: + url: https://data.ethpandaops.io/xatu-cbt/mainnet/fusaka/int_transaction_mempool_observation_hourly_mempool_transaction.parquet + network_column: meta_network_name +assertions: + - name: Row count should be greater than zero + sql: SELECT COUNT(*) AS count FROM int_transaction_mempool_observation_hourly FINAL + assertions: + - type: greater_than + column: count + value: 0