Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions barretenberg/cpp/pil/vm2/context.pil
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,10 @@ namespace execution;

pol commit is_static;
is_static * (1 - is_static) = 0;

pol commit parent_calldata_offset_addr;
pol commit parent_calldata_size_addr;

pol commit last_child_returndata_offset_addr;
pol commit last_child_returndata_size_addr;
pol commit last_child_success; // Careful with this for now...
3 changes: 3 additions & 0 deletions barretenberg/cpp/pil/vm2/context_stack.pil
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ namespace context_stack;

pol commit is_static;
is_static * (1 - is_static) = 0;

pol commit parent_calldata_offset_addr;
pol commit parent_calldata_size_addr;
6 changes: 3 additions & 3 deletions barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,12 @@ class AvmFlavor {
static constexpr bool HasZK = false;

static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 47;
static constexpr size_t NUM_WITNESS_ENTITIES = 929;
static constexpr size_t NUM_WITNESS_ENTITIES = 936;
static constexpr size_t NUM_SHIFTED_ENTITIES = 134;
static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES;
// We have two copies of the witness entities, so we subtract the number of fixed ones (they have no shift), one for
// the unshifted and one for the shifted
static constexpr size_t NUM_ALL_ENTITIES = 1110;
static constexpr size_t NUM_ALL_ENTITIES = 1117;

// In the sumcheck univariate computation, we divide the trace in chunks and each chunk is
// evenly processed by all the threads. This constant defines the maximum number of rows
Expand Down
171 changes: 125 additions & 46 deletions barretenberg/cpp/src/barretenberg/vm2/simulation/context.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#pragma once

#include <algorithm>
#include <cstdint>
#include <memory>
#include <span>
#include <vector>

#include "barretenberg/vm2/common/aztec_types.hpp"
#include "barretenberg/vm2/common/field.hpp"
#include "barretenberg/vm2/common/memory_types.hpp"
#include "barretenberg/vm2/simulation/bytecode_manager.hpp"
#include "barretenberg/vm2/simulation/events/context_events.hpp"
#include "barretenberg/vm2/simulation/events/event_emitter.hpp"
Expand All @@ -26,7 +28,6 @@ class ContextInterface {
virtual void set_pc(uint32_t new_pc) = 0;
virtual uint32_t get_next_pc() const = 0;
virtual void set_next_pc(uint32_t new_next_pc) = 0;
virtual void set_nested_returndata(std::vector<FF> return_data) = 0;
virtual bool halted() const = 0;
virtual void halt() = 0;

Expand All @@ -35,11 +36,24 @@ class ContextInterface {
// Environment.
virtual const AztecAddress& get_address() const = 0;
virtual const AztecAddress& get_msg_sender() const = 0;
virtual std::span<const FF> get_calldata() const = 0;
virtual bool get_is_static() const = 0;

// Input / Output
virtual std::vector<FF> get_calldata(uint32_t cd_offset, uint32_t cd_size) const = 0;
virtual std::vector<FF> get_returndata(uint32_t rd_offset, uint32_t rd_size) = 0;
virtual ContextInterface& get_child_context() = 0;
virtual void set_child_context(std::unique_ptr<ContextInterface> child_ctx) = 0;

virtual MemoryAddress get_last_rd_offset() const = 0;
virtual void set_last_rd_offset(MemoryAddress rd_offset) = 0;

virtual MemoryAddress get_last_rd_size() const = 0;
virtual void set_last_rd_size(MemoryAddress rd_size) = 0;

virtual bool get_last_success() const = 0;
virtual void set_last_success(bool success) = 0;

// Events
virtual void emit_context_snapshot() = 0;
virtual ContextEvent get_current_context() = 0;
};

Expand All @@ -49,19 +63,15 @@ class BaseContext : public ContextInterface {
BaseContext(uint32_t context_id,
AztecAddress address,
AztecAddress msg_sender,
std::span<const FF> calldata,
bool is_static,
std::unique_ptr<BytecodeManagerInterface> bytecode,
std::unique_ptr<MemoryInterface> memory,
EventEmitterInterface<ContextStackEvent>& ctx_stack_events)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Migrated to Execution - feels better

std::unique_ptr<MemoryInterface> memory)
: address(address)
, msg_sender(msg_sender)
, calldata(calldata.begin(), calldata.end())
, is_static(is_static)
, context_id(context_id)
, bytecode(std::move(bytecode))
, memory(std::move(memory))
, ctx_stack_events(ctx_stack_events)
{}

// Having getters and setters make it easier to mock the context.
Expand All @@ -72,7 +82,6 @@ class BaseContext : public ContextInterface {
void set_pc(uint32_t new_pc) override { pc = new_pc; }
uint32_t get_next_pc() const override { return next_pc; }
void set_next_pc(uint32_t new_next_pc) override { next_pc = new_next_pc; }
void set_nested_returndata(std::vector<FF> return_data) override { nested_returndata = std::move(return_data); }
bool halted() const override { return has_halted; }
void halt() override { has_halted = true; }

Expand All @@ -81,31 +90,40 @@ class BaseContext : public ContextInterface {
// Environment.
const AztecAddress& get_address() const override { return address; }
const AztecAddress& get_msg_sender() const override { return msg_sender; }
std::span<const FF> get_calldata() const override { return calldata; }
bool get_is_static() const override { return is_static; }

// Event Emitting
void emit_context_snapshot() override
ContextInterface& get_child_context() override { return *child_context; }
void set_child_context(std::unique_ptr<ContextInterface> child_ctx) override
{
ctx_stack_events.emit({ .id = context_id,
.next_pc = next_pc,
.msg_sender = msg_sender,
.contract_addr = address,
.is_static = is_static });
};
child_context = std::move(child_ctx);
}

ContextEvent get_current_context() override
MemoryAddress get_last_rd_offset() const override { return last_child_rd_offset; }
void set_last_rd_offset(MemoryAddress rd_offset) override { last_child_rd_offset = rd_offset; }

MemoryAddress get_last_rd_size() const override { return last_child_rd_size; }
void set_last_rd_size(MemoryAddress rd_size) override { last_child_rd_size = rd_size; }

bool get_last_success() const override { return last_child_success; }
void set_last_success(bool success) override { last_child_success = success; }

// Input / Output
std::vector<FF> get_returndata(uint32_t rd_offset, uint32_t rd_size) override
{
return {
.id = context_id, .pc = pc, .msg_sender = msg_sender, .contract_addr = address, .is_static = is_static
};
MemoryInterface& child_memory = get_child_context().get_memory();
auto get_returndata_size = child_memory.get(last_child_rd_size);
uint32_t returndata_size = static_cast<uint32_t>(get_returndata_size.value);
[[maybe_unused]] uint32_t write_size = std::min(rd_offset + rd_size, returndata_size);
std::vector<FF>
retrieved_returndata = {}; // child_memory.set_slice(get_last_rd_offset() + rd_offset, write_size)
retrieved_returndata.resize(rd_size);
return retrieved_returndata;
};

private:
// Environment.
AztecAddress address;
AztecAddress msg_sender;
std::vector<FF> calldata;
bool is_static;

uint32_t context_id;
Expand All @@ -114,12 +132,14 @@ class BaseContext : public ContextInterface {
uint32_t pc = 0;
uint32_t next_pc = 0;
bool has_halted = false;
std::vector<FF> nested_returndata;
std::unique_ptr<BytecodeManagerInterface> bytecode;
std::unique_ptr<MemoryInterface> memory;

// Emiiters
EventEmitterInterface<ContextStackEvent>& ctx_stack_events;
// Output
std::unique_ptr<ContextInterface> child_context = nullptr;
MemoryAddress last_child_rd_offset = 0;
MemoryAddress last_child_rd_size = 0;
bool last_child_success = false;
};

// TODO(ilyas): flesh these out in the cpp file, these are just temporary
Expand All @@ -128,20 +148,47 @@ class EnqueuedCallContext : public BaseContext {
EnqueuedCallContext(uint32_t context_id,
AztecAddress address,
AztecAddress msg_sender,
std::span<const FF> calldata,
bool is_static,
std::unique_ptr<BytecodeManagerInterface> bytecode,
std::unique_ptr<MemoryInterface> memory,
EventEmitterInterface<ContextStackEvent>& ctx_stack_events)
: BaseContext(context_id,
address,
msg_sender,
calldata,
is_static,
std::move(bytecode),
std::move(memory),
ctx_stack_events)
std::span<const FF> calldata)
: BaseContext(context_id, address, msg_sender, is_static, std::move(bytecode), std::move(memory))
, calldata(calldata.begin(), calldata.end())
{}

// Event Emitting
ContextEvent get_current_context() override
{
return { .id = get_context_id(),
.pc = get_pc(),
.msg_sender = get_msg_sender(),
.contract_addr = get_address(),
.is_static = get_is_static(),
.parent_cd_addr = 0,
.parent_cd_size_addr = 0,
.last_child_rd_addr = get_last_rd_offset(),
.last_child_rd_size_addr = get_last_rd_size(),
.last_child_success = get_last_success() };
};

// Input / Output
std::vector<FF> get_calldata(uint32_t cd_offset, uint32_t cd_size) const override
{
// TODO(ilyas): Do we assert to assert cd_size < calldata.size(), otherwise it could trigger a massive write of
// zeroes. OTOH: this should be caught by an OUT_OF_GAS exception
std::vector<FF> padded_calldata(cd_size, 0); // Vector of size cd_size filled with zeroes;

// We first take a slice of the data, the most we can slice is the actual size of the data
size_t slice_size = std::min(static_cast<size_t>(cd_offset + cd_size), calldata.size());

for (size_t i = cd_offset; i < slice_size; i++) {
padded_calldata[i] = calldata[i];
}
return padded_calldata;
};

private:
std::vector<FF> calldata;
};

// Parameters for a nested call need to be changed
Expand All @@ -150,20 +197,52 @@ class NestedContext : public BaseContext {
NestedContext(uint32_t context_id,
AztecAddress address,
AztecAddress msg_sender,
std::span<const FF> calldata,
bool is_static,
std::unique_ptr<BytecodeManagerInterface> bytecode,
std::unique_ptr<MemoryInterface> memory,
EventEmitterInterface<ContextStackEvent>& ctx_stack_events)
: BaseContext(context_id,
address,
msg_sender,
calldata,
is_static,
std::move(bytecode),
std::move(memory),
ctx_stack_events)
ContextInterface& parent_context,
MemoryAddress cd_offset_address, /* This is a direct mem address */
MemoryAddress cd_size_address /* This is a direct mem address */
)
: BaseContext(context_id, address, msg_sender, is_static, std::move(bytecode), std::move(memory))
, parent_cd_offset(cd_offset_address)
, parent_cd_size(cd_size_address)
, parent_context(parent_context)
{}

// Event Emitting
ContextEvent get_current_context() override
{
return { .id = get_context_id(),
.pc = get_pc(),
.msg_sender = get_msg_sender(),
.contract_addr = get_address(),
.is_static = get_is_static(),
.parent_cd_addr = parent_cd_offset,
.parent_cd_size_addr = parent_cd_size };
};

// Input / Output
std::vector<FF> get_calldata(uint32_t cd_offset, uint32_t cd_size) const override
{
ValueRefAndTag get_calldata_size = parent_context.get_memory().get(parent_cd_size);
// TODO(ilyas): error if tag != U32
auto calldata_size = static_cast<uint32_t>(get_calldata_size.value);
uint32_t read_size = std::min(cd_offset + cd_size, calldata_size);

auto retrieved_calldata = parent_context.get_memory().get_slice(parent_cd_offset + cd_offset, read_size).first;

// Pad the calldata
retrieved_calldata.resize(cd_size, 0);
return retrieved_calldata;
};

private:
// These are direct addresses to look up into the parent context during calldata copying
MemoryAddress parent_cd_offset;
MemoryAddress parent_cd_size;

ContextInterface& parent_context;
};

} // namespace bb::avm2::simulation
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,15 @@ struct ContextEvent {
AztecAddress contract_addr;
bool is_static;

// Calldata info
// uint32_t cd_addr;
// uint32_t cd_size_addr;

// Returndata info
// uint32_t rd_addr;
// uint32_t rd_size_addr;
// Calldata info from parent context
uint32_t parent_cd_addr;
uint32_t parent_cd_size_addr;

// Returndata info from child context
uint32_t last_child_rd_addr;
uint32_t last_child_rd_size_addr;
// Success
// bool nested_ctx_success;
bool last_child_success;

// Gas
// uint32_t l2_gas_used;
Expand All @@ -47,9 +46,9 @@ struct ContextStackEvent {
AztecAddress contract_addr;
bool is_static;

// Calldata info
// uint32_t cd_addr;
// uint32_t cd_size_addr;
// Calldata info from parent context
uint32_t parent_cd_addr;
uint32_t parent_cd_size_addr;

// Gas
// uint32_t l2_gas_used;
Expand Down
Loading
Loading