Skip to content

Instantly share code, notes, and snippets.

@mfornet
Last active February 11, 2022 22:46
Show Gist options
  • Save mfornet/bedc71fe0d0122540bb07718f76b713b to your computer and use it in GitHub Desktop.
Save mfornet/bedc71fe0d0122540bb07718f76b713b to your computer and use it in GitHub Desktop.
Macros expanded for rainbow bridge contracts
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2018::*;
#[macro_use]
extern crate std;
use borsh::{BorshDeserialize, BorshSerialize};
use eth_types::*;
use near_plugins::{only, pause, FullAccessKeyFallback, Ownable, Pausable, Upgradable};
use near_sdk::collections::UnorderedMap;
use near_sdk::AccountId;
use near_sdk::{env, near_bindgen, PanicOnDefault};
pub struct DoubleNodeWithMerkleProof {
pub dag_nodes: Vec<H512>,
pub proof: Vec<H128>,
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::default::Default for DoubleNodeWithMerkleProof {
#[inline]
fn default() -> DoubleNodeWithMerkleProof {
DoubleNodeWithMerkleProof {
dag_nodes: ::core::default::Default::default(),
proof: ::core::default::Default::default(),
}
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::fmt::Debug for DoubleNodeWithMerkleProof {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match *self {
DoubleNodeWithMerkleProof {
dag_nodes: ref __self_0_0,
proof: ref __self_0_1,
} => {
let debug_trait_builder =
&mut ::core::fmt::Formatter::debug_struct(f, "DoubleNodeWithMerkleProof");
let _ = ::core::fmt::DebugStruct::field(
debug_trait_builder,
"dag_nodes",
&&(*__self_0_0),
);
let _ =
::core::fmt::DebugStruct::field(debug_trait_builder, "proof", &&(*__self_0_1));
::core::fmt::DebugStruct::finish(debug_trait_builder)
}
}
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for DoubleNodeWithMerkleProof {
#[inline]
fn clone(&self) -> DoubleNodeWithMerkleProof {
match *self {
DoubleNodeWithMerkleProof {
dag_nodes: ref __self_0_0,
proof: ref __self_0_1,
} => DoubleNodeWithMerkleProof {
dag_nodes: ::core::clone::Clone::clone(&(*__self_0_0)),
proof: ::core::clone::Clone::clone(&(*__self_0_1)),
},
}
}
}
impl borsh::de::BorshDeserialize for DoubleNodeWithMerkleProof
where
Vec<H512>: borsh::BorshDeserialize,
Vec<H128>: borsh::BorshDeserialize,
{
fn deserialize(buf: &mut &[u8]) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
dag_nodes: borsh::BorshDeserialize::deserialize(buf)?,
proof: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
impl borsh::ser::BorshSerialize for DoubleNodeWithMerkleProof
where
Vec<H512>: borsh::ser::BorshSerialize,
Vec<H128>: borsh::ser::BorshSerialize,
{
fn serialize<W: borsh::maybestd::io::Write>(
&self,
writer: &mut W,
) -> ::core::result::Result<(), borsh::maybestd::io::Error> {
borsh::BorshSerialize::serialize(&self.dag_nodes, writer)?;
borsh::BorshSerialize::serialize(&self.proof, writer)?;
Ok(())
}
}
impl DoubleNodeWithMerkleProof {
fn truncate_to_h128(arr: H256) -> H128 {
let mut data = [0u8; 16];
data.copy_from_slice(&(arr.0).0[16..]);
H128(data.into())
}
fn hash_h128(l: H128, r: H128) -> H128 {
let mut data = [0u8; 64];
data[16..32].copy_from_slice(&(l.0).0);
data[48..64].copy_from_slice(&(r.0).0);
Self::truncate_to_h128(near_sha256(&data).into())
}
pub fn apply_merkle_proof(&self, index: u64) -> H128 {
let mut data = [0u8; 128];
data[..64].copy_from_slice(&(self.dag_nodes[0].0).0);
data[64..].copy_from_slice(&(self.dag_nodes[1].0).0);
let mut leaf = Self::truncate_to_h128(near_sha256(&data).into());
for i in 0..self.proof.len() {
if (index >> i as u64) % 2 == 0 {
leaf = Self::hash_h128(leaf, self.proof[i]);
} else {
leaf = Self::hash_h128(self.proof[i], leaf);
}
}
leaf
}
}
/// Minimal information about a header.
pub struct HeaderInfo {
pub total_difficulty: U256,
pub parent_hash: H256,
pub number: u64,
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::default::Default for HeaderInfo {
#[inline]
fn default() -> HeaderInfo {
HeaderInfo {
total_difficulty: ::core::default::Default::default(),
parent_hash: ::core::default::Default::default(),
number: ::core::default::Default::default(),
}
}
}
impl borsh::de::BorshDeserialize for HeaderInfo
where
U256: borsh::BorshDeserialize,
H256: borsh::BorshDeserialize,
u64: borsh::BorshDeserialize,
{
fn deserialize(buf: &mut &[u8]) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
total_difficulty: borsh::BorshDeserialize::deserialize(buf)?,
parent_hash: borsh::BorshDeserialize::deserialize(buf)?,
number: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
impl borsh::ser::BorshSerialize for HeaderInfo
where
U256: borsh::ser::BorshSerialize,
H256: borsh::ser::BorshSerialize,
u64: borsh::ser::BorshSerialize,
{
fn serialize<W: borsh::maybestd::io::Write>(
&self,
writer: &mut W,
) -> ::core::result::Result<(), borsh::maybestd::io::Error> {
borsh::BorshSerialize::serialize(&self.total_difficulty, writer)?;
borsh::BorshSerialize::serialize(&self.parent_hash, writer)?;
borsh::BorshSerialize::serialize(&self.number, writer)?;
Ok(())
}
}
pub struct EthClient {
/// Whether client validates the PoW when accepting the header. Should only be set to `false`
/// for debugging, testing, diagnostic purposes when used with Ganache or in PoA testnets
validate_ethash: bool,
/// The epoch from which the DAG merkle roots start.
dags_start_epoch: u64,
/// DAG merkle roots for the next several years.
dags_merkle_roots: Vec<H128>,
/// Hash of the header that has the highest cumulative difficulty. The current head of the
/// canonical chain.
best_header_hash: H256,
/// We store the hashes of the blocks for the past `hashes_gc_threshold` headers.
/// Events that happen past this threshold cannot be verified by the client.
/// It is desirable that this number is larger than 7 days worth of headers, which is roughly
/// 40k Ethereum blocks. So this number should be 40k in production.
hashes_gc_threshold: u64,
/// We store full information about the headers for the past `finalized_gc_threshold` blocks.
/// This is required to be able to adjust the canonical chain when the fork switch happens.
/// The commonly used number is 500 blocks, so this number should be 500 in production.
finalized_gc_threshold: u64,
/// Number of confirmations that applications can use to consider the transaction safe.
/// For most use cases 25 should be enough, for super safe cases it should be 500.
num_confirmations: u64,
/// Hashes of the canonical chain mapped to their numbers. Stores up to `hashes_gc_threshold`
/// entries.
/// header number -> header hash
canonical_header_hashes: UnorderedMap<u64, H256>,
/// All known header hashes. Stores up to `finalized_gc_threshold`.
/// header number -> hashes of all headers with this number.
all_header_hashes: UnorderedMap<u64, Vec<H256>>,
/// Known headers. Stores up to `finalized_gc_threshold`.
headers: UnorderedMap<H256, BlockHeader>,
/// Minimal information about the headers, like cumulative difficulty. Stores up to
/// `finalized_gc_threshold`.
infos: UnorderedMap<H256, HeaderInfo>,
/// If set, block header added by trusted signer will skip validation and added by
/// others will be immediately rejected, used in PoA testnets
trusted_signer: Option<AccountId>,
__paused: u128,
}
impl borsh::de::BorshDeserialize for EthClient
where
bool: borsh::BorshDeserialize,
u64: borsh::BorshDeserialize,
Vec<H128>: borsh::BorshDeserialize,
H256: borsh::BorshDeserialize,
u64: borsh::BorshDeserialize,
u64: borsh::BorshDeserialize,
u64: borsh::BorshDeserialize,
UnorderedMap<u64, H256>: borsh::BorshDeserialize,
UnorderedMap<u64, Vec<H256>>: borsh::BorshDeserialize,
UnorderedMap<H256, BlockHeader>: borsh::BorshDeserialize,
UnorderedMap<H256, HeaderInfo>: borsh::BorshDeserialize,
Option<AccountId>: borsh::BorshDeserialize,
u128: borsh::BorshDeserialize,
{
fn deserialize(buf: &mut &[u8]) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
validate_ethash: borsh::BorshDeserialize::deserialize(buf)?,
dags_start_epoch: borsh::BorshDeserialize::deserialize(buf)?,
dags_merkle_roots: borsh::BorshDeserialize::deserialize(buf)?,
best_header_hash: borsh::BorshDeserialize::deserialize(buf)?,
hashes_gc_threshold: borsh::BorshDeserialize::deserialize(buf)?,
finalized_gc_threshold: borsh::BorshDeserialize::deserialize(buf)?,
num_confirmations: borsh::BorshDeserialize::deserialize(buf)?,
canonical_header_hashes: borsh::BorshDeserialize::deserialize(buf)?,
all_header_hashes: borsh::BorshDeserialize::deserialize(buf)?,
headers: borsh::BorshDeserialize::deserialize(buf)?,
infos: borsh::BorshDeserialize::deserialize(buf)?,
trusted_signer: borsh::BorshDeserialize::deserialize(buf)?,
__paused: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
impl borsh::ser::BorshSerialize for EthClient
where
bool: borsh::ser::BorshSerialize,
u64: borsh::ser::BorshSerialize,
Vec<H128>: borsh::ser::BorshSerialize,
H256: borsh::ser::BorshSerialize,
u64: borsh::ser::BorshSerialize,
u64: borsh::ser::BorshSerialize,
u64: borsh::ser::BorshSerialize,
UnorderedMap<u64, H256>: borsh::ser::BorshSerialize,
UnorderedMap<u64, Vec<H256>>: borsh::ser::BorshSerialize,
UnorderedMap<H256, BlockHeader>: borsh::ser::BorshSerialize,
UnorderedMap<H256, HeaderInfo>: borsh::ser::BorshSerialize,
Option<AccountId>: borsh::ser::BorshSerialize,
u128: borsh::ser::BorshSerialize,
{
fn serialize<W: borsh::maybestd::io::Write>(
&self,
writer: &mut W,
) -> ::core::result::Result<(), borsh::maybestd::io::Error> {
borsh::BorshSerialize::serialize(&self.validate_ethash, writer)?;
borsh::BorshSerialize::serialize(&self.dags_start_epoch, writer)?;
borsh::BorshSerialize::serialize(&self.dags_merkle_roots, writer)?;
borsh::BorshSerialize::serialize(&self.best_header_hash, writer)?;
borsh::BorshSerialize::serialize(&self.hashes_gc_threshold, writer)?;
borsh::BorshSerialize::serialize(&self.finalized_gc_threshold, writer)?;
borsh::BorshSerialize::serialize(&self.num_confirmations, writer)?;
borsh::BorshSerialize::serialize(&self.canonical_header_hashes, writer)?;
borsh::BorshSerialize::serialize(&self.all_header_hashes, writer)?;
borsh::BorshSerialize::serialize(&self.headers, writer)?;
borsh::BorshSerialize::serialize(&self.infos, writer)?;
borsh::BorshSerialize::serialize(&self.trusted_signer, writer)?;
borsh::BorshSerialize::serialize(&self.__paused, writer)?;
Ok(())
}
}
impl Default for EthClient {
fn default() -> Self {
near_sdk::env::panic_str("The contract is not initialized");
}
}
impl Ownable for EthClient {
fn owner_storage_key(&self) -> Vec<u8> {
("__OWNER__").as_bytes().to_vec()
}
fn owner_get(&self) -> Option<::near_sdk::AccountId> {
::near_sdk::env::storage_read(&self.owner_storage_key()).map(|owner_bytes| {
let owner_raw = String::from_utf8(owner_bytes).expect("Ownable: Invalid string format");
std::convert::TryInto::try_into(owner_raw).expect("Ownable: Invalid account id")
})
}
fn owner_set(&mut self, owner: Option<::near_sdk::AccountId>) {
let current_owner = self.owner_get();
if let Some(owner) = current_owner.as_ref() {
{
match (&&::near_sdk::env::predecessor_account_id(), &owner) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::Some(::core::fmt::Arguments::new_v1(
&["Ownable: Only owner can update current owner"],
&[],
)),
);
}
}
}
};
} else {
{
match (
&::near_sdk::env::predecessor_account_id(),
&::near_sdk::env::current_account_id(),
) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::Some(::core::fmt::Arguments::new_v1(
&["Ownable: Owner not set. Only self can set the owner"],
&[],
)),
);
}
}
}
};
}
::near_sdk::env::log_str(
near_plugins::events::AsEvent::event(&near_plugins::ownable::OwnershipTransferred {
previous_owner: current_owner,
new_owner: owner.clone(),
})
.as_ref(),
);
match owner.as_ref() {
Some(owner) => {
::near_sdk::env::storage_write(&self.owner_storage_key(), owner.as_ref().as_bytes())
}
None => ::near_sdk::env::storage_remove(&self.owner_storage_key()),
};
}
fn owner_is(&self) -> bool {
self.owner_get().map_or(false, |owner| {
owner == ::near_sdk::env::predecessor_account_id()
})
}
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn owner_storage_key() {
near_sdk::env::setup_panic_hook();
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.owner_storage_key();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn owner_get() {
near_sdk::env::setup_panic_hook();
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.owner_get();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn owner_set() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method owner_set doesn\'t accept deposit");
}
#[serde(crate = "near_sdk::serde")]
struct Input {
owner: Option<::near_sdk::AccountId>,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _IMPL_DESERIALIZE_FOR_Input: () = {
use near_sdk::serde as _serde;
#[automatically_derived]
impl<'de> near_sdk::serde::Deserialize<'de> for Input {
fn deserialize<__D>(
__deserializer: __D,
) -> near_sdk::serde::export::Result<Self, __D::Error>
where
__D: near_sdk::serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(
self,
__value: u64,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"owner" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"owner" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::export::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de> {
marker: _serde::export::PhantomData<Input>,
lifetime: _serde::export::PhantomData<&'de ()>,
}
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Input;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "struct Input")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 = match match _serde::de::SeqAccess::next_element::<
Option<::near_sdk::AccountId>,
>(&mut __seq)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
} {
_serde::export::Some(__value) => __value,
_serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(
0usize,
&"struct Input with 1 element",
));
}
};
_serde::export::Ok(Input { owner: __field0 })
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::export::Option<Option<::near_sdk::AccountId>> =
_serde::export::None;
while let _serde::export::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::export::Option::is_some(&__field0) {
return _serde::export::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"owner",
),
);
}
__field0 = _serde::export::Some(
match _serde::de::MapAccess::next_value::<
Option<::near_sdk::AccountId>,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::export::Some(__field0) => __field0,
_serde::export::None => {
match _serde::private::de::missing_field("owner") {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
}
};
_serde::export::Ok(Input { owner: __field0 })
}
}
const FIELDS: &'static [&'static str] = &["owner"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"Input",
FIELDS,
__Visitor {
marker: _serde::export::PhantomData::<Input>,
lifetime: _serde::export::PhantomData,
},
)
}
}
};
let Input { owner }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");
let mut contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
contract.owner_set(owner);
near_sdk::env::state_write(&contract);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn owner_is() {
near_sdk::env::setup_panic_hook();
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.owner_is();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
impl Pausable for EthClient {
fn pa_storage_key(&self) -> Vec<u8> {
("__PAUSE__").as_bytes().to_vec()
}
fn pa_is_paused(&self, key: String) -> bool {
self.pa_all_paused()
.map(|keys| keys.contains(&key) || keys.contains("ALL"))
.unwrap_or(false)
}
fn pa_all_paused(&self) -> Option<std::collections::HashSet<String>> {
::near_sdk::env::storage_read(self.pa_storage_key().as_ref()).map(|value| {
std::collections::HashSet::try_from_slice(value.as_ref())
.expect("Pausable: Invalid format for paused keys")
})
}
fn pa_pause_feature(&mut self, key: String) {
if !self.owner_is() {
{
::std::rt::begin_panic("Ownable: Method must be called from owner")
}
};
let mut paused_keys = self.pa_all_paused().unwrap_or_default();
paused_keys.insert(key.clone());
::near_sdk::env::log_str(
near_plugins::events::AsEvent::event(&near_plugins::pausable::Pause {
by: ::near_sdk::env::predecessor_account_id(),
key,
})
.as_ref(),
);
::near_sdk::env::storage_write(
self.pa_storage_key().as_ref(),
paused_keys
.try_to_vec()
.expect("Pausable: Unexpected error serializing keys")
.as_ref(),
);
}
fn pa_unpause_feature(&mut self, key: String) {
if !self.owner_is() {
{
::std::rt::begin_panic("Ownable: Method must be called from owner")
}
};
let mut paused_keys = self.pa_all_paused().unwrap_or_default();
paused_keys.remove(&key);
::near_sdk::env::log_str(
near_plugins::events::AsEvent::event(&near_plugins::pausable::Unpause {
by: ::near_sdk::env::predecessor_account_id(),
key,
})
.as_ref(),
);
if paused_keys.is_empty() {
::near_sdk::env::storage_remove(self.pa_storage_key().as_ref());
} else {
::near_sdk::env::storage_write(
self.pa_storage_key().as_ref(),
paused_keys
.try_to_vec()
.expect("Pausable: Unexpected error serializing keys")
.as_ref(),
);
}
}
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn pa_storage_key() {
near_sdk::env::setup_panic_hook();
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.pa_storage_key();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn pa_is_paused() {
near_sdk::env::setup_panic_hook();
#[serde(crate = "near_sdk::serde")]
struct Input {
key: String,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _IMPL_DESERIALIZE_FOR_Input: () = {
use near_sdk::serde as _serde;
#[automatically_derived]
impl<'de> near_sdk::serde::Deserialize<'de> for Input {
fn deserialize<__D>(
__deserializer: __D,
) -> near_sdk::serde::export::Result<Self, __D::Error>
where
__D: near_sdk::serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(
self,
__value: u64,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::export::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de> {
marker: _serde::export::PhantomData<Input>,
lifetime: _serde::export::PhantomData<&'de ()>,
}
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Input;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "struct Input")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 =
match match _serde::de::SeqAccess::next_element::<String>(&mut __seq) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
} {
_serde::export::Some(__value) => __value,
_serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(
0usize,
&"struct Input with 1 element",
));
}
};
_serde::export::Ok(Input { key: __field0 })
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::export::Option<String> = _serde::export::None;
while let _serde::export::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::export::Option::is_some(&__field0) {
return _serde::export::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"key",
),
);
}
__field0 = _serde::export::Some(
match _serde::de::MapAccess::next_value::<String>(
&mut __map,
) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::export::Some(__field0) => __field0,
_serde::export::None => match _serde::private::de::missing_field("key")
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
};
_serde::export::Ok(Input { key: __field0 })
}
}
const FIELDS: &'static [&'static str] = &["key"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"Input",
FIELDS,
__Visitor {
marker: _serde::export::PhantomData::<Input>,
lifetime: _serde::export::PhantomData,
},
)
}
}
};
let Input { key }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.pa_is_paused(key);
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn pa_all_paused() {
near_sdk::env::setup_panic_hook();
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.pa_all_paused();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn pa_pause_feature() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method pa_pause_feature doesn\'t accept deposit");
}
#[serde(crate = "near_sdk::serde")]
struct Input {
key: String,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _IMPL_DESERIALIZE_FOR_Input: () = {
use near_sdk::serde as _serde;
#[automatically_derived]
impl<'de> near_sdk::serde::Deserialize<'de> for Input {
fn deserialize<__D>(
__deserializer: __D,
) -> near_sdk::serde::export::Result<Self, __D::Error>
where
__D: near_sdk::serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(
self,
__value: u64,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::export::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de> {
marker: _serde::export::PhantomData<Input>,
lifetime: _serde::export::PhantomData<&'de ()>,
}
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Input;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "struct Input")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 =
match match _serde::de::SeqAccess::next_element::<String>(&mut __seq) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
} {
_serde::export::Some(__value) => __value,
_serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(
0usize,
&"struct Input with 1 element",
));
}
};
_serde::export::Ok(Input { key: __field0 })
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::export::Option<String> = _serde::export::None;
while let _serde::export::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::export::Option::is_some(&__field0) {
return _serde::export::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"key",
),
);
}
__field0 = _serde::export::Some(
match _serde::de::MapAccess::next_value::<String>(
&mut __map,
) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::export::Some(__field0) => __field0,
_serde::export::None => match _serde::private::de::missing_field("key")
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
};
_serde::export::Ok(Input { key: __field0 })
}
}
const FIELDS: &'static [&'static str] = &["key"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"Input",
FIELDS,
__Visitor {
marker: _serde::export::PhantomData::<Input>,
lifetime: _serde::export::PhantomData,
},
)
}
}
};
let Input { key }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");
let mut contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
contract.pa_pause_feature(key);
near_sdk::env::state_write(&contract);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn pa_unpause_feature() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method pa_unpause_feature doesn\'t accept deposit");
}
#[serde(crate = "near_sdk::serde")]
struct Input {
key: String,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _IMPL_DESERIALIZE_FOR_Input: () = {
use near_sdk::serde as _serde;
#[automatically_derived]
impl<'de> near_sdk::serde::Deserialize<'de> for Input {
fn deserialize<__D>(
__deserializer: __D,
) -> near_sdk::serde::export::Result<Self, __D::Error>
where
__D: near_sdk::serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(
self,
__value: u64,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::export::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de> {
marker: _serde::export::PhantomData<Input>,
lifetime: _serde::export::PhantomData<&'de ()>,
}
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Input;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "struct Input")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 =
match match _serde::de::SeqAccess::next_element::<String>(&mut __seq) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
} {
_serde::export::Some(__value) => __value,
_serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(
0usize,
&"struct Input with 1 element",
));
}
};
_serde::export::Ok(Input { key: __field0 })
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::export::Option<String> = _serde::export::None;
while let _serde::export::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::export::Option::is_some(&__field0) {
return _serde::export::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"key",
),
);
}
__field0 = _serde::export::Some(
match _serde::de::MapAccess::next_value::<String>(
&mut __map,
) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::export::Some(__field0) => __field0,
_serde::export::None => match _serde::private::de::missing_field("key")
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
};
_serde::export::Ok(Input { key: __field0 })
}
}
const FIELDS: &'static [&'static str] = &["key"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"Input",
FIELDS,
__Visitor {
marker: _serde::export::PhantomData::<Input>,
lifetime: _serde::export::PhantomData,
},
)
}
}
};
let Input { key }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");
let mut contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
contract.pa_unpause_feature(key);
near_sdk::env::state_write(&contract);
}
impl Upgradable for EthClient {
fn up_storage_key(&self) -> Vec<u8> {
("__CODE__").as_bytes().to_vec()
}
fn up_stage_code(&mut self, code: Vec<u8>) {
if !self.owner_is() {
{
::std::rt::begin_panic("Ownable: Method must be called from owner")
}
};
if code.is_empty() {
near_sdk::env::storage_remove(self.up_storage_key().as_ref());
} else {
near_sdk::env::storage_write(self.up_storage_key().as_ref(), code.as_ref());
}
}
fn up_staged_code(&self) -> Option<Vec<u8>> {
near_sdk::env::storage_read(self.up_storage_key().as_ref())
}
fn up_staged_code_hash(&self) -> Option<::near_sdk::CryptoHash> {
self.up_staged_code().map(|code| {
std::convert::TryInto::try_into(near_sdk::env::sha256(code.as_ref())).unwrap()
})
}
fn up_deploy_code(&mut self) -> near_sdk::Promise {
if !self.owner_is() {
{
::std::rt::begin_panic("Ownable: Method must be called from owner")
}
};
near_sdk::Promise::new(near_sdk::env::current_account_id())
.deploy_contract(self.up_staged_code().expect("Upgradable: No staged code"))
}
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn up_storage_key() {
near_sdk::env::setup_panic_hook();
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.up_storage_key();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn up_stage_code() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method up_stage_code doesn\'t accept deposit");
}
struct Input {
code: Vec<u8>,
}
impl borsh::de::BorshDeserialize for Input
where
Vec<u8>: borsh::BorshDeserialize,
{
fn deserialize(
buf: &mut &[u8],
) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
code: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
let Input { code }: Input = near_sdk::borsh::BorshDeserialize::try_from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from Borsh.");
let mut contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
contract.up_stage_code(code);
near_sdk::env::state_write(&contract);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn up_staged_code() {
near_sdk::env::setup_panic_hook();
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.up_staged_code();
let result = near_sdk::borsh::BorshSerialize::try_to_vec(&result)
.expect("Failed to serialize the return value using Borsh.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn up_staged_code_hash() {
near_sdk::env::setup_panic_hook();
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.up_staged_code_hash();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn up_deploy_code() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method up_deploy_code doesn\'t accept deposit");
}
let mut contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.up_deploy_code();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
near_sdk::env::state_write(&contract);
}
impl FullAccessKeyFallback for EthClient {
fn attach_full_access_key(&mut self, public_key: ::near_sdk::PublicKey) -> near_sdk::Promise {
if !self.owner_is() {
{
::std::rt::begin_panic("Ownable: Method must be called from owner")
}
};
let current_account_id = ::near_sdk::env::current_account_id();
::near_sdk::env::log_str(
near_plugins::events::AsEvent::event(
&near_plugins::full_access_key_fallback::FullAccessKeyAdded {
by: current_account_id.clone(),
public_key: public_key.clone(),
},
)
.as_ref(),
);
::near_sdk::Promise::new(current_account_id).add_full_access_key(public_key)
}
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn attach_full_access_key() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method attach_full_access_key doesn\'t accept deposit");
}
#[serde(crate = "near_sdk::serde")]
struct Input {
public_key: ::near_sdk::PublicKey,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _IMPL_DESERIALIZE_FOR_Input: () = {
use near_sdk::serde as _serde;
#[automatically_derived]
impl<'de> near_sdk::serde::Deserialize<'de> for Input {
fn deserialize<__D>(
__deserializer: __D,
) -> near_sdk::serde::export::Result<Self, __D::Error>
where
__D: near_sdk::serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(
self,
__value: u64,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"public_key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"public_key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::export::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de> {
marker: _serde::export::PhantomData<Input>,
lifetime: _serde::export::PhantomData<&'de ()>,
}
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Input;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "struct Input")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 = match match _serde::de::SeqAccess::next_element::<
::near_sdk::PublicKey,
>(&mut __seq)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
} {
_serde::export::Some(__value) => __value,
_serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(
0usize,
&"struct Input with 1 element",
));
}
};
_serde::export::Ok(Input {
public_key: __field0,
})
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::export::Option<::near_sdk::PublicKey> =
_serde::export::None;
while let _serde::export::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::export::Option::is_some(&__field0) {
return _serde::export::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"public_key",
),
);
}
__field0 = _serde::export::Some(
match _serde::de::MapAccess::next_value::<
::near_sdk::PublicKey,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::export::Some(__field0) => __field0,
_serde::export::None => {
match _serde::private::de::missing_field("public_key") {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
}
};
_serde::export::Ok(Input {
public_key: __field0,
})
}
}
const FIELDS: &'static [&'static str] = &["public_key"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"Input",
FIELDS,
__Visitor {
marker: _serde::export::PhantomData::<Input>,
lifetime: _serde::export::PhantomData,
},
)
}
}
};
let Input { public_key }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");
let mut contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.attach_full_access_key(public_key);
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
near_sdk::env::state_write(&contract);
}
impl EthClient {
pub fn init(
validate_ethash: bool,
dags_start_epoch: u64,
dags_merkle_roots: Vec<H128>,
first_header: Vec<u8>,
hashes_gc_threshold: u64,
finalized_gc_threshold: u64,
num_confirmations: u64,
trusted_signer: Option<AccountId>,
) -> Self {
let header: BlockHeader = rlp::decode(first_header.as_slice()).unwrap();
let header_hash = header.hash.unwrap().clone();
let header_number = header.number;
let mut res = Self {
validate_ethash,
dags_start_epoch,
dags_merkle_roots,
best_header_hash: header_hash.clone(),
hashes_gc_threshold,
finalized_gc_threshold,
num_confirmations,
canonical_header_hashes: UnorderedMap::new(b"c".to_vec()),
all_header_hashes: UnorderedMap::new(b"a".to_vec()),
headers: UnorderedMap::new(b"h".to_vec()),
infos: UnorderedMap::new(b"i".to_vec()),
trusted_signer,
__paused: Default::default(),
};
res.canonical_header_hashes
.insert(&header_number, &header_hash);
res.all_header_hashes
.insert(&header_number, &<[_]>::into_vec(box [header_hash.clone()]));
res.headers.insert(&header_hash, &header);
res.infos.insert(
&header_hash,
&HeaderInfo {
total_difficulty: Default::default(),
parent_hash: Default::default(),
number: header_number,
},
);
res
}
pub fn initialized() -> bool {
env::state_read::<EthClient>().is_some()
}
pub fn dag_merkle_root(&self, epoch: u64) -> H128 {
self.dags_merkle_roots[(&epoch - self.dags_start_epoch) as usize]
}
pub fn last_block_number(&self) -> u64 {
self.infos
.get(&self.best_header_hash)
.unwrap_or_default()
.number
}
/// Returns the block hash from the canonical chain.
pub fn block_hash(&self, index: u64) -> Option<H256> {
self.canonical_header_hashes.get(&index)
}
/// Returns all hashes known for that height.
pub fn known_hashes(&self, index: u64) -> Vec<H256> {
self.all_header_hashes.get(&index).unwrap_or_default()
}
/// Returns block hash and the number of confirmations.
pub fn block_hash_safe(&self, index: u64) -> Option<H256> {
let header_hash = self.block_hash(index)?;
let last_block_number = self.last_block_number();
if index + self.num_confirmations > last_block_number {
None
} else {
Some(header_hash)
}
}
/// Add the block header to the client.
/// `block_header` -- RLP-encoded Ethereum header;
/// `dag_nodes` -- dag nodes with their merkle proofs.
pub fn add_block_header(
&mut self,
block_header: Vec<u8>,
dag_nodes: Vec<DoubleNodeWithMerkleProof>,
) {
let mut check_paused = true;
if check_paused {
if !!self.pa_is_paused("add_block_header".to_string()) {
{
::std::rt::begin_panic("Pausable: Method is paused")
}
};
}
env::log_str("Add block header");
let header: BlockHeader = rlp::decode(block_header.as_slice()).unwrap();
if let Some(trusted_signer) = &self.trusted_signer {
{
match (&&env::signer_account_id(), &trusted_signer) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
:: core :: panicking :: assert_failed (kind , & * left_val , & * right_val , :: core :: option :: Option :: Some (:: core :: fmt :: Arguments :: new_v1 (& ["Eth-client is deployed as trust mode, only trusted_signer can add a new header"] , & []))) ;
}
}
}
};
} else {
let prev = self
.headers
.get(&header.parent_hash)
.expect("Parent header should be present to add a new header");
if !self.verify_header(&header, &prev, &dag_nodes) {
{
::std::rt::panic_fmt(::core::fmt::Arguments::new_v1(
&["The new header ", " should be valid"],
&[::core::fmt::ArgumentV1::new_display(&header.number)],
))
}
};
}
self.record_header(header);
}
pub fn update_trusted_signer(&mut self, trusted_signer: Option<AccountId>) {
if !self.owner_is() {
{
::std::rt::begin_panic("Ownable: Method must be called from owner")
}
};
self.trusted_signer = trusted_signer;
}
pub fn get_trusted_signer(&self) -> Option<AccountId> {
self.trusted_signer.clone()
}
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn init() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method init doesn\'t accept deposit");
}
struct Input {
validate_ethash: bool,
dags_start_epoch: u64,
dags_merkle_roots: Vec<H128>,
first_header: Vec<u8>,
hashes_gc_threshold: u64,
finalized_gc_threshold: u64,
num_confirmations: u64,
trusted_signer: Option<AccountId>,
}
impl borsh::de::BorshDeserialize for Input
where
bool: borsh::BorshDeserialize,
u64: borsh::BorshDeserialize,
Vec<H128>: borsh::BorshDeserialize,
Vec<u8>: borsh::BorshDeserialize,
u64: borsh::BorshDeserialize,
u64: borsh::BorshDeserialize,
u64: borsh::BorshDeserialize,
Option<AccountId>: borsh::BorshDeserialize,
{
fn deserialize(
buf: &mut &[u8],
) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
validate_ethash: borsh::BorshDeserialize::deserialize(buf)?,
dags_start_epoch: borsh::BorshDeserialize::deserialize(buf)?,
dags_merkle_roots: borsh::BorshDeserialize::deserialize(buf)?,
first_header: borsh::BorshDeserialize::deserialize(buf)?,
hashes_gc_threshold: borsh::BorshDeserialize::deserialize(buf)?,
finalized_gc_threshold: borsh::BorshDeserialize::deserialize(buf)?,
num_confirmations: borsh::BorshDeserialize::deserialize(buf)?,
trusted_signer: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
let Input {
validate_ethash,
dags_start_epoch,
dags_merkle_roots,
first_header,
hashes_gc_threshold,
finalized_gc_threshold,
num_confirmations,
trusted_signer,
}: Input = near_sdk::borsh::BorshDeserialize::try_from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from Borsh.");
if near_sdk::env::state_exists() {
near_sdk::env::panic_str("The contract has already been initialized");
}
let contract = EthClient::init(
validate_ethash,
dags_start_epoch,
dags_merkle_roots,
first_header,
hashes_gc_threshold,
finalized_gc_threshold,
num_confirmations,
trusted_signer,
);
near_sdk::env::state_write(&contract);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn initialized() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method initialized doesn\'t accept deposit");
}
let result = EthClient::initialized();
let result = near_sdk::borsh::BorshSerialize::try_to_vec(&result)
.expect("Failed to serialize the return value using Borsh.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn dag_merkle_root() {
near_sdk::env::setup_panic_hook();
struct Input {
epoch: u64,
}
impl borsh::de::BorshDeserialize for Input
where
u64: borsh::BorshDeserialize,
{
fn deserialize(
buf: &mut &[u8],
) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
epoch: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
let Input { epoch }: Input = near_sdk::borsh::BorshDeserialize::try_from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from Borsh.");
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.dag_merkle_root(epoch);
let result = near_sdk::borsh::BorshSerialize::try_to_vec(&result)
.expect("Failed to serialize the return value using Borsh.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn last_block_number() {
near_sdk::env::setup_panic_hook();
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.last_block_number();
let result = near_sdk::borsh::BorshSerialize::try_to_vec(&result)
.expect("Failed to serialize the return value using Borsh.");
near_sdk::env::value_return(&result);
}
/// Returns the block hash from the canonical chain.
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn block_hash() {
near_sdk::env::setup_panic_hook();
struct Input {
index: u64,
}
impl borsh::de::BorshDeserialize for Input
where
u64: borsh::BorshDeserialize,
{
fn deserialize(
buf: &mut &[u8],
) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
index: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
let Input { index }: Input = near_sdk::borsh::BorshDeserialize::try_from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from Borsh.");
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.block_hash(index);
let result = near_sdk::borsh::BorshSerialize::try_to_vec(&result)
.expect("Failed to serialize the return value using Borsh.");
near_sdk::env::value_return(&result);
}
/// Returns all hashes known for that height.
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn known_hashes() {
near_sdk::env::setup_panic_hook();
struct Input {
index: u64,
}
impl borsh::de::BorshDeserialize for Input
where
u64: borsh::BorshDeserialize,
{
fn deserialize(
buf: &mut &[u8],
) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
index: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
let Input { index }: Input = near_sdk::borsh::BorshDeserialize::try_from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from Borsh.");
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.known_hashes(index);
let result = near_sdk::borsh::BorshSerialize::try_to_vec(&result)
.expect("Failed to serialize the return value using Borsh.");
near_sdk::env::value_return(&result);
}
/// Returns block hash and the number of confirmations.
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn block_hash_safe() {
near_sdk::env::setup_panic_hook();
struct Input {
index: u64,
}
impl borsh::de::BorshDeserialize for Input
where
u64: borsh::BorshDeserialize,
{
fn deserialize(
buf: &mut &[u8],
) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
index: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
let Input { index }: Input = near_sdk::borsh::BorshDeserialize::try_from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from Borsh.");
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.block_hash_safe(index);
let result = near_sdk::borsh::BorshSerialize::try_to_vec(&result)
.expect("Failed to serialize the return value using Borsh.");
near_sdk::env::value_return(&result);
}
/// Add the block header to the client.
/// `block_header` -- RLP-encoded Ethereum header;
/// `dag_nodes` -- dag nodes with their merkle proofs.
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn add_block_header() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method add_block_header doesn\'t accept deposit");
}
struct Input {
block_header: Vec<u8>,
dag_nodes: Vec<DoubleNodeWithMerkleProof>,
}
impl borsh::de::BorshDeserialize for Input
where
Vec<u8>: borsh::BorshDeserialize,
Vec<DoubleNodeWithMerkleProof>: borsh::BorshDeserialize,
{
fn deserialize(
buf: &mut &[u8],
) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
block_header: borsh::BorshDeserialize::deserialize(buf)?,
dag_nodes: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
let Input {
block_header,
dag_nodes,
}: Input = near_sdk::borsh::BorshDeserialize::try_from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from Borsh.");
let mut contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
contract.add_block_header(block_header, dag_nodes);
near_sdk::env::state_write(&contract);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn update_trusted_signer() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method update_trusted_signer doesn\'t accept deposit");
}
#[serde(crate = "near_sdk::serde")]
struct Input {
trusted_signer: Option<AccountId>,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _IMPL_DESERIALIZE_FOR_Input: () = {
use near_sdk::serde as _serde;
#[automatically_derived]
impl<'de> near_sdk::serde::Deserialize<'de> for Input {
fn deserialize<__D>(
__deserializer: __D,
) -> near_sdk::serde::export::Result<Self, __D::Error>
where
__D: near_sdk::serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(
self,
__value: u64,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"trusted_signer" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"trusted_signer" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::export::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de> {
marker: _serde::export::PhantomData<Input>,
lifetime: _serde::export::PhantomData<&'de ()>,
}
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Input;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "struct Input")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 = match match _serde::de::SeqAccess::next_element::<
Option<AccountId>,
>(&mut __seq)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
} {
_serde::export::Some(__value) => __value,
_serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(
0usize,
&"struct Input with 1 element",
));
}
};
_serde::export::Ok(Input {
trusted_signer: __field0,
})
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::export::Option<Option<AccountId>> =
_serde::export::None;
while let _serde::export::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::export::Option::is_some(&__field0) {
return _serde::export::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"trusted_signer",
),
);
}
__field0 = _serde::export::Some(
match _serde::de::MapAccess::next_value::<Option<AccountId>>(
&mut __map,
) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::export::Some(__field0) => __field0,
_serde::export::None => {
match _serde::private::de::missing_field("trusted_signer") {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
}
};
_serde::export::Ok(Input {
trusted_signer: __field0,
})
}
}
const FIELDS: &'static [&'static str] = &["trusted_signer"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"Input",
FIELDS,
__Visitor {
marker: _serde::export::PhantomData::<Input>,
lifetime: _serde::export::PhantomData,
},
)
}
}
};
let Input { trusted_signer }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");
let mut contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
contract.update_trusted_signer(trusted_signer);
near_sdk::env::state_write(&contract);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn get_trusted_signer() {
near_sdk::env::setup_panic_hook();
let contract: EthClient = near_sdk::env::state_read().unwrap_or_default();
let result = contract.get_trusted_signer();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
impl EthClient {
/// Record the header. If needed update the canonical chain and perform the GC.
fn record_header(&mut self, header: BlockHeader) {
env::log_str("Record header");
let best_info = self.infos.get(&self.best_header_hash).unwrap();
let header_hash = header.hash.unwrap();
let header_number = header.number;
if header_number + self.finalized_gc_threshold < best_info.number {
{
::std::rt::begin_panic(
"Header is too old to have a chance to appear on the canonical chain.",
)
};
}
let parent_info = self
.infos
.get(&header.parent_hash)
.expect("Header has unknown parent. Parent should be submitted first.");
let mut all_hashes = self
.all_header_hashes
.get(&header_number)
.unwrap_or_default();
if !all_hashes.iter().find(|x| **x == header_hash).is_none() {
{
::std::rt::panic_fmt(::core::fmt::Arguments::new_v1(
&["Header is already known. Number: "],
&[::core::fmt::ArgumentV1::new_display(&header_number)],
))
}
};
all_hashes.push(header_hash);
self.all_header_hashes.insert(&header_number, &all_hashes);
env::log_str("Inserting header");
self.headers.insert(&header_hash, &header);
let info = HeaderInfo {
total_difficulty: parent_info.total_difficulty + header.difficulty,
parent_hash: header.parent_hash.clone(),
number: header_number,
};
self.infos.insert(&header_hash, &info);
env::log_str("Inserted");
if info.total_difficulty > best_info.total_difficulty
|| (info.total_difficulty == best_info.total_difficulty
&& header.difficulty % 2 == U256::default())
{
env::log_str("Canonical chain needs to be updated.");
if best_info.number > info.number {
for number in info.number + 1..=best_info.number {
self.canonical_header_hashes.remove(&number);
}
}
self.best_header_hash = header_hash;
self.canonical_header_hashes
.insert(&header_number, &header_hash);
let mut number = header.number - 1;
let mut current_hash = info.parent_hash;
loop {
let prev_value = self.canonical_header_hashes.insert(&number, &current_hash);
if number == 0 || prev_value == Some(current_hash) {
break;
}
if let Some(info) = self.infos.get(&current_hash) {
current_hash = info.parent_hash;
} else {
break;
}
number -= 1;
}
if header_number >= self.hashes_gc_threshold {
self.gc_canonical_chain(header_number - self.hashes_gc_threshold);
}
if header_number >= self.finalized_gc_threshold {
self.gc_headers(header_number - self.finalized_gc_threshold);
}
}
}
/// Remove hashes from the canonical chain that are at least as old as the given header number.
fn gc_canonical_chain(&mut self, mut header_number: u64) {
loop {
if self.canonical_header_hashes.get(&header_number).is_some() {
self.canonical_header_hashes.remove(&header_number);
if header_number == 0 {
break;
} else {
header_number -= 1;
}
} else {
break;
}
}
}
/// Remove information about the headers that are at least as old as the given header number.
fn gc_headers(&mut self, mut header_number: u64) {
env::log_str(
{
let res = ::alloc::fmt::format(::core::fmt::Arguments::new_v1(
&["Run headers GC. Used gas: "],
&[::core::fmt::ArgumentV1::new_debug(&env::used_gas())],
));
res
}
.as_str(),
);
loop {
if let Some(all_headers) = self.all_header_hashes.get(&header_number) {
for hash in all_headers {
self.headers.remove_raw(&hash.try_to_vec().unwrap());
self.infos.remove(&hash);
}
self.all_header_hashes.remove(&header_number);
if header_number == 0 {
break;
} else {
header_number -= 1;
}
} else {
break;
}
}
env::log_str(
{
let res = ::alloc::fmt::format(::core::fmt::Arguments::new_v1(
&["Finish headers GC. Used gas: "],
&[::core::fmt::ArgumentV1::new_debug(&env::used_gas())],
));
res
}
.as_str(),
);
}
/// Verify PoW of the header.
fn verify_header(
&self,
header: &BlockHeader,
prev: &BlockHeader,
dag_nodes: &[DoubleNodeWithMerkleProof],
) -> bool {
let (_mix_hash, result) = self.hashimoto_merkle(
&header.partial_hash.unwrap(),
&header.nonce,
header.number,
dag_nodes,
);
U256((result.0).0.into()) < U256(ethash::cross_boundary(header.difficulty.0))
&& (!self.validate_ethash
|| (header.difficulty < prev.difficulty * 101 / 100
&& header.difficulty > prev.difficulty * 99 / 100))
&& header.gas_used <= header.gas_limit
&& header.gas_limit < prev.gas_limit * 1025 / 1024
&& header.gas_limit > prev.gas_limit * 1023 / 1024
&& header.gas_limit >= U256(5000.into())
&& header.timestamp > prev.timestamp
&& header.number == prev.number + 1
&& header.parent_hash == prev.hash.unwrap()
&& header.extra_data.len() <= 32
}
/// Verify merkle paths to the DAG nodes.
fn hashimoto_merkle(
&self,
header_hash: &H256,
nonce: &H64,
header_number: u64,
nodes: &[DoubleNodeWithMerkleProof],
) -> (H256, H256) {
let index = std::cell::RefCell::new(0);
let merkle_root = self.dag_merkle_root((header_number as usize / 30000) as u64);
let pair = ethash::hashimoto_with_hasher(
header_hash.0,
nonce.0,
ethash::get_full_size(header_number / 30000),
|offset| {
let idx = *index.borrow_mut();
*index.borrow_mut() += 1;
let node = &nodes[idx / 2];
if idx % 2 == 0 && self.validate_ethash {
{
match (&merkle_root, &node.apply_merkle_proof((offset / 2) as u64)) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::None,
);
}
}
}
};
};
let mut data = (node.dag_nodes[idx % 2].0).0;
data[..32].reverse();
data[32..].reverse();
data.into()
},
near_keccak256,
near_keccak512,
);
(H256(pair.0), H256(pair.1))
}
}
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2018::*;
#[macro_use]
extern crate std;
use borsh::{BorshDeserialize, BorshSerialize};
use eth_types::{near_keccak256, BlockHeader, LogEntry, Receipt, H256};
use near_plugins::{only, pause, FullAccessKeyFallback, Ownable, Pausable, Upgradable};
use near_sdk::{env, ext_contract, near_bindgen, AccountId, Gas, PanicOnDefault, PromiseOrValue};
use rlp::Rlp;
/// Gas to call block_hash_safe
const BLOCK_HASH_SAFE_GAS: Gas = Gas(10 * Gas::ONE_TERA.0);
/// Gas to call on_block_hash
const ON_BLOCK_HASH_GAS: Gas = Gas(5 * Gas::ONE_TERA.0);
pub struct EthProver {
bridge_smart_contract: AccountId,
__paused: u128,
}
impl borsh::de::BorshDeserialize for EthProver
where
AccountId: borsh::BorshDeserialize,
u128: borsh::BorshDeserialize,
{
fn deserialize(buf: &mut &[u8]) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
bridge_smart_contract: borsh::BorshDeserialize::deserialize(buf)?,
__paused: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
impl borsh::ser::BorshSerialize for EthProver
where
AccountId: borsh::ser::BorshSerialize,
u128: borsh::ser::BorshSerialize,
{
fn serialize<W: borsh::maybestd::io::Write>(
&self,
writer: &mut W,
) -> ::core::result::Result<(), borsh::maybestd::io::Error> {
borsh::BorshSerialize::serialize(&self.bridge_smart_contract, writer)?;
borsh::BorshSerialize::serialize(&self.__paused, writer)?;
Ok(())
}
}
impl Default for EthProver {
fn default() -> Self {
near_sdk::env::panic_str("The contract is not initialized");
}
}
impl Ownable for EthProver {
fn owner_storage_key(&self) -> Vec<u8> {
("__OWNER__").as_bytes().to_vec()
}
fn owner_get(&self) -> Option<::near_sdk::AccountId> {
::near_sdk::env::storage_read(&self.owner_storage_key()).map(|owner_bytes| {
let owner_raw = String::from_utf8(owner_bytes).expect("Ownable: Invalid string format");
std::convert::TryInto::try_into(owner_raw).expect("Ownable: Invalid account id")
})
}
fn owner_set(&mut self, owner: Option<::near_sdk::AccountId>) {
let current_owner = self.owner_get();
if let Some(owner) = current_owner.as_ref() {
{
match (&&::near_sdk::env::predecessor_account_id(), &owner) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::Some(::core::fmt::Arguments::new_v1(
&["Ownable: Only owner can update current owner"],
&[],
)),
);
}
}
}
};
} else {
{
match (
&::near_sdk::env::predecessor_account_id(),
&::near_sdk::env::current_account_id(),
) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::Some(::core::fmt::Arguments::new_v1(
&["Ownable: Owner not set. Only self can set the owner"],
&[],
)),
);
}
}
}
};
}
::near_sdk::env::log_str(
near_plugins::events::AsEvent::event(&near_plugins::ownable::OwnershipTransferred {
previous_owner: current_owner,
new_owner: owner.clone(),
})
.as_ref(),
);
match owner.as_ref() {
Some(owner) => {
::near_sdk::env::storage_write(&self.owner_storage_key(), owner.as_ref().as_bytes())
}
None => ::near_sdk::env::storage_remove(&self.owner_storage_key()),
};
}
fn owner_is(&self) -> bool {
self.owner_get().map_or(false, |owner| {
owner == ::near_sdk::env::predecessor_account_id()
})
}
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn owner_storage_key() {
near_sdk::env::setup_panic_hook();
let contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.owner_storage_key();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn owner_get() {
near_sdk::env::setup_panic_hook();
let contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.owner_get();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn owner_set() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method owner_set doesn\'t accept deposit");
}
#[serde(crate = "near_sdk::serde")]
struct Input {
owner: Option<::near_sdk::AccountId>,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _IMPL_DESERIALIZE_FOR_Input: () = {
use near_sdk::serde as _serde;
#[automatically_derived]
impl<'de> near_sdk::serde::Deserialize<'de> for Input {
fn deserialize<__D>(
__deserializer: __D,
) -> near_sdk::serde::export::Result<Self, __D::Error>
where
__D: near_sdk::serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(
self,
__value: u64,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"owner" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"owner" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::export::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de> {
marker: _serde::export::PhantomData<Input>,
lifetime: _serde::export::PhantomData<&'de ()>,
}
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Input;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "struct Input")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 = match match _serde::de::SeqAccess::next_element::<
Option<::near_sdk::AccountId>,
>(&mut __seq)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
} {
_serde::export::Some(__value) => __value,
_serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(
0usize,
&"struct Input with 1 element",
));
}
};
_serde::export::Ok(Input { owner: __field0 })
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::export::Option<Option<::near_sdk::AccountId>> =
_serde::export::None;
while let _serde::export::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::export::Option::is_some(&__field0) {
return _serde::export::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"owner",
),
);
}
__field0 = _serde::export::Some(
match _serde::de::MapAccess::next_value::<
Option<::near_sdk::AccountId>,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::export::Some(__field0) => __field0,
_serde::export::None => {
match _serde::private::de::missing_field("owner") {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
}
};
_serde::export::Ok(Input { owner: __field0 })
}
}
const FIELDS: &'static [&'static str] = &["owner"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"Input",
FIELDS,
__Visitor {
marker: _serde::export::PhantomData::<Input>,
lifetime: _serde::export::PhantomData,
},
)
}
}
};
let Input { owner }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");
let mut contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
contract.owner_set(owner);
near_sdk::env::state_write(&contract);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn owner_is() {
near_sdk::env::setup_panic_hook();
let contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.owner_is();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
impl Pausable for EthProver {
fn pa_storage_key(&self) -> Vec<u8> {
("__PAUSE__").as_bytes().to_vec()
}
fn pa_is_paused(&self, key: String) -> bool {
self.pa_all_paused()
.map(|keys| keys.contains(&key) || keys.contains("ALL"))
.unwrap_or(false)
}
fn pa_all_paused(&self) -> Option<std::collections::HashSet<String>> {
::near_sdk::env::storage_read(self.pa_storage_key().as_ref()).map(|value| {
std::collections::HashSet::try_from_slice(value.as_ref())
.expect("Pausable: Invalid format for paused keys")
})
}
fn pa_pause_feature(&mut self, key: String) {
if !self.owner_is() {
{
::std::rt::begin_panic("Ownable: Method must be called from owner")
}
};
let mut paused_keys = self.pa_all_paused().unwrap_or_default();
paused_keys.insert(key.clone());
::near_sdk::env::log_str(
near_plugins::events::AsEvent::event(&near_plugins::pausable::Pause {
by: ::near_sdk::env::predecessor_account_id(),
key,
})
.as_ref(),
);
::near_sdk::env::storage_write(
self.pa_storage_key().as_ref(),
paused_keys
.try_to_vec()
.expect("Pausable: Unexpected error serializing keys")
.as_ref(),
);
}
fn pa_unpause_feature(&mut self, key: String) {
if !self.owner_is() {
{
::std::rt::begin_panic("Ownable: Method must be called from owner")
}
};
let mut paused_keys = self.pa_all_paused().unwrap_or_default();
paused_keys.remove(&key);
::near_sdk::env::log_str(
near_plugins::events::AsEvent::event(&near_plugins::pausable::Unpause {
by: ::near_sdk::env::predecessor_account_id(),
key,
})
.as_ref(),
);
if paused_keys.is_empty() {
::near_sdk::env::storage_remove(self.pa_storage_key().as_ref());
} else {
::near_sdk::env::storage_write(
self.pa_storage_key().as_ref(),
paused_keys
.try_to_vec()
.expect("Pausable: Unexpected error serializing keys")
.as_ref(),
);
}
}
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn pa_storage_key() {
near_sdk::env::setup_panic_hook();
let contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.pa_storage_key();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn pa_is_paused() {
near_sdk::env::setup_panic_hook();
#[serde(crate = "near_sdk::serde")]
struct Input {
key: String,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _IMPL_DESERIALIZE_FOR_Input: () = {
use near_sdk::serde as _serde;
#[automatically_derived]
impl<'de> near_sdk::serde::Deserialize<'de> for Input {
fn deserialize<__D>(
__deserializer: __D,
) -> near_sdk::serde::export::Result<Self, __D::Error>
where
__D: near_sdk::serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(
self,
__value: u64,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::export::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de> {
marker: _serde::export::PhantomData<Input>,
lifetime: _serde::export::PhantomData<&'de ()>,
}
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Input;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "struct Input")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 =
match match _serde::de::SeqAccess::next_element::<String>(&mut __seq) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
} {
_serde::export::Some(__value) => __value,
_serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(
0usize,
&"struct Input with 1 element",
));
}
};
_serde::export::Ok(Input { key: __field0 })
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::export::Option<String> = _serde::export::None;
while let _serde::export::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::export::Option::is_some(&__field0) {
return _serde::export::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"key",
),
);
}
__field0 = _serde::export::Some(
match _serde::de::MapAccess::next_value::<String>(
&mut __map,
) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::export::Some(__field0) => __field0,
_serde::export::None => match _serde::private::de::missing_field("key")
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
};
_serde::export::Ok(Input { key: __field0 })
}
}
const FIELDS: &'static [&'static str] = &["key"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"Input",
FIELDS,
__Visitor {
marker: _serde::export::PhantomData::<Input>,
lifetime: _serde::export::PhantomData,
},
)
}
}
};
let Input { key }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");
let contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.pa_is_paused(key);
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn pa_all_paused() {
near_sdk::env::setup_panic_hook();
let contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.pa_all_paused();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn pa_pause_feature() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method pa_pause_feature doesn\'t accept deposit");
}
#[serde(crate = "near_sdk::serde")]
struct Input {
key: String,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _IMPL_DESERIALIZE_FOR_Input: () = {
use near_sdk::serde as _serde;
#[automatically_derived]
impl<'de> near_sdk::serde::Deserialize<'de> for Input {
fn deserialize<__D>(
__deserializer: __D,
) -> near_sdk::serde::export::Result<Self, __D::Error>
where
__D: near_sdk::serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(
self,
__value: u64,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::export::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de> {
marker: _serde::export::PhantomData<Input>,
lifetime: _serde::export::PhantomData<&'de ()>,
}
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Input;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "struct Input")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 =
match match _serde::de::SeqAccess::next_element::<String>(&mut __seq) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
} {
_serde::export::Some(__value) => __value,
_serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(
0usize,
&"struct Input with 1 element",
));
}
};
_serde::export::Ok(Input { key: __field0 })
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::export::Option<String> = _serde::export::None;
while let _serde::export::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::export::Option::is_some(&__field0) {
return _serde::export::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"key",
),
);
}
__field0 = _serde::export::Some(
match _serde::de::MapAccess::next_value::<String>(
&mut __map,
) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::export::Some(__field0) => __field0,
_serde::export::None => match _serde::private::de::missing_field("key")
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
};
_serde::export::Ok(Input { key: __field0 })
}
}
const FIELDS: &'static [&'static str] = &["key"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"Input",
FIELDS,
__Visitor {
marker: _serde::export::PhantomData::<Input>,
lifetime: _serde::export::PhantomData,
},
)
}
}
};
let Input { key }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");
let mut contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
contract.pa_pause_feature(key);
near_sdk::env::state_write(&contract);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn pa_unpause_feature() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method pa_unpause_feature doesn\'t accept deposit");
}
#[serde(crate = "near_sdk::serde")]
struct Input {
key: String,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _IMPL_DESERIALIZE_FOR_Input: () = {
use near_sdk::serde as _serde;
#[automatically_derived]
impl<'de> near_sdk::serde::Deserialize<'de> for Input {
fn deserialize<__D>(
__deserializer: __D,
) -> near_sdk::serde::export::Result<Self, __D::Error>
where
__D: near_sdk::serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(
self,
__value: u64,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::export::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de> {
marker: _serde::export::PhantomData<Input>,
lifetime: _serde::export::PhantomData<&'de ()>,
}
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Input;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "struct Input")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 =
match match _serde::de::SeqAccess::next_element::<String>(&mut __seq) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
} {
_serde::export::Some(__value) => __value,
_serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(
0usize,
&"struct Input with 1 element",
));
}
};
_serde::export::Ok(Input { key: __field0 })
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::export::Option<String> = _serde::export::None;
while let _serde::export::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::export::Option::is_some(&__field0) {
return _serde::export::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"key",
),
);
}
__field0 = _serde::export::Some(
match _serde::de::MapAccess::next_value::<String>(
&mut __map,
) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::export::Some(__field0) => __field0,
_serde::export::None => match _serde::private::de::missing_field("key")
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
};
_serde::export::Ok(Input { key: __field0 })
}
}
const FIELDS: &'static [&'static str] = &["key"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"Input",
FIELDS,
__Visitor {
marker: _serde::export::PhantomData::<Input>,
lifetime: _serde::export::PhantomData,
},
)
}
}
};
let Input { key }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");
let mut contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
contract.pa_unpause_feature(key);
near_sdk::env::state_write(&contract);
}
impl Upgradable for EthProver {
fn up_storage_key(&self) -> Vec<u8> {
("__CODE__").as_bytes().to_vec()
}
fn up_stage_code(&mut self, code: Vec<u8>) {
if !self.owner_is() {
{
::std::rt::begin_panic("Ownable: Method must be called from owner")
}
};
if code.is_empty() {
near_sdk::env::storage_remove(self.up_storage_key().as_ref());
} else {
near_sdk::env::storage_write(self.up_storage_key().as_ref(), code.as_ref());
}
}
fn up_staged_code(&self) -> Option<Vec<u8>> {
near_sdk::env::storage_read(self.up_storage_key().as_ref())
}
fn up_staged_code_hash(&self) -> Option<::near_sdk::CryptoHash> {
self.up_staged_code().map(|code| {
std::convert::TryInto::try_into(near_sdk::env::sha256(code.as_ref())).unwrap()
})
}
fn up_deploy_code(&mut self) -> near_sdk::Promise {
if !self.owner_is() {
{
::std::rt::begin_panic("Ownable: Method must be called from owner")
}
};
near_sdk::Promise::new(near_sdk::env::current_account_id())
.deploy_contract(self.up_staged_code().expect("Upgradable: No staged code"))
}
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn up_storage_key() {
near_sdk::env::setup_panic_hook();
let contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.up_storage_key();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn up_stage_code() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method up_stage_code doesn\'t accept deposit");
}
struct Input {
code: Vec<u8>,
}
impl borsh::de::BorshDeserialize for Input
where
Vec<u8>: borsh::BorshDeserialize,
{
fn deserialize(
buf: &mut &[u8],
) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
code: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
let Input { code }: Input = near_sdk::borsh::BorshDeserialize::try_from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from Borsh.");
let mut contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
contract.up_stage_code(code);
near_sdk::env::state_write(&contract);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn up_staged_code() {
near_sdk::env::setup_panic_hook();
let contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.up_staged_code();
let result = near_sdk::borsh::BorshSerialize::try_to_vec(&result)
.expect("Failed to serialize the return value using Borsh.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn up_staged_code_hash() {
near_sdk::env::setup_panic_hook();
let contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.up_staged_code_hash();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn up_deploy_code() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method up_deploy_code doesn\'t accept deposit");
}
let mut contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.up_deploy_code();
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
near_sdk::env::state_write(&contract);
}
impl FullAccessKeyFallback for EthProver {
fn attach_full_access_key(&mut self, public_key: ::near_sdk::PublicKey) -> near_sdk::Promise {
if !self.owner_is() {
{
::std::rt::begin_panic("Ownable: Method must be called from owner")
}
};
let current_account_id = ::near_sdk::env::current_account_id();
::near_sdk::env::log_str(
near_plugins::events::AsEvent::event(
&near_plugins::full_access_key_fallback::FullAccessKeyAdded {
by: current_account_id.clone(),
public_key: public_key.clone(),
},
)
.as_ref(),
);
::near_sdk::Promise::new(current_account_id).add_full_access_key(public_key)
}
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn attach_full_access_key() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method attach_full_access_key doesn\'t accept deposit");
}
#[serde(crate = "near_sdk::serde")]
struct Input {
public_key: ::near_sdk::PublicKey,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _IMPL_DESERIALIZE_FOR_Input: () = {
use near_sdk::serde as _serde;
#[automatically_derived]
impl<'de> near_sdk::serde::Deserialize<'de> for Input {
fn deserialize<__D>(
__deserializer: __D,
) -> near_sdk::serde::export::Result<Self, __D::Error>
where
__D: near_sdk::serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(
self,
__value: u64,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"public_key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"public_key" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::export::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de> {
marker: _serde::export::PhantomData<Input>,
lifetime: _serde::export::PhantomData<&'de ()>,
}
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Input;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "struct Input")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 = match match _serde::de::SeqAccess::next_element::<
::near_sdk::PublicKey,
>(&mut __seq)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
} {
_serde::export::Some(__value) => __value,
_serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(
0usize,
&"struct Input with 1 element",
));
}
};
_serde::export::Ok(Input {
public_key: __field0,
})
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::export::Option<::near_sdk::PublicKey> =
_serde::export::None;
while let _serde::export::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::export::Option::is_some(&__field0) {
return _serde::export::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"public_key",
),
);
}
__field0 = _serde::export::Some(
match _serde::de::MapAccess::next_value::<
::near_sdk::PublicKey,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::export::Some(__field0) => __field0,
_serde::export::None => {
match _serde::private::de::missing_field("public_key") {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
}
};
_serde::export::Ok(Input {
public_key: __field0,
})
}
}
const FIELDS: &'static [&'static str] = &["public_key"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"Input",
FIELDS,
__Visitor {
marker: _serde::export::PhantomData::<Input>,
lifetime: _serde::export::PhantomData,
},
)
}
}
};
let Input { public_key }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");
let mut contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.attach_full_access_key(public_key);
let result = near_sdk::serde_json::to_vec(&result)
.expect("Failed to serialize the return value using JSON.");
near_sdk::env::value_return(&result);
near_sdk::env::state_write(&contract);
}
pub mod remote_self {
use super::*;
use near_sdk::{Gas, Balance, AccountId, Promise};
pub fn on_block_hash(
expected_block_hash: H256,
__account_id: AccountId,
__balance: near_sdk::Balance,
__gas: near_sdk::Gas,
) -> near_sdk::Promise {
struct Input {
expected_block_hash: H256,
}
impl borsh::ser::BorshSerialize for Input
where
H256: borsh::ser::BorshSerialize,
{
fn serialize<W: borsh::maybestd::io::Write>(
&self,
writer: &mut W,
) -> ::core::result::Result<(), borsh::maybestd::io::Error> {
borsh::BorshSerialize::serialize(&self.expected_block_hash, writer)?;
Ok(())
}
}
let args = Input {
expected_block_hash,
};
let args = near_sdk::borsh::BorshSerialize::try_to_vec(&args)
.expect("Failed to serialize the cross contract args using Borsh.");
near_sdk::Promise::new(__account_id).function_call(
"on_block_hash".to_string(),
args,
__balance,
__gas,
)
}
}
pub mod eth_client {
use super::*;
use near_sdk::{Gas, Balance, AccountId, Promise};
pub fn block_hash_safe(
index: u64,
__account_id: AccountId,
__balance: near_sdk::Balance,
__gas: near_sdk::Gas,
) -> near_sdk::Promise {
struct Input {
index: u64,
}
impl borsh::ser::BorshSerialize for Input
where
u64: borsh::ser::BorshSerialize,
{
fn serialize<W: borsh::maybestd::io::Write>(
&self,
writer: &mut W,
) -> ::core::result::Result<(), borsh::maybestd::io::Error> {
borsh::BorshSerialize::serialize(&self.index, writer)?;
Ok(())
}
}
let args = Input { index };
let args = near_sdk::borsh::BorshSerialize::try_to_vec(&args)
.expect("Failed to serialize the cross contract args using Borsh.");
near_sdk::Promise::new(__account_id).function_call(
"block_hash_safe".to_string(),
args,
__balance,
__gas,
)
}
}
/// Get element at position `pos` from rlp encoded data,
/// and decode it as vector of bytes
fn get_vec(data: &Rlp, pos: usize) -> Vec<u8> {
data.at(pos).unwrap().as_val::<Vec<u8>>().unwrap()
}
impl EthProver {
pub fn init(bridge_smart_contract: AccountId) -> Self {
if !env::state_read::<EthProver>().is_none() {
{
::std::rt::begin_panic("The contract is already initialized")
}
};
Self {
bridge_smart_contract,
__paused: Default::default(),
}
}
/// Implementation of the callback when the EthClient returns data.
/// This method can only be called by the EthProver contract itself (e.g. as callback).
/// - `block_hash` is the actual data from the EthClient call
/// - `expected_block_hash` is the block hash that we expect to be passed by us.
pub fn on_block_hash(&self, block_hash: Option<H256>, expected_block_hash: H256) -> bool {
::near_sdk::assert_self();
return block_hash == Some(expected_block_hash);
}
/// Externally visible method to verify that the given block hash is part of the safe canonical
/// chain on the remote EthClient contract.
/// Returns a promise.
pub fn assert_ethclient_hash(
&self,
block_number: u64,
expected_block_hash: H256,
) -> PromiseOrValue<bool> {
eth_client::block_hash_safe(
block_number,
self.bridge_smart_contract.clone(),
0,
BLOCK_HASH_SAFE_GAS,
)
.then(remote_self::on_block_hash(
expected_block_hash,
env::current_account_id(),
0,
ON_BLOCK_HASH_GAS,
))
.into()
}
pub fn verify_log_entry(
&self,
log_index: u64,
log_entry_data: Vec<u8>,
receipt_index: u64,
receipt_data: Vec<u8>,
header_data: Vec<u8>,
proof: Vec<Vec<u8>>,
skip_bridge_call: bool,
) -> PromiseOrValue<bool> {
let mut check_paused = true;
if check_paused {
if !!self.pa_is_paused("verify_log_entry".to_string()) {
{
::std::rt::begin_panic("Pausable: Method is paused")
}
};
}
let log_entry: LogEntry = rlp::decode(log_entry_data.as_slice()).unwrap();
let receipt: Receipt = rlp::decode(receipt_data.as_slice()).unwrap();
let header: BlockHeader = rlp::decode(header_data.as_slice()).unwrap();
{
match (&receipt.logs[log_index as usize], &log_entry) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::None,
);
}
}
}
};
let data =
Self::verify_trie_proof(header.receipts_root, rlp::encode(&receipt_index), proof);
let verification_result = receipt_data == data;
if verification_result && skip_bridge_call {
return PromiseOrValue::Value(true);
} else if !verification_result {
return PromiseOrValue::Value(false);
}
eth_client::block_hash_safe(
header.number,
self.bridge_smart_contract.clone(),
0,
BLOCK_HASH_SAFE_GAS,
)
.then(remote_self::on_block_hash(
header.hash.unwrap(),
env::current_account_id(),
0,
ON_BLOCK_HASH_GAS,
))
.into()
}
/// Verify the proof recursively traversing through the key.
/// Return the value at the end of the key, in case the proof is valid.
///
/// @param expected_root is the expected root of the current node.
/// @param key is the key for which we are proving the value.
/// @param proof contains relevant information to verify data is valid
///
/// Patricia Trie: https://eth.wiki/en/fundamentals/patricia-tree
/// Patricia Img: https://ethereum.stackexchange.com/questions/268/ethereum-block-architecture/6413#6413
///
/// Verification: https://github.com/slockit/in3/wiki/Ethereum-Verification-and-MerkleProof#receipt-proof
/// Article: https://medium.com/@ouvrard.pierre.alain/merkle-proof-verification-for-ethereum-patricia-tree-48f29658eec
/// Python impl: https://gist.github.com/mfornet/0ff283274c0162f1cca45966bccf69ee
///
fn verify_trie_proof(expected_root: H256, key: Vec<u8>, proof: Vec<Vec<u8>>) -> Vec<u8> {
let mut actual_key = ::alloc::vec::Vec::new();
for el in key {
actual_key.push(el / 16);
actual_key.push(el % 16);
}
Self::_verify_trie_proof((expected_root.0).0.into(), &actual_key, &proof, 0, 0)
}
fn _verify_trie_proof(
expected_root: Vec<u8>,
key: &Vec<u8>,
proof: &Vec<Vec<u8>>,
key_index: usize,
proof_index: usize,
) -> Vec<u8> {
let node = &proof[proof_index];
if key_index == 0 {
{
match (&near_keccak256(node), &expected_root.as_slice()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::None,
);
}
}
}
};
} else if node.len() < 32 {
{
match (&node.as_slice(), &expected_root) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::None,
);
}
}
}
};
} else {
{
match (&near_keccak256(node), &expected_root.as_slice()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::None,
);
}
}
}
};
}
let node = Rlp::new(&node.as_slice());
if node.iter().count() == 17 {
if key_index == key.len() {
{
match (&(proof_index + 1), &proof.len()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::None,
);
}
}
}
};
get_vec(&node, 16)
} else {
let new_expected_root = get_vec(&node, key[key_index] as usize);
Self::_verify_trie_proof(
new_expected_root,
key,
proof,
key_index + 1,
proof_index + 1,
)
}
} else {
{
match (&node.iter().count(), &2) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::None,
);
}
}
}
};
let path_u8 = get_vec(&node, 0);
let head = path_u8[0] / 16;
if !(head <= 3) {
::core::panicking::panic("assertion failed: head <= 3")
};
let mut path = ::alloc::vec::Vec::new();
if head % 2 == 1 {
path.push(path_u8[0] % 16);
}
for val in path_u8.into_iter().skip(1) {
path.push(val / 16);
path.push(val % 16);
}
{
match (&path.as_slice(), &&key[key_index..key_index + path.len()]) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::None,
);
}
}
}
};
if head >= 2 {
{
match (&(proof_index + 1), &proof.len()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::None,
);
}
}
}
};
{
match (&(key_index + path.len()), &key.len()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(
kind,
&*left_val,
&*right_val,
::core::option::Option::None,
);
}
}
}
};
get_vec(&node, 1)
} else {
let new_expected_root = get_vec(&node, 1);
Self::_verify_trie_proof(
new_expected_root,
key,
proof,
key_index + path.len(),
proof_index + 1,
)
}
}
}
pub fn set_bridge(&mut self, bridge: AccountId) {
if !self.owner_is() {
{
::std::rt::begin_panic("Ownable: Method must be called from owner")
}
};
env::log_str(
{
let res = ::alloc::fmt::format(::core::fmt::Arguments::new_v1(
&["Old bridge account: ", " New bridge account "],
&[
::core::fmt::ArgumentV1::new_display(&self.bridge_smart_contract),
::core::fmt::ArgumentV1::new_display(&bridge),
],
));
res
}
.as_str(),
);
self.bridge_smart_contract = bridge;
}
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn init() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method init doesn\'t accept deposit");
}
struct Input {
bridge_smart_contract: AccountId,
}
impl borsh::de::BorshDeserialize for Input
where
AccountId: borsh::BorshDeserialize,
{
fn deserialize(
buf: &mut &[u8],
) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
bridge_smart_contract: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
let Input {
bridge_smart_contract,
}: Input = near_sdk::borsh::BorshDeserialize::try_from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from Borsh.");
if near_sdk::env::state_exists() {
near_sdk::env::panic_str("The contract has already been initialized");
}
let contract = EthProver::init(bridge_smart_contract);
near_sdk::env::state_write(&contract);
}
/// Implementation of the callback when the EthClient returns data.
/// This method can only be called by the EthProver contract itself (e.g. as callback).
/// - `block_hash` is the actual data from the EthClient call
/// - `expected_block_hash` is the block hash that we expect to be passed by us.
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn on_block_hash() {
near_sdk::env::setup_panic_hook();
struct Input {
expected_block_hash: H256,
}
impl borsh::de::BorshDeserialize for Input
where
H256: borsh::BorshDeserialize,
{
fn deserialize(
buf: &mut &[u8],
) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
expected_block_hash: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
let Input {
expected_block_hash,
}: Input = near_sdk::borsh::BorshDeserialize::try_from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from Borsh.");
let data: Vec<u8> = match near_sdk::env::promise_result(0u64) {
near_sdk::PromiseResult::Successful(x) => x,
_ => near_sdk::env::panic_str("Callback computation 0 was not successful"),
};
let block_hash: Option<H256> = near_sdk::borsh::BorshDeserialize::try_from_slice(&data)
.expect("Failed to deserialize callback using Borsh");
let contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.on_block_hash(block_hash, expected_block_hash);
let result = near_sdk::borsh::BorshSerialize::try_to_vec(&result)
.expect("Failed to serialize the return value using Borsh.");
near_sdk::env::value_return(&result);
}
/// Externally visible method to verify that the given block hash is part of the safe canonical
/// chain on the remote EthClient contract.
/// Returns a promise.
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn assert_ethclient_hash() {
near_sdk::env::setup_panic_hook();
struct Input {
block_number: u64,
expected_block_hash: H256,
}
impl borsh::de::BorshDeserialize for Input
where
u64: borsh::BorshDeserialize,
H256: borsh::BorshDeserialize,
{
fn deserialize(
buf: &mut &[u8],
) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
block_number: borsh::BorshDeserialize::deserialize(buf)?,
expected_block_hash: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
let Input {
block_number,
expected_block_hash,
}: Input = near_sdk::borsh::BorshDeserialize::try_from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from Borsh.");
let contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.assert_ethclient_hash(block_number, expected_block_hash);
let result = near_sdk::borsh::BorshSerialize::try_to_vec(&result)
.expect("Failed to serialize the return value using Borsh.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn verify_log_entry() {
near_sdk::env::setup_panic_hook();
struct Input {
log_index: u64,
log_entry_data: Vec<u8>,
receipt_index: u64,
receipt_data: Vec<u8>,
header_data: Vec<u8>,
proof: Vec<Vec<u8>>,
skip_bridge_call: bool,
}
impl borsh::de::BorshDeserialize for Input
where
u64: borsh::BorshDeserialize,
Vec<u8>: borsh::BorshDeserialize,
u64: borsh::BorshDeserialize,
Vec<u8>: borsh::BorshDeserialize,
Vec<u8>: borsh::BorshDeserialize,
Vec<Vec<u8>>: borsh::BorshDeserialize,
bool: borsh::BorshDeserialize,
{
fn deserialize(
buf: &mut &[u8],
) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
log_index: borsh::BorshDeserialize::deserialize(buf)?,
log_entry_data: borsh::BorshDeserialize::deserialize(buf)?,
receipt_index: borsh::BorshDeserialize::deserialize(buf)?,
receipt_data: borsh::BorshDeserialize::deserialize(buf)?,
header_data: borsh::BorshDeserialize::deserialize(buf)?,
proof: borsh::BorshDeserialize::deserialize(buf)?,
skip_bridge_call: borsh::BorshDeserialize::deserialize(buf)?,
})
}
}
let Input {
log_index,
log_entry_data,
receipt_index,
receipt_data,
header_data,
proof,
skip_bridge_call,
}: Input = near_sdk::borsh::BorshDeserialize::try_from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from Borsh.");
let contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
let result = contract.verify_log_entry(
log_index,
log_entry_data,
receipt_index,
receipt_data,
header_data,
proof,
skip_bridge_call,
);
let result = near_sdk::borsh::BorshSerialize::try_to_vec(&result)
.expect("Failed to serialize the return value using Borsh.");
near_sdk::env::value_return(&result);
}
#[cfg(target_arch = "wasm32")]
#[no_mangle]
pub extern "C" fn set_bridge() {
near_sdk::env::setup_panic_hook();
if near_sdk::env::attached_deposit() != 0 {
near_sdk::env::panic_str("Method set_bridge doesn\'t accept deposit");
}
#[serde(crate = "near_sdk::serde")]
struct Input {
bridge: AccountId,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _IMPL_DESERIALIZE_FOR_Input: () = {
use near_sdk::serde as _serde;
#[automatically_derived]
impl<'de> near_sdk::serde::Deserialize<'de> for Input {
fn deserialize<__D>(
__deserializer: __D,
) -> near_sdk::serde::export::Result<Self, __D::Error>
where
__D: near_sdk::serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(
self,
__value: u64,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"bridge" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::export::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"bridge" => _serde::export::Ok(__Field::__field0),
_ => _serde::export::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::export::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de> {
marker: _serde::export::PhantomData<Input>,
lifetime: _serde::export::PhantomData<&'de ()>,
}
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = Input;
fn expecting(
&self,
__formatter: &mut _serde::export::Formatter,
) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(__formatter, "struct Input")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 = match match _serde::de::SeqAccess::next_element::<AccountId>(
&mut __seq,
) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
} {
_serde::export::Some(__value) => __value,
_serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(
0usize,
&"struct Input with 1 element",
));
}
};
_serde::export::Ok(Input { bridge: __field0 })
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::export::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::export::Option<AccountId> = _serde::export::None;
while let _serde::export::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::export::Option::is_some(&__field0) {
return _serde::export::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"bridge",
),
);
}
__field0 = _serde::export::Some(
match _serde::de::MapAccess::next_value::<AccountId>(
&mut __map,
) {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::export::Some(__field0) => __field0,
_serde::export::None => {
match _serde::private::de::missing_field("bridge") {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
}
};
_serde::export::Ok(Input { bridge: __field0 })
}
}
const FIELDS: &'static [&'static str] = &["bridge"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"Input",
FIELDS,
__Visitor {
marker: _serde::export::PhantomData::<Input>,
lifetime: _serde::export::PhantomData,
},
)
}
}
};
let Input { bridge }: Input = near_sdk::serde_json::from_slice(
&near_sdk::env::input().expect("Expected input since method has arguments."),
)
.expect("Failed to deserialize input from JSON.");
let mut contract: EthProver = near_sdk::env::state_read().unwrap_or_default();
contract.set_bridge(bridge);
near_sdk::env::state_write(&contract);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment