mirror of https://github.com/status-im/evmc.git
Merge pull request #257 from ethereum/cpp-host-call
cpp: Fix Host::call()
This commit is contained in:
commit
2dc8eeb77c
|
@ -1,5 +1,13 @@
|
|||
# Changelog
|
||||
|
||||
## [6.2.1] - unreleased
|
||||
|
||||
- Fixed:
|
||||
[[#256](https://github.com/ethereum/evmc/issues/256),
|
||||
[#257](https://github.com/ethereum/evmc/issues/257)]
|
||||
Disallow implicit conversion from C++ `evmc::result` to `evmc_result`
|
||||
causing unintendent premature releasing of resources.
|
||||
|
||||
## [6.2.0] - 2019-04-25
|
||||
|
||||
- Added: [[#216](https://github.com/ethereum/evmc/pull/216)]
|
||||
|
|
|
@ -66,12 +66,12 @@ jobs:
|
|||
CXX: g++-8
|
||||
CMAKE_OPTIONS: -DTOOLCHAIN=cxx17-pic
|
||||
|
||||
build-cxx14:
|
||||
build-cxx14-asan:
|
||||
<<: *build
|
||||
environment:
|
||||
CC: clang-8
|
||||
CXX: clang++-8
|
||||
CMAKE_OPTIONS: -DTOOLCHAIN=cxx14-pic
|
||||
CMAKE_OPTIONS: -DTOOLCHAIN=cxx14-pic -DSANITIZE=address
|
||||
|
||||
build-gcc6:
|
||||
<<: *build
|
||||
|
@ -178,7 +178,7 @@ workflows:
|
|||
jobs:
|
||||
- lint
|
||||
- build-cxx17
|
||||
- build-cxx14
|
||||
- build-cxx14-asan
|
||||
- build-gcc6
|
||||
- build-clang3.8
|
||||
- bindings-go-latest
|
||||
|
|
|
@ -94,10 +94,14 @@ public:
|
|||
|
||||
evmc::result call(const evmc_message& msg) noexcept final
|
||||
{
|
||||
(void)msg;
|
||||
// TODO: Improve C++ API for result creation.
|
||||
evmc_result res{};
|
||||
res.status_code = EVMC_FAILURE;
|
||||
res.status_code = EVMC_REVERT;
|
||||
auto output = new uint8_t[msg.input_size];
|
||||
std::copy(&msg.input_data[0], &msg.input_data[msg.input_size], output);
|
||||
res.output_size = msg.input_size;
|
||||
res.output_data = output;
|
||||
res.release = [](const evmc_result* r) noexcept { delete[] r->output_data; };
|
||||
return evmc::result{res};
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,15 @@ namespace evmc
|
|||
///
|
||||
/// This is a RAII wrapper for evmc_result and objects of this type
|
||||
/// automatically release attached resources.
|
||||
class result : public evmc_result
|
||||
class result : private evmc_result
|
||||
{
|
||||
public:
|
||||
using evmc_result::create_address;
|
||||
using evmc_result::gas_left;
|
||||
using evmc_result::output_data;
|
||||
using evmc_result::output_size;
|
||||
using evmc_result::status_code;
|
||||
|
||||
/// Converting constructor from raw evmc_result.
|
||||
explicit result(evmc_result const& res) noexcept : evmc_result{res} {}
|
||||
|
||||
|
@ -45,6 +51,15 @@ public:
|
|||
std::swap(*this, other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Returns the raw copy of evmc_result,
|
||||
/// releases the ownership of the resources and invalidates this object.
|
||||
evmc_result raw() noexcept
|
||||
{
|
||||
auto out = evmc_result{};
|
||||
std::swap<evmc_result>(out, *this);
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
/// @copybrief evmc_instance
|
||||
|
@ -302,7 +317,7 @@ inline void selfdestruct(evmc_context* h,
|
|||
}
|
||||
inline evmc_result call(evmc_context* h, const evmc_message* msg) noexcept
|
||||
{
|
||||
return static_cast<Host*>(h)->call(*msg);
|
||||
return static_cast<Host*>(h)->call(*msg).raw();
|
||||
}
|
||||
inline evmc_tx_context get_tx_context(evmc_context* h) noexcept
|
||||
{
|
||||
|
|
|
@ -87,7 +87,6 @@ TEST(cpp, host)
|
|||
EXPECT_EQ(host.copy_code(a, 0, nullptr, 0), 0);
|
||||
|
||||
host.selfdestruct(a, a);
|
||||
EXPECT_EQ(host.call({}).gas_left, 0);
|
||||
|
||||
auto tx = host.get_tx_context();
|
||||
EXPECT_EQ(host.get_tx_context().block_number, tx.block_number);
|
||||
|
@ -98,3 +97,26 @@ TEST(cpp, host)
|
|||
|
||||
example_host_destroy_context(host_context);
|
||||
}
|
||||
|
||||
TEST(cpp, host_call)
|
||||
{
|
||||
// Use example host to test Host::call() method.
|
||||
|
||||
auto* host_context = example_host_create_context();
|
||||
auto host = evmc::HostContext{host_context};
|
||||
|
||||
EXPECT_EQ(host.call({}).gas_left, 0);
|
||||
|
||||
auto msg = evmc_message{};
|
||||
msg.gas = 1;
|
||||
uint8_t input[] = {0xa, 0xb, 0xc};
|
||||
msg.input_data = input;
|
||||
msg.input_size = sizeof(input);
|
||||
|
||||
auto res = host.call(msg);
|
||||
EXPECT_EQ(res.status_code, EVMC_REVERT);
|
||||
EXPECT_EQ(res.output_size, msg.input_size);
|
||||
EXPECT_TRUE(std::equal(&res.output_data[0], &res.output_data[res.output_size], msg.input_data));
|
||||
|
||||
example_host_destroy_context(host_context);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue