use std::sync::Arc;
use borsh::{BorshDeserialize, BorshSerialize};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use sov_rollup_interface::rpc::{BatchResponse, TxIdentifier, TxResponse};
use sov_rollup_interface::stf::{Event, EventKey, TransactionReceipt};
#[derive(
Clone, PartialEq, PartialOrd, Eq, Ord, Debug, Default, BorshDeserialize, BorshSerialize,
)]
#[cfg_attr(feature = "arbitrary", derive(proptest_derive::Arbitrary))]
pub struct DbBytes(Arc<Vec<u8>>);
impl DbBytes {
pub fn new(contents: Vec<u8>) -> Self {
Self(Arc::new(contents))
}
}
impl From<Vec<u8>> for DbBytes {
fn from(value: Vec<u8>) -> Self {
Self(Arc::new(value))
}
}
impl AsRef<[u8]> for DbBytes {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
pub type AccessoryKey = Vec<u8>;
pub type AccessoryStateValue = Option<Vec<u8>>;
pub type DbHash = [u8; 32];
pub type JmtValue = Option<Vec<u8>>;
pub(crate) type StateKey = Vec<u8>;
#[derive(Debug, PartialEq, BorshDeserialize, BorshSerialize)]
#[cfg_attr(feature = "arbitrary", derive(proptest_derive::Arbitrary))]
pub struct StoredSlot {
pub hash: DbHash,
pub extra_data: DbBytes,
pub batches: std::ops::Range<BatchNumber>,
}
#[derive(Debug, PartialEq, BorshDeserialize, BorshSerialize)]
#[cfg_attr(feature = "arbitrary", derive(proptest_derive::Arbitrary))]
pub struct StoredBatch {
pub hash: DbHash,
pub txs: std::ops::Range<TxNumber>,
pub custom_receipt: DbBytes,
}
impl<B: DeserializeOwned, T> TryFrom<StoredBatch> for BatchResponse<B, T> {
type Error = anyhow::Error;
fn try_from(value: StoredBatch) -> Result<Self, Self::Error> {
Ok(Self {
hash: value.hash,
custom_receipt: bincode::deserialize(&value.custom_receipt.0)?,
tx_range: value.txs.start.into()..value.txs.end.into(),
txs: None,
})
}
}
#[derive(Debug, PartialEq, BorshSerialize, BorshDeserialize, Clone)]
pub struct StoredTransaction {
pub hash: DbHash,
pub events: std::ops::Range<EventNumber>,
pub body: Option<Vec<u8>>,
pub custom_receipt: DbBytes,
}
impl<R: DeserializeOwned> TryFrom<StoredTransaction> for TxResponse<R> {
type Error = anyhow::Error;
fn try_from(value: StoredTransaction) -> Result<Self, Self::Error> {
Ok(Self {
hash: value.hash,
event_range: value.events.start.into()..value.events.end.into(),
body: value.body,
custom_receipt: bincode::deserialize(&value.custom_receipt.0)?,
})
}
}
pub fn split_tx_for_storage<R: Serialize>(
tx: TransactionReceipt<R>,
event_offset: u64,
) -> (StoredTransaction, Vec<Event>) {
let event_range = EventNumber(event_offset)..EventNumber(event_offset + tx.events.len() as u64);
let tx_for_storage = StoredTransaction {
hash: tx.tx_hash,
events: event_range,
body: tx.body_to_save,
custom_receipt: DbBytes::new(
bincode::serialize(&tx.receipt).expect("Serialization to vec is infallible"),
),
};
(tx_for_storage, tx.events)
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub enum EventIdentifier {
TxIdAndIndex((TxIdentifier, u64)),
TxIdAndKey((TxIdentifier, EventKey)),
Number(EventNumber),
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub enum EventGroupIdentifier {
TxId(TxIdentifier),
Key(Vec<u8>),
}
macro_rules! u64_wrapper {
($name:ident) => {
#[derive(
Clone,
Copy,
::core::fmt::Debug,
Default,
PartialEq,
Eq,
PartialOrd,
Ord,
::borsh::BorshDeserialize,
::borsh::BorshSerialize,
::serde::Serialize,
::serde::Deserialize,
)]
#[cfg_attr(feature = "arbitrary", derive(proptest_derive::Arbitrary))]
pub struct $name(pub u64);
impl From<$name> for u64 {
fn from(value: $name) -> Self {
value.0
}
}
#[cfg(feature = "arbitrary")]
impl<'a> ::arbitrary::Arbitrary<'a> for $name {
fn arbitrary(u: &mut ::arbitrary::Unstructured<'a>) -> ::arbitrary::Result<Self> {
u.arbitrary().map($name)
}
}
};
}
u64_wrapper!(SlotNumber);
u64_wrapper!(BatchNumber);
u64_wrapper!(TxNumber);
u64_wrapper!(EventNumber);
#[cfg(feature = "arbitrary")]
pub mod arbitrary {
use super::*;
impl<'a> ::arbitrary::Arbitrary<'a> for DbBytes {
fn arbitrary(u: &mut ::arbitrary::Unstructured<'a>) -> ::arbitrary::Result<Self> {
u.arbitrary().map(DbBytes::new)
}
}
impl<'a> ::arbitrary::Arbitrary<'a> for StoredTransaction {
fn arbitrary(u: &mut ::arbitrary::Unstructured<'a>) -> ::arbitrary::Result<Self> {
Ok(StoredTransaction {
hash: u.arbitrary()?,
events: u.arbitrary()?,
body: u.arbitrary()?,
custom_receipt: u.arbitrary()?,
})
}
}
impl<'a> ::arbitrary::Arbitrary<'a> for StoredBatch {
fn arbitrary(u: &mut ::arbitrary::Unstructured<'a>) -> ::arbitrary::Result<Self> {
Ok(StoredBatch {
hash: u.arbitrary()?,
txs: u.arbitrary()?,
custom_receipt: u.arbitrary()?,
})
}
}
impl<'a> ::arbitrary::Arbitrary<'a> for StoredSlot {
fn arbitrary(u: &mut ::arbitrary::Unstructured<'a>) -> ::arbitrary::Result<Self> {
Ok(StoredSlot {
hash: u.arbitrary()?,
extra_data: u.arbitrary()?,
batches: u.arbitrary()?,
})
}
}
}