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

feat(avm): error handling for address resolution #9994

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

jeanmon
Copy link
Contributor

@jeanmon jeanmon commented Nov 15, 2024

Resolves #9131

@jeanmon jeanmon marked this pull request as ready for review November 15, 2024 13:48
Copy link
Contributor

@fcarreiro fcarreiro left a comment

Choose a reason for hiding this comment

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

I left some thoughts on who should do the validation. Give it a thought and LMK what you think.

yarn-project/simulator/src/avm/opcodes/addressing_mode.ts Outdated Show resolved Hide resolved
resolved[i] += Number(mem.get(0).toBigInt());
const baseAddr = Number(mem.get(0).toBigInt());
resolved[i] += baseAddr;
if (resolved[i] > maxUint32) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm I'm not sure this should be done here. And I mean that twice:
(1) a relative address that is too big is probably not bad until you try to resolve it
(2) in principle I'd move this to the "INDIRECT" if statement but...

These things might be better handled inside mem.get, which is the part of the system knowing about the memory limit. A red flag is that you had to import this maxUint32, but what if we change the memory size?

Also in your followup work, you will need to handle memory accesses in each opcode. I think what you are doing is assuming "if the resolution already 'constrains' the addresses, then they should be right". That is partially ok. But think of the cases where we read slices. Then the slice+length is not sanitized and it falls back to the memory component to validate it. Which it does, with an assert.

Overall, on the simulator side, it might be better to just change the memory assertions to exceptions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In cpp code, we have the type safety (uint32_t) which guarantees that we cannot read an address out of range. It would be very artificial, to upcast memory address to larger integer types. Alternatively, how should we defer (not in address resolution) the cpp error handling if an address is out of range? Probably, wrapping the uint32_t into a "MemoryAddress" type and keep a special value when we are out of range.

TS and cpp need to be kept in sync and errors need to happen at the same step of execution. We might add a "safeguard" on TS, by throwing an error when a memory read happens out of range, but this should only serve to detect a coding mistake (like an assert in cpp).

barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp Outdated Show resolved Hide resolved
// TODO(#9131): Error handling needs to be done
ASSERT(mem_tag == AvmMemoryTag::U32);
resolved[i] = static_cast<uint32_t>(mem_builder.unconstrained_read(space_id, resolved[i]));
const auto mem_tag = mem_builder.unconstrained_get_memory_tag(space_id, res_addr);
Copy link
Contributor

Choose a reason for hiding this comment

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

Just like I mention in the TS file, it might be better to just throw OutOfRange in the mem_builder and catch in the opcode implementation

barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp Outdated Show resolved Hide resolved
@jeanmon jeanmon force-pushed the jm/9131-error-handling-addr-resolution branch 2 times, most recently from c08c648 to 79b2573 Compare November 19, 2024 10:41
@jeanmon jeanmon force-pushed the jm/9131-error-handling-addr-resolution branch from 79b2573 to 8c9282f Compare November 19, 2024 13:54
Copy link
Contributor

Changes to circuit sizes

Generated at commit: 50e73ee19e478e75b6a2bbdca9b41476a8fbcaaa, compared to commit: c8de6cf883db85f8cf0c266e0996eb3f6c53345c

🧾 Summary (100% most significant diffs)

Program ACIR opcodes (+/-) % Circuit size (+/-) %
rollup_base_private +176 ❌ +0.05% +176 ❌ +0.01%
rollup_base_public +176 ❌ +0.04% +176 ❌ +0.00%
rollup_root +4 ❌ +0.03% +4 ❌ +0.00%
rollup_block_merge +4 ❌ +0.03% +4 ❌ +0.00%

Full diff report 👇
Program ACIR opcodes (+/-) % Circuit size (+/-) %
rollup_base_private 335,237 (+176) +0.05% 3,409,576 (+176) +0.01%
rollup_base_public 472,504 (+176) +0.04% 3,745,928 (+176) +0.00%
rollup_root 11,993 (+4) +0.03% 1,858,510 (+4) +0.00%
rollup_block_merge 12,009 (+4) +0.03% 1,858,524 (+4) +0.00%

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.

Avm circuit: relative memory addressing - error handling
2 participants