Skip to content

Commit

Permalink
Merge branch 'feat/get-erc20-balance' into chore/aleksuss/charge_gas_…
Browse files Browse the repository at this point in the history
…optim
  • Loading branch information
joshuajbouw committed Feb 1, 2023
2 parents 19f3a12 + 2ff79be commit e45e098
Show file tree
Hide file tree
Showing 40 changed files with 1,283 additions and 1,370 deletions.
591 changes: 322 additions & 269 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions engine-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ autobenches = false

[dependencies]
aurora-engine-types = { path = "../engine-types", default-features = false }
borsh = { version = "0.9.3", default-features = false }
sha3 = { version = "0.10.2", default-features = false }
sha2 = { version = "0.10.2", default-features = false }

base64 = { version = "0.21", default-features = false, features = [ "alloc" ] }
borsh = { version = "0.9", default-features = false }
sha2 = { version = "0.10", default-features = false }
sha3 = { version = "0.10", default-features = false }

[features]
std = ["aurora-engine-types/std", "borsh/std", "sha3/std", "sha2/std"]
std = ["aurora-engine-types/std", "borsh/std", "sha3/std", "sha2/std", "base64/std" ]
contract = []
log = []
all-promise-actions = []
Expand Down
13 changes: 13 additions & 0 deletions engine-sdk/src/base64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use aurora_engine_types::{String, Vec};
pub use base64::DecodeError;
use base64::Engine;

/// Encode arbitrary octets as base64 using the standard `base64::Engine`.
pub fn encode<T: AsRef<[u8]>>(input: T) -> String {
base64::engine::general_purpose::STANDARD.encode(input)
}

/// Decode from string reference as octets using the standard `base64::Engine`.
pub fn decode<T: AsRef<[u8]>>(input: T) -> Result<Vec<u8>, DecodeError> {
base64::engine::general_purpose::STANDARD.decode(input)
}
2 changes: 1 addition & 1 deletion engine-sdk/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc_error_handler))]

#[cfg(feature = "contract")]
use crate::prelude::{Address, Vec, U256};
use crate::prelude::{H256, STORAGE_PRICE_PER_BYTE};
pub use types::keccak;

pub mod base64;
pub mod caching;
pub mod env;
pub mod error;
Expand Down
3 changes: 1 addition & 2 deletions engine-standalone-storage/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@ aurora-engine-types = { path = "../engine-types", default-features = false, feat
aurora-engine-sdk = { path = "../engine-sdk", default-features = false, features = ["std"] }
aurora-engine-transactions = { path = "../engine-transactions", default-features = false, features = ["std"] }
aurora-engine-precompiles = { path = "../engine-precompiles", default-features = false, features = ["std"] }
borsh = { version = "0.9.3" }
borsh = "0.9"
evm-core = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.4-aurora", default-features = false }
hex = "0.4.3"
rocksdb = { version = "0.19.0", default-features = false }
postgres = "0.19.2"
serde = "1.0.130"
serde_json = "1.0.72"
base64 = "0.13.0"

[features]
default = ["snappy", "lz4", "zstd", "zlib"]
Expand Down
12 changes: 7 additions & 5 deletions engine-standalone-storage/src/json_snapshot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ pub fn initialize_engine_state(

let mut batch = rocksdb::WriteBatch::default();
for entry in snapshot.result.values {
let key = base64::decode(entry.key)?;
let value = base64::decode(entry.value)?;
let key = aurora_engine_sdk::base64::decode(entry.key)?;
let value = aurora_engine_sdk::base64::decode(entry.value)?;
let storage_key = crate::construct_engine_key(&key, block_height, transaction_position);
let storage_value = crate::diff::DiffValue::Modified(value);
batch.put(storage_key, storage_value.try_to_bytes()?);
Expand All @@ -26,15 +26,17 @@ pub fn initialize_engine_state(
}

pub mod error {
use aurora_engine_sdk::base64::DecodeError;

#[derive(Debug)]
pub enum Error {
Base64(base64::DecodeError),
Base64(DecodeError),
Rocksdb(rocksdb::Error),
Borsh(std::io::Error),
}

impl From<base64::DecodeError> for Error {
fn from(e: base64::DecodeError) -> Self {
impl From<DecodeError> for Error {
fn from(e: DecodeError) -> Self {
Self::Base64(e)
}
}
Expand Down
6 changes: 3 additions & 3 deletions engine-standalone-storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,11 @@ impl Storage {

let value = if iter.valid() {
let bytes = iter.value().unwrap();
diff::DiffValue::try_from_bytes(bytes).unwrap_or_else(|e| {
DiffValue::try_from_bytes(bytes).unwrap_or_else(|e| {
panic!(
"Could not deserialize key={} value={} error={:?}",
base64::encode(&db_key),
base64::encode(bytes),
aurora_engine_sdk::base64::encode(&db_key),
aurora_engine_sdk::base64::encode(bytes),
e,
)
})
Expand Down
6 changes: 3 additions & 3 deletions engine-standalone-storage/src/relayer_db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ pub mod error {
pub enum Error {
Storage(crate::Error),
Postgres(postgres::Error),
EngineState(state::error::EngineStateError),
EngineState(state::EngineStateError),
Engine(engine::EngineError),
}

Expand All @@ -181,8 +181,8 @@ pub mod error {
}
}

impl From<state::error::EngineStateError> for Error {
fn from(e: state::error::EngineStateError) -> Self {
impl From<state::EngineStateError> for Error {
fn from(e: state::EngineStateError) -> Self {
Self::EngineState(e)
}
}
Expand Down
8 changes: 4 additions & 4 deletions engine-standalone-storage/src/sync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ fn non_submit_execute<'db>(
}

TransactionKind::RefundOnError(maybe_args) => {
let result: Result<Option<TransactionExecutionResult>, state::error::EngineStateError> =
let result: Result<Option<TransactionExecutionResult>, state::EngineStateError> =
maybe_args
.clone()
.map(|args| {
Expand Down Expand Up @@ -438,7 +438,7 @@ pub mod error {

#[derive(Debug)]
pub enum Error {
EngineState(state::error::EngineStateError),
EngineState(state::EngineStateError),
Engine(engine::EngineError),
DeployErc20(engine::DeployErc20Error),
FtOnTransfer(connector::error::FtTransferCallError),
Expand All @@ -452,8 +452,8 @@ pub mod error {
ConnectorStorage(connector::error::StorageReadError),
}

impl From<state::error::EngineStateError> for Error {
fn from(e: state::error::EngineStateError) -> Self {
impl From<state::EngineStateError> for Error {
fn from(e: state::EngineStateError) -> Self {
Self::EngineState(e)
}
}
Expand Down
23 changes: 9 additions & 14 deletions engine-test-doubles/src/io.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use aurora_engine_sdk::io::{StorageIntermediate, IO};
use std::cell::RefCell;
use std::collections::HashMap;
use std::sync::RwLock;

pub struct Value(Vec<u8>);

Expand All @@ -27,37 +27,32 @@ pub struct Storage {

/// In-memory implementation of [IO].
#[derive(Debug, Clone, Copy)]
pub struct StoragePointer<'a>(pub &'a RwLock<Storage>);
pub struct StoragePointer<'a>(pub &'a RefCell<Storage>);

impl<'a> IO for StoragePointer<'a> {
type StorageValue = Value;

fn read_input(&self) -> Self::StorageValue {
Value(self.0.read().unwrap().input.clone())
Value(self.0.borrow().input.clone())
}

fn return_output(&mut self, value: &[u8]) {
let mut storage = self.0.write().unwrap();
let mut storage = self.0.borrow_mut();
storage.output = value.to_vec();
}

fn read_storage(&self, key: &[u8]) -> Option<Self::StorageValue> {
self.0
.read()
.unwrap()
.kv_store
.get(key)
.map(|v| Value(v.clone()))
self.0.borrow().kv_store.get(key).map(|v| Value(v.clone()))
}

fn storage_has_key(&self, key: &[u8]) -> bool {
self.0.read().unwrap().kv_store.contains_key(key)
self.0.borrow().kv_store.contains_key(key)
}

fn write_storage(&mut self, key: &[u8], value: &[u8]) -> Option<Self::StorageValue> {
let key = key.to_vec();
let value = value.to_vec();
let mut storage = self.0.write().unwrap();
let mut storage = self.0.borrow_mut();
storage.kv_store.insert(key, value).map(Value)
}

Expand All @@ -67,12 +62,12 @@ impl<'a> IO for StoragePointer<'a> {
value: Self::StorageValue,
) -> Option<Self::StorageValue> {
let key = key.to_vec();
let mut storage = self.0.write().unwrap();
let mut storage = self.0.borrow_mut();
storage.kv_store.insert(key, value.0).map(Value)
}

fn remove_storage(&mut self, key: &[u8]) -> Option<Self::StorageValue> {
let mut storage = self.0.write().unwrap();
let mut storage = self.0.borrow_mut();
storage.kv_store.remove(key).map(Value)
}
}
3 changes: 1 addition & 2 deletions engine-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ evm = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.4-
evm-runtime = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.4-aurora", default-features = false, features = ["std", "tracing"] }
evm-gasometer = { git = "https://github.com/aurora-is-near/sputnikvm.git", tag = "v0.37.4-aurora", default-features = false, features = ["std", "tracing"] }
rlp = { version = "0.5.0", default-features = false }
base64 = "0.13.0"
bstr = "1.0.1"
byte-slice-cast = { version = "1.0", default-features = false }
ethabi = "18.0"
Expand All @@ -47,7 +46,7 @@ near-primitives = { git = "https://github.com/birchmd/nearcore.git", rev = "6033
libsecp256k1 = { version = "0.7.0", default-features = false }
rand = "0.8.5"
criterion = "0.4.0"
git2 = "0.15"
git2 = "0.16"
tempfile = "3.2.0"
walrus = "0.19"

Expand Down
4 changes: 2 additions & 2 deletions engine-tests/src/test_utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ impl AuroraRunner {
) {
let trie = &mut self.ext.underlying.fake_trie;
for entry in snapshot.result.values {
let key = base64::decode(entry.key).unwrap();
let value = base64::decode(entry.value).unwrap();
let key = aurora_engine_sdk::base64::decode(entry.key).unwrap();
let value = aurora_engine_sdk::base64::decode(entry.value).unwrap();
trie.insert(key, value);
}
}
Expand Down
60 changes: 31 additions & 29 deletions engine-tests/src/tests/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,19 @@ fn test_state_format() {
assert_eq!(hex::encode(state.try_to_vec().unwrap()), expected_hex);
}

fn generate_code(len: usize) -> Vec<u8> {
let mut rng = rand::thread_rng();
let mut buf = vec![0u8; len];
rng.fill_bytes(&mut buf);
buf
}

#[test]
fn test_deploy_contract() {
let (mut runner, mut signer, _) = initialize_transfer();

// Randomly generate some "contract code"
const LEN: usize = 567;
let code: Vec<u8> = {
let mut rng = rand::thread_rng();
let mut buf = vec![0u8; LEN];
rng.fill_bytes(&mut buf);
buf
};

let code = generate_code(567);
// Deploy that code
let result = runner
.submit_with_signer(&mut signer, |nonce| {
Expand All @@ -183,12 +183,7 @@ fn test_deploy_largest_contract() {
let (mut runner, mut signer, _) = initialize_transfer();

let len = evm::Config::berlin().create_contract_limit.unwrap();
let code: Vec<u8> = {
let mut rng = rand::thread_rng();
let mut buf = vec![0u8; len];
rng.fill_bytes(&mut buf);
buf
};
let code = generate_code(len);

// Deploy that code
let (result, profile) = runner
Expand Down Expand Up @@ -352,9 +347,7 @@ fn test_solidity_pure_bench() {
);

// Pure rust version of the same contract
let base_path = std::path::Path::new("../etc")
.join("tests")
.join("benchmark-contract");
let base_path = Path::new("../etc").join("tests").join("benchmark-contract");
let output_path =
base_path.join("target/wasm32-unknown-unknown/release/benchmark_contract.wasm");
test_utils::rust::compile(base_path);
Expand Down Expand Up @@ -404,7 +397,7 @@ fn test_revert_during_contract_deploy() {
.submit_transaction(&signer.secret_key, deploy_tx)
.unwrap();

let revert_bytes = crate::test_utils::unwrap_revert(submit_result);
let revert_bytes = test_utils::unwrap_revert(submit_result);
// First 4 bytes is a function selector with signature `Error(string)`
assert_eq!(&revert_bytes[0..4], &[8, 195, 121, 160]);
// Remaining data is an ABI-encoded string
Expand Down Expand Up @@ -562,9 +555,7 @@ fn test_override_state() {
))
.unwrap();
match result {
crate::prelude::parameters::TransactionStatus::Succeed(bytes) => {
Address::try_from_slice(&bytes[12..32]).unwrap()
}
TransactionStatus::Succeed(bytes) => Address::try_from_slice(&bytes[12..32]).unwrap(),
_ => panic!("tx failed"),
}
};
Expand Down Expand Up @@ -808,6 +799,8 @@ fn test_transfer_charging_gas_success() {

#[test]
fn test_eth_transfer_charging_gas_not_enough_balance() {
use near_vm_errors::{FunctionCallError, HostError, VMError};

let (mut runner, mut source_account, dest_address) = initialize_transfer();
let source_address = test_utils::address_from_secret_key(&source_account.secret_key);
let transaction = |nonce| {
Expand All @@ -829,10 +822,13 @@ fn test_eth_transfer_charging_gas_not_enough_balance() {
test_utils::validate_address_balance_and_nonce(&runner, dest_address, Wei::zero(), 0.into());

// attempt transfer
let result = runner
let error = runner
.submit_with_signer(&mut source_account, transaction)
.unwrap();
assert_eq!(result.status, TransactionStatus::OutOfFund);
.unwrap_err();
assert!(matches!(error, VMError::FunctionCallError(
FunctionCallError::HostError(
HostError::GuestPanic { panic_msg })) if panic_msg == "ERR_OUT_OF_FUND"
));

// validate post-state
let relayer = sdk::types::near_account_to_evm_address(
Expand All @@ -843,8 +839,8 @@ fn test_eth_transfer_charging_gas_not_enough_balance() {
&runner,
source_address,
INITIAL_BALANCE,
// we shouldn't increment nonce in case of OutOfFund error
(INITIAL_NONCE).into(),
// nonce is still not incremented since the transaction was invalid
INITIAL_NONCE.into(),
);
test_utils::validate_address_balance_and_nonce(&runner, dest_address, Wei::zero(), 0.into());
test_utils::validate_address_balance_and_nonce(&runner, relayer, Wei::zero(), 0.into());
Expand Down Expand Up @@ -996,6 +992,8 @@ fn test_eth_transfer_insufficient_balance_sim() {
// Same as `test_eth_transfer_charging_gas_not_enough_balance` but run through `near-sdk-sim`.
#[test]
fn test_eth_transfer_charging_gas_not_enough_balance_sim() {
use near_primitives::{errors::TxExecutionError, transaction::ExecutionStatus};

let (aurora, mut signer, address) = initialize_evm_sim();

// Run transaction which will fail (not enough balance to cover gas)
Expand All @@ -1009,13 +1007,17 @@ fn test_eth_transfer_charging_gas_not_enough_balance_sim() {
&signer.secret_key,
);
let call_result = aurora.call("submit", rlp::encode(&signed_tx).as_ref());
let result: SubmitResult = call_result.unwrap_borsh();
assert_eq!(result.status, TransactionStatus::OutOfFund);
let outcome = call_result.outcome();
assert!(matches!(
&outcome.status,
ExecutionStatus::Failure(
TxExecutionError::ActionError(e)) if e.to_string().contains("ERR_OUT_OF_FUND")
));

// validate post-state
assert_eq!(
query_address_sim(&address, "get_nonce", &aurora),
U256::from(INITIAL_NONCE),
INITIAL_NONCE.into(), // nonce hasn't been changed because an error occurs
);
assert_eq!(
query_address_sim(&address, "get_balance", &aurora),
Expand Down
Loading

0 comments on commit e45e098

Please sign in to comment.