1use crate::executor::{AddressOf, ExecError, ExecResult, ExecResultT, ExternalCall, HashOf};
6use alloc::{collections::btree_map::BTreeMap, vec::Vec};
7use codec::{Decode, Encode};
8use core::fmt;
9
10mod and;
11mod executable;
12mod for_all;
13mod not;
14mod or;
15mod there_exists;
16
17pub use and::AndPredicate;
18pub use executable::CompiledExecutable;
19pub use for_all::ForAllPredicate;
20pub use not::NotPredicate;
21pub use or::OrPredicate;
22pub use there_exists::ThereExistsPredicate;
23
24mod equal;
25mod is_contained;
26mod is_less;
27mod is_stored;
28mod is_valid_signature;
29mod verify_inclusion;
30pub use equal::EqualPredicate;
31pub use is_contained::IsContainedPredicate;
32pub use is_less::IsLessThanPredicate;
33pub use is_stored::IsStoredPredicate;
34pub use is_valid_signature::IsValidSignaturePredicate;
35pub use verify_inclusion::VerifyInclusionPredicate;
36
37pub enum AtomicExecutable<'a, Ext: ExternalCall> {
38 Equal(EqualPredicate<'a, Ext>),
39 IsContained(IsContainedPredicate<'a, Ext>),
40 IsLess(IsLessThanPredicate<'a, Ext>),
41 IsStored(IsStoredPredicate<'a, Ext>),
42 IsValidSignature(IsValidSignaturePredicate<'a, Ext>),
43 VerifyInclusion(VerifyInclusionPredicate<'a, Ext>),
44}
45
46impl<Ext: ExternalCall> AtomicPredicateInterface<AddressOf<Ext>> for AtomicExecutable<'_, Ext> {
47 fn decide(&self, inputs: Vec<Vec<u8>>) -> ExecResult<AddressOf<Ext>> {
48 match self {
49 AtomicExecutable::Equal(p) => p.decide(inputs),
50 AtomicExecutable::IsContained(p) => p.decide(inputs),
51 AtomicExecutable::IsLess(p) => p.decide(inputs),
52 AtomicExecutable::IsStored(p) => p.decide(inputs),
53 AtomicExecutable::IsValidSignature(p) => p.decide(inputs),
54 AtomicExecutable::VerifyInclusion(p) => p.decide(inputs),
55 }
56 }
57
58 fn decide_true(&self, inputs: Vec<Vec<u8>>) -> ExecResult<AddressOf<Ext>> {
59 match self {
60 AtomicExecutable::Equal(p) => p.decide_true(inputs),
61 AtomicExecutable::IsContained(p) => p.decide_true(inputs),
62 AtomicExecutable::IsLess(p) => p.decide_true(inputs),
63 AtomicExecutable::IsStored(p) => p.decide_true(inputs),
64 AtomicExecutable::IsValidSignature(p) => p.decide_true(inputs),
65 AtomicExecutable::VerifyInclusion(p) => p.decide_true(inputs),
66 }
67 }
68}
69
70impl<Ext: ExternalCall> AtomicHelperInterface<AddressOf<Ext>> for AtomicExecutable<'_, Ext> {
71 type Hash = HashOf<Ext>;
72 fn ext_address(&self) -> AddressOf<Ext> {
73 AddressOf::<Ext>::default()
74 }
75 fn ext_set_predicate_decision(
76 &self,
77 _game_id: Self::Hash,
78 _decision: bool,
79 ) -> ExecResult<AddressOf<Ext>> {
80 Err(ExecError::Unimplemented)
81 }
82 fn ext_get_property_id(&self, _property: &Property<AddressOf<Ext>>) -> Self::Hash {
83 Self::Hash::default()
84 }
85}
86
87pub enum LogicalConnectiveExecutable<'a, Ext: ExternalCall> {
88 And(AndPredicate<'a, Ext>),
89 Not(NotPredicate<'a, Ext>),
90 Or(OrPredicate<'a, Ext>),
91 ForAll(ForAllPredicate<'a, Ext>),
92 ThereExists(ThereExistsPredicate<'a, Ext>),
93}
94
95impl<Ext: ExternalCall> LogicalConnectiveInterface<AddressOf<Ext>>
96 for LogicalConnectiveExecutable<'_, Ext>
97{
98 fn is_valid_challenge(
99 &self,
100 inputs: Vec<Vec<u8>>,
101 challenge_inputs: Vec<Vec<u8>>,
102 challenge: Property<AddressOf<Ext>>,
103 ) -> ExecResult<AddressOf<Ext>> {
104 match self {
105 LogicalConnectiveExecutable::And(and) => {
106 and.is_valid_challenge(inputs, challenge_inputs, challenge)
107 }
108 LogicalConnectiveExecutable::Not(not) => {
109 not.is_valid_challenge(inputs, challenge_inputs, challenge)
110 }
111 LogicalConnectiveExecutable::Or(or) => {
112 or.is_valid_challenge(inputs, challenge_inputs, challenge)
113 }
114 LogicalConnectiveExecutable::ForAll(for_all) => {
115 for_all.is_valid_challenge(inputs, challenge_inputs, challenge)
116 }
117 LogicalConnectiveExecutable::ThereExists(there_exists) => {
118 there_exists.is_valid_challenge(inputs, challenge_inputs, challenge)
119 }
120 }
121 }
122}
123
124pub enum DecidableExecutable<'a, Ext: ExternalCall> {
125 And(AndPredicate<'a, Ext>),
126 Not(NotPredicate<'a, Ext>),
127 Or(OrPredicate<'a, Ext>),
128 ForAll(ForAllPredicate<'a, Ext>),
129 ThereExists(ThereExistsPredicate<'a, Ext>),
130 Equal(EqualPredicate<'a, Ext>),
131 IsContained(IsContainedPredicate<'a, Ext>),
132 IsLess(IsLessThanPredicate<'a, Ext>),
133 IsStored(IsStoredPredicate<'a, Ext>),
134 IsValidSignature(IsValidSignaturePredicate<'a, Ext>),
135 VerifyInclusion(VerifyInclusionPredicate<'a, Ext>),
136}
137
138impl<Ext: ExternalCall> DecidablePredicateInterface<AddressOf<Ext>>
139 for DecidableExecutable<'_, Ext>
140{
141 fn decide_with_witness(
142 &self,
143 inputs: Vec<Vec<u8>>,
144 witness: Vec<Vec<u8>>,
145 ) -> ExecResult<AddressOf<Ext>> {
146 match self {
147 DecidableExecutable::And(p) => p.decide_with_witness(inputs, witness),
148 DecidableExecutable::Not(p) => p.decide_with_witness(inputs, witness),
149 DecidableExecutable::Or(p) => p.decide_with_witness(inputs, witness),
150 DecidableExecutable::ForAll(p) => p.decide_with_witness(inputs, witness),
151 DecidableExecutable::ThereExists(p) => p.decide_with_witness(inputs, witness),
152 DecidableExecutable::Equal(p) => p.decide_with_witness(inputs, witness),
153 DecidableExecutable::IsContained(p) => p.decide_with_witness(inputs, witness),
154 DecidableExecutable::IsLess(p) => p.decide_with_witness(inputs, witness),
155 DecidableExecutable::IsStored(p) => p.decide_with_witness(inputs, witness),
156 DecidableExecutable::IsValidSignature(p) => p.decide_with_witness(inputs, witness),
157 DecidableExecutable::VerifyInclusion(p) => p.decide_with_witness(inputs, witness),
158 }
159 }
160}
161
162pub enum BaseAtomicExecutable<'a, Ext: ExternalCall> {
163 Equal(EqualPredicate<'a, Ext>),
164 IsContained(IsContainedPredicate<'a, Ext>),
165 IsLess(IsLessThanPredicate<'a, Ext>),
166 IsStored(IsStoredPredicate<'a, Ext>),
167 IsValidSignature(IsValidSignaturePredicate<'a, Ext>),
168 VerifyInclusion(VerifyInclusionPredicate<'a, Ext>),
169}
170
171impl<Ext: ExternalCall> DecidablePredicateInterface<AddressOf<Ext>>
172 for BaseAtomicExecutable<'_, Ext>
173{
174 fn decide_with_witness(
175 &self,
176 inputs: Vec<Vec<u8>>,
177 witness: Vec<Vec<u8>>,
178 ) -> ExecResult<AddressOf<Ext>> {
179 match self {
180 BaseAtomicExecutable::Equal(p) => p.decide_with_witness(inputs, witness),
181 BaseAtomicExecutable::IsContained(p) => p.decide_with_witness(inputs, witness),
182 BaseAtomicExecutable::IsLess(p) => p.decide_with_witness(inputs, witness),
183 BaseAtomicExecutable::IsStored(p) => p.decide_with_witness(inputs, witness),
184 BaseAtomicExecutable::IsValidSignature(p) => p.decide_with_witness(inputs, witness),
185 BaseAtomicExecutable::VerifyInclusion(p) => p.decide_with_witness(inputs, witness),
186 }
187 }
188}
189
190impl<Ext: ExternalCall> AtomicPredicateInterface<AddressOf<Ext>> for BaseAtomicExecutable<'_, Ext> {
191 fn decide(&self, inputs: Vec<Vec<u8>>) -> ExecResult<AddressOf<Ext>> {
192 match self {
193 BaseAtomicExecutable::Equal(p) => p.decide(inputs),
194 BaseAtomicExecutable::IsContained(p) => p.decide(inputs),
195 BaseAtomicExecutable::IsLess(p) => p.decide(inputs),
196 BaseAtomicExecutable::IsStored(p) => p.decide(inputs),
197 BaseAtomicExecutable::IsValidSignature(p) => p.decide(inputs),
198 BaseAtomicExecutable::VerifyInclusion(p) => p.decide(inputs),
199 }
200 }
201
202 fn decide_true(&self, inputs: Vec<Vec<u8>>) -> ExecResult<AddressOf<Ext>> {
203 match self {
204 BaseAtomicExecutable::Equal(p) => p.decide_true(inputs),
205 BaseAtomicExecutable::IsContained(p) => p.decide_true(inputs),
206 BaseAtomicExecutable::IsLess(p) => p.decide_true(inputs),
207 BaseAtomicExecutable::IsStored(p) => p.decide_true(inputs),
208 BaseAtomicExecutable::IsValidSignature(p) => p.decide_true(inputs),
209 BaseAtomicExecutable::VerifyInclusion(p) => p.decide_true(inputs),
210 }
211 }
212}
213
214impl<Ext: ExternalCall> BaseAtomicPredicateInterface<AddressOf<Ext>>
215 for BaseAtomicExecutable<'_, Ext>
216{
217}
218
219impl<Ext: ExternalCall> AtomicHelperInterface<AddressOf<Ext>> for BaseAtomicExecutable<'_, Ext> {
220 type Hash = HashOf<Ext>;
221 fn ext_address(&self) -> AddressOf<Ext> {
222 AddressOf::<Ext>::default()
223 }
224 fn ext_set_predicate_decision(
225 &self,
226 _game_id: Self::Hash,
227 _decision: bool,
228 ) -> ExecResult<AddressOf<Ext>> {
229 Err(ExecError::Unimplemented)
230 }
231 fn ext_get_property_id(&self, _property: &Property<AddressOf<Ext>>) -> Self::Hash {
232 Self::Hash::default()
233 }
234}
235
236#[derive(Clone, Eq, PartialEq, Encode, Decode, Hash)]
237#[cfg_attr(feature = "std", derive(Debug))]
238pub enum PredicateCallInputs<Address> {
239 AtomicPredicate(AtomicPredicateCallInputs),
240 DecidablePredicate(DecidablePredicateCallInputs),
241 LogicalConnective(LogicalConnectiveCallInputs<Address>),
242 BaseAtomicPredicate(BaseAtomicPredicateCallInputs),
243 CompiledPredicate(CompiledPredicateCallInputs<Address>),
244}
245
246#[derive(Clone, Eq, PartialEq, Encode, Decode, Hash)]
247#[cfg_attr(feature = "std", derive(Debug))]
248pub enum AtomicPredicateCallInputs {
249 DecideTrue { inputs: Vec<Vec<u8>> },
250 Decide { inputs: Vec<Vec<u8>> },
251}
252
253impl fmt::Display for AtomicPredicateCallInputs {
254 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> fmt::Result {
255 let state = match self {
256 AtomicPredicateCallInputs::Decide { inputs: _ } => "Decide",
257 AtomicPredicateCallInputs::DecideTrue { inputs: _ } => "DecideTrue",
258 };
259 write!(f, "{}", state)
260 }
261}
262
263#[derive(Clone, Eq, PartialEq, Encode, Decode, Hash)]
264#[cfg_attr(feature = "std", derive(Debug))]
265pub enum DecidablePredicateCallInputs {
266 DecideWithWitness {
267 inputs: Vec<Vec<u8>>,
268 witness: Vec<Vec<u8>>,
269 },
270}
271
272impl fmt::Display for DecidablePredicateCallInputs {
273 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> fmt::Result {
274 let state = match self {
275 DecidablePredicateCallInputs::DecideWithWitness {
276 inputs: _,
277 witness: _,
278 } => "DecideWithWitness",
279 };
280 write!(f, "{}", state)
281 }
282}
283
284#[derive(Clone, Eq, PartialEq, Encode, Decode, Hash)]
285#[cfg_attr(feature = "std", derive(Debug))]
286pub enum LogicalConnectiveCallInputs<Address> {
287 IsValidChallenge {
288 inputs: Vec<Vec<u8>>,
289 challenge_inputs: Vec<Vec<u8>>,
290 challenge: Property<Address>,
291 },
292}
293
294impl<Address> fmt::Display for LogicalConnectiveCallInputs<Address> {
295 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> fmt::Result {
296 let state = match self {
297 LogicalConnectiveCallInputs::IsValidChallenge {
298 inputs: _,
299 challenge_inputs: _,
300 challenge: _,
301 } => "IsValidChallenge",
302 };
303 write!(f, "{}", state)
304 }
305}
306
307#[derive(Clone, Eq, PartialEq, Encode, Decode, Hash)]
308#[cfg_attr(feature = "std", derive(Debug))]
309pub enum BaseAtomicPredicateCallInputs {
310 Decide {
311 inputs: Vec<Vec<u8>>,
312 },
313 DecideWithWitness {
314 inputs: Vec<Vec<u8>>,
315 witness: Vec<Vec<u8>>,
316 },
317 DecideTrue {
318 inputs: Vec<Vec<u8>>,
319 },
320}
321
322impl fmt::Display for BaseAtomicPredicateCallInputs {
323 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> fmt::Result {
324 let state = match self {
325 BaseAtomicPredicateCallInputs::Decide { inputs: _ } => "Decide",
326 BaseAtomicPredicateCallInputs::DecideTrue { inputs: _ } => "DecideTrue",
327 BaseAtomicPredicateCallInputs::DecideWithWitness {
328 inputs: _,
329 witness: _,
330 } => "DecideWithWitness",
331 };
332 write!(f, "{}", state)
333 }
334}
335
336#[derive(Clone, Eq, PartialEq, Encode, Decode, Hash)]
337#[cfg_attr(feature = "std", derive(Debug))]
338pub enum CompiledPredicateCallInputs<Address> {
339 IsValidChallenge {
340 inputs: Vec<Vec<u8>>,
341 challenge_inputs: Vec<Vec<u8>>,
342 challenge: Property<Address>,
343 },
344 Decide {
345 inputs: Vec<Vec<u8>>,
346 witness: Vec<Vec<u8>>,
347 },
348 DecideTrue {
349 inputs: Vec<Vec<u8>>,
350 witness: Vec<Vec<u8>>,
351 },
352 DecideWithWitness {
353 inputs: Vec<Vec<u8>>,
354 witness: Vec<Vec<u8>>,
355 },
356 GetChild {
357 inputs: Vec<Vec<u8>>,
358 challenge_input: Vec<Vec<u8>>,
359 },
360}
361
362impl<Address> fmt::Display for CompiledPredicateCallInputs<Address> {
363 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> fmt::Result {
364 let state = match self {
365 CompiledPredicateCallInputs::IsValidChallenge {
366 inputs: _,
367 challenge_inputs: _,
368 challenge: _,
369 } => "IsValidChallenge",
370 CompiledPredicateCallInputs::Decide {
371 inputs: _,
372 witness: _,
373 } => "Decide",
374 CompiledPredicateCallInputs::DecideTrue {
375 inputs: _,
376 witness: _,
377 } => "DecideTrue",
378 CompiledPredicateCallInputs::DecideWithWitness {
379 inputs: _,
380 witness: _,
381 } => "DecideWithWitness",
382 CompiledPredicateCallInputs::GetChild {
383 inputs: _,
384 challenge_input: _,
385 } => "GetChild",
386 };
387 write!(f, "{}", state)
388 }
389}
390
391#[derive(Encode, Decode, Clone, PartialEq, Eq, Hash)]
394#[cfg_attr(feature = "std", derive(Debug))]
395pub struct Property<Address> {
396 predicate_address: Address,
398 inputs: Vec<Vec<u8>>,
400}
401
402pub trait UniversalAdjudication<Hash> {
403 fn ext_set_predicate_decision(&self, game_id: Hash, decision: bool);
404}
405
406pub trait Utils<Hash> {
407 fn ext_get_property_id(&self) -> Hash;
408}
409
410pub trait BaseAtomicPredicateInterface<Address>:
411 AtomicPredicateInterface<Address> + DecidablePredicateInterface<Address>
412{
413}
414
415pub trait AtomicPredicateInterface<Address>: AtomicHelperInterface<Address> {
416 fn decide(&self, _inputs: Vec<Vec<u8>>) -> ExecResult<Address> {
417 return Ok(false);
418 }
419
420 fn decide_true(&self, inputs: Vec<Vec<u8>>) -> ExecResult<Address> {
421 let result_of_decide = AtomicPredicateInterface::decide(self, inputs.clone())?;
422 require_with_message!(result_of_decide, "must decide true");
423 let property = Property {
424 predicate_address: self.ext_address(),
425 inputs: inputs,
426 };
427 self.ext_set_predicate_decision(self.ext_get_property_id(&property), true)?;
428 Ok(true)
429 }
430}
431
432pub trait AtomicHelperInterface<Address> {
433 type Hash;
434 fn ext_address(&self) -> Address;
435 fn ext_set_predicate_decision(
436 &self,
437 game_id: Self::Hash,
438 decision: bool,
439 ) -> ExecResult<Address>;
440 fn ext_get_property_id(&self, property: &Property<Address>) -> Self::Hash;
441}
442
443pub trait DecidablePredicateInterface<Address> {
444 fn decide_with_witness(
445 &self,
446 _inputs: Vec<Vec<u8>>,
447 _witness: Vec<Vec<u8>>,
448 ) -> ExecResult<Address>;
449}
450
451pub trait CompiledPredicateInterface<Address> {
452 fn payout_contract_address(&self) -> Address;
453
454 fn is_valid_challenge(
455 &self,
456 _inputs: Vec<Vec<u8>>,
457 _challenge_inputs: Vec<Vec<u8>>,
458 _challenge: Property<Address>,
459 ) -> ExecResult<Address>;
460
461 fn get_child(
463 &self,
464 inputs: Vec<Vec<u8>>,
465 challenge_input: Vec<Vec<u8>>,
466 ) -> ExecResultT<Property<Address>, Address>;
467
468 fn decide(&self, _inputs: Vec<Vec<u8>>, _witness: Vec<Vec<u8>>) -> ExecResult<Address>;
469 fn decide_true(&self, _inputs: Vec<Vec<u8>>, _witness: Vec<Vec<u8>>) -> ExecResult<Address>;
470 fn decide_with_witness(
471 &self,
472 _inputs: Vec<Vec<u8>>,
473 _witness: Vec<Vec<u8>>,
474 ) -> ExecResult<Address>;
475}
476
477pub trait LogicalConnectiveInterface<Address> {
478 fn is_valid_challenge(
479 &self,
480 _inputs: Vec<Vec<u8>>,
481 _challenge_inputs: Vec<Vec<u8>>,
482 _challenge: Property<Address>,
483 ) -> ExecResult<Address>;
484}