Skip to content

EOF code validation (EIP-3670)#366

Merged
gumb0 merged 2 commits intomasterfrom
eof-code-validation
Apr 4, 2022
Merged

EOF code validation (EIP-3670)#366
gumb0 merged 2 commits intomasterfrom
eof-code-validation

Conversation

@gumb0
Copy link
Copy Markdown
Member

@gumb0 gumb0 commented Jul 28, 2021

No description provided.

@gumb0 gumb0 force-pushed the eof-code-validation branch from 7765c0b to d27046d Compare July 28, 2021 14:05
@codecov
Copy link
Copy Markdown

codecov bot commented Jul 28, 2021

Codecov Report

Merging #366 (6c563f4) into eof-execution (631b430) will increase coverage by 0.00%.
The diff coverage is 100.00%.

❗ Current head 6c563f4 differs from pull request most recent head 7ac440c. Consider uploading reports for the commit 7ac440c to get more accurate results

@@              Coverage Diff               @@
##           eof-execution     #366   +/-   ##
==============================================
  Coverage          99.57%   99.58%           
==============================================
  Files                 37       37           
  Lines               4487     4551   +64     
==============================================
+ Hits                4468     4532   +64     
  Misses                19       19           
Flag Coverage Δ
consensus 78.94% <0.00%> (-1.22%) ⬇️
unittests 99.62% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
lib/evmone/eof.cpp 98.03% <100.00%> (+0.39%) ⬆️
test/unittests/eof_validation_test.cpp 100.00% <100.00%> (ø)

@gumb0 gumb0 force-pushed the eof-execution branch 9 times, most recently from b166534 to 850d7b8 Compare August 12, 2021 13:45
@gumb0 gumb0 force-pushed the eof-code-validation branch from d27046d to cac511b Compare August 12, 2021 14:24
@gumb0 gumb0 force-pushed the eof-code-validation branch 2 times, most recently from 1ccc8aa to f82ac27 Compare August 30, 2021 13:56
@gumb0 gumb0 force-pushed the eof-execution branch 2 times, most recently from e07ffef to de74fc2 Compare September 29, 2021 14:51
@gumb0 gumb0 force-pushed the eof-code-validation branch 3 times, most recently from 3b42a85 to 2411d77 Compare October 4, 2021 11:27
@gumb0 gumb0 force-pushed the eof-execution branch 2 times, most recently from 8127c9b to 6181dd1 Compare October 6, 2021 15:26
@gumb0 gumb0 force-pushed the eof-code-validation branch 4 times, most recently from a73f066 to eb773aa Compare October 11, 2021 16:43
@gumb0 gumb0 force-pushed the eof-execution branch 5 times, most recently from d387060 to 38461f6 Compare March 2, 2022 15:06
@gumb0 gumb0 force-pushed the eof-execution branch 15 times, most recently from a574ec8 to 6eb5cc5 Compare March 15, 2022 14:21
@gumb0 gumb0 force-pushed the eof-code-validation branch 2 times, most recently from 1210ca1 to e017bda Compare March 16, 2022 11:47
@gumb0 gumb0 force-pushed the eof-execution branch 4 times, most recently from 6826cc4 to 453c9ca Compare March 22, 2022 11:28
@gumb0 gumb0 force-pushed the eof-code-validation branch from e017bda to c09f8cc Compare March 22, 2022 11:36
int8_t stack_height_change = 0;

/// Size of the immediate argument in bytes.
uint8_t immediate_size = 0;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably better to place it as the second field. The whole traits change should be submitted separately.

Copy link
Copy Markdown
Member Author

@gumb0 gumb0 Mar 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the second? What about is_terminating?

Do you want a separate PR? (these fields are used only in this PR) I put it into a separate commit so far.

return {{}, error};
assert(code.size() > 0); // guaranteed by EOF headers validation

size_t i = 0;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isn't this an iterator instead?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because with an iterator loop end condition can be only it != code.end(), but loop can overrun end in case of truncated immediate.

{
op = code[i];
const auto& since = instr::traits[op].since;
if (!since.has_value() || *since > rev)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this doesn't cover the case when we want to remove an opcode (e.g.calldata) from EOF contracts?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, when that happens I guess we will need to add final revision to traits.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. This looks like a good solution if needed.

Validate that all used instructions are defined and code ends with a terminating instruction.

namespace
{
inline EOFValidationError validate_eof(bytes_view cont, evmc_revision rev = EVMC_SHANGHAI) noexcept
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
inline EOFValidationError validate_eof(bytes_view cont, evmc_revision rev = EVMC_SHANGHAI) noexcept
inline EOFValidationError validate_eof(bytes_view container, evmc_revision rev = EVMC_SHANGHAI) noexcept

{
inline EOFValidationError validate_eof(bytes_view cont, evmc_revision rev = EVMC_SHANGHAI) noexcept
{
return ::validate_eof(rev, cont);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it call evmone::validate_eof()? I'm confused.

}

inline EOFValidationError validate_eof(
std::string_view code_hex, evmc_revision rev = EVMC_SHANGHAI) noexcept
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this overload is used once and there is another use case as validate_eof(from_hex(...)). I'm rather for removing this overload. It sometimes become confusing when a unit tests multiple levels of wrappers. Using from_hex() or bytecode{} is fine or you can use bytecode as the type of the parameter.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed it to a single helper with bytecode parameter, can be called with either hex string or bytes container.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy want it as const bytecode&. I think changing it like this should not be a problem.

while (i < code.size())
{
op = code[i];
const auto& since = instr::traits[op].since;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is fine for now, but instr::traits has sub-optimal layout for runtime use.

{
op = code[i];
const auto& since = instr::traits[op].since;
if (!since.has_value() || *since > rev)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. This looks like a good solution if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants