#![forbid(clippy::little_endian_bytes)]
use std::{
fmt::{Debug, Display},
hash::Hash,
};
use ark_serialize::SerializationError;
use bitvec::prelude::*;
use committable::Committable;
use jf_vid::VidScheme;
use primitive_types::U256;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use tagged_base64::{TaggedBase64, Tb64Error};
use super::EncodeBytes;
use crate::{
bundle::Bundle, traits::node_implementation::NodeType, utils::BuilderCommitment,
vid::VidSchemeType,
};
pub trait StakeTableEntryType<K> {
fn stake(&self) -> U256;
fn public_key(&self) -> K;
}
pub trait PrivateSignatureKey:
Send + Sync + Sized + Clone + Debug + Eq + Hash + for<'a> TryFrom<&'a TaggedBase64>
{
fn to_bytes(&self) -> Vec<u8>;
fn from_bytes(bytes: &[u8]) -> anyhow::Result<Self>;
fn to_tagged_base64(&self) -> Result<TaggedBase64, Tb64Error>;
}
pub trait SignatureKey:
Send
+ Sync
+ Clone
+ Sized
+ Debug
+ Hash
+ Serialize
+ for<'a> Deserialize<'a>
+ PartialEq
+ Eq
+ PartialOrd
+ Ord
+ Display
+ for<'a> TryFrom<&'a TaggedBase64>
+ Into<TaggedBase64>
{
type PrivateKey: PrivateSignatureKey;
type StakeTableEntry: StakeTableEntryType<Self>
+ Send
+ Sync
+ Sized
+ Clone
+ Debug
+ Hash
+ Eq
+ Serialize
+ for<'a> Deserialize<'a>;
type QcParams: Send + Sync + Sized + Clone + Debug + Hash;
type PureAssembledSignatureType: Send
+ Sync
+ Sized
+ Clone
+ Debug
+ Hash
+ PartialEq
+ Eq
+ Serialize
+ for<'a> Deserialize<'a>
+ Into<TaggedBase64>
+ for<'a> TryFrom<&'a TaggedBase64>;
type QcType: Send
+ Sync
+ Sized
+ Clone
+ Debug
+ Hash
+ PartialEq
+ Eq
+ Serialize
+ for<'a> Deserialize<'a>;
type SignError: std::error::Error + Send + Sync;
fn validate(&self, signature: &Self::PureAssembledSignatureType, data: &[u8]) -> bool;
fn sign(
private_key: &Self::PrivateKey,
data: &[u8],
) -> Result<Self::PureAssembledSignatureType, Self::SignError>;
fn from_private(private_key: &Self::PrivateKey) -> Self;
fn to_bytes(&self) -> Vec<u8>;
fn from_bytes(bytes: &[u8]) -> Result<Self, SerializationError>;
fn generated_from_seed_indexed(seed: [u8; 32], index: u64) -> (Self, Self::PrivateKey);
fn stake_table_entry(&self, stake: u64) -> Self::StakeTableEntry;
fn public_key(entry: &Self::StakeTableEntry) -> Self;
fn public_parameter(
stake_entries: Vec<Self::StakeTableEntry>,
threshold: U256,
) -> Self::QcParams;
fn check(real_qc_pp: &Self::QcParams, data: &[u8], qc: &Self::QcType) -> bool;
fn sig_proof(signature: &Self::QcType) -> (Self::PureAssembledSignatureType, BitVec);
fn assemble(
real_qc_pp: &Self::QcParams,
signers: &BitSlice,
sigs: &[Self::PureAssembledSignatureType],
) -> Self::QcType;
#[must_use]
fn genesis_proposer_pk() -> Self;
}
pub trait BuilderSignatureKey:
Send
+ Sync
+ Clone
+ Sized
+ Debug
+ Hash
+ Serialize
+ DeserializeOwned
+ PartialEq
+ Eq
+ PartialOrd
+ Ord
+ Display
{
type BuilderPrivateKey: PrivateSignatureKey;
type BuilderSignature: Send
+ Sync
+ Sized
+ Clone
+ Debug
+ Eq
+ Serialize
+ for<'a> Deserialize<'a>
+ Hash;
type SignError: std::error::Error + Send + Sync;
fn validate_builder_signature(&self, signature: &Self::BuilderSignature, data: &[u8]) -> bool;
fn validate_fee_signature<Metadata: EncodeBytes>(
&self,
signature: &Self::BuilderSignature,
fee_amount: u64,
metadata: &Metadata,
vid_commitment: &<VidSchemeType as VidScheme>::Commit,
) -> bool {
self.validate_builder_signature(
signature,
&aggregate_fee_data(fee_amount, metadata, vid_commitment),
)
}
fn validate_sequencing_fee_signature_marketplace(
&self,
signature: &Self::BuilderSignature,
fee_amount: u64,
view_number: u64,
) -> bool {
self.validate_builder_signature(
signature,
&aggregate_fee_data_marketplace(fee_amount, view_number),
)
}
fn validate_bundle_signature<TYPES: NodeType<BuilderSignatureKey = Self>>(
&self,
bundle: Bundle<TYPES>,
) -> bool where {
let commitments = bundle
.transactions
.iter()
.flat_map(|txn| <[u8; 32]>::from(txn.commit()))
.collect::<Vec<u8>>();
self.validate_builder_signature(&bundle.signature, &commitments)
}
fn validate_block_info_signature(
&self,
signature: &Self::BuilderSignature,
block_size: u64,
fee_amount: u64,
payload_commitment: &BuilderCommitment,
) -> bool {
self.validate_builder_signature(
signature,
&aggregate_block_info_data(block_size, fee_amount, payload_commitment),
)
}
fn sign_builder_message(
private_key: &Self::BuilderPrivateKey,
data: &[u8],
) -> Result<Self::BuilderSignature, Self::SignError>;
fn sign_fee<Metadata: EncodeBytes>(
private_key: &Self::BuilderPrivateKey,
fee_amount: u64,
metadata: &Metadata,
vid_commitment: &<VidSchemeType as VidScheme>::Commit,
) -> Result<Self::BuilderSignature, Self::SignError> {
Self::sign_builder_message(
private_key,
&aggregate_fee_data(fee_amount, metadata, vid_commitment),
)
}
fn sign_sequencing_fee_marketplace(
private_key: &Self::BuilderPrivateKey,
fee_amount: u64,
view_number: u64,
) -> Result<Self::BuilderSignature, Self::SignError> {
Self::sign_builder_message(
private_key,
&aggregate_fee_data_marketplace(fee_amount, view_number),
)
}
fn sign_bundle<TYPES: NodeType>(
private_key: &Self::BuilderPrivateKey,
transactions: &[TYPES::Transaction],
) -> Result<Self::BuilderSignature, Self::SignError> {
let commitments = transactions
.iter()
.flat_map(|txn| <[u8; 32]>::from(txn.commit()))
.collect::<Vec<u8>>();
Self::sign_builder_message(private_key, &commitments)
}
fn sign_block_info(
private_key: &Self::BuilderPrivateKey,
block_size: u64,
fee_amount: u64,
payload_commitment: &BuilderCommitment,
) -> Result<Self::BuilderSignature, Self::SignError> {
Self::sign_builder_message(
private_key,
&aggregate_block_info_data(block_size, fee_amount, payload_commitment),
)
}
fn generated_from_seed_indexed(seed: [u8; 32], index: u64) -> (Self, Self::BuilderPrivateKey);
}
fn aggregate_fee_data<Metadata: EncodeBytes>(
fee_amount: u64,
metadata: &Metadata,
vid_commitment: &<VidSchemeType as VidScheme>::Commit,
) -> Vec<u8> {
let mut fee_info = Vec::new();
fee_info.extend_from_slice(fee_amount.to_be_bytes().as_ref());
fee_info.extend_from_slice(metadata.encode().as_ref());
fee_info.extend_from_slice(vid_commitment.as_ref());
fee_info
}
fn aggregate_fee_data_marketplace(fee_amount: u64, view_number: u64) -> Vec<u8> {
let mut fee_info = Vec::new();
fee_info.extend_from_slice(fee_amount.to_be_bytes().as_ref());
fee_info.extend_from_slice(view_number.to_be_bytes().as_ref());
fee_info
}
fn aggregate_block_info_data(
block_size: u64,
fee_amount: u64,
payload_commitment: &BuilderCommitment,
) -> Vec<u8> {
let mut block_info = Vec::new();
block_info.extend_from_slice(block_size.to_be_bytes().as_ref());
block_info.extend_from_slice(fee_amount.to_be_bytes().as_ref());
block_info.extend_from_slice(payload_commitment.as_ref());
block_info
}