cpp: Add evmc::result constructor to copy output

This commit is contained in:
Paweł Bylica 2019-06-26 13:51:45 +02:00
parent 4f7aa2e4f9
commit e4ae2162c5
No known key found for this signature in database
GPG Key ID: 7A0C037434FE77EF
3 changed files with 51 additions and 9 deletions

View File

@ -95,15 +95,7 @@ public:
evmc::result call(const evmc_message& msg) noexcept final
{
// TODO: Improve C++ API for result creation.
evmc_result res{};
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};
return {EVMC_REVERT, msg.gas, msg.input_data, msg.input_size};
}
evmc_tx_context get_tx_context() noexcept final { return {}; }

View File

@ -7,6 +7,8 @@
#include <evmc/evmc.h>
#include <evmc/helpers.h>
#include <algorithm>
#include <cstdlib>
#include <functional>
#include <initializer_list>
#include <utility>
@ -268,6 +270,33 @@ public:
using evmc_result::output_size;
using evmc_result::status_code;
/// Creates the result from the provided arguments.
///
/// The provided output is copied to memory allocated with malloc()
/// and the evmc_result::release function is set to one invoking free().
///
/// @param _status_code The status code.
/// @param _gas_left The amount of gas left.
/// @param _output_data The pointer to the output.
/// @param _output_size The output size.
result(evmc_status_code _status_code,
int64_t _gas_left,
const uint8_t* _output_data,
size_t _output_size) noexcept
: evmc_result{_status_code, _gas_left, nullptr, _output_size, {}, {}, {}}
{
if (output_size != 0)
{
auto mem = static_cast<uint8_t*>(std::malloc(output_size));
std::copy_n(_output_data, output_size, mem);
output_data = mem;
release = [](const evmc_result* r) noexcept
{
std::free(const_cast<uint8_t*>(r->output_data));
};
}
}
/// Converting constructor from raw evmc_result.
explicit result(evmc_result const& res) noexcept : evmc_result{res} {}

View File

@ -472,3 +472,24 @@ TEST(cpp, result_move)
}
EXPECT_EQ(release_called, 2);
}
TEST(cpp, result_create_no_output)
{
auto r = evmc::result{EVMC_REVERT, 1, nullptr, 0};
EXPECT_EQ(r.status_code, EVMC_REVERT);
EXPECT_EQ(r.gas_left, 1);
EXPECT_FALSE(r.output_data);
EXPECT_EQ(r.output_size, 0);
}
TEST(cpp, result_create)
{
const uint8_t output[] = {1, 2};
auto r = evmc::result{EVMC_FAILURE, -1, output, sizeof(output)};
EXPECT_EQ(r.status_code, EVMC_FAILURE);
EXPECT_EQ(r.gas_left, -1);
ASSERT_TRUE(r.output_data);
ASSERT_EQ(r.output_size, 2);
EXPECT_EQ(r.output_data[0], 1);
EXPECT_EQ(r.output_data[1], 2);
}