Skip to content

Commit 352f2db

Browse files
author
Drew Robinson
committed
Replace unmaintained bincode with binary-compatible wincode
This replaces the unmaintained bincode serialization library with wincode, which produces identical byte output while being actively maintained. Key changes: - Replace bincode dependency with wincode in all Cargo.toml files - Update Value enum derives from Serialize/Deserialize to also include SchemaWrite/SchemaRead (keeping both for compatibility) - Replace bincode::serialize() calls with wincode::serialize() - Replace bincode::deserialize() calls with wincode::deserialize() - Update error handling for wincode::WriteError and wincode::ReadError - Update protobuf documentation to note wincode (binary compatible with bincode) The wire protocol remains unchanged as wincode produces byte-for-byte identical output to bincode, maintaining compatibility with existing Go clients and other consumers of the RPC protocol.
1 parent b5dab26 commit 352f2db

11 files changed

Lines changed: 177 additions & 77 deletions

File tree

Cargo.lock

Lines changed: 134 additions & 49 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libsql-replication/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ cbc = "0.1.2"
2929

3030
[dev-dependencies]
3131
arbitrary = { version = "1.3.0", features = ["derive_arbitrary"] }
32-
bincode = "1.3.3"
32+
wincode = { version = "0.2", features = ["derive"] }
3333
tempfile = "3.8.0"
3434
prost-build = "0.12"
3535
tonic-build = "0.11"

libsql-replication/proto/proxy.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ message Description {
7171
}
7272

7373
message Value {
74-
/// bincode encoded Value
74+
/// wincode encoded Value (binary compatible with bincode)
7575
bytes data = 1;
7676
}
7777

libsql-server/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ async-trait = "0.1.58"
1818
axum = { version = "0.6.18", features = ["headers"] }
1919
axum-extra = { version = "0.7", features = ["json-lines", "query"] }
2020
base64 = "0.21.0"
21-
bincode = "1.3.3"
21+
wincode = { version = "0.2", features = ["derive"] }
2222
bottomless = { version = "0", path = "../bottomless", features = ["libsql_linked_statically"] }
2323
bytes = { version = "1.2.1", features = ["serde"] }
2424
bytesize = { version = "1.2.0", features = ["serde"] }

libsql-server/src/error.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,14 @@ impl From<tokio::sync::oneshot::error::RecvError> for Error {
244244
}
245245
}
246246

