use std::sync::Arc;
use datasize::DataSize;
use serde::{Deserialize, Serialize};
use tracing::info;
use casper_types::{crypto, Digest, PublicKey, SecretKey, Signature};
use crate::{
components::consensus::traits::{ConsensusValueT, Context, ValidatorSecret},
types::BlockPayload,
};
#[derive(DataSize)]
pub struct Keypair {
secret_key: Arc<SecretKey>,
public_key: PublicKey,
}
impl Keypair {
pub(crate) fn new(secret_key: Arc<SecretKey>, public_key: PublicKey) -> Self {
Self {
secret_key,
public_key,
}
}
#[cfg(test)]
pub(crate) fn public_key(&self) -> &PublicKey {
&self.public_key
}
}
impl From<Arc<SecretKey>> for Keypair {
fn from(secret_key: Arc<SecretKey>) -> Self {
let public_key: PublicKey = secret_key.as_ref().into();
Self::new(secret_key, public_key)
}
}
impl ValidatorSecret for Keypair {
type Hash = Digest;
type Signature = Signature;
fn sign(&self, hash: &Digest) -> Signature {
crypto::sign(hash, self.secret_key.as_ref(), &self.public_key)
}
}
impl ConsensusValueT for Arc<BlockPayload> {
fn needs_validation(&self) -> bool {
self.all_transactions().next().is_some()
|| !self.accusations().is_empty()
|| self.rewarded_signatures().has_some()
}
}
#[derive(Clone, DataSize, Debug, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
pub struct ClContext;
impl Context for ClContext {
type ConsensusValue = Arc<BlockPayload>;
type ValidatorId = PublicKey;
type ValidatorSecret = Keypair;
type Signature = Signature;
type Hash = Digest;
type InstanceId = Digest;
fn hash(data: &[u8]) -> Digest {
Digest::hash(data)
}
fn verify_signature(hash: &Digest, public_key: &PublicKey, signature: &Signature) -> bool {
if let Err(error) = crypto::verify(hash, signature, public_key) {
info!(%error, %signature, %public_key, %hash, "failed to validate signature");
return false;
}
true
}
}
mod specimen_support {
use super::Keypair;
use crate::utils::specimen::{Cache, LargestSpecimen, SizeEstimator};
use casper_types::{PublicKey, SecretKey};
use std::sync::Arc;
impl LargestSpecimen for Keypair {
fn largest_specimen<E: SizeEstimator>(estimator: &E, cache: &mut Cache) -> Self {
let secret_key = SecretKey::largest_specimen(estimator, cache);
let public_key = PublicKey::from(&secret_key);
Keypair {
secret_key: Arc::new(secret_key),
public_key,
}
}
}
}