From 03e911ecd51f514baf07872bc3ac261bec610723 Mon Sep 17 00:00:00 2001 From: Daniil Polyakov Date: Wed, 3 Dec 2025 18:33:40 +0300 Subject: [PATCH] feat: apply base64 encoding for large binary data transfer --- common/Cargo.toml | 1 + common/src/rpc_primitives/requests.rs | 61 +++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/common/Cargo.toml b/common/Cargo.toml index 999c731..920ad2a 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -15,6 +15,7 @@ log.workspace = true hex.workspace = true nssa-core = { path = "../nssa/core", features = ["host"] } borsh.workspace = true +base64.workspace = true [dependencies.nssa] path = "../nssa" diff --git a/common/src/rpc_primitives/requests.rs b/common/src/rpc_primitives/requests.rs index f87dc69..e0c6d31 100644 --- a/common/src/rpc_primitives/requests.rs +++ b/common/src/rpc_primitives/requests.rs @@ -20,6 +20,7 @@ pub struct RegisterAccountRequest { #[derive(Serialize, Deserialize, Debug)] pub struct SendTxRequest { + #[serde(with = "base64_deser")] pub transaction: Vec, } @@ -105,14 +106,74 @@ pub struct SendTxResponse { #[derive(Serialize, Deserialize, Debug)] pub struct GetBlockDataResponse { + #[serde(with = "base64_deser")] pub block: Vec, } #[derive(Serialize, Deserialize, Debug)] pub struct GetBlockRangeDataResponse { + #[serde(with = "base64_deser::vec")] pub blocks: Vec>, } +mod base64_deser { + use base64::{Engine as _, engine::general_purpose}; + use serde::{self, Deserialize, Deserializer, Serializer, ser::SerializeSeq as _}; + + pub fn serialize(bytes: &[u8], serializer: S) -> Result + where + S: Serializer, + { + let base64_string = general_purpose::STANDARD.encode(bytes); + serializer.serialize_str(&base64_string) + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let base64_string: String = Deserialize::deserialize(deserializer)?; + general_purpose::STANDARD + .decode(&base64_string) + .map_err(serde::de::Error::custom) + } + + pub mod vec { + use super::*; + + pub fn serialize(bytes: &[Vec], serializer: S) -> Result + where + S: Serializer, + { + let base64_strings: Vec = bytes + .iter() + .map(|b| general_purpose::STANDARD.encode(b)) + .collect(); + let mut seq = serializer.serialize_seq(Some(base64_strings.len()))?; + for s in base64_strings { + seq.serialize_element(&s)?; + } + seq.end() + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result>, D::Error> + where + D: Deserializer<'de>, + { + let base64_strings: Vec = Deserialize::deserialize(deserializer)?; + let bytes_vec: Result>, D::Error> = base64_strings + .into_iter() + .map(|s| { + general_purpose::STANDARD + .decode(&s) + .map_err(serde::de::Error::custom) + }) + .collect(); + bytes_vec + } + } +} + #[derive(Serialize, Deserialize, Debug)] pub struct GetGenesisIdResponse { pub genesis_id: u64,