Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bridge basic message emission #630

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c092f8a
Add bridgereg/bridgeunreg actions
elmato Jul 24, 2023
91c58a5
Handle 'emit' EVM call messages
elmato Jul 24, 2023
bd531a3
Add tests for 'emit' message functionality
elmato Jul 24, 2023
2850d30
Add more tests for the 'emit' message functionality
elmato Jul 24, 2023
1e300f2
Add call actions. Pending submodule silkworm updates.
yarkinwho Jul 27, 2023
02f90c7
Use EVM message filter functionality to process bridge messages
elmato Jul 27, 2023
6e8750e
Allow call to create contracts.
yarkinwho Jul 28, 2023
a6bd606
Change error message when inline pushtx actions fails and add tests for
yarkinwho Aug 4, 2023
48513d5
update submodule silkworm
yarkinwho Aug 4, 2023
867fa2c
Add missing const.
yarkinwho Aug 7, 2023
7ae7a54
Optimize build artifact size by removing object files.
oschwaldp-oci Aug 8, 2023
87dff73
Optimize tests build artifact size by removing object files.
oschwaldp-oci Aug 8, 2023
a7ed7d9
Merge pull request #639 from eosnetworkfoundation/gh-632-reduce-artif…
oschwaldp-oci Aug 8, 2023
bc173c3
Optimze logic when processing tx with special signature.
yarkinwho Aug 9, 2023
4a22a22
Fix test styles.
yarkinwho Aug 9, 2023
8156407
More detailed tests for gas fee.
yarkinwho Aug 9, 2023
3ec3131
Merge branch 'main' into yarkin/call_action_new
yarkinwho Aug 9, 2023
4b35e5e
Update submodule
yarkinwho Aug 9, 2023
33c066b
improve bridge tx handling logic.
yarkinwho Aug 10, 2023
5d9afcd
Only intx::uint128's ctor can work properly with uint128_t. We may
yarkinwho Aug 10, 2023
8101a51
Add tests for calls with payments.
yarkinwho Aug 10, 2023
9759072
Change data type of value to const byte&
yarkinwho Aug 11, 2023
37b8ee2
Fix an unsafe intx::load.
yarkinwho Aug 14, 2023
f1d9f9f
Merge pull request #634 from eosnetworkfoundation/yarkin/call_action_new
arhag Aug 14, 2023
31d7024
Update silkworm submodule
arhag Aug 14, 2023
509c3ee
Merge pull request #641 from eosnetworkfoundation/arhag/update-silkworm
arhag Aug 14, 2023
f506abe
tests: move inevm function to base tester class
elmato Aug 16, 2023
76319e7
Remove balance modification for the EOS EVM contract account
elmato Aug 16, 2023
656706e
Add versioning to the bridge message
elmato Aug 16, 2023
cecbafe
Merge branch 'elmato/bridge-basic-message-emission' into merge-bridge
elmato Aug 17, 2023
ccaa5d7
Add force_atomic parameter to method bridgeMsgV0
elmato Aug 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-contract-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ ee make -j "$(nproc)" unit_test

# pack
ee popd
ee 'tar -czf ../contract-test.tar.gz build/*'
ee 'tar -czf ../contract-test.tar.gz --exclude="*.o" build/*'
ee popd

echo "Done! - ${0##*/}"
2 changes: 1 addition & 1 deletion .github/workflows/build-contract.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ ee make -j "$(nproc)"

# pack
ee popd
ee 'tar -czf contract.tar.gz build/*'
ee 'tar -czf contract.tar.gz --exclude="*.obj" build/*'

echo "Done! - ${0##*/}"
76 changes: 76 additions & 0 deletions include/evm_runtime/bridge.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#pragma once

#include <evm_runtime/types.hpp>

