use crate::imp::core::config::HostImportsConfig;
use crate::imp::core::types::{Bytes32, Bytes48, Bytes96};
use crate::imp::crypto::bls::BlsSecretKey;
use crate::imp::host::clock::Clock;
use crate::imp::host::error::HostError;
use crate::imp::host::random::HostRng;
use crate::imp::host::session::SessionTable;
use crate::imp::host::teehook::SharedBackend;
use crate::imp::prover::{ChainSource, Prover};
use std::sync::Arc;
pub struct ReturnBuffer {
bytes: Vec<u8>,
max: usize,
}
impl ReturnBuffer {
pub fn new(cfg: &HostImportsConfig) -> Self {
ReturnBuffer {
bytes: Vec::with_capacity(cfg.return_buffer_capacity),
max: cfg.max_return_buffer_size,
}
}
pub fn set(&mut self, data: &[u8]) -> Result<usize, HostError> {
if data.len() > self.max {
return Err(HostError::ReturnBufferOverflow {
needed: data.len(),
max: self.max,
});
}
self.bytes.clear();
self.bytes.extend_from_slice(data);
Ok(data.len())
}
pub fn as_slice(&self) -> &[u8] {
&self.bytes
}
}
pub struct HostKeys {
pub bls_secret: Arc<BlsSecretKey>,
pub bls_public: Bytes48,
}
pub struct HostState {
pub store_id: Bytes32,
pub config: HostImportsConfig,
pub return_buffer: ReturnBuffer,
pub keys: Arc<HostKeys>,
pub attestation: SharedBackend,
pub clock: Arc<dyn Clock>,
pub sessions: SessionTable,
pub chain: Arc<dyn ChainSource>,
pub prover: Arc<dyn Prover>,
pub rng: HostRng,
pub instance_id: Bytes32,
pub http_timeout_secs: u64,
pub last_signature: Option<Bytes96>,
}
#[cfg(all(test, not(target_arch = "wasm32")))]
mod tests {
use super::*;
use crate::imp::core::config::HostImportsConfig;
fn cfg() -> HostImportsConfig {
HostImportsConfig {
return_buffer_capacity: 64 * 1024,
max_return_buffer_size: 16 * 1024 * 1024,
max_random_bytes: 1024,
host_version: "dig-host-test/0.1".to_string(),
}
}
#[test]
fn set_return_then_read_round_trips() {
let mut rb = ReturnBuffer::new(&cfg());
let written = rb.set(&[1, 2, 3, 4]).unwrap();
assert_eq!(written, 4);
assert_eq!(rb.as_slice(), &[1, 2, 3, 4]);
}
#[test]
fn buffer_grows_past_initial_capacity() {
let mut rb = ReturnBuffer::new(&cfg());
let big = vec![7u8; 128 * 1024];
let written = rb.set(&big).unwrap();
assert_eq!(written, 128 * 1024);
assert_eq!(rb.as_slice().len(), 128 * 1024);
}
#[test]
fn buffer_rejects_over_max() {
let mut rb = ReturnBuffer::new(&cfg());
let too_big = vec![0u8; 16 * 1024 * 1024 + 1];
let err = rb.set(&too_big).unwrap_err();
assert!(matches!(
err,
crate::imp::host::error::HostError::ReturnBufferOverflow { .. }
));
}
}