#![deny(missing_docs)]
#![doc = include_str!("../README.md")]
mod capabilities;
#[cfg(feature = "native")]
mod query;
#[cfg(feature = "native")]
pub use query::{BlobStorageRpcImpl, BlobStorageRpcServer, Response};
use sov_chain_state::TransitionHeight;
use sov_modules_api::{Module, ModuleInfo};
use sov_state::{StateMap, WorkingSet};
const DEFERRED_SLOTS_COUNT: u64 = 1;
#[cfg_attr(feature = "native", derive(sov_modules_api::ModuleCallJsonSchema))]
#[derive(Clone, ModuleInfo)]
pub struct BlobStorage<C: sov_modules_api::Context, Da: sov_modules_api::DaSpec> {
#[address]
pub(crate) address: C::Address,
#[state]
pub(crate) blobs: StateMap<u64, Vec<Vec<u8>>>,
#[module]
pub(crate) sequencer_registry: sov_sequencer_registry::SequencerRegistry<C>,
#[module]
chain_state: sov_chain_state::ChainState<C, Da>,
}
impl<C: sov_modules_api::Context, Da: sov_modules_api::DaSpec> BlobStorage<C, Da> {
pub fn store_blobs(
&self,
slot_height: TransitionHeight,
blobs: &[&Da::BlobTransaction],
working_set: &mut WorkingSet<C::Storage>,
) -> anyhow::Result<()> {
let mut raw_blobs: Vec<Vec<u8>> = Vec::with_capacity(blobs.len());
for blob in blobs {
raw_blobs.push(bincode::serialize(blob)?);
}
self.blobs.set(&slot_height, &raw_blobs, working_set);
Ok(())
}
pub fn take_blobs_for_slot_height(
&self,
slot_height: TransitionHeight,
working_set: &mut WorkingSet<C::Storage>,
) -> Vec<Da::BlobTransaction> {
self.blobs
.remove(&slot_height, working_set)
.unwrap_or_default()
.iter()
.map(|b| bincode::deserialize(b).expect("malformed blob was stored previously"))
.collect()
}
pub(crate) fn get_preferred_sequencer(
&self,
working_set: &mut WorkingSet<C::Storage>,
) -> Option<Vec<u8>> {
self.sequencer_registry.get_preferred_sequencer(working_set)
}
pub(crate) fn get_current_slot_height(
&self,
working_set: &mut WorkingSet<C::Storage>,
) -> TransitionHeight {
self.chain_state.get_slot_height(working_set)
}
pub(crate) fn get_deferred_slots_count(
&self,
_working_set: &mut WorkingSet<C::Storage>,
) -> u64 {
DEFERRED_SLOTS_COUNT
}
}
impl<C: sov_modules_api::Context, Da: sov_modules_api::DaSpec> Module for BlobStorage<C, Da> {
type Context = C;
type Config = ();
type CallMessage = sov_modules_api::NonInstantiable;
}