v0.2.9-pre.009
This commit is contained in:
@@ -1,11 +1,8 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/grpc_subscribe.rs
|
||||
// version: 6
|
||||
// version: 7
|
||||
|
||||
#[cfg(test)]
|
||||
const MAX_GRPC_BLOCKHASH_TEXT_LENGTH_BYTES: usize = 128;
|
||||
#[cfg(test)]
|
||||
const MAX_GRPC_BLOCK_VECTOR_COUNT: usize = 65_536;
|
||||
#[cfg(test)]
|
||||
const MAX_GRPC_SUBSCRIBE_ACCOUNT_DATA_LENGTH_BYTES: usize = 512 * 1024 * 1024;
|
||||
const MAX_GRPC_SUBSCRIBE_ACCOUNT_PREDICATE_COUNT: usize = 256;
|
||||
const MAX_GRPC_SUBSCRIBE_ACCOUNT_SELECTOR_COUNT: usize = 50_000;
|
||||
@@ -16,26 +13,16 @@ const MAX_GRPC_SUBSCRIBE_FILTER_GROUP_COUNT: usize = 1_024;
|
||||
const MAX_GRPC_SUBSCRIBE_FILTER_NAME_LENGTH_BYTES: usize = 128;
|
||||
const MAX_GRPC_SUBSCRIBE_MEMCMP_BYTES: usize = 1024 * 1024;
|
||||
const MAX_GRPC_SUBSCRIBE_MEMCMP_TEXT_LENGTH_BYTES: usize = 2 * 1024 * 1024;
|
||||
#[cfg(test)]
|
||||
const MAX_GRPC_SUBSCRIBE_SLOT_DEAD_ERROR_LENGTH_BYTES: usize = 16 * 1024;
|
||||
const MAX_GRPC_SUBSCRIBE_TRANSACTION_SIGNATURE_TEXT_LENGTH_BYTES: usize = 128;
|
||||
#[cfg(test)]
|
||||
const MAX_GRPC_SUBSCRIBE_UPDATE_FILTER_COUNT: usize = 1_024;
|
||||
#[cfg(test)]
|
||||
const MAX_GRPC_TRANSACTION_ERROR_BYTES: usize = 64 * 1024;
|
||||
#[cfg(test)]
|
||||
const MAX_GRPC_TRANSACTION_INSTRUCTION_DATA_BYTES: usize = 1024 * 1024;
|
||||
#[cfg(test)]
|
||||
const MAX_GRPC_TRANSACTION_LOG_COUNT: usize = 16_384;
|
||||
#[cfg(test)]
|
||||
const MAX_GRPC_TRANSACTION_LOG_LENGTH_BYTES: usize = 64 * 1024;
|
||||
#[cfg(test)]
|
||||
const MAX_GRPC_TRANSACTION_RETURN_DATA_BYTES: usize = 1024 * 1024;
|
||||
#[cfg(test)]
|
||||
const MAX_GRPC_TRANSACTION_TEXT_LENGTH_BYTES: usize = 64 * 1024;
|
||||
#[cfg(test)]
|
||||
const MAX_GRPC_TRANSACTION_VECTOR_COUNT: usize = 65_536;
|
||||
#[cfg(test)]
|
||||
const YELLOWSTONE_HASH_LENGTH_BYTES: usize = 32;
|
||||
const YELLOWSTONE_TRANSACTION_SIGNATURE_WIRE_LENGTH_BYTES: usize = 64;
|
||||
|
||||
@@ -105,7 +92,6 @@ impl YellowstoneAccountsDataSlice {
|
||||
return self.length;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn to_wire(self) -> yellowstone_grpc_proto::geyser::SubscribeRequestAccountsDataSlice {
|
||||
return yellowstone_grpc_proto::geyser::SubscribeRequestAccountsDataSlice { offset: self.offset, length: self.length };
|
||||
}
|
||||
@@ -130,7 +116,6 @@ impl YellowstoneSubscribePing {
|
||||
return self.id;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn to_wire(self) -> yellowstone_grpc_proto::geyser::SubscribeRequestPing {
|
||||
return yellowstone_grpc_proto::geyser::SubscribeRequestPing { id: self.id };
|
||||
}
|
||||
@@ -144,7 +129,6 @@ pub enum YellowstoneCuckooHashAlgorithm {
|
||||
}
|
||||
|
||||
impl YellowstoneCuckooHashAlgorithm {
|
||||
#[cfg(test)]
|
||||
const fn to_wire(self) -> i32 {
|
||||
return match self {
|
||||
Self::SipHash => yellowstone_grpc_proto::geyser::CuckooHashAlgorithm::SipHash as i32,
|
||||
@@ -222,7 +206,6 @@ impl YellowstoneCuckooFilter {
|
||||
return self.hash_algorithm;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn to_wire(&self) -> yellowstone_grpc_proto::geyser::CuckooFilter {
|
||||
return yellowstone_grpc_proto::geyser::CuckooFilter {
|
||||
data: self.data.clone(),
|
||||
@@ -335,7 +318,6 @@ impl YellowstoneAccountMemcmp {
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn to_wire(&self) -> yellowstone_grpc_proto::geyser::SubscribeRequestFilterAccountsFilterMemcmp {
|
||||
let data = match &self.data {
|
||||
YellowstoneAccountMemcmpData::Bytes(value) => {
|
||||
@@ -394,7 +376,6 @@ pub enum YellowstoneAccountFilterPredicate {
|
||||
}
|
||||
|
||||
impl YellowstoneAccountFilterPredicate {
|
||||
#[cfg(test)]
|
||||
fn to_wire(&self) -> yellowstone_grpc_proto::geyser::SubscribeRequestFilterAccountsFilter {
|
||||
let filter = match self {
|
||||
Self::Memcmp(value) => yellowstone_grpc_proto::geyser::subscribe_request_filter_accounts_filter::Filter::Memcmp(value.to_wire()),
|
||||
@@ -514,7 +495,6 @@ impl YellowstoneSubscribeAccountFilter {
|
||||
return self.cuckoo_accounts_filter.as_ref();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn to_wire(&self) -> yellowstone_grpc_proto::geyser::SubscribeRequestFilterAccounts {
|
||||
return yellowstone_grpc_proto::geyser::SubscribeRequestFilterAccounts {
|
||||
account: self.accounts.iter().map(std::string::ToString::to_string).collect(),
|
||||
@@ -581,7 +561,6 @@ impl YellowstoneSubscribeSlotFilter {
|
||||
return self.interslot_updates;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn to_wire(self) -> yellowstone_grpc_proto::geyser::SubscribeRequestFilterSlots {
|
||||
return yellowstone_grpc_proto::geyser::SubscribeRequestFilterSlots {
|
||||
filter_by_commitment: self.filter_by_commitment,
|
||||
@@ -872,7 +851,6 @@ pub enum YellowstoneTokenAccountExpansion {
|
||||
}
|
||||
|
||||
impl YellowstoneTokenAccountExpansion {
|
||||
#[cfg(test)]
|
||||
const fn to_wire(self) -> i32 {
|
||||
return match self {
|
||||
Self::All => yellowstone_grpc_proto::geyser::TokenAccountExpansionControlFlag::All as i32,
|
||||
@@ -1033,7 +1011,6 @@ impl YellowstoneSubscribeTransactionFilter {
|
||||
return self.token_accounts;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn to_wire(&self) -> yellowstone_grpc_proto::geyser::SubscribeRequestFilterTransactions {
|
||||
return yellowstone_grpc_proto::geyser::SubscribeRequestFilterTransactions {
|
||||
vote: self.vote,
|
||||
@@ -2027,7 +2004,6 @@ impl YellowstoneSubscribeBlockFilter {
|
||||
return self.cuckoo_account_include.as_ref();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn to_wire(&self) -> yellowstone_grpc_proto::geyser::SubscribeRequestFilterBlocks {
|
||||
return yellowstone_grpc_proto::geyser::SubscribeRequestFilterBlocks {
|
||||
account_include: self.account_include.iter().map(std::string::ToString::to_string).collect(),
|
||||
@@ -2424,6 +2400,99 @@ impl std::fmt::Debug for YellowstoneEntryUpdate {
|
||||
}
|
||||
}
|
||||
|
||||
/// Server-side Yellowstone keepalive ping update.
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub struct YellowstoneSubscribePingUpdate {
|
||||
filters: std::vec::Vec<crate::YellowstoneSubscribeFilterName>,
|
||||
created_at: std::option::Option<crate::YellowstoneUpdateTimestamp>,
|
||||
}
|
||||
|
||||
impl YellowstoneSubscribePingUpdate {
|
||||
/// Returns echoed matching filter names in server order.
|
||||
#[must_use]
|
||||
pub fn filters(&self) -> &[crate::YellowstoneSubscribeFilterName] {
|
||||
return self.filters.as_slice();
|
||||
}
|
||||
|
||||
/// Returns the optional server creation timestamp.
|
||||
#[must_use]
|
||||
pub const fn created_at(&self) -> std::option::Option<crate::YellowstoneUpdateTimestamp> {
|
||||
return self.created_at;
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for YellowstoneSubscribePingUpdate {
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
return formatter
|
||||
.debug_struct("YellowstoneSubscribePingUpdate")
|
||||
.field("filter_count", &self.filters.len())
|
||||
.field("created_at", &self.created_at)
|
||||
.finish();
|
||||
}
|
||||
}
|
||||
|
||||
/// Server-side Yellowstone keepalive pong update.
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub struct YellowstoneSubscribePongUpdate {
|
||||
filters: std::vec::Vec<crate::YellowstoneSubscribeFilterName>,
|
||||
created_at: std::option::Option<crate::YellowstoneUpdateTimestamp>,
|
||||
id: i32,
|
||||
}
|
||||
|
||||
impl YellowstoneSubscribePongUpdate {
|
||||
/// Returns echoed matching filter names in server order.
|
||||
#[must_use]
|
||||
pub fn filters(&self) -> &[crate::YellowstoneSubscribeFilterName] {
|
||||
return self.filters.as_slice();
|
||||
}
|
||||
|
||||
/// Returns the optional server creation timestamp.
|
||||
#[must_use]
|
||||
pub const fn created_at(&self) -> std::option::Option<crate::YellowstoneUpdateTimestamp> {
|
||||
return self.created_at;
|
||||
}
|
||||
|
||||
/// Returns the exact ping identifier echoed by the server.
|
||||
#[must_use]
|
||||
pub const fn id(&self) -> i32 {
|
||||
return self.id;
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for YellowstoneSubscribePongUpdate {
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
return formatter
|
||||
.debug_struct("YellowstoneSubscribePongUpdate")
|
||||
.field("filter_count", &self.filters.len())
|
||||
.field("created_at", &self.created_at)
|
||||
.field("id", &self.id)
|
||||
.finish();
|
||||
}
|
||||
}
|
||||
|
||||
/// Any standard Yellowstone update delivered by the bidirectional `Subscribe` stream.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum YellowstoneSubscribeUpdate {
|
||||
/// Account update.
|
||||
Account(crate::YellowstoneAccountUpdate),
|
||||
/// Slot lifecycle update.
|
||||
Slot(crate::YellowstoneSlotUpdate),
|
||||
/// Full transaction update.
|
||||
Transaction(crate::YellowstoneTransactionUpdate),
|
||||
/// Lightweight transaction-status update.
|
||||
TransactionStatus(crate::YellowstoneTransactionStatusUpdate),
|
||||
/// Full block update.
|
||||
Block(crate::YellowstoneBlockUpdate),
|
||||
/// Server keepalive ping. KSP replies automatically with a ping request.
|
||||
Ping(crate::YellowstoneSubscribePingUpdate),
|
||||
/// Server keepalive pong.
|
||||
Pong(crate::YellowstoneSubscribePongUpdate),
|
||||
/// Block-metadata update.
|
||||
BlockMeta(crate::YellowstoneBlockMetaUpdate),
|
||||
/// Entry update.
|
||||
Entry(crate::YellowstoneEntryUpdate),
|
||||
}
|
||||
|
||||
/// Named empty filter activating the standard Yellowstone `blocks_meta` family.
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
||||
pub struct YellowstoneSubscribeBlocksMetaFilter {
|
||||
@@ -2437,7 +2506,6 @@ impl YellowstoneSubscribeBlocksMetaFilter {
|
||||
return Self { _private: () };
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn to_wire(self) -> yellowstone_grpc_proto::geyser::SubscribeRequestFilterBlocksMeta {
|
||||
return yellowstone_grpc_proto::geyser::SubscribeRequestFilterBlocksMeta::default();
|
||||
}
|
||||
@@ -2456,7 +2524,6 @@ impl YellowstoneSubscribeEntryFilter {
|
||||
return Self { _private: () };
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn to_wire(self) -> yellowstone_grpc_proto::geyser::SubscribeRequestFilterEntry {
|
||||
return yellowstone_grpc_proto::geyser::SubscribeRequestFilterEntry::default();
|
||||
}
|
||||
@@ -2712,7 +2779,6 @@ impl YellowstoneSubscribeRequest {
|
||||
return std::result::Result::Ok(());
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn to_wire(&self) -> ksp_core_lib::Result<yellowstone_grpc_proto::geyser::SubscribeRequest> {
|
||||
let validation = self.validate();
|
||||
if let std::result::Result::Err(error) = validation {
|
||||
@@ -2770,7 +2836,6 @@ impl YellowstoneSubscribeRequest {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_account_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate) -> ksp_core_lib::Result<crate::YellowstoneAccountUpdate> {
|
||||
let (filters, created_at) = match decode_update_envelope(wire.filters, wire.created_at) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -2790,7 +2855,6 @@ fn decode_account_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate)
|
||||
return std::result::Result::Ok(crate::YellowstoneAccountUpdate { filters, created_at, account, slot: update.slot, is_startup: update.is_startup });
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_slot_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate) -> ksp_core_lib::Result<crate::YellowstoneSlotUpdate> {
|
||||
let (filters, created_at) = match decode_update_envelope(wire.filters, wire.created_at) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -2823,7 +2887,6 @@ fn decode_slot_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate) ->
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_transaction_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate) -> ksp_core_lib::Result<crate::YellowstoneTransactionUpdate> {
|
||||
let (filters, created_at) = match decode_update_envelope(wire.filters, wire.created_at) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -2843,7 +2906,6 @@ fn decode_transaction_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpda
|
||||
return std::result::Result::Ok(crate::YellowstoneTransactionUpdate { filters, created_at, transaction, slot: update.slot });
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_transaction_status_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate) -> ksp_core_lib::Result<crate::YellowstoneTransactionStatusUpdate> {
|
||||
let (filters, created_at) = match decode_update_envelope(wire.filters, wire.created_at) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -2875,7 +2937,30 @@ fn decode_transaction_status_update(wire: yellowstone_grpc_proto::geyser::Subscr
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_ping_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate) -> ksp_core_lib::Result<crate::YellowstoneSubscribePingUpdate> {
|
||||
let (filters, created_at) = match decode_update_envelope(wire.filters, wire.created_at) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
match wire.update_oneof {
|
||||
std::option::Option::Some(yellowstone_grpc_proto::geyser::subscribe_update::UpdateOneof::Ping(_)) => {},
|
||||
_ => return invalid_subscribe_response("ping", "Yellowstone update does not contain a ping payload"),
|
||||
}
|
||||
return std::result::Result::Ok(crate::YellowstoneSubscribePingUpdate { filters, created_at });
|
||||
}
|
||||
|
||||
fn decode_pong_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate) -> ksp_core_lib::Result<crate::YellowstoneSubscribePongUpdate> {
|
||||
let (filters, created_at) = match decode_update_envelope(wire.filters, wire.created_at) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let pong = match wire.update_oneof {
|
||||
std::option::Option::Some(yellowstone_grpc_proto::geyser::subscribe_update::UpdateOneof::Pong(value)) => value,
|
||||
_ => return invalid_subscribe_response("pong", "Yellowstone update does not contain a pong payload"),
|
||||
};
|
||||
return std::result::Result::Ok(crate::YellowstoneSubscribePongUpdate { filters, created_at, id: pong.id });
|
||||
}
|
||||
|
||||
fn decode_block_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate) -> ksp_core_lib::Result<crate::YellowstoneBlockUpdate> {
|
||||
let (filters, created_at) = match decode_update_envelope(wire.filters, wire.created_at) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -2951,7 +3036,6 @@ fn decode_block_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate) ->
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_block_meta_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate) -> ksp_core_lib::Result<crate::YellowstoneBlockMetaUpdate> {
|
||||
let (filters, created_at) = match decode_update_envelope(wire.filters, wire.created_at) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -2991,7 +3075,6 @@ fn decode_block_meta_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdat
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_entry_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate) -> ksp_core_lib::Result<crate::YellowstoneEntryUpdate> {
|
||||
let (filters, created_at) = match decode_update_envelope(wire.filters, wire.created_at) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -3008,7 +3091,6 @@ fn decode_entry_update(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate) ->
|
||||
return std::result::Result::Ok(crate::YellowstoneEntryUpdate { filters, created_at, entry });
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_block_rewards(wire: yellowstone_grpc_proto::solana::storage::confirmed_block::Rewards) -> ksp_core_lib::Result<crate::YellowstoneBlockRewards> {
|
||||
if wire.rewards.len() > MAX_GRPC_BLOCK_VECTOR_COUNT {
|
||||
return invalid_subscribe_response("block.rewards", "Yellowstone block reward count exceeds the KSP bound");
|
||||
@@ -3024,7 +3106,6 @@ fn decode_block_rewards(wire: yellowstone_grpc_proto::solana::storage::confirmed
|
||||
return std::result::Result::Ok(crate::YellowstoneBlockRewards { rewards, num_partitions: wire.num_partitions.map(|value| return value.num_partitions) });
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_entry_info(wire: yellowstone_grpc_proto::geyser::SubscribeUpdateEntry) -> ksp_core_lib::Result<crate::YellowstoneEntryInfo> {
|
||||
let hash = match decode_entry_hash(wire.hash) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -3040,7 +3121,6 @@ fn decode_entry_info(wire: yellowstone_grpc_proto::geyser::SubscribeUpdateEntry)
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_entry_hash(bytes: std::vec::Vec<u8>) -> ksp_core_lib::Result<crate::YellowstoneHashBytes> {
|
||||
let bytes: [u8; YELLOWSTONE_HASH_LENGTH_BYTES] = match bytes.try_into() {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -3049,7 +3129,6 @@ fn decode_entry_hash(bytes: std::vec::Vec<u8>) -> ksp_core_lib::Result<crate::Ye
|
||||
return std::result::Result::Ok(crate::YellowstoneHashBytes { bytes });
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_blockhash_text(field: &'static str, value: std::string::String) -> ksp_core_lib::Result<std::string::String> {
|
||||
if value.is_empty()
|
||||
|| value.len() > MAX_GRPC_BLOCKHASH_TEXT_LENGTH_BYTES
|
||||
@@ -3061,7 +3140,6 @@ fn decode_blockhash_text(field: &'static str, value: std::string::String) -> ksp
|
||||
return std::result::Result::Ok(value);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_transaction_info(wire: yellowstone_grpc_proto::geyser::SubscribeUpdateTransactionInfo) -> ksp_core_lib::Result<crate::YellowstoneTransactionInfo> {
|
||||
let signature = match decode_transaction_signature("transaction.signature", wire.signature) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -3084,7 +3162,6 @@ fn decode_transaction_info(wire: yellowstone_grpc_proto::geyser::SubscribeUpdate
|
||||
return std::result::Result::Ok(crate::YellowstoneTransactionInfo { signature, is_vote: wire.is_vote, transaction, meta, index: wire.index });
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_stored_transaction(
|
||||
wire: yellowstone_grpc_proto::solana::storage::confirmed_block::Transaction,
|
||||
) -> ksp_core_lib::Result<crate::YellowstoneStoredTransaction> {
|
||||
@@ -3109,7 +3186,6 @@ fn decode_stored_transaction(
|
||||
return std::result::Result::Ok(crate::YellowstoneStoredTransaction { signatures, message });
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_transaction_message(
|
||||
wire: yellowstone_grpc_proto::solana::storage::confirmed_block::Message,
|
||||
) -> ksp_core_lib::Result<crate::YellowstoneTransactionMessage> {
|
||||
@@ -3174,7 +3250,6 @@ fn decode_transaction_message(
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_compiled_instruction(
|
||||
wire: yellowstone_grpc_proto::solana::storage::confirmed_block::CompiledInstruction,
|
||||
) -> ksp_core_lib::Result<crate::YellowstoneCompiledInstruction> {
|
||||
@@ -3188,7 +3263,6 @@ fn decode_compiled_instruction(
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_message_address_table_lookup(
|
||||
wire: yellowstone_grpc_proto::solana::storage::confirmed_block::MessageAddressTableLookup,
|
||||
) -> ksp_core_lib::Result<crate::YellowstoneMessageAddressTableLookup> {
|
||||
@@ -3206,7 +3280,6 @@ fn decode_message_address_table_lookup(
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_transaction_status_meta(
|
||||
wire: yellowstone_grpc_proto::solana::storage::confirmed_block::TransactionStatusMeta,
|
||||
) -> ksp_core_lib::Result<crate::YellowstoneTransactionStatusMeta> {
|
||||
@@ -3310,7 +3383,6 @@ fn decode_transaction_status_meta(
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_inner_instructions(
|
||||
wire: yellowstone_grpc_proto::solana::storage::confirmed_block::InnerInstructions,
|
||||
) -> ksp_core_lib::Result<crate::YellowstoneInnerInstructions> {
|
||||
@@ -3332,7 +3404,6 @@ fn decode_inner_instructions(
|
||||
return std::result::Result::Ok(crate::YellowstoneInnerInstructions { index: wire.index, instructions });
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_token_balance(wire: yellowstone_grpc_proto::solana::storage::confirmed_block::TokenBalance) -> ksp_core_lib::Result<crate::YellowstoneTokenBalance> {
|
||||
if wire.mint.len() > MAX_GRPC_TRANSACTION_TEXT_LENGTH_BYTES
|
||||
|| wire.owner.len() > MAX_GRPC_TRANSACTION_TEXT_LENGTH_BYTES
|
||||
@@ -3363,7 +3434,6 @@ fn decode_token_balance(wire: yellowstone_grpc_proto::solana::storage::confirmed
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_return_data(wire: yellowstone_grpc_proto::solana::storage::confirmed_block::ReturnData) -> ksp_core_lib::Result<crate::YellowstoneReturnData> {
|
||||
if wire.data.len() > MAX_GRPC_TRANSACTION_RETURN_DATA_BYTES {
|
||||
return invalid_subscribe_response("transaction.meta.return_data", "Yellowstone transaction return data exceeds the KSP bound");
|
||||
@@ -3375,7 +3445,6 @@ fn decode_return_data(wire: yellowstone_grpc_proto::solana::storage::confirmed_b
|
||||
return std::result::Result::Ok(crate::YellowstoneReturnData { program_id, data: wire.data });
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_reward(wire: yellowstone_grpc_proto::solana::storage::confirmed_block::Reward) -> ksp_core_lib::Result<crate::YellowstoneReward> {
|
||||
if wire.pubkey.len() > MAX_GRPC_TRANSACTION_TEXT_LENGTH_BYTES
|
||||
|| wire.commission.len() > MAX_GRPC_TRANSACTION_TEXT_LENGTH_BYTES
|
||||
@@ -3410,7 +3479,6 @@ fn decode_reward(wire: yellowstone_grpc_proto::solana::storage::confirmed_block:
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_transaction_error(
|
||||
field: &'static str,
|
||||
wire: yellowstone_grpc_proto::solana::storage::confirmed_block::TransactionError,
|
||||
@@ -3421,7 +3489,6 @@ fn decode_transaction_error(
|
||||
return std::result::Result::Ok(crate::YellowstoneTransactionError { bytes: wire.err });
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_transaction_signature(field: &'static str, bytes: std::vec::Vec<u8>) -> ksp_core_lib::Result<crate::YellowstoneTransactionSignature> {
|
||||
let bytes: [u8; YELLOWSTONE_TRANSACTION_SIGNATURE_WIRE_LENGTH_BYTES] = match bytes.try_into() {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -3430,7 +3497,6 @@ fn decode_transaction_signature(field: &'static str, bytes: std::vec::Vec<u8>) -
|
||||
return std::result::Result::Ok(crate::YellowstoneTransactionSignature::new(bytes));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_hash_bytes(field: &'static str, bytes: std::vec::Vec<u8>) -> ksp_core_lib::Result<crate::YellowstoneHashBytes> {
|
||||
let bytes: [u8; YELLOWSTONE_HASH_LENGTH_BYTES] = match bytes.try_into() {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -3439,7 +3505,6 @@ fn decode_hash_bytes(field: &'static str, bytes: std::vec::Vec<u8>) -> ksp_core_
|
||||
return std::result::Result::Ok(crate::YellowstoneHashBytes { bytes });
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_update_envelope(
|
||||
filters: std::vec::Vec<std::string::String>,
|
||||
created_at: std::option::Option<yellowstone_grpc_proto::prost_types::Timestamp>,
|
||||
@@ -3471,7 +3536,6 @@ fn decode_update_envelope(
|
||||
return std::result::Result::Ok((decoded_filters, decoded_created_at));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_account_info(wire: yellowstone_grpc_proto::geyser::SubscribeUpdateAccountInfo) -> ksp_core_lib::Result<crate::YellowstoneAccountInfo> {
|
||||
if wire.data.len() > MAX_GRPC_SUBSCRIBE_ACCOUNT_DATA_LENGTH_BYTES {
|
||||
return invalid_subscribe_response("account.data", "Yellowstone account data exceeds the KSP bound");
|
||||
@@ -3508,7 +3572,6 @@ fn decode_account_info(wire: yellowstone_grpc_proto::geyser::SubscribeUpdateAcco
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_pubkey_bytes(field: &'static str, bytes: std::vec::Vec<u8>) -> ksp_core_lib::Result<ksp_core_lib::Pubkey> {
|
||||
let array: [u8; 32] = match bytes.try_into() {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -3588,16 +3651,53 @@ fn validate_memcmp_text(value: &str) -> ksp_core_lib::Result<()> {
|
||||
return std::result::Result::Ok(());
|
||||
}
|
||||
|
||||
/// Converts one validated KSP subscribe request to the internal Yellowstone protobuf wire.
|
||||
pub(crate) fn yellowstone_subscribe_request_to_wire(
|
||||
request: &crate::YellowstoneSubscribeRequest,
|
||||
) -> ksp_core_lib::Result<yellowstone_grpc_proto::geyser::SubscribeRequest> {
|
||||
return request.to_wire();
|
||||
}
|
||||
|
||||
/// Decodes one internal Yellowstone protobuf update into the complete KSP-owned update enum.
|
||||
pub(crate) fn yellowstone_subscribe_update_from_wire(
|
||||
wire: yellowstone_grpc_proto::geyser::SubscribeUpdate,
|
||||
) -> ksp_core_lib::Result<crate::YellowstoneSubscribeUpdate> {
|
||||
let kind = match wire.update_oneof.as_ref() {
|
||||
std::option::Option::Some(yellowstone_grpc_proto::geyser::subscribe_update::UpdateOneof::Account(_)) => 1_u8,
|
||||
std::option::Option::Some(yellowstone_grpc_proto::geyser::subscribe_update::UpdateOneof::Slot(_)) => 2_u8,
|
||||
std::option::Option::Some(yellowstone_grpc_proto::geyser::subscribe_update::UpdateOneof::Transaction(_)) => 3_u8,
|
||||
std::option::Option::Some(yellowstone_grpc_proto::geyser::subscribe_update::UpdateOneof::TransactionStatus(_)) => 4_u8,
|
||||
std::option::Option::Some(yellowstone_grpc_proto::geyser::subscribe_update::UpdateOneof::Block(_)) => 5_u8,
|
||||
std::option::Option::Some(yellowstone_grpc_proto::geyser::subscribe_update::UpdateOneof::Ping(_)) => 6_u8,
|
||||
std::option::Option::Some(yellowstone_grpc_proto::geyser::subscribe_update::UpdateOneof::Pong(_)) => 7_u8,
|
||||
std::option::Option::Some(yellowstone_grpc_proto::geyser::subscribe_update::UpdateOneof::BlockMeta(_)) => 8_u8,
|
||||
std::option::Option::Some(yellowstone_grpc_proto::geyser::subscribe_update::UpdateOneof::Entry(_)) => 9_u8,
|
||||
std::option::Option::None => {
|
||||
return invalid_subscribe_response("update.oneof", "Yellowstone subscribe update is missing its oneof payload");
|
||||
},
|
||||
};
|
||||
return match kind {
|
||||
1 => decode_account_update(wire).map(crate::YellowstoneSubscribeUpdate::Account),
|
||||
2 => decode_slot_update(wire).map(crate::YellowstoneSubscribeUpdate::Slot),
|
||||
3 => decode_transaction_update(wire).map(crate::YellowstoneSubscribeUpdate::Transaction),
|
||||
4 => decode_transaction_status_update(wire).map(crate::YellowstoneSubscribeUpdate::TransactionStatus),
|
||||
5 => decode_block_update(wire).map(crate::YellowstoneSubscribeUpdate::Block),
|
||||
6 => decode_ping_update(wire).map(crate::YellowstoneSubscribeUpdate::Ping),
|
||||
7 => decode_pong_update(wire).map(crate::YellowstoneSubscribeUpdate::Pong),
|
||||
8 => decode_block_meta_update(wire).map(crate::YellowstoneSubscribeUpdate::BlockMeta),
|
||||
9 => decode_entry_update(wire).map(crate::YellowstoneSubscribeUpdate::Entry),
|
||||
_ => invalid_subscribe_response("update.oneof", "Yellowstone subscribe update kind is unsupported"),
|
||||
};
|
||||
}
|
||||
|
||||
fn invalid_subscribe_parameter<T>(field: &'static str, message: &'static str) -> ksp_core_lib::Result<T> {
|
||||
return std::result::Result::Err(ksp_core_lib::Error::new(crate::ERROR_CODE_INVALID_RPC_PARAMETERS, message).with_context("field", field));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn invalid_subscribe_response<T>(field: &'static str, message: &'static str) -> ksp_core_lib::Result<T> {
|
||||
return std::result::Result::Err(ksp_core_lib::Error::new(crate::ERROR_CODE_INVALID_RESPONSE, message).with_context("grpc_update", field));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn commitment_to_wire(commitment: std::option::Option<crate::SolanaCommitment>) -> std::option::Option<i32> {
|
||||
return commitment.map(|value| {
|
||||
return match value {
|
||||
|
||||
Reference in New Issue
Block a user