247-
impl From<bincode::Error> for Error {
248-
fn from(other: bincode::Error) -> Self {
247+
impl From<wincode::WriteError> for Error {
248+
fn from(other: wincode::WriteError) -> Self {
249+
Self::Internal(other.to_string())
250+
}
251+
}
252+
253+
impl From<wincode::ReadError> for Error {
254+
fn from(other: wincode::ReadError) -> Self {
249255
Self::Internal(other.to_string())
250256
}
251257
}

libsql-server/src/query.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ use anyhow::{anyhow, ensure, Context};
44
use rusqlite::types::{ToSqlOutput, ValueRef};
55
use rusqlite::ToSql;
66
use serde::{Deserialize, Serialize};
7+
use wincode::{SchemaWrite, SchemaRead};
78

89
use crate::query_analysis::Statement;
910

1011
/// Mirrors rusqlite::Value, but implement extra traits
11-
#[derive(Debug, Clone, Serialize, Deserialize)]
12+
#[derive(Debug, Clone, Serialize, Deserialize, SchemaWrite, SchemaRead)]
1213
#[cfg_attr(test, derive(arbitrary::Arbitrary))]
1314
pub enum Value {
1415
Null,

libsql-server/src/rpc/proxy.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ pub mod rpc {
9999
crate::query::Params::Named(params) => {
100100
let iter = params.into_iter().map(|(k, v)| -> Result<_, SqldError> {
101101
let v = Value {
102-
data: bincode::serialize(&v)?,
102+
data: wincode::serialize(&v)?,
103103
};
104104
Ok((k, v))
105105
});
@@ -111,7 +111,7 @@ pub mod rpc {
111111
.iter()
112112
.map(|v| {
113113
Ok(Value {
114-
data: bincode::serialize(&v)?,
114+
data: wincode::serialize(&v)?,
115115
})
116116
})
117117
.collect::<Result<Vec<_>, SqldError>>()?;
@@ -130,12 +130,12 @@ pub mod rpc {
130130
let params = pos
131131
.values
132132
.into_iter()
133-
.map(|v| bincode::deserialize(&v.data).map_err(|e| e.into()))
133+
.map(|v| wincode::deserialize(&v.data).map_err(|e| e.into()))
134134
.collect::<Result<Vec<_>, SqldError>>()?;
135135
Ok(Self::Positional(params))
136136
}
137137
query::Params::Named(named) => {
138-
let values = named.values.iter().map(|v| bincode::deserialize(&v.data));
138+
let values = named.values.iter().map(|v| wincode::deserialize(&v.data));
139139
let params = itertools::process_results(values, |values| {
140140
named.names.into_iter().zip(values).collect()
141141
})?;
@@ -455,7 +455,7 @@ impl QueryResultBuilder for ExecuteResultsBuilder {
455455
}
456456

457457
fn add_row_value(&mut self, v: ValueRef) -> Result<(), QueryResultBuilderError> {
458-
let data = bincode::serialize(
458+
let data = wincode::serialize(
459459
&crate::query::Value::try_from(v).map_err(QueryResultBuilderError::from_any)?,
460460
)
461461
.map_err(QueryResultBuilderError::from_any)?;

libsql/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ bitflags = { version = "2.4.0", optional = true }
2727
tower = { workspace = true, features = ["util"], optional = true }
2828
worker = { version = "0.6.7", optional = true }
2929

30-
bincode = { version = "1", optional = true }
30+
wincode = { version = "0.2", optional = true, features = ["derive"] }
3131
anyhow = { version = "1.0.71", optional = true }
3232
bytes = { version = "1.4.0", features = ["serde"], optional = true }
3333
uuid = { version = "1.4.0", features = ["v4", "serde"], optional = true }
@@ -83,7 +83,7 @@ replication = [
8383
"dep:http",
8484
"dep:tokio",
8585
"dep:anyhow",
86-
"dep:bincode",
86+
"dep:wincode",
8787
"dep:zerocopy",
8888
"dep:bytes",
8989
"dep:uuid",

libsql/src/errors.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ pub enum Error {
3131
Hrana(crate::BoxError), // Not in rusqlite
3232
#[error("Write delegation: `{0}`")]
3333
WriteDelegation(crate::BoxError), // Not in rusqlite
34-
#[error("bincode: `{0}`")]
35-
Bincode(crate::BoxError),
34+
#[error("wincode: `{0}`")]
35+
Wincode(crate::BoxError),
3636
#[error("invalid column index")]
3737
InvalidColumnIndex,
3838
#[error("invalid column type")]
@@ -112,8 +112,15 @@ pub fn sqlite_errmsg_to_string(errmsg: *const std::ffi::c_char) -> String {
112112
}
113113

114114
#[cfg(feature = "replication")]
115-
impl From<bincode::Error> for Error {
116-
fn from(e: bincode::Error) -> Self {
117-
Error::Bincode(e.into())
115+
impl From<wincode::WriteError> for Error {
116+
fn from(e: wincode::WriteError) -> Self {
117+
Error::Wincode(e.into())
118+
}
119+
}
120+
121+
#[cfg(feature = "replication")]
122+
impl From<wincode::ReadError> for Error {
123+
fn from(e: wincode::ReadError) -> Self {
124+
Error::Wincode(e.into())
118125
}
119126
}

libsql/src/params.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ impl From<Params> for libsql_replication::rpc::proxy::query::Params {
291291
Params::Positional(values) => {
292292
let values = values
293293
.iter()
294-
.map(|v| bincode::serialize(v).unwrap())
294+
.map(|v| wincode::serialize(v).unwrap())
295295
.map(|data| proxy::Value { data })
296296
.collect::<Vec<_>>();
297297
proxy::query::Params::Positional(proxy::Positional { values })
@@ -300,7 +300,7 @@ impl From<Params> for libsql_replication::rpc::proxy::query::Params {
300300
let (names, values) = values
301301
.into_iter()
302302
.map(|(name, value)| {
303-
let data = bincode::serialize(&value).unwrap();
303+
let data = wincode::serialize(&value).unwrap();
304304
let value = proxy::Value { data };
305305
(name, value)
306306
})

0 commit comments

Comments
 (0)