entropyxyz / programs

Source, toolchain, and examples for using programs on Entropy
https://docs.entropy.xyz/concepts/programs/
GNU Affero General Public License v3.0
19 stars 3 forks source link

WIT generation from Application configurations #16

Open jakehemmerle opened 1 year ago

jakehemmerle commented 1 year ago

The only other option is to hand-code each WIT file and then generate types from it, which is needlessly tedious.

Let's use a simple EVM ACL whitelisting program as an example. In this case, the configuration for the ACL is quite literally just the ACL struct:

pub struct Acl<Address> {
    pub addresses: Vec<Address>,
    pub kind: AclKind,
    pub allow_null_recipient: bool,
}

Since we have implemented SatisfiableByArchitecture, the following evaluation logic is included in the Wasm blob:

impl SatisfiableForArchitecture<Evm> for Acl<<Evm as Architecture>::AddressRaw> {
    fn is_satisfied_by(
        self,
        tx: &<Evm as Architecture>::TransactionRequest,
    ) -> Result<(), CoreError> {
        if tx.to.is_none() {
            return match self.allow_null_recipient {
                true => Ok(()),
                false => Err(CoreError::Evaluation(
                    "Null recipients are not allowed.".to_string(),
                )),
            };
        }

        let converted_addresses: Vec<NameOrAddress> = self
            .addresses
            .into_iter()
            .map(|a| NameOrAddress::Address(H160::from(a)))
            .collect();

        match (
            converted_addresses.contains(&tx.to.clone().unwrap()),
            self.kind,
        ) {
            (true, AclKind::Allow) => Ok(()),
            (false, AclKind::Deny) => Ok(()),
            _ => Err(CoreError::Evaluation(
                "Transaction not allowed.".to_string(),
            )),
        }
    }
}

Before doing this, we should rewrite evaluation in an Architecture generic way eg.

impl <A: Architecture> SatisfiableForArchitecture<A> for Acl<A::AddressRaw> { ...

In this example program, we want to we want to generate a WIT file that includes a this Config (maybe record?) from the Acl and SatisfiableForArchitecture<Architecture>, resulting in ConfigBtc, ConfigEvm, etc.

package username:acl

use entropy:core

world acl {
  export evaluate: func(config: config-eth) -> result<_, error>
  export evaluate: func(config: config-btc) -> result<_, error>

  record config-eth {
    /// The preimage of the user's data under constraint evaulation (eg. RLP-encoded ETH transaction request).
    addresses: list<list<u8>>
    kind: (whatever WIT enum is)
    allow_null_recipient: bool
  }
   record config-btc {
    addresses: list<list<u8>>
    kind: (whatever WIT enum is)
    allow_null_recipient: bool
  }
... you get the idea

}

We should probably generate a WIT record and evaluate export from each SatisfiableForArchitecture monomorphic function (or whatever related trait is appropriate by then).