git.delta.rocks / unique-network / refs/commits / 99e7a932fe6e

difftreelog

feat define new execution traits

Yaroslav Bolyukin2021-07-20parent: #d604f6b.patch.diff
in: master

5 files changed

modifiedcrates/evm-coder-macros/src/lib.rsdiffbeforeafterboth
127}127}
128128
129// Gets T out of Result<T>129// Gets T out of Result<T>
130fn parse_result_ok(ty: &Type) -> syn::Result<&Ident> {130fn parse_result_ok(ty: &Type) -> syn::Result<&Type> {
131 let path = parse_path(ty)?;131 let path = parse_path(ty)?;
132 let segment = parse_path_segment(path)?;132 let segment = parse_path_segment(path)?;
133133
160 }160 }
161 };161 };
162162
163 parse_ident_from_type(ty)163 Ok(ty)
164}164}
165165
166fn pascal_ident_to_call(ident: &Ident) -> Ident {166fn pascal_ident_to_call(ident: &Ident) -> Ident {
184 Ident::new(&name, ident.span())184 Ident::new(&name, ident.span())
185}185}
186
187fn format_ty(ty: &Ident) -> String {
188 if ty == "string" {
189 format!("{} memory", ty)
190 } else {
191 ty.to_string()
192 }
193}
194186
195#[proc_macro_attribute]187#[proc_macro_attribute]
196pub fn solidity_interface(args: TokenStream, stream: TokenStream) -> TokenStream {188pub fn solidity_interface(args: TokenStream, stream: TokenStream) -> TokenStream {
modifiedcrates/evm-coder-macros/src/solidity_interface.rsdiffbeforeafterboth
4use darling::FromMeta;4use darling::FromMeta;
5use inflector::cases;5use inflector::cases;
6use std::fmt::Write;6use std::fmt::Write;
7use syn::{7use syn::{FnArg, Ident, ItemTrait, Meta, NestedMeta, PatType, Path, ReturnType, TraitItem, TraitItemMethod, Type, Visibility, spanned::Spanned};
8 FnArg, Ident, ItemTrait, Meta, NestedMeta, PatType, Path, ReturnType, TraitItem,
9 TraitItemMethod, Visibility, spanned::Spanned,
10};
118
12use crate::{9use crate::{
13 fn_selector_str, format_ty, parse_ident_from_pat, parse_ident_from_path, parse_ident_from_type,10 fn_selector_str, parse_ident_from_pat, parse_ident_from_path, parse_ident_from_type,
14 parse_result_ok, pascal_ident_to_call, pascal_ident_to_snake_call, snake_ident_to_pascal,11 parse_result_ok, pascal_ident_to_call, pascal_ident_to_snake_call, snake_ident_to_pascal,
15 snake_ident_to_screaming,12 snake_ident_to_screaming,
16};13};
68 let snake_call_name = &self.snake_call_name;65 let snake_call_name = &self.snake_call_name;
69 let pascal_call_name = &self.pascal_call_name;66 let pascal_call_name = &self.pascal_call_name;
70 quote! {67 quote! {
71 fn #snake_call_name(&mut self, c: Msg<#pascal_call_name>) -> ::core::result::Result<::evm_coder::abi::AbiWriter, Self::Error>;68 fn #snake_call_name(&mut self, c: Msg<#pascal_call_name>) -> Result<::evm_coder::abi::AbiWriter>;
72 }69 }
73 }70 }
7471
174 }171 }
175 }172 }
176
177 fn solidity_def(&self) -> String {
178 assert!(!self.is_special());
179 format!("{} {}", format_ty(&self.ty), self.name)
180 }
181}173}
182174
183#[derive(PartialEq)]175#[derive(PartialEq)]
197 args: Vec<MethodArg>,189 args: Vec<MethodArg>,
198 has_normal_args: bool,190 has_normal_args: bool,
199 mutability: Mutability,191 mutability: Mutability,
200 result: Ident,192 result: Type,
201}193}
202impl Method {194impl Method {
203 fn try_from(value: &TraitItemMethod) -> syn::Result<Self> {195 fn try_from(value: &TraitItemMethod) -> syn::Result<Self> {
392 }384 }
393 }385 }
394
395 fn solidity_def(&self) -> String {
396 let mut out = format!("function {}(", self.camel_name);
397 for (i, arg) in self.args.iter().filter(|a| !a.is_special()).enumerate() {
398 if i != 0 {
399 out.push_str(", ");
400 }
401 out.push_str(&arg.solidity_def());
402 }
403 out.push(')');
404 match self.mutability {
405 Mutability::Mutable => {}
406 Mutability::View => write!(out, " view").unwrap(),
407 Mutability::Pure => write!(out, " pure").unwrap(),
408 }
409 if self.result != "void" {
410 write!(out, " returns ({})", format_ty(&self.result)).unwrap();
411 }
412 out.push(';');
413 out
414 }
415}386}
416387
417pub struct SolidityInterface {388pub struct SolidityInterface {
423}394}
424impl SolidityInterface {395impl SolidityInterface {
425 pub fn try_from(info: InterfaceInfo, value: &ItemTrait) -> syn::Result<Self> {396 pub fn try_from(info: InterfaceInfo, value: &ItemTrait) -> syn::Result<Self> {
426 let mut found_error = false;
427 let mut methods = Vec::new();397 let mut methods = Vec::new();
428398
429 for item in &value.items {399 for item in &value.items {
430 match item {400 match item {
431 TraitItem::Type(ty) => {
432 if ty.ident == "Error" {
433 found_error = true;
434 }
435 }
436 TraitItem::Method(method) => methods.push(Method::try_from(method)?),401 TraitItem::Method(method) => methods.push(Method::try_from(method)?),
437 _ => {}402 _ => {}
438 }403 }
439 }404 }
440 if !found_error {
441 return Err(syn::Error::new(
442 value.span(),
443 "expected associated type called Error, which should implement From<&str>",
444 ));
445 }
446 Ok(Self {405 Ok(Self {
447 vis: value.vis.clone(),406 vis: value.vis.clone(),
448 name: value.ident.clone(),407 name: value.ident.clone(),
508 #call_sub,467 #call_sub,
509 )*468 )*
510 }469 }
511 impl #call_name {470 impl #call_name {
471 #(
472 #consts
473 )*
474 pub const fn interface_id() -> u32 {
475 let mut interface_id = 0;
476 #(#interface_id)*
477 #(#inline_interface_id)*
478 interface_id
479 }
480 pub fn supports_interface(interface_id: u32) -> bool {
481 interface_id != 0xffffff && (
482 interface_id == Self::interface_id()
483 #(
484 || #supports_interface
485 )*
486 )
487 }
488 }
512 #(489 impl ::evm_coder::Call for #call_name {
513 #consts
514 )*
515 pub fn parse(method_id: u32, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::abi::Result<Option<Self>> {490 fn parse(method_id: u32, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Option<Self>> {
516 use ::evm_coder::abi::AbiRead;491 use ::evm_coder::abi::AbiRead;
517 match method_id {492 match method_id {
518 #(493 #(
525 )else*500 )else*
526 return Ok(None);501 return Ok(None);
527 }502 }
528 pub const fn interface_id() -> u32 {503 }
529 let mut interface_id = 0;
530 #(#interface_id)*
531 #(#inline_interface_id)*
532 interface_id
533 }
534 pub fn supports_interface(interface_id: u32) -> bool {
535 interface_id != 0xffffff && (
536 interface_id == Self::interface_id()
537 #(
538 || #supports_interface
539 )*
540 )
541 }
542 }
543 #vis trait #name {504 #vis trait #name {
544 #(505 #(
545 #items506 #items
546 )*507 )*
547 #(508 #(
548 #call_inner509 #call_inner
549 )*510 )*
511 }
512 impl<T> ::evm_coder::Callable for T where T: #name {
513 type Call = #call_name;
550 #[allow(unreachable_code)] // In case of no inner calls514 #[allow(unreachable_code)] // In case of no inner calls
551 fn call(&mut self, c: Msg<#call_name>) -> ::core::result::Result<::evm_coder::abi::AbiWriter, Self::Error> {515 fn call(&mut self, c: Msg<#call_name>) -> Result<::evm_coder::abi::AbiWriter> {
552 use ::evm_coder::abi::AbiWrite;516 use ::evm_coder::abi::AbiWrite;
553 type InternalCall = #call_name;517 type InternalCall = #call_name;
554 match c.call {518 match c.call {
566 }530 }
567 Ok(writer)531 Ok(writer)
568 }532 }
569 }533 }
570 }534 }
571 }535 }
572}536}
modifiedcrates/evm-coder/Cargo.tomldiffbeforeafterboth
8primitive-types = { version = "0.9", default-features = false }8primitive-types = { version = "0.9", default-features = false }
9hex-literal = "0.3"9hex-literal = "0.3"
10ethereum = { version = "0.7.1", default-features = false }10ethereum = { version = "0.7.1", default-features = false }
11evm-core = { git = "https://github.com/usetech-llc/evm.git", branch="precompile-output-parachain" }
12impl-trait-for-tuples = "0.2.1"
1113
12[dev-dependencies]14[dev-dependencies]
13hex = "0.4.3"15hex = "0.4.3"
modifiedcrates/evm-coder/src/lib.rsdiffbeforeafterboth
2#[cfg(not(feature = "std"))]2#[cfg(not(feature = "std"))]
3extern crate alloc;3extern crate alloc;
44
5use abi::{AbiReader, AbiWriter};
5pub use evm_coder_macros::{event_topic, fn_selector, solidity_interface, solidity, ToLog};6pub use evm_coder_macros::{event_topic, fn_selector, solidity_interface, solidity, ToLog};
6pub mod abi;7pub mod abi;
7pub mod events;8pub mod events;
8pub use events::ToLog;9pub use events::ToLog;
10pub mod execution;
11pub mod solidity;
912
10/// Solidity type definitions13/// Solidity type definitions
11pub mod types {14pub mod types {
50 }53 }
51}54}
55
56pub trait Call: Sized {
57 fn parse(selector: u32, input: &mut AbiReader) -> execution::Result<Option<Self>>;
58}
59
60pub trait Callable {
61 type Call: Call;
62 fn call(&mut self, call: types::Msg<Self::Call>) -> execution::Result<AbiWriter>;
63}
5264
53#[cfg(test)]65#[cfg(test)]
54mod tests {66mod tests {
modifiedcrates/evm-coder/tests/a.rsdiffbeforeafterboth
1#![allow(dead_code)] // This test only checks that macros is not panicking1#![allow(dead_code)] // This test only checks that macros is not panicking
22
3use evm_coder::{solidity_interface, types::*, ToLog};3use evm_coder::{solidity_interface, types::*, ToLog, execution::Result};
4use evm_coder_macros::solidity;4use evm_coder_macros::solidity;
55
6#[solidity_interface]6#[solidity_interface]
7trait OurInterface {7trait OurInterface {
8 type Error;
9 fn fn_a(&self, input: uint256) -> Result<bool, Self::Error>;8 fn fn_a(&self, input: uint256) -> Result<bool>;
10}9}
1110
12#[solidity_interface]11#[solidity_interface]
13trait OurInterface1 {12trait OurInterface1 {
14 type Error;
15 fn fn_b(&self, input: uint128) -> Result<uint32, Self::Error>;13 fn fn_b(&self, input: uint128) -> Result<uint32>;
16}14}
1715
18#[solidity_interface(is(OurInterface), inline_is(OurInterface1), events(ERC721Log))]16#[solidity_interface(is(OurInterface), inline_is(OurInterface1), events(ERC721Log))]
19trait OurInterface2 {17trait OurInterface2 {
20 type Error;
21 #[solidity(rename_selector = "fnK")]18 #[solidity(rename_selector = "fnK")]
22 fn fn_c(&self, input: uint32) -> Result<uint8, Self::Error>;19 fn fn_c(&self, input: uint32) -> Result<uint8>;
23 fn fn_d(&self, value: uint32) -> Result<uint32, Self::Error>;20 fn fn_d(&self, value: uint32) -> Result<uint32>;
2421
25 fn caller_sensitive(&self, caller: caller) -> Result<uint8, Self::Error>;22 fn caller_sensitive(&self, caller: caller) -> Result<uint8>;
26 fn payable(&mut self, value: value) -> Result<uint8, Self::Error>;23 fn payable(&mut self, value: value) -> Result<uint8>;
27}24}
2825
29#[derive(ToLog)]26#[derive(ToLog)]
4441
45#[solidity_interface]42#[solidity_interface]
46trait ERC20 {43trait ERC20 {
47 type Error;
48
49 fn decimals(&self) -> Result<uint8, Self::Error>;44 fn decimals(&self) -> Result<uint8>;
50 fn balance_of(&self, owner: address) -> Result<uint256, Self::Error>;45 fn balance_of(&self, owner: address) -> Result<uint256>;
51 fn transfer(46 fn transfer(&mut self, caller: caller, to: address, value: uint256) -> Result<bool>;
52 &mut self,
53 caller: caller,
54 to: address,
55 value: uint256,
56 ) -> Result<bool, Self::Error>;
57 fn transfer_from(47 fn transfer_from(
58 &mut self,48 &mut self,
59 caller: caller,49 caller: caller,
60 from: address,50 from: address,
61 to: address,51 to: address,
62 value: uint256,52 value: uint256,
63 ) -> Result<bool, Self::Error>;53 ) -> Result<bool>;
64 fn approve(54 fn approve(&mut self, caller: caller, spender: address, value: uint256) -> Result<bool>;
65 &mut self,
66 caller: caller,
67 spender: address,
68 value: uint256,
69 ) -> Result<bool, Self::Error>;
70 fn allowance(&self, owner: address, spender: address) -> Result<uint256, Self::Error>;55 fn allowance(&self, owner: address, spender: address) -> Result<uint256>;
71}56}
7257