Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,6 @@ struct SLOAD_Instruction {
/// @brief GETENVVAR: M[result_offset] = getenvvar(type)
struct GETENVVAR_Instruction {
AddressRef result_address;
// msgpack cannot pack enum classes, so we pack that as a uint8_t
// 0 -> ADDRESS, 1 -> SENDER, 2 -> TRANSACTIONFEE, 3 -> CHAINID, 4 -> VERSION, 5 -> BLOCKNUMBER, 6 -> TIMESTAMP,
// 7 -> MINFEEPERDAGAS, 8 -> MINFEEPERL2GAS, 9 -> ISSTATICCALL, 10 -> L2GASLEFT, 11 -> DAGASLEFT
uint8_t type;
MSGPACK_FIELDS(result_address, type);
};
Expand Down Expand Up @@ -636,6 +633,15 @@ struct TORADIXBE_Instruction {
MSGPACK_FIELDS(value_address, radix_address, num_limbs_address, output_bits_address, dst_address, is_output_bits);
};

struct DEBUGLOG_Instruction {
ParamRef level_offset;
ParamRef message_offset;
ParamRef fields_offset;
ParamRef fields_size_offset;
uint16_t message_size;
MSGPACK_FIELDS(level_offset, message_offset, fields_offset, fields_size_offset, message_size);
};

using FuzzInstruction = std::variant<ADD_8_Instruction,
FDIV_8_Instruction,
SET_8_Instruction,
Expand Down Expand Up @@ -693,7 +699,8 @@ using FuzzInstruction = std::variant<ADD_8_Instruction,
POSEIDON2PERM_Instruction,
KECCAKF1600_Instruction,
SHA256COMPRESSION_Instruction,
TORADIXBE_Instruction>;
TORADIXBE_Instruction,
DEBUGLOG_Instruction>;

template <class... Ts> struct overloaded : Ts... {
using Ts::operator()...;
Expand Down Expand Up @@ -905,6 +912,10 @@ inline std::ostream& operator<<(std::ostream& os, const FuzzInstruction& instruc
<< arg.num_limbs_address << " " << arg.output_bits_address << " " << arg.dst_address << " "
<< arg.is_output_bits;
},
[&](DEBUGLOG_Instruction arg) {
os << "DEBUGLOG_Instruction " << arg.level_offset << " " << arg.message_offset << " "
<< arg.fields_offset << " " << arg.fields_size_offset << " " << arg.message_size;
},
[&](auto) { os << "Unknown instruction"; },
},
instruction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -993,19 +993,18 @@ void ProgramBlock::process_getenvvar_instruction(GETENVVAR_Instruction instructi
#ifdef DISABLE_GETENVVAR_INSTRUCTION
return;
#endif
auto instruction_type = static_cast<uint8_t>(instruction.type % 12);
auto result_address_operand = memory_manager.get_resolved_address_and_operand_16(instruction.result_address);
if (!result_address_operand.has_value()) {
return;
}
preprocess_memory_addresses(result_address_operand.value().first);
auto getenvvar_instruction = bb::avm2::testing::InstructionBuilder(bb::avm2::WireOpCode::GETENVVAR_16)
.operand(result_address_operand.value().second)
.operand(instruction_type)
.operand(instruction.type)
.build();
instructions.push_back(getenvvar_instruction);
// special case for timestamp, it returns a 64-bit value
if (instruction_type == 6) {
if (instruction.type == 6) {
memory_manager.set_memory_address(bb::avm2::MemoryTag::U64,
result_address_operand.value().first.absolute_address);
} else {
Expand Down Expand Up @@ -1511,6 +1510,34 @@ void ProgramBlock::process_toradixbe_instruction(TORADIXBE_Instruction instructi
memory_manager.set_memory_address(output_tag, dst_operand.value().first.absolute_address);
}

void ProgramBlock::process_debuglog_instruction(DEBUGLOG_Instruction instruction)
{
auto level_operand = memory_manager.get_resolved_address_and_operand_16(instruction.level_offset);
auto message_operand = memory_manager.get_resolved_address_and_operand_16(instruction.message_offset);
auto fields_operand = memory_manager.get_resolved_address_and_operand_16(instruction.fields_offset);
auto fields_size_operand = memory_manager.get_resolved_address_and_operand_16(instruction.fields_size_offset);
auto message_size = instruction.message_size;

if (!level_operand.has_value() || !message_operand.has_value() || !fields_operand.has_value() ||
!fields_size_operand.has_value()) {
return;
}

preprocess_memory_addresses(level_operand.value().first);
preprocess_memory_addresses(message_operand.value().first);
preprocess_memory_addresses(fields_operand.value().first);
preprocess_memory_addresses(fields_size_operand.value().first);

auto debuglog_instruction = bb::avm2::testing::InstructionBuilder(bb::avm2::WireOpCode::DEBUGLOG)
.operand(level_operand.value().second)
.operand(message_operand.value().second)
.operand(fields_operand.value().second)
.operand(fields_size_operand.value().second)
.operand(message_size)
.build();
instructions.push_back(debuglog_instruction);
}

void ProgramBlock::finalize_with_return(uint8_t return_size,
MemoryTagWrapper return_value_tag,
uint16_t return_value_offset_index)
Expand Down Expand Up @@ -1731,6 +1758,7 @@ void ProgramBlock::process_instruction(FuzzInstruction instruction)
return this->process_l1tol2msgexists_instruction(instruction);
},
[this](TORADIXBE_Instruction instruction) { return this->process_toradixbe_instruction(instruction); },
[this](DEBUGLOG_Instruction instruction) { return this->process_debuglog_instruction(instruction); },
[](auto) { throw std::runtime_error("Unknown instruction"); },
},
instruction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class ProgramBlock {
void process_sha256compression_instruction(SHA256COMPRESSION_Instruction instruction);
void process_l1tol2msgexists_instruction(L1TOL2MSGEXISTS_Instruction instruction);
void process_toradixbe_instruction(TORADIXBE_Instruction instruction);
void process_debuglog_instruction(DEBUGLOG_Instruction instruction);

public:
std::vector<ProgramBlock*> successors;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,10 @@ enum class InstructionGenerationOptions {
KECCAKF1600,
SHA256COMPRESSION,
TORADIXBE,
DEBUGLOG,
};

using InstructionGenerationConfig = WeightedSelectionConfig<InstructionGenerationOptions, 58>;
using InstructionGenerationConfig = WeightedSelectionConfig<InstructionGenerationOptions, 59>;

constexpr InstructionGenerationConfig BASIC_INSTRUCTION_GENERATION_CONFIGURATION = InstructionGenerationConfig({
{ InstructionGenerationOptions::ADD_8, 1 },
Expand Down Expand Up @@ -338,6 +339,7 @@ constexpr InstructionGenerationConfig BASIC_INSTRUCTION_GENERATION_CONFIGURATION
{ InstructionGenerationOptions::KECCAKF1600, 1 },
{ InstructionGenerationOptions::SHA256COMPRESSION, 1 },
{ InstructionGenerationOptions::TORADIXBE, 1 },
{ InstructionGenerationOptions::DEBUGLOG, 1 },
});

enum class SStoreMutationOptions { src_address, result_address, slot };
Expand Down Expand Up @@ -500,6 +502,17 @@ constexpr ToRadixBEMutationConfig BASIC_TORADIXBE_MUTATION_CONFIGURATION = ToRad
{ ToRadixBEMutationOptions::is_output_bits, 1 },
});

enum class DebugLogMutationOptions { level_offset, message_offset, fields_offset, fields_size_offset, message_size };
using DebugLogMutationConfig = WeightedSelectionConfig<DebugLogMutationOptions, 5>;

constexpr DebugLogMutationConfig BASIC_DEBUGLOG_MUTATION_CONFIGURATION = DebugLogMutationConfig({
{ DebugLogMutationOptions::level_offset, 1 },
{ DebugLogMutationOptions::message_offset, 1 },
{ DebugLogMutationOptions::fields_offset, 1 },
{ DebugLogMutationOptions::fields_size_offset, 1 },
{ DebugLogMutationOptions::message_size, 1 },
});

enum class ReturnOptionsMutationOptions { return_size, return_value_tag, return_value_offset_index };

using ReturnOptionsMutationConfig = WeightedSelectionConfig<ReturnOptionsMutationOptions, 3>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,19 @@ std::vector<FuzzInstruction> generate_getcontractinstance_instruction(std::mt199
return instructions;
}

uint8_t generate_envvar_type(std::mt19937_64& rng)
{
bool valid_type = std::uniform_int_distribution<int>(0, 9)(rng) != 0;

if (valid_type) {
// 0 -> ADDRESS, 1 -> SENDER, 2 -> TRANSACTIONFEE, 3 -> CHAINID, 4 -> VERSION, 5 -> BLOCKNUMBER, 6 -> TIMESTAMP,
// 7 -> MINFEEPERDAGAS, 8 -> MINFEEPERL2GAS, 9 -> ISSTATICCALL, 10 -> L2GASLEFT, 11 -> DAGASLEFT
return std::uniform_int_distribution<uint8_t>(0, 11)(rng);
} else {
return generate_random_uint8(rng);
}
}

namespace bb::avm2::fuzzer {
std::vector<FuzzInstruction> generate_instruction(std::mt19937_64& rng, const FuzzerContext& context)
{
Expand Down Expand Up @@ -671,7 +684,7 @@ std::vector<FuzzInstruction> generate_instruction(std::mt19937_64& rng, const Fu
return generate_sload_instruction(rng);
case InstructionGenerationOptions::GETENVVAR:
return { GETENVVAR_Instruction{ .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
.type = generate_random_uint8(rng) } };
.type = generate_envvar_type(rng) } };
case InstructionGenerationOptions::EMITNULLIFIER:
return { EMITNULLIFIER_Instruction{ .nullifier_address = generate_variable_ref(rng) } };
case InstructionGenerationOptions::NULLIFIEREXISTS:
Expand Down Expand Up @@ -724,6 +737,12 @@ std::vector<FuzzInstruction> generate_instruction(std::mt19937_64& rng, const Fu
return generate_sha256compression_instruction(rng);
case InstructionGenerationOptions::TORADIXBE:
return generate_toradixbe_instruction(rng);
case InstructionGenerationOptions::DEBUGLOG:
return { { DEBUGLOG_Instruction{ .level_offset = generate_variable_ref(rng),
.message_offset = generate_variable_ref(rng),
.fields_offset = generate_variable_ref(rng),
.fields_size_offset = generate_variable_ref(rng),
.message_size = generate_random_uint16(rng) } } };
}
}
/// Most of the tags will be equal to the default tag
Expand Down Expand Up @@ -1060,7 +1079,7 @@ void mutate_getenvvar_instruction(GETENVVAR_Instruction& instruction, std::mt199
mutate_address_ref(instruction.result_address, rng, MAX_16BIT_OPERAND);
break;
case GetEnvVarMutationOptions::type:
mutate_uint8_t(instruction.type, rng, BASIC_UINT8_T_MUTATION_CONFIGURATION);
instruction.type = generate_envvar_type(rng);
break;
}
}
Expand Down Expand Up @@ -1357,6 +1376,28 @@ void mutate_toradixbe_instruction(TORADIXBE_Instruction& instruction, std::mt199
}
}

void mutate_debuglog_instruction(DEBUGLOG_Instruction& instruction, std::mt19937_64& rng)
{
DebugLogMutationOptions option = BASIC_DEBUGLOG_MUTATION_CONFIGURATION.select(rng);
switch (option) {
case DebugLogMutationOptions::level_offset:
mutate_param_ref(instruction.level_offset, rng, MemoryTag::U32, MAX_16BIT_OPERAND);
break;
case DebugLogMutationOptions::message_offset:
mutate_param_ref(instruction.message_offset, rng, MemoryTag::U32, MAX_16BIT_OPERAND);
break;
case DebugLogMutationOptions::fields_offset:
mutate_param_ref(instruction.fields_offset, rng, MemoryTag::U32, MAX_16BIT_OPERAND);
break;
case DebugLogMutationOptions::fields_size_offset:
mutate_param_ref(instruction.fields_size_offset, rng, MemoryTag::U32, MAX_16BIT_OPERAND);
break;
case DebugLogMutationOptions::message_size:
mutate_uint16_t(instruction.message_size, rng, BASIC_UINT16_T_MUTATION_CONFIGURATION);
break;
}
}

void mutate_instruction(FuzzInstruction& instruction,
std::mt19937_64& rng,
[[maybe_unused]] const FuzzerContext& context)
Expand Down Expand Up @@ -1423,6 +1464,7 @@ void mutate_instruction(FuzzInstruction& instruction,
[&rng](KECCAKF1600_Instruction& instr) { mutate_keccakf1600_instruction(instr, rng); },
[&rng](SHA256COMPRESSION_Instruction& instr) { mutate_sha256compression_instruction(instr, rng); },
[&rng](TORADIXBE_Instruction& instr) { mutate_toradixbe_instruction(instr, rng); },
[&rng](DEBUGLOG_Instruction& instr) { mutate_debuglog_instruction(instr, rng); },
[](auto&) { throw std::runtime_error("Unknown instruction"); } },
instruction);
}
Expand Down
Loading