namespace evm_runtime { namespace bridge {

struct message_v0 {
static constexpr uint32_t id = 0xf781185b; //sha3('bridgeMsgV0(string,bool,bytes)')[:4]

string account;
bool force_atomic; //currently only atomic is supported
bytes data;

name get_account_as_name() const {
if(!account_.has_value()) {
account_ = name{account};
eosio::check(account_.value().to_string() == account, "invalid account name");
}
return *account_;
}

mutable std::optional<name> account_;
};

using message = std::variant<message_v0>;

message_v0 decode_message_v0(eosio::datastream<const uint8_t*>& ds) {
// offset_p1 (32) + p2_value (32) + offset_p3 (32)
// p1_len (32) + p1_data ((p1_len+31)/32*32)
// p3_len (32) + p3_data ((p2_len+31)/32*32)
uint256 offset_p1, value_p2, offset_p3;

ds >> offset_p1;
eosio::check(offset_p1 == 0x60, "invalid p1 offset");
ds >> value_p2;
eosio::check(value_p2 <= 1, "invalid p2 value");
ds >> offset_p3;
eosio::check(offset_p3 == 0xA0, "invalid p3 offset");

message_v0 res;
res.force_atomic = value_p2 ? true : false;

auto get_length=[&]() -> uint32_t {
uint256 len;
ds >> len;
eosio::check(len < std::numeric_limits<uint32_t>::max(), "invalid length");
return static_cast<uint32_t>(len);
};

uint32_t p1_len = get_length();
auto p1_len_32 = (p1_len+31)/32*32;
res.account.resize(p1_len_32);
ds.read(res.account.data(), p1_len_32);
res.account.resize(p1_len);

uint32_t p3_len = get_length();
auto p3_len_32 = (p3_len+31)/32*32;
res.data.resize(p3_len_32);
ds.read(res.data.data(), p3_len_32);
res.data.resize(p3_len);

return res;
}

std::optional<message> decode_message(ByteView bv) {
// method_id (4)
eosio::datastream<const uint8_t*> ds(bv.data(), bv.size());
uint32_t method_id;
ds >> method_id;

if(method_id == __builtin_bswap32(message_v0::id)) return decode_message_v0(ds);
return {};
}

} //namespace bridge
} //namespace evm_runtime
9 changes: 9 additions & 0 deletions include/evm_runtime/evm_contract.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ class [[eosio::contract]] evm_contract : public contract
/// @return true if all garbage has been collected
[[eosio::action]] bool gc(uint32_t max);

[[eosio::action]] void bridgereg(eosio::name receiver, const eosio::asset& min_fee);
[[eosio::action]] void bridgeunreg(eosio::name receiver);

[[eosio::action]] void call(eosio::name from, const bytes& to, const bytes& value, const bytes& data, uint64_t gas_limit);
[[eosio::action]] void admincall(const bytes& from, const bytes& to, const bytes& value, const bytes& data, uint64_t gas_limit);

#ifdef WITH_TEST_ACTIONS
[[eosio::action]] void testtx(const std::optional<bytes>& orlptx, const evm_runtime::test::block_info& bi);
[[eosio::action]] void
Expand Down Expand Up @@ -132,6 +138,7 @@ class [[eosio::contract]] evm_contract : public contract
}

silkworm::Receipt execute_tx(eosio::name miner, silkworm::Block& block, silkworm::Transaction& tx, silkworm::ExecutionProcessor& ep, bool enforce_chain_id);
void process_filtered_messages(const std::vector<silkworm::FilteredMessage>& filtered_messages);

uint64_t get_and_increment_nonce(const name owner);

Expand All @@ -140,6 +147,8 @@ class [[eosio::contract]] evm_contract : public contract
void handle_account_transfer(const eosio::asset& quantity, const std::string& memo);
void handle_evm_transfer(eosio::asset quantity, const std::string& memo);

void call_(intx::uint256 s, const bytes& to, intx::uint256 value, const bytes& data, uint64_t gas_limit, uint64_t nonce);

