evmc/test/vmtester/tests.cpp

171 lines
4.4 KiB
C++
Raw Normal View History

2018-08-30 15:38:14 +00:00
// EVMC: Ethereum Client-VM Connector API
// Copyright 2018-2019 The EVMC Authors.
// Licensed under the Apache License, Version 2.0.
2018-04-10 22:37:03 +00:00
2018-08-30 16:16:15 +00:00
#include "../../examples/example_host.h"
2018-04-10 22:37:03 +00:00
#include "vmtester.hpp"
#include <evmc/helpers.h>
2019-04-24 10:33:55 +00:00
#include <evmc/helpers.hpp>
2018-08-27 14:33:16 +00:00
#include <array>
2018-04-17 09:11:07 +00:00
#include <cstring>
namespace
{
// NOTE: this is to avoid compiler optimisations when reading the buffer
uint8_t read_uint8(const volatile uint8_t* p)
{
return *p;
}
void read_buffer(const uint8_t* ptr, size_t size)
{
for (size_t i = 0; i < size; i++)
{
read_uint8(&ptr[i]);
}
}
} // namespace
2018-04-10 22:37:03 +00:00
TEST_F(evmc_vm_test, abi_version_match)
{
ASSERT_EQ(vm->abi_version, EVMC_ABI_VERSION);
}
TEST_F(evmc_vm_test, name)
{
ASSERT_NE(vm->name, nullptr);
EXPECT_GT(std::strlen(vm->name), 0) << "VM name cannot be empty";
}
TEST_F(evmc_vm_test, version)
{
ASSERT_NE(vm->version, nullptr);
EXPECT_GT(std::strlen(vm->version), 0) << "VM name cannot be empty";
}
2019-04-24 10:33:55 +00:00
TEST_F(evmc_vm_test, execute_call)
2018-08-27 14:33:16 +00:00
{
2018-08-30 13:15:39 +00:00
evmc_context* context = example_host_create_context();
2018-08-27 14:33:16 +00:00
evmc_message msg{};
std::array<uint8_t, 2> code = {{0xfe, 0x00}};
evmc_result result =
vm->execute(vm, context, EVMC_MAX_REVISION, &msg, code.data(), code.size());
2018-08-27 14:33:16 +00:00
// Validate some constraints
if (result.status_code != EVMC_SUCCESS && result.status_code != EVMC_REVERT)
2018-08-29 20:56:55 +00:00
{
2018-08-27 14:33:16 +00:00
EXPECT_EQ(result.gas_left, 0);
2018-08-29 20:56:55 +00:00
}
2018-08-27 14:33:16 +00:00
if (result.output_data == NULL)
2018-08-29 20:56:55 +00:00
{
2018-08-27 14:33:16 +00:00
EXPECT_EQ(result.output_size, 0);
2018-08-29 20:56:55 +00:00
}
else
{
EXPECT_NE(result.output_size, 0);
read_buffer(result.output_data, result.output_size);
}
2018-08-27 14:33:16 +00:00
if (result.release)
result.release(&result);
2018-08-30 13:15:39 +00:00
example_host_destroy_context(context);
2018-08-27 14:33:16 +00:00
}
2019-04-24 10:33:55 +00:00
TEST_F(evmc_vm_test, execute_create)
{
evmc_context* context = example_host_create_context();
evmc_message msg{
EVMC_CREATE, 0, 0, 65536, evmc_address{}, evmc_address{}, NULL, 0, evmc_uint256be{},
evmc_bytes32{}};
std::array<uint8_t, 2> code = {{0xfe, 0x00}};
evmc_result result =
vm->execute(vm, context, EVMC_MAX_REVISION, &msg, code.data(), code.size());
// Validate some constraints
if (result.status_code != EVMC_SUCCESS && result.status_code != EVMC_REVERT)
{
EXPECT_EQ(result.gas_left, 0);
}
if (result.output_data == NULL)
{
EXPECT_EQ(result.output_size, 0);
}
else
{
EXPECT_NE(result.output_size, 0);
read_buffer(result.output_data, result.output_size);
}
if (result.status_code == EVMC_SUCCESS)
{
// This assumes that CREATE returns a non-zero address on success.
EXPECT_FALSE(is_zero(result.create_address));
}
if (result.release)
result.release(&result);
example_host_destroy_context(context);
}
TEST_F(evmc_vm_test, set_option_unknown_name)
2018-04-10 22:37:03 +00:00
{
if (vm->set_option)
{
evmc_set_option_result r = vm->set_option(vm, "unknown_option_csk9twq", "v");
2018-09-05 17:24:02 +00:00
EXPECT_EQ(r, EVMC_SET_OPTION_INVALID_NAME);
2018-04-10 22:37:03 +00:00
r = vm->set_option(vm, "unknown_option_csk9twq", "x");
2018-09-05 17:24:02 +00:00
EXPECT_EQ(r, EVMC_SET_OPTION_INVALID_NAME);
2018-04-10 22:37:03 +00:00
}
}
TEST_F(evmc_vm_test, set_option_empty_value)
{
if (vm->set_option)
{
evmc_set_option_result r = vm->set_option(vm, "unknown_option_csk9twq", nullptr);
2018-09-05 17:24:02 +00:00
EXPECT_EQ(r, EVMC_SET_OPTION_INVALID_NAME);
2018-04-10 22:37:03 +00:00
}
2018-04-17 09:11:07 +00:00
}
TEST_F(evmc_vm_test, set_option_unknown_value)
{
auto r = evmc_set_option(vm, "verbose", "1");
// Execute more tests if the VM supports "verbose" option.
if (r != EVMC_SET_OPTION_INVALID_NAME)
{
// The VM supports "verbose" option. Try dummy value for it.
auto r2 = evmc_set_option(vm, "verbose", "GjNOONsbUl");
EXPECT_EQ(r2, EVMC_SET_OPTION_INVALID_VALUE);
// For null the behavior should be the same.
auto r3 = evmc_set_option(vm, "verbose", nullptr);
EXPECT_EQ(r3, EVMC_SET_OPTION_INVALID_VALUE);
}
}
TEST_F(evmc_vm_test, set_tracer)
{
2019-03-11 11:54:12 +00:00
static const auto tracer_callback =
[](evmc_tracer_context*, size_t, evmc_status_code, int64_t, size_t, const evmc_uint256be*,
size_t, size_t, size_t, const uint8_t*) noexcept {};
2018-06-18 12:22:16 +00:00
if (vm->set_tracer)
vm->set_tracer(vm, tracer_callback, nullptr);
}
2018-09-08 16:23:27 +00:00
TEST_F(evmc_vm_test, capabilities)
{
// The VM should have at least one of EVM1 or EWASM capabilities.
EXPECT_TRUE(evmc_vm_has_capability(vm, EVMC_CAPABILITY_EVM1) ||
evmc_vm_has_capability(vm, EVMC_CAPABILITY_EWASM));
}