From a5e609e9e67c7b97b572627f133e9d668a80cac5 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Sun, 19 May 2019 18:31:05 +0300 Subject: [PATCH 1/3] MAINT: Removed manual Serialize/Deserialize implementaion from `enigma-types` --- enigma-crypto/src/hash.rs | 1 + enigma-types/Cargo.toml | 4 ++-- enigma-types/src/hash.rs | 49 ++++----------------------------------- 3 files changed, 7 insertions(+), 47 deletions(-) diff --git a/enigma-crypto/src/hash.rs b/enigma-crypto/src/hash.rs index 10ba9504..6b243d98 100644 --- a/enigma-crypto/src/hash.rs +++ b/enigma-crypto/src/hash.rs @@ -13,6 +13,7 @@ use enigma_types::Hash256; /// let ready = hash::prepare_hash_multiple(&[msg, msg2]); /// ``` #[cfg(any(feature = "sgx", feature = "std"))] +#[allow(unused_imports)] pub fn prepare_hash_multiple>(messages: &[B]) -> crate::localstd::vec::Vec { use crate::localstd::{vec::Vec, mem}; let mut res = Vec::with_capacity(messages.len() * mem::size_of::()); diff --git a/enigma-types/Cargo.toml b/enigma-types/Cargo.toml index 96d061c8..42b631a1 100644 --- a/enigma-types/Cargo.toml +++ b/enigma-types/Cargo.toml @@ -9,8 +9,8 @@ categories = ["no-std"] [dependencies] rustc-hex = { version = "2.0.1", default-features = false } arrayvec = { version = "0.4.10", default-features = false } -serde_sgx = { package = "serde", git = "https://github.com/mesalock-linux/serde-sgx.git", rev = "407aaaa2558dda5c2367d57ba40324c52cf9acc2", optional = true } -serde_std = { package = "serde", version = "1.0", default-features = false } +serde_sgx = { package = "serde", git = "https://github.com/mesalock-linux/serde-sgx.git", rev = "407aaaa2558dda5c2367d57ba40324c52cf9acc2", features = ["derive"], optional = true } +serde_std = { package = "serde", version = "1.0", default-features = false, features = ["derive"] } [build-dependencies] cbindgen = "0.8" diff --git a/enigma-types/src/hash.rs b/enigma-types/src/hash.rs index 2e79a7aa..6e6ab353 100644 --- a/enigma-types/src/hash.rs +++ b/enigma-types/src/hash.rs @@ -1,8 +1,11 @@ use core::ops::{Deref, DerefMut}; use rustc_hex::{FromHex, FromHexError}; use arrayvec::ArrayVec; +use crate::serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Default)] +#[serde(crate = "crate::serde")] #[repr(C)] -#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Default)] pub struct Hash256([u8; 32]); @@ -65,50 +68,6 @@ impl AsMut<[u8]> for Hash256 { } } -use crate::serde::de::{SeqAccess, Error}; -use core::fmt::{self, Formatter}; -use crate::serde::{Serialize, Deserialize, Serializer, Deserializer, de::Visitor}; - -impl Serialize for Hash256 { - fn serialize(&self, ser: S) -> Result where S: Serializer { - Serializer::serialize_newtype_struct(ser, "Hash256", &self.0) - } -} - -struct Hash256Visitor; - -impl<'de> Visitor<'de> for Hash256Visitor { - type Value = Hash256; - fn expecting(&self, fmt: &mut Formatter) -> fmt::Result { - fmt.write_str("tuple struct Hash256") - } - - fn visit_newtype_struct(self, err: E) -> Result where E: Deserializer<'de>, { - - match <[u8; 32] as Deserialize>::deserialize(err) { - Ok(field) => Ok(Hash256(field)), - Err(err) => Err(err), - } - } - - fn visit_seq(self, mut seq: A ) -> Result where A: SeqAccess<'de> { - match seq.next_element::<[u8; 32]>() { - Ok(v) => match v { - Some(field) => Ok(Hash256(field)), - None => Err(Error::invalid_length(0, &"tuple struct Hash256 with 1 element" )), - }, - Err(err) => Err(err) - } - } -} - - -impl<'de> Deserialize<'de> for Hash256 { - fn deserialize(des: D) -> Result where D: Deserializer<'de>, { - des.deserialize_newtype_struct("Hash256", Hash256Visitor) - } -} - #[cfg(test)] mod test { use super::Hash256; From 55fa44aac8ff202bee578c9163a260d69490b443 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Sun, 19 May 2019 18:31:25 +0300 Subject: [PATCH 2/3] MAINT: Removed manual Serialize/Deserialize implementaion from `enigma-tools-m` --- enigma-tools-m/Cargo.toml | 4 +- .../src/primitives/km_primitives.rs | 9 +- enigma-tools-m/src/primitives/mod.rs | 3 +- enigma-tools-m/src/primitives/serde_impls.rs | 224 ------------------ 4 files changed, 9 insertions(+), 231 deletions(-) delete mode 100644 enigma-tools-m/src/primitives/serde_impls.rs diff --git a/enigma-tools-m/Cargo.toml b/enigma-tools-m/Cargo.toml index dfbe720f..c5e9f4d8 100644 --- a/enigma-tools-m/Cargo.toml +++ b/enigma-tools-m/Cargo.toml @@ -19,7 +19,7 @@ rustc-hex = { version = "2.0.1", default-features = false } ethabi_std = { package = "ethabi", version = "6.0.1", optional = true } ethereum_types_std = { package = "ethereum-types", version = "0.4", optional = true } rmp_serde_std = { package = "rmp-serde", git = "https://github.com/3Hren/msgpack-rust.git", optional = true } -serde_std = { package = "serde", version = "1.0", default-features = false, optional = true } +serde_std = { package = "serde", version = "1.0", default-features = false, features = ["derive"], optional = true } serde_json_std = { package = "serde_json", version = "1.0", optional = true } @@ -28,7 +28,7 @@ ethabi_sgx = { package = "ethabi", git = "https://github.com/enigmampc/ethabi.gi ethereum_types_sgx = { package = "ethereum-types", git = "https://github.com/enigmampc/primitives.git", rev = "sgx-v0.4.0", default-features = false, optional = true } rmp_serde_sgx = { package = "rmp-serde", git = "https://github.com/enigmampc/msgpack-rust.git", rev = "0.14.0-sgx-1.0.8", optional = true } sgx_tstd = { git = "https://github.com/baidu/rust-sgx-sdk.git", rev = "v1.0.8", optional = true } -serde_sgx = { package = "serde", git = "https://github.com/mesalock-linux/serde-sgx.git", rev = "407aaaa2558dda5c2367d57ba40324c52cf9acc2", default-features = false, optional = true } +serde_sgx = { package = "serde", git = "https://github.com/mesalock-linux/serde-sgx.git", rev = "407aaaa2558dda5c2367d57ba40324c52cf9acc2", default-features = false, features = ["derive"], optional = true } serde_json_sgx = { package = "serde_json", git = "https://github.com/enigmampc/serde-json-sgx.git", rev = "1.0.39-sgx-1.0.8", optional = true } [features] diff --git a/enigma-tools-m/src/primitives/km_primitives.rs b/enigma-tools-m/src/primitives/km_primitives.rs index 04017b10..4349981d 100644 --- a/enigma-tools-m/src/primitives/km_primitives.rs +++ b/enigma-tools-m/src/primitives/km_primitives.rs @@ -8,14 +8,16 @@ use enigma_types::{ContractAddress, DhKey, PubKey, StateKey}; pub type MsgID = [u8; 12]; -#[derive(Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] +#[serde(crate = "crate::serde")] pub enum PrincipalMessageType { Response(Vec<(ContractAddress, StateKey)>), Request(Option>), EncryptedResponse(Vec), } -#[derive(Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] +#[serde(crate = "crate::serde")] pub struct PrincipalMessage { pub data: PrincipalMessageType, pub(crate) pubkey: Vec, @@ -131,7 +133,8 @@ impl<'a> Encryption<&'a DhKey, CryptoError, Self, [u8; 12]> for PrincipalMessage } } -#[derive(Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] +#[serde(crate = "crate::serde")] pub struct UserMessage { pub(crate) pubkey: Vec, } diff --git a/enigma-tools-m/src/primitives/mod.rs b/enigma-tools-m/src/primitives/mod.rs index 20cc0d91..7026788d 100644 --- a/enigma-tools-m/src/primitives/mod.rs +++ b/enigma-tools-m/src/primitives/mod.rs @@ -1,2 +1 @@ -pub mod km_primitives; -pub mod serde_impls; +pub mod km_primitives; \ No newline at end of file diff --git a/enigma-tools-m/src/primitives/serde_impls.rs b/enigma-tools-m/src/primitives/serde_impls.rs deleted file mode 100644 index fa1eaee5..00000000 --- a/enigma-tools-m/src/primitives/serde_impls.rs +++ /dev/null @@ -1,224 +0,0 @@ -use crate::localstd::fmt::{self, Formatter}; -use crate::localstd::vec::Vec; -use crate::primitives::km_primitives::*; -use crate::serde::{de::{EnumAccess, Error, IgnoredAny, MapAccess, SeqAccess, Unexpected, VariantAccess, Visitor}, - ser::SerializeStruct, - Deserialize, Deserializer, Serialize, Serializer}; -use enigma_types::{ContractAddress, StateKey}; -// The main reason why we need to implement Serialize/Deserialize ourselves is because the derive macro -// contains `extern crate serde as _serde` but we renamed serde. so that's invalid. https://github.com/serde-rs/serde/pull/1499 -impl Serialize for UserMessage { - fn serialize(&self, ser: S) -> Result - where S: Serializer { - let mut state = Serializer::serialize_struct(ser, "UserMessage", 1)?; - state.serialize_field("pubkey", &self.pubkey)?; - state.end() - } -} - -impl<'de> Deserialize<'de> for UserMessage { - fn deserialize(des: D) -> Result - where D: Deserializer<'de> { - struct UserMessageVisitor; - - impl<'de> Visitor<'de> for UserMessageVisitor { - type Value = UserMessage; - fn expecting(&self, fmt: &mut Formatter) -> fmt::Result { fmt.write_str("struct UserMessage") } - - fn visit_seq(self, mut seq: A) -> Result - where A: SeqAccess<'de> { - let err_msg = "struct UserMessage with 1 elements"; - let pubkey = seq.next_element::>()?.ok_or_else(|| Error::invalid_length(0, &err_msg))?; - if pubkey.len() != 64 { - return Err(Error::invalid_value(Unexpected::Bytes(&pubkey), &"The pubkey should be 64 bytes")); - } - Ok(UserMessage { pubkey }) - } - } - - des.deserialize_newtype_struct("UserMessage", UserMessageVisitor) - } -} - -impl Serialize for PrincipalMessageType { - fn serialize(&self, ser: S) -> Result - where S: Serializer { - match *self { - PrincipalMessageType::Response(ref f) => ser.serialize_newtype_variant("PrincipalMessageType", 0, "Response", f), - PrincipalMessageType::Request(ref f) => ser.serialize_newtype_variant("PrincipalMessageType", 1, "Request", f), - PrincipalMessageType::EncryptedResponse(ref f) => { - ser.serialize_newtype_variant("PrincipalMessageType", 2, "EncryptedResponse", f) - } - } - } -} - -impl<'de> Deserialize<'de> for PrincipalMessageType { - #[inline] - fn deserialize(des: D) -> Result - where D: Deserializer<'de> { - enum PrincipalMessageTypeFields { - Response, - Request, - EncryptedResponse, - } - struct FieldsVisitor; - - struct PrincipalMessageTypeVisitor; - const VARIANTS: &[&str] = &["Response", "Request", "EncryptedResponse"]; - - impl<'de> Visitor<'de> for FieldsVisitor { - type Value = PrincipalMessageTypeFields; - fn expecting(&self, fmt: &mut Formatter) -> fmt::Result { fmt.write_str("variant identifier") } - fn visit_str(self, value: &str) -> Result - where E: Error { - match value { - "Response" => Ok(PrincipalMessageTypeFields::Response), - "Request" => Ok(PrincipalMessageTypeFields::Request), - "EncryptedResponse" => Ok(PrincipalMessageTypeFields::EncryptedResponse), - _ => Err(Error::unknown_variant(value, VARIANTS)), - } - } - } - - impl<'de> Deserialize<'de> for PrincipalMessageTypeFields { - #[inline] - fn deserialize(des: D) -> Result - where D: Deserializer<'de> { - des.deserialize_identifier(FieldsVisitor) - } - } - - impl<'de> Visitor<'de> for PrincipalMessageTypeVisitor { - type Value = PrincipalMessageType; - fn expecting(&self, fmt: &mut Formatter) -> fmt::Result { fmt.write_str("enum PrincipalMessageType") } - fn visit_enum(self, data: A) -> Result - where A: EnumAccess<'de> { - match data.variant()? { - (PrincipalMessageTypeFields::Response, var) => { - var.newtype_variant::>().map(PrincipalMessageType::Response) - } - (PrincipalMessageTypeFields::Request, var) => { - var.newtype_variant::>>().map(PrincipalMessageType::Request) - } - (PrincipalMessageTypeFields::EncryptedResponse, var) => { - var.newtype_variant::>().map(PrincipalMessageType::EncryptedResponse) - } - } - } - } - - des.deserialize_enum("PrincipalMessageType", VARIANTS, PrincipalMessageTypeVisitor) - } -} - -impl Serialize for PrincipalMessage { - fn serialize(&self, ser: S) -> Result - where S: Serializer { - let mut state = Serializer::serialize_struct(ser, "PrincipalMessage", 3)?; - state.serialize_field("data", &self.data)?; - state.serialize_field("pubkey", &self.pubkey)?; - state.serialize_field("id", &self.id)?; - state.end() - } -} - -impl<'de> Deserialize<'de> for PrincipalMessage { - fn deserialize(des: D) -> Result - where D: Deserializer<'de> { - #[allow(non_camel_case_types)] - enum PrincipalMessageFields { - data, - pubkey, - id, - __ignore, - } - struct FieldsVisitor; - struct PrincipalMessageVisitor; - const VARIANTS: &[&str] = &["prefix", "data", "pubkey", "id"]; - - impl<'de> Visitor<'de> for FieldsVisitor { - type Value = PrincipalMessageFields; - fn expecting(&self, fmt: &mut Formatter) -> fmt::Result { fmt.write_str("field identifier") } - fn visit_str(self, value: &str) -> Result - where E: Error { - match value { - "data" => Ok(PrincipalMessageFields::data), - "pubkey" => Ok(PrincipalMessageFields::pubkey), - "id" => Ok(PrincipalMessageFields::id), - _ => Ok(PrincipalMessageFields::__ignore), - } - } - } - - impl<'de> Deserialize<'de> for PrincipalMessageFields { - #[inline] - fn deserialize(des: D) -> Result - where D: Deserializer<'de> { - des.deserialize_identifier(FieldsVisitor) - } - } - - impl<'de> Visitor<'de> for PrincipalMessageVisitor { - type Value = PrincipalMessage; - fn expecting(&self, fmt: &mut Formatter) -> fmt::Result { fmt.write_str("struct PrincipalMessage") } - - fn visit_seq(self, mut seq: A) -> Result - where A: SeqAccess<'de> { - let err_msg = "struct PrincipalMessage with 3 elements"; - let data = seq.next_element::()?.ok_or_else(|| Error::invalid_length(0, &err_msg))?; - let pubkey = seq.next_element::>()?.ok_or_else(|| Error::invalid_length(1, &err_msg))?; - if pubkey.len() != 64 { - return Err(Error::invalid_value(Unexpected::Bytes(&pubkey), &"The pubkey should be 64 bytes")); - } - let id = seq.next_element::()?.ok_or_else(|| Error::invalid_length(2, &err_msg))?; - - Ok(PrincipalMessage { data, pubkey, id }) - } - - fn visit_map(self, mut map: A) -> Result - where A: MapAccess<'de> { - let mut data: Option = None; - let mut pubkey: Option> = None; - let mut id: Option = None; - - while let Some(key) = map.next_key::()? { - match key { - PrincipalMessageFields::data => { - if data.is_some() { - return Err(::duplicate_field("data")); - } else { - data = Some(map.next_value()?); - } - } - PrincipalMessageFields::pubkey => { - if pubkey.is_some() { - return Err(::duplicate_field("pubkey")); - } else { - pubkey = Some(map.next_value()?); - } - } - PrincipalMessageFields::id => { - if id.is_some() { - return Err(::duplicate_field("id")); - } else { - id = Some(map.next_value()?); - } - } - _ => { - map.next_value::()?; - } - } - } - - let data = data.ok_or_else(|| Error::missing_field("data"))?; - let pubkey = pubkey.ok_or_else(|| Error::missing_field("pubkey"))?; - let id = id.ok_or_else(|| Error::missing_field("id"))?; - - Ok(PrincipalMessage { data, pubkey, id }) - } - } - - des.deserialize_struct("PrincipalMessage", VARIANTS, PrincipalMessageVisitor) - } -} From e94ddd366825d096ed6a71d271955ea50de7b7d5 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Wed, 22 May 2019 15:04:00 +0300 Subject: [PATCH 3/3] MAINT: Ignoring `#[no_mangle]` warnings we can remove that next rustc update https://github.com/rust-lang/rust/issues/60050 --- eng-wasm/derive/src/lib.rs | 2 ++ eng-wasm/src/lib.rs | 2 ++ enigma-core/enclave/src/lib.rs | 4 +++- enigma-principal/enclave/src/lib.rs | 1 + .../eng_wasm_contracts/contract_with_eth_calls/src/lib.rs | 1 + examples/eng_wasm_contracts/erc20/src/lib.rs | 2 +- .../eng_wasm_contracts/millionaires_problem_demo/src/lib.rs | 1 + examples/eng_wasm_contracts/simple_addition/src/lib.rs | 1 + examples/eng_wasm_contracts/simple_calculator/src/lib.rs | 2 +- examples/eng_wasm_contracts/simplest/src/lib.rs | 1 + examples/eng_wasm_contracts/voting_demo/src/lib.rs | 4 +--- 11 files changed, 15 insertions(+), 6 deletions(-) diff --git a/eng-wasm/derive/src/lib.rs b/eng-wasm/derive/src/lib.rs index 62747111..547cda27 100755 --- a/eng-wasm/derive/src/lib.rs +++ b/eng-wasm/derive/src/lib.rs @@ -2,6 +2,8 @@ #![feature(box_patterns)] #![recursion_limit="128"] #![feature(slice_concat_ext)] +#![allow(unused_attributes)] // TODO: Remove on future nightly https://github.com/rust-lang/rust/issues/60050 + extern crate eng_wasm; extern crate proc_macro2; diff --git a/eng-wasm/src/lib.rs b/eng-wasm/src/lib.rs index 078f4b28..ee576d1b 100755 --- a/eng-wasm/src/lib.rs +++ b/eng-wasm/src/lib.rs @@ -1,6 +1,8 @@ #![no_std] #![feature(slice_concat_ext)] #![deny(unused_extern_crates)] +#![allow(unused_attributes)] // TODO: Remove on future nightly https://github.com/rust-lang/rust/issues/60050 + /// Enigma implementation of bindings to the Enigma runtime. /// This crate should be used in contracts. diff --git a/enigma-core/enclave/src/lib.rs b/enigma-core/enclave/src/lib.rs index 0103b8f8..2e5afdfc 100755 --- a/enigma-core/enclave/src/lib.rs +++ b/enigma-core/enclave/src/lib.rs @@ -2,9 +2,11 @@ #![crate_type = "staticlib"] #![no_std] #![cfg_attr(target_env = "sgx", feature(rustc_private))] + #![warn(clippy::all)] -#![allow(clippy::cast_ptr_alignment)] // TODO: Try to remove it when fixing the sealing #![warn(unused_extern_crates)] +#![allow(clippy::cast_ptr_alignment)] // TODO: Try to remove it when fixing the sealing +#![allow(unused_attributes)] // TODO: Remove on future nightly https://github.com/rust-lang/rust/issues/60050 extern crate enigma_runtime_t; #[macro_use] diff --git a/enigma-principal/enclave/src/lib.rs b/enigma-principal/enclave/src/lib.rs index 535cc4ed..f3216b4f 100644 --- a/enigma-principal/enclave/src/lib.rs +++ b/enigma-principal/enclave/src/lib.rs @@ -5,6 +5,7 @@ #![feature(slice_concat_ext)] #![deny(unused_extern_crates)] +#![allow(unused_attributes)] // https://github.com/rust-lang/rust/issues/60050 extern crate enigma_crypto; extern crate enigma_tools_m; diff --git a/examples/eng_wasm_contracts/contract_with_eth_calls/src/lib.rs b/examples/eng_wasm_contracts/contract_with_eth_calls/src/lib.rs index f8745b8d..0747b5cc 100755 --- a/examples/eng_wasm_contracts/contract_with_eth_calls/src/lib.rs +++ b/examples/eng_wasm_contracts/contract_with_eth_calls/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![allow(unused_attributes)] // TODO: Remove on future nightly https://github.com/rust-lang/rust/issues/60050 extern crate eng_wasm; diff --git a/examples/eng_wasm_contracts/erc20/src/lib.rs b/examples/eng_wasm_contracts/erc20/src/lib.rs index c4b34e74..2a91c31a 100755 --- a/examples/eng_wasm_contracts/erc20/src/lib.rs +++ b/examples/eng_wasm_contracts/erc20/src/lib.rs @@ -1,5 +1,5 @@ #![no_std] - +#![allow(unused_attributes)] // TODO: Remove on future nightly https://github.com/rust-lang/rust/issues/60050 diff --git a/examples/eng_wasm_contracts/millionaires_problem_demo/src/lib.rs b/examples/eng_wasm_contracts/millionaires_problem_demo/src/lib.rs index 7a765afc..a5764c9e 100644 --- a/examples/eng_wasm_contracts/millionaires_problem_demo/src/lib.rs +++ b/examples/eng_wasm_contracts/millionaires_problem_demo/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![allow(unused_attributes)] // TODO: Remove on future nightly https://github.com/rust-lang/rust/issues/60050 diff --git a/examples/eng_wasm_contracts/simple_addition/src/lib.rs b/examples/eng_wasm_contracts/simple_addition/src/lib.rs index 0c2786d8..be9eb461 100755 --- a/examples/eng_wasm_contracts/simple_addition/src/lib.rs +++ b/examples/eng_wasm_contracts/simple_addition/src/lib.rs @@ -2,6 +2,7 @@ // features of its host system: threads, networking, heap allocation, and others. SGX environments // do not have these features, so we tell Rust that we don’t want to use the standard library #![no_std] +#![allow(unused_attributes)] // TODO: Remove on future nightly https://github.com/rust-lang/rust/issues/60050 diff --git a/examples/eng_wasm_contracts/simple_calculator/src/lib.rs b/examples/eng_wasm_contracts/simple_calculator/src/lib.rs index afd3f2f5..cd05f700 100755 --- a/examples/eng_wasm_contracts/simple_calculator/src/lib.rs +++ b/examples/eng_wasm_contracts/simple_calculator/src/lib.rs @@ -1,5 +1,5 @@ #![no_std] - +#![allow(unused_attributes)] // TODO: Remove on future nightly https://github.com/rust-lang/rust/issues/60050 diff --git a/examples/eng_wasm_contracts/simplest/src/lib.rs b/examples/eng_wasm_contracts/simplest/src/lib.rs index 28f9c4c4..d0984868 100755 --- a/examples/eng_wasm_contracts/simplest/src/lib.rs +++ b/examples/eng_wasm_contracts/simplest/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![allow(unused_attributes)] // TODO: Remove on future nightly https://github.com/rust-lang/rust/issues/60050 diff --git a/examples/eng_wasm_contracts/voting_demo/src/lib.rs b/examples/eng_wasm_contracts/voting_demo/src/lib.rs index b6c37c87..cd99b768 100644 --- a/examples/eng_wasm_contracts/voting_demo/src/lib.rs +++ b/examples/eng_wasm_contracts/voting_demo/src/lib.rs @@ -1,7 +1,5 @@ #![no_std] - - - +#![allow(unused_attributes)] // https://github.com/rust-lang/rust/issues/60050 extern crate eng_wasm; extern crate eng_wasm_derive;