fix(eip712): improve argument parsing (#1485)
* fix(eip712): improve argument parsing * use reexported serde_json * chore: rustfmt * fix: add missing salt
This commit is contained in:
parent
1d4f3efe8a
commit
a958b4fd28
|
@ -42,7 +42,7 @@ pub(crate) fn struct_declaration(cx: &Context) -> TokenStream {
|
||||||
|
|
||||||
let abi_parse = if !cx.human_readable {
|
let abi_parse = if !cx.human_readable {
|
||||||
quote! {
|
quote! {
|
||||||
pub static #abi_name: #ethers_contract::Lazy<#ethers_core::abi::Abi> = #ethers_contract::Lazy::new(|| serde_json::from_str(#abi)
|
pub static #abi_name: #ethers_contract::Lazy<#ethers_core::abi::Abi> = #ethers_contract::Lazy::new(|| #ethers_core::utils::__serde_json::from_str(#abi)
|
||||||
.expect("invalid abi"));
|
.expect("invalid abi"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -61,7 +61,6 @@
|
||||||
//! determine if there is a nested eip712 struct. However, this work is not yet complete.
|
//! determine if there is a nested eip712 struct. However, this work is not yet complete.
|
||||||
|
|
||||||
#![deny(rustdoc::broken_intra_doc_links)]
|
#![deny(rustdoc::broken_intra_doc_links)]
|
||||||
#![deny(unused_crate_dependencies)]
|
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
@ -121,7 +120,7 @@ fn impl_eip_712_macro(ast: &syn::DeriveInput) -> TokenStream {
|
||||||
|
|
||||||
fn type_hash() -> Result<[u8; 32], Self::Error> {
|
fn type_hash() -> Result<[u8; 32], Self::Error> {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
let decoded = hex::decode(#type_hash)?;
|
let decoded = #ethers_core::utils::hex::decode(#type_hash)?;
|
||||||
let byte_array: [u8; 32] = <[u8; 32]>::try_from(&decoded[..])?;
|
let byte_array: [u8; 32] = <[u8; 32]>::try_from(&decoded[..])?;
|
||||||
Ok(byte_array)
|
Ok(byte_array)
|
||||||
}
|
}
|
||||||
|
@ -129,13 +128,13 @@ fn impl_eip_712_macro(ast: &syn::DeriveInput) -> TokenStream {
|
||||||
// Return the pre-computed domain separator from compile time;
|
// Return the pre-computed domain separator from compile time;
|
||||||
fn domain_separator(&self) -> Result<[u8; 32], Self::Error> {
|
fn domain_separator(&self) -> Result<[u8; 32], Self::Error> {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
let decoded = hex::decode(#domain_separator)?;
|
let decoded = #ethers_core::utils::hex::decode(#domain_separator)?;
|
||||||
let byte_array: [u8; 32] = <[u8; 32]>::try_from(&decoded[..])?;
|
let byte_array: [u8; 32] = <[u8; 32]>::try_from(&decoded[..])?;
|
||||||
Ok(byte_array)
|
Ok(byte_array)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn domain(&self) -> Result<#ethers_core::types::transaction::eip712::EIP712Domain, Self::Error> {
|
fn domain(&self) -> Result<#ethers_core::types::transaction::eip712::EIP712Domain, Self::Error> {
|
||||||
let domain: #ethers_core::types::transaction::eip712::EIP712Domain = serde_json::from_str(#domain_str)?;
|
let domain: #ethers_core::types::transaction::eip712::EIP712Domain = # ethers_core::utils::__serde_json::from_str(#domain_str)?;
|
||||||
|
|
||||||
Ok(domain)
|
Ok(domain)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use syn::{
|
||||||
use crate::{
|
use crate::{
|
||||||
abi,
|
abi,
|
||||||
abi::{ParamType, Token},
|
abi::{ParamType, Token},
|
||||||
types::{Address, H160, U256},
|
types::{Address, U256},
|
||||||
utils::keccak256,
|
utils::keccak256,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -196,9 +196,14 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
||||||
type Error = TokenStream;
|
type Error = TokenStream;
|
||||||
fn try_from(input: &syn::DeriveInput) -> Result<EIP712Domain, Self::Error> {
|
fn try_from(input: &syn::DeriveInput) -> Result<EIP712Domain, Self::Error> {
|
||||||
let mut domain = EIP712Domain::default();
|
let mut domain = EIP712Domain::default();
|
||||||
|
let mut domain_name = None;
|
||||||
|
let mut domain_version = None;
|
||||||
|
let mut chain_id = None;
|
||||||
|
let mut verifying_contract = None;
|
||||||
|
|
||||||
let mut found_eip712_attribute = false;
|
let mut found_eip712_attribute = false;
|
||||||
|
|
||||||
for attribute in input.attrs.iter() {
|
'attribute_search: for attribute in input.attrs.iter() {
|
||||||
if let AttrStyle::Outer = attribute.style {
|
if let AttrStyle::Outer = attribute.style {
|
||||||
if let Ok(syn::Meta::List(meta)) = attribute.parse_meta() {
|
if let Ok(syn::Meta::List(meta)) = attribute.parse_meta() {
|
||||||
if meta.path.is_ident("eip712") {
|
if meta.path.is_ident("eip712") {
|
||||||
|
@ -219,7 +224,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
||||||
match ident.to_string().as_ref() {
|
match ident.to_string().as_ref() {
|
||||||
"name" => match meta.lit {
|
"name" => match meta.lit {
|
||||||
syn::Lit::Str(ref lit_str) => {
|
syn::Lit::Str(ref lit_str) => {
|
||||||
if domain.name != String::default() {
|
if domain_name.is_some() {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
meta.path.span(),
|
meta.path.span(),
|
||||||
"domain name already specified",
|
"domain name already specified",
|
||||||
|
@ -227,7 +232,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
||||||
.to_compile_error())
|
.to_compile_error())
|
||||||
}
|
}
|
||||||
|
|
||||||
domain.name = lit_str.value();
|
domain_name = Some(lit_str.value());
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
|
@ -239,7 +244,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
||||||
},
|
},
|
||||||
"version" => match meta.lit {
|
"version" => match meta.lit {
|
||||||
syn::Lit::Str(ref lit_str) => {
|
syn::Lit::Str(ref lit_str) => {
|
||||||
if domain.version != String::default() {
|
if domain_version.is_some() {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
meta.path.span(),
|
meta.path.span(),
|
||||||
"domain version already specified",
|
"domain version already specified",
|
||||||
|
@ -247,7 +252,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
||||||
.to_compile_error())
|
.to_compile_error())
|
||||||
}
|
}
|
||||||
|
|
||||||
domain.version = lit_str.value();
|
domain_version = Some(lit_str.value());
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
|
@ -259,7 +264,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
||||||
},
|
},
|
||||||
"chain_id" => match meta.lit {
|
"chain_id" => match meta.lit {
|
||||||
syn::Lit::Int(ref lit_int) => {
|
syn::Lit::Int(ref lit_int) => {
|
||||||
if domain.chain_id != U256::default() {
|
if chain_id.is_some() {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
meta.path.span(),
|
meta.path.span(),
|
||||||
"domain chain_id already specified",
|
"domain chain_id already specified",
|
||||||
|
@ -267,7 +272,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
||||||
.to_compile_error())
|
.to_compile_error())
|
||||||
}
|
}
|
||||||
|
|
||||||
domain.chain_id = U256::from(
|
chain_id = Some(U256::from(
|
||||||
lit_int.base10_parse::<u64>().map_err(
|
lit_int.base10_parse::<u64>().map_err(
|
||||||
|_| {
|
|_| {
|
||||||
Error::new(
|
Error::new(
|
||||||
|
@ -277,7 +282,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
||||||
.to_compile_error()
|
.to_compile_error()
|
||||||
},
|
},
|
||||||
)?,
|
)?,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
|
@ -289,8 +294,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
||||||
},
|
},
|
||||||
"verifying_contract" => match meta.lit {
|
"verifying_contract" => match meta.lit {
|
||||||
syn::Lit::Str(ref lit_str) => {
|
syn::Lit::Str(ref lit_str) => {
|
||||||
if domain.verifying_contract != H160::default()
|
if verifying_contract.is_some() {
|
||||||
{
|
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
meta.path.span(),
|
meta.path.span(),
|
||||||
"domain verifying_contract already specified",
|
"domain verifying_contract already specified",
|
||||||
|
@ -298,13 +302,13 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
||||||
.to_compile_error());
|
.to_compile_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
domain.verifying_contract = lit_str.value().parse().map_err(|_| {
|
verifying_contract = Some(lit_str.value().parse().map_err(|_| {
|
||||||
Error::new(
|
Error::new(
|
||||||
meta.path.span(),
|
meta.path.span(),
|
||||||
"failed to parse verifying contract into Address",
|
"failed to parse verifying contract into Address",
|
||||||
)
|
)
|
||||||
.to_compile_error()
|
.to_compile_error()
|
||||||
})?;
|
})?);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
|
@ -316,7 +320,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
||||||
},
|
},
|
||||||
"salt" => match meta.lit {
|
"salt" => match meta.lit {
|
||||||
syn::Lit::Str(ref lit_str) => {
|
syn::Lit::Str(ref lit_str) => {
|
||||||
if domain.salt != Option::None {
|
if domain.salt.is_some() {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
meta.path.span(),
|
meta.path.span(),
|
||||||
"domain salt already specified",
|
"domain salt already specified",
|
||||||
|
@ -365,36 +369,41 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if domain.name == String::default() {
|
domain.name = domain_name.ok_or_else(|| {
|
||||||
return Err(Error::new(
|
Error::new(
|
||||||
meta.path.span(),
|
meta.path.span(),
|
||||||
"missing required domain attribute: 'name'".to_string(),
|
"missing required domain attribute: 'name'".to_string(),
|
||||||
)
|
)
|
||||||
.to_compile_error())
|
.to_compile_error()
|
||||||
}
|
})?;
|
||||||
if domain.version == String::default() {
|
|
||||||
return Err(Error::new(
|
domain.version = domain_version.ok_or_else(|| {
|
||||||
|
Error::new(
|
||||||
meta.path.span(),
|
meta.path.span(),
|
||||||
"missing required domain attribute: 'version'".to_string(),
|
"missing required domain attribute: 'version'".to_string(),
|
||||||
)
|
)
|
||||||
.to_compile_error())
|
.to_compile_error()
|
||||||
}
|
})?;
|
||||||
if domain.chain_id == U256::default() {
|
|
||||||
return Err(Error::new(
|
domain.chain_id = chain_id.ok_or_else(|| {
|
||||||
|
Error::new(
|
||||||
meta.path.span(),
|
meta.path.span(),
|
||||||
"missing required domain attribute: 'chain_id'".to_string(),
|
"missing required domain attribute: 'chain_id'".to_string(),
|
||||||
)
|
)
|
||||||
.to_compile_error())
|
.to_compile_error()
|
||||||
}
|
})?;
|
||||||
if domain.verifying_contract == H160::default() {
|
|
||||||
return Err(Error::new(
|
domain.verifying_contract = verifying_contract.ok_or_else(|| {
|
||||||
|
Error::new(
|
||||||
meta.path.span(),
|
meta.path.span(),
|
||||||
"missing required domain attribute: 'verifying_contract'"
|
"missing required domain attribute: 'verifying_contract'"
|
||||||
.to_string(),
|
.to_string(),
|
||||||
)
|
)
|
||||||
.to_compile_error())
|
.to_compile_error()
|
||||||
}
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break 'attribute_search
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,12 @@ use k256::{ecdsa::SigningKey, PublicKey as K256PublicKey};
|
||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::{TryFrom, TryInto};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
/// Re-export of serde-json
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub mod __serde_json {
|
||||||
|
pub use serde_json::*;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum ConversionError {
|
pub enum ConversionError {
|
||||||
#[error("Unknown units: {0}")]
|
#[error("Unknown units: {0}")]
|
||||||
|
|
Loading…
Reference in New Issue