From 8f056b8e5f8b1737dc3a94a42d56fcbf7e9dd87f Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 20 Sep 2024 11:00:40 +0200 Subject: [PATCH] iface: refactor OutpointFilter into AssignmentsFilter which accounts for witness id --- src/interface/contract.rs | 33 +++++++++----- src/interface/filter.rs | 90 ++++++++++++++++++++++++--------------- src/interface/mod.rs | 2 +- 3 files changed, 80 insertions(+), 45 deletions(-) diff --git a/src/interface/contract.rs b/src/interface/contract.rs index 72c767c9..78e85409 100644 --- a/src/interface/contract.rs +++ b/src/interface/contract.rs @@ -32,7 +32,7 @@ use strict_types::{StrictVal, TypeSystem}; use crate::contract::{KnownState, OutputAssignment}; use crate::info::ContractInfo; -use crate::interface::{IfaceImpl, OutpointFilter}; +use crate::interface::{AssignmentsFilter, IfaceImpl}; use crate::persistence::ContractStateRead; use crate::LIB_NAME_RGB_STD; @@ -194,7 +194,21 @@ impl ContractIface { &'c self, state: impl IntoIterator> + 'c, name: impl Into, - filter: impl OutpointFilter + 'c, + filter: impl AssignmentsFilter + 'c, + ) -> Result> + 'c, ContractError> + where + A: Clone + KnownState + 'c, + U: From + KnownState + 'c, + { + Ok(self + .extract_state_unfiltered(state, name)? + .filter(move |outp| filter.should_include(outp.seal, outp.witness))) + } + + fn extract_state_unfiltered<'c, A, U>( + &'c self, + state: impl IntoIterator> + 'c, + name: impl Into, ) -> Result> + 'c, ContractError> where A: Clone + KnownState + 'c, @@ -208,7 +222,6 @@ impl ContractIface { Ok(state .into_iter() .filter(move |outp| outp.opout.ty == type_id) - .filter(move |outp| filter.include_outpoint(outp.seal)) .cloned() .map(OutputAssignment::::transmute)) } @@ -216,7 +229,7 @@ impl ContractIface { pub fn rights<'c>( &'c self, name: impl Into, - filter: impl OutpointFilter + 'c, + filter: impl AssignmentsFilter + 'c, ) -> Result + 'c, ContractError> { self.extract_state(self.state.rights_all(), name, filter) } @@ -224,7 +237,7 @@ impl ContractIface { pub fn fungible<'c>( &'c self, name: impl Into, - filter: impl OutpointFilter + 'c, + filter: impl AssignmentsFilter + 'c, ) -> Result + 'c, ContractError> { self.extract_state(self.state.fungible_all(), name, filter) } @@ -232,7 +245,7 @@ impl ContractIface { pub fn data<'c>( &'c self, name: impl Into, - filter: impl OutpointFilter + 'c, + filter: impl AssignmentsFilter + 'c, ) -> Result + 'c, ContractError> { self.extract_state(self.state.data_all(), name, filter) } @@ -240,17 +253,17 @@ impl ContractIface { pub fn attachments<'c>( &'c self, name: impl Into, - filter: impl OutpointFilter + 'c, + filter: impl AssignmentsFilter + 'c, ) -> Result + 'c, ContractError> { self.extract_state(self.state.attach_all(), name, filter) } pub fn allocations<'c>( &'c self, - filter: impl OutpointFilter + Copy + 'c, + filter: impl AssignmentsFilter + Copy + 'c, ) -> impl Iterator + 'c { fn f<'a, S, U>( - filter: impl OutpointFilter + 'a, + filter: impl AssignmentsFilter + 'a, state: impl IntoIterator> + 'a, ) -> impl Iterator> + 'a where @@ -259,7 +272,7 @@ impl ContractIface { { state .into_iter() - .filter(move |outp| filter.include_outpoint(outp.seal)) + .filter(move |outp| filter.should_include(outp.seal, outp.witness)) .cloned() .map(OutputAssignment::::transmute) } diff --git a/src/interface/filter.rs b/src/interface/filter.rs index 5e802fff..b76ccd65 100644 --- a/src/interface/filter.rs +++ b/src/interface/filter.rs @@ -22,88 +22,110 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::ops::Deref; -use rgb::XOutpoint; - -pub trait OutpointFilter { - fn include_outpoint(&self, outpoint: impl Into) -> bool; +use rgb::{XOutpoint, XWitnessId}; + +pub trait AssignmentsFilter { + fn should_include( + &self, + outpoint: impl Into, + witness_id: Option, + ) -> bool; } pub struct FilterIncludeAll; pub struct FilterExclude(pub T); -impl OutpointFilter for FilterIncludeAll { - fn include_outpoint(&self, _: impl Into) -> bool { true } +impl AssignmentsFilter for FilterIncludeAll { + fn should_include(&self, _: impl Into, _: Option) -> bool { true } } -impl OutpointFilter for FilterExclude { - fn include_outpoint(&self, outpoint: impl Into) -> bool { - !self.0.include_outpoint(outpoint.into()) +impl AssignmentsFilter for FilterExclude { + fn should_include( + &self, + outpoint: impl Into, + witness_id: Option, + ) -> bool { + !self.0.should_include(outpoint.into(), witness_id) } } -impl OutpointFilter for &T { - fn include_outpoint(&self, outpoint: impl Into) -> bool { - (*self).include_outpoint(outpoint) +impl AssignmentsFilter for &T { + fn should_include( + &self, + outpoint: impl Into, + witness_id: Option, + ) -> bool { + (*self).should_include(outpoint, witness_id) } } -impl OutpointFilter for &mut T { - fn include_outpoint(&self, outpoint: impl Into) -> bool { - self.deref().include_outpoint(outpoint) +impl AssignmentsFilter for &mut T { + fn should_include( + &self, + outpoint: impl Into, + witness_id: Option, + ) -> bool { + self.deref().should_include(outpoint, witness_id) } } -impl OutpointFilter for Option { - fn include_outpoint(&self, outpoint: impl Into) -> bool { +impl AssignmentsFilter for Option { + fn should_include( + &self, + outpoint: impl Into, + witness_id: Option, + ) -> bool { self.as_ref() - .map(|filter| filter.include_outpoint(outpoint)) + .map(|filter| filter.should_include(outpoint, witness_id)) .unwrap_or(true) } } -impl OutpointFilter for XOutpoint { - fn include_outpoint(&self, outpoint: impl Into) -> bool { *self == outpoint.into() } +impl AssignmentsFilter for XOutpoint { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { + *self == outpoint.into() + } } -impl OutpointFilter for [XOutpoint; LEN] { - fn include_outpoint(&self, outpoint: impl Into) -> bool { +impl AssignmentsFilter for [XOutpoint; LEN] { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { self.contains(&outpoint.into()) } } -impl OutpointFilter for &[XOutpoint] { - fn include_outpoint(&self, outpoint: impl Into) -> bool { +impl AssignmentsFilter for &[XOutpoint] { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { self.contains(&outpoint.into()) } } -impl OutpointFilter for Vec { - fn include_outpoint(&self, outpoint: impl Into) -> bool { +impl AssignmentsFilter for Vec { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { self.contains(&outpoint.into()) } } -impl OutpointFilter for HashSet { - fn include_outpoint(&self, outpoint: impl Into) -> bool { +impl AssignmentsFilter for HashSet { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { self.contains(&outpoint.into()) } } -impl OutpointFilter for BTreeSet { - fn include_outpoint(&self, outpoint: impl Into) -> bool { +impl AssignmentsFilter for BTreeSet { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { self.contains(&outpoint.into()) } } -impl OutpointFilter for HashMap { - fn include_outpoint(&self, outpoint: impl Into) -> bool { +impl AssignmentsFilter for HashMap { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { let outpoint = outpoint.into(); self.keys().any(|o| *o == outpoint) } } -impl OutpointFilter for BTreeMap { - fn include_outpoint(&self, outpoint: impl Into) -> bool { +impl AssignmentsFilter for BTreeMap { + fn should_include(&self, outpoint: impl Into, _: Option) -> bool { let outpoint = outpoint.into(); self.keys().any(|o| *o == outpoint) } diff --git a/src/interface/mod.rs b/src/interface/mod.rs index 240ab1cf..2ffbac11 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -38,7 +38,7 @@ pub use contract::{ FungibleAllocation, OwnedAllocation, RightsAllocation, StateChange, }; pub use contractum::IfaceDisplay; -pub use filter::{FilterExclude, FilterIncludeAll, OutpointFilter}; +pub use filter::{AssignmentsFilter, FilterExclude, FilterIncludeAll}; pub use iface::{ ArgMap, AssignIface, ExtensionIface, GenesisIface, GlobalIface, Iface, IfaceClass, IfaceId, IfaceInconsistency, IfaceRef, IfaceWrapper, Modifier, OpName, OwnedIface, Req, TransitionIface,