Skip to content

Commit

Permalink
fix(sov-db): serialize SlotByNumber, EventByNumber as big-endian
Browse files Browse the repository at this point in the history
The big-endian fix for u64_wrapper! wasn't applied to all relevant types. I've
made the following changes:

* Renamed define_table_with_u64_wrapper_keys -> define_table_with_seek_key_codec
  to not be u64_wrapper! -specific.
* I replaced the u64_wrapper! specific logic inside said macro to use
* big-endian bincode instead, in preparation for using it for different and
  more complex types. Not yet used for anything other than u64_wrapper!.
* I removed the blanked implementation of SeekKeyEncoder for all KeyEncoder's,
  so that implementors have to opt-in, providing a fail-safe.

In the future we'll explore better type safety mechanisms.
  • Loading branch information
neysofu committed Jun 29, 2023
1 parent adacf22 commit ae4c3d8
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 22 deletions.
44 changes: 34 additions & 10 deletions full-node/db/sov-db/src/schema/tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@ use super::types::{
StoredTransaction, TxNumber,
};

use anyhow::Context;
use borsh::{maybestd, BorshDeserialize, BorshSerialize};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use jmt::{
storage::{Node, NodeKey},
Version,
};
use sov_rollup_interface::db::errors::CodecError;
use sov_rollup_interface::db::{errors::CodecError, SeekKeyEncoder};
use sov_rollup_interface::{
db::{KeyDecoder, KeyEncoder, ValueCodec},
stf::{Event, EventKey},
Expand Down Expand Up @@ -154,20 +153,39 @@ macro_rules! define_table_with_default_codec {
/// your key type is a `u64_wrapper!`. Borsh serializes integers as
/// little-endian, but RocksDB uses lexigographic ordering which is only
/// compatible with big-endian, so that's what we do here.
macro_rules! define_table_with_u64_wrapper_keys {
macro_rules! define_table_with_seek_key_codec {
($(#[$docs:meta])+ ($table_name:ident) $key:ty => $value:ty) => {
define_table_without_codec!($(#[$docs])+ ( $table_name ) $key => $value);

impl ::sov_rollup_interface::db::KeyEncoder<$table_name> for $key {
fn encode_key(&self) -> ::std::result::Result<::sov_rollup_interface::maybestd::vec::Vec<u8>, ::sov_rollup_interface::db::errors::CodecError> {
Ok(self.0.to_be_bytes().to_vec())
use ::anyhow::Context;
use ::bincode::Options;

let bincode_options = ::bincode::options()
.with_fixint_encoding()
.with_big_endian();

bincode_options.serialize(self).context("Failed to serialize key").map_err(Into::into)
}
}

impl ::sov_rollup_interface::db::KeyDecoder<$table_name> for $key {
fn decode_key(data: &[u8]) -> ::std::result::Result<Self, ::sov_rollup_interface::db::errors::CodecError> {
let be_bytes = data.try_into().context("Invalid key length (8 bytes expected)")?;
Ok(Self(u64::from_be_bytes(be_bytes)))
use ::anyhow::Context;
use ::bincode::Options;

let bincode_options = ::bincode::options()
.with_fixint_encoding()
.with_big_endian();

bincode_options.deserialize_from(&mut &data[..]).context("Failed to deserialize key").map_err(Into::into)
}
}

impl ::sov_rollup_interface::db::SeekKeyEncoder<$table_name> for $key {
fn encode_seek_key(&self) -> ::std::result::Result<::sov_rollup_interface::maybestd::vec::Vec<u8>, ::sov_rollup_interface::db::errors::CodecError> {
<Self as ::sov_rollup_interface::db::KeyEncoder<$table_name>>::encode_key(self)
}
}

Expand All @@ -176,7 +194,7 @@ macro_rules! define_table_with_u64_wrapper_keys {
}

// fn deser(target: &mut &[u8]) -> Result<Self, DeserializationError>;
define_table_with_default_codec!(
define_table_with_seek_key_codec!(
/// The primary source for slot data
(SlotByNumber) SlotNumber => StoredSlot
);
Expand All @@ -186,7 +204,7 @@ define_table_with_default_codec!(
(SlotByHash) DbHash => SlotNumber
);

define_table_with_u64_wrapper_keys!(
define_table_with_seek_key_codec!(
/// The primary source for batch data
(BatchByNumber) BatchNumber => StoredBatch
);
Expand All @@ -196,7 +214,7 @@ define_table_with_default_codec!(
(BatchByHash) DbHash => BatchNumber
);

define_table_with_u64_wrapper_keys!(
define_table_with_seek_key_codec!(
/// The primary source for transaction data
(TxByNumber) TxNumber => StoredTransaction
);
Expand All @@ -206,7 +224,7 @@ define_table_with_default_codec!(
(TxByHash) DbHash => TxNumber
);

define_table_with_default_codec!(
define_table_with_seek_key_codec!(
/// The primary store for event data
(EventByNumber) EventNumber => Event
);
Expand Down Expand Up @@ -262,6 +280,12 @@ impl<T: AsRef<[u8]> + PartialEq + core::fmt::Debug> KeyEncoder<JmtValues> for (T
}
}

impl<T: AsRef<[u8]> + PartialEq + core::fmt::Debug> SeekKeyEncoder<JmtValues> for (T, Version) {
fn encode_seek_key(&self) -> sov_rollup_interface::db::Result<Vec<u8>> {
self.encode_key()
}
}

impl KeyDecoder<JmtValues> for (StateKey, Version) {
fn decode_key(data: &[u8]) -> sov_rollup_interface::db::Result<Self> {
let mut cursor = maybestd::io::Cursor::new(data);
Expand Down
6 changes: 6 additions & 0 deletions full-node/db/sov-schema-db/src/iterator_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ impl KeyDecoder<TestSchema> for TestKey {
}
}

impl SeekKeyEncoder<TestSchema> for TestKey {
fn encode_seek_key(&self) -> sov_rollup_interface::db::Result<Vec<u8>> {
self.encode_key()
}
}

impl ValueCodec<TestSchema> for TestValue {
fn encode_value(&self) -> Result<Vec<u8>, CodecError> {
Ok(self.0.to_be_bytes().to_vec())
Expand Down
12 changes: 0 additions & 12 deletions rollup-interface/src/node/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,6 @@ pub trait SeekKeyEncoder<S: Schema + ?Sized>: Sized {
fn encode_seek_key(&self) -> Result<Vec<u8>>;
}

/// All keys can automatically be used as seek keys.
impl<S, K> SeekKeyEncoder<S> for K
where
S: Schema,
K: KeyEncoder<S>,
{
/// Delegates to [`KeyCodec::encode_key`].
fn encode_seek_key(&self) -> Result<Vec<u8>> {
<K as KeyEncoder<S>>::encode_key(self)
}
}

#[macro_export]
macro_rules! define_schema {
($schema_type:ident, $key_type:ty, $value_type:ty, $cf_name:expr) => {
Expand Down

0 comments on commit ae4c3d8

Please sign in to comment.