use core::fmt::Debug;
use std::cmp::min;
use borsh::{BorshDeserialize, BorshSerialize};
use bytes::Buf;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use crate::zk::ValidityCondition;
use crate::BasicAddress;
pub trait DaSpec: 'static + Debug + PartialEq + Eq {
type SlotHash: BlockHashTrait;
type BlockHeader: BlockHeaderTrait<Hash = Self::SlotHash>;
type BlobTransaction: BlobReaderTrait<Address = Self::Address>;
type Address: BasicAddress;
type ValidityCondition: ValidityCondition;
type InclusionMultiProof: Serialize + DeserializeOwned;
type CompletenessProof: Serialize + DeserializeOwned;
type ChainParams;
}
pub trait DaVerifier {
type Spec: DaSpec;
type Error: Debug;
fn new(params: <Self::Spec as DaSpec>::ChainParams) -> Self;
fn verify_relevant_tx_list(
&self,
block_header: &<Self::Spec as DaSpec>::BlockHeader,
txs: &[<Self::Spec as DaSpec>::BlobTransaction],
inclusion_proof: <Self::Spec as DaSpec>::InclusionMultiProof,
completeness_proof: <Self::Spec as DaSpec>::CompletenessProof,
) -> Result<<Self::Spec as DaSpec>::ValidityCondition, Self::Error>;
}
#[derive(Debug, Clone, Serialize, Deserialize, BorshDeserialize, BorshSerialize, PartialEq)]
pub struct CountedBufReader<B: Buf> {
inner: B,
accumulator: Vec<u8>,
}
impl<B: Buf> CountedBufReader<B> {
pub fn new(inner: B) -> Self {
let buf_size = inner.remaining();
CountedBufReader {
inner,
accumulator: Vec::with_capacity(buf_size),
}
}
pub fn advance(&mut self, num_bytes: usize) {
let requested = num_bytes;
let remaining = self.inner.remaining();
if remaining == 0 {
return;
}
let num_to_read = min(remaining, requested);
self.accumulator
.resize(self.accumulator.len() + num_to_read, 0);
let accumulator_len = self.accumulator.len();
self.inner
.copy_to_slice(self.accumulator[accumulator_len - num_to_read..].as_mut());
}
pub fn accumulator(&self) -> &[u8] {
&self.accumulator
}
pub fn total_len(&self) -> usize {
self.inner.remaining() + self.accumulator.len()
}
}
pub trait BlobReaderTrait: Serialize + DeserializeOwned + Send + Sync + 'static {
type Address: BasicAddress;
fn sender(&self) -> Self::Address;
fn hash(&self) -> [u8; 32];
fn verified_data(&self) -> &[u8];
fn total_len(&self) -> usize;
#[cfg(feature = "native")]
fn advance(&mut self, num_bytes: usize) -> &[u8];
#[cfg(feature = "native")]
fn full_data(&mut self) -> &[u8] {
self.advance(self.total_len())
}
}
pub trait BlockHashTrait:
Serialize + DeserializeOwned + PartialEq + Debug + Send + Sync + Clone + Eq + Into<[u8; 32]>
{
}
pub trait BlockHeaderTrait: PartialEq + Debug + Clone + Serialize + DeserializeOwned {
type Hash: Clone;
fn prev_hash(&self) -> Self::Hash;
fn hash(&self) -> Self::Hash;
fn height(&self) -> u64;
fn time(&self) -> Time;
}
#[derive(
Serialize, Deserialize, Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize, Default,
)]
pub struct Time {
secs: i64,
nanos: u32,
}
#[derive(Debug, Error)]
#[error("Only intervals less than one second may be represented as nanoseconds")]
pub struct ErrTooManyNanos;
pub struct NanoSeconds(u32);
impl NanoSeconds {
pub fn new(nanos: u32) -> Result<Self, ErrTooManyNanos> {
if nanos < NANOS_PER_SECOND {
Ok(NanoSeconds(nanos))
} else {
Err(ErrTooManyNanos)
}
}
}
const NANOS_PER_SECOND: u32 = 1_000_000_000;
impl Time {
pub const fn new(secs: i64, nanos: NanoSeconds) -> Self {
Time {
secs,
nanos: nanos.0,
}
}
pub const fn from_secs(secs: i64) -> Self {
Time { secs, nanos: 0 }
}
pub fn secs(&self) -> i64 {
self.secs
}
pub fn subsec_nanos(&self) -> u32 {
self.nanos
}
}