From 7472d0697566161ab4b2da7805cc7c083602ab38 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sun, 18 Feb 2024 22:46:23 +0100 Subject: [PATCH] wip on global state in VM --- src/validation/logic.rs | 13 +++++++++---- src/validation/validator.rs | 24 ++++++++++++++++-------- src/vm/isa.rs | 2 +- src/vm/op_contract.rs | 8 ++++---- src/vm/runtime.rs | 2 +- 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/validation/logic.rs b/src/validation/logic.rs index 621f3c3a..2f8a839b 100644 --- a/src/validation/logic.rs +++ b/src/validation/logic.rs @@ -39,6 +39,7 @@ impl Schema { &'validator self, consignment: &'validator CheckedConsignment<'consignment, C>, op: OpRef, + globals: &'consignment GlobalState, vm: &'consignment dyn VirtualMachine, ) -> validation::Status { let id = op.id(); @@ -168,6 +169,7 @@ impl Schema { consignment.genesis().contract_id(), id, self.subset_of.is_some(), + globals, &op, &prev_state, &redeemed, @@ -426,7 +428,7 @@ impl Schema { } } -pub struct OpInfo<'op> { +pub struct OpInfo<'contract, 'op> { pub subschema: bool, pub contract_id: ContractId, pub id: OpId, @@ -437,14 +439,16 @@ pub struct OpInfo<'op> { pub owned_state: AssignmentsRef<'op>, pub redeemed: &'op Valencies, pub valencies: &'op Valencies, - pub global: &'op GlobalState, + pub op_global: &'op GlobalState, + pub contract_global: &'contract GlobalState, } -impl<'op> OpInfo<'op> { +impl<'contract, 'op> OpInfo<'contract, 'op> { pub fn with( contract_id: ContractId, id: OpId, subschema: bool, + globals: &'contract GlobalState, op: &'op OpRef<'op>, prev_state: &'op Assignments, redeemed: &'op Valencies, @@ -461,7 +465,8 @@ impl<'op> OpInfo<'op> { owned_state: op.assignments(), redeemed, valencies: op.valencies(), - global: op.globals(), + op_global: op.globals(), + contract_global: globals, } } } diff --git a/src/validation/validator.rs b/src/validation/validator.rs index b6b1ccc7..de7b622f 100644 --- a/src/validation/validator.rs +++ b/src/validation/validator.rs @@ -32,9 +32,9 @@ use super::status::{Failure, Warning}; use super::{CheckedConsignment, ConsignmentApi, Status, Validity, VirtualMachine}; use crate::vm::AluRuntime; use crate::{ - AltLayer1, BundleId, ContractId, Layer1, OpId, OpRef, OpType, Operation, Opout, Schema, - SchemaId, SchemaRoot, Script, SubSchema, Transition, TransitionBundle, TypedAssigns, WitnessId, - XAnchor, XChain, XOutpoint, XOutputSeal, XPubWitness, XWitness, + AltLayer1, BundleId, ContractId, GlobalState, Layer1, OpId, OpRef, OpType, Operation, Opout, + Schema, SchemaId, SchemaRoot, Script, SubSchema, Transition, TransitionBundle, TypedAssigns, + WitnessId, XAnchor, XChain, XOutpoint, XOutputSeal, XPubWitness, XWitness, }; #[derive(Clone, Debug, Display, Error, From)] @@ -66,6 +66,8 @@ pub struct Validator<'consignment, 'resolver, C: ConsignmentApi, R: ResolveWitne validated_op_seals: BTreeSet, validated_op_state: BTreeSet, + global_state: GlobalState, + vm: Box, resolver: &'resolver R, } @@ -134,6 +136,7 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveWitness> validated_op_seals, vm, resolver, + global_state: none!(), } } @@ -199,6 +202,7 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveWitness> self.status += schema.validate_state( &self.consignment, OpRef::Genesis(self.consignment.genesis()), + &self.global_state, self.vm.as_ref(), ); self.validated_op_state.insert(self.genesis_id); @@ -231,7 +235,7 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveWitness> // utilize queue to keep the track of the upstream (ancestor) nodes and make // sure that ve have validated each one of them up to genesis. The graph is // valid when each of its nodes and each of its edges is valid, i.e. when all - // individual nodes has passed validation against the schema (we track + // individual nodes have passed validation against the schema (we track // that fact with `validation_index`) and each of the operation ancestor state // change to a given operation is valid against the schema + committed // into bitcoin transaction graph with proper anchor. That is what we are @@ -253,8 +257,12 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveWitness> } // [VALIDATION]: Verify operation against the schema and scripts if self.validated_op_state.insert(opid) { - self.status += - schema.validate_state(&self.consignment, operation, self.vm.as_ref()); + self.status += schema.validate_state( + &self.consignment, + operation, + &self.global_state, + self.vm.as_ref(), + ); } match operation { @@ -530,8 +538,8 @@ impl<'consignment, 'resolver, C: ConsignmentApi, R: ResolveWitness> /// generic type `Dbc`) and extra-transaction data, which are taken from /// anchors DBC proof. /// - /// Additionally checks that the provided message contains commitment to the - /// bundle under the current contract. + /// Additionally, checks that the provided message contains commitment to + /// the bundle under the current contract. fn validate_seal_closing<'seal, 'temp, Seal: 'seal, Dbc: dbc::Proof>( &mut self, seals: impl IntoIterator, diff --git a/src/vm/isa.rs b/src/vm/isa.rs index ed0090fe..2964f876 100644 --- a/src/vm/isa.rs +++ b/src/vm/isa.rs @@ -46,7 +46,7 @@ pub enum RgbIsa { } impl InstructionSet for RgbIsa { - type Context<'ctx> = OpInfo<'ctx>; + type Context<'ctx> = OpInfo<'ctx, 'ctx>; fn isa_ids() -> BTreeSet<&'static str> { bset! {"RGB"} diff --git a/src/vm/op_contract.rs b/src/vm/op_contract.rs index 94caa453..dc6ce65a 100644 --- a/src/vm/op_contract.rs +++ b/src/vm/op_contract.rs @@ -153,7 +153,7 @@ pub enum ContractOp { } impl InstructionSet for ContractOp { - type Context<'ctx> = OpInfo<'ctx>; + type Context<'ctx> = OpInfo<'ctx, 'ctx>; fn isa_ids() -> BTreeSet<&'static str> { none!() } @@ -246,7 +246,7 @@ impl InstructionSet for ContractOp { ); } ContractOp::CnG(state_type, reg) => { - regs.set_n(RegA::A16, *reg, context.global.get(state_type).map(|a| a.len_u16())); + regs.set_n(RegA::A16, *reg, context.op_global.get(state_type).map(|a| a.len_u16())); } ContractOp::CnC(_state_type, _reg) => { // TODO: implement global contract state @@ -286,7 +286,7 @@ impl InstructionSet for ContractOp { } ContractOp::LdG(state_type, index, reg) => { let Some(state) = context - .global + .op_global .get(state_type) .and_then(|a| a.get(*index as usize)) else { @@ -315,7 +315,7 @@ impl InstructionSet for ContractOp { } ContractOp::PcCs(owned_state, global_state) => { - let Some(sum) = context.global.get(global_state) else { + let Some(sum) = context.op_global.get(global_state) else { fail!() }; if sum.len() != 1 { diff --git a/src/vm/runtime.rs b/src/vm/runtime.rs index 055040c9..bd199114 100644 --- a/src/vm/runtime.rs +++ b/src/vm/runtime.rs @@ -60,7 +60,7 @@ impl<'script> AluRuntime<'script> { } } - for ty in info.global.keys() { + for ty in info.op_global.keys() { regs.nums .insert((RegAFR::A(RegA::A16), Reg32::Reg1), ty.into_inner().into()); self.run(EntryPoint::ValidateGlobalState(*ty), ®s, info)?;