use std::sync::Arc;
use crate::imp::core::config::HostImportsConfig;
use crate::imp::core::types::{Bytes32, Bytes48};
use crate::imp::crypto::bls::BlsSecretKey;
use crate::imp::prover::{ChainSource, MockChainSource, MockProver, Prover};
use crate::imp::host::clock::{Clock, FixedClock};
use crate::imp::host::config::ExecutionLimits;
use crate::imp::host::error::HostError;
use crate::imp::host::runtime::{HostDeps, HostRuntime};
fn mock_block() -> crate::imp::core::ChiaBlockRef {
crate::imp::core::ChiaBlockRef {
header_hash: Bytes32([0x55u8; 32]),
height: 100,
timestamp: 1_700_000_000,
}
}
pub fn request_for_retrieval_key(retrieval_key: &[u8; 32]) -> Vec<u8> {
let mut out = Vec::with_capacity(36);
out.extend_from_slice(retrieval_key);
out.push(0); out.push(0); out.push(0); out.push(0); out
}
pub struct BlindServeConfig {
pub store_id: Bytes32,
pub bls_secret: BlsSecretKey,
pub bls_public: Bytes48,
pub clock_unix: u64,
}
impl BlindServeConfig {
pub fn from_seed(store_id: Bytes32, seed: &[u8]) -> Self {
let sk = BlsSecretKey::from_seed(seed);
let pk = sk.public_key().to_bytes();
BlindServeConfig {
store_id,
bls_secret: sk,
bls_public: pk,
clock_unix: 1_700_000_000,
}
}
}
pub struct BlindServeDeps {
pub prover: Arc<dyn Prover>,
pub chain: Arc<dyn ChainSource>,
pub clock: Arc<dyn Clock>,
}
impl BlindServeDeps {
pub fn mock(clock_unix: u64) -> Self {
let prover_sk = BlsSecretKey::from_seed(&[7u8; 32]);
let prover_pk = prover_sk.public_key();
let block = mock_block();
let chain: Arc<dyn ChainSource> =
Arc::new(MockChainSource::new(vec![block.clone()], clock_unix));
let prover = MockProver::new(prover_sk, prover_pk, block);
BlindServeDeps {
prover: Arc::new(prover),
chain,
clock: Arc::new(FixedClock::new(clock_unix)),
}
}
pub fn with_real_chain_clock(mut self, chain: Arc<dyn ChainSource>) -> Self {
self.chain = chain;
self.clock = Arc::new(crate::imp::host::clock::SystemClock);
self
}
pub fn with_prover(mut self, prover: Arc<dyn Prover>) -> Self {
self.prover = prover;
self
}
#[cfg(feature = "risc0")]
pub fn with_risc0_prover(mut self, node_seed: &[u8]) -> Result<Self, HostError> {
use crate::imp::prover::risc0_backend::Risc0Prover;
let peak = self
.chain
.get_peak()
.map_err(|e| HostError::Wasmtime(format!("chain get_peak for risc0 prover: {e}")))?;
let node_sk = crate::imp::crypto::bls::SecretKey::from_seed(node_seed);
let node_pk = node_sk.public_key();
self.prover = Arc::new(Risc0Prover::new(node_sk, node_pk, peak));
Ok(self)
}
}
fn host_deps(cfg: BlindServeConfig, deps: BlindServeDeps) -> HostDeps {
HostDeps {
store_id: cfg.store_id,
bls_secret: cfg.bls_secret,
bls_public: cfg.bls_public,
clock: deps.clock,
chain: deps.chain,
prover: deps.prover,
rng_seed: None,
instance_id: Bytes32([1u8; 32]),
attestation: None,
}
}
pub fn serve_blind(
module_bytes: &[u8],
retrieval_key: &[u8; 32],
cfg: BlindServeConfig,
) -> Result<Vec<u8>, HostError> {
let deps = BlindServeDeps::mock(cfg.clock_unix);
serve_blind_with(module_bytes, retrieval_key, cfg, deps)
}
pub fn serve_blind_with(
module_bytes: &[u8],
retrieval_key: &[u8; 32],
cfg: BlindServeConfig,
deps: BlindServeDeps,
) -> Result<Vec<u8>, HostError> {
let mut rt = HostRuntime::new(
module_bytes,
HostImportsConfig::default(),
ExecutionLimits::default(),
host_deps(cfg, deps),
)?;
let request = request_for_retrieval_key(retrieval_key);
rt.serve_content(&request)
}