Skip to content

Commit

Permalink
Submission 2
Browse files Browse the repository at this point in the history
  • Loading branch information
jafri committed Mar 2, 2020
1 parent cc0510c commit fe440f1
Show file tree
Hide file tree
Showing 40 changed files with 581 additions and 749 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
- Full gas cost calculations (not billed to sender)
- Web3-similar call support (query view functions with no state modifications)
- Total size of ~200KB (With OPTRACE and TESTING set to false)
- ecrecover, sha256, ripdemd160 and identity precompiles supported

NOTE: CHARGE_SENDER_FOR_GAS and TESTING must be enabled in the file eosio.evm/include/eosio.evm/constants.hpp for ethereum tests to work properly.
NOTE: (TESTING, CHARGE_SENDER_FOR_GAS) must be enabled, and (OPTRACE, PRINT_LOGS) must be disabled in the file eosio.evm/include/eosio.evm/constants.hpp for ethereum/tests testing to pass successfuly.

For testing, tests with balance/value over 2^62-1 (max EOSIO asset) were excluded. Pre-compile support is being worked on, some precompiles like ec_mul and ec_add are due to be added as intrinsics to EOSIO soon.
For testing, tests with balance/value over 2^62-1 (max EOSIO asset) were excluded. Full Pre-compile support is being worked on, some precompiles like ec_mul and ec_add are due to be added as intrinsics to EOSIO soon.

### Usage instructions
Recommended: [eos-evm-js guide](https://github.com/jafri/eosio.evm/tree/master/eos-evm-js)
Expand Down
Binary file modified eos-evm-js/src/eos-contracts/eosio.evm.wasm
Binary file not shown.
7 changes: 6 additions & 1 deletion eosio.evm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ add_contract(eosio.evm eosio.evm
${CMAKE_CURRENT_SOURCE_DIR}/src/testing.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/stack.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/instructions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/precompiles/index.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/precompiles/ecrecover.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/precompiles/sha256.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/precompiles/ripemd160.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/precompiles/identity.cpp
)

target_include_directories(eosio.evm
Expand All @@ -22,7 +27,7 @@ target_include_directories(eosio.evm
${CMAKE_CURRENT_SOURCE_DIR}/include
)

target_link_options(eosio.evm PUBLIC -stack-size 48000 )
target_link_options(eosio.evm PUBLIC -stack-size 40000 -use-freeing-malloc )

set_target_properties(eosio.evm
PROPERTIES
Expand Down
Binary file modified eosio.evm/eosio.evm.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion eosio.evm/include/eosio.evm/block.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License.
#pragma once

Expand Down
27 changes: 20 additions & 7 deletions eosio.evm/include/eosio.evm/constants.hpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License.

#pragma once

// Testing
#define PRINT_LOGS true // not really helpful on EOSIO, but kept for completeness
#define TESTING true // only for testing
#define OPTRACE false // only for testing
#define PRINT_STATE false // only for testing
#define CHARGE_SENDER_FOR_GAS false // only for testing
// Adds superpower testing functions (required for running cpp tests/clearing data in contract)
#define TESTING true

// Only turn this on when doing ethereum/tests (otherwise balances won't match)
#define CHARGE_SENDER_FOR_GAS false

// Keep all of these off unless testing/debugging
#define PRINT_LOGS false // not really helpful on EOSIO, but kept for completeness
#define OPTRACE false
#define PRINT_STATE false

// Token constants
#define TOKEN_SYMBOL_CODE_RAW "EOS"
Expand Down Expand Up @@ -73,6 +77,15 @@ namespace eosio_evm
static constexpr uint256_t GP_SSTORE_CLEARS_SCHEDULE = 15000;
static constexpr uint256_t GP_EXTRA_PER_LOG = 375;

// Precompiles
static constexpr uint256_t GP_ECRECOVER = 3000;
static constexpr uint256_t GP_IDENTITY_BASE = 15;
static constexpr uint256_t GP_IDENTITY_WORD = 3;
static constexpr uint256_t GP_SHA256 = 60;
static constexpr uint256_t GP_SHA256_WORD = 12;
static constexpr uint256_t GP_RIPEMD160 = 600;
static constexpr uint256_t GP_RIPEMD160_WORD = 120;

// TX
static constexpr size_t R_FIXED_LENGTH = 32u;
static constexpr size_t MAX_TX_SIZE = 128 * 1024; // Currently 128KB, more after EIP-2464
Expand Down
3 changes: 2 additions & 1 deletion eosio.evm/include/eosio.evm/context.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License.

#pragma once
Expand Down Expand Up @@ -31,6 +31,7 @@ namespace eosio_evm {
std::vector<uint8_t> mem;
Stack s;
uint256_t gas_left;
std::vector<uint8_t> last_return_data; // last returned data

const size_t sm_checkpoint;
const Account& caller;
Expand Down
4 changes: 2 additions & 2 deletions eosio.evm/include/eosio.evm/exception.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License.

#pragma once
Expand All @@ -13,7 +13,7 @@ namespace eosio_evm
public:
enum class Type
{
outOfBounds,
OOB,
outOfGas,
outOfFunds,
overflow,
Expand Down
10 changes: 7 additions & 3 deletions eosio.evm/include/eosio.evm/opcode.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License.

#pragma once
Expand Down Expand Up @@ -467,7 +467,8 @@ namespace eosio_evm
}

#if (OPTRACE == true)
static std::map<uint8_t, std::string> opcodeToString = {
static std::string opcodeToString (uint8_t op) {
std::map<uint8_t, std::string> opToStrings = {
// 0s: Stop and Arithmetic Operations
{ 0x00, "STOP" }, // Halts execution
{ 0x01, "ADD" }, // Addition operation
Expand Down Expand Up @@ -632,5 +633,8 @@ namespace eosio_evm
{ 0xfe, "INVALID" }, // Designated invalid instruction
{ 0xff, "SELFDESTRUCT" }
};
#endif /** OPTRACE **/

return opToStrings[op];
}
#endif /** OPTRACE **/
} // namespace eosio_evm
15 changes: 12 additions & 3 deletions eosio.evm/include/eosio.evm/processor.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License.

#pragma once
Expand All @@ -20,7 +20,6 @@ namespace eosio_evm {
evm* contract; // pointer to parent contract (to call EOSIO actions)
Context* ctx; // pointer to the current context
std::vector<std::unique_ptr<Context>> ctxs; // the stack of contexts (one per nested call)
std::vector<uint8_t> last_return_data; // last returned data

public:
Processor(EthereumTransaction& transaction, evm* contract)
Expand Down Expand Up @@ -55,7 +54,7 @@ namespace eosio_evm {
// Can return/throw errors
bool access_mem(const uint256_t& offset, const uint256_t& size);
bool prepare_mem_access(const uint256_t& offset, const uint64_t& size);
bool jump_to(const uint64_t newPc);
bool jump_to(const uint256_t& newPc);
bool use_gas(uint256_t amount);
bool process_sstore_gas(uint256_t original_value, uint256_t current_value, uint256_t new_value);
bool throw_error(const Exception& exception, const std::vector<uint8_t>& output);
Expand All @@ -75,6 +74,7 @@ namespace eosio_evm {
void selfdestruct(const Address& addr);
void kill_storage(const uint64_t& address_index);
bool transfer_internal(const Address& from, const Address& to, const int64_t amount);
void throw_stack();

// Reverting
void remove_code(const Address& address);
Expand All @@ -85,6 +85,15 @@ namespace eosio_evm {
void storekv(const uint64_t& address_index, const uint256_t& key, const uint256_t& value);
uint256_t loadkv(const uint64_t& address_index, const uint256_t& key);

// Precompile
void precompile_execute(uint256_t address);
void precompile_return(const std::vector<uint8_t>& output);
void precompile_not_implemented();
void precompile_ecrecover();
void precompile_sha256();
void precompile_ripemd160();
void precompile_identity();

// Instructions
void stop();
void add();
Expand Down
4 changes: 2 additions & 2 deletions eosio.evm/include/eosio.evm/program.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License.

#pragma once
Expand All @@ -12,7 +12,7 @@ namespace eosio_evm
const std::vector<uint8_t> code;
const std::set<uint64_t> jump_dests;

Program(std::vector<uint8_t>&& c)
Program(const std::vector<uint8_t>&& c)
: code(c),
jump_dests(compute_jump_dests(code)) {}

Expand Down
2 changes: 1 addition & 1 deletion eosio.evm/include/eosio.evm/stack.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License.

#pragma once
Expand Down
2 changes: 1 addition & 1 deletion eosio.evm/include/eosio.evm/tables.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License.

#pragma once
Expand Down
12 changes: 5 additions & 7 deletions eosio.evm/include/eosio.evm/transaction.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License.
#pragma once

Expand Down Expand Up @@ -65,6 +65,7 @@ namespace eosio_evm
#if (PRINT_LOGS == true)
std::string as_json_string() const {
std::string output = "[";

for (auto i = 0; i < logs.size(); i++) {
output += R"({"address": ")" + intx::hex(logs[i].address) + "\"," +
R"("data": ")" + bin2hex(logs[i].data) + "\"," +
Expand Down Expand Up @@ -343,7 +344,9 @@ namespace eosio_evm
"\"gasUsed\": ", intx::to_string(gas_used), ",",
"\"gasLimit\": ", intx::to_string(gas_limit), ",",
"\"gasPrice\": ", static_cast<int128_t>(gas_price), ",",
"\"logs\": ", PRINT_LOGS ? logs.as_json_string() : "", ",",
#if(PRINT_LOGS == true)
"\"logs\": ", logs.as_json_string(), ",",
#endif
"\"output\": \"", bin2hex(result.output), "\","
"\"errors\": ", errors_as_json_string(), ","
"\"transactionHash\": \"", hash, "\""
Expand All @@ -369,11 +372,6 @@ namespace eosio_evm
"hash ", hash, "\n"
);
}
void printEncoded() const
{
eosio::print("\n", encode() );
}
#endif /* TESTING */

};
} // namespace eosio_evm
8 changes: 6 additions & 2 deletions eosio.evm/include/eosio.evm/util.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License..

#pragma once
Expand All @@ -23,7 +23,11 @@ namespace eosio_evm
return res;
}

inline constexpr int64_t num_words(uint64_t size_in_bytes) noexcept
inline constexpr bool is_precompile(uint256_t address) {
return address >= 1 && address <= 65535;
}

inline constexpr int64_t num_words(uint64_t size_in_bytes)
{
return (static_cast<int64_t>(size_in_bytes) + (WORD_SIZE - 1)) / WORD_SIZE;
}
Expand Down
2 changes: 1 addition & 1 deletion eosio.evm/src/account.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License.

#include <eosio.evm/eosio.evm.hpp>
Expand Down
23 changes: 12 additions & 11 deletions eosio.evm/src/copy.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License..

// evmone: Fast Ethereum Virtual Machine implementation
// Copyright 2019 Pawel Bylica.
// Licensed under the Apache License, Version 2.0.
// Copyright (c) 2020 Syed Jafri. All rights reserved.
// Licensed under the MIT License..
// - Modified error handling and sources modified

#include <eosio.evm/eosio.evm.hpp>

Expand Down Expand Up @@ -48,8 +48,9 @@ namespace eosio_evm
// Resize
const auto end = static_cast<size_t>(new_words * WORD_SIZE);
if (end >= MAX_MEM_SIZE) {
return throw_error(Exception(ET::outOfBounds, "Memory limit exceeded"), {});
return throw_error(Exception(ET::OOB, "Memory limit exceeded"), {});
}

ctx->mem.resize(end);
}

Expand All @@ -62,7 +63,7 @@ namespace eosio_evm
const auto mem_index = ctx->s.pop();
const auto input_index = ctx->s.pop();
const auto size = ctx->s.pop();
if (ctx->s.stack_error) return (void) throw_error(Exception(ET::outOfBounds, *ctx->s.stack_error), {});
if (ctx->s.stack_error) return throw_stack();;

// Memory access + gas cost
bool memory_error = access_mem(mem_index, size);
Expand Down Expand Up @@ -97,7 +98,7 @@ namespace eosio_evm
const auto mem_index = ctx->s.pop();
const auto input_index = ctx->s.pop();
const auto size = ctx->s.pop();
if (ctx->s.stack_error) return (void) throw_error(Exception(ET::outOfBounds, *ctx->s.stack_error), {});
if (ctx->s.stack_error) return throw_stack();;

// Memory access + gas cost
bool memory_error = access_mem(mem_index, size);
Expand Down Expand Up @@ -136,7 +137,7 @@ namespace eosio_evm
const auto mem_index = ctx->s.pop();
const auto input_index = ctx->s.pop();
const auto size = ctx->s.pop();
if (ctx->s.stack_error) return (void) throw_error(Exception(ET::outOfBounds, *ctx->s.stack_error), {});
if (ctx->s.stack_error) return throw_stack();;

// Memory access + gas cost
bool memory_error = access_mem(mem_index, size);
Expand All @@ -146,9 +147,9 @@ namespace eosio_evm
auto destination_index = static_cast<size_t>(mem_index);

// Validate return data
auto return_data_size = last_return_data.size();
auto return_data_size = ctx->last_return_data.size();
if (return_data_size < input_index) {
throw_error(Exception(ET::outOfBounds, "Invalid memory access"), {});
throw_error(Exception(ET::OOB, "Invalid memory access"), {});
return;
}

Expand All @@ -158,7 +159,7 @@ namespace eosio_evm

// Validate source index
if (source_index + bounded_size > return_data_size) {
throw_error(Exception(ET::outOfBounds, "Invalid memory access"), {});
throw_error(Exception(ET::OOB, "Invalid memory access"), {});
return;
}

Expand All @@ -168,7 +169,7 @@ namespace eosio_evm

// Write to memory
if (bounded_size > 0) {
std::memcpy(&ctx->mem[destination_index], &last_return_data[source_index], bounded_size);
std::memcpy(&ctx->mem[destination_index], &ctx->last_return_data[source_index], bounded_size);
}
}
} // namespace eosio_evm
Loading

0 comments on commit fe440f1

Please sign in to comment.