diff --git a/lite-rpc/src/bridge.rs b/lite-rpc/src/bridge.rs index 26fb5ce7..95e99f80 100644 --- a/lite-rpc/src/bridge.rs +++ b/lite-rpc/src/bridge.rs @@ -3,10 +3,11 @@ use jsonrpsee::core::RpcResult; use prometheus::{opts, register_int_counter, IntCounter}; use solana_account_decoder::UiAccount; use solana_lite_rpc_accounts::account_service::AccountService; +use solana_lite_rpc_core::encoding::{BASE58, BASE64}; use solana_lite_rpc_prioritization_fees::account_prio_service::AccountPrioService; use solana_lite_rpc_prioritization_fees::prioritization_fee_calculation_method::PrioritizationFeeCalculationMethod; use solana_rpc_client::nonblocking::rpc_client::RpcClient; -use solana_rpc_client_api::config::RpcAccountInfoConfig; +use solana_rpc_client_api::config::{RpcAccountInfoConfig, RpcSendTransactionConfig}; use solana_rpc_client_api::response::{OptionalContext, RpcKeyedAccount}; use solana_rpc_client_api::{ config::{ @@ -21,28 +22,27 @@ use solana_rpc_client_api::{ }, }; use solana_sdk::epoch_info::EpochInfo; +use solana_sdk::packet::PACKET_DATA_SIZE; use solana_sdk::signature::Signature; use solana_sdk::{commitment_config::CommitmentConfig, pubkey::Pubkey, slot_history::Slot}; -use solana_transaction_status::{TransactionStatus, UiConfirmedBlock}; +use solana_transaction_status::{ + TransactionBinaryEncoding, TransactionStatus, UiConfirmedBlock, UiTransactionEncoding, +}; use std::collections::HashMap; use std::str::FromStr; use std::sync::Arc; use solana_lite_rpc_blockstore::history::History; use solana_lite_rpc_core::solana_utils::hash_from_str; -use solana_lite_rpc_core::{ - encoding, - stores::{block_information_store::BlockInformation, data_cache::DataCache}, +use solana_lite_rpc_core::stores::{ + block_information_store::BlockInformation, data_cache::DataCache, }; use solana_lite_rpc_services::{ transaction_service::TransactionService, tx_sender::TXS_IN_CHANNEL, }; use crate::rpc_errors::RpcErrors; -use crate::{ - configs::{IsBlockHashValidConfig, SendTransactionConfig}, - rpc::LiteRpcServer, -}; +use crate::{configs::IsBlockHashValidConfig, rpc::LiteRpcServer}; use solana_lite_rpc_prioritization_fees::rpc_data::{AccountPrioFeesStats, PrioFeesStats}; use solana_lite_rpc_prioritization_fees::PrioFeesService; @@ -347,7 +347,7 @@ impl LiteRpcServer for LiteBridge { async fn send_transaction( &self, tx: String, - send_transaction_config: Option, + send_transaction_config: Option, ) -> RpcResult { RPC_SEND_TX.inc(); @@ -355,29 +355,51 @@ impl LiteRpcServer for LiteBridge { const MAX_BASE58_SIZE: usize = 1683; const MAX_BASE64_SIZE: usize = 1644; - let SendTransactionConfig { + let RpcSendTransactionConfig { encoding, max_retries, + .. } = send_transaction_config.unwrap_or_default(); + let encoding = encoding.unwrap_or(UiTransactionEncoding::Base58); let expected_size = match encoding { - encoding::BinaryEncoding::Base58 => MAX_BASE58_SIZE, - encoding::BinaryEncoding::Base64 => MAX_BASE64_SIZE, + UiTransactionEncoding::Base58 => MAX_BASE58_SIZE, + UiTransactionEncoding::Base64 => MAX_BASE64_SIZE, + _ => usize::MAX, }; if tx.len() > expected_size { return Err(jsonrpsee::types::error::ErrorCode::OversizedRequest.into()); } - let raw_tx = match encoding.decode(tx) { - Ok(raw_tx) => raw_tx, - Err(_) => { - return Err(jsonrpsee::types::error::ErrorCode::InvalidParams.into()); + let binary_encoding = encoding + .into_binary_encoding() + .ok_or(jsonrpsee::types::error::ErrorCode::InvalidParams)?; + + let wire_output = match binary_encoding { + TransactionBinaryEncoding::Base58 => { + if tx.len() > MAX_BASE58_SIZE { + return Err(jsonrpsee::types::error::ErrorCode::OversizedRequest.into()); + } + BASE58 + .decode(tx) + .map_err(|_| jsonrpsee::types::error::ErrorCode::InvalidParams)? + } + TransactionBinaryEncoding::Base64 => { + if tx.len() > MAX_BASE64_SIZE { + return Err(jsonrpsee::types::error::ErrorCode::OversizedRequest.into()); + } + BASE64 + .decode(tx) + .map_err(|_| jsonrpsee::types::error::ErrorCode::InvalidParams)? } }; - + if wire_output.len() > PACKET_DATA_SIZE { + return Err(jsonrpsee::types::error::ErrorCode::OversizedRequest.into()); + } + let max_retries = max_retries.map(|x| x as u16); match self .transaction_service - .send_wire_transaction(raw_tx, max_retries) + .send_wire_transaction(wire_output, max_retries) .await { Ok(sig) => { diff --git a/lite-rpc/src/bridge_pubsub.rs b/lite-rpc/src/bridge_pubsub.rs index bb37e8d1..93923cfd 100644 --- a/lite-rpc/src/bridge_pubsub.rs +++ b/lite-rpc/src/bridge_pubsub.rs @@ -141,6 +141,7 @@ impl LiteRpcPubSubServer for LitePubSubBridge { config: RpcSignatureSubscribeConfig, ) -> SubscriptionResult { RPC_SIGNATURE_SUBSCRIBE.inc(); + log::info!("subscribing to signature : {}", signature.to_string()); let sink = pending.accept().await?; let jsonrpsee_sink = JsonRpseeSubscriptionHandlerSink::new(sink); diff --git a/lite-rpc/src/rpc.rs b/lite-rpc/src/rpc.rs index 5be8ea34..6c1b1425 100644 --- a/lite-rpc/src/rpc.rs +++ b/lite-rpc/src/rpc.rs @@ -1,4 +1,4 @@ -use crate::configs::{IsBlockHashValidConfig, SendTransactionConfig}; +use crate::configs::IsBlockHashValidConfig; use jsonrpsee::core::RpcResult; use jsonrpsee::proc_macros::rpc; use solana_account_decoder::UiAccount; @@ -7,7 +7,7 @@ use solana_lite_rpc_prioritization_fees::rpc_data::{AccountPrioFeesStats, PrioFe use solana_rpc_client_api::config::{ RpcAccountInfoConfig, RpcBlocksConfigWrapper, RpcContextConfig, RpcGetVoteAccountsConfig, RpcLeaderScheduleConfig, RpcProgramAccountsConfig, RpcRequestAirdropConfig, - RpcSignatureStatusConfig, RpcSignaturesForAddressConfig, + RpcSendTransactionConfig, RpcSignatureStatusConfig, RpcSignaturesForAddressConfig, }; use solana_rpc_client_api::response::{ OptionalContext, Response as RpcResponse, RpcBlockhash, @@ -133,7 +133,7 @@ pub trait LiteRpc { async fn send_transaction( &self, tx: String, - send_transaction_config: Option, + send_transaction_config: Option, ) -> RpcResult; // *********************** diff --git a/lite-rpc/src/rpc_pubsub.rs b/lite-rpc/src/rpc_pubsub.rs index 1cdf0f38..cb450b68 100644 --- a/lite-rpc/src/rpc_pubsub.rs +++ b/lite-rpc/src/rpc_pubsub.rs @@ -45,7 +45,7 @@ pub trait LiteRpcPubSub { ) -> SubscriptionResult; // WARN: enable_received_notification: bool is ignored - #[subscription(name = "signatureSubscribe" => "signatureNotification", unsubscribe="signatureUnsubscribe", item=RpcResponse)] + #[subscription(name = "signatureSubscribe" => "signatureNotification", unsubscribe="signatureUnsubscribe", item=RpcResponse)] async fn signature_subscribe( &self, signature: Signature, diff --git a/quic-forward-proxy-integration-test/Cargo.toml b/quic-forward-proxy-integration-test/Cargo.toml index 59d57a42..ffbf807c 100644 --- a/quic-forward-proxy-integration-test/Cargo.toml +++ b/quic-forward-proxy-integration-test/Cargo.toml @@ -18,7 +18,7 @@ solana-sdk = { workspace = true } solana-streamer = { workspace = true } solana-transaction-status = { workspace = true } solana-net-utils = { workspace = true } -rustls = { workspace = true, features = ["dangerous_configuration"]} +rustls = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } bincode = { workspace = true } diff --git a/stake_vote/src/bootstrap.rs b/stake_vote/src/bootstrap.rs index 4b0f3c07..cff3ca5c 100644 --- a/stake_vote/src/bootstrap.rs +++ b/stake_vote/src/bootstrap.rs @@ -17,7 +17,6 @@ use solana_client::rpc_response::RpcVoteAccountStatus; use solana_lite_rpc_core::stores::data_cache::DataCache; use solana_lite_rpc_core::structures::leaderschedule::CalculatedSchedule; use solana_lite_rpc_core::structures::leaderschedule::LeaderScheduleData; -use solana_program::slot_history::Slot; use solana_sdk::account::Account; use solana_sdk::commitment_config::CommitmentConfig; use solana_sdk::epoch_info::EpochInfo; diff --git a/tests/client.test.ts b/tests/client.test.ts index cfbae8e8..8ffeb513 100644 --- a/tests/client.test.ts +++ b/tests/client.test.ts @@ -6,7 +6,7 @@ import * as crypto from "crypto"; jest.setTimeout(60000); const MEMO_PROGRAM_ID = new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"); -const connection = new Connection('http://0.0.0.0:8899', 'confirmed'); +const connection = new Connection('http://0.0.0.0:8890', 'finalized'); const keypair_file = fs.readFileSync(`${os.homedir}/.config/solana/id.json`, 'utf-8'); const payer = Keypair.fromSecretKey(Uint8Array.from(JSON.parse(keypair_file))); @@ -27,16 +27,14 @@ function createTransaction(): Transaction { test('send and confirm transaction BlockheightBasedTransactionConfirmationStrategy', async () => { const tx = createTransaction(); const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash(); - const signature = await connection.sendTransaction(tx, [payer]); + console.log(`https://explorer.solana.com/tx/${signature}`); await connection.confirmTransaction({ blockhash, lastValidBlockHeight, signature, abortSignal: undefined }); - - console.log(`https://explorer.solana.com/tx/${signature}`) }); test('send and confirm transaction', async () => {