// to allow sending through a Bytes (basic_string<uint8_t>) w/o copying over to a std::vector<char>
void pushtx_bytes(eosio::name miner, const std::basic_string<uint8_t>& rlptx);
using pushtx_action = eosio::action_wrapper<"pushtx"_n, &evm_contract::pushtx_bytes>;
Expand Down
18 changes: 10 additions & 8 deletions include/evm_runtime/print_tracer.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#pragma once
#include <evmc/instructions.h>
#include <eosio/eosio.hpp>
namespace evm_runtime {

struct print_tracer : EvmTracer {
struct print_tracer : silkworm::EvmTracer {

const char* const* opcode_names_ = nullptr;

Expand All @@ -19,27 +20,28 @@ struct print_tracer : EvmTracer {
}

void on_instruction_start(uint32_t pc, const intx::uint256* stack_top, int stack_height,
const evmone::ExecutionState& state,
const IntraBlockState& intra_block_state) noexcept override {
const auto opcode = state.code[pc];
int64_t gas, const evmone::ExecutionState& state,
const silkworm::IntraBlockState& intra_block_state) override {

const auto opcode = state.original_code[pc];
auto opcode_name = get_opcode_name(opcode_names_, opcode);
eosio::print(opcode_name.c_str(), "\n");
}

void on_execution_end(const evmc_result& result, const IntraBlockState& intra_block_state) noexcept override {
void on_execution_end(const evmc_result& result, const silkworm::IntraBlockState& intra_block_state) noexcept override {
eosio::print("TRACE: end\n");
}

void on_creation_completed(const evmc_result& result, const IntraBlockState& intra_block_state) noexcept override {
void on_creation_completed(const evmc_result& result, const silkworm::IntraBlockState& intra_block_state) noexcept override {

}

void on_precompiled_run(const evmc_result& result, int64_t gas,
const IntraBlockState& intra_block_state) noexcept override {
const silkworm::IntraBlockState& intra_block_state) noexcept override {

}

void on_reward_granted(const CallResult& result, const IntraBlockState& intra_block_state) noexcept override {
void on_reward_granted(const silkworm::CallResult& result, const silkworm::IntraBlockState& intra_block_state) noexcept override {

}

Expand Down
22 changes: 21 additions & 1 deletion include/evm_runtime/tables.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,24 @@ struct [[eosio::table]] [[eosio::contract("evm_contract")]] allowed_egress_accou

typedef eosio::multi_index<"egresslist"_n, allowed_egress_account> egresslist;

} //namespace evm_runtime
struct [[eosio::table]] [[eosio::contract("evm_contract")]] message_receiver {

enum flag : uint32_t {
FORCE_ATOMIC = 0x1
};

name account;
asset min_fee;
uint32_t flags;

uint64_t primary_key() const { return account.value; }
bool has_flag(flag f) const {
return (flags & f) != 0;
}

EOSLIB_SERIALIZE(message_receiver, (account)(min_fee)(flags));
};

typedef eosio::multi_index<"msgreceiver"_n, message_receiver> message_receiver_table;

} //namespace evm_runtime
14 changes: 13 additions & 1 deletion include/evm_runtime/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace evm_runtime {
eosio::checksum256 make_key(bytes data);
eosio::checksum256 make_key(const evmc::address& addr);
eosio::checksum256 make_key(const evmc::bytes32& data);

bytes to_bytes(const uint256& val);
bytes to_bytes(const evmc::bytes32& val);
bytes to_bytes(const evmc::address& addr);
Expand Down Expand Up @@ -63,6 +63,18 @@ namespace evm_runtime {
EOSLIB_SERIALIZE(exec_output, (status)(data)(context));
};

struct bridge_message_v0 {
eosio::name receiver;
bytes sender;
eosio::time_point timestamp;
bytes value;
bytes data;

EOSLIB_SERIALIZE(bridge_message_v0, (receiver)(sender)(timestamp)(value)(data));
};

using bridge_message = std::variant<bridge_message_v0>;

} //namespace evm_runtime

namespace eosio {
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,5 @@ target_compile_options(evm_runtime PUBLIC --no-missing-ricardian-clause)
if (WITH_LARGE_STACK)
target_link_options(evm_runtime PUBLIC --stack-size=50000000)
else()
target_link_options(evm_runtime PUBLIC --stack-size=38560)
target_link_options(evm_runtime PUBLIC --stack-size=32768)
endif()
Loading