From cb4ea10628d779eafa5bc4ed2d026b4fb043754b Mon Sep 17 00:00:00 2001 From: ennucore Date: Mon, 15 Aug 2022 22:31:21 +0300 Subject: [PATCH] Message matchers, Contract type, Code --- agolang/src/templates.rs | 6 ++++ agolang/src/value.rs | 3 +- agorata_contracts/src/contract.rs | 11 ++++++ agorata_contracts/src/error.rs | 7 ++++ agorata_contracts/src/lib.rs | 2 ++ agorata_contracts/src/message.rs | 58 ++++++++++++++++++++++++++++++- 6 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 agorata_contracts/src/contract.rs create mode 100644 agorata_contracts/src/error.rs diff --git a/agolang/src/templates.rs b/agolang/src/templates.rs index 8a6dfaf..87cda3a 100644 --- a/agolang/src/templates.rs +++ b/agolang/src/templates.rs @@ -60,6 +60,12 @@ impl Matcher { } } +impl Default for Matcher { + fn default() -> Self { + Self::Any + } +} + /// **The Complex Matcher** /// diff --git a/agolang/src/value.rs b/agolang/src/value.rs index 9e62c08..7c671ad 100644 --- a/agolang/src/value.rs +++ b/agolang/src/value.rs @@ -1,12 +1,13 @@ use serde::{Deserialize, Serialize}; /// Values used for variables in templates. +/// TODO: Create Vec and Tuple to work with outgoing messages in contracts and tokens in messages. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum Value { Int(i64), Bool(bool), Address(Address), - Token(Address), + Token(String), Data(Vec), String(String), } diff --git a/agorata_contracts/src/contract.rs b/agorata_contracts/src/contract.rs new file mode 100644 index 0000000..d573a63 --- /dev/null +++ b/agorata_contracts/src/contract.rs @@ -0,0 +1,11 @@ +use serde::{Deserialize, Serialize}; +use agolang::Function; +use crate::state::{State, StateDescriptor}; + +/// The contract representation. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Contract { + state_descriptor: StateDescriptor, + init_state: State, + code: Function, +} diff --git a/agorata_contracts/src/error.rs b/agorata_contracts/src/error.rs new file mode 100644 index 0000000..c4d1be6 --- /dev/null +++ b/agorata_contracts/src/error.rs @@ -0,0 +1,7 @@ +use serde::{Serialize, Deserialize}; + +/// The Error type +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum AgoContractError { + InternalError(String) +} diff --git a/agorata_contracts/src/lib.rs b/agorata_contracts/src/lib.rs index 1d3fefe..96d523b 100644 --- a/agorata_contracts/src/lib.rs +++ b/agorata_contracts/src/lib.rs @@ -3,6 +3,8 @@ extern crate serde; /// Message and Address types pub mod message; pub mod state; +pub mod contract; +pub mod error; #[cfg(test)] mod tests { diff --git a/agorata_contracts/src/message.rs b/agorata_contracts/src/message.rs index 7cec5fb..60bf848 100644 --- a/agorata_contracts/src/message.rs +++ b/agorata_contracts/src/message.rs @@ -1,5 +1,7 @@ use serde::{Deserialize, Serialize}; -use agolang::value::Address; +use agolang::templates::{ComplexMatcher, Matcher}; +use agolang::value::{Address, Value}; +use agolang::value::Type; /// The Message. For now, it's the TON Message. Later, it will be adapted to other blockchains. /// See [here](https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb) for the full TON message schema (seizure warning) or [here](https://ton.org/docs/#/smart-contracts/messages) for a humane version. @@ -16,3 +18,57 @@ pub struct Message { /// Other currencies. pub amounts: Vec<(String, i64)>, } + +impl Message { + /// Generate a vec of values for checking it with a `ComplexMatcher` + pub fn to_vec_of_values(&self) -> Vec { + vec![ + Value::Address(self.source), + Value::Address(self.destination), + Value::Data(self.data.clone()), + Value::Int(self.amount), + Value::String(self.amounts.first().unwrap_or(&("".to_string(), 0)).0.clone()), + Value::Int(self.amounts.first().unwrap_or(&("".to_string(), 0)).1), + ] + } +} + + +/// A struct that represent a class of messages (or one message, whatever) for matching +/// +/// For now, this can only match the first of amounts (todo) +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] +pub struct MessageTemplate { + pub source: Matcher, + pub destination: Matcher, + pub data: Matcher, + pub amount: Matcher, + /// if `amounts` isn't empty, we check the name of the first token + pub token_name: Matcher, + /// if `amounts` isn't empty, we check the value of the first token + pub token_value: Matcher, +} + +impl MessageTemplate { + /// Check the validity of the matcher + pub fn is_valid(&self) -> bool { + self.source.check_correctness_for_type(Type::Address) + && self.destination.check_correctness_for_type(Type::Address) + && self.data.check_correctness_for_type(Type::Data) + && self.amount.check_correctness_for_type(Type::Int) + && self.token_name.check_correctness_for_type(Type::String) + && self.token_value.check_correctness_for_type(Type::Int) + } + + /// Convert this to a `ComplexMatcher` that takes all the params + pub fn get_complex_matcher(self) -> ComplexMatcher { + ComplexMatcher::Compose(vec![ + ComplexMatcher::Primitive(self.source), + ComplexMatcher::Primitive(self.destination), + ComplexMatcher::Primitive(self.data), + ComplexMatcher::Primitive(self.amount), + ComplexMatcher::Primitive(self.token_name), + ComplexMatcher::Primitive(self.token_value), + ]) + } +}