2023-08-24 19:06:22 -04:00
|
|
|
use scale::Encode;
|
|
|
|
|
use serai_client::primitives::{NetworkId, BlockHash};
|
|
|
|
|
|
2023-04-23 04:31:00 -04:00
|
|
|
pub use serai_db::*;
|
|
|
|
|
|
|
|
|
|
use crate::tributary::TributarySpec;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
2023-04-26 00:10:06 -04:00
|
|
|
pub struct MainDb<'a, D: Db>(&'a mut D);
|
|
|
|
|
impl<'a, D: Db> MainDb<'a, D> {
|
|
|
|
|
pub fn new(db: &'a mut D) -> Self {
|
2023-04-23 04:31:00 -04:00
|
|
|
Self(db)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main_key(dst: &'static [u8], key: impl AsRef<[u8]>) -> Vec<u8> {
|
|
|
|
|
D::key(b"MAIN", dst, key)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn acive_tributaries_key() -> Vec<u8> {
|
|
|
|
|
Self::main_key(b"active_tributaries", [])
|
|
|
|
|
}
|
|
|
|
|
pub fn active_tributaries(&self) -> (Vec<u8>, Vec<TributarySpec>) {
|
|
|
|
|
let bytes = self.0.get(Self::acive_tributaries_key()).unwrap_or(vec![]);
|
|
|
|
|
let mut bytes_ref: &[u8] = bytes.as_ref();
|
|
|
|
|
|
|
|
|
|
let mut tributaries = vec![];
|
|
|
|
|
while !bytes_ref.is_empty() {
|
|
|
|
|
tributaries.push(TributarySpec::read(&mut bytes_ref).unwrap());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(bytes, tributaries)
|
|
|
|
|
}
|
|
|
|
|
pub fn add_active_tributary(&mut self, spec: &TributarySpec) {
|
|
|
|
|
let key = Self::acive_tributaries_key();
|
|
|
|
|
let (mut existing_bytes, existing) = self.active_tributaries();
|
|
|
|
|
for tributary in &existing {
|
|
|
|
|
if tributary == spec {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
spec.write(&mut existing_bytes).unwrap();
|
|
|
|
|
let mut txn = self.0.txn();
|
|
|
|
|
txn.put(key, existing_bytes);
|
|
|
|
|
txn.commit();
|
|
|
|
|
}
|
2023-05-08 22:20:51 -04:00
|
|
|
|
2023-08-24 19:06:22 -04:00
|
|
|
fn batches_in_block_key(network: NetworkId, block: [u8; 32]) -> Vec<u8> {
|
|
|
|
|
Self::main_key(b"batches_in_block", (network, block).encode())
|
|
|
|
|
}
|
|
|
|
|
pub fn batches_in_block<G: Get>(
|
|
|
|
|
getter: &G,
|
|
|
|
|
network: NetworkId,
|
|
|
|
|
block: [u8; 32],
|
|
|
|
|
) -> Vec<[u8; 32]> {
|
|
|
|
|
getter
|
|
|
|
|
.get(Self::batches_in_block_key(network, block))
|
|
|
|
|
.expect("asking for batches in block for block without batches")
|
|
|
|
|
.chunks(32)
|
|
|
|
|
.map(|id| id.try_into().unwrap())
|
|
|
|
|
.collect()
|
|
|
|
|
}
|
|
|
|
|
pub fn add_batch_to_block(
|
|
|
|
|
txn: &mut D::Transaction<'_>,
|
|
|
|
|
network: NetworkId,
|
|
|
|
|
block: BlockHash,
|
|
|
|
|
id: [u8; 32],
|
|
|
|
|
) {
|
|
|
|
|
let key = Self::batches_in_block_key(network, block.0);
|
|
|
|
|
let Some(mut existing) = txn.get(&key) else {
|
2023-08-24 21:55:59 -04:00
|
|
|
txn.put(&key, id);
|
2023-08-24 19:06:22 -04:00
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if existing.chunks(32).any(|existing_id| existing_id == id) {
|
|
|
|
|
// TODO: Is this an invariant?
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-24 21:55:59 -04:00
|
|
|
existing.extend(id);
|
2023-08-24 19:06:22 -04:00
|
|
|
txn.put(&key, existing);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 22:20:51 -04:00
|
|
|
fn first_preprocess_key(id: [u8; 32]) -> Vec<u8> {
|
|
|
|
|
Self::main_key(b"first_preprocess", id)
|
|
|
|
|
}
|
|
|
|
|
pub fn save_first_preprocess(txn: &mut D::Transaction<'_>, id: [u8; 32], preprocess: Vec<u8>) {
|
|
|
|
|
let key = Self::first_preprocess_key(id);
|
|
|
|
|
if let Some(existing) = txn.get(&key) {
|
|
|
|
|
assert_eq!(existing, preprocess, "saved a distinct first preprocess");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
txn.put(key, preprocess);
|
|
|
|
|
}
|
|
|
|
|
pub fn first_preprocess<G: Get>(getter: &G, id: [u8; 32]) -> Vec<u8> {
|
|
|
|
|
getter.get(Self::first_preprocess_key(id)).expect("asked for first preprocess we never saved")
|
|
|
|
|
}
|
2023-04-23 04:31:00 -04:00
|
|
|
}
|