1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
use std::sync::Arc;
use crate::sigma_protocol::prover::ContextExtension;
use bounded_vec::BoundedVec;
use ergo_chain_types::{Header, PreHeader};
use ergotree_ir::chain::ergo_box::ErgoBox;
/// BoundedVec type for Tx inputs, output_candidates and outputs
pub type TxIoVec<T> = BoundedVec<T, 1, { u16::MAX as usize }>;
/// Interpreter's context (blockchain state)
#[derive(Debug)]
pub struct Context {
/// Current height
pub height: u32,
/// Box that contains the script we're evaluating (from spending transaction inputs)
pub self_box: Arc<ErgoBox>,
/// Spending transaction outputs
pub outputs: Vec<Arc<ErgoBox>>,
/// Spending transaction data inputs
pub data_inputs: Option<TxIoVec<Arc<ErgoBox>>>,
/// Spending transaction inputs
pub inputs: TxIoVec<Arc<ErgoBox>>,
/// Pre header of current block
pub pre_header: PreHeader,
/// Fixed number of last block headers in descending order (first header is the newest one)
pub headers: [Header; 10],
/// prover-defined key-value pairs, that may be used inside a script
pub extension: ContextExtension,
}
impl Context {
/// Return a new Context with given context extension
pub fn with_extension(self, ext: ContextExtension) -> Self {
Context {
extension: ext,
..self
}
}
}
#[cfg(feature = "arbitrary")]
#[allow(clippy::unwrap_used)]
mod arbitrary {
use super::*;
use proptest::{collection::vec, option::of, prelude::*};
impl Arbitrary for Context {
type Parameters = ();
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
(
0..i32::MAX as u32,
any::<ErgoBox>(),
vec(any::<ErgoBox>(), 1..3),
vec(any::<ErgoBox>(), 1..3),
of(vec(any::<ErgoBox>(), 1..3)),
any::<PreHeader>(),
any::<ContextExtension>(),
any::<[Header; 10]>(),
)
.prop_map(
|(
height,
self_box,
outputs,
inputs,
data_inputs,
pre_header,
extension,
headers,
)| {
Self {
height,
self_box: Arc::new(self_box),
outputs: outputs.into_iter().map(Arc::new).collect(),
data_inputs: data_inputs.map(|v| {
TxIoVec::from_vec(v.into_iter().map(Arc::new).collect()).unwrap()
}),
inputs: TxIoVec::from_vec(inputs.into_iter().map(Arc::new).collect())
.unwrap(),
pre_header,
extension,
headers,
}
},
)
.boxed()
}
type Strategy = BoxedStrategy<Self>;
}
}
#[cfg(test)]
mod tests {}