diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp index 26242da0bdd..a5d6a718246 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp @@ -152,7 +152,8 @@ TEST_F(AvmExecutionTests, basicAddReturn) "00FF"; // ret size offset 255 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); // 2 instructions ASSERT_THAT(instructions, SizeIs(5)); @@ -214,7 +215,8 @@ TEST_F(AvmExecutionTests, setAndSubOpcodes) "00FF"; // ret size offset 255 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(5)); @@ -295,7 +297,8 @@ TEST_F(AvmExecutionTests, powerWithMulOpcodes) bytecode_hex.append(ret_hex); auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(16)); @@ -394,7 +397,8 @@ TEST_F(AvmExecutionTests, simpleInternalCall) ; auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); EXPECT_THAT(instructions, SizeIs(7)); @@ -475,7 +479,8 @@ TEST_F(AvmExecutionTests, nestedInternalCalls) bytecode_f2 + bytecode_f1 + bytecode_g; auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(13)); @@ -555,7 +560,8 @@ TEST_F(AvmExecutionTests, jumpAndCalldatacopy) ; auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(8)); @@ -657,7 +663,8 @@ TEST_F(AvmExecutionTests, jumpiAndCalldatacopy) ; auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(9)); @@ -714,7 +721,8 @@ TEST_F(AvmExecutionTests, movOpcode) "00FF"; // ret size offset 255 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(4)); @@ -773,7 +781,8 @@ TEST_F(AvmExecutionTests, indMovOpcode) "00FF"; // ret size offset 255 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(6)); @@ -815,7 +824,8 @@ TEST_F(AvmExecutionTests, setAndCastOpcodes) "00FF"; // ret size offset 255 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(4)); @@ -884,7 +894,8 @@ TEST_F(AvmExecutionTests, toRadixBeOpcodeBytes) "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); // Assign a vector that we will mutate internally in gen_trace to store the return values; std::vector returndata; @@ -958,7 +969,8 @@ TEST_F(AvmExecutionTests, toRadixBeOpcodeBitsMode) "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); // Assign a vector that we will mutate internally in gen_trace to store the return values; std::vector returndata; @@ -1031,7 +1043,8 @@ TEST_F(AvmExecutionTests, sha256CompressionOpcode) "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); // Assign a vector that we will mutate internally in gen_trace to store the return values; std::vector calldata = std::vector(); @@ -1093,7 +1106,8 @@ TEST_F(AvmExecutionTests, poseidon2PermutationOpCode) "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); // Assign a vector that we will mutate internally in gen_trace to store the return values; std::vector returndata = std::vector(); @@ -1168,7 +1182,8 @@ TEST_F(AvmExecutionTests, keccakf1600OpCode) "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); // Assign a vector that we will mutate internally in gen_trace to store the return values; std::vector calldata = std::vector(); @@ -1241,7 +1256,8 @@ TEST_F(AvmExecutionTests, embeddedCurveAddOpCode) "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); // Assign a vector that we will mutate internally in gen_trace to store the return values; std::vector returndata; @@ -1336,7 +1352,8 @@ TEST_F(AvmExecutionTests, msmOpCode) "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); // Assign a vector that we will mutate internally in gen_trace to store the return values; std::vector returndata; @@ -1407,7 +1424,8 @@ TEST_F(AvmExecutionTests, getEnvOpcode) "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(13)); @@ -1623,7 +1641,8 @@ TEST_F(AvmExecutionTests, getEnvOpcode) // "0001"; // dst_offset // // auto bytecode = hex_to_bytes(bytecode_hex); -// auto instructions = Deserialization::parse_bytecode_statically(bytecode); +// auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); +// ASSERT_TRUE(is_ok(error)); // // // Public inputs for the circuit // std::vector calldata; @@ -1660,7 +1679,8 @@ TEST_F(AvmExecutionTests, l2GasLeft) "00FF"; // ret size offset 255 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(4)); @@ -1708,7 +1728,8 @@ TEST_F(AvmExecutionTests, daGasLeft) "00FF"; // ret size offset 255 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(4)); @@ -1747,7 +1768,8 @@ TEST_F(AvmExecutionTests, ExecutorThrowsWithTooMuchGasAllocated) public_inputs.gas_settings.gas_limits.l2_gas = MAX_L2_GAS_PER_ENQUEUED_CALL; auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ExecutionHints execution_hints; EXPECT_THROW_WITH_MESSAGE(gen_trace(bytecode, calldata, public_inputs, returndata, execution_hints), @@ -1767,7 +1789,8 @@ TEST_F(AvmExecutionTests, ExecutorThrowsWithTooMuchGasAllocated) // std::vector public_inputs = { 1 }; // // auto bytecode = hex_to_bytes(bytecode_hex); -// auto instructions = Deserialization::parse_bytecode_statically(bytecode); +// auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); +// ASSERT_TRUE(is_ok(error)); // // ExecutionHints execution_hints; // EXPECT_THROW_WITH_MESSAGE(gen_trace(bytecode, calldata, public_inputs, returndata, execution_hints), @@ -1814,7 +1837,8 @@ TEST_F(AvmExecutionTests, kernelOutputEmitOpcodes) "0000"; // ret size 0 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(8)); @@ -1943,7 +1967,8 @@ TEST_F(AvmExecutionTests, kernelOutputStorageLoadOpcodeSimple) "00FF"; // ret size offset 255 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(5)); @@ -2010,7 +2035,8 @@ TEST_F(AvmExecutionTests, kernelOutputStorageStoreOpcodeSimple) "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); std::vector returndata; @@ -2072,7 +2098,8 @@ TEST_F(AvmExecutionTests, kernelOutputStorageOpcodes) "00FF"; // ret size offset 255 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(6)); @@ -2159,7 +2186,8 @@ TEST_F(AvmExecutionTests, kernelOutputHashExistsOpcodes) "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(7)); @@ -2313,7 +2341,8 @@ TEST_F(AvmExecutionTests, opCallOpcodes) "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); std::vector returndata; @@ -2392,7 +2421,8 @@ TEST_F(AvmExecutionTests, opGetContractInstanceOpcode) "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); ASSERT_THAT(instructions, SizeIs(6)); @@ -2427,7 +2457,9 @@ TEST_F(AvmExecutionTests, opGetContractInstanceOpcodeBadEnum) + to_hex(static_cast(ContractInstanceMember::MAX_MEMBER)); // member enum auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse_bytecode_statically(bytecode); + auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_TRUE(is_ok(error)); + ASSERT_THAT(instructions, SizeIs(2)); std::vector calldata; @@ -2457,7 +2489,8 @@ TEST_F(AvmExecutionTests, invalidOpcode) "0000"; // ret size 0 auto bytecode = hex_to_bytes(bytecode_hex); - EXPECT_THROW_WITH_MESSAGE(Deserialization::parse_bytecode_statically(bytecode), "Invalid opcode"); + const auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_EQ(error, AvmError::INVALID_OPCODE); } // Negative test detecting an incomplete instruction: instruction tag present but an operand is missing @@ -2474,7 +2507,8 @@ TEST_F(AvmExecutionTests, truncatedInstructionNoOperand) "FF"; // addr b and missing address for c = a-b auto bytecode = hex_to_bytes(bytecode_hex); - EXPECT_THROW_WITH_MESSAGE(Deserialization::parse_bytecode_statically(bytecode), "Operand is missing"); + const auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); + ASSERT_EQ(error, AvmError::PARSING_ERROR); } } // namespace tests_avm diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp index d3ad4039d15..ba6a60397ae 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp @@ -225,26 +225,38 @@ uint32_t Deserialization::get_pc_increment(OpCode opcode) * @throws runtime_error exception when the bytecode is invalid or pos is out-of-range * @return The instruction */ -Instruction Deserialization::parse(const std::vector& bytecode, size_t pos) +InstructionWithError Deserialization::parse(const std::vector& bytecode, size_t pos) { const auto length = bytecode.size(); if (pos >= length) { - throw_or_abort("Position is out of range. Position: " + std::to_string(pos) + - " Bytecode length: " + std::to_string(length)); + info("Position is out of range. Position: " + std::to_string(pos) + + " Bytecode length: " + std::to_string(length)); + return InstructionWithError{ + .instruction = Instruction(OpCode::LAST_OPCODE_SENTINEL, {}), + .error = AvmError::INVALID_PROGRAM_COUNTER, + }; } const uint8_t opcode_byte = bytecode.at(pos); if (!Bytecode::is_valid(opcode_byte)) { - throw_or_abort("Invalid opcode byte: " + to_hex(opcode_byte) + " at position: " + std::to_string(pos)); + info("Invalid opcode byte: " + to_hex(opcode_byte) + " at position: " + std::to_string(pos)); + return InstructionWithError{ + .instruction = Instruction(OpCode::LAST_OPCODE_SENTINEL, {}), + .error = AvmError::INVALID_OPCODE, + }; } pos++; const auto opcode = static_cast(opcode_byte); const auto iter = OPCODE_WIRE_FORMAT.find(opcode); if (iter == OPCODE_WIRE_FORMAT.end()) { - throw_or_abort("Opcode not found in OPCODE_WIRE_FORMAT: " + to_hex(opcode) + " name " + to_string(opcode)); + info("Opcode not found in OPCODE_WIRE_FORMAT: " + to_hex(opcode) + " name " + to_string(opcode)); + return InstructionWithError{ + .instruction = Instruction(OpCode::LAST_OPCODE_SENTINEL, {}), + .error = AvmError::INVALID_OPCODE, + }; } const std::vector& inst_format = iter->second; @@ -253,16 +265,24 @@ Instruction Deserialization::parse(const std::vector& bytecode, size_t // No underflow as above condition guarantees pos <= length (after pos++) const auto operand_size = OPERAND_TYPE_SIZE.at(op_type); if (length - pos < operand_size) { - throw_or_abort("Operand is missing at position " + std::to_string(pos) + " for opcode " + to_hex(opcode) + - " not enough bytes for operand type " + std::to_string(static_cast(op_type))); + info("Operand is missing at position " + std::to_string(pos) + " for opcode " + to_hex(opcode) + + " not enough bytes for operand type " + std::to_string(static_cast(op_type))); + return InstructionWithError{ + .instruction = Instruction(OpCode::LAST_OPCODE_SENTINEL, {}), + .error = AvmError::PARSING_ERROR, + }; } switch (op_type) { case OperandType::TAG: { uint8_t tag_u8 = bytecode.at(pos); if (tag_u8 > MAX_MEM_TAG) { - throw_or_abort("Instruction tag is invalid at position " + std::to_string(pos) + - " value: " + std::to_string(tag_u8) + " for opcode: " + to_string(opcode)); + info("Instruction tag is invalid at position " + std::to_string(pos) + + " value: " + std::to_string(tag_u8) + " for opcode: " + to_string(opcode)); + return InstructionWithError{ + .instruction = Instruction(OpCode::LAST_OPCODE_SENTINEL, {}), + .error = AvmError::INVALID_TAG_VALUE, + }; } operands.emplace_back(static_cast(tag_u8)); break; @@ -310,8 +330,7 @@ Instruction Deserialization::parse(const std::vector& bytecode, size_t pos += operand_size; } - auto instruction = Instruction(opcode, operands); - return instruction; + return InstructionWithError{ .instruction = Instruction(opcode, operands), .error = AvmError::NO_ERROR }; }; /** @@ -321,18 +340,28 @@ Instruction Deserialization::parse(const std::vector& bytecode, size_t * * @param bytecode The bytecode to be parsed as a vector of bytes/uint8_t * @throws runtime_error exception when the bytecode is invalid or pos is out-of-range - * @return The list of instructions as a vector + * @return The list of instructions as a vector with an error. */ -std::vector Deserialization::parse_bytecode_statically(const std::vector& bytecode) +ParsedBytecode Deserialization::parse_bytecode_statically(const std::vector& bytecode) { uint32_t pc = 0; std::vector instructions; while (pc < bytecode.size()) { - const auto instruction = parse(bytecode, pc); + const auto [instruction, error] = parse(bytecode, pc); + if (!is_ok(error)) { + return ParsedBytecode{ + .instructions = instructions, + .error = error, + }; + } instructions.emplace_back(instruction); pc += get_pc_increment(instruction.op_code); } - return instructions; + + return ParsedBytecode{ + .instructions = instructions, + .error = AvmError::NO_ERROR, + }; } } // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.hpp index eb58ddc803d..b71570f1e98 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.hpp @@ -14,12 +14,17 @@ namespace bb::avm_trace { // INDIRECT is parsed as UINT8 where the bits represent the operands that have indirect mem access. enum class OperandType : uint8_t { INDIRECT8, INDIRECT16, TAG, UINT8, UINT16, UINT32, UINT64, UINT128, FF }; +struct ParsedBytecode { + std::vector instructions; + AvmError error; +}; + class Deserialization { public: Deserialization() = default; - static Instruction parse(const std::vector& bytecode, size_t pos); - static std::vector parse_bytecode_statically(const std::vector& bytecode); + static InstructionWithError parse(const std::vector& bytecode, size_t pos); + static ParsedBytecode parse_bytecode_statically(const std::vector& bytecode); static uint32_t get_pc_increment(OpCode opcode); }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/errors.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/errors.hpp index 271b4fa56f3..e31d486e502 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/errors.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/errors.hpp @@ -6,7 +6,10 @@ namespace bb::avm_trace { enum class AvmError : uint32_t { NO_ERROR, - TAG_ERROR, + INVALID_PROGRAM_COUNTER, + INVALID_OPCODE, + INVALID_TAG_VALUE, + CHECK_TAG_ERROR, ADDR_RES_TAG_ERROR, REL_ADDR_OUT_OF_RANGE, DIV_ZERO, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp index 6d685793eb8..828b46a01e3 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp @@ -322,8 +322,14 @@ std::vector Execution::gen_trace(std::vector const& calldata, uint32_t pc = 0; uint32_t counter = 0; AvmError error = AvmError::NO_ERROR; - while (error == AvmError::NO_ERROR && (pc = trace_builder.get_pc()) < bytecode.size()) { - auto inst = Deserialization::parse(bytecode, pc); + while (is_ok(error) && (pc = trace_builder.get_pc()) < bytecode.size()) { + auto [inst, parse_error] = Deserialization::parse(bytecode, pc); + error = parse_error; + + if (!is_ok(error)) { + break; + } + debug("[PC:" + std::to_string(pc) + "] [IC:" + std::to_string(counter++) + "] " + inst.to_string() + " (gasLeft l2=" + std::to_string(trace_builder.get_l2_gas_left()) + ")"); @@ -818,7 +824,7 @@ std::vector Execution::gen_trace(std::vector const& calldata, } } - if (error != AvmError::NO_ERROR) { + if (!is_ok(error)) { info("AVM stopped due to exceptional halting condition. Error: ", to_name(error), " at PC: ", @@ -827,7 +833,6 @@ std::vector Execution::gen_trace(std::vector const& calldata, counter - 1); // Need adjustement as counter increment occurs in loop body } } - auto trace = trace_builder.finalize(); show_trace_info(trace); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp index 936daf0f0ed..e40a90129d5 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp @@ -105,8 +105,14 @@ std::string to_name(AvmError error) switch (error) { case AvmError::NO_ERROR: return "NO ERROR"; - case AvmError::TAG_ERROR: - return "TAG ERROR"; + case AvmError::INVALID_PROGRAM_COUNTER: + return "INVALID PROGRAM COUNTER"; + case AvmError::INVALID_OPCODE: + return "INVALIE OPCODE"; + case AvmError::INVALID_TAG_VALUE: + return "INVALID TAG VALUE"; + case AvmError::CHECK_TAG_ERROR: + return "TAG CHECKING ERROR"; case AvmError::ADDR_RES_TAG_ERROR: return "ADDRESS RESOLUTION TAG ERROR"; case AvmError::REL_ADDR_OUT_OF_RANGE: diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/instructions.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/instructions.hpp index 5c003ece969..252265ea582 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/instructions.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/instructions.hpp @@ -2,6 +2,7 @@ #include "barretenberg/numeric/uint128/uint128.hpp" #include "barretenberg/vm/avm/trace/common.hpp" +#include "barretenberg/vm/avm/trace/errors.hpp" #include "barretenberg/vm/avm/trace/opcode.hpp" #include @@ -50,4 +51,9 @@ class Instruction { } }; +struct InstructionWithError { + Instruction instruction; + AvmError error; +}; + } // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp index a88951779e2..ecd740ca9ba 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp @@ -353,7 +353,7 @@ AvmError AvmTraceBuilder::op_add( bool tag_match = read_a.tag_match && read_b.tag_match; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // a + b = c @@ -436,7 +436,7 @@ AvmError AvmTraceBuilder::op_sub( bool tag_match = read_a.tag_match && read_b.tag_match; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // a - b = c @@ -517,7 +517,7 @@ AvmError AvmTraceBuilder::op_mul( bool tag_match = read_a.tag_match && read_b.tag_match; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // a * b = c @@ -599,7 +599,7 @@ AvmError AvmTraceBuilder::op_div( // No need to add check_tag_integral(read_b.tag) as this follows from tag matching and that a has integral tag. if (is_ok(error) && !(tag_match && check_tag_integral(read_a.tag))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // a / b = c @@ -695,7 +695,7 @@ AvmError AvmTraceBuilder::op_fdiv( bool tag_match = read_a.tag_match && read_b.tag_match; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // a * b^(-1) = c @@ -789,7 +789,7 @@ AvmError AvmTraceBuilder::op_eq( bool tag_match = read_a.tag_match && read_b.tag_match; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } FF a = read_a.val; @@ -860,7 +860,7 @@ AvmError AvmTraceBuilder::op_lt( bool tag_match = read_a.tag_match && read_b.tag_match; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } FF a = tag_match ? read_a.val : FF(0); @@ -929,7 +929,7 @@ AvmError AvmTraceBuilder::op_lte( bool tag_match = read_a.tag_match && read_b.tag_match; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } FF a = tag_match ? read_a.val : FF(0); @@ -1003,7 +1003,7 @@ AvmError AvmTraceBuilder::op_and( bool tag_match = read_a.tag_match && read_b.tag_match; // No need to add check_tag_integral(read_b.tag) as this follows from tag matching and that a has integral tag. if (is_ok(error) && !(tag_match && check_tag_integral(read_a.tag))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } FF a = tag_match ? read_a.val : FF(0); @@ -1073,7 +1073,7 @@ AvmError AvmTraceBuilder::op_or( bool tag_match = read_a.tag_match && read_b.tag_match; // No need to add check_tag_integral(read_b.tag) as this follows from tag matching and that a has integral tag. if (is_ok(error) && !(tag_match && check_tag_integral(read_a.tag))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } FF a = tag_match ? read_a.val : FF(0); @@ -1143,7 +1143,7 @@ AvmError AvmTraceBuilder::op_xor( bool tag_match = read_a.tag_match && read_b.tag_match; // No need to add check_tag_integral(read_b.tag) as this follows from tag matching and that a has integral tag. if (is_ok(error) && !(tag_match && check_tag_integral(read_a.tag))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } FF a = tag_match ? read_a.val : FF(0); @@ -1217,7 +1217,7 @@ AvmError AvmTraceBuilder::op_not(uint8_t indirect, uint32_t a_offset, uint32_t d auto read_a = constrained_read_from_memory(call_ptr, clk, resolved_a, in_tag, in_tag, IntermRegister::IA); if (is_ok(error) && !check_tag_integral(read_a.tag)) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // ~a = c @@ -1284,7 +1284,7 @@ AvmError AvmTraceBuilder::op_shl( auto read_b = unconstrained_read_from_memory(resolved_b); if (is_ok(error) && !(check_tag_integral(read_a.tag) && check_tag(AvmMemoryTag::U8, resolved_b))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } FF a = is_ok(error) ? read_a.val : FF(0); @@ -1351,7 +1351,7 @@ AvmError AvmTraceBuilder::op_shr( // IntermRegister::IB); bool tag_match = read_a.tag_match && read_b.tag_match; auto read_b = unconstrained_read_from_memory(resolved_b); if (is_ok(error) && !(check_tag_integral(read_a.tag) && check_tag(AvmMemoryTag::U8, resolved_b))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } FF a = is_ok(error) ? read_a.val : FF(0); @@ -1773,7 +1773,7 @@ AvmError AvmTraceBuilder::op_calldata_copy(uint8_t indirect, bool tag_match = true; if (is_ok(error) && !(check_tag(AvmMemoryTag::U32, cd_offset_resolved) && check_tag(AvmMemoryTag::U32, copy_size_offset_resolved))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // TODO: constrain these. @@ -1823,7 +1823,7 @@ AvmError AvmTraceBuilder::op_returndata_size(uint8_t indirect, uint32_t dst_offs error = res_error; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } FF returndata_size = tag_match ? FF(nested_returndata.size()) : FF(0); @@ -1867,7 +1867,7 @@ AvmError AvmTraceBuilder::op_returndata_copy(uint8_t indirect, bool tag_match = true; if (is_ok(error) && !(check_tag(AvmMemoryTag::U32, rd_offset_resolved) && check_tag(AvmMemoryTag::U32, copy_size_offset_resolved))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // TODO: constrain these. @@ -2024,7 +2024,7 @@ AvmError AvmTraceBuilder::op_jumpi(uint8_t indirect, uint32_t cond_offset, uint3 error = res_error; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // Specific JUMPI loading of conditional value into intermediate register id without any tag constraint. @@ -2184,7 +2184,7 @@ AvmError AvmTraceBuilder::op_set( call_ptr, clk, resolved_dst_offset, val, AvmMemoryTag::FF, in_tag, IntermRegister::IC); if (is_ok(error) && !write_c.tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // Constrain gas cost @@ -2240,7 +2240,7 @@ AvmError AvmTraceBuilder::op_mov(uint8_t indirect, uint32_t src_offset, uint32_t error = res_error; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // Reading from memory and loading into ia without tag check. @@ -2305,7 +2305,7 @@ RowWithError AvmTraceBuilder::create_kernel_output_opcode(uint8_t indirect, uint call_ptr, clk, resolved_data, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); bool tag_match = read_a.tag_match; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } return RowWithError{ .row = @@ -2360,7 +2360,7 @@ RowWithError AvmTraceBuilder::create_kernel_output_opcode_with_metadata(uint8_t bool tag_match = read_a.tag_match && read_b.tag_match; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } return RowWithError{ .row = @@ -2507,7 +2507,7 @@ RowWithError AvmTraceBuilder::create_kernel_output_opcode_with_set_value_from_hi bool tag_match = write_a.tag_match && read_b.tag_match; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } return RowWithError{ .row = @@ -2544,9 +2544,12 @@ AvmError AvmTraceBuilder::op_sload(uint8_t indirect, uint32_t slot_offset, uint3 { auto clk = static_cast(main_trace.size()) + 1; + // We keep the first encountered error + AvmError error = AvmError::NO_ERROR; auto [resolved_addrs, res_error] = Addressing<2>::fromWire(indirect, call_ptr).resolve({ slot_offset, dest_offset }, mem_trace_builder); auto [resolved_slot, resolved_dest] = resolved_addrs; + error = res_error; auto read_slot = unconstrained_read_from_memory(resolved_slot); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/7960): Until this is moved @@ -2571,6 +2574,10 @@ AvmError AvmTraceBuilder::op_sload(uint8_t indirect, uint32_t slot_offset, uint3 auto write_a = constrained_write_to_memory( call_ptr, clk, resolved_dest, value, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); + if (is_ok(error) && !write_a.tag_match) { + error = AvmError::CHECK_TAG_ERROR; + } + // TODO(8945): remove fake rows auto row = Row{ .main_clk = clk, @@ -2600,7 +2607,7 @@ AvmError AvmTraceBuilder::op_sload(uint8_t indirect, uint32_t slot_offset, uint3 clk++; pc += Deserialization::get_pc_increment(OpCode::SLOAD); - return write_a.tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; + return error; } AvmError AvmTraceBuilder::op_sstore(uint8_t indirect, uint32_t src_offset, uint32_t slot_offset) @@ -2608,9 +2615,12 @@ AvmError AvmTraceBuilder::op_sstore(uint8_t indirect, uint32_t src_offset, uint3 // We keep the first encountered error auto clk = static_cast(main_trace.size()) + 1; + // We keep the first encountered error + AvmError error = AvmError::NO_ERROR; auto [resolved_addrs, res_error] = Addressing<2>::fromWire(indirect, call_ptr).resolve({ src_offset, slot_offset }, mem_trace_builder); auto [resolved_src, resolved_slot] = resolved_addrs; + error = res_error; auto read_slot = unconstrained_read_from_memory(resolved_slot); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/7960): Until this is moved @@ -2620,6 +2630,10 @@ AvmError AvmTraceBuilder::op_sstore(uint8_t indirect, uint32_t src_offset, uint3 auto read_a = constrained_read_from_memory( call_ptr, clk, resolved_src, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); + if (is_ok(error) && !read_a.tag_match) { + error = AvmError::CHECK_TAG_ERROR; + } + // Merkle check for SSTORE // (a) We compute the tree leaf slot of the low nullifier // (b) We check the membership of the low nullifier in the public data tree @@ -2666,7 +2680,7 @@ AvmError AvmTraceBuilder::op_sstore(uint8_t indirect, uint32_t src_offset, uint3 side_effect_counter++; clk++; pc += Deserialization::get_pc_increment(OpCode::SSTORE); - return read_a.tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; + return error; } AvmError AvmTraceBuilder::op_note_hash_exists(uint8_t indirect, @@ -2685,7 +2699,7 @@ AvmError AvmTraceBuilder::op_note_hash_exists(uint8_t indirect, error = res_error; if (is_ok(error) && !check_tag(AvmMemoryTag::FF, resolved_leaf_index)) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } Row row; @@ -2742,7 +2756,7 @@ AvmError AvmTraceBuilder::op_note_hash_exists(uint8_t indirect, row.main_sel_op_note_hash_exists = FF(1); if (is_ok(error) && row.main_tag_err != FF(0)) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } } else { row = Row{ @@ -2814,7 +2828,7 @@ AvmError AvmTraceBuilder::op_nullifier_exists(uint8_t indirect, error = res_error; if (is_ok(error) && !check_tag(AvmMemoryTag::FF, resolved_address)) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } Row row; @@ -2881,7 +2895,7 @@ AvmError AvmTraceBuilder::op_nullifier_exists(uint8_t indirect, // clk, resolved_nullifier_offset, resolved_address, resolved_dest); row.main_sel_op_nullifier_exists = FF(1); if (is_ok(error) && row.main_tag_err != FF(0)) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } } else { row = Row{ @@ -2977,7 +2991,7 @@ AvmError AvmTraceBuilder::op_l1_to_l2_msg_exists(uint8_t indirect, const auto leaf_index = unconstrained_read_from_memory(resolved_leaf_index); if (is_ok(error) && !check_tag(AvmMemoryTag::FF, resolved_leaf_index)) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } Row row; @@ -3035,7 +3049,7 @@ AvmError AvmTraceBuilder::op_l1_to_l2_msg_exists(uint8_t indirect, row.main_sel_op_l1_to_l2_msg_exists = FF(1); if (is_ok(error) && row.main_tag_err != FF(0)) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } } else { row = Row{ @@ -3094,7 +3108,7 @@ AvmError AvmTraceBuilder::op_get_contract_instance( call_ptr, clk, resolved_address_offset, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); bool tag_match = read_address.tag_match; if (is_ok(error) && !tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // Read the contract instance @@ -3196,7 +3210,7 @@ AvmError AvmTraceBuilder::op_emit_unencrypted_log(uint8_t indirect, uint32_t log if (is_ok(error) && !(check_tag(AvmMemoryTag::FF, resolved_log_offset) && check_tag(AvmMemoryTag::U32, resolved_log_size_offset))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } Row row; @@ -3217,7 +3231,7 @@ AvmError AvmTraceBuilder::op_emit_unencrypted_log(uint8_t indirect, uint32_t log direct_field_addr = AddressWithMode(static_cast(resolved_log_offset)); if (!check_tag_range(AvmMemoryTag::FF, direct_field_addr, log_size)) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; }; } @@ -3337,7 +3351,7 @@ AvmError AvmTraceBuilder::constrain_external_call(OpCode opcode, bool tag_match = read_gas_l2.tag_match && read_gas_da.tag_match && read_addr.tag_match && read_args.tag_match; if (is_ok(error) && !(tag_match && check_tag(AvmMemoryTag::U32, resolved_args_size_offset))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // TODO: constrain this @@ -3476,7 +3490,7 @@ ReturnDataError AvmTraceBuilder::op_return(uint8_t indirect, uint32_t ret_offset error = res_error; if (is_ok(error) && !(tag_match && check_tag(AvmMemoryTag::U32, resolved_ret_size_offset))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } const auto ret_size = static_cast(unconstrained_read_from_memory(resolved_ret_size_offset)); @@ -3550,7 +3564,7 @@ ReturnDataError AvmTraceBuilder::op_revert(uint8_t indirect, uint32_t ret_offset error = res_error; if (is_ok(error) && !(tag_match && check_tag(AvmMemoryTag::U32, ret_size_offset))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } const auto ret_size = @@ -3631,7 +3645,7 @@ AvmError AvmTraceBuilder::op_debug_log(uint8_t indirect, error = res_error; if (is_ok(error) && !check_tag(AvmMemoryTag::U32, resolved_fields_size_offset)) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } const uint32_t fields_size = @@ -3642,7 +3656,7 @@ AvmError AvmTraceBuilder::op_debug_log(uint8_t indirect, if (is_ok(error) && !(check_tag_range(AvmMemoryTag::U8, resolved_message_offset, message_size) && check_tag_range(AvmMemoryTag::FF, resolved_fields_offset, fields_size))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } main_trace.push_back(Row{ @@ -3726,7 +3740,7 @@ AvmError AvmTraceBuilder::op_poseidon2_permutation(uint8_t indirect, uint32_t in bool read_tag_valid = read_a.tag_match && read_b.tag_match && read_c.tag_match && read_d.tag_match; if (is_ok(error) && !read_tag_valid) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } if (is_ok(error)) { @@ -3776,7 +3790,7 @@ AvmError AvmTraceBuilder::op_poseidon2_permutation(uint8_t indirect, uint32_t in bool write_tag_valid = write_a.tag_match && write_b.tag_match && write_c.tag_match && write_d.tag_match; if (is_ok(error) && !write_tag_valid) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } } @@ -3836,7 +3850,7 @@ AvmError AvmTraceBuilder::op_sha256_compression(uint8_t indirect, if (is_ok(error) && !(check_tag_range(AvmMemoryTag::U32, resolved_state_offset, STATE_SIZE) && check_tag_range(AvmMemoryTag::U32, resolved_inputs_offset, INPUTS_SIZE))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // Constrain gas cost @@ -3935,7 +3949,7 @@ AvmError AvmTraceBuilder::op_keccakf1600(uint8_t indirect, uint32_t output_offse if (is_ok(error) && !(tag_match && check_tag_range(AvmMemoryTag::U64, resolved_input_offset, KECCAKF1600_INPUT_SIZE))) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // Constrain gas cost @@ -4020,7 +4034,7 @@ AvmError AvmTraceBuilder::op_ec_add(uint16_t indirect, check_tag(AvmMemoryTag::FF, resolved_rhs_y_offset) && check_tag(AvmMemoryTag::U1, resolved_rhs_is_inf_offset); if (is_ok(error) && !tags_valid) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } gas_trace_builder.constrain_gas(clk, OpCode::ECADD); @@ -4092,7 +4106,7 @@ AvmError AvmTraceBuilder::op_variable_msm(uint8_t indirect, error = res_error; if (is_ok(error) && !check_tag(AvmMemoryTag::U32, resolved_point_length_offset)) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } const FF points_length = is_ok(error) ? unconstrained_read_from_memory(resolved_point_length_offset) : 0; @@ -4116,7 +4130,7 @@ AvmError AvmTraceBuilder::op_variable_msm(uint8_t indirect, tags_valid = tags_valid && check_tag_range(AvmMemoryTag::FF, resolved_scalars_offset, scalar_read_length); if (is_ok(error) && !tags_valid) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // TODO(dbanks12): length needs to fit into u32 here or it will certainly @@ -4245,7 +4259,7 @@ AvmError AvmTraceBuilder::op_to_radix_be(uint8_t indirect, // call_ptr, clk, resolved_radix_offset, AvmMemoryTag::U32, AvmMemoryTag::U32, IntermRegister::IB); if (is_ok(error) && !check_tag(AvmMemoryTag::U32, resolved_radix_offset)) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } auto read_radix = unconstrained_read_from_memory(resolved_radix_offset); @@ -4253,7 +4267,7 @@ AvmError AvmTraceBuilder::op_to_radix_be(uint8_t indirect, FF input = read_src.val; if (is_ok(error) && !read_src.tag_match) { - error = AvmError::TAG_ERROR; + error = AvmError::CHECK_TAG_ERROR; } // TODO(8603): uncomment diff --git a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp index e887772f3af..d2fff918e9a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp @@ -38,14 +38,14 @@ #define PUBLIC_INNER_CALL_REQUEST_LENGTH 13 #define STATE_REFERENCE_LENGTH 8 #define TOTAL_FEES_LENGTH 1 -#define HEADER_LENGTH 24 -#define PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH 866 +#define HEADER_LENGTH 25 +#define PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH 867 #define AVM_ACCUMULATED_DATA_LENGTH 318 #define AVM_CIRCUIT_PUBLIC_INPUTS_LENGTH 1006 #define AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS 86 #define AVM_PROOF_LENGTH_IN_FIELDS 4166 #define AVM_PUBLIC_COLUMN_MAX_SIZE 1024 -#define AVM_PUBLIC_INPUTS_FLATTENED_SIZE 2914 +#define AVM_PUBLIC_INPUTS_FLATTENED_SIZE 2915 #define MEM_TAG_FF 0 #define MEM_TAG_U1 1 #define MEM_TAG_U8 2 diff --git a/barretenberg/cpp/src/barretenberg/world_state/world_state.cpp b/barretenberg/cpp/src/barretenberg/world_state/world_state.cpp index a61b0fe1914..3d81fbb58b5 100644 --- a/barretenberg/cpp/src/barretenberg/world_state/world_state.cpp +++ b/barretenberg/cpp/src/barretenberg/world_state/world_state.cpp @@ -639,12 +639,16 @@ WorldStateStatusFull WorldState::remove_historical_blocks(const index_t& toBlock WorldStateRevision revision{ .forkId = CANONICAL_FORK_ID, .blockNumber = 0, .includeUncommitted = false }; TreeMetaResponse archive_state = get_tree_info(revision, MerkleTreeId::ARCHIVE); if (toBlockNumber <= archive_state.meta.oldestHistoricBlock) { - throw std::runtime_error("Unable to remove historical block, block not found"); + throw std::runtime_error(format("Unable to remove historical blocks to block number ", + toBlockNumber, + ", blocks not found. Current oldest block: ", + archive_state.meta.oldestHistoricBlock)); } WorldStateStatusFull status; for (index_t blockNumber = archive_state.meta.oldestHistoricBlock; blockNumber < toBlockNumber; blockNumber++) { if (!remove_historical_block(blockNumber, status)) { - throw std::runtime_error("Failed to remove historical block"); + throw std::runtime_error(format( + "Failed to remove historical block ", blockNumber, " when removing blocks up to ", toBlockNumber)); } } populate_status_summary(status); @@ -828,6 +832,8 @@ bb::fr WorldState::compute_initial_archive(const StateReference& initial_state_r 0, 0, // total fees + 0, + // total mana used 0 }); } diff --git a/barretenberg/cpp/src/barretenberg/world_state/world_state.test.cpp b/barretenberg/cpp/src/barretenberg/world_state/world_state.test.cpp index 1967ec6c8b8..024ffbf4ac0 100644 --- a/barretenberg/cpp/src/barretenberg/world_state/world_state.test.cpp +++ b/barretenberg/cpp/src/barretenberg/world_state/world_state.test.cpp @@ -30,10 +30,12 @@ class WorldStateTest : public testing::Test { static std::string data_dir; uint64_t map_size = 10240; uint64_t thread_pool_size = 1; + + // TODO(): https://github.com/AztecProtocol/aztec-packages/issues/8084 std::unordered_map tree_heights{ - { MerkleTreeId::NULLIFIER_TREE, 20 }, { MerkleTreeId::NOTE_HASH_TREE, 32 }, - { MerkleTreeId::PUBLIC_DATA_TREE, 40 }, { MerkleTreeId::L1_TO_L2_MESSAGE_TREE, 16 }, - { MerkleTreeId::ARCHIVE, 16 }, + { MerkleTreeId::NULLIFIER_TREE, 40 }, { MerkleTreeId::NOTE_HASH_TREE, 40 }, + { MerkleTreeId::PUBLIC_DATA_TREE, 40 }, { MerkleTreeId::L1_TO_L2_MESSAGE_TREE, 39 }, + { MerkleTreeId::ARCHIVE, 29 }, }; std::unordered_map tree_prefill{ { MerkleTreeId::NULLIFIER_TREE, 128 }, @@ -141,14 +143,14 @@ TEST_F(WorldStateTest, GetInitialTreeInfoForAllTrees) auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NULLIFIER_TREE); EXPECT_EQ(info.meta.size, 128); EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::NULLIFIER_TREE)); - EXPECT_EQ(info.meta.root, bb::fr("0x19a8c197c12bb33da6314c4ef4f8f6fcb9e25250c085df8672adf67c8f1e3dbc")); + EXPECT_EQ(info.meta.root, bb::fr("0x0c499b373a1f0fe1b510a63563546d2d39e206895056a5af0143c5f30d639073")); } { auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::NOTE_HASH_TREE); EXPECT_EQ(info.meta.size, 0); EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::NOTE_HASH_TREE)); - EXPECT_EQ(info.meta.root, bb::fr("0x0b59baa35b9dc267744f0ccb4e3b0255c1fc512460d91130c6bc19fb2668568d")); + EXPECT_EQ(info.meta.root, bb::fr("0x1fd848aa69e1633722fe249a5b7f53b094f1c9cef9f5c694b073fd1cc5850dfb")); } { @@ -162,7 +164,7 @@ TEST_F(WorldStateTest, GetInitialTreeInfoForAllTrees) auto info = ws.get_tree_info(WorldStateRevision::committed(), MerkleTreeId::L1_TO_L2_MESSAGE_TREE); EXPECT_EQ(info.meta.size, 0); EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::L1_TO_L2_MESSAGE_TREE)); - EXPECT_EQ(info.meta.root, bb::fr("0x14f44d672eb357739e42463497f9fdac46623af863eea4d947ca00a497dcdeb3")); + EXPECT_EQ(info.meta.root, bb::fr("0x2e33ee2008411c04b99c24b313513d097a0d21a5040b6193d1f978b8226892d6")); } { @@ -170,7 +172,7 @@ TEST_F(WorldStateTest, GetInitialTreeInfoForAllTrees) EXPECT_EQ(info.meta.size, 1); EXPECT_EQ(info.meta.depth, tree_heights.at(MerkleTreeId::ARCHIVE)); // this is the expected archive tree root at genesis - EXPECT_EQ(info.meta.root, bb::fr("0x1200a06aae1368abe36530b585bd7a4d2ba4de5037b82076412691a187d7621e")); + EXPECT_EQ(info.meta.root, bb::fr("0x0237797d6a2c04d20d4fa06b74482bd970ccd51a43d9b05b57e9b91fa1ae1cae")); } } @@ -184,14 +186,14 @@ TEST_F(WorldStateTest, GetStateReference) auto snapshot = state_ref.at(MerkleTreeId::NULLIFIER_TREE); EXPECT_EQ( snapshot, - std::make_pair(bb::fr("0x19a8c197c12bb33da6314c4ef4f8f6fcb9e25250c085df8672adf67c8f1e3dbc"), 128UL)); + std::make_pair(bb::fr("0x0c499b373a1f0fe1b510a63563546d2d39e206895056a5af0143c5f30d639073"), 128UL)); } { auto snapshot = state_ref.at(MerkleTreeId::NOTE_HASH_TREE); EXPECT_EQ( snapshot, - std::make_pair(bb::fr("0x0b59baa35b9dc267744f0ccb4e3b0255c1fc512460d91130c6bc19fb2668568d"), 0UL)); + std::make_pair(bb::fr("0x1fd848aa69e1633722fe249a5b7f53b094f1c9cef9f5c694b073fd1cc5850dfb"), 0UL)); } { @@ -205,7 +207,7 @@ TEST_F(WorldStateTest, GetStateReference) auto snapshot = state_ref.at(MerkleTreeId::L1_TO_L2_MESSAGE_TREE); EXPECT_EQ( snapshot, - std::make_pair(bb::fr("0x14f44d672eb357739e42463497f9fdac46623af863eea4d947ca00a497dcdeb3"), 0UL)); + std::make_pair(bb::fr("0x2e33ee2008411c04b99c24b313513d097a0d21a5040b6193d1f978b8226892d6"), 0UL)); } } @@ -217,14 +219,14 @@ TEST_F(WorldStateTest, GetStateReference) auto snapshot = state_ref.at(MerkleTreeId::NULLIFIER_TREE); EXPECT_EQ( snapshot, - std::make_pair(bb::fr("0x19a8c197c12bb33da6314c4ef4f8f6fcb9e25250c085df8672adf67c8f1e3dbc"), 128UL)); + std::make_pair(bb::fr("0x0c499b373a1f0fe1b510a63563546d2d39e206895056a5af0143c5f30d639073"), 128UL)); } { auto snapshot = state_ref.at(MerkleTreeId::NOTE_HASH_TREE); EXPECT_EQ( snapshot, - std::make_pair(bb::fr("0x12dbc0ae893e0aa914df8ed20837148c89d78fbef9471ede1d39416d9660c169"), 1UL)); + std::make_pair(bb::fr("0x0f031292dfc64353244dfc38871cbeac74ddbd03df4a0856c411bb1ddfb494f0"), 1UL)); } { @@ -238,7 +240,7 @@ TEST_F(WorldStateTest, GetStateReference) auto snapshot = state_ref.at(MerkleTreeId::L1_TO_L2_MESSAGE_TREE); EXPECT_EQ( snapshot, - std::make_pair(bb::fr("0x14f44d672eb357739e42463497f9fdac46623af863eea4d947ca00a497dcdeb3"), 0UL)); + std::make_pair(bb::fr("0x2e33ee2008411c04b99c24b313513d097a0d21a5040b6193d1f978b8226892d6"), 0UL)); } } } @@ -497,13 +499,13 @@ TEST_F(WorldStateTest, SyncExternalBlockFromEmpty) WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point); StateReference block_state_ref = { { MerkleTreeId::NULLIFIER_TREE, - { fr("0x0342578609a7358092788d0eed7d1ee0ec8e0c596c0b1e85ba980ddd5cc79d04"), 129 } }, + { fr("0x187a19972150cd1e76d8201d720da7682fcf4d93ec6a3c7b0d84bbefde5bd927"), 129 } }, { MerkleTreeId::NOTE_HASH_TREE, - { fr("0x15dad063953d8d216c1db77739d6fb27e1b73a5beef748a1208898b3428781eb"), 1 } }, + { fr("0x2467e5f90736b4ea977e7d21cfb3714181e16b7d6cd867768b59e2ea90fa3eaf"), 1 } }, { MerkleTreeId::PUBLIC_DATA_TREE, { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } }, { MerkleTreeId::L1_TO_L2_MESSAGE_TREE, - { fr("0x20ea8ca97f96508aaed2d6cdc4198a41c77c640bfa8785a51bb905b9a672ba0b"), 1 } }, + { fr("0x24ffd0fab86555ab2e86cffc706d4cfb4b8c405c3966af805de954504ffc27ac"), 1 } }, }; WorldStateStatusFull status = ws.sync_block( @@ -529,13 +531,13 @@ TEST_F(WorldStateTest, SyncBlockFromDirtyState) WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point); StateReference block_state_ref = { { MerkleTreeId::NULLIFIER_TREE, - { fr("0x0342578609a7358092788d0eed7d1ee0ec8e0c596c0b1e85ba980ddd5cc79d04"), 129 } }, + { fr("0x187a19972150cd1e76d8201d720da7682fcf4d93ec6a3c7b0d84bbefde5bd927"), 129 } }, { MerkleTreeId::NOTE_HASH_TREE, - { fr("0x15dad063953d8d216c1db77739d6fb27e1b73a5beef748a1208898b3428781eb"), 1 } }, + { fr("0x2467e5f90736b4ea977e7d21cfb3714181e16b7d6cd867768b59e2ea90fa3eaf"), 1 } }, { MerkleTreeId::PUBLIC_DATA_TREE, { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } }, { MerkleTreeId::L1_TO_L2_MESSAGE_TREE, - { fr("0x20ea8ca97f96508aaed2d6cdc4198a41c77c640bfa8785a51bb905b9a672ba0b"), 1 } }, + { fr("0x24ffd0fab86555ab2e86cffc706d4cfb4b8c405c3966af805de954504ffc27ac"), 1 } }, }; ws.append_leaves(MerkleTreeId::NOTE_HASH_TREE, { fr(142) }); @@ -572,13 +574,13 @@ TEST_F(WorldStateTest, SyncCurrentBlock) bb::fr block_hash(1); StateReference block_state_ref = { { MerkleTreeId::NULLIFIER_TREE, - { fr("0x0342578609a7358092788d0eed7d1ee0ec8e0c596c0b1e85ba980ddd5cc79d04"), 129 } }, + { fr("0x187a19972150cd1e76d8201d720da7682fcf4d93ec6a3c7b0d84bbefde5bd927"), 129 } }, { MerkleTreeId::NOTE_HASH_TREE, - { fr("0x15dad063953d8d216c1db77739d6fb27e1b73a5beef748a1208898b3428781eb"), 1 } }, + { fr("0x2467e5f90736b4ea977e7d21cfb3714181e16b7d6cd867768b59e2ea90fa3eaf"), 1 } }, { MerkleTreeId::PUBLIC_DATA_TREE, { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } }, { MerkleTreeId::L1_TO_L2_MESSAGE_TREE, - { fr("0x20ea8ca97f96508aaed2d6cdc4198a41c77c640bfa8785a51bb905b9a672ba0b"), 1 } }, + { fr("0x24ffd0fab86555ab2e86cffc706d4cfb4b8c405c3966af805de954504ffc27ac"), 1 } }, }; ws.append_leaves(MerkleTreeId::NOTE_HASH_TREE, { 42 }); @@ -610,13 +612,13 @@ TEST_F(WorldStateTest, RejectSyncBlockWithBadPublicWriteBatches) WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point); StateReference block_state_ref = { { MerkleTreeId::NULLIFIER_TREE, - { fr("0x0342578609a7358092788d0eed7d1ee0ec8e0c596c0b1e85ba980ddd5cc79d04"), 129 } }, + { fr("0x187a19972150cd1e76d8201d720da7682fcf4d93ec6a3c7b0d84bbefde5bd927"), 129 } }, { MerkleTreeId::NOTE_HASH_TREE, - { fr("0x15dad063953d8d216c1db77739d6fb27e1b73a5beef748a1208898b3428781eb"), 1 } }, + { fr("0x2467e5f90736b4ea977e7d21cfb3714181e16b7d6cd867768b59e2ea90fa3eaf"), 1 } }, { MerkleTreeId::PUBLIC_DATA_TREE, { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } }, { MerkleTreeId::L1_TO_L2_MESSAGE_TREE, - { fr("0x20ea8ca97f96508aaed2d6cdc4198a41c77c640bfa8785a51bb905b9a672ba0b"), 1 } }, + { fr("0x24ffd0fab86555ab2e86cffc706d4cfb4b8c405c3966af805de954504ffc27ac"), 1 } }, }; auto sync = [&]() { @@ -637,13 +639,13 @@ TEST_F(WorldStateTest, RejectSyncBlockWithInvalidStateRef) WorldState ws(thread_pool_size, data_dir, map_size, tree_heights, tree_prefill, initial_header_generator_point); StateReference block_state_ref = { { MerkleTreeId::NULLIFIER_TREE, - { fr("0x0342578609a7358092788d0eed7d1ee0ec8e0c596c0b1e85ba980ddd5cc79d04"), 129 } }, + { fr("0x187a19972150cd1e76d8201d720da7682fcf4d93ec6a3c7b0d84bbefde5bd927"), 129 } }, { MerkleTreeId::NOTE_HASH_TREE, - { fr("0x15dad063953d8d216c1db77739d6fb27e1b73a5beef748a1208898b3428781eb"), 1 } }, + { fr("0x2467e5f90736b4ea977e7d21cfb3714181e16b7d6cd867768b59e2ea90fa3eaf"), 1 } }, { MerkleTreeId::PUBLIC_DATA_TREE, { fr("0x0278dcf9ff541da255ee722aecfad849b66af0d42c2924d949b5a509f2e1aec9"), 129 } }, { MerkleTreeId::L1_TO_L2_MESSAGE_TREE, - { fr("0x20ea8ca97f96508aaed2d6cdc4198a41c77c640bfa8785a51bb905b9a672ba0b"), 1 } }, + { fr("0x24ffd0fab86555ab2e86cffc706d4cfb4b8c405c3966af805de954504ffc27ac"), 1 } }, }; auto sync = [&]() { diff --git a/docs/docs/protocol-specs/gas-and-fees/specifying-gas-fee-info.md b/docs/docs/protocol-specs/gas-and-fees/specifying-gas-fee-info.md index 4701fd06fa5..274afac824f 100644 --- a/docs/docs/protocol-specs/gas-and-fees/specifying-gas-fee-info.md +++ b/docs/docs/protocol-specs/gas-and-fees/specifying-gas-fee-info.md @@ -78,6 +78,7 @@ classDiagram class Header { +GlobalVariables globalVariables +Fr totalFees + +Fr totalManaUsed } class GlobalVariables { @@ -100,6 +101,8 @@ The `feePerGas` is presently held constant at `1` for both dimensions, but may b `totalFees` is the total fees collected in the block in FPA. +`totalManaUsed` is the total mana used in the block and used to update the base fee. + `coinbase` is the L1 address that receives the fees. ## Transaction Fee diff --git a/l1-contracts/src/core/Rollup.sol b/l1-contracts/src/core/Rollup.sol index 80ec25e9e18..4ab86edf4e0 100644 --- a/l1-contracts/src/core/Rollup.sol +++ b/l1-contracts/src/core/Rollup.sol @@ -10,7 +10,8 @@ import { FeeHeader, ManaBaseFeeComponents, BlockLog, - L1FeeData + L1FeeData, + SubmitEpochRootProofArgs } from "@aztec/core/interfaces/IRollup.sol"; import {IVerifier} from "@aztec/core/interfaces/IVerifier.sol"; import {IInbox} from "@aztec/core/interfaces/messagebridge/IInbox.sol"; @@ -51,6 +52,13 @@ struct Config { uint256 aztecEpochProofClaimWindowInL2Slots; } +struct SubmitEpochRootProofInterimValues { + uint256 previousBlockNumber; + uint256 endBlockNumber; + Epoch epochToProve; + Epoch startEpoch; +} + /** * @title Rollup * @author Aztec Labs @@ -64,6 +72,7 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup { using SafeERC20 for IERC20; using ProposeLib for ProposeArgs; using FeeMath for uint256; + using FeeMath for ManaBaseFeeComponents; struct L1GasOracleValues { L1FeeData pre; @@ -81,6 +90,10 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup { // for justification of CLAIM_DURATION_IN_L2_SLOTS. uint256 public constant PROOF_COMMITMENT_MIN_BOND_AMOUNT_IN_TST = 1000; + // A Cuauhxicalli [kʷaːʍʃiˈkalːi] ("eagle gourd bowl") is a ceremonial Aztec vessel or altar used to hold offerings, + // such as sacrificial hearts, during rituals performed within temples. + address public constant CUAUHXICALLI = address(bytes20("CUAUHXICALLI")); + address public constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); bool public immutable IS_FOUNDRY_TEST; @@ -154,7 +167,8 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup { excessMana: 0, feeAssetPriceNumerator: 0, manaUsed: 0, - provingCostPerManaNumerator: 0 + provingCostPerManaNumerator: 0, + congestionCost: 0 }), archive: bytes32(Constants.GENESIS_ARCHIVE_ROOT), blockHash: bytes32(0), // TODO(palla/prover): The first block does not have hash zero @@ -263,37 +277,45 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup { * @dev We provide the `_archive` and `_blockHash` even if it could be read from storage itself because it allow for * better error messages. Without passing it, we would just have a proof verification failure. * - * @param _epochSize - The size of the epoch (to be promoted to a constant) - * @param _args - Array of public inputs to the proof (previousArchive, endArchive, previousBlockHash, endBlockHash, endTimestamp, outHash, proverId) - * @param _fees - Array of recipient-value pairs with fees to be distributed for the epoch - * @param _aggregationObject - The aggregation object for the proof - * @param _proof - The proof to verify + * @param _args - The arguments to submit the epoch root proof: + * _epochSize - The size of the epoch (to be promoted to a constant) + * _args - Array of public inputs to the proof (previousArchive, endArchive, previousBlockHash, endBlockHash, endTimestamp, outHash, proverId) + * _fees - Array of recipient-value pairs with fees to be distributed for the epoch + * _aggregationObject - The aggregation object for the proof + * _proof - The proof to verify */ - function submitEpochRootProof( - uint256 _epochSize, - bytes32[7] calldata _args, - bytes32[] calldata _fees, - bytes calldata _aggregationObject, - bytes calldata _proof - ) external override(IRollup) { + function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args) external override(IRollup) { if (canPrune()) { _prune(); } - uint256 previousBlockNumber = tips.provenBlockNumber; - uint256 endBlockNumber = previousBlockNumber + _epochSize; + SubmitEpochRootProofInterimValues memory interimValues; + + interimValues.previousBlockNumber = tips.provenBlockNumber; + interimValues.endBlockNumber = interimValues.previousBlockNumber + _args.epochSize; // @note The getEpochForBlock is expected to revert if the block is beyond pending. // If this changes you are gonna get so rekt you won't believe it. // I mean proving blocks that have been pruned rekt. - Epoch epochToProve = getEpochForBlock(endBlockNumber); + interimValues.epochToProve = getEpochForBlock(interimValues.endBlockNumber); + interimValues.startEpoch = getEpochForBlock(interimValues.previousBlockNumber + 1); + + // Ensure that the proof is not across epochs + require( + interimValues.startEpoch == interimValues.epochToProve, + Errors.Rollup__InvalidEpoch(interimValues.startEpoch, interimValues.epochToProve) + ); bytes32[] memory publicInputs = - getEpochProofPublicInputs(_epochSize, _args, _fees, _aggregationObject); + getEpochProofPublicInputs(_args.epochSize, _args.args, _args.fees, _args.aggregationObject); + + require(epochProofVerifier.verify(_args.proof, publicInputs), Errors.Rollup__InvalidProof()); - require(epochProofVerifier.verify(_proof, publicInputs), Errors.Rollup__InvalidProof()); + if (proofClaim.epochToProve == interimValues.epochToProve) { + PROOF_COMMITMENT_ESCROW.unstakeBond(proofClaim.bondProvider, proofClaim.bondAmount); + } - tips.provenBlockNumber = endBlockNumber; + tips.provenBlockNumber = interimValues.endBlockNumber; // @note Only if the rollup is the canonical will it be able to meaningfully claim fees // Otherwise, the fees are unbacked #7938. @@ -301,17 +323,25 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup { bool isRewardDistributorCanonical = address(this) == REWARD_DISTRIBUTOR.canonicalRollup(); uint256 totalProverReward = 0; + uint256 totalBurn = 0; if (isFeeCanonical || isRewardDistributorCanonical) { - for (uint256 i = 0; i < _epochSize; i++) { + for (uint256 i = 0; i < _args.epochSize; i++) { address coinbase = address(uint160(uint256(publicInputs[9 + i * 2]))); uint256 reward = 0; uint256 toProver = 0; + uint256 burn = 0; if (isFeeCanonical) { uint256 fees = uint256(publicInputs[10 + i * 2]); if (fees > 0) { - reward += fees; + // This is insanely expensive, and will be fixed as part of the general storage cost reduction. + // See #9826. + FeeHeader storage feeHeader = + blocks[interimValues.previousBlockNumber + 1 + i].feeHeader; + burn += feeHeader.congestionCost * feeHeader.manaUsed; + + reward += (fees - burn); FEE_JUICE_PORTAL.distributeFees(address(this), fees); } } @@ -335,6 +365,7 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup { } totalProverReward += toProver; + totalBurn += burn; } if (totalProverReward > 0) { @@ -343,13 +374,13 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup { proofClaim.bondProvider == address(0) ? msg.sender : proofClaim.bondProvider; ASSET.safeTransfer(proofRewardRecipient, totalProverReward); } - } - if (proofClaim.epochToProve == epochToProve) { - PROOF_COMMITMENT_ESCROW.unstakeBond(proofClaim.bondProvider, proofClaim.bondAmount); + if (totalBurn > 0) { + ASSET.safeTransfer(CUAUHXICALLI, totalBurn); + } } - emit L2ProofVerified(endBlockNumber, _args[6]); + emit L2ProofVerified(interimValues.endBlockNumber, _args.args[6]); } function status(uint256 _myHeaderBlockNumber) @@ -520,13 +551,13 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup { // Decode and validate header HeaderLib.Header memory header = HeaderLib.decode(_args.header); - bytes32 digest = _args.digest(); setupEpoch(); - uint256 manaBaseFee = getManaBaseFee(true); + ManaBaseFeeComponents memory components = getManaBaseFeeComponents(true); + uint256 manaBaseFee = FeeMath.summedBaseFee(components); _validateHeader({ _header: header, _signatures: _signatures, - _digest: digest, + _digest: _args.digest(), _currentTime: Timestamp.wrap(block.timestamp), _manaBaseFee: manaBaseFee, _txEffectsHash: txsEffectsHash, @@ -553,17 +584,20 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup { manaUsed: header.totalManaUsed, provingCostPerManaNumerator: parentFeeHeader.provingCostPerManaNumerator.clampedAdd( _args.oracleInput.provingCostModifier - ) + ), + congestionCost: components.congestionCost }) }); } // @note The block number here will always be >=1 as the genesis block is at 0 - bytes32 inHash = INBOX.consume(blockNumber); - require( - header.contentCommitment.inHash == inHash, - Errors.Rollup__InvalidInHash(inHash, header.contentCommitment.inHash) - ); + { + bytes32 inHash = INBOX.consume(blockNumber); + require( + header.contentCommitment.inHash == inHash, + Errors.Rollup__InvalidInHash(inHash, header.contentCommitment.inHash) + ); + } // TODO(#7218): Revert to fixed height tree for outbox, currently just providing min as interim // Min size = smallest path of the rollup tree + 1 @@ -644,9 +678,8 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup { * @return The mana base fee */ function getManaBaseFee(bool _inFeeAsset) public view override(IRollup) returns (uint256) { - ManaBaseFeeComponents memory components = manaBaseFeeComponents(_inFeeAsset); - return - components.dataCost + components.gasCost + components.provingCost + components.congestionCost; + ManaBaseFeeComponents memory components = getManaBaseFeeComponents(_inFeeAsset); + return components.summedBaseFee(); } /** @@ -661,7 +694,7 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup { * * @return The mana base fee components */ - function manaBaseFeeComponents(bool _inFeeAsset) + function getManaBaseFeeComponents(bool _inFeeAsset) public view override(ITestRollup) diff --git a/l1-contracts/src/core/interfaces/IRollup.sol b/l1-contracts/src/core/interfaces/IRollup.sol index 00981c23eaf..f04333c4a22 100644 --- a/l1-contracts/src/core/interfaces/IRollup.sol +++ b/l1-contracts/src/core/interfaces/IRollup.sol @@ -7,14 +7,24 @@ import {IOutbox} from "@aztec/core/interfaces/messagebridge/IOutbox.sol"; import {SignatureLib} from "@aztec/core/libraries/crypto/SignatureLib.sol"; import {DataStructures} from "@aztec/core/libraries/DataStructures.sol"; import {EpochProofQuoteLib} from "@aztec/core/libraries/EpochProofQuoteLib.sol"; +import {ManaBaseFeeComponents} from "@aztec/core/libraries/FeeMath.sol"; import {ProposeArgs} from "@aztec/core/libraries/ProposeLib.sol"; import {Timestamp, Slot, Epoch} from "@aztec/core/libraries/TimeMath.sol"; +struct SubmitEpochRootProofArgs { + uint256 epochSize; + bytes32[7] args; + bytes32[] fees; + bytes aggregationObject; + bytes proof; +} + struct FeeHeader { uint256 excessMana; uint256 feeAssetPriceNumerator; uint256 manaUsed; uint256 provingCostPerManaNumerator; + uint256 congestionCost; } struct BlockLog { @@ -29,20 +39,12 @@ struct L1FeeData { uint256 blobFee; } -struct ManaBaseFeeComponents { - uint256 congestionCost; - uint256 congestionMultiplier; - uint256 dataCost; - uint256 gasCost; - uint256 provingCost; -} - interface ITestRollup { function setEpochVerifier(address _verifier) external; function setVkTreeRoot(bytes32 _vkTreeRoot) external; function setProtocolContractTreeRoot(bytes32 _protocolContractTreeRoot) external; function setAssumeProvenThroughBlockNumber(uint256 _blockNumber) external; - function manaBaseFeeComponents(bool _inFeeAsset) + function getManaBaseFeeComponents(bool _inFeeAsset) external view returns (ManaBaseFeeComponents memory); @@ -78,13 +80,7 @@ interface IRollup { EpochProofQuoteLib.SignedEpochProofQuote calldata _quote ) external; - function submitEpochRootProof( - uint256 _epochSize, - bytes32[7] calldata _args, - bytes32[] calldata _fees, - bytes calldata _aggregationObject, - bytes calldata _proof - ) external; + function submitEpochRootProof(SubmitEpochRootProofArgs calldata _args) external; function canProposeAtTime(Timestamp _ts, bytes32 _archive) external view returns (Slot, uint256); diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index 362808524e1..67ae38a6201 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -96,7 +96,7 @@ library Constants { uint256 internal constant BLOB_SIZE_IN_BYTES = 126976; uint256 internal constant AZTEC_MAX_EPOCH_DURATION = 32; uint256 internal constant GENESIS_ARCHIVE_ROOT = - 19007378675971183768036762391356802220352606103602592933942074152320327194720; + 1002640778211850180189505934749257244705296832326768971348723156503780793518; uint256 internal constant FEE_JUICE_INITIAL_MINT = 20000000000000000000; uint256 internal constant FEE_FUNDING_FOR_TESTER_ACCOUNT = 100000000000000000000; uint256 internal constant PUBLIC_DISPATCH_SELECTOR = 3578010381; @@ -201,27 +201,28 @@ library Constants { uint256 internal constant TX_CONTEXT_LENGTH = 8; uint256 internal constant TX_REQUEST_LENGTH = 12; uint256 internal constant TOTAL_FEES_LENGTH = 1; - uint256 internal constant HEADER_LENGTH = 24; - uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 490; - uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 866; - uint256 internal constant PRIVATE_CONTEXT_INPUTS_LENGTH = 37; + uint256 internal constant TOTAL_MANA_USED_LENGTH = 1; + uint256 internal constant HEADER_LENGTH = 25; + uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 491; + uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 867; + uint256 internal constant PRIVATE_CONTEXT_INPUTS_LENGTH = 38; uint256 internal constant FEE_RECIPIENT_LENGTH = 2; uint256 internal constant AGGREGATION_OBJECT_LENGTH = 16; uint256 internal constant SCOPED_READ_REQUEST_LEN = 3; uint256 internal constant PUBLIC_DATA_READ_LENGTH = 3; uint256 internal constant PRIVATE_VALIDATION_REQUESTS_LENGTH = 772; uint256 internal constant COMBINED_ACCUMULATED_DATA_LENGTH = 550; - uint256 internal constant TX_CONSTANT_DATA_LENGTH = 34; - uint256 internal constant COMBINED_CONSTANT_DATA_LENGTH = 43; + uint256 internal constant TX_CONSTANT_DATA_LENGTH = 35; + uint256 internal constant COMBINED_CONSTANT_DATA_LENGTH = 44; uint256 internal constant PRIVATE_ACCUMULATED_DATA_LENGTH = 1036; - uint256 internal constant PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1849; + uint256 internal constant PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1850; uint256 internal constant PRIVATE_TO_PUBLIC_ACCUMULATED_DATA_LENGTH = 548; uint256 internal constant PRIVATE_TO_AVM_ACCUMULATED_DATA_LENGTH = 160; uint256 internal constant NUM_PRIVATE_TO_AVM_ACCUMULATED_DATA_ARRAYS = 3; - uint256 internal constant PRIVATE_TO_PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1140; - uint256 internal constant KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 605; + uint256 internal constant PRIVATE_TO_PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1141; + uint256 internal constant KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 606; uint256 internal constant CONSTANT_ROLLUP_DATA_LENGTH = 13; - uint256 internal constant BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH = 30; + uint256 internal constant BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH = 31; uint256 internal constant BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH = 90; uint256 internal constant ROOT_ROLLUP_PUBLIC_INPUTS_LENGTH = 76; uint256 internal constant GET_NOTES_ORACLE_RETURN_LENGTH = 674; diff --git a/l1-contracts/src/core/libraries/FeeMath.sol b/l1-contracts/src/core/libraries/FeeMath.sol index 6c63cc0e08f..215c2e4739a 100644 --- a/l1-contracts/src/core/libraries/FeeMath.sol +++ b/l1-contracts/src/core/libraries/FeeMath.sol @@ -13,6 +13,14 @@ struct OracleInput { int256 feeAssetPriceModifier; } +struct ManaBaseFeeComponents { + uint256 congestionCost; + uint256 congestionMultiplier; + uint256 dataCost; + uint256 gasCost; + uint256 provingCost; +} + library FeeMath { using Math for uint256; using SafeCast for int256; @@ -81,6 +89,11 @@ library FeeMath { return fakeExponential(MINIMUM_CONGESTION_MULTIPLIER, _numerator, CONGESTION_UPDATE_FRACTION); } + function summedBaseFee(ManaBaseFeeComponents memory _components) internal pure returns (uint256) { + return _components.dataCost + _components.gasCost + _components.provingCost + + _components.congestionCost; + } + /** * @notice An approximation of the exponential function: factor * e ** (numerator / denominator) * diff --git a/l1-contracts/src/core/libraries/HeaderLib.sol b/l1-contracts/src/core/libraries/HeaderLib.sol index 3df6acfdc7a..4cade7f20e6 100644 --- a/l1-contracts/src/core/libraries/HeaderLib.sol +++ b/l1-contracts/src/core/libraries/HeaderLib.sol @@ -11,24 +11,6 @@ import {Errors} from "@aztec/core/libraries/Errors.sol"; * @notice Decoding and validating an L2 block header * Concerned with readability and velocity of development not giving a damn about gas costs. * - * ,ggg, ,ggg,_,ggg, ,ggg, gg - * I8 I8 ,dPYb,dP""Y8dP""Y88P""Y8b dP""Y8a 88 8I ,dPYb, ,dPYb, - * I8 I8 IP'`YbYb, `88' `88' `88 Yb, `88 88 8I IP'`Yb IP'`Yb - * 88888888 88888888 I8 8I `" 88 88 88 `" 88 88 8I gg I8 8I I8 8I - * I8 I8 I8 8' 88 88 88 88 88 8I "" I8 8' I8 8bgg, - * I8 ,ggggg, I8 ,gggg,gg I8 dP 88 88 88 ,gggg,gg ,ggg,,ggg, ,gggg,gg 88 88 ,g, ,ggg, ,gggg,8I gg ,g, I8 dP ,gggg,gg I8 dP" "8 ,ggg, - * I8 dP" "Y8ggg I8 dP" "Y8I I8dP 88 88 88 dP" "Y8I ,8" "8P" "8, dP" "Y8I 88 88 ,8'8, i8" "8i dP" "Y8I 88 ,8'8, I8dP dP" "Y8I I8d8bggP" i8" "8i - * ,I8, i8' ,8I ,I8, i8' ,8I I8P 88 88 88 i8' ,8I I8 8I 8I i8' ,8I 88 88 ,8' Yb I8, ,8I i8' ,8I 88 ,8' Yb I8P i8' ,8I I8P' "Yb, I8, ,8I - * ,d88b, ,d8, ,d8' ,d88b, ,d8, ,d8b,,d8b,_ 88 88 Y8,,d8, ,d8b,,dP 8I Yb,,d8, ,d8b, Y8b,____,d88,,8'_ 8) `YbadP' ,d8, ,d8b, _,88,_,8'_ 8) ,d8b,_ ,d8, ,d8b,,d8 `Yb, `YbadP' - * 88P""Y88P"Y8888P" 88P""Y88P"Y8888P"`Y88P'"Y88 88 88 `Y8P"Y8888P"`Y88P' 8I `Y8P"Y8888P"`Y8 "Y888888P"Y8P' "YY8P8P888P"Y888P"Y8888P"`Y8 8P""Y8P' "YY8P8P PI8"8888P"Y8888P"`Y888P Y8888P"Y888 - * I8 `8, - * I8 `8, - * The `totalManaUsed` value is not yet part of the "real" header, but can be passed by extending - * the header struct with an additional 256-bit value. - * It will be better supported as part of #9716, right now there is a few hacks going on in here. - * - * - * * ------------------- * You can use https://gist.github.com/LHerskind/724a7e362c97e8ac2902c6b961d36830 to generate the below outline. * ------------------- @@ -124,7 +106,7 @@ library HeaderLib { uint256 totalManaUsed; } - uint256 private constant HEADER_LENGTH = 0x268; // Header byte length + uint256 private constant HEADER_LENGTH = 0x288; // Header byte length /** * @notice Decodes the header @@ -132,9 +114,8 @@ library HeaderLib { * @return The decoded header */ function decode(bytes calldata _header) internal pure returns (Header memory) { - bool hasTotalManaUsed = _header.length == HEADER_LENGTH + 0x20; require( - _header.length == HEADER_LENGTH || hasTotalManaUsed, + _header.length == HEADER_LENGTH, Errors.HeaderLib__InvalidHeaderSize(HEADER_LENGTH, _header.length) ); @@ -179,15 +160,14 @@ library HeaderLib { // Reading totalFees header.totalFees = uint256(bytes32(_header[0x0248:0x0268])); - if (hasTotalManaUsed) { - header.totalManaUsed = uint256(bytes32(_header[0x0268:0x0288])); - } + // Reading totalManaUsed + header.totalManaUsed = uint256(bytes32(_header[0x0268:0x0288])); return header; } function toFields(Header memory _header) internal pure returns (bytes32[] memory) { - bytes32[] memory fields = new bytes32[](24); + bytes32[] memory fields = new bytes32[](25); // must match the order in the Header.getFields fields[0] = _header.lastArchive.root; @@ -220,7 +200,7 @@ library HeaderLib { fields[21] = bytes32(_header.globalVariables.gasFees.feePerDaGas); fields[22] = bytes32(_header.globalVariables.gasFees.feePerL2Gas); fields[23] = bytes32(_header.totalFees); - + fields[24] = bytes32(_header.totalManaUsed); // fail if the header structure has changed without updating this function require( fields.length == Constants.HEADER_LENGTH, diff --git a/l1-contracts/src/core/libraries/crypto/SampleLib.sol b/l1-contracts/src/core/libraries/crypto/SampleLib.sol index bdca8f12628..a790dc6e56f 100644 --- a/l1-contracts/src/core/libraries/crypto/SampleLib.sol +++ b/l1-contracts/src/core/libraries/crypto/SampleLib.sol @@ -21,6 +21,62 @@ import {Errors} from "@aztec/core/libraries/Errors.sol"; * https://link.springer.com/content/pdf/10.1007%2F978-3-642-32009-5_1.pdf */ library SampleLib { + /** + * @notice Computing a committee the most direct way. + * This is horribly inefficient as we are throwing plenty of things away, but it is useful + * for testing and just showcasing the simplest case. + * + * @param _committeeSize - The size of the committee + * @param _indexCount - The total number of indices + * @param _seed - The seed to use for shuffling + * + * @return indices - The indices of the committee + */ + function computeCommitteeStupid(uint256 _committeeSize, uint256 _indexCount, uint256 _seed) + external + pure + returns (uint256[] memory) + { + uint256[] memory indices = new uint256[](_committeeSize); + + for (uint256 index = 0; index < _indexCount; index++) { + uint256 sampledIndex = computeShuffledIndex(index, _indexCount, _seed); + if (sampledIndex < _committeeSize) { + indices[sampledIndex] = index; + } + } + + return indices; + } + + /** + * @notice Computing a committee slightly more cleverly. + * Only computes for the committee size, and does not sample the full set. + * This is more efficient than the stupid way, but still not optimal. + * To be more clever, we can compute the `shuffeRounds` and `pivots` separately + * such that they get shared accross multiple indices. + * + * @param _committeeSize - The size of the committee + * @param _indexCount - The total number of indices + * @param _seed - The seed to use for shuffling + * + * @return indices - The indices of the committee + */ + function computeCommitteeClever(uint256 _committeeSize, uint256 _indexCount, uint256 _seed) + external + pure + returns (uint256[] memory) + { + uint256[] memory indices = new uint256[](_committeeSize); + + for (uint256 index = 0; index < _committeeSize; index++) { + uint256 originalIndex = computeOriginalIndex(index, _indexCount, _seed); + indices[index] = originalIndex; + } + + return indices; + } + /** * @notice Computes the shuffled index * @@ -78,62 +134,6 @@ library SampleLib { return index; } - /** - * @notice Computing a committee the most direct way. - * This is horribly inefficient as we are throwing plenty of things away, but it is useful - * for testing and just showcasing the simplest case. - * - * @param _committeeSize - The size of the committee - * @param _indexCount - The total number of indices - * @param _seed - The seed to use for shuffling - * - * @return indices - The indices of the committee - */ - function computeCommitteeStupid(uint256 _committeeSize, uint256 _indexCount, uint256 _seed) - internal - pure - returns (uint256[] memory) - { - uint256[] memory indices = new uint256[](_committeeSize); - - for (uint256 index = 0; index < _indexCount; index++) { - uint256 sampledIndex = computeShuffledIndex(index, _indexCount, _seed); - if (sampledIndex < _committeeSize) { - indices[sampledIndex] = index; - } - } - - return indices; - } - - /** - * @notice Computing a committee slightly more cleverly. - * Only computes for the committee size, and does not sample the full set. - * This is more efficient than the stupid way, but still not optimal. - * To be more clever, we can compute the `shuffeRounds` and `pivots` separately - * such that they get shared accross multiple indices. - * - * @param _committeeSize - The size of the committee - * @param _indexCount - The total number of indices - * @param _seed - The seed to use for shuffling - * - * @return indices - The indices of the committee - */ - function computeCommitteeClever(uint256 _committeeSize, uint256 _indexCount, uint256 _seed) - internal - pure - returns (uint256[] memory) - { - uint256[] memory indices = new uint256[](_committeeSize); - - for (uint256 index = 0; index < _committeeSize; index++) { - uint256 originalIndex = computeOriginalIndex(index, _indexCount, _seed); - indices[index] = originalIndex; - } - - return indices; - } - /** * @notice Compute the number of shuffle rounds * diff --git a/l1-contracts/test/Rollup.t.sol b/l1-contracts/test/Rollup.t.sol index 3c7883aa54d..3fc32d369d8 100644 --- a/l1-contracts/test/Rollup.t.sol +++ b/l1-contracts/test/Rollup.t.sol @@ -14,9 +14,8 @@ import {Registry} from "@aztec/governance/Registry.sol"; import {Inbox} from "@aztec/core/messagebridge/Inbox.sol"; import {Outbox} from "@aztec/core/messagebridge/Outbox.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; -import {BlockLog} from "@aztec/core/interfaces/IRollup.sol"; import {Rollup} from "./harnesses/Rollup.sol"; -import {IRollup} from "@aztec/core/interfaces/IRollup.sol"; +import {IRollup, BlockLog, SubmitEpochRootProofArgs} from "@aztec/core/interfaces/IRollup.sol"; import {IProofCommitmentEscrow} from "@aztec/core/interfaces/IProofCommitmentEscrow.sol"; import {FeeJuicePortal} from "@aztec/core/FeeJuicePortal.sol"; import {Leonidas} from "@aztec/core/Leonidas.sol"; @@ -726,9 +725,55 @@ contract RollupTest is DecoderBase, TimeFns { assertEq(rollup.getProvenBlockNumber(), 0 + toProve, "Invalid proven block number"); } + function testRevertSubmittingProofForBlocksAcrossEpochs() public setUpFor("mixed_block_1") { + _testBlock("mixed_block_1", false, 1); + _testBlock("mixed_block_2", false, TestConstants.AZTEC_EPOCH_DURATION + 1); + + DecoderBase.Data memory data = load("mixed_block_2").block; + + assertEq(rollup.getProvenBlockNumber(), 0, "Invalid initial proven block number"); + + BlockLog memory blockLog = rollup.getBlock(0); + + bytes32[7] memory args = [ + blockLog.archive, + data.archive, + blockLog.blockHash, + data.blockHash, + bytes32(0), + bytes32(0), + bytes32(0) + ]; + + bytes32[] memory fees = new bytes32[](Constants.AZTEC_MAX_EPOCH_DURATION * 2); + + fees[0] = bytes32(uint256(uint160(address(0)))); + fees[1] = bytes32(0); + + bytes memory aggregationObject = ""; + bytes memory proof = ""; + + vm.expectRevert( + abi.encodeWithSelector(Errors.Rollup__InvalidEpoch.selector, Epoch.wrap(0), Epoch.wrap(1)) + ); + + rollup.submitEpochRootProof( + SubmitEpochRootProofArgs({ + epochSize: 2, + args: args, + fees: fees, + aggregationObject: aggregationObject, + proof: proof + }) + ); + + assertEq(rollup.getPendingBlockNumber(), 2, "Invalid pending block number"); + assertEq(rollup.getProvenBlockNumber(), 0, "Invalid proven block number"); + } + function testProveEpochWithTwoMixedBlocks() public setUpFor("mixed_block_1") { - _testBlock("mixed_block_1", false); - _testBlock("mixed_block_2", false); + _testBlock("mixed_block_1", false, 1); + _testBlock("mixed_block_2", false, 2); DecoderBase.Data memory data = load("mixed_block_2").block; @@ -1125,7 +1170,15 @@ contract RollupTest is DecoderBase, TimeFns { bytes memory aggregationObject = ""; bytes memory proof = ""; - _rollup.submitEpochRootProof(_epochSize, args, fees, aggregationObject, proof); + _rollup.submitEpochRootProof( + SubmitEpochRootProofArgs({ + epochSize: _epochSize, + args: args, + fees: fees, + aggregationObject: aggregationObject, + proof: proof + }) + ); } function _quoteToSignedQuote(EpochProofQuoteLib.EpochProofQuote memory _quote) diff --git a/l1-contracts/test/decoders/Base.sol b/l1-contracts/test/decoders/Base.sol index d91a3e7f884..5ac503e888e 100644 --- a/l1-contracts/test/decoders/Base.sol +++ b/l1-contracts/test/decoders/Base.sol @@ -51,6 +51,8 @@ contract DecoderBase is TestBase { GlobalVariables globalVariables; AppendOnlyTreeSnapshot lastArchive; StateReference stateReference; + uint256 totalFees; + uint256 totalManaUsed; } struct GasFees { diff --git a/l1-contracts/test/fees/FeeRollup.t.sol b/l1-contracts/test/fees/FeeRollup.t.sol index 0f38f8e1a43..512d9fd2f8c 100644 --- a/l1-contracts/test/fees/FeeRollup.t.sol +++ b/l1-contracts/test/fees/FeeRollup.t.sol @@ -20,7 +20,8 @@ import { BlockLog, L1FeeData, FeeHeader, - ManaBaseFeeComponents + ManaBaseFeeComponents, + SubmitEpochRootProofArgs } from "@aztec/core/Rollup.sol"; import {IRollup} from "@aztec/core/interfaces/IRollup.sol"; import {IProofCommitmentEscrow} from "@aztec/core/interfaces/IProofCommitmentEscrow.sol"; @@ -37,6 +38,7 @@ import {IFeeJuicePortal} from "@aztec/core/interfaces/IFeeJuicePortal.sol"; import {IRewardDistributor} from "@aztec/governance/interfaces/IRewardDistributor.sol"; import {OracleInput} from "@aztec/core/libraries/FeeMath.sol"; import {ProposeArgs, OracleInput, ProposeLib} from "@aztec/core/libraries/ProposeLib.sol"; +import {IERC20} from "@oz/token/ERC20/IERC20.sol"; import { FeeHeader as FeeHeaderModel, @@ -52,17 +54,32 @@ import {MinimalFeeModel} from "./MinimalFeeModel.sol"; // solhint-disable comprehensive-interface contract FakeCanonical { - function canonicalRollup() external view returns (address) { - return msg.sender; + uint256 public constant BLOCK_REWARD = 50e18; + IERC20 public immutable UNDERLYING; + + address public canonicalRollup; + + constructor(IERC20 _asset) { + UNDERLYING = _asset; + } + + function setCanonicalRollup(address _rollup) external { + canonicalRollup = _rollup; + } + + function claim(address _recipient) external returns (uint256) { + TestERC20(address(UNDERLYING)).mint(_recipient, BLOCK_REWARD); + return BLOCK_REWARD; } - function UNDERLYING() external pure returns (address) { - return address(0); + function distributeFees(address _recipient, uint256 _amount) external { + TestERC20(address(UNDERLYING)).mint(_recipient, _amount); } } contract FeeRollupTest is FeeModelTestPoints, DecoderBase { using SlotLib for Slot; + using EpochLib for Epoch; // We need to build a block that we can submit. We will be using some values from // the empty blocks, but otherwise populate using the fee model test points. @@ -82,6 +99,10 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { Rollup internal rollup; + address internal coinbase = address(bytes20("MONEY MAKER")); + TestERC20 internal asset; + FakeCanonical internal fakeCanonical; + function setUp() public { // We deploy a the rollup and sets the time and all to @@ -89,7 +110,9 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { vm.fee(l1Metadata[0].base_fee); vm.blobBaseFee(l1Metadata[0].blob_fee); - FakeCanonical fakeCanonical = new FakeCanonical(); + asset = new TestERC20(); + + fakeCanonical = new FakeCanonical(IERC20(address(asset))); rollup = new Rollup( IFeeJuicePortal(address(fakeCanonical)), IRewardDistributor(address(fakeCanonical)), @@ -104,6 +127,13 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { aztecEpochProofClaimWindowInL2Slots: 16 }) ); + fakeCanonical.setCanonicalRollup(address(rollup)); + + vm.label(coinbase, "coinbase"); + vm.label(address(rollup), "ROLLUP"); + vm.label(address(fakeCanonical), "FAKE CANONICAL"); + vm.label(address(asset), "ASSET"); + vm.label(rollup.CUAUHXICALLI(), "CUAUHXICALLI"); } function _loadL1Metadata(uint256 index) internal { @@ -143,6 +173,11 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { assertEq(manaBaseFee, rollup.getManaBaseFee(true), "mana base fee mismatch"); + uint256 manaSpent = point.block_header.mana_spent; + + // Put coinbase onto the stack + address cb = coinbase; + // Updating the header with important information! assembly { let headerRef := add(header, 0x20) @@ -160,15 +195,13 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { mstore(add(headerRef, 0x0174), bn) mstore(add(headerRef, 0x0194), slotNumber) mstore(add(headerRef, 0x01b4), ts) - mstore(add(headerRef, 0x01d4), 0) - mstore(add(headerRef, 0x01e8), 0) - mstore(add(headerRef, 0x0208), 0) - mstore(add(headerRef, 0x0228), manaBaseFee) + mstore(add(headerRef, 0x01d4), cb) // coinbase + mstore(add(headerRef, 0x01e8), 0) // fee recipient + mstore(add(headerRef, 0x0208), 0) // fee per da gas + mstore(add(headerRef, 0x0228), manaBaseFee) // fee per l2 gas + mstore(add(headerRef, 0x0268), manaSpent) // total mana used } - // We extend the with 20 bytes of mana spent information. - header = bytes.concat(header, bytes32(point.block_header.mana_spent)); - return Block({ archive: archiveRoot, blockHash: blockHash, @@ -179,10 +212,9 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { }); } - function test_BigBrainTime() public { - rollup.setAssumeProvenThroughBlockNumber(10000); - + function test_FeeModelEquivalence() public { Slot nextSlot = Slot.wrap(1); + Epoch nextEpoch = Epoch.wrap(1); // Loop through all of the L1 metadata for (uint256 i = 0; i < l1Metadata.length; i++) { @@ -197,8 +229,8 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { L1FeeData memory fees = rollup.getCurrentL1Fees(); uint256 feeAssetPrice = rollup.getFeeAssetPrice(); - ManaBaseFeeComponents memory components = rollup.manaBaseFeeComponents(false); - ManaBaseFeeComponents memory componentsFeeAsset = rollup.manaBaseFeeComponents(true); + ManaBaseFeeComponents memory components = rollup.getManaBaseFeeComponents(false); + ManaBaseFeeComponents memory componentsFeeAsset = rollup.getManaBaseFeeComponents(true); BlockLog memory parentBlockLog = rollup.getBlock(nextSlot.unwrap() - 1); Block memory b = getBlock(); @@ -220,6 +252,11 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { BlockLog memory blockLog = rollup.getBlock(nextSlot.unwrap()); + assertEq( + componentsFeeAsset.congestionCost, + blockLog.feeHeader.congestionCost, + "congestion cost mismatch" + ); // Want to check the fee header to see if they are as we want them. assertEq(point.block_header.block_number, nextSlot, "invalid l2 block number"); @@ -242,6 +279,78 @@ contract FeeRollupTest is FeeModelTestPoints, DecoderBase { nextSlot = nextSlot + Slot.wrap(1); } + + // If we are entering a new epoch, we will post a proof + // Ensure that the fees are split correctly between sequencers and burns etc. + if (rollup.getCurrentEpoch() == nextEpoch) { + nextEpoch = nextEpoch + Epoch.wrap(1); + uint256 pendingBlockNumber = rollup.getPendingBlockNumber(); + uint256 start = rollup.getProvenBlockNumber() + 1; + uint256 epochSize = 0; + while ( + start + epochSize <= pendingBlockNumber + && rollup.getEpochForBlock(start) == rollup.getEpochForBlock(start + epochSize) + ) { + epochSize++; + } + + uint256 feeSum = 0; + uint256 burnSum = 0; + bytes32[] memory fees = new bytes32[](Constants.AZTEC_MAX_EPOCH_DURATION * 2); + + for (uint256 feeIndex = 0; feeIndex < epochSize; feeIndex++) { + TestPoint memory point = points[start + feeIndex - 1]; + + // We assume that everyone PERFECTLY pays their fees with 0 priority fees and no + // overpaying on teardown. + uint256 baseFee = point.outputs.mana_base_fee_components_in_fee_asset.data_cost + + point.outputs.mana_base_fee_components_in_fee_asset.gas_cost + + point.outputs.mana_base_fee_components_in_fee_asset.proving_cost + + point.outputs.mana_base_fee_components_in_fee_asset.congestion_cost; + + uint256 fee = rollup.getBlock(start + feeIndex).feeHeader.manaUsed * baseFee; + feeSum += fee; + burnSum += rollup.getBlock(start + feeIndex).feeHeader.manaUsed + * point.outputs.mana_base_fee_components_in_fee_asset.congestion_cost; + + fees[feeIndex * 2] = bytes32(uint256(uint160(coinbase))); + fees[feeIndex * 2 + 1] = bytes32(fee); + } + + bytes memory aggregationObject = ""; + bytes memory proof = ""; + + uint256 cuauhxicalliBalanceBefore = asset.balanceOf(rollup.CUAUHXICALLI()); + uint256 coinbaseBalanceBefore = asset.balanceOf(coinbase); + + bytes32[7] memory args = [ + rollup.getBlock(start).archive, + rollup.getBlock(start + epochSize - 1).archive, + rollup.getBlock(start).blockHash, + rollup.getBlock(start + epochSize - 1).blockHash, + bytes32(0), + bytes32(0), + bytes32(0) + ]; + rollup.submitEpochRootProof( + SubmitEpochRootProofArgs({ + epochSize: epochSize, + args: args, + fees: fees, + aggregationObject: aggregationObject, + proof: proof + }) + ); + + uint256 burned = asset.balanceOf(rollup.CUAUHXICALLI()) - cuauhxicalliBalanceBefore; + assertEq( + asset.balanceOf(coinbase) - coinbaseBalanceBefore + - fakeCanonical.BLOCK_REWARD() * epochSize + burned, + feeSum, + "Sum of fees does not match" + ); + assertEq(burnSum, burned, "Sum of burned does not match"); + } } } diff --git a/l1-contracts/test/fixtures/empty_block_1.json b/l1-contracts/test/fixtures/empty_block_1.json index 0070d3ebdd8..84692ccb0e3 100644 --- a/l1-contracts/test/fixtures/empty_block_1.json +++ b/l1-contracts/test/fixtures/empty_block_1.json @@ -8,8 +8,8 @@ "l2ToL1Messages": [] }, "block": { - "archive": "0x1f80d0f24457c066a8b752a2c424ee0c8bd61143db120fa0841d0f4233f7e21d", - "blockHash": "0x267f79fe7e757b20e924fac9f78264a0d1c8c4b481fea21d0bbe74650d87a1f1", + "archive": "0x14cc4063ccae0d809992631edee86e43cd48aa4465598e54e05f4c91fc7cf9dc", + "blockHash": "0x02baa47f911948eb68e332e631af8c30d801187c66b6d48f1432c7cb98fd755c", "body": "0x00000000", "txsEffectsHash": "0x002dcd61493c9a7f3ce4605573ee657e6ced4a3dd10bfb216f44a796b3d585c9", "decodedHeader": { @@ -23,18 +23,20 @@ "blockNumber": 1, "slotNumber": "0x0000000000000000000000000000000000000000000000000000000000000012", "chainId": 31337, - "timestamp": 1731434785, + "timestamp": 1732579818, "version": 1, - "coinbase": "0x4f6cd865d580ac0011a4776d8dc51db519c2318a", - "feeRecipient": "0x1ae8b5e1d9882013ea5271b1e71b307bc48c191549588587a227c8a118834864", + "coinbase": "0xbebcbac2f24abc01241a668cca41d0659589499e", + "feeRecipient": "0x1fb24139a0110fb00ebdcf0b6667bdd95c82ede876a1d34fb8cef074eae1db2c", "gasFees": { "feePerDaGas": 0, - "feePerL2Gas": 0 + "feePerL2Gas": 54153599320 } }, + "totalFees": "0x0000000000000000000000000000000000000000000000000000000000000000", + "totalManaUsed": "0x0000000000000000000000000000000000000000000000000000000000000000", "lastArchive": { "nextAvailableLeafIndex": 1, - "root": "0x2a05cb8aeefe9b9797f90650eae072f5ab7437807e62f9724ce1900467779860" + "root": "0x0237797d6a2c04d20d4fa06b74482bd970ccd51a43d9b05b57e9b91fa1ae1cae" }, "stateReference": { "l1ToL2MessageTree": { @@ -51,14 +53,14 @@ "root": "0x0c499b373a1f0fe1b510a63563546d2d39e206895056a5af0143c5f30d639073" }, "publicDataTree": { - "nextAvailableLeafIndex": 256, + "nextAvailableLeafIndex": 128, "root": "0x23c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9" } } } }, - "header": "0x2a05cb8aeefe9b9797f90650eae072f5ab7437807e62f9724ce1900467779860000000010000000000000000000000000000000000000000000000000000000000000002002dcd61493c9a7f3ce4605573ee657e6ced4a3dd10bfb216f44a796b3d585c900089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c00f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb2e33ee2008411c04b99c24b313513d097a0d21a5040b6193d1f978b8226892d6000000101fd848aa69e1633722fe249a5b7f53b094f1c9cef9f5c694b073fd1cc5850dfb000000800c499b373a1f0fe1b510a63563546d2d39e206895056a5af0143c5f30d6390730000010023c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9000001000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000673399214f6cd865d580ac0011a4776d8dc51db519c2318a1ae8b5e1d9882013ea5271b1e71b307bc48c191549588587a227c8a118834864000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "publicInputsHash": "0x00f45c9ec73df38136aa1fed90362a5df796817e37a36d02df4700f80bc356b2", + "header": "0x0237797d6a2c04d20d4fa06b74482bd970ccd51a43d9b05b57e9b91fa1ae1cae000000010000000000000000000000000000000000000000000000000000000000000002002dcd61493c9a7f3ce4605573ee657e6ced4a3dd10bfb216f44a796b3d585c900089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c00f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb2e33ee2008411c04b99c24b313513d097a0d21a5040b6193d1f978b8226892d6000000101fd848aa69e1633722fe249a5b7f53b094f1c9cef9f5c694b073fd1cc5850dfb000000800c499b373a1f0fe1b510a63563546d2d39e206895056a5af0143c5f30d6390730000010023c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9000000800000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000674511eabebcbac2f24abc01241a668cca41d0659589499e1fb24139a0110fb00ebdcf0b6667bdd95c82ede876a1d34fb8cef074eae1db2c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c9bce595800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "publicInputsHash": "0x00f5efb7d5e53918275f835f7103b62acc1d37c11bbf27e0482680f107fc01d4", "numTxs": 0 } } \ No newline at end of file diff --git a/l1-contracts/test/fixtures/empty_block_2.json b/l1-contracts/test/fixtures/empty_block_2.json index 447934f005b..1b2bd47c849 100644 --- a/l1-contracts/test/fixtures/empty_block_2.json +++ b/l1-contracts/test/fixtures/empty_block_2.json @@ -8,8 +8,8 @@ "l2ToL1Messages": [] }, "block": { - "archive": "0x1120ec22c3dd3dd6904b9520f086189726776a41c75c53f8f4cea4a53bc45844", - "blockHash": "0x2d48eea4aa6c13eea47df326e22cd76e74ecc24ee272d6b4207eb5f494f891d3", + "archive": "0x1ced42b04845f5bc2a98f47f54a9aac0e7cd55642cbba1da95401a8dd9b1e357", + "blockHash": "0x12caff598a6843ec10beac259597243dd5b069866f03bf67a8e4669e2a56335a", "body": "0x00000000", "txsEffectsHash": "0x002dcd61493c9a7f3ce4605573ee657e6ced4a3dd10bfb216f44a796b3d585c9", "decodedHeader": { @@ -23,18 +23,20 @@ "blockNumber": 2, "slotNumber": "0x0000000000000000000000000000000000000000000000000000000000000013", "chainId": 31337, - "timestamp": 1731434809, + "timestamp": 1732579842, "version": 1, - "coinbase": "0x4f6cd865d580ac0011a4776d8dc51db519c2318a", - "feeRecipient": "0x1ae8b5e1d9882013ea5271b1e71b307bc48c191549588587a227c8a118834864", + "coinbase": "0xbebcbac2f24abc01241a668cca41d0659589499e", + "feeRecipient": "0x1fb24139a0110fb00ebdcf0b6667bdd95c82ede876a1d34fb8cef074eae1db2c", "gasFees": { "feePerDaGas": 0, - "feePerL2Gas": 0 + "feePerL2Gas": 54153599320 } }, + "totalFees": "0x0000000000000000000000000000000000000000000000000000000000000000", + "totalManaUsed": "0x0000000000000000000000000000000000000000000000000000000000000000", "lastArchive": { "nextAvailableLeafIndex": 2, - "root": "0x1f80d0f24457c066a8b752a2c424ee0c8bd61143db120fa0841d0f4233f7e21d" + "root": "0x14cc4063ccae0d809992631edee86e43cd48aa4465598e54e05f4c91fc7cf9dc" }, "stateReference": { "l1ToL2MessageTree": { @@ -51,14 +53,14 @@ "root": "0x0c499b373a1f0fe1b510a63563546d2d39e206895056a5af0143c5f30d639073" }, "publicDataTree": { - "nextAvailableLeafIndex": 384, + "nextAvailableLeafIndex": 128, "root": "0x23c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9" } } } }, - "header": "0x1f80d0f24457c066a8b752a2c424ee0c8bd61143db120fa0841d0f4233f7e21d000000020000000000000000000000000000000000000000000000000000000000000002002dcd61493c9a7f3ce4605573ee657e6ced4a3dd10bfb216f44a796b3d585c900089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c00f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb2e33ee2008411c04b99c24b313513d097a0d21a5040b6193d1f978b8226892d6000000201fd848aa69e1633722fe249a5b7f53b094f1c9cef9f5c694b073fd1cc5850dfb000001000c499b373a1f0fe1b510a63563546d2d39e206895056a5af0143c5f30d6390730000018023c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9000001800000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000673399394f6cd865d580ac0011a4776d8dc51db519c2318a1ae8b5e1d9882013ea5271b1e71b307bc48c191549588587a227c8a118834864000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "publicInputsHash": "0x0050ad1c615efe79df6f8ed137584b719b7043725a87ff1b1e2a29f22f0827c8", + "header": "0x14cc4063ccae0d809992631edee86e43cd48aa4465598e54e05f4c91fc7cf9dc000000020000000000000000000000000000000000000000000000000000000000000002002dcd61493c9a7f3ce4605573ee657e6ced4a3dd10bfb216f44a796b3d585c900089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c00f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb2e33ee2008411c04b99c24b313513d097a0d21a5040b6193d1f978b8226892d6000000201fd848aa69e1633722fe249a5b7f53b094f1c9cef9f5c694b073fd1cc5850dfb000001000c499b373a1f0fe1b510a63563546d2d39e206895056a5af0143c5f30d6390730000018023c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9000000800000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000067451202bebcbac2f24abc01241a668cca41d0659589499e1fb24139a0110fb00ebdcf0b6667bdd95c82ede876a1d34fb8cef074eae1db2c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c9bce595800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "publicInputsHash": "0x004cab0bf8cace3c6a6b2506f12a17d5f1ccaf63db14d8f6e67b3fea6d34fc3d", "numTxs": 0 } } \ No newline at end of file diff --git a/l1-contracts/test/fixtures/mixed_block_1.json b/l1-contracts/test/fixtures/mixed_block_1.json index e3a5c4cceb9..65e4c926d83 100644 --- a/l1-contracts/test/fixtures/mixed_block_1.json +++ b/l1-contracts/test/fixtures/mixed_block_1.json @@ -58,8 +58,8 @@ ] }, "block": { - "archive": "0x13232b1c92fcfba5f94aee813d7e454764f93d6292215552b8c973ef42c8e396", - "blockHash": "0x024c7ee2217388b1e45747c7233b2f3993bfc88a8a944ee89a11d9c66c24907d", + "archive": "0x0dd5f1f4c97e09c3d85323d27343341b245c49c5e7032c43c8b7c70d8b79629a", + "blockHash": "0x1b22c2fdad7b5b96c8f0d57c83a52cad8b6f03f012d53be9e4987b92f978b29d", "body": "0x00000004000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000000000000000000000000000004100100000000000000000000000000000000000000000000000000000000000410020000000000000000000000000000000000000000000000000000000000041003000000000000000000000000000000000000000000000000000000000004100400000000000000000000000000000000000000000000000000000000000410050000000000000000000000000000000000000000000000000000000000041006000000000000000000000000000000000000000000000000000000000004100700000000000000000000000000000000000000000000000000000000000410080000000000000000000000000000000000000000000000000000000000041009000000000000000000000000000000000000000000000000000000000004100a000000000000000000000000000000000000000000000000000000000004100b000000000000000000000000000000000000000000000000000000000004100c000000000000000000000000000000000000000000000000000000000004100d000000000000000000000000000000000000000000000000000000000004100e000000000000000000000000000000000000000000000000000000000004100f0000000000000000000000000000000000000000000000000000000000041010000000000000000000000000000000000000000000000000000000000004101100000000000000000000000000000000000000000000000000000000000410120000000000000000000000000000000000000000000000000000000000041013000000000000000000000000000000000000000000000000000000000004101400000000000000000000000000000000000000000000000000000000000410150000000000000000000000000000000000000000000000000000000000041016000000000000000000000000000000000000000000000000000000000004101700000000000000000000000000000000000000000000000000000000000410180000000000000000000000000000000000000000000000000000000000041019000000000000000000000000000000000000000000000000000000000004101a000000000000000000000000000000000000000000000000000000000004101b000000000000000000000000000000000000000000000000000000000004101c000000000000000000000000000000000000000000000000000000000004101d000000000000000000000000000000000000000000000000000000000004101e000000000000000000000000000000000000000000000000000000000004101f0000000000000000000000000000000000000000000000000000000000041020000000000000000000000000000000000000000000000000000000000004102100000000000000000000000000000000000000000000000000000000000410220000000000000000000000000000000000000000000000000000000000041023000000000000000000000000000000000000000000000000000000000004102400000000000000000000000000000000000000000000000000000000000410250000000000000000000000000000000000000000000000000000000000041026000000000000000000000000000000000000000000000000000000000004102700000000000000000000000000000000000000000000000000000000000410280000000000000000000000000000000000000000000000000000000000041029000000000000000000000000000000000000000000000000000000000004102a000000000000000000000000000000000000000000000000000000000004102b000000000000000000000000000000000000000000000000000000000004102c000000000000000000000000000000000000000000000000000000000004102d000000000000000000000000000000000000000000000000000000000004102e000000000000000000000000000000000000000000000000000000000004102f0000000000000000000000000000000000000000000000000000000000041030000000000000000000000000000000000000000000000000000000000004103100000000000000000000000000000000000000000000000000000000000410320000000000000000000000000000000000000000000000000000000000041033000000000000000000000000000000000000000000000000000000000004103400000000000000000000000000000000000000000000000000000000000410350000000000000000000000000000000000000000000000000000000000041036000000000000000000000000000000000000000000000000000000000004103700000000000000000000000000000000000000000000000000000000000410380000000000000000000000000000000000000000000000000000000000041039000000000000000000000000000000000000000000000000000000000004103a000000000000000000000000000000000000000000000000000000000004103b000000000000000000000000000000000000000000000000000000000004103c000000000000000000000000000000000000000000000000000000000004103d000000000000000000000000000000000000000000000000000000000004103e000000000000000000000000000000000000000000000000000000000004103f3f0000000000000000000000000000000000000000000000000000000000041100000000000000000000000000000000000000000000000000000000000004110100000000000000000000000000000000000000000000000000000000000411020000000000000000000000000000000000000000000000000000000000041103000000000000000000000000000000000000000000000000000000000004110400000000000000000000000000000000000000000000000000000000000411050000000000000000000000000000000000000000000000000000000000041106000000000000000000000000000000000000000000000000000000000004110700000000000000000000000000000000000000000000000000000000000411080000000000000000000000000000000000000000000000000000000000041109000000000000000000000000000000000000000000000000000000000004110a000000000000000000000000000000000000000000000000000000000004110b000000000000000000000000000000000000000000000000000000000004110c000000000000000000000000000000000000000000000000000000000004110d000000000000000000000000000000000000000000000000000000000004110e000000000000000000000000000000000000000000000000000000000004110f0000000000000000000000000000000000000000000000000000000000041110000000000000000000000000000000000000000000000000000000000004111100000000000000000000000000000000000000000000000000000000000411120000000000000000000000000000000000000000000000000000000000041113000000000000000000000000000000000000000000000000000000000004111400000000000000000000000000000000000000000000000000000000000411150000000000000000000000000000000000000000000000000000000000041116000000000000000000000000000000000000000000000000000000000004111700000000000000000000000000000000000000000000000000000000000411180000000000000000000000000000000000000000000000000000000000041119000000000000000000000000000000000000000000000000000000000004111a000000000000000000000000000000000000000000000000000000000004111b000000000000000000000000000000000000000000000000000000000004111c000000000000000000000000000000000000000000000000000000000004111d000000000000000000000000000000000000000000000000000000000004111e000000000000000000000000000000000000000000000000000000000004111f0000000000000000000000000000000000000000000000000000000000041120000000000000000000000000000000000000000000000000000000000004112100000000000000000000000000000000000000000000000000000000000411220000000000000000000000000000000000000000000000000000000000041123000000000000000000000000000000000000000000000000000000000004112400000000000000000000000000000000000000000000000000000000000411250000000000000000000000000000000000000000000000000000000000041126000000000000000000000000000000000000000000000000000000000004112700000000000000000000000000000000000000000000000000000000000411280000000000000000000000000000000000000000000000000000000000041129000000000000000000000000000000000000000000000000000000000004112a000000000000000000000000000000000000000000000000000000000004112b000000000000000000000000000000000000000000000000000000000004112c000000000000000000000000000000000000000000000000000000000004112d000000000000000000000000000000000000000000000000000000000004112e000000000000000000000000000000000000000000000000000000000004112f0000000000000000000000000000000000000000000000000000000000041130000000000000000000000000000000000000000000000000000000000004113100000000000000000000000000000000000000000000000000000000000411320000000000000000000000000000000000000000000000000000000000041133000000000000000000000000000000000000000000000000000000000004113400000000000000000000000000000000000000000000000000000000000411350000000000000000000000000000000000000000000000000000000000041136000000000000000000000000000000000000000000000000000000000004113700000000000000000000000000000000000000000000000000000000000411380000000000000000000000000000000000000000000000000000000000041139000000000000000000000000000000000000000000000000000000000004113a000000000000000000000000000000000000000000000000000000000004113b000000000000000000000000000000000000000000000000000000000004113c000000000000000000000000000000000000000000000000000000000004113d000000000000000000000000000000000000000000000000000000000004113e080097a6ec570e9b8e257647c9c74c5ad3edc57ca5ef6ae44d80b3c30d1d99b9b300ce48ec41d1edde0066fab553a456ae2f380d14fa8f956af1fb0217513a598900619ff12eaf97f63aa2a2311de3b6571a7b880a5247cb33b6a74787bf3f9bd5007854a2fad4e1801c6404394bf3d37ab08c135ea38a1974242e39a21273685f000f55796e72957a819e68a22e8602d73c3ba3718a5a4bd92b80b0aa444b182a00788b6e9874fb040ee679a7fae257190099a605229b948334e54a57739535d4004f1658ee3c1a91627e5d72f5a731f0796299df82ab41e72c88eee0c82fa85e003ee802add96628c693ed71afa9908138ba5a6fbf0a5f29a9c74e4e42aba6713f0000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000004200a0000000000000000000000000000000000000000000000000000000000042001000000000000000000000000000000000000000000000000000000000004200b0000000000000000000000000000000000000000000000000000000000042002000000000000000000000000000000000000000000000000000000000004200c0000000000000000000000000000000000000000000000000000000000042003000000000000000000000000000000000000000000000000000000000004200d0000000000000000000000000000000000000000000000000000000000042004000000000000000000000000000000000000000000000000000000000004200e0000000000000000000000000000000000000000000000000000000000042005000000000000000000000000000000000000000000000000000000000004200f00000000000000000000000000000000000000000000000000000000000420060000000000000000000000000000000000000000000000000000000000042010000000000000000000000000000000000000000000000000000000000004200700000000000000000000000000000000000000000000000000000000000420110000000000000000000000000000000000000000000000000000000000042008000000000000000000000000000000000000000000000000000000000004201200000000000000000000000000000000000000000000000000000000000420090000000000000000000000000000000000000000000000000000000000042013000000000000000000000000000000000000000000000000000000000004200a0000000000000000000000000000000000000000000000000000000000042014000000000000000000000000000000000000000000000000000000000004200b0000000000000000000000000000000000000000000000000000000000042015000000000000000000000000000000000000000000000000000000000004200c0000000000000000000000000000000000000000000000000000000000042016000000000000000000000000000000000000000000000000000000000004200d0000000000000000000000000000000000000000000000000000000000042017000000000000000000000000000000000000000000000000000000000004200e0000000000000000000000000000000000000000000000000000000000042018000000000000000000000000000000000000000000000000000000000004200f00000000000000000000000000000000000000000000000000000000000420190000000000000000000000000000000000000000000000000000000000042010000000000000000000000000000000000000000000000000000000000004201a0000000000000000000000000000000000000000000000000000000000042011000000000000000000000000000000000000000000000000000000000004201b0000000000000000000000000000000000000000000000000000000000042012000000000000000000000000000000000000000000000000000000000004201c0000000000000000000000000000000000000000000000000000000000042013000000000000000000000000000000000000000000000000000000000004201d0000000000000000000000000000000000000000000000000000000000042014000000000000000000000000000000000000000000000000000000000004201e0000000000000000000000000000000000000000000000000000000000042015000000000000000000000000000000000000000000000000000000000004201f00000000000000000000000000000000000000000000000000000000000420160000000000000000000000000000000000000000000000000000000000042020000000000000000000000000000000000000000000000000000000000004201700000000000000000000000000000000000000000000000000000000000420210000000000000000000000000000000000000000000000000000000000042018000000000000000000000000000000000000000000000000000000000004202200000000000000000000000000000000000000000000000000000000000420190000000000000000000000000000000000000000000000000000000000042023000000000000000000000000000000000000000000000000000000000004201a0000000000000000000000000000000000000000000000000000000000042024000000000000000000000000000000000000000000000000000000000004201b0000000000000000000000000000000000000000000000000000000000042025000000000000000000000000000000000000000000000000000000000004201c0000000000000000000000000000000000000000000000000000000000042026000000000000000000000000000000000000000000000000000000000004201d0000000000000000000000000000000000000000000000000000000000042027000000000000000000000000000000000000000000000000000000000004201e0000000000000000000000000000000000000000000000000000000000042028000000000000000000000000000000000000000000000000000000000004201f00000000000000000000000000000000000000000000000000000000000420290000000000000000000000000000000000000000000000000000000000042020000000000000000000000000000000000000000000000000000000000004202a0000000000000000000000000000000000000000000000000000000000042021000000000000000000000000000000000000000000000000000000000004202b0000000000000000000000000000000000000000000000000000000000042022000000000000000000000000000000000000000000000000000000000004202c0000000000000000000000000000000000000000000000000000000000042023000000000000000000000000000000000000000000000000000000000004202d0000000000000000000000000000000000000000000000000000000000042024000000000000000000000000000000000000000000000000000000000004202e0000000000000000000000000000000000000000000000000000000000042025000000000000000000000000000000000000000000000000000000000004202f00000000000000000000000000000000000000000000000000000000000420260000000000000000000000000000000000000000000000000000000000042030000000000000000000000000000000000000000000000000000000000004202700000000000000000000000000000000000000000000000000000000000420310000000000000000000000000000000000000000000000000000000000042028000000000000000000000000000000000000000000000000000000000004203200000000000000000000000000000000000000000000000000000000000420290000000000000000000000000000000000000000000000000000000000042033000000000000000000000000000000000000000000000000000000000004202a0000000000000000000000000000000000000000000000000000000000042034000000000000000000000000000000000000000000000000000000000004202b0000000000000000000000000000000000000000000000000000000000042035000000000000000000000000000000000000000000000000000000000004202c0000000000000000000000000000000000000000000000000000000000042036000000000000000000000000000000000000000000000000000000000004202d0000000000000000000000000000000000000000000000000000000000042037000000000000000000000000000000000000000000000000000000000004202e0000000000000000000000000000000000000000000000000000000000042038000000000000000000000000000000000000000000000000000000000004202f00000000000000000000000000000000000000000000000000000000000420390000000000000000000000000000000000000000000000000000000000042030000000000000000000000000000000000000000000000000000000000004203a0000000000000000000000000000000000000000000000000000000000042031000000000000000000000000000000000000000000000000000000000004203b0000000000000000000000000000000000000000000000000000000000042032000000000000000000000000000000000000000000000000000000000004203c0000000000000000000000000000000000000000000000000000000000042033000000000000000000000000000000000000000000000000000000000004203d0000000000000000000000000000000000000000000000000000000000042034000000000000000000000000000000000000000000000000000000000004203e0000000000000000000000000000000000000000000000000000000000042035000000000000000000000000000000000000000000000000000000000004203f00000000000000000000000000000000000000000000000000000000000420360000000000000000000000000000000000000000000000000000000000042040000000000000000000000000000000000000000000000000000000000004203700000000000000000000000000000000000000000000000000000000000420410000000000000000000000000000000000000000000000000000000000042038000000000000000000000000000000000000000000000000000000000004204200000000000000000000000000000000000000000000000000000000000420390000000000000000000000000000000000000000000000000000000000042043000000000000000000000000000000000000000000000000000000000004203a0000000000000000000000000000000000000000000000000000000000042044000000000000000000000000000000000000000000000000000000000004203b0000000000000000000000000000000000000000000000000000000000042045000000000000000000000000000000000000000000000000000000000004203c0000000000000000000000000000000000000000000000000000000000042046000000000000000000000000000000000000000000000000000000000004203d0000000000000000000000000000000000000000000000000000000000042047000000000000000000000000000000000000000000000000000000000004203e0000000000000000000000000000000000000000000000000000000000042048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000008100100000000000000000000000000000000000000000000000000000000000810020000000000000000000000000000000000000000000000000000000000081003000000000000000000000000000000000000000000000000000000000008100400000000000000000000000000000000000000000000000000000000000810050000000000000000000000000000000000000000000000000000000000081006000000000000000000000000000000000000000000000000000000000008100700000000000000000000000000000000000000000000000000000000000810080000000000000000000000000000000000000000000000000000000000081009000000000000000000000000000000000000000000000000000000000008100a000000000000000000000000000000000000000000000000000000000008100b000000000000000000000000000000000000000000000000000000000008100c000000000000000000000000000000000000000000000000000000000008100d000000000000000000000000000000000000000000000000000000000008100e000000000000000000000000000000000000000000000000000000000008100f0000000000000000000000000000000000000000000000000000000000081010000000000000000000000000000000000000000000000000000000000008101100000000000000000000000000000000000000000000000000000000000810120000000000000000000000000000000000000000000000000000000000081013000000000000000000000000000000000000000000000000000000000008101400000000000000000000000000000000000000000000000000000000000810150000000000000000000000000000000000000000000000000000000000081016000000000000000000000000000000000000000000000000000000000008101700000000000000000000000000000000000000000000000000000000000810180000000000000000000000000000000000000000000000000000000000081019000000000000000000000000000000000000000000000000000000000008101a000000000000000000000000000000000000000000000000000000000008101b000000000000000000000000000000000000000000000000000000000008101c000000000000000000000000000000000000000000000000000000000008101d000000000000000000000000000000000000000000000000000000000008101e000000000000000000000000000000000000000000000000000000000008101f0000000000000000000000000000000000000000000000000000000000081020000000000000000000000000000000000000000000000000000000000008102100000000000000000000000000000000000000000000000000000000000810220000000000000000000000000000000000000000000000000000000000081023000000000000000000000000000000000000000000000000000000000008102400000000000000000000000000000000000000000000000000000000000810250000000000000000000000000000000000000000000000000000000000081026000000000000000000000000000000000000000000000000000000000008102700000000000000000000000000000000000000000000000000000000000810280000000000000000000000000000000000000000000000000000000000081029000000000000000000000000000000000000000000000000000000000008102a000000000000000000000000000000000000000000000000000000000008102b000000000000000000000000000000000000000000000000000000000008102c000000000000000000000000000000000000000000000000000000000008102d000000000000000000000000000000000000000000000000000000000008102e000000000000000000000000000000000000000000000000000000000008102f0000000000000000000000000000000000000000000000000000000000081030000000000000000000000000000000000000000000000000000000000008103100000000000000000000000000000000000000000000000000000000000810320000000000000000000000000000000000000000000000000000000000081033000000000000000000000000000000000000000000000000000000000008103400000000000000000000000000000000000000000000000000000000000810350000000000000000000000000000000000000000000000000000000000081036000000000000000000000000000000000000000000000000000000000008103700000000000000000000000000000000000000000000000000000000000810380000000000000000000000000000000000000000000000000000000000081039000000000000000000000000000000000000000000000000000000000008103a000000000000000000000000000000000000000000000000000000000008103b000000000000000000000000000000000000000000000000000000000008103c000000000000000000000000000000000000000000000000000000000008103d000000000000000000000000000000000000000000000000000000000008103e000000000000000000000000000000000000000000000000000000000008103f3f0000000000000000000000000000000000000000000000000000000000081100000000000000000000000000000000000000000000000000000000000008110100000000000000000000000000000000000000000000000000000000000811020000000000000000000000000000000000000000000000000000000000081103000000000000000000000000000000000000000000000000000000000008110400000000000000000000000000000000000000000000000000000000000811050000000000000000000000000000000000000000000000000000000000081106000000000000000000000000000000000000000000000000000000000008110700000000000000000000000000000000000000000000000000000000000811080000000000000000000000000000000000000000000000000000000000081109000000000000000000000000000000000000000000000000000000000008110a000000000000000000000000000000000000000000000000000000000008110b000000000000000000000000000000000000000000000000000000000008110c000000000000000000000000000000000000000000000000000000000008110d000000000000000000000000000000000000000000000000000000000008110e000000000000000000000000000000000000000000000000000000000008110f0000000000000000000000000000000000000000000000000000000000081110000000000000000000000000000000000000000000000000000000000008111100000000000000000000000000000000000000000000000000000000000811120000000000000000000000000000000000000000000000000000000000081113000000000000000000000000000000000000000000000000000000000008111400000000000000000000000000000000000000000000000000000000000811150000000000000000000000000000000000000000000000000000000000081116000000000000000000000000000000000000000000000000000000000008111700000000000000000000000000000000000000000000000000000000000811180000000000000000000000000000000000000000000000000000000000081119000000000000000000000000000000000000000000000000000000000008111a000000000000000000000000000000000000000000000000000000000008111b000000000000000000000000000000000000000000000000000000000008111c000000000000000000000000000000000000000000000000000000000008111d000000000000000000000000000000000000000000000000000000000008111e000000000000000000000000000000000000000000000000000000000008111f0000000000000000000000000000000000000000000000000000000000081120000000000000000000000000000000000000000000000000000000000008112100000000000000000000000000000000000000000000000000000000000811220000000000000000000000000000000000000000000000000000000000081123000000000000000000000000000000000000000000000000000000000008112400000000000000000000000000000000000000000000000000000000000811250000000000000000000000000000000000000000000000000000000000081126000000000000000000000000000000000000000000000000000000000008112700000000000000000000000000000000000000000000000000000000000811280000000000000000000000000000000000000000000000000000000000081129000000000000000000000000000000000000000000000000000000000008112a000000000000000000000000000000000000000000000000000000000008112b000000000000000000000000000000000000000000000000000000000008112c000000000000000000000000000000000000000000000000000000000008112d000000000000000000000000000000000000000000000000000000000008112e000000000000000000000000000000000000000000000000000000000008112f0000000000000000000000000000000000000000000000000000000000081130000000000000000000000000000000000000000000000000000000000008113100000000000000000000000000000000000000000000000000000000000811320000000000000000000000000000000000000000000000000000000000081133000000000000000000000000000000000000000000000000000000000008113400000000000000000000000000000000000000000000000000000000000811350000000000000000000000000000000000000000000000000000000000081136000000000000000000000000000000000000000000000000000000000008113700000000000000000000000000000000000000000000000000000000000811380000000000000000000000000000000000000000000000000000000000081139000000000000000000000000000000000000000000000000000000000008113a000000000000000000000000000000000000000000000000000000000008113b000000000000000000000000000000000000000000000000000000000008113c000000000000000000000000000000000000000000000000000000000008113d000000000000000000000000000000000000000000000000000000000008113e08003c0472260790b0bdfb8ae4dc4d437e7686b73643f2198970d84e1059a5f13500bfd46275a318e438726ff2765ae154b63ab8a0daebcbed668a5f58a0e63dc1007906b9418dc758c6b4f8454c69baa48b7889b6b511d707abe8e2cb8f7c397300aeb60c4d65a44f122e58bf9565dfe2024b3ae654d5cf2e47ecb035d53c927000bf82e8cda20345f37bbb1de3932172324b57f0b98be483392697b168e3bba8000fb4bbad884ef30edf68e45a6cf2733fcf50310c69d7c1432b29af2c0aa8040023e1622d27fee3b4a40ab975ae0eb2e31619ef3dc76eb858f7fddb6a056131004689cd7007daf98dd3218b839b8e6a29f957154347b391fdb376bd0b344be23f0000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000008200a0000000000000000000000000000000000000000000000000000000000082001000000000000000000000000000000000000000000000000000000000008200b0000000000000000000000000000000000000000000000000000000000082002000000000000000000000000000000000000000000000000000000000008200c0000000000000000000000000000000000000000000000000000000000082003000000000000000000000000000000000000000000000000000000000008200d0000000000000000000000000000000000000000000000000000000000082004000000000000000000000000000000000000000000000000000000000008200e0000000000000000000000000000000000000000000000000000000000082005000000000000000000000000000000000000000000000000000000000008200f00000000000000000000000000000000000000000000000000000000000820060000000000000000000000000000000000000000000000000000000000082010000000000000000000000000000000000000000000000000000000000008200700000000000000000000000000000000000000000000000000000000000820110000000000000000000000000000000000000000000000000000000000082008000000000000000000000000000000000000000000000000000000000008201200000000000000000000000000000000000000000000000000000000000820090000000000000000000000000000000000000000000000000000000000082013000000000000000000000000000000000000000000000000000000000008200a0000000000000000000000000000000000000000000000000000000000082014000000000000000000000000000000000000000000000000000000000008200b0000000000000000000000000000000000000000000000000000000000082015000000000000000000000000000000000000000000000000000000000008200c0000000000000000000000000000000000000000000000000000000000082016000000000000000000000000000000000000000000000000000000000008200d0000000000000000000000000000000000000000000000000000000000082017000000000000000000000000000000000000000000000000000000000008200e0000000000000000000000000000000000000000000000000000000000082018000000000000000000000000000000000000000000000000000000000008200f00000000000000000000000000000000000000000000000000000000000820190000000000000000000000000000000000000000000000000000000000082010000000000000000000000000000000000000000000000000000000000008201a0000000000000000000000000000000000000000000000000000000000082011000000000000000000000000000000000000000000000000000000000008201b0000000000000000000000000000000000000000000000000000000000082012000000000000000000000000000000000000000000000000000000000008201c0000000000000000000000000000000000000000000000000000000000082013000000000000000000000000000000000000000000000000000000000008201d0000000000000000000000000000000000000000000000000000000000082014000000000000000000000000000000000000000000000000000000000008201e0000000000000000000000000000000000000000000000000000000000082015000000000000000000000000000000000000000000000000000000000008201f00000000000000000000000000000000000000000000000000000000000820160000000000000000000000000000000000000000000000000000000000082020000000000000000000000000000000000000000000000000000000000008201700000000000000000000000000000000000000000000000000000000000820210000000000000000000000000000000000000000000000000000000000082018000000000000000000000000000000000000000000000000000000000008202200000000000000000000000000000000000000000000000000000000000820190000000000000000000000000000000000000000000000000000000000082023000000000000000000000000000000000000000000000000000000000008201a0000000000000000000000000000000000000000000000000000000000082024000000000000000000000000000000000000000000000000000000000008201b0000000000000000000000000000000000000000000000000000000000082025000000000000000000000000000000000000000000000000000000000008201c0000000000000000000000000000000000000000000000000000000000082026000000000000000000000000000000000000000000000000000000000008201d0000000000000000000000000000000000000000000000000000000000082027000000000000000000000000000000000000000000000000000000000008201e0000000000000000000000000000000000000000000000000000000000082028000000000000000000000000000000000000000000000000000000000008201f00000000000000000000000000000000000000000000000000000000000820290000000000000000000000000000000000000000000000000000000000082020000000000000000000000000000000000000000000000000000000000008202a0000000000000000000000000000000000000000000000000000000000082021000000000000000000000000000000000000000000000000000000000008202b0000000000000000000000000000000000000000000000000000000000082022000000000000000000000000000000000000000000000000000000000008202c0000000000000000000000000000000000000000000000000000000000082023000000000000000000000000000000000000000000000000000000000008202d0000000000000000000000000000000000000000000000000000000000082024000000000000000000000000000000000000000000000000000000000008202e0000000000000000000000000000000000000000000000000000000000082025000000000000000000000000000000000000000000000000000000000008202f00000000000000000000000000000000000000000000000000000000000820260000000000000000000000000000000000000000000000000000000000082030000000000000000000000000000000000000000000000000000000000008202700000000000000000000000000000000000000000000000000000000000820310000000000000000000000000000000000000000000000000000000000082028000000000000000000000000000000000000000000000000000000000008203200000000000000000000000000000000000000000000000000000000000820290000000000000000000000000000000000000000000000000000000000082033000000000000000000000000000000000000000000000000000000000008202a0000000000000000000000000000000000000000000000000000000000082034000000000000000000000000000000000000000000000000000000000008202b0000000000000000000000000000000000000000000000000000000000082035000000000000000000000000000000000000000000000000000000000008202c0000000000000000000000000000000000000000000000000000000000082036000000000000000000000000000000000000000000000000000000000008202d0000000000000000000000000000000000000000000000000000000000082037000000000000000000000000000000000000000000000000000000000008202e0000000000000000000000000000000000000000000000000000000000082038000000000000000000000000000000000000000000000000000000000008202f00000000000000000000000000000000000000000000000000000000000820390000000000000000000000000000000000000000000000000000000000082030000000000000000000000000000000000000000000000000000000000008203a0000000000000000000000000000000000000000000000000000000000082031000000000000000000000000000000000000000000000000000000000008203b0000000000000000000000000000000000000000000000000000000000082032000000000000000000000000000000000000000000000000000000000008203c0000000000000000000000000000000000000000000000000000000000082033000000000000000000000000000000000000000000000000000000000008203d0000000000000000000000000000000000000000000000000000000000082034000000000000000000000000000000000000000000000000000000000008203e0000000000000000000000000000000000000000000000000000000000082035000000000000000000000000000000000000000000000000000000000008203f00000000000000000000000000000000000000000000000000000000000820360000000000000000000000000000000000000000000000000000000000082040000000000000000000000000000000000000000000000000000000000008203700000000000000000000000000000000000000000000000000000000000820410000000000000000000000000000000000000000000000000000000000082038000000000000000000000000000000000000000000000000000000000008204200000000000000000000000000000000000000000000000000000000000820390000000000000000000000000000000000000000000000000000000000082043000000000000000000000000000000000000000000000000000000000008203a0000000000000000000000000000000000000000000000000000000000082044000000000000000000000000000000000000000000000000000000000008203b0000000000000000000000000000000000000000000000000000000000082045000000000000000000000000000000000000000000000000000000000008203c0000000000000000000000000000000000000000000000000000000000082046000000000000000000000000000000000000000000000000000000000008203d0000000000000000000000000000000000000000000000000000000000082047000000000000000000000000000000000000000000000000000000000008203e00000000000000000000000000000000000000000000000000000000000820480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000c100100000000000000000000000000000000000000000000000000000000000c100200000000000000000000000000000000000000000000000000000000000c100300000000000000000000000000000000000000000000000000000000000c100400000000000000000000000000000000000000000000000000000000000c100500000000000000000000000000000000000000000000000000000000000c100600000000000000000000000000000000000000000000000000000000000c100700000000000000000000000000000000000000000000000000000000000c100800000000000000000000000000000000000000000000000000000000000c100900000000000000000000000000000000000000000000000000000000000c100a00000000000000000000000000000000000000000000000000000000000c100b00000000000000000000000000000000000000000000000000000000000c100c00000000000000000000000000000000000000000000000000000000000c100d00000000000000000000000000000000000000000000000000000000000c100e00000000000000000000000000000000000000000000000000000000000c100f00000000000000000000000000000000000000000000000000000000000c101000000000000000000000000000000000000000000000000000000000000c101100000000000000000000000000000000000000000000000000000000000c101200000000000000000000000000000000000000000000000000000000000c101300000000000000000000000000000000000000000000000000000000000c101400000000000000000000000000000000000000000000000000000000000c101500000000000000000000000000000000000000000000000000000000000c101600000000000000000000000000000000000000000000000000000000000c101700000000000000000000000000000000000000000000000000000000000c101800000000000000000000000000000000000000000000000000000000000c101900000000000000000000000000000000000000000000000000000000000c101a00000000000000000000000000000000000000000000000000000000000c101b00000000000000000000000000000000000000000000000000000000000c101c00000000000000000000000000000000000000000000000000000000000c101d00000000000000000000000000000000000000000000000000000000000c101e00000000000000000000000000000000000000000000000000000000000c101f00000000000000000000000000000000000000000000000000000000000c102000000000000000000000000000000000000000000000000000000000000c102100000000000000000000000000000000000000000000000000000000000c102200000000000000000000000000000000000000000000000000000000000c102300000000000000000000000000000000000000000000000000000000000c102400000000000000000000000000000000000000000000000000000000000c102500000000000000000000000000000000000000000000000000000000000c102600000000000000000000000000000000000000000000000000000000000c102700000000000000000000000000000000000000000000000000000000000c102800000000000000000000000000000000000000000000000000000000000c102900000000000000000000000000000000000000000000000000000000000c102a00000000000000000000000000000000000000000000000000000000000c102b00000000000000000000000000000000000000000000000000000000000c102c00000000000000000000000000000000000000000000000000000000000c102d00000000000000000000000000000000000000000000000000000000000c102e00000000000000000000000000000000000000000000000000000000000c102f00000000000000000000000000000000000000000000000000000000000c103000000000000000000000000000000000000000000000000000000000000c103100000000000000000000000000000000000000000000000000000000000c103200000000000000000000000000000000000000000000000000000000000c103300000000000000000000000000000000000000000000000000000000000c103400000000000000000000000000000000000000000000000000000000000c103500000000000000000000000000000000000000000000000000000000000c103600000000000000000000000000000000000000000000000000000000000c103700000000000000000000000000000000000000000000000000000000000c103800000000000000000000000000000000000000000000000000000000000c103900000000000000000000000000000000000000000000000000000000000c103a00000000000000000000000000000000000000000000000000000000000c103b00000000000000000000000000000000000000000000000000000000000c103c00000000000000000000000000000000000000000000000000000000000c103d00000000000000000000000000000000000000000000000000000000000c103e00000000000000000000000000000000000000000000000000000000000c103f3f00000000000000000000000000000000000000000000000000000000000c110000000000000000000000000000000000000000000000000000000000000c110100000000000000000000000000000000000000000000000000000000000c110200000000000000000000000000000000000000000000000000000000000c110300000000000000000000000000000000000000000000000000000000000c110400000000000000000000000000000000000000000000000000000000000c110500000000000000000000000000000000000000000000000000000000000c110600000000000000000000000000000000000000000000000000000000000c110700000000000000000000000000000000000000000000000000000000000c110800000000000000000000000000000000000000000000000000000000000c110900000000000000000000000000000000000000000000000000000000000c110a00000000000000000000000000000000000000000000000000000000000c110b00000000000000000000000000000000000000000000000000000000000c110c00000000000000000000000000000000000000000000000000000000000c110d00000000000000000000000000000000000000000000000000000000000c110e00000000000000000000000000000000000000000000000000000000000c110f00000000000000000000000000000000000000000000000000000000000c111000000000000000000000000000000000000000000000000000000000000c111100000000000000000000000000000000000000000000000000000000000c111200000000000000000000000000000000000000000000000000000000000c111300000000000000000000000000000000000000000000000000000000000c111400000000000000000000000000000000000000000000000000000000000c111500000000000000000000000000000000000000000000000000000000000c111600000000000000000000000000000000000000000000000000000000000c111700000000000000000000000000000000000000000000000000000000000c111800000000000000000000000000000000000000000000000000000000000c111900000000000000000000000000000000000000000000000000000000000c111a00000000000000000000000000000000000000000000000000000000000c111b00000000000000000000000000000000000000000000000000000000000c111c00000000000000000000000000000000000000000000000000000000000c111d00000000000000000000000000000000000000000000000000000000000c111e00000000000000000000000000000000000000000000000000000000000c111f00000000000000000000000000000000000000000000000000000000000c112000000000000000000000000000000000000000000000000000000000000c112100000000000000000000000000000000000000000000000000000000000c112200000000000000000000000000000000000000000000000000000000000c112300000000000000000000000000000000000000000000000000000000000c112400000000000000000000000000000000000000000000000000000000000c112500000000000000000000000000000000000000000000000000000000000c112600000000000000000000000000000000000000000000000000000000000c112700000000000000000000000000000000000000000000000000000000000c112800000000000000000000000000000000000000000000000000000000000c112900000000000000000000000000000000000000000000000000000000000c112a00000000000000000000000000000000000000000000000000000000000c112b00000000000000000000000000000000000000000000000000000000000c112c00000000000000000000000000000000000000000000000000000000000c112d00000000000000000000000000000000000000000000000000000000000c112e00000000000000000000000000000000000000000000000000000000000c112f00000000000000000000000000000000000000000000000000000000000c113000000000000000000000000000000000000000000000000000000000000c113100000000000000000000000000000000000000000000000000000000000c113200000000000000000000000000000000000000000000000000000000000c113300000000000000000000000000000000000000000000000000000000000c113400000000000000000000000000000000000000000000000000000000000c113500000000000000000000000000000000000000000000000000000000000c113600000000000000000000000000000000000000000000000000000000000c113700000000000000000000000000000000000000000000000000000000000c113800000000000000000000000000000000000000000000000000000000000c113900000000000000000000000000000000000000000000000000000000000c113a00000000000000000000000000000000000000000000000000000000000c113b00000000000000000000000000000000000000000000000000000000000c113c00000000000000000000000000000000000000000000000000000000000c113d00000000000000000000000000000000000000000000000000000000000c113e0800f8029be42ec3f25204907ca981fb71e5b357093eb5db10fc01ca98a4e4154c0030e13d351a5bf1d5a040e82a163ca57017f39162693f85c571e441e36d702d00a550ae0f39f977d9473d6de1be3232fc68ed0c4a601d53542148695102cfc9005580bc65e4bff9c8fffa64db02c0fa6af14d9d26fd962f4c5904cbd3ddec2500758c4a0d43dfec788b2f580877c4f473adec8f168ea24424f2600e4eb4916f00342602bf90d10f8ca8e582a894dcc4c02bb89fe458532e0c632b53bae54b4d00ca43ab78ab834337e9964d84a0674c9adabdca140539c5a6bc96e0ba9a51f6004ffbfd91be292a7c6a0e255e50caa156ac2d628b40ad2128c4ab63a92d8a1c3f00000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000c200a00000000000000000000000000000000000000000000000000000000000c200100000000000000000000000000000000000000000000000000000000000c200b00000000000000000000000000000000000000000000000000000000000c200200000000000000000000000000000000000000000000000000000000000c200c00000000000000000000000000000000000000000000000000000000000c200300000000000000000000000000000000000000000000000000000000000c200d00000000000000000000000000000000000000000000000000000000000c200400000000000000000000000000000000000000000000000000000000000c200e00000000000000000000000000000000000000000000000000000000000c200500000000000000000000000000000000000000000000000000000000000c200f00000000000000000000000000000000000000000000000000000000000c200600000000000000000000000000000000000000000000000000000000000c201000000000000000000000000000000000000000000000000000000000000c200700000000000000000000000000000000000000000000000000000000000c201100000000000000000000000000000000000000000000000000000000000c200800000000000000000000000000000000000000000000000000000000000c201200000000000000000000000000000000000000000000000000000000000c200900000000000000000000000000000000000000000000000000000000000c201300000000000000000000000000000000000000000000000000000000000c200a00000000000000000000000000000000000000000000000000000000000c201400000000000000000000000000000000000000000000000000000000000c200b00000000000000000000000000000000000000000000000000000000000c201500000000000000000000000000000000000000000000000000000000000c200c00000000000000000000000000000000000000000000000000000000000c201600000000000000000000000000000000000000000000000000000000000c200d00000000000000000000000000000000000000000000000000000000000c201700000000000000000000000000000000000000000000000000000000000c200e00000000000000000000000000000000000000000000000000000000000c201800000000000000000000000000000000000000000000000000000000000c200f00000000000000000000000000000000000000000000000000000000000c201900000000000000000000000000000000000000000000000000000000000c201000000000000000000000000000000000000000000000000000000000000c201a00000000000000000000000000000000000000000000000000000000000c201100000000000000000000000000000000000000000000000000000000000c201b00000000000000000000000000000000000000000000000000000000000c201200000000000000000000000000000000000000000000000000000000000c201c00000000000000000000000000000000000000000000000000000000000c201300000000000000000000000000000000000000000000000000000000000c201d00000000000000000000000000000000000000000000000000000000000c201400000000000000000000000000000000000000000000000000000000000c201e00000000000000000000000000000000000000000000000000000000000c201500000000000000000000000000000000000000000000000000000000000c201f00000000000000000000000000000000000000000000000000000000000c201600000000000000000000000000000000000000000000000000000000000c202000000000000000000000000000000000000000000000000000000000000c201700000000000000000000000000000000000000000000000000000000000c202100000000000000000000000000000000000000000000000000000000000c201800000000000000000000000000000000000000000000000000000000000c202200000000000000000000000000000000000000000000000000000000000c201900000000000000000000000000000000000000000000000000000000000c202300000000000000000000000000000000000000000000000000000000000c201a00000000000000000000000000000000000000000000000000000000000c202400000000000000000000000000000000000000000000000000000000000c201b00000000000000000000000000000000000000000000000000000000000c202500000000000000000000000000000000000000000000000000000000000c201c00000000000000000000000000000000000000000000000000000000000c202600000000000000000000000000000000000000000000000000000000000c201d00000000000000000000000000000000000000000000000000000000000c202700000000000000000000000000000000000000000000000000000000000c201e00000000000000000000000000000000000000000000000000000000000c202800000000000000000000000000000000000000000000000000000000000c201f00000000000000000000000000000000000000000000000000000000000c202900000000000000000000000000000000000000000000000000000000000c202000000000000000000000000000000000000000000000000000000000000c202a00000000000000000000000000000000000000000000000000000000000c202100000000000000000000000000000000000000000000000000000000000c202b00000000000000000000000000000000000000000000000000000000000c202200000000000000000000000000000000000000000000000000000000000c202c00000000000000000000000000000000000000000000000000000000000c202300000000000000000000000000000000000000000000000000000000000c202d00000000000000000000000000000000000000000000000000000000000c202400000000000000000000000000000000000000000000000000000000000c202e00000000000000000000000000000000000000000000000000000000000c202500000000000000000000000000000000000000000000000000000000000c202f00000000000000000000000000000000000000000000000000000000000c202600000000000000000000000000000000000000000000000000000000000c203000000000000000000000000000000000000000000000000000000000000c202700000000000000000000000000000000000000000000000000000000000c203100000000000000000000000000000000000000000000000000000000000c202800000000000000000000000000000000000000000000000000000000000c203200000000000000000000000000000000000000000000000000000000000c202900000000000000000000000000000000000000000000000000000000000c203300000000000000000000000000000000000000000000000000000000000c202a00000000000000000000000000000000000000000000000000000000000c203400000000000000000000000000000000000000000000000000000000000c202b00000000000000000000000000000000000000000000000000000000000c203500000000000000000000000000000000000000000000000000000000000c202c00000000000000000000000000000000000000000000000000000000000c203600000000000000000000000000000000000000000000000000000000000c202d00000000000000000000000000000000000000000000000000000000000c203700000000000000000000000000000000000000000000000000000000000c202e00000000000000000000000000000000000000000000000000000000000c203800000000000000000000000000000000000000000000000000000000000c202f00000000000000000000000000000000000000000000000000000000000c203900000000000000000000000000000000000000000000000000000000000c203000000000000000000000000000000000000000000000000000000000000c203a00000000000000000000000000000000000000000000000000000000000c203100000000000000000000000000000000000000000000000000000000000c203b00000000000000000000000000000000000000000000000000000000000c203200000000000000000000000000000000000000000000000000000000000c203c00000000000000000000000000000000000000000000000000000000000c203300000000000000000000000000000000000000000000000000000000000c203d00000000000000000000000000000000000000000000000000000000000c203400000000000000000000000000000000000000000000000000000000000c203e00000000000000000000000000000000000000000000000000000000000c203500000000000000000000000000000000000000000000000000000000000c203f00000000000000000000000000000000000000000000000000000000000c203600000000000000000000000000000000000000000000000000000000000c204000000000000000000000000000000000000000000000000000000000000c203700000000000000000000000000000000000000000000000000000000000c204100000000000000000000000000000000000000000000000000000000000c203800000000000000000000000000000000000000000000000000000000000c204200000000000000000000000000000000000000000000000000000000000c203900000000000000000000000000000000000000000000000000000000000c204300000000000000000000000000000000000000000000000000000000000c203a00000000000000000000000000000000000000000000000000000000000c204400000000000000000000000000000000000000000000000000000000000c203b00000000000000000000000000000000000000000000000000000000000c204500000000000000000000000000000000000000000000000000000000000c203c00000000000000000000000000000000000000000000000000000000000c204600000000000000000000000000000000000000000000000000000000000c203d00000000000000000000000000000000000000000000000000000000000c204700000000000000000000000000000000000000000000000000000000000c203e00000000000000000000000000000000000000000000000000000000000c2048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000101000000000000000000000000000000000000000000000000000000000000010100100000000000000000000000000000000000000000000000000000000001010020000000000000000000000000000000000000000000000000000000000101003000000000000000000000000000000000000000000000000000000000010100400000000000000000000000000000000000000000000000000000000001010050000000000000000000000000000000000000000000000000000000000101006000000000000000000000000000000000000000000000000000000000010100700000000000000000000000000000000000000000000000000000000001010080000000000000000000000000000000000000000000000000000000000101009000000000000000000000000000000000000000000000000000000000010100a000000000000000000000000000000000000000000000000000000000010100b000000000000000000000000000000000000000000000000000000000010100c000000000000000000000000000000000000000000000000000000000010100d000000000000000000000000000000000000000000000000000000000010100e000000000000000000000000000000000000000000000000000000000010100f0000000000000000000000000000000000000000000000000000000000101010000000000000000000000000000000000000000000000000000000000010101100000000000000000000000000000000000000000000000000000000001010120000000000000000000000000000000000000000000000000000000000101013000000000000000000000000000000000000000000000000000000000010101400000000000000000000000000000000000000000000000000000000001010150000000000000000000000000000000000000000000000000000000000101016000000000000000000000000000000000000000000000000000000000010101700000000000000000000000000000000000000000000000000000000001010180000000000000000000000000000000000000000000000000000000000101019000000000000000000000000000000000000000000000000000000000010101a000000000000000000000000000000000000000000000000000000000010101b000000000000000000000000000000000000000000000000000000000010101c000000000000000000000000000000000000000000000000000000000010101d000000000000000000000000000000000000000000000000000000000010101e000000000000000000000000000000000000000000000000000000000010101f0000000000000000000000000000000000000000000000000000000000101020000000000000000000000000000000000000000000000000000000000010102100000000000000000000000000000000000000000000000000000000001010220000000000000000000000000000000000000000000000000000000000101023000000000000000000000000000000000000000000000000000000000010102400000000000000000000000000000000000000000000000000000000001010250000000000000000000000000000000000000000000000000000000000101026000000000000000000000000000000000000000000000000000000000010102700000000000000000000000000000000000000000000000000000000001010280000000000000000000000000000000000000000000000000000000000101029000000000000000000000000000000000000000000000000000000000010102a000000000000000000000000000000000000000000000000000000000010102b000000000000000000000000000000000000000000000000000000000010102c000000000000000000000000000000000000000000000000000000000010102d000000000000000000000000000000000000000000000000000000000010102e000000000000000000000000000000000000000000000000000000000010102f0000000000000000000000000000000000000000000000000000000000101030000000000000000000000000000000000000000000000000000000000010103100000000000000000000000000000000000000000000000000000000001010320000000000000000000000000000000000000000000000000000000000101033000000000000000000000000000000000000000000000000000000000010103400000000000000000000000000000000000000000000000000000000001010350000000000000000000000000000000000000000000000000000000000101036000000000000000000000000000000000000000000000000000000000010103700000000000000000000000000000000000000000000000000000000001010380000000000000000000000000000000000000000000000000000000000101039000000000000000000000000000000000000000000000000000000000010103a000000000000000000000000000000000000000000000000000000000010103b000000000000000000000000000000000000000000000000000000000010103c000000000000000000000000000000000000000000000000000000000010103d000000000000000000000000000000000000000000000000000000000010103e000000000000000000000000000000000000000000000000000000000010103f3f0000000000000000000000000000000000000000000000000000000000101100000000000000000000000000000000000000000000000000000000000010110100000000000000000000000000000000000000000000000000000000001011020000000000000000000000000000000000000000000000000000000000101103000000000000000000000000000000000000000000000000000000000010110400000000000000000000000000000000000000000000000000000000001011050000000000000000000000000000000000000000000000000000000000101106000000000000000000000000000000000000000000000000000000000010110700000000000000000000000000000000000000000000000000000000001011080000000000000000000000000000000000000000000000000000000000101109000000000000000000000000000000000000000000000000000000000010110a000000000000000000000000000000000000000000000000000000000010110b000000000000000000000000000000000000000000000000000000000010110c000000000000000000000000000000000000000000000000000000000010110d000000000000000000000000000000000000000000000000000000000010110e000000000000000000000000000000000000000000000000000000000010110f0000000000000000000000000000000000000000000000000000000000101110000000000000000000000000000000000000000000000000000000000010111100000000000000000000000000000000000000000000000000000000001011120000000000000000000000000000000000000000000000000000000000101113000000000000000000000000000000000000000000000000000000000010111400000000000000000000000000000000000000000000000000000000001011150000000000000000000000000000000000000000000000000000000000101116000000000000000000000000000000000000000000000000000000000010111700000000000000000000000000000000000000000000000000000000001011180000000000000000000000000000000000000000000000000000000000101119000000000000000000000000000000000000000000000000000000000010111a000000000000000000000000000000000000000000000000000000000010111b000000000000000000000000000000000000000000000000000000000010111c000000000000000000000000000000000000000000000000000000000010111d000000000000000000000000000000000000000000000000000000000010111e000000000000000000000000000000000000000000000000000000000010111f0000000000000000000000000000000000000000000000000000000000101120000000000000000000000000000000000000000000000000000000000010112100000000000000000000000000000000000000000000000000000000001011220000000000000000000000000000000000000000000000000000000000101123000000000000000000000000000000000000000000000000000000000010112400000000000000000000000000000000000000000000000000000000001011250000000000000000000000000000000000000000000000000000000000101126000000000000000000000000000000000000000000000000000000000010112700000000000000000000000000000000000000000000000000000000001011280000000000000000000000000000000000000000000000000000000000101129000000000000000000000000000000000000000000000000000000000010112a000000000000000000000000000000000000000000000000000000000010112b000000000000000000000000000000000000000000000000000000000010112c000000000000000000000000000000000000000000000000000000000010112d000000000000000000000000000000000000000000000000000000000010112e000000000000000000000000000000000000000000000000000000000010112f0000000000000000000000000000000000000000000000000000000000101130000000000000000000000000000000000000000000000000000000000010113100000000000000000000000000000000000000000000000000000000001011320000000000000000000000000000000000000000000000000000000000101133000000000000000000000000000000000000000000000000000000000010113400000000000000000000000000000000000000000000000000000000001011350000000000000000000000000000000000000000000000000000000000101136000000000000000000000000000000000000000000000000000000000010113700000000000000000000000000000000000000000000000000000000001011380000000000000000000000000000000000000000000000000000000000101139000000000000000000000000000000000000000000000000000000000010113a000000000000000000000000000000000000000000000000000000000010113b000000000000000000000000000000000000000000000000000000000010113c000000000000000000000000000000000000000000000000000000000010113d000000000000000000000000000000000000000000000000000000000010113e080099145b6c0d32753835121f8b271186d01236948a4622ce78a98347fcfc98390085277a27c6acbd5ffc4c19cd65fc30056999e9bec36998f753132db0ff8e2300f3cf77a7261759ebd5f4149f6ad56746f4499cfcd4adf27a1d373f77da64d5009bc6e0e994a23cde8c95b90c1acc1b4a480c6599d1df2c3f9f6e76f3d1aff200d7a1c4a2700dacaaf07f1f0ff33837bdbabcf0b9ace17efabe0761708c4bb900dbeb8e96d14f21e57d5786b6d6ae7e5ddb1bb35935c0fb246d4bdbca62e02c00fbf12b5e0df6223b801088798e4e04d2a92ffe9a11639b7f0ce314e3412a8000d796e0724de03b796ba77069fcd6cf921e566f3aed15eb3e77258add74e9ff3f0000000000000000000000000000000000000000000000000000000000102000000000000000000000000000000000000000000000000000000000000010200a0000000000000000000000000000000000000000000000000000000000102001000000000000000000000000000000000000000000000000000000000010200b0000000000000000000000000000000000000000000000000000000000102002000000000000000000000000000000000000000000000000000000000010200c0000000000000000000000000000000000000000000000000000000000102003000000000000000000000000000000000000000000000000000000000010200d0000000000000000000000000000000000000000000000000000000000102004000000000000000000000000000000000000000000000000000000000010200e0000000000000000000000000000000000000000000000000000000000102005000000000000000000000000000000000000000000000000000000000010200f00000000000000000000000000000000000000000000000000000000001020060000000000000000000000000000000000000000000000000000000000102010000000000000000000000000000000000000000000000000000000000010200700000000000000000000000000000000000000000000000000000000001020110000000000000000000000000000000000000000000000000000000000102008000000000000000000000000000000000000000000000000000000000010201200000000000000000000000000000000000000000000000000000000001020090000000000000000000000000000000000000000000000000000000000102013000000000000000000000000000000000000000000000000000000000010200a0000000000000000000000000000000000000000000000000000000000102014000000000000000000000000000000000000000000000000000000000010200b0000000000000000000000000000000000000000000000000000000000102015000000000000000000000000000000000000000000000000000000000010200c0000000000000000000000000000000000000000000000000000000000102016000000000000000000000000000000000000000000000000000000000010200d0000000000000000000000000000000000000000000000000000000000102017000000000000000000000000000000000000000000000000000000000010200e0000000000000000000000000000000000000000000000000000000000102018000000000000000000000000000000000000000000000000000000000010200f00000000000000000000000000000000000000000000000000000000001020190000000000000000000000000000000000000000000000000000000000102010000000000000000000000000000000000000000000000000000000000010201a0000000000000000000000000000000000000000000000000000000000102011000000000000000000000000000000000000000000000000000000000010201b0000000000000000000000000000000000000000000000000000000000102012000000000000000000000000000000000000000000000000000000000010201c0000000000000000000000000000000000000000000000000000000000102013000000000000000000000000000000000000000000000000000000000010201d0000000000000000000000000000000000000000000000000000000000102014000000000000000000000000000000000000000000000000000000000010201e0000000000000000000000000000000000000000000000000000000000102015000000000000000000000000000000000000000000000000000000000010201f00000000000000000000000000000000000000000000000000000000001020160000000000000000000000000000000000000000000000000000000000102020000000000000000000000000000000000000000000000000000000000010201700000000000000000000000000000000000000000000000000000000001020210000000000000000000000000000000000000000000000000000000000102018000000000000000000000000000000000000000000000000000000000010202200000000000000000000000000000000000000000000000000000000001020190000000000000000000000000000000000000000000000000000000000102023000000000000000000000000000000000000000000000000000000000010201a0000000000000000000000000000000000000000000000000000000000102024000000000000000000000000000000000000000000000000000000000010201b0000000000000000000000000000000000000000000000000000000000102025000000000000000000000000000000000000000000000000000000000010201c0000000000000000000000000000000000000000000000000000000000102026000000000000000000000000000000000000000000000000000000000010201d0000000000000000000000000000000000000000000000000000000000102027000000000000000000000000000000000000000000000000000000000010201e0000000000000000000000000000000000000000000000000000000000102028000000000000000000000000000000000000000000000000000000000010201f00000000000000000000000000000000000000000000000000000000001020290000000000000000000000000000000000000000000000000000000000102020000000000000000000000000000000000000000000000000000000000010202a0000000000000000000000000000000000000000000000000000000000102021000000000000000000000000000000000000000000000000000000000010202b0000000000000000000000000000000000000000000000000000000000102022000000000000000000000000000000000000000000000000000000000010202c0000000000000000000000000000000000000000000000000000000000102023000000000000000000000000000000000000000000000000000000000010202d0000000000000000000000000000000000000000000000000000000000102024000000000000000000000000000000000000000000000000000000000010202e0000000000000000000000000000000000000000000000000000000000102025000000000000000000000000000000000000000000000000000000000010202f00000000000000000000000000000000000000000000000000000000001020260000000000000000000000000000000000000000000000000000000000102030000000000000000000000000000000000000000000000000000000000010202700000000000000000000000000000000000000000000000000000000001020310000000000000000000000000000000000000000000000000000000000102028000000000000000000000000000000000000000000000000000000000010203200000000000000000000000000000000000000000000000000000000001020290000000000000000000000000000000000000000000000000000000000102033000000000000000000000000000000000000000000000000000000000010202a0000000000000000000000000000000000000000000000000000000000102034000000000000000000000000000000000000000000000000000000000010202b0000000000000000000000000000000000000000000000000000000000102035000000000000000000000000000000000000000000000000000000000010202c0000000000000000000000000000000000000000000000000000000000102036000000000000000000000000000000000000000000000000000000000010202d0000000000000000000000000000000000000000000000000000000000102037000000000000000000000000000000000000000000000000000000000010202e0000000000000000000000000000000000000000000000000000000000102038000000000000000000000000000000000000000000000000000000000010202f00000000000000000000000000000000000000000000000000000000001020390000000000000000000000000000000000000000000000000000000000102030000000000000000000000000000000000000000000000000000000000010203a0000000000000000000000000000000000000000000000000000000000102031000000000000000000000000000000000000000000000000000000000010203b0000000000000000000000000000000000000000000000000000000000102032000000000000000000000000000000000000000000000000000000000010203c0000000000000000000000000000000000000000000000000000000000102033000000000000000000000000000000000000000000000000000000000010203d0000000000000000000000000000000000000000000000000000000000102034000000000000000000000000000000000000000000000000000000000010203e0000000000000000000000000000000000000000000000000000000000102035000000000000000000000000000000000000000000000000000000000010203f00000000000000000000000000000000000000000000000000000000001020360000000000000000000000000000000000000000000000000000000000102040000000000000000000000000000000000000000000000000000000000010203700000000000000000000000000000000000000000000000000000000001020410000000000000000000000000000000000000000000000000000000000102038000000000000000000000000000000000000000000000000000000000010204200000000000000000000000000000000000000000000000000000000001020390000000000000000000000000000000000000000000000000000000000102043000000000000000000000000000000000000000000000000000000000010203a0000000000000000000000000000000000000000000000000000000000102044000000000000000000000000000000000000000000000000000000000010203b0000000000000000000000000000000000000000000000000000000000102045000000000000000000000000000000000000000000000000000000000010203c0000000000000000000000000000000000000000000000000000000000102046000000000000000000000000000000000000000000000000000000000010203d0000000000000000000000000000000000000000000000000000000000102047000000000000000000000000000000000000000000000000000000000010203e0000000000000000000000000000000000000000000000000000000000102048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "txsEffectsHash": "0x00db66b36b24ebccb7543a74620018056cad2f0b08eaf251ad00362551f0a2d0", "decodedHeader": { @@ -73,18 +73,20 @@ "blockNumber": 1, "slotNumber": "0x000000000000000000000000000000000000000000000000000000000000001a", "chainId": 31337, - "timestamp": 1731434005, + "timestamp": 1732579038, "version": 1, - "coinbase": "0xa8f1a4313bc15dcd3681ed2b6fdd042f1ee1f823", - "feeRecipient": "0x2abdc96d2ec8465dfd2bb7401f90dd3af0db16c3cece57bd5de2b63a3d25140b", + "coinbase": "0x7bf63a9118e60cc630c4faa654223f715d4bd20e", + "feeRecipient": "0x2f2bacf41d88061f8a9e9234dfb8f6cdf5287e15eeeb4a6af5b0691d846bad5d", "gasFees": { "feePerDaGas": 0, - "feePerL2Gas": 0 + "feePerL2Gas": 54166854910 } }, + "totalFees": "0x0000000000000000000000000000000000000000000000000000000000000000", + "totalManaUsed": "0x0000000000000000000000000000000000000000000000000000000000000000", "lastArchive": { "nextAvailableLeafIndex": 1, - "root": "0x2a05cb8aeefe9b9797f90650eae072f5ab7437807e62f9724ce1900467779860" + "root": "0x0237797d6a2c04d20d4fa06b74482bd970ccd51a43d9b05b57e9b91fa1ae1cae" }, "stateReference": { "l1ToL2MessageTree": { @@ -101,14 +103,14 @@ "root": "0x1d52eeaaacb445d9193d29e0df8f0ad4bf69bc457fe955b8e05b48ae3fdc3b3f" }, "publicDataTree": { - "nextAvailableLeafIndex": 384, - "root": "0x160cf8d0dbcc7b6a69aede9d89adb66554ba8054d9944b6ab5475e155e8f73d4" + "nextAvailableLeafIndex": 380, + "root": "0x20a27b2839a892ce7ac7c3a76b625388d4efdd4d736f29f86d41bb32d4bc73cf" } } } }, - "header": "0x2a05cb8aeefe9b9797f90650eae072f5ab7437807e62f9724ce190046777986000000001000000000000000000000000000000000000000000000000000000000000000400db66b36b24ebccb7543a74620018056cad2f0b08eaf251ad00362551f0a2d000089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c000ca4a4610ad22c97c9161cedcf01faa3619f1b85457f1627d09627b71903a62e33ee2008411c04b99c24b313513d097a0d21a5040b6193d1f978b8226892d60000001000553ea03210e12bf95ed15f0105108f39db784d318cfe9b52cba413618711ce000001001d52eeaaacb445d9193d29e0df8f0ad4bf69bc457fe955b8e05b48ae3fdc3b3f00000180160cf8d0dbcc7b6a69aede9d89adb66554ba8054d9944b6ab5475e155e8f73d4000001800000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000067339615a8f1a4313bc15dcd3681ed2b6fdd042f1ee1f8232abdc96d2ec8465dfd2bb7401f90dd3af0db16c3cece57bd5de2b63a3d25140b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "publicInputsHash": "0x0058fc697c9471ef94446a35f46a068633d057596164ddf20e6152f6fac19f81", + "header": "0x0237797d6a2c04d20d4fa06b74482bd970ccd51a43d9b05b57e9b91fa1ae1cae00000001000000000000000000000000000000000000000000000000000000000000000400db66b36b24ebccb7543a74620018056cad2f0b08eaf251ad00362551f0a2d000089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c000ca4a4610ad22c97c9161cedcf01faa3619f1b85457f1627d09627b71903a62e33ee2008411c04b99c24b313513d097a0d21a5040b6193d1f978b8226892d60000001000553ea03210e12bf95ed15f0105108f39db784d318cfe9b52cba413618711ce000001001d52eeaaacb445d9193d29e0df8f0ad4bf69bc457fe955b8e05b48ae3fdc3b3f0000018020a27b2839a892ce7ac7c3a76b625388d4efdd4d736f29f86d41bb32d4bc73cf0000017c0000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000067450ede7bf63a9118e60cc630c4faa654223f715d4bd20e2f2bacf41d88061f8a9e9234dfb8f6cdf5287e15eeeb4a6af5b0691d846bad5d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c9c989cfe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "publicInputsHash": "0x00f895b5ad3a835f2abbcc0793d4799b7316a18e690c18b45c96e6a12d2a3231", "numTxs": 4 } } \ No newline at end of file diff --git a/l1-contracts/test/fixtures/mixed_block_2.json b/l1-contracts/test/fixtures/mixed_block_2.json index 1a84a75aa31..309977c2b3a 100644 --- a/l1-contracts/test/fixtures/mixed_block_2.json +++ b/l1-contracts/test/fixtures/mixed_block_2.json @@ -23,38 +23,6 @@ }, "messages": { "l2ToL1Messages": [ - "0x0097a6ec570e9b8e257647c9c74c5ad3edc57ca5ef6ae44d80b3c30d1d99b9b3", - "0x00ce48ec41d1edde0066fab553a456ae2f380d14fa8f956af1fb0217513a5989", - "0x00619ff12eaf97f63aa2a2311de3b6571a7b880a5247cb33b6a74787bf3f9bd5", - "0x007854a2fad4e1801c6404394bf3d37ab08c135ea38a1974242e39a21273685f", - "0x000f55796e72957a819e68a22e8602d73c3ba3718a5a4bd92b80b0aa444b182a", - "0x00788b6e9874fb040ee679a7fae257190099a605229b948334e54a57739535d4", - "0x004f1658ee3c1a91627e5d72f5a731f0796299df82ab41e72c88eee0c82fa85e", - "0x003ee802add96628c693ed71afa9908138ba5a6fbf0a5f29a9c74e4e42aba671", - "0x003c0472260790b0bdfb8ae4dc4d437e7686b73643f2198970d84e1059a5f135", - "0x00bfd46275a318e438726ff2765ae154b63ab8a0daebcbed668a5f58a0e63dc1", - "0x007906b9418dc758c6b4f8454c69baa48b7889b6b511d707abe8e2cb8f7c3973", - "0x00aeb60c4d65a44f122e58bf9565dfe2024b3ae654d5cf2e47ecb035d53c9270", - "0x00bf82e8cda20345f37bbb1de3932172324b57f0b98be483392697b168e3bba8", - "0x000fb4bbad884ef30edf68e45a6cf2733fcf50310c69d7c1432b29af2c0aa804", - "0x0023e1622d27fee3b4a40ab975ae0eb2e31619ef3dc76eb858f7fddb6a056131", - "0x004689cd7007daf98dd3218b839b8e6a29f957154347b391fdb376bd0b344be2", - "0x00f8029be42ec3f25204907ca981fb71e5b357093eb5db10fc01ca98a4e4154c", - "0x0030e13d351a5bf1d5a040e82a163ca57017f39162693f85c571e441e36d702d", - "0x00a550ae0f39f977d9473d6de1be3232fc68ed0c4a601d53542148695102cfc9", - "0x005580bc65e4bff9c8fffa64db02c0fa6af14d9d26fd962f4c5904cbd3ddec25", - "0x00758c4a0d43dfec788b2f580877c4f473adec8f168ea24424f2600e4eb4916f", - "0x00342602bf90d10f8ca8e582a894dcc4c02bb89fe458532e0c632b53bae54b4d", - "0x00ca43ab78ab834337e9964d84a0674c9adabdca140539c5a6bc96e0ba9a51f6", - "0x004ffbfd91be292a7c6a0e255e50caa156ac2d628b40ad2128c4ab63a92d8a1c", - "0x0099145b6c0d32753835121f8b271186d01236948a4622ce78a98347fcfc9839", - "0x0085277a27c6acbd5ffc4c19cd65fc30056999e9bec36998f753132db0ff8e23", - "0x00f3cf77a7261759ebd5f4149f6ad56746f4499cfcd4adf27a1d373f77da64d5", - "0x009bc6e0e994a23cde8c95b90c1acc1b4a480c6599d1df2c3f9f6e76f3d1aff2", - "0x00d7a1c4a2700dacaaf07f1f0ff33837bdbabcf0b9ace17efabe0761708c4bb9", - "0x00dbeb8e96d14f21e57d5786b6d6ae7e5ddb1bb35935c0fb246d4bdbca62e02c", - "0x00fbf12b5e0df6223b801088798e4e04d2a92ffe9a11639b7f0ce314e3412a80", - "0x00d796e0724de03b796ba77069fcd6cf921e566f3aed15eb3e77258add74e9ff", "0x005c015113cb57d67dd6c0febd596819ac0298b6a23fc80aba17d445d540059a", "0x00f20b7d1308051fe7b68031a7c336b0b4b56738928b6510133aff1b818d5a9a", "0x0063eec1883a4f95f4933f9275e850d84b3d035f5061ed986c437a07331fd30e", @@ -90,33 +58,35 @@ ] }, "block": { - "archive": "0x18d695c543b39ed4aebf51260b01cd023d27c36e90e2756413803fe06d376c70", - "blockHash": "0x1794217194decb456524466a01a7356e8b08b751ef0bc596431405c749627782", - "body": "0x00000008000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000000000000000000000000000004100100000000000000000000000000000000000000000000000000000000000410020000000000000000000000000000000000000000000000000000000000041003000000000000000000000000000000000000000000000000000000000004100400000000000000000000000000000000000000000000000000000000000410050000000000000000000000000000000000000000000000000000000000041006000000000000000000000000000000000000000000000000000000000004100700000000000000000000000000000000000000000000000000000000000410080000000000000000000000000000000000000000000000000000000000041009000000000000000000000000000000000000000000000000000000000004100a000000000000000000000000000000000000000000000000000000000004100b000000000000000000000000000000000000000000000000000000000004100c000000000000000000000000000000000000000000000000000000000004100d000000000000000000000000000000000000000000000000000000000004100e000000000000000000000000000000000000000000000000000000000004100f0000000000000000000000000000000000000000000000000000000000041010000000000000000000000000000000000000000000000000000000000004101100000000000000000000000000000000000000000000000000000000000410120000000000000000000000000000000000000000000000000000000000041013000000000000000000000000000000000000000000000000000000000004101400000000000000000000000000000000000000000000000000000000000410150000000000000000000000000000000000000000000000000000000000041016000000000000000000000000000000000000000000000000000000000004101700000000000000000000000000000000000000000000000000000000000410180000000000000000000000000000000000000000000000000000000000041019000000000000000000000000000000000000000000000000000000000004101a000000000000000000000000000000000000000000000000000000000004101b000000000000000000000000000000000000000000000000000000000004101c000000000000000000000000000000000000000000000000000000000004101d000000000000000000000000000000000000000000000000000000000004101e000000000000000000000000000000000000000000000000000000000004101f0000000000000000000000000000000000000000000000000000000000041020000000000000000000000000000000000000000000000000000000000004102100000000000000000000000000000000000000000000000000000000000410220000000000000000000000000000000000000000000000000000000000041023000000000000000000000000000000000000000000000000000000000004102400000000000000000000000000000000000000000000000000000000000410250000000000000000000000000000000000000000000000000000000000041026000000000000000000000000000000000000000000000000000000000004102700000000000000000000000000000000000000000000000000000000000410280000000000000000000000000000000000000000000000000000000000041029000000000000000000000000000000000000000000000000000000000004102a000000000000000000000000000000000000000000000000000000000004102b000000000000000000000000000000000000000000000000000000000004102c000000000000000000000000000000000000000000000000000000000004102d000000000000000000000000000000000000000000000000000000000004102e000000000000000000000000000000000000000000000000000000000004102f0000000000000000000000000000000000000000000000000000000000041030000000000000000000000000000000000000000000000000000000000004103100000000000000000000000000000000000000000000000000000000000410320000000000000000000000000000000000000000000000000000000000041033000000000000000000000000000000000000000000000000000000000004103400000000000000000000000000000000000000000000000000000000000410350000000000000000000000000000000000000000000000000000000000041036000000000000000000000000000000000000000000000000000000000004103700000000000000000000000000000000000000000000000000000000000410380000000000000000000000000000000000000000000000000000000000041039000000000000000000000000000000000000000000000000000000000004103a000000000000000000000000000000000000000000000000000000000004103b000000000000000000000000000000000000000000000000000000000004103c000000000000000000000000000000000000000000000000000000000004103d000000000000000000000000000000000000000000000000000000000004103e000000000000000000000000000000000000000000000000000000000004103f3f0000000000000000000000000000000000000000000000000000000000041100000000000000000000000000000000000000000000000000000000000004110100000000000000000000000000000000000000000000000000000000000411020000000000000000000000000000000000000000000000000000000000041103000000000000000000000000000000000000000000000000000000000004110400000000000000000000000000000000000000000000000000000000000411050000000000000000000000000000000000000000000000000000000000041106000000000000000000000000000000000000000000000000000000000004110700000000000000000000000000000000000000000000000000000000000411080000000000000000000000000000000000000000000000000000000000041109000000000000000000000000000000000000000000000000000000000004110a000000000000000000000000000000000000000000000000000000000004110b000000000000000000000000000000000000000000000000000000000004110c000000000000000000000000000000000000000000000000000000000004110d000000000000000000000000000000000000000000000000000000000004110e000000000000000000000000000000000000000000000000000000000004110f0000000000000000000000000000000000000000000000000000000000041110000000000000000000000000000000000000000000000000000000000004111100000000000000000000000000000000000000000000000000000000000411120000000000000000000000000000000000000000000000000000000000041113000000000000000000000000000000000000000000000000000000000004111400000000000000000000000000000000000000000000000000000000000411150000000000000000000000000000000000000000000000000000000000041116000000000000000000000000000000000000000000000000000000000004111700000000000000000000000000000000000000000000000000000000000411180000000000000000000000000000000000000000000000000000000000041119000000000000000000000000000000000000000000000000000000000004111a000000000000000000000000000000000000000000000000000000000004111b000000000000000000000000000000000000000000000000000000000004111c000000000000000000000000000000000000000000000000000000000004111d000000000000000000000000000000000000000000000000000000000004111e000000000000000000000000000000000000000000000000000000000004111f0000000000000000000000000000000000000000000000000000000000041120000000000000000000000000000000000000000000000000000000000004112100000000000000000000000000000000000000000000000000000000000411220000000000000000000000000000000000000000000000000000000000041123000000000000000000000000000000000000000000000000000000000004112400000000000000000000000000000000000000000000000000000000000411250000000000000000000000000000000000000000000000000000000000041126000000000000000000000000000000000000000000000000000000000004112700000000000000000000000000000000000000000000000000000000000411280000000000000000000000000000000000000000000000000000000000041129000000000000000000000000000000000000000000000000000000000004112a000000000000000000000000000000000000000000000000000000000004112b000000000000000000000000000000000000000000000000000000000004112c000000000000000000000000000000000000000000000000000000000004112d000000000000000000000000000000000000000000000000000000000004112e000000000000000000000000000000000000000000000000000000000004112f0000000000000000000000000000000000000000000000000000000000041130000000000000000000000000000000000000000000000000000000000004113100000000000000000000000000000000000000000000000000000000000411320000000000000000000000000000000000000000000000000000000000041133000000000000000000000000000000000000000000000000000000000004113400000000000000000000000000000000000000000000000000000000000411350000000000000000000000000000000000000000000000000000000000041136000000000000000000000000000000000000000000000000000000000004113700000000000000000000000000000000000000000000000000000000000411380000000000000000000000000000000000000000000000000000000000041139000000000000000000000000000000000000000000000000000000000004113a000000000000000000000000000000000000000000000000000000000004113b000000000000000000000000000000000000000000000000000000000004113c000000000000000000000000000000000000000000000000000000000004113d000000000000000000000000000000000000000000000000000000000004113e080097a6ec570e9b8e257647c9c74c5ad3edc57ca5ef6ae44d80b3c30d1d99b9b300ce48ec41d1edde0066fab553a456ae2f380d14fa8f956af1fb0217513a598900619ff12eaf97f63aa2a2311de3b6571a7b880a5247cb33b6a74787bf3f9bd5007854a2fad4e1801c6404394bf3d37ab08c135ea38a1974242e39a21273685f000f55796e72957a819e68a22e8602d73c3ba3718a5a4bd92b80b0aa444b182a00788b6e9874fb040ee679a7fae257190099a605229b948334e54a57739535d4004f1658ee3c1a91627e5d72f5a731f0796299df82ab41e72c88eee0c82fa85e003ee802add96628c693ed71afa9908138ba5a6fbf0a5f29a9c74e4e42aba6713f0000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000004200a0000000000000000000000000000000000000000000000000000000000042001000000000000000000000000000000000000000000000000000000000004200b0000000000000000000000000000000000000000000000000000000000042002000000000000000000000000000000000000000000000000000000000004200c0000000000000000000000000000000000000000000000000000000000042003000000000000000000000000000000000000000000000000000000000004200d0000000000000000000000000000000000000000000000000000000000042004000000000000000000000000000000000000000000000000000000000004200e0000000000000000000000000000000000000000000000000000000000042005000000000000000000000000000000000000000000000000000000000004200f00000000000000000000000000000000000000000000000000000000000420060000000000000000000000000000000000000000000000000000000000042010000000000000000000000000000000000000000000000000000000000004200700000000000000000000000000000000000000000000000000000000000420110000000000000000000000000000000000000000000000000000000000042008000000000000000000000000000000000000000000000000000000000004201200000000000000000000000000000000000000000000000000000000000420090000000000000000000000000000000000000000000000000000000000042013000000000000000000000000000000000000000000000000000000000004200a0000000000000000000000000000000000000000000000000000000000042014000000000000000000000000000000000000000000000000000000000004200b0000000000000000000000000000000000000000000000000000000000042015000000000000000000000000000000000000000000000000000000000004200c0000000000000000000000000000000000000000000000000000000000042016000000000000000000000000000000000000000000000000000000000004200d0000000000000000000000000000000000000000000000000000000000042017000000000000000000000000000000000000000000000000000000000004200e0000000000000000000000000000000000000000000000000000000000042018000000000000000000000000000000000000000000000000000000000004200f00000000000000000000000000000000000000000000000000000000000420190000000000000000000000000000000000000000000000000000000000042010000000000000000000000000000000000000000000000000000000000004201a0000000000000000000000000000000000000000000000000000000000042011000000000000000000000000000000000000000000000000000000000004201b0000000000000000000000000000000000000000000000000000000000042012000000000000000000000000000000000000000000000000000000000004201c0000000000000000000000000000000000000000000000000000000000042013000000000000000000000000000000000000000000000000000000000004201d0000000000000000000000000000000000000000000000000000000000042014000000000000000000000000000000000000000000000000000000000004201e0000000000000000000000000000000000000000000000000000000000042015000000000000000000000000000000000000000000000000000000000004201f00000000000000000000000000000000000000000000000000000000000420160000000000000000000000000000000000000000000000000000000000042020000000000000000000000000000000000000000000000000000000000004201700000000000000000000000000000000000000000000000000000000000420210000000000000000000000000000000000000000000000000000000000042018000000000000000000000000000000000000000000000000000000000004202200000000000000000000000000000000000000000000000000000000000420190000000000000000000000000000000000000000000000000000000000042023000000000000000000000000000000000000000000000000000000000004201a0000000000000000000000000000000000000000000000000000000000042024000000000000000000000000000000000000000000000000000000000004201b0000000000000000000000000000000000000000000000000000000000042025000000000000000000000000000000000000000000000000000000000004201c0000000000000000000000000000000000000000000000000000000000042026000000000000000000000000000000000000000000000000000000000004201d0000000000000000000000000000000000000000000000000000000000042027000000000000000000000000000000000000000000000000000000000004201e0000000000000000000000000000000000000000000000000000000000042028000000000000000000000000000000000000000000000000000000000004201f00000000000000000000000000000000000000000000000000000000000420290000000000000000000000000000000000000000000000000000000000042020000000000000000000000000000000000000000000000000000000000004202a0000000000000000000000000000000000000000000000000000000000042021000000000000000000000000000000000000000000000000000000000004202b0000000000000000000000000000000000000000000000000000000000042022000000000000000000000000000000000000000000000000000000000004202c0000000000000000000000000000000000000000000000000000000000042023000000000000000000000000000000000000000000000000000000000004202d0000000000000000000000000000000000000000000000000000000000042024000000000000000000000000000000000000000000000000000000000004202e0000000000000000000000000000000000000000000000000000000000042025000000000000000000000000000000000000000000000000000000000004202f00000000000000000000000000000000000000000000000000000000000420260000000000000000000000000000000000000000000000000000000000042030000000000000000000000000000000000000000000000000000000000004202700000000000000000000000000000000000000000000000000000000000420310000000000000000000000000000000000000000000000000000000000042028000000000000000000000000000000000000000000000000000000000004203200000000000000000000000000000000000000000000000000000000000420290000000000000000000000000000000000000000000000000000000000042033000000000000000000000000000000000000000000000000000000000004202a0000000000000000000000000000000000000000000000000000000000042034000000000000000000000000000000000000000000000000000000000004202b0000000000000000000000000000000000000000000000000000000000042035000000000000000000000000000000000000000000000000000000000004202c0000000000000000000000000000000000000000000000000000000000042036000000000000000000000000000000000000000000000000000000000004202d0000000000000000000000000000000000000000000000000000000000042037000000000000000000000000000000000000000000000000000000000004202e0000000000000000000000000000000000000000000000000000000000042038000000000000000000000000000000000000000000000000000000000004202f00000000000000000000000000000000000000000000000000000000000420390000000000000000000000000000000000000000000000000000000000042030000000000000000000000000000000000000000000000000000000000004203a0000000000000000000000000000000000000000000000000000000000042031000000000000000000000000000000000000000000000000000000000004203b0000000000000000000000000000000000000000000000000000000000042032000000000000000000000000000000000000000000000000000000000004203c0000000000000000000000000000000000000000000000000000000000042033000000000000000000000000000000000000000000000000000000000004203d0000000000000000000000000000000000000000000000000000000000042034000000000000000000000000000000000000000000000000000000000004203e0000000000000000000000000000000000000000000000000000000000042035000000000000000000000000000000000000000000000000000000000004203f00000000000000000000000000000000000000000000000000000000000420360000000000000000000000000000000000000000000000000000000000042040000000000000000000000000000000000000000000000000000000000004203700000000000000000000000000000000000000000000000000000000000420410000000000000000000000000000000000000000000000000000000000042038000000000000000000000000000000000000000000000000000000000004204200000000000000000000000000000000000000000000000000000000000420390000000000000000000000000000000000000000000000000000000000042043000000000000000000000000000000000000000000000000000000000004203a0000000000000000000000000000000000000000000000000000000000042044000000000000000000000000000000000000000000000000000000000004203b0000000000000000000000000000000000000000000000000000000000042045000000000000000000000000000000000000000000000000000000000004203c0000000000000000000000000000000000000000000000000000000000042046000000000000000000000000000000000000000000000000000000000004203d0000000000000000000000000000000000000000000000000000000000042047000000000000000000000000000000000000000000000000000000000004203e0000000000000000000000000000000000000000000000000000000000042048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000008100100000000000000000000000000000000000000000000000000000000000810020000000000000000000000000000000000000000000000000000000000081003000000000000000000000000000000000000000000000000000000000008100400000000000000000000000000000000000000000000000000000000000810050000000000000000000000000000000000000000000000000000000000081006000000000000000000000000000000000000000000000000000000000008100700000000000000000000000000000000000000000000000000000000000810080000000000000000000000000000000000000000000000000000000000081009000000000000000000000000000000000000000000000000000000000008100a000000000000000000000000000000000000000000000000000000000008100b000000000000000000000000000000000000000000000000000000000008100c000000000000000000000000000000000000000000000000000000000008100d000000000000000000000000000000000000000000000000000000000008100e000000000000000000000000000000000000000000000000000000000008100f0000000000000000000000000000000000000000000000000000000000081010000000000000000000000000000000000000000000000000000000000008101100000000000000000000000000000000000000000000000000000000000810120000000000000000000000000000000000000000000000000000000000081013000000000000000000000000000000000000000000000000000000000008101400000000000000000000000000000000000000000000000000000000000810150000000000000000000000000000000000000000000000000000000000081016000000000000000000000000000000000000000000000000000000000008101700000000000000000000000000000000000000000000000000000000000810180000000000000000000000000000000000000000000000000000000000081019000000000000000000000000000000000000000000000000000000000008101a000000000000000000000000000000000000000000000000000000000008101b000000000000000000000000000000000000000000000000000000000008101c000000000000000000000000000000000000000000000000000000000008101d000000000000000000000000000000000000000000000000000000000008101e000000000000000000000000000000000000000000000000000000000008101f0000000000000000000000000000000000000000000000000000000000081020000000000000000000000000000000000000000000000000000000000008102100000000000000000000000000000000000000000000000000000000000810220000000000000000000000000000000000000000000000000000000000081023000000000000000000000000000000000000000000000000000000000008102400000000000000000000000000000000000000000000000000000000000810250000000000000000000000000000000000000000000000000000000000081026000000000000000000000000000000000000000000000000000000000008102700000000000000000000000000000000000000000000000000000000000810280000000000000000000000000000000000000000000000000000000000081029000000000000000000000000000000000000000000000000000000000008102a000000000000000000000000000000000000000000000000000000000008102b000000000000000000000000000000000000000000000000000000000008102c000000000000000000000000000000000000000000000000000000000008102d000000000000000000000000000000000000000000000000000000000008102e000000000000000000000000000000000000000000000000000000000008102f0000000000000000000000000000000000000000000000000000000000081030000000000000000000000000000000000000000000000000000000000008103100000000000000000000000000000000000000000000000000000000000810320000000000000000000000000000000000000000000000000000000000081033000000000000000000000000000000000000000000000000000000000008103400000000000000000000000000000000000000000000000000000000000810350000000000000000000000000000000000000000000000000000000000081036000000000000000000000000000000000000000000000000000000000008103700000000000000000000000000000000000000000000000000000000000810380000000000000000000000000000000000000000000000000000000000081039000000000000000000000000000000000000000000000000000000000008103a000000000000000000000000000000000000000000000000000000000008103b000000000000000000000000000000000000000000000000000000000008103c000000000000000000000000000000000000000000000000000000000008103d000000000000000000000000000000000000000000000000000000000008103e000000000000000000000000000000000000000000000000000000000008103f3f0000000000000000000000000000000000000000000000000000000000081100000000000000000000000000000000000000000000000000000000000008110100000000000000000000000000000000000000000000000000000000000811020000000000000000000000000000000000000000000000000000000000081103000000000000000000000000000000000000000000000000000000000008110400000000000000000000000000000000000000000000000000000000000811050000000000000000000000000000000000000000000000000000000000081106000000000000000000000000000000000000000000000000000000000008110700000000000000000000000000000000000000000000000000000000000811080000000000000000000000000000000000000000000000000000000000081109000000000000000000000000000000000000000000000000000000000008110a000000000000000000000000000000000000000000000000000000000008110b000000000000000000000000000000000000000000000000000000000008110c000000000000000000000000000000000000000000000000000000000008110d000000000000000000000000000000000000000000000000000000000008110e000000000000000000000000000000000000000000000000000000000008110f0000000000000000000000000000000000000000000000000000000000081110000000000000000000000000000000000000000000000000000000000008111100000000000000000000000000000000000000000000000000000000000811120000000000000000000000000000000000000000000000000000000000081113000000000000000000000000000000000000000000000000000000000008111400000000000000000000000000000000000000000000000000000000000811150000000000000000000000000000000000000000000000000000000000081116000000000000000000000000000000000000000000000000000000000008111700000000000000000000000000000000000000000000000000000000000811180000000000000000000000000000000000000000000000000000000000081119000000000000000000000000000000000000000000000000000000000008111a000000000000000000000000000000000000000000000000000000000008111b000000000000000000000000000000000000000000000000000000000008111c000000000000000000000000000000000000000000000000000000000008111d000000000000000000000000000000000000000000000000000000000008111e000000000000000000000000000000000000000000000000000000000008111f0000000000000000000000000000000000000000000000000000000000081120000000000000000000000000000000000000000000000000000000000008112100000000000000000000000000000000000000000000000000000000000811220000000000000000000000000000000000000000000000000000000000081123000000000000000000000000000000000000000000000000000000000008112400000000000000000000000000000000000000000000000000000000000811250000000000000000000000000000000000000000000000000000000000081126000000000000000000000000000000000000000000000000000000000008112700000000000000000000000000000000000000000000000000000000000811280000000000000000000000000000000000000000000000000000000000081129000000000000000000000000000000000000000000000000000000000008112a000000000000000000000000000000000000000000000000000000000008112b000000000000000000000000000000000000000000000000000000000008112c000000000000000000000000000000000000000000000000000000000008112d000000000000000000000000000000000000000000000000000000000008112e000000000000000000000000000000000000000000000000000000000008112f0000000000000000000000000000000000000000000000000000000000081130000000000000000000000000000000000000000000000000000000000008113100000000000000000000000000000000000000000000000000000000000811320000000000000000000000000000000000000000000000000000000000081133000000000000000000000000000000000000000000000000000000000008113400000000000000000000000000000000000000000000000000000000000811350000000000000000000000000000000000000000000000000000000000081136000000000000000000000000000000000000000000000000000000000008113700000000000000000000000000000000000000000000000000000000000811380000000000000000000000000000000000000000000000000000000000081139000000000000000000000000000000000000000000000000000000000008113a000000000000000000000000000000000000000000000000000000000008113b000000000000000000000000000000000000000000000000000000000008113c000000000000000000000000000000000000000000000000000000000008113d000000000000000000000000000000000000000000000000000000000008113e08003c0472260790b0bdfb8ae4dc4d437e7686b73643f2198970d84e1059a5f13500bfd46275a318e438726ff2765ae154b63ab8a0daebcbed668a5f58a0e63dc1007906b9418dc758c6b4f8454c69baa48b7889b6b511d707abe8e2cb8f7c397300aeb60c4d65a44f122e58bf9565dfe2024b3ae654d5cf2e47ecb035d53c927000bf82e8cda20345f37bbb1de3932172324b57f0b98be483392697b168e3bba8000fb4bbad884ef30edf68e45a6cf2733fcf50310c69d7c1432b29af2c0aa8040023e1622d27fee3b4a40ab975ae0eb2e31619ef3dc76eb858f7fddb6a056131004689cd7007daf98dd3218b839b8e6a29f957154347b391fdb376bd0b344be23f0000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000008200a0000000000000000000000000000000000000000000000000000000000082001000000000000000000000000000000000000000000000000000000000008200b0000000000000000000000000000000000000000000000000000000000082002000000000000000000000000000000000000000000000000000000000008200c0000000000000000000000000000000000000000000000000000000000082003000000000000000000000000000000000000000000000000000000000008200d0000000000000000000000000000000000000000000000000000000000082004000000000000000000000000000000000000000000000000000000000008200e0000000000000000000000000000000000000000000000000000000000082005000000000000000000000000000000000000000000000000000000000008200f00000000000000000000000000000000000000000000000000000000000820060000000000000000000000000000000000000000000000000000000000082010000000000000000000000000000000000000000000000000000000000008200700000000000000000000000000000000000000000000000000000000000820110000000000000000000000000000000000000000000000000000000000082008000000000000000000000000000000000000000000000000000000000008201200000000000000000000000000000000000000000000000000000000000820090000000000000000000000000000000000000000000000000000000000082013000000000000000000000000000000000000000000000000000000000008200a0000000000000000000000000000000000000000000000000000000000082014000000000000000000000000000000000000000000000000000000000008200b0000000000000000000000000000000000000000000000000000000000082015000000000000000000000000000000000000000000000000000000000008200c0000000000000000000000000000000000000000000000000000000000082016000000000000000000000000000000000000000000000000000000000008200d0000000000000000000000000000000000000000000000000000000000082017000000000000000000000000000000000000000000000000000000000008200e0000000000000000000000000000000000000000000000000000000000082018000000000000000000000000000000000000000000000000000000000008200f00000000000000000000000000000000000000000000000000000000000820190000000000000000000000000000000000000000000000000000000000082010000000000000000000000000000000000000000000000000000000000008201a0000000000000000000000000000000000000000000000000000000000082011000000000000000000000000000000000000000000000000000000000008201b0000000000000000000000000000000000000000000000000000000000082012000000000000000000000000000000000000000000000000000000000008201c0000000000000000000000000000000000000000000000000000000000082013000000000000000000000000000000000000000000000000000000000008201d0000000000000000000000000000000000000000000000000000000000082014000000000000000000000000000000000000000000000000000000000008201e0000000000000000000000000000000000000000000000000000000000082015000000000000000000000000000000000000000000000000000000000008201f00000000000000000000000000000000000000000000000000000000000820160000000000000000000000000000000000000000000000000000000000082020000000000000000000000000000000000000000000000000000000000008201700000000000000000000000000000000000000000000000000000000000820210000000000000000000000000000000000000000000000000000000000082018000000000000000000000000000000000000000000000000000000000008202200000000000000000000000000000000000000000000000000000000000820190000000000000000000000000000000000000000000000000000000000082023000000000000000000000000000000000000000000000000000000000008201a0000000000000000000000000000000000000000000000000000000000082024000000000000000000000000000000000000000000000000000000000008201b0000000000000000000000000000000000000000000000000000000000082025000000000000000000000000000000000000000000000000000000000008201c0000000000000000000000000000000000000000000000000000000000082026000000000000000000000000000000000000000000000000000000000008201d0000000000000000000000000000000000000000000000000000000000082027000000000000000000000000000000000000000000000000000000000008201e0000000000000000000000000000000000000000000000000000000000082028000000000000000000000000000000000000000000000000000000000008201f00000000000000000000000000000000000000000000000000000000000820290000000000000000000000000000000000000000000000000000000000082020000000000000000000000000000000000000000000000000000000000008202a0000000000000000000000000000000000000000000000000000000000082021000000000000000000000000000000000000000000000000000000000008202b0000000000000000000000000000000000000000000000000000000000082022000000000000000000000000000000000000000000000000000000000008202c0000000000000000000000000000000000000000000000000000000000082023000000000000000000000000000000000000000000000000000000000008202d0000000000000000000000000000000000000000000000000000000000082024000000000000000000000000000000000000000000000000000000000008202e0000000000000000000000000000000000000000000000000000000000082025000000000000000000000000000000000000000000000000000000000008202f00000000000000000000000000000000000000000000000000000000000820260000000000000000000000000000000000000000000000000000000000082030000000000000000000000000000000000000000000000000000000000008202700000000000000000000000000000000000000000000000000000000000820310000000000000000000000000000000000000000000000000000000000082028000000000000000000000000000000000000000000000000000000000008203200000000000000000000000000000000000000000000000000000000000820290000000000000000000000000000000000000000000000000000000000082033000000000000000000000000000000000000000000000000000000000008202a0000000000000000000000000000000000000000000000000000000000082034000000000000000000000000000000000000000000000000000000000008202b0000000000000000000000000000000000000000000000000000000000082035000000000000000000000000000000000000000000000000000000000008202c0000000000000000000000000000000000000000000000000000000000082036000000000000000000000000000000000000000000000000000000000008202d0000000000000000000000000000000000000000000000000000000000082037000000000000000000000000000000000000000000000000000000000008202e0000000000000000000000000000000000000000000000000000000000082038000000000000000000000000000000000000000000000000000000000008202f00000000000000000000000000000000000000000000000000000000000820390000000000000000000000000000000000000000000000000000000000082030000000000000000000000000000000000000000000000000000000000008203a0000000000000000000000000000000000000000000000000000000000082031000000000000000000000000000000000000000000000000000000000008203b0000000000000000000000000000000000000000000000000000000000082032000000000000000000000000000000000000000000000000000000000008203c0000000000000000000000000000000000000000000000000000000000082033000000000000000000000000000000000000000000000000000000000008203d0000000000000000000000000000000000000000000000000000000000082034000000000000000000000000000000000000000000000000000000000008203e0000000000000000000000000000000000000000000000000000000000082035000000000000000000000000000000000000000000000000000000000008203f00000000000000000000000000000000000000000000000000000000000820360000000000000000000000000000000000000000000000000000000000082040000000000000000000000000000000000000000000000000000000000008203700000000000000000000000000000000000000000000000000000000000820410000000000000000000000000000000000000000000000000000000000082038000000000000000000000000000000000000000000000000000000000008204200000000000000000000000000000000000000000000000000000000000820390000000000000000000000000000000000000000000000000000000000082043000000000000000000000000000000000000000000000000000000000008203a0000000000000000000000000000000000000000000000000000000000082044000000000000000000000000000000000000000000000000000000000008203b0000000000000000000000000000000000000000000000000000000000082045000000000000000000000000000000000000000000000000000000000008203c0000000000000000000000000000000000000000000000000000000000082046000000000000000000000000000000000000000000000000000000000008203d0000000000000000000000000000000000000000000000000000000000082047000000000000000000000000000000000000000000000000000000000008203e00000000000000000000000000000000000000000000000000000000000820480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000c100000000000000000000000000000000000000000000000000000000000000c100100000000000000000000000000000000000000000000000000000000000c100200000000000000000000000000000000000000000000000000000000000c100300000000000000000000000000000000000000000000000000000000000c100400000000000000000000000000000000000000000000000000000000000c100500000000000000000000000000000000000000000000000000000000000c100600000000000000000000000000000000000000000000000000000000000c100700000000000000000000000000000000000000000000000000000000000c100800000000000000000000000000000000000000000000000000000000000c100900000000000000000000000000000000000000000000000000000000000c100a00000000000000000000000000000000000000000000000000000000000c100b00000000000000000000000000000000000000000000000000000000000c100c00000000000000000000000000000000000000000000000000000000000c100d00000000000000000000000000000000000000000000000000000000000c100e00000000000000000000000000000000000000000000000000000000000c100f00000000000000000000000000000000000000000000000000000000000c101000000000000000000000000000000000000000000000000000000000000c101100000000000000000000000000000000000000000000000000000000000c101200000000000000000000000000000000000000000000000000000000000c101300000000000000000000000000000000000000000000000000000000000c101400000000000000000000000000000000000000000000000000000000000c101500000000000000000000000000000000000000000000000000000000000c101600000000000000000000000000000000000000000000000000000000000c101700000000000000000000000000000000000000000000000000000000000c101800000000000000000000000000000000000000000000000000000000000c101900000000000000000000000000000000000000000000000000000000000c101a00000000000000000000000000000000000000000000000000000000000c101b00000000000000000000000000000000000000000000000000000000000c101c00000000000000000000000000000000000000000000000000000000000c101d00000000000000000000000000000000000000000000000000000000000c101e00000000000000000000000000000000000000000000000000000000000c101f00000000000000000000000000000000000000000000000000000000000c102000000000000000000000000000000000000000000000000000000000000c102100000000000000000000000000000000000000000000000000000000000c102200000000000000000000000000000000000000000000000000000000000c102300000000000000000000000000000000000000000000000000000000000c102400000000000000000000000000000000000000000000000000000000000c102500000000000000000000000000000000000000000000000000000000000c102600000000000000000000000000000000000000000000000000000000000c102700000000000000000000000000000000000000000000000000000000000c102800000000000000000000000000000000000000000000000000000000000c102900000000000000000000000000000000000000000000000000000000000c102a00000000000000000000000000000000000000000000000000000000000c102b00000000000000000000000000000000000000000000000000000000000c102c00000000000000000000000000000000000000000000000000000000000c102d00000000000000000000000000000000000000000000000000000000000c102e00000000000000000000000000000000000000000000000000000000000c102f00000000000000000000000000000000000000000000000000000000000c103000000000000000000000000000000000000000000000000000000000000c103100000000000000000000000000000000000000000000000000000000000c103200000000000000000000000000000000000000000000000000000000000c103300000000000000000000000000000000000000000000000000000000000c103400000000000000000000000000000000000000000000000000000000000c103500000000000000000000000000000000000000000000000000000000000c103600000000000000000000000000000000000000000000000000000000000c103700000000000000000000000000000000000000000000000000000000000c103800000000000000000000000000000000000000000000000000000000000c103900000000000000000000000000000000000000000000000000000000000c103a00000000000000000000000000000000000000000000000000000000000c103b00000000000000000000000000000000000000000000000000000000000c103c00000000000000000000000000000000000000000000000000000000000c103d00000000000000000000000000000000000000000000000000000000000c103e00000000000000000000000000000000000000000000000000000000000c103f3f00000000000000000000000000000000000000000000000000000000000c110000000000000000000000000000000000000000000000000000000000000c110100000000000000000000000000000000000000000000000000000000000c110200000000000000000000000000000000000000000000000000000000000c110300000000000000000000000000000000000000000000000000000000000c110400000000000000000000000000000000000000000000000000000000000c110500000000000000000000000000000000000000000000000000000000000c110600000000000000000000000000000000000000000000000000000000000c110700000000000000000000000000000000000000000000000000000000000c110800000000000000000000000000000000000000000000000000000000000c110900000000000000000000000000000000000000000000000000000000000c110a00000000000000000000000000000000000000000000000000000000000c110b00000000000000000000000000000000000000000000000000000000000c110c00000000000000000000000000000000000000000000000000000000000c110d00000000000000000000000000000000000000000000000000000000000c110e00000000000000000000000000000000000000000000000000000000000c110f00000000000000000000000000000000000000000000000000000000000c111000000000000000000000000000000000000000000000000000000000000c111100000000000000000000000000000000000000000000000000000000000c111200000000000000000000000000000000000000000000000000000000000c111300000000000000000000000000000000000000000000000000000000000c111400000000000000000000000000000000000000000000000000000000000c111500000000000000000000000000000000000000000000000000000000000c111600000000000000000000000000000000000000000000000000000000000c111700000000000000000000000000000000000000000000000000000000000c111800000000000000000000000000000000000000000000000000000000000c111900000000000000000000000000000000000000000000000000000000000c111a00000000000000000000000000000000000000000000000000000000000c111b00000000000000000000000000000000000000000000000000000000000c111c00000000000000000000000000000000000000000000000000000000000c111d00000000000000000000000000000000000000000000000000000000000c111e00000000000000000000000000000000000000000000000000000000000c111f00000000000000000000000000000000000000000000000000000000000c112000000000000000000000000000000000000000000000000000000000000c112100000000000000000000000000000000000000000000000000000000000c112200000000000000000000000000000000000000000000000000000000000c112300000000000000000000000000000000000000000000000000000000000c112400000000000000000000000000000000000000000000000000000000000c112500000000000000000000000000000000000000000000000000000000000c112600000000000000000000000000000000000000000000000000000000000c112700000000000000000000000000000000000000000000000000000000000c112800000000000000000000000000000000000000000000000000000000000c112900000000000000000000000000000000000000000000000000000000000c112a00000000000000000000000000000000000000000000000000000000000c112b00000000000000000000000000000000000000000000000000000000000c112c00000000000000000000000000000000000000000000000000000000000c112d00000000000000000000000000000000000000000000000000000000000c112e00000000000000000000000000000000000000000000000000000000000c112f00000000000000000000000000000000000000000000000000000000000c113000000000000000000000000000000000000000000000000000000000000c113100000000000000000000000000000000000000000000000000000000000c113200000000000000000000000000000000000000000000000000000000000c113300000000000000000000000000000000000000000000000000000000000c113400000000000000000000000000000000000000000000000000000000000c113500000000000000000000000000000000000000000000000000000000000c113600000000000000000000000000000000000000000000000000000000000c113700000000000000000000000000000000000000000000000000000000000c113800000000000000000000000000000000000000000000000000000000000c113900000000000000000000000000000000000000000000000000000000000c113a00000000000000000000000000000000000000000000000000000000000c113b00000000000000000000000000000000000000000000000000000000000c113c00000000000000000000000000000000000000000000000000000000000c113d00000000000000000000000000000000000000000000000000000000000c113e0800f8029be42ec3f25204907ca981fb71e5b357093eb5db10fc01ca98a4e4154c0030e13d351a5bf1d5a040e82a163ca57017f39162693f85c571e441e36d702d00a550ae0f39f977d9473d6de1be3232fc68ed0c4a601d53542148695102cfc9005580bc65e4bff9c8fffa64db02c0fa6af14d9d26fd962f4c5904cbd3ddec2500758c4a0d43dfec788b2f580877c4f473adec8f168ea24424f2600e4eb4916f00342602bf90d10f8ca8e582a894dcc4c02bb89fe458532e0c632b53bae54b4d00ca43ab78ab834337e9964d84a0674c9adabdca140539c5a6bc96e0ba9a51f6004ffbfd91be292a7c6a0e255e50caa156ac2d628b40ad2128c4ab63a92d8a1c3f00000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000c200a00000000000000000000000000000000000000000000000000000000000c200100000000000000000000000000000000000000000000000000000000000c200b00000000000000000000000000000000000000000000000000000000000c200200000000000000000000000000000000000000000000000000000000000c200c00000000000000000000000000000000000000000000000000000000000c200300000000000000000000000000000000000000000000000000000000000c200d00000000000000000000000000000000000000000000000000000000000c200400000000000000000000000000000000000000000000000000000000000c200e00000000000000000000000000000000000000000000000000000000000c200500000000000000000000000000000000000000000000000000000000000c200f00000000000000000000000000000000000000000000000000000000000c200600000000000000000000000000000000000000000000000000000000000c201000000000000000000000000000000000000000000000000000000000000c200700000000000000000000000000000000000000000000000000000000000c201100000000000000000000000000000000000000000000000000000000000c200800000000000000000000000000000000000000000000000000000000000c201200000000000000000000000000000000000000000000000000000000000c200900000000000000000000000000000000000000000000000000000000000c201300000000000000000000000000000000000000000000000000000000000c200a00000000000000000000000000000000000000000000000000000000000c201400000000000000000000000000000000000000000000000000000000000c200b00000000000000000000000000000000000000000000000000000000000c201500000000000000000000000000000000000000000000000000000000000c200c00000000000000000000000000000000000000000000000000000000000c201600000000000000000000000000000000000000000000000000000000000c200d00000000000000000000000000000000000000000000000000000000000c201700000000000000000000000000000000000000000000000000000000000c200e00000000000000000000000000000000000000000000000000000000000c201800000000000000000000000000000000000000000000000000000000000c200f00000000000000000000000000000000000000000000000000000000000c201900000000000000000000000000000000000000000000000000000000000c201000000000000000000000000000000000000000000000000000000000000c201a00000000000000000000000000000000000000000000000000000000000c201100000000000000000000000000000000000000000000000000000000000c201b00000000000000000000000000000000000000000000000000000000000c201200000000000000000000000000000000000000000000000000000000000c201c00000000000000000000000000000000000000000000000000000000000c201300000000000000000000000000000000000000000000000000000000000c201d00000000000000000000000000000000000000000000000000000000000c201400000000000000000000000000000000000000000000000000000000000c201e00000000000000000000000000000000000000000000000000000000000c201500000000000000000000000000000000000000000000000000000000000c201f00000000000000000000000000000000000000000000000000000000000c201600000000000000000000000000000000000000000000000000000000000c202000000000000000000000000000000000000000000000000000000000000c201700000000000000000000000000000000000000000000000000000000000c202100000000000000000000000000000000000000000000000000000000000c201800000000000000000000000000000000000000000000000000000000000c202200000000000000000000000000000000000000000000000000000000000c201900000000000000000000000000000000000000000000000000000000000c202300000000000000000000000000000000000000000000000000000000000c201a00000000000000000000000000000000000000000000000000000000000c202400000000000000000000000000000000000000000000000000000000000c201b00000000000000000000000000000000000000000000000000000000000c202500000000000000000000000000000000000000000000000000000000000c201c00000000000000000000000000000000000000000000000000000000000c202600000000000000000000000000000000000000000000000000000000000c201d00000000000000000000000000000000000000000000000000000000000c202700000000000000000000000000000000000000000000000000000000000c201e00000000000000000000000000000000000000000000000000000000000c202800000000000000000000000000000000000000000000000000000000000c201f00000000000000000000000000000000000000000000000000000000000c202900000000000000000000000000000000000000000000000000000000000c202000000000000000000000000000000000000000000000000000000000000c202a00000000000000000000000000000000000000000000000000000000000c202100000000000000000000000000000000000000000000000000000000000c202b00000000000000000000000000000000000000000000000000000000000c202200000000000000000000000000000000000000000000000000000000000c202c00000000000000000000000000000000000000000000000000000000000c202300000000000000000000000000000000000000000000000000000000000c202d00000000000000000000000000000000000000000000000000000000000c202400000000000000000000000000000000000000000000000000000000000c202e00000000000000000000000000000000000000000000000000000000000c202500000000000000000000000000000000000000000000000000000000000c202f00000000000000000000000000000000000000000000000000000000000c202600000000000000000000000000000000000000000000000000000000000c203000000000000000000000000000000000000000000000000000000000000c202700000000000000000000000000000000000000000000000000000000000c203100000000000000000000000000000000000000000000000000000000000c202800000000000000000000000000000000000000000000000000000000000c203200000000000000000000000000000000000000000000000000000000000c202900000000000000000000000000000000000000000000000000000000000c203300000000000000000000000000000000000000000000000000000000000c202a00000000000000000000000000000000000000000000000000000000000c203400000000000000000000000000000000000000000000000000000000000c202b00000000000000000000000000000000000000000000000000000000000c203500000000000000000000000000000000000000000000000000000000000c202c00000000000000000000000000000000000000000000000000000000000c203600000000000000000000000000000000000000000000000000000000000c202d00000000000000000000000000000000000000000000000000000000000c203700000000000000000000000000000000000000000000000000000000000c202e00000000000000000000000000000000000000000000000000000000000c203800000000000000000000000000000000000000000000000000000000000c202f00000000000000000000000000000000000000000000000000000000000c203900000000000000000000000000000000000000000000000000000000000c203000000000000000000000000000000000000000000000000000000000000c203a00000000000000000000000000000000000000000000000000000000000c203100000000000000000000000000000000000000000000000000000000000c203b00000000000000000000000000000000000000000000000000000000000c203200000000000000000000000000000000000000000000000000000000000c203c00000000000000000000000000000000000000000000000000000000000c203300000000000000000000000000000000000000000000000000000000000c203d00000000000000000000000000000000000000000000000000000000000c203400000000000000000000000000000000000000000000000000000000000c203e00000000000000000000000000000000000000000000000000000000000c203500000000000000000000000000000000000000000000000000000000000c203f00000000000000000000000000000000000000000000000000000000000c203600000000000000000000000000000000000000000000000000000000000c204000000000000000000000000000000000000000000000000000000000000c203700000000000000000000000000000000000000000000000000000000000c204100000000000000000000000000000000000000000000000000000000000c203800000000000000000000000000000000000000000000000000000000000c204200000000000000000000000000000000000000000000000000000000000c203900000000000000000000000000000000000000000000000000000000000c204300000000000000000000000000000000000000000000000000000000000c203a00000000000000000000000000000000000000000000000000000000000c204400000000000000000000000000000000000000000000000000000000000c203b00000000000000000000000000000000000000000000000000000000000c204500000000000000000000000000000000000000000000000000000000000c203c00000000000000000000000000000000000000000000000000000000000c204600000000000000000000000000000000000000000000000000000000000c203d00000000000000000000000000000000000000000000000000000000000c204700000000000000000000000000000000000000000000000000000000000c203e00000000000000000000000000000000000000000000000000000000000c2048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000101000000000000000000000000000000000000000000000000000000000000010100100000000000000000000000000000000000000000000000000000000001010020000000000000000000000000000000000000000000000000000000000101003000000000000000000000000000000000000000000000000000000000010100400000000000000000000000000000000000000000000000000000000001010050000000000000000000000000000000000000000000000000000000000101006000000000000000000000000000000000000000000000000000000000010100700000000000000000000000000000000000000000000000000000000001010080000000000000000000000000000000000000000000000000000000000101009000000000000000000000000000000000000000000000000000000000010100a000000000000000000000000000000000000000000000000000000000010100b000000000000000000000000000000000000000000000000000000000010100c000000000000000000000000000000000000000000000000000000000010100d000000000000000000000000000000000000000000000000000000000010100e000000000000000000000000000000000000000000000000000000000010100f0000000000000000000000000000000000000000000000000000000000101010000000000000000000000000000000000000000000000000000000000010101100000000000000000000000000000000000000000000000000000000001010120000000000000000000000000000000000000000000000000000000000101013000000000000000000000000000000000000000000000000000000000010101400000000000000000000000000000000000000000000000000000000001010150000000000000000000000000000000000000000000000000000000000101016000000000000000000000000000000000000000000000000000000000010101700000000000000000000000000000000000000000000000000000000001010180000000000000000000000000000000000000000000000000000000000101019000000000000000000000000000000000000000000000000000000000010101a000000000000000000000000000000000000000000000000000000000010101b000000000000000000000000000000000000000000000000000000000010101c000000000000000000000000000000000000000000000000000000000010101d000000000000000000000000000000000000000000000000000000000010101e000000000000000000000000000000000000000000000000000000000010101f0000000000000000000000000000000000000000000000000000000000101020000000000000000000000000000000000000000000000000000000000010102100000000000000000000000000000000000000000000000000000000001010220000000000000000000000000000000000000000000000000000000000101023000000000000000000000000000000000000000000000000000000000010102400000000000000000000000000000000000000000000000000000000001010250000000000000000000000000000000000000000000000000000000000101026000000000000000000000000000000000000000000000000000000000010102700000000000000000000000000000000000000000000000000000000001010280000000000000000000000000000000000000000000000000000000000101029000000000000000000000000000000000000000000000000000000000010102a000000000000000000000000000000000000000000000000000000000010102b000000000000000000000000000000000000000000000000000000000010102c000000000000000000000000000000000000000000000000000000000010102d000000000000000000000000000000000000000000000000000000000010102e000000000000000000000000000000000000000000000000000000000010102f0000000000000000000000000000000000000000000000000000000000101030000000000000000000000000000000000000000000000000000000000010103100000000000000000000000000000000000000000000000000000000001010320000000000000000000000000000000000000000000000000000000000101033000000000000000000000000000000000000000000000000000000000010103400000000000000000000000000000000000000000000000000000000001010350000000000000000000000000000000000000000000000000000000000101036000000000000000000000000000000000000000000000000000000000010103700000000000000000000000000000000000000000000000000000000001010380000000000000000000000000000000000000000000000000000000000101039000000000000000000000000000000000000000000000000000000000010103a000000000000000000000000000000000000000000000000000000000010103b000000000000000000000000000000000000000000000000000000000010103c000000000000000000000000000000000000000000000000000000000010103d000000000000000000000000000000000000000000000000000000000010103e000000000000000000000000000000000000000000000000000000000010103f3f0000000000000000000000000000000000000000000000000000000000101100000000000000000000000000000000000000000000000000000000000010110100000000000000000000000000000000000000000000000000000000001011020000000000000000000000000000000000000000000000000000000000101103000000000000000000000000000000000000000000000000000000000010110400000000000000000000000000000000000000000000000000000000001011050000000000000000000000000000000000000000000000000000000000101106000000000000000000000000000000000000000000000000000000000010110700000000000000000000000000000000000000000000000000000000001011080000000000000000000000000000000000000000000000000000000000101109000000000000000000000000000000000000000000000000000000000010110a000000000000000000000000000000000000000000000000000000000010110b000000000000000000000000000000000000000000000000000000000010110c000000000000000000000000000000000000000000000000000000000010110d000000000000000000000000000000000000000000000000000000000010110e000000000000000000000000000000000000000000000000000000000010110f0000000000000000000000000000000000000000000000000000000000101110000000000000000000000000000000000000000000000000000000000010111100000000000000000000000000000000000000000000000000000000001011120000000000000000000000000000000000000000000000000000000000101113000000000000000000000000000000000000000000000000000000000010111400000000000000000000000000000000000000000000000000000000001011150000000000000000000000000000000000000000000000000000000000101116000000000000000000000000000000000000000000000000000000000010111700000000000000000000000000000000000000000000000000000000001011180000000000000000000000000000000000000000000000000000000000101119000000000000000000000000000000000000000000000000000000000010111a000000000000000000000000000000000000000000000000000000000010111b000000000000000000000000000000000000000000000000000000000010111c000000000000000000000000000000000000000000000000000000000010111d000000000000000000000000000000000000000000000000000000000010111e000000000000000000000000000000000000000000000000000000000010111f0000000000000000000000000000000000000000000000000000000000101120000000000000000000000000000000000000000000000000000000000010112100000000000000000000000000000000000000000000000000000000001011220000000000000000000000000000000000000000000000000000000000101123000000000000000000000000000000000000000000000000000000000010112400000000000000000000000000000000000000000000000000000000001011250000000000000000000000000000000000000000000000000000000000101126000000000000000000000000000000000000000000000000000000000010112700000000000000000000000000000000000000000000000000000000001011280000000000000000000000000000000000000000000000000000000000101129000000000000000000000000000000000000000000000000000000000010112a000000000000000000000000000000000000000000000000000000000010112b000000000000000000000000000000000000000000000000000000000010112c000000000000000000000000000000000000000000000000000000000010112d000000000000000000000000000000000000000000000000000000000010112e000000000000000000000000000000000000000000000000000000000010112f0000000000000000000000000000000000000000000000000000000000101130000000000000000000000000000000000000000000000000000000000010113100000000000000000000000000000000000000000000000000000000001011320000000000000000000000000000000000000000000000000000000000101133000000000000000000000000000000000000000000000000000000000010113400000000000000000000000000000000000000000000000000000000001011350000000000000000000000000000000000000000000000000000000000101136000000000000000000000000000000000000000000000000000000000010113700000000000000000000000000000000000000000000000000000000001011380000000000000000000000000000000000000000000000000000000000101139000000000000000000000000000000000000000000000000000000000010113a000000000000000000000000000000000000000000000000000000000010113b000000000000000000000000000000000000000000000000000000000010113c000000000000000000000000000000000000000000000000000000000010113d000000000000000000000000000000000000000000000000000000000010113e080099145b6c0d32753835121f8b271186d01236948a4622ce78a98347fcfc98390085277a27c6acbd5ffc4c19cd65fc30056999e9bec36998f753132db0ff8e2300f3cf77a7261759ebd5f4149f6ad56746f4499cfcd4adf27a1d373f77da64d5009bc6e0e994a23cde8c95b90c1acc1b4a480c6599d1df2c3f9f6e76f3d1aff200d7a1c4a2700dacaaf07f1f0ff33837bdbabcf0b9ace17efabe0761708c4bb900dbeb8e96d14f21e57d5786b6d6ae7e5ddb1bb35935c0fb246d4bdbca62e02c00fbf12b5e0df6223b801088798e4e04d2a92ffe9a11639b7f0ce314e3412a8000d796e0724de03b796ba77069fcd6cf921e566f3aed15eb3e77258add74e9ff3f0000000000000000000000000000000000000000000000000000000000102000000000000000000000000000000000000000000000000000000000000010200a0000000000000000000000000000000000000000000000000000000000102001000000000000000000000000000000000000000000000000000000000010200b0000000000000000000000000000000000000000000000000000000000102002000000000000000000000000000000000000000000000000000000000010200c0000000000000000000000000000000000000000000000000000000000102003000000000000000000000000000000000000000000000000000000000010200d0000000000000000000000000000000000000000000000000000000000102004000000000000000000000000000000000000000000000000000000000010200e0000000000000000000000000000000000000000000000000000000000102005000000000000000000000000000000000000000000000000000000000010200f00000000000000000000000000000000000000000000000000000000001020060000000000000000000000000000000000000000000000000000000000102010000000000000000000000000000000000000000000000000000000000010200700000000000000000000000000000000000000000000000000000000001020110000000000000000000000000000000000000000000000000000000000102008000000000000000000000000000000000000000000000000000000000010201200000000000000000000000000000000000000000000000000000000001020090000000000000000000000000000000000000000000000000000000000102013000000000000000000000000000000000000000000000000000000000010200a0000000000000000000000000000000000000000000000000000000000102014000000000000000000000000000000000000000000000000000000000010200b0000000000000000000000000000000000000000000000000000000000102015000000000000000000000000000000000000000000000000000000000010200c0000000000000000000000000000000000000000000000000000000000102016000000000000000000000000000000000000000000000000000000000010200d0000000000000000000000000000000000000000000000000000000000102017000000000000000000000000000000000000000000000000000000000010200e0000000000000000000000000000000000000000000000000000000000102018000000000000000000000000000000000000000000000000000000000010200f00000000000000000000000000000000000000000000000000000000001020190000000000000000000000000000000000000000000000000000000000102010000000000000000000000000000000000000000000000000000000000010201a0000000000000000000000000000000000000000000000000000000000102011000000000000000000000000000000000000000000000000000000000010201b0000000000000000000000000000000000000000000000000000000000102012000000000000000000000000000000000000000000000000000000000010201c0000000000000000000000000000000000000000000000000000000000102013000000000000000000000000000000000000000000000000000000000010201d0000000000000000000000000000000000000000000000000000000000102014000000000000000000000000000000000000000000000000000000000010201e0000000000000000000000000000000000000000000000000000000000102015000000000000000000000000000000000000000000000000000000000010201f00000000000000000000000000000000000000000000000000000000001020160000000000000000000000000000000000000000000000000000000000102020000000000000000000000000000000000000000000000000000000000010201700000000000000000000000000000000000000000000000000000000001020210000000000000000000000000000000000000000000000000000000000102018000000000000000000000000000000000000000000000000000000000010202200000000000000000000000000000000000000000000000000000000001020190000000000000000000000000000000000000000000000000000000000102023000000000000000000000000000000000000000000000000000000000010201a0000000000000000000000000000000000000000000000000000000000102024000000000000000000000000000000000000000000000000000000000010201b0000000000000000000000000000000000000000000000000000000000102025000000000000000000000000000000000000000000000000000000000010201c0000000000000000000000000000000000000000000000000000000000102026000000000000000000000000000000000000000000000000000000000010201d0000000000000000000000000000000000000000000000000000000000102027000000000000000000000000000000000000000000000000000000000010201e0000000000000000000000000000000000000000000000000000000000102028000000000000000000000000000000000000000000000000000000000010201f00000000000000000000000000000000000000000000000000000000001020290000000000000000000000000000000000000000000000000000000000102020000000000000000000000000000000000000000000000000000000000010202a0000000000000000000000000000000000000000000000000000000000102021000000000000000000000000000000000000000000000000000000000010202b0000000000000000000000000000000000000000000000000000000000102022000000000000000000000000000000000000000000000000000000000010202c0000000000000000000000000000000000000000000000000000000000102023000000000000000000000000000000000000000000000000000000000010202d0000000000000000000000000000000000000000000000000000000000102024000000000000000000000000000000000000000000000000000000000010202e0000000000000000000000000000000000000000000000000000000000102025000000000000000000000000000000000000000000000000000000000010202f00000000000000000000000000000000000000000000000000000000001020260000000000000000000000000000000000000000000000000000000000102030000000000000000000000000000000000000000000000000000000000010202700000000000000000000000000000000000000000000000000000000001020310000000000000000000000000000000000000000000000000000000000102028000000000000000000000000000000000000000000000000000000000010203200000000000000000000000000000000000000000000000000000000001020290000000000000000000000000000000000000000000000000000000000102033000000000000000000000000000000000000000000000000000000000010202a0000000000000000000000000000000000000000000000000000000000102034000000000000000000000000000000000000000000000000000000000010202b0000000000000000000000000000000000000000000000000000000000102035000000000000000000000000000000000000000000000000000000000010202c0000000000000000000000000000000000000000000000000000000000102036000000000000000000000000000000000000000000000000000000000010202d0000000000000000000000000000000000000000000000000000000000102037000000000000000000000000000000000000000000000000000000000010202e0000000000000000000000000000000000000000000000000000000000102038000000000000000000000000000000000000000000000000000000000010202f00000000000000000000000000000000000000000000000000000000001020390000000000000000000000000000000000000000000000000000000000102030000000000000000000000000000000000000000000000000000000000010203a0000000000000000000000000000000000000000000000000000000000102031000000000000000000000000000000000000000000000000000000000010203b0000000000000000000000000000000000000000000000000000000000102032000000000000000000000000000000000000000000000000000000000010203c0000000000000000000000000000000000000000000000000000000000102033000000000000000000000000000000000000000000000000000000000010203d0000000000000000000000000000000000000000000000000000000000102034000000000000000000000000000000000000000000000000000000000010203e0000000000000000000000000000000000000000000000000000000000102035000000000000000000000000000000000000000000000000000000000010203f00000000000000000000000000000000000000000000000000000000001020360000000000000000000000000000000000000000000000000000000000102040000000000000000000000000000000000000000000000000000000000010203700000000000000000000000000000000000000000000000000000000001020410000000000000000000000000000000000000000000000000000000000102038000000000000000000000000000000000000000000000000000000000010204200000000000000000000000000000000000000000000000000000000001020390000000000000000000000000000000000000000000000000000000000102043000000000000000000000000000000000000000000000000000000000010203a0000000000000000000000000000000000000000000000000000000000102044000000000000000000000000000000000000000000000000000000000010203b0000000000000000000000000000000000000000000000000000000000102045000000000000000000000000000000000000000000000000000000000010203c0000000000000000000000000000000000000000000000000000000000102046000000000000000000000000000000000000000000000000000000000010203d0000000000000000000000000000000000000000000000000000000000102047000000000000000000000000000000000000000000000000000000000010203e0000000000000000000000000000000000000000000000000000000000102048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000141000000000000000000000000000000000000000000000000000000000000014100100000000000000000000000000000000000000000000000000000000001410020000000000000000000000000000000000000000000000000000000000141003000000000000000000000000000000000000000000000000000000000014100400000000000000000000000000000000000000000000000000000000001410050000000000000000000000000000000000000000000000000000000000141006000000000000000000000000000000000000000000000000000000000014100700000000000000000000000000000000000000000000000000000000001410080000000000000000000000000000000000000000000000000000000000141009000000000000000000000000000000000000000000000000000000000014100a000000000000000000000000000000000000000000000000000000000014100b000000000000000000000000000000000000000000000000000000000014100c000000000000000000000000000000000000000000000000000000000014100d000000000000000000000000000000000000000000000000000000000014100e000000000000000000000000000000000000000000000000000000000014100f0000000000000000000000000000000000000000000000000000000000141010000000000000000000000000000000000000000000000000000000000014101100000000000000000000000000000000000000000000000000000000001410120000000000000000000000000000000000000000000000000000000000141013000000000000000000000000000000000000000000000000000000000014101400000000000000000000000000000000000000000000000000000000001410150000000000000000000000000000000000000000000000000000000000141016000000000000000000000000000000000000000000000000000000000014101700000000000000000000000000000000000000000000000000000000001410180000000000000000000000000000000000000000000000000000000000141019000000000000000000000000000000000000000000000000000000000014101a000000000000000000000000000000000000000000000000000000000014101b000000000000000000000000000000000000000000000000000000000014101c000000000000000000000000000000000000000000000000000000000014101d000000000000000000000000000000000000000000000000000000000014101e000000000000000000000000000000000000000000000000000000000014101f0000000000000000000000000000000000000000000000000000000000141020000000000000000000000000000000000000000000000000000000000014102100000000000000000000000000000000000000000000000000000000001410220000000000000000000000000000000000000000000000000000000000141023000000000000000000000000000000000000000000000000000000000014102400000000000000000000000000000000000000000000000000000000001410250000000000000000000000000000000000000000000000000000000000141026000000000000000000000000000000000000000000000000000000000014102700000000000000000000000000000000000000000000000000000000001410280000000000000000000000000000000000000000000000000000000000141029000000000000000000000000000000000000000000000000000000000014102a000000000000000000000000000000000000000000000000000000000014102b000000000000000000000000000000000000000000000000000000000014102c000000000000000000000000000000000000000000000000000000000014102d000000000000000000000000000000000000000000000000000000000014102e000000000000000000000000000000000000000000000000000000000014102f0000000000000000000000000000000000000000000000000000000000141030000000000000000000000000000000000000000000000000000000000014103100000000000000000000000000000000000000000000000000000000001410320000000000000000000000000000000000000000000000000000000000141033000000000000000000000000000000000000000000000000000000000014103400000000000000000000000000000000000000000000000000000000001410350000000000000000000000000000000000000000000000000000000000141036000000000000000000000000000000000000000000000000000000000014103700000000000000000000000000000000000000000000000000000000001410380000000000000000000000000000000000000000000000000000000000141039000000000000000000000000000000000000000000000000000000000014103a000000000000000000000000000000000000000000000000000000000014103b000000000000000000000000000000000000000000000000000000000014103c000000000000000000000000000000000000000000000000000000000014103d000000000000000000000000000000000000000000000000000000000014103e000000000000000000000000000000000000000000000000000000000014103f3f0000000000000000000000000000000000000000000000000000000000141100000000000000000000000000000000000000000000000000000000000014110100000000000000000000000000000000000000000000000000000000001411020000000000000000000000000000000000000000000000000000000000141103000000000000000000000000000000000000000000000000000000000014110400000000000000000000000000000000000000000000000000000000001411050000000000000000000000000000000000000000000000000000000000141106000000000000000000000000000000000000000000000000000000000014110700000000000000000000000000000000000000000000000000000000001411080000000000000000000000000000000000000000000000000000000000141109000000000000000000000000000000000000000000000000000000000014110a000000000000000000000000000000000000000000000000000000000014110b000000000000000000000000000000000000000000000000000000000014110c000000000000000000000000000000000000000000000000000000000014110d000000000000000000000000000000000000000000000000000000000014110e000000000000000000000000000000000000000000000000000000000014110f0000000000000000000000000000000000000000000000000000000000141110000000000000000000000000000000000000000000000000000000000014111100000000000000000000000000000000000000000000000000000000001411120000000000000000000000000000000000000000000000000000000000141113000000000000000000000000000000000000000000000000000000000014111400000000000000000000000000000000000000000000000000000000001411150000000000000000000000000000000000000000000000000000000000141116000000000000000000000000000000000000000000000000000000000014111700000000000000000000000000000000000000000000000000000000001411180000000000000000000000000000000000000000000000000000000000141119000000000000000000000000000000000000000000000000000000000014111a000000000000000000000000000000000000000000000000000000000014111b000000000000000000000000000000000000000000000000000000000014111c000000000000000000000000000000000000000000000000000000000014111d000000000000000000000000000000000000000000000000000000000014111e000000000000000000000000000000000000000000000000000000000014111f0000000000000000000000000000000000000000000000000000000000141120000000000000000000000000000000000000000000000000000000000014112100000000000000000000000000000000000000000000000000000000001411220000000000000000000000000000000000000000000000000000000000141123000000000000000000000000000000000000000000000000000000000014112400000000000000000000000000000000000000000000000000000000001411250000000000000000000000000000000000000000000000000000000000141126000000000000000000000000000000000000000000000000000000000014112700000000000000000000000000000000000000000000000000000000001411280000000000000000000000000000000000000000000000000000000000141129000000000000000000000000000000000000000000000000000000000014112a000000000000000000000000000000000000000000000000000000000014112b000000000000000000000000000000000000000000000000000000000014112c000000000000000000000000000000000000000000000000000000000014112d000000000000000000000000000000000000000000000000000000000014112e000000000000000000000000000000000000000000000000000000000014112f0000000000000000000000000000000000000000000000000000000000141130000000000000000000000000000000000000000000000000000000000014113100000000000000000000000000000000000000000000000000000000001411320000000000000000000000000000000000000000000000000000000000141133000000000000000000000000000000000000000000000000000000000014113400000000000000000000000000000000000000000000000000000000001411350000000000000000000000000000000000000000000000000000000000141136000000000000000000000000000000000000000000000000000000000014113700000000000000000000000000000000000000000000000000000000001411380000000000000000000000000000000000000000000000000000000000141139000000000000000000000000000000000000000000000000000000000014113a000000000000000000000000000000000000000000000000000000000014113b000000000000000000000000000000000000000000000000000000000014113c000000000000000000000000000000000000000000000000000000000014113d000000000000000000000000000000000000000000000000000000000014113e08005c015113cb57d67dd6c0febd596819ac0298b6a23fc80aba17d445d540059a00f20b7d1308051fe7b68031a7c336b0b4b56738928b6510133aff1b818d5a9a0063eec1883a4f95f4933f9275e850d84b3d035f5061ed986c437a07331fd30e00d3a32d6bbc4fd843686fd0c5e118a73b847529977dca5b9e0e81f6604f22ca00c2f4f5133d9194d41e853e5e951e16690babce8461f25342c0bad20f2aa1e3000a6bf4739e7eb387913d955dc2e8f14f8cce27696b9d2e128b6acefafb80ee005763f7e0648f958b559677622a648f318fc79ebc0cb539170d49c26456e69200302e2b8a92cda941e9af8761b89899a58a587656d9710594e1d865b16522993f0000000000000000000000000000000000000000000000000000000000142000000000000000000000000000000000000000000000000000000000000014200a0000000000000000000000000000000000000000000000000000000000142001000000000000000000000000000000000000000000000000000000000014200b0000000000000000000000000000000000000000000000000000000000142002000000000000000000000000000000000000000000000000000000000014200c0000000000000000000000000000000000000000000000000000000000142003000000000000000000000000000000000000000000000000000000000014200d0000000000000000000000000000000000000000000000000000000000142004000000000000000000000000000000000000000000000000000000000014200e0000000000000000000000000000000000000000000000000000000000142005000000000000000000000000000000000000000000000000000000000014200f00000000000000000000000000000000000000000000000000000000001420060000000000000000000000000000000000000000000000000000000000142010000000000000000000000000000000000000000000000000000000000014200700000000000000000000000000000000000000000000000000000000001420110000000000000000000000000000000000000000000000000000000000142008000000000000000000000000000000000000000000000000000000000014201200000000000000000000000000000000000000000000000000000000001420090000000000000000000000000000000000000000000000000000000000142013000000000000000000000000000000000000000000000000000000000014200a0000000000000000000000000000000000000000000000000000000000142014000000000000000000000000000000000000000000000000000000000014200b0000000000000000000000000000000000000000000000000000000000142015000000000000000000000000000000000000000000000000000000000014200c0000000000000000000000000000000000000000000000000000000000142016000000000000000000000000000000000000000000000000000000000014200d0000000000000000000000000000000000000000000000000000000000142017000000000000000000000000000000000000000000000000000000000014200e0000000000000000000000000000000000000000000000000000000000142018000000000000000000000000000000000000000000000000000000000014200f00000000000000000000000000000000000000000000000000000000001420190000000000000000000000000000000000000000000000000000000000142010000000000000000000000000000000000000000000000000000000000014201a0000000000000000000000000000000000000000000000000000000000142011000000000000000000000000000000000000000000000000000000000014201b0000000000000000000000000000000000000000000000000000000000142012000000000000000000000000000000000000000000000000000000000014201c0000000000000000000000000000000000000000000000000000000000142013000000000000000000000000000000000000000000000000000000000014201d0000000000000000000000000000000000000000000000000000000000142014000000000000000000000000000000000000000000000000000000000014201e0000000000000000000000000000000000000000000000000000000000142015000000000000000000000000000000000000000000000000000000000014201f00000000000000000000000000000000000000000000000000000000001420160000000000000000000000000000000000000000000000000000000000142020000000000000000000000000000000000000000000000000000000000014201700000000000000000000000000000000000000000000000000000000001420210000000000000000000000000000000000000000000000000000000000142018000000000000000000000000000000000000000000000000000000000014202200000000000000000000000000000000000000000000000000000000001420190000000000000000000000000000000000000000000000000000000000142023000000000000000000000000000000000000000000000000000000000014201a0000000000000000000000000000000000000000000000000000000000142024000000000000000000000000000000000000000000000000000000000014201b0000000000000000000000000000000000000000000000000000000000142025000000000000000000000000000000000000000000000000000000000014201c0000000000000000000000000000000000000000000000000000000000142026000000000000000000000000000000000000000000000000000000000014201d0000000000000000000000000000000000000000000000000000000000142027000000000000000000000000000000000000000000000000000000000014201e0000000000000000000000000000000000000000000000000000000000142028000000000000000000000000000000000000000000000000000000000014201f00000000000000000000000000000000000000000000000000000000001420290000000000000000000000000000000000000000000000000000000000142020000000000000000000000000000000000000000000000000000000000014202a0000000000000000000000000000000000000000000000000000000000142021000000000000000000000000000000000000000000000000000000000014202b0000000000000000000000000000000000000000000000000000000000142022000000000000000000000000000000000000000000000000000000000014202c0000000000000000000000000000000000000000000000000000000000142023000000000000000000000000000000000000000000000000000000000014202d0000000000000000000000000000000000000000000000000000000000142024000000000000000000000000000000000000000000000000000000000014202e0000000000000000000000000000000000000000000000000000000000142025000000000000000000000000000000000000000000000000000000000014202f00000000000000000000000000000000000000000000000000000000001420260000000000000000000000000000000000000000000000000000000000142030000000000000000000000000000000000000000000000000000000000014202700000000000000000000000000000000000000000000000000000000001420310000000000000000000000000000000000000000000000000000000000142028000000000000000000000000000000000000000000000000000000000014203200000000000000000000000000000000000000000000000000000000001420290000000000000000000000000000000000000000000000000000000000142033000000000000000000000000000000000000000000000000000000000014202a0000000000000000000000000000000000000000000000000000000000142034000000000000000000000000000000000000000000000000000000000014202b0000000000000000000000000000000000000000000000000000000000142035000000000000000000000000000000000000000000000000000000000014202c0000000000000000000000000000000000000000000000000000000000142036000000000000000000000000000000000000000000000000000000000014202d0000000000000000000000000000000000000000000000000000000000142037000000000000000000000000000000000000000000000000000000000014202e0000000000000000000000000000000000000000000000000000000000142038000000000000000000000000000000000000000000000000000000000014202f00000000000000000000000000000000000000000000000000000000001420390000000000000000000000000000000000000000000000000000000000142030000000000000000000000000000000000000000000000000000000000014203a0000000000000000000000000000000000000000000000000000000000142031000000000000000000000000000000000000000000000000000000000014203b0000000000000000000000000000000000000000000000000000000000142032000000000000000000000000000000000000000000000000000000000014203c0000000000000000000000000000000000000000000000000000000000142033000000000000000000000000000000000000000000000000000000000014203d0000000000000000000000000000000000000000000000000000000000142034000000000000000000000000000000000000000000000000000000000014203e0000000000000000000000000000000000000000000000000000000000142035000000000000000000000000000000000000000000000000000000000014203f00000000000000000000000000000000000000000000000000000000001420360000000000000000000000000000000000000000000000000000000000142040000000000000000000000000000000000000000000000000000000000014203700000000000000000000000000000000000000000000000000000000001420410000000000000000000000000000000000000000000000000000000000142038000000000000000000000000000000000000000000000000000000000014204200000000000000000000000000000000000000000000000000000000001420390000000000000000000000000000000000000000000000000000000000142043000000000000000000000000000000000000000000000000000000000014203a0000000000000000000000000000000000000000000000000000000000142044000000000000000000000000000000000000000000000000000000000014203b0000000000000000000000000000000000000000000000000000000000142045000000000000000000000000000000000000000000000000000000000014203c0000000000000000000000000000000000000000000000000000000000142046000000000000000000000000000000000000000000000000000000000014203d0000000000000000000000000000000000000000000000000000000000142047000000000000000000000000000000000000000000000000000000000014203e0000000000000000000000000000000000000000000000000000000000142048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000181000000000000000000000000000000000000000000000000000000000000018100100000000000000000000000000000000000000000000000000000000001810020000000000000000000000000000000000000000000000000000000000181003000000000000000000000000000000000000000000000000000000000018100400000000000000000000000000000000000000000000000000000000001810050000000000000000000000000000000000000000000000000000000000181006000000000000000000000000000000000000000000000000000000000018100700000000000000000000000000000000000000000000000000000000001810080000000000000000000000000000000000000000000000000000000000181009000000000000000000000000000000000000000000000000000000000018100a000000000000000000000000000000000000000000000000000000000018100b000000000000000000000000000000000000000000000000000000000018100c000000000000000000000000000000000000000000000000000000000018100d000000000000000000000000000000000000000000000000000000000018100e000000000000000000000000000000000000000000000000000000000018100f0000000000000000000000000000000000000000000000000000000000181010000000000000000000000000000000000000000000000000000000000018101100000000000000000000000000000000000000000000000000000000001810120000000000000000000000000000000000000000000000000000000000181013000000000000000000000000000000000000000000000000000000000018101400000000000000000000000000000000000000000000000000000000001810150000000000000000000000000000000000000000000000000000000000181016000000000000000000000000000000000000000000000000000000000018101700000000000000000000000000000000000000000000000000000000001810180000000000000000000000000000000000000000000000000000000000181019000000000000000000000000000000000000000000000000000000000018101a000000000000000000000000000000000000000000000000000000000018101b000000000000000000000000000000000000000000000000000000000018101c000000000000000000000000000000000000000000000000000000000018101d000000000000000000000000000000000000000000000000000000000018101e000000000000000000000000000000000000000000000000000000000018101f0000000000000000000000000000000000000000000000000000000000181020000000000000000000000000000000000000000000000000000000000018102100000000000000000000000000000000000000000000000000000000001810220000000000000000000000000000000000000000000000000000000000181023000000000000000000000000000000000000000000000000000000000018102400000000000000000000000000000000000000000000000000000000001810250000000000000000000000000000000000000000000000000000000000181026000000000000000000000000000000000000000000000000000000000018102700000000000000000000000000000000000000000000000000000000001810280000000000000000000000000000000000000000000000000000000000181029000000000000000000000000000000000000000000000000000000000018102a000000000000000000000000000000000000000000000000000000000018102b000000000000000000000000000000000000000000000000000000000018102c000000000000000000000000000000000000000000000000000000000018102d000000000000000000000000000000000000000000000000000000000018102e000000000000000000000000000000000000000000000000000000000018102f0000000000000000000000000000000000000000000000000000000000181030000000000000000000000000000000000000000000000000000000000018103100000000000000000000000000000000000000000000000000000000001810320000000000000000000000000000000000000000000000000000000000181033000000000000000000000000000000000000000000000000000000000018103400000000000000000000000000000000000000000000000000000000001810350000000000000000000000000000000000000000000000000000000000181036000000000000000000000000000000000000000000000000000000000018103700000000000000000000000000000000000000000000000000000000001810380000000000000000000000000000000000000000000000000000000000181039000000000000000000000000000000000000000000000000000000000018103a000000000000000000000000000000000000000000000000000000000018103b000000000000000000000000000000000000000000000000000000000018103c000000000000000000000000000000000000000000000000000000000018103d000000000000000000000000000000000000000000000000000000000018103e000000000000000000000000000000000000000000000000000000000018103f3f0000000000000000000000000000000000000000000000000000000000181100000000000000000000000000000000000000000000000000000000000018110100000000000000000000000000000000000000000000000000000000001811020000000000000000000000000000000000000000000000000000000000181103000000000000000000000000000000000000000000000000000000000018110400000000000000000000000000000000000000000000000000000000001811050000000000000000000000000000000000000000000000000000000000181106000000000000000000000000000000000000000000000000000000000018110700000000000000000000000000000000000000000000000000000000001811080000000000000000000000000000000000000000000000000000000000181109000000000000000000000000000000000000000000000000000000000018110a000000000000000000000000000000000000000000000000000000000018110b000000000000000000000000000000000000000000000000000000000018110c000000000000000000000000000000000000000000000000000000000018110d000000000000000000000000000000000000000000000000000000000018110e000000000000000000000000000000000000000000000000000000000018110f0000000000000000000000000000000000000000000000000000000000181110000000000000000000000000000000000000000000000000000000000018111100000000000000000000000000000000000000000000000000000000001811120000000000000000000000000000000000000000000000000000000000181113000000000000000000000000000000000000000000000000000000000018111400000000000000000000000000000000000000000000000000000000001811150000000000000000000000000000000000000000000000000000000000181116000000000000000000000000000000000000000000000000000000000018111700000000000000000000000000000000000000000000000000000000001811180000000000000000000000000000000000000000000000000000000000181119000000000000000000000000000000000000000000000000000000000018111a000000000000000000000000000000000000000000000000000000000018111b000000000000000000000000000000000000000000000000000000000018111c000000000000000000000000000000000000000000000000000000000018111d000000000000000000000000000000000000000000000000000000000018111e000000000000000000000000000000000000000000000000000000000018111f0000000000000000000000000000000000000000000000000000000000181120000000000000000000000000000000000000000000000000000000000018112100000000000000000000000000000000000000000000000000000000001811220000000000000000000000000000000000000000000000000000000000181123000000000000000000000000000000000000000000000000000000000018112400000000000000000000000000000000000000000000000000000000001811250000000000000000000000000000000000000000000000000000000000181126000000000000000000000000000000000000000000000000000000000018112700000000000000000000000000000000000000000000000000000000001811280000000000000000000000000000000000000000000000000000000000181129000000000000000000000000000000000000000000000000000000000018112a000000000000000000000000000000000000000000000000000000000018112b000000000000000000000000000000000000000000000000000000000018112c000000000000000000000000000000000000000000000000000000000018112d000000000000000000000000000000000000000000000000000000000018112e000000000000000000000000000000000000000000000000000000000018112f0000000000000000000000000000000000000000000000000000000000181130000000000000000000000000000000000000000000000000000000000018113100000000000000000000000000000000000000000000000000000000001811320000000000000000000000000000000000000000000000000000000000181133000000000000000000000000000000000000000000000000000000000018113400000000000000000000000000000000000000000000000000000000001811350000000000000000000000000000000000000000000000000000000000181136000000000000000000000000000000000000000000000000000000000018113700000000000000000000000000000000000000000000000000000000001811380000000000000000000000000000000000000000000000000000000000181139000000000000000000000000000000000000000000000000000000000018113a000000000000000000000000000000000000000000000000000000000018113b000000000000000000000000000000000000000000000000000000000018113c000000000000000000000000000000000000000000000000000000000018113d000000000000000000000000000000000000000000000000000000000018113e0800f872eb9653f03af10f331da1361fa1524d3cd958cb72dacea1d424f19df3af00ffc548a17cd6ba1f2d228f30e4ddb19ecc46ad3b609977d52bb0f49e1206410032f8058bd779c520eabae2743b02ec4f71670428506fcceb2d4b69f26fb11800c0283e15fbf74ffa4eafb984030394f3c2ea6733cc0eacb0431a9475eff28f00b7f55314bfd9d441c1c624e241908228fe4da3d3a0a7fbd56814e1c8cd5d3e00f430f33a786675271736fd728c7bf7428b8c24ac948d7faf76ddb8783a496c0048fc235ead8d4b9d44929662a6384074fc4e5076bec5b7deb34f612393684300fd9b61cb1ad9b4b28f58399906e73933e3cccee8fc98a393f0eedb95b13ee63f0000000000000000000000000000000000000000000000000000000000182000000000000000000000000000000000000000000000000000000000000018200a0000000000000000000000000000000000000000000000000000000000182001000000000000000000000000000000000000000000000000000000000018200b0000000000000000000000000000000000000000000000000000000000182002000000000000000000000000000000000000000000000000000000000018200c0000000000000000000000000000000000000000000000000000000000182003000000000000000000000000000000000000000000000000000000000018200d0000000000000000000000000000000000000000000000000000000000182004000000000000000000000000000000000000000000000000000000000018200e0000000000000000000000000000000000000000000000000000000000182005000000000000000000000000000000000000000000000000000000000018200f00000000000000000000000000000000000000000000000000000000001820060000000000000000000000000000000000000000000000000000000000182010000000000000000000000000000000000000000000000000000000000018200700000000000000000000000000000000000000000000000000000000001820110000000000000000000000000000000000000000000000000000000000182008000000000000000000000000000000000000000000000000000000000018201200000000000000000000000000000000000000000000000000000000001820090000000000000000000000000000000000000000000000000000000000182013000000000000000000000000000000000000000000000000000000000018200a0000000000000000000000000000000000000000000000000000000000182014000000000000000000000000000000000000000000000000000000000018200b0000000000000000000000000000000000000000000000000000000000182015000000000000000000000000000000000000000000000000000000000018200c0000000000000000000000000000000000000000000000000000000000182016000000000000000000000000000000000000000000000000000000000018200d0000000000000000000000000000000000000000000000000000000000182017000000000000000000000000000000000000000000000000000000000018200e0000000000000000000000000000000000000000000000000000000000182018000000000000000000000000000000000000000000000000000000000018200f00000000000000000000000000000000000000000000000000000000001820190000000000000000000000000000000000000000000000000000000000182010000000000000000000000000000000000000000000000000000000000018201a0000000000000000000000000000000000000000000000000000000000182011000000000000000000000000000000000000000000000000000000000018201b0000000000000000000000000000000000000000000000000000000000182012000000000000000000000000000000000000000000000000000000000018201c0000000000000000000000000000000000000000000000000000000000182013000000000000000000000000000000000000000000000000000000000018201d0000000000000000000000000000000000000000000000000000000000182014000000000000000000000000000000000000000000000000000000000018201e0000000000000000000000000000000000000000000000000000000000182015000000000000000000000000000000000000000000000000000000000018201f00000000000000000000000000000000000000000000000000000000001820160000000000000000000000000000000000000000000000000000000000182020000000000000000000000000000000000000000000000000000000000018201700000000000000000000000000000000000000000000000000000000001820210000000000000000000000000000000000000000000000000000000000182018000000000000000000000000000000000000000000000000000000000018202200000000000000000000000000000000000000000000000000000000001820190000000000000000000000000000000000000000000000000000000000182023000000000000000000000000000000000000000000000000000000000018201a0000000000000000000000000000000000000000000000000000000000182024000000000000000000000000000000000000000000000000000000000018201b0000000000000000000000000000000000000000000000000000000000182025000000000000000000000000000000000000000000000000000000000018201c0000000000000000000000000000000000000000000000000000000000182026000000000000000000000000000000000000000000000000000000000018201d0000000000000000000000000000000000000000000000000000000000182027000000000000000000000000000000000000000000000000000000000018201e0000000000000000000000000000000000000000000000000000000000182028000000000000000000000000000000000000000000000000000000000018201f00000000000000000000000000000000000000000000000000000000001820290000000000000000000000000000000000000000000000000000000000182020000000000000000000000000000000000000000000000000000000000018202a0000000000000000000000000000000000000000000000000000000000182021000000000000000000000000000000000000000000000000000000000018202b0000000000000000000000000000000000000000000000000000000000182022000000000000000000000000000000000000000000000000000000000018202c0000000000000000000000000000000000000000000000000000000000182023000000000000000000000000000000000000000000000000000000000018202d0000000000000000000000000000000000000000000000000000000000182024000000000000000000000000000000000000000000000000000000000018202e0000000000000000000000000000000000000000000000000000000000182025000000000000000000000000000000000000000000000000000000000018202f00000000000000000000000000000000000000000000000000000000001820260000000000000000000000000000000000000000000000000000000000182030000000000000000000000000000000000000000000000000000000000018202700000000000000000000000000000000000000000000000000000000001820310000000000000000000000000000000000000000000000000000000000182028000000000000000000000000000000000000000000000000000000000018203200000000000000000000000000000000000000000000000000000000001820290000000000000000000000000000000000000000000000000000000000182033000000000000000000000000000000000000000000000000000000000018202a0000000000000000000000000000000000000000000000000000000000182034000000000000000000000000000000000000000000000000000000000018202b0000000000000000000000000000000000000000000000000000000000182035000000000000000000000000000000000000000000000000000000000018202c0000000000000000000000000000000000000000000000000000000000182036000000000000000000000000000000000000000000000000000000000018202d0000000000000000000000000000000000000000000000000000000000182037000000000000000000000000000000000000000000000000000000000018202e0000000000000000000000000000000000000000000000000000000000182038000000000000000000000000000000000000000000000000000000000018202f00000000000000000000000000000000000000000000000000000000001820390000000000000000000000000000000000000000000000000000000000182030000000000000000000000000000000000000000000000000000000000018203a0000000000000000000000000000000000000000000000000000000000182031000000000000000000000000000000000000000000000000000000000018203b0000000000000000000000000000000000000000000000000000000000182032000000000000000000000000000000000000000000000000000000000018203c0000000000000000000000000000000000000000000000000000000000182033000000000000000000000000000000000000000000000000000000000018203d0000000000000000000000000000000000000000000000000000000000182034000000000000000000000000000000000000000000000000000000000018203e0000000000000000000000000000000000000000000000000000000000182035000000000000000000000000000000000000000000000000000000000018203f00000000000000000000000000000000000000000000000000000000001820360000000000000000000000000000000000000000000000000000000000182040000000000000000000000000000000000000000000000000000000000018203700000000000000000000000000000000000000000000000000000000001820410000000000000000000000000000000000000000000000000000000000182038000000000000000000000000000000000000000000000000000000000018204200000000000000000000000000000000000000000000000000000000001820390000000000000000000000000000000000000000000000000000000000182043000000000000000000000000000000000000000000000000000000000018203a0000000000000000000000000000000000000000000000000000000000182044000000000000000000000000000000000000000000000000000000000018203b0000000000000000000000000000000000000000000000000000000000182045000000000000000000000000000000000000000000000000000000000018203c0000000000000000000000000000000000000000000000000000000000182046000000000000000000000000000000000000000000000000000000000018203d0000000000000000000000000000000000000000000000000000000000182047000000000000000000000000000000000000000000000000000000000018203e00000000000000000000000000000000000000000000000000000000001820480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000001c100000000000000000000000000000000000000000000000000000000000001c100100000000000000000000000000000000000000000000000000000000001c100200000000000000000000000000000000000000000000000000000000001c100300000000000000000000000000000000000000000000000000000000001c100400000000000000000000000000000000000000000000000000000000001c100500000000000000000000000000000000000000000000000000000000001c100600000000000000000000000000000000000000000000000000000000001c100700000000000000000000000000000000000000000000000000000000001c100800000000000000000000000000000000000000000000000000000000001c100900000000000000000000000000000000000000000000000000000000001c100a00000000000000000000000000000000000000000000000000000000001c100b00000000000000000000000000000000000000000000000000000000001c100c00000000000000000000000000000000000000000000000000000000001c100d00000000000000000000000000000000000000000000000000000000001c100e00000000000000000000000000000000000000000000000000000000001c100f00000000000000000000000000000000000000000000000000000000001c101000000000000000000000000000000000000000000000000000000000001c101100000000000000000000000000000000000000000000000000000000001c101200000000000000000000000000000000000000000000000000000000001c101300000000000000000000000000000000000000000000000000000000001c101400000000000000000000000000000000000000000000000000000000001c101500000000000000000000000000000000000000000000000000000000001c101600000000000000000000000000000000000000000000000000000000001c101700000000000000000000000000000000000000000000000000000000001c101800000000000000000000000000000000000000000000000000000000001c101900000000000000000000000000000000000000000000000000000000001c101a00000000000000000000000000000000000000000000000000000000001c101b00000000000000000000000000000000000000000000000000000000001c101c00000000000000000000000000000000000000000000000000000000001c101d00000000000000000000000000000000000000000000000000000000001c101e00000000000000000000000000000000000000000000000000000000001c101f00000000000000000000000000000000000000000000000000000000001c102000000000000000000000000000000000000000000000000000000000001c102100000000000000000000000000000000000000000000000000000000001c102200000000000000000000000000000000000000000000000000000000001c102300000000000000000000000000000000000000000000000000000000001c102400000000000000000000000000000000000000000000000000000000001c102500000000000000000000000000000000000000000000000000000000001c102600000000000000000000000000000000000000000000000000000000001c102700000000000000000000000000000000000000000000000000000000001c102800000000000000000000000000000000000000000000000000000000001c102900000000000000000000000000000000000000000000000000000000001c102a00000000000000000000000000000000000000000000000000000000001c102b00000000000000000000000000000000000000000000000000000000001c102c00000000000000000000000000000000000000000000000000000000001c102d00000000000000000000000000000000000000000000000000000000001c102e00000000000000000000000000000000000000000000000000000000001c102f00000000000000000000000000000000000000000000000000000000001c103000000000000000000000000000000000000000000000000000000000001c103100000000000000000000000000000000000000000000000000000000001c103200000000000000000000000000000000000000000000000000000000001c103300000000000000000000000000000000000000000000000000000000001c103400000000000000000000000000000000000000000000000000000000001c103500000000000000000000000000000000000000000000000000000000001c103600000000000000000000000000000000000000000000000000000000001c103700000000000000000000000000000000000000000000000000000000001c103800000000000000000000000000000000000000000000000000000000001c103900000000000000000000000000000000000000000000000000000000001c103a00000000000000000000000000000000000000000000000000000000001c103b00000000000000000000000000000000000000000000000000000000001c103c00000000000000000000000000000000000000000000000000000000001c103d00000000000000000000000000000000000000000000000000000000001c103e00000000000000000000000000000000000000000000000000000000001c103f3f00000000000000000000000000000000000000000000000000000000001c110000000000000000000000000000000000000000000000000000000000001c110100000000000000000000000000000000000000000000000000000000001c110200000000000000000000000000000000000000000000000000000000001c110300000000000000000000000000000000000000000000000000000000001c110400000000000000000000000000000000000000000000000000000000001c110500000000000000000000000000000000000000000000000000000000001c110600000000000000000000000000000000000000000000000000000000001c110700000000000000000000000000000000000000000000000000000000001c110800000000000000000000000000000000000000000000000000000000001c110900000000000000000000000000000000000000000000000000000000001c110a00000000000000000000000000000000000000000000000000000000001c110b00000000000000000000000000000000000000000000000000000000001c110c00000000000000000000000000000000000000000000000000000000001c110d00000000000000000000000000000000000000000000000000000000001c110e00000000000000000000000000000000000000000000000000000000001c110f00000000000000000000000000000000000000000000000000000000001c111000000000000000000000000000000000000000000000000000000000001c111100000000000000000000000000000000000000000000000000000000001c111200000000000000000000000000000000000000000000000000000000001c111300000000000000000000000000000000000000000000000000000000001c111400000000000000000000000000000000000000000000000000000000001c111500000000000000000000000000000000000000000000000000000000001c111600000000000000000000000000000000000000000000000000000000001c111700000000000000000000000000000000000000000000000000000000001c111800000000000000000000000000000000000000000000000000000000001c111900000000000000000000000000000000000000000000000000000000001c111a00000000000000000000000000000000000000000000000000000000001c111b00000000000000000000000000000000000000000000000000000000001c111c00000000000000000000000000000000000000000000000000000000001c111d00000000000000000000000000000000000000000000000000000000001c111e00000000000000000000000000000000000000000000000000000000001c111f00000000000000000000000000000000000000000000000000000000001c112000000000000000000000000000000000000000000000000000000000001c112100000000000000000000000000000000000000000000000000000000001c112200000000000000000000000000000000000000000000000000000000001c112300000000000000000000000000000000000000000000000000000000001c112400000000000000000000000000000000000000000000000000000000001c112500000000000000000000000000000000000000000000000000000000001c112600000000000000000000000000000000000000000000000000000000001c112700000000000000000000000000000000000000000000000000000000001c112800000000000000000000000000000000000000000000000000000000001c112900000000000000000000000000000000000000000000000000000000001c112a00000000000000000000000000000000000000000000000000000000001c112b00000000000000000000000000000000000000000000000000000000001c112c00000000000000000000000000000000000000000000000000000000001c112d00000000000000000000000000000000000000000000000000000000001c112e00000000000000000000000000000000000000000000000000000000001c112f00000000000000000000000000000000000000000000000000000000001c113000000000000000000000000000000000000000000000000000000000001c113100000000000000000000000000000000000000000000000000000000001c113200000000000000000000000000000000000000000000000000000000001c113300000000000000000000000000000000000000000000000000000000001c113400000000000000000000000000000000000000000000000000000000001c113500000000000000000000000000000000000000000000000000000000001c113600000000000000000000000000000000000000000000000000000000001c113700000000000000000000000000000000000000000000000000000000001c113800000000000000000000000000000000000000000000000000000000001c113900000000000000000000000000000000000000000000000000000000001c113a00000000000000000000000000000000000000000000000000000000001c113b00000000000000000000000000000000000000000000000000000000001c113c00000000000000000000000000000000000000000000000000000000001c113d00000000000000000000000000000000000000000000000000000000001c113e08006838aa99533bea0d4204cad17cb3c147e99c2f9089e54a4289d54733eeada2002ab314bd11ace2494a3fb0970d276da39f0fe7da19c9a2438b9c7c334d32470071703d79d8425a7eca52006df6a8f9728508a83639e3e1c2ebae2b853a087c00c9501ac04a78ac5413c9131b08708064ed2c2515b8893f12c2d1cda15a44f100a0955f93e109778d26f9e5b0d46e45c539e59b0941517bfa888eb2d7d2d8a6005adc3be9406cc5f102c6adb44746e8529a256e2396353a8659344cc3e914c4007a5fe572cf6af804f472dabf095c5eb6b30efc5fd627ad3245a8ef0f3f578c003dcaa91dfc9fdad7ba8da68a48fc662dfc0a995cbb0c1bc62099c8257d240d3f00000000000000000000000000000000000000000000000000000000001c200000000000000000000000000000000000000000000000000000000000001c200a00000000000000000000000000000000000000000000000000000000001c200100000000000000000000000000000000000000000000000000000000001c200b00000000000000000000000000000000000000000000000000000000001c200200000000000000000000000000000000000000000000000000000000001c200c00000000000000000000000000000000000000000000000000000000001c200300000000000000000000000000000000000000000000000000000000001c200d00000000000000000000000000000000000000000000000000000000001c200400000000000000000000000000000000000000000000000000000000001c200e00000000000000000000000000000000000000000000000000000000001c200500000000000000000000000000000000000000000000000000000000001c200f00000000000000000000000000000000000000000000000000000000001c200600000000000000000000000000000000000000000000000000000000001c201000000000000000000000000000000000000000000000000000000000001c200700000000000000000000000000000000000000000000000000000000001c201100000000000000000000000000000000000000000000000000000000001c200800000000000000000000000000000000000000000000000000000000001c201200000000000000000000000000000000000000000000000000000000001c200900000000000000000000000000000000000000000000000000000000001c201300000000000000000000000000000000000000000000000000000000001c200a00000000000000000000000000000000000000000000000000000000001c201400000000000000000000000000000000000000000000000000000000001c200b00000000000000000000000000000000000000000000000000000000001c201500000000000000000000000000000000000000000000000000000000001c200c00000000000000000000000000000000000000000000000000000000001c201600000000000000000000000000000000000000000000000000000000001c200d00000000000000000000000000000000000000000000000000000000001c201700000000000000000000000000000000000000000000000000000000001c200e00000000000000000000000000000000000000000000000000000000001c201800000000000000000000000000000000000000000000000000000000001c200f00000000000000000000000000000000000000000000000000000000001c201900000000000000000000000000000000000000000000000000000000001c201000000000000000000000000000000000000000000000000000000000001c201a00000000000000000000000000000000000000000000000000000000001c201100000000000000000000000000000000000000000000000000000000001c201b00000000000000000000000000000000000000000000000000000000001c201200000000000000000000000000000000000000000000000000000000001c201c00000000000000000000000000000000000000000000000000000000001c201300000000000000000000000000000000000000000000000000000000001c201d00000000000000000000000000000000000000000000000000000000001c201400000000000000000000000000000000000000000000000000000000001c201e00000000000000000000000000000000000000000000000000000000001c201500000000000000000000000000000000000000000000000000000000001c201f00000000000000000000000000000000000000000000000000000000001c201600000000000000000000000000000000000000000000000000000000001c202000000000000000000000000000000000000000000000000000000000001c201700000000000000000000000000000000000000000000000000000000001c202100000000000000000000000000000000000000000000000000000000001c201800000000000000000000000000000000000000000000000000000000001c202200000000000000000000000000000000000000000000000000000000001c201900000000000000000000000000000000000000000000000000000000001c202300000000000000000000000000000000000000000000000000000000001c201a00000000000000000000000000000000000000000000000000000000001c202400000000000000000000000000000000000000000000000000000000001c201b00000000000000000000000000000000000000000000000000000000001c202500000000000000000000000000000000000000000000000000000000001c201c00000000000000000000000000000000000000000000000000000000001c202600000000000000000000000000000000000000000000000000000000001c201d00000000000000000000000000000000000000000000000000000000001c202700000000000000000000000000000000000000000000000000000000001c201e00000000000000000000000000000000000000000000000000000000001c202800000000000000000000000000000000000000000000000000000000001c201f00000000000000000000000000000000000000000000000000000000001c202900000000000000000000000000000000000000000000000000000000001c202000000000000000000000000000000000000000000000000000000000001c202a00000000000000000000000000000000000000000000000000000000001c202100000000000000000000000000000000000000000000000000000000001c202b00000000000000000000000000000000000000000000000000000000001c202200000000000000000000000000000000000000000000000000000000001c202c00000000000000000000000000000000000000000000000000000000001c202300000000000000000000000000000000000000000000000000000000001c202d00000000000000000000000000000000000000000000000000000000001c202400000000000000000000000000000000000000000000000000000000001c202e00000000000000000000000000000000000000000000000000000000001c202500000000000000000000000000000000000000000000000000000000001c202f00000000000000000000000000000000000000000000000000000000001c202600000000000000000000000000000000000000000000000000000000001c203000000000000000000000000000000000000000000000000000000000001c202700000000000000000000000000000000000000000000000000000000001c203100000000000000000000000000000000000000000000000000000000001c202800000000000000000000000000000000000000000000000000000000001c203200000000000000000000000000000000000000000000000000000000001c202900000000000000000000000000000000000000000000000000000000001c203300000000000000000000000000000000000000000000000000000000001c202a00000000000000000000000000000000000000000000000000000000001c203400000000000000000000000000000000000000000000000000000000001c202b00000000000000000000000000000000000000000000000000000000001c203500000000000000000000000000000000000000000000000000000000001c202c00000000000000000000000000000000000000000000000000000000001c203600000000000000000000000000000000000000000000000000000000001c202d00000000000000000000000000000000000000000000000000000000001c203700000000000000000000000000000000000000000000000000000000001c202e00000000000000000000000000000000000000000000000000000000001c203800000000000000000000000000000000000000000000000000000000001c202f00000000000000000000000000000000000000000000000000000000001c203900000000000000000000000000000000000000000000000000000000001c203000000000000000000000000000000000000000000000000000000000001c203a00000000000000000000000000000000000000000000000000000000001c203100000000000000000000000000000000000000000000000000000000001c203b00000000000000000000000000000000000000000000000000000000001c203200000000000000000000000000000000000000000000000000000000001c203c00000000000000000000000000000000000000000000000000000000001c203300000000000000000000000000000000000000000000000000000000001c203d00000000000000000000000000000000000000000000000000000000001c203400000000000000000000000000000000000000000000000000000000001c203e00000000000000000000000000000000000000000000000000000000001c203500000000000000000000000000000000000000000000000000000000001c203f00000000000000000000000000000000000000000000000000000000001c203600000000000000000000000000000000000000000000000000000000001c204000000000000000000000000000000000000000000000000000000000001c203700000000000000000000000000000000000000000000000000000000001c204100000000000000000000000000000000000000000000000000000000001c203800000000000000000000000000000000000000000000000000000000001c204200000000000000000000000000000000000000000000000000000000001c203900000000000000000000000000000000000000000000000000000000001c204300000000000000000000000000000000000000000000000000000000001c203a00000000000000000000000000000000000000000000000000000000001c204400000000000000000000000000000000000000000000000000000000001c203b00000000000000000000000000000000000000000000000000000000001c204500000000000000000000000000000000000000000000000000000000001c203c00000000000000000000000000000000000000000000000000000000001c204600000000000000000000000000000000000000000000000000000000001c203d00000000000000000000000000000000000000000000000000000000001c204700000000000000000000000000000000000000000000000000000000001c203e00000000000000000000000000000000000000000000000000000000001c2048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000201000000000000000000000000000000000000000000000000000000000000020100100000000000000000000000000000000000000000000000000000000002010020000000000000000000000000000000000000000000000000000000000201003000000000000000000000000000000000000000000000000000000000020100400000000000000000000000000000000000000000000000000000000002010050000000000000000000000000000000000000000000000000000000000201006000000000000000000000000000000000000000000000000000000000020100700000000000000000000000000000000000000000000000000000000002010080000000000000000000000000000000000000000000000000000000000201009000000000000000000000000000000000000000000000000000000000020100a000000000000000000000000000000000000000000000000000000000020100b000000000000000000000000000000000000000000000000000000000020100c000000000000000000000000000000000000000000000000000000000020100d000000000000000000000000000000000000000000000000000000000020100e000000000000000000000000000000000000000000000000000000000020100f0000000000000000000000000000000000000000000000000000000000201010000000000000000000000000000000000000000000000000000000000020101100000000000000000000000000000000000000000000000000000000002010120000000000000000000000000000000000000000000000000000000000201013000000000000000000000000000000000000000000000000000000000020101400000000000000000000000000000000000000000000000000000000002010150000000000000000000000000000000000000000000000000000000000201016000000000000000000000000000000000000000000000000000000000020101700000000000000000000000000000000000000000000000000000000002010180000000000000000000000000000000000000000000000000000000000201019000000000000000000000000000000000000000000000000000000000020101a000000000000000000000000000000000000000000000000000000000020101b000000000000000000000000000000000000000000000000000000000020101c000000000000000000000000000000000000000000000000000000000020101d000000000000000000000000000000000000000000000000000000000020101e000000000000000000000000000000000000000000000000000000000020101f0000000000000000000000000000000000000000000000000000000000201020000000000000000000000000000000000000000000000000000000000020102100000000000000000000000000000000000000000000000000000000002010220000000000000000000000000000000000000000000000000000000000201023000000000000000000000000000000000000000000000000000000000020102400000000000000000000000000000000000000000000000000000000002010250000000000000000000000000000000000000000000000000000000000201026000000000000000000000000000000000000000000000000000000000020102700000000000000000000000000000000000000000000000000000000002010280000000000000000000000000000000000000000000000000000000000201029000000000000000000000000000000000000000000000000000000000020102a000000000000000000000000000000000000000000000000000000000020102b000000000000000000000000000000000000000000000000000000000020102c000000000000000000000000000000000000000000000000000000000020102d000000000000000000000000000000000000000000000000000000000020102e000000000000000000000000000000000000000000000000000000000020102f0000000000000000000000000000000000000000000000000000000000201030000000000000000000000000000000000000000000000000000000000020103100000000000000000000000000000000000000000000000000000000002010320000000000000000000000000000000000000000000000000000000000201033000000000000000000000000000000000000000000000000000000000020103400000000000000000000000000000000000000000000000000000000002010350000000000000000000000000000000000000000000000000000000000201036000000000000000000000000000000000000000000000000000000000020103700000000000000000000000000000000000000000000000000000000002010380000000000000000000000000000000000000000000000000000000000201039000000000000000000000000000000000000000000000000000000000020103a000000000000000000000000000000000000000000000000000000000020103b000000000000000000000000000000000000000000000000000000000020103c000000000000000000000000000000000000000000000000000000000020103d000000000000000000000000000000000000000000000000000000000020103e000000000000000000000000000000000000000000000000000000000020103f3f0000000000000000000000000000000000000000000000000000000000201100000000000000000000000000000000000000000000000000000000000020110100000000000000000000000000000000000000000000000000000000002011020000000000000000000000000000000000000000000000000000000000201103000000000000000000000000000000000000000000000000000000000020110400000000000000000000000000000000000000000000000000000000002011050000000000000000000000000000000000000000000000000000000000201106000000000000000000000000000000000000000000000000000000000020110700000000000000000000000000000000000000000000000000000000002011080000000000000000000000000000000000000000000000000000000000201109000000000000000000000000000000000000000000000000000000000020110a000000000000000000000000000000000000000000000000000000000020110b000000000000000000000000000000000000000000000000000000000020110c000000000000000000000000000000000000000000000000000000000020110d000000000000000000000000000000000000000000000000000000000020110e000000000000000000000000000000000000000000000000000000000020110f0000000000000000000000000000000000000000000000000000000000201110000000000000000000000000000000000000000000000000000000000020111100000000000000000000000000000000000000000000000000000000002011120000000000000000000000000000000000000000000000000000000000201113000000000000000000000000000000000000000000000000000000000020111400000000000000000000000000000000000000000000000000000000002011150000000000000000000000000000000000000000000000000000000000201116000000000000000000000000000000000000000000000000000000000020111700000000000000000000000000000000000000000000000000000000002011180000000000000000000000000000000000000000000000000000000000201119000000000000000000000000000000000000000000000000000000000020111a000000000000000000000000000000000000000000000000000000000020111b000000000000000000000000000000000000000000000000000000000020111c000000000000000000000000000000000000000000000000000000000020111d000000000000000000000000000000000000000000000000000000000020111e000000000000000000000000000000000000000000000000000000000020111f0000000000000000000000000000000000000000000000000000000000201120000000000000000000000000000000000000000000000000000000000020112100000000000000000000000000000000000000000000000000000000002011220000000000000000000000000000000000000000000000000000000000201123000000000000000000000000000000000000000000000000000000000020112400000000000000000000000000000000000000000000000000000000002011250000000000000000000000000000000000000000000000000000000000201126000000000000000000000000000000000000000000000000000000000020112700000000000000000000000000000000000000000000000000000000002011280000000000000000000000000000000000000000000000000000000000201129000000000000000000000000000000000000000000000000000000000020112a000000000000000000000000000000000000000000000000000000000020112b000000000000000000000000000000000000000000000000000000000020112c000000000000000000000000000000000000000000000000000000000020112d000000000000000000000000000000000000000000000000000000000020112e000000000000000000000000000000000000000000000000000000000020112f0000000000000000000000000000000000000000000000000000000000201130000000000000000000000000000000000000000000000000000000000020113100000000000000000000000000000000000000000000000000000000002011320000000000000000000000000000000000000000000000000000000000201133000000000000000000000000000000000000000000000000000000000020113400000000000000000000000000000000000000000000000000000000002011350000000000000000000000000000000000000000000000000000000000201136000000000000000000000000000000000000000000000000000000000020113700000000000000000000000000000000000000000000000000000000002011380000000000000000000000000000000000000000000000000000000000201139000000000000000000000000000000000000000000000000000000000020113a000000000000000000000000000000000000000000000000000000000020113b000000000000000000000000000000000000000000000000000000000020113c000000000000000000000000000000000000000000000000000000000020113d000000000000000000000000000000000000000000000000000000000020113e0800e9805e8a4faa87fc419af08a6d956f18976c46ea694bbd4cf6946e6d02033200e0925a6b172b4b01bb76eb1d3f7dd2ced118bca70d223a6d61afa1b75915ae00383590492d2f99a0283d1de57015b4b6b0759a8023af2c68fb4929dee2f303007ed57100dd77e2b6405f780503ef61b7b53e13f344b6e6a6eff3e3c13de0d0001ab1b0c348c46184dbc86ff79f248e7da1b09d3f9c6a986e98fe45389f060d0023d134bc68d7efa25e255001069827dc0bee766c08c988d6300071ed27fe6c0031cbb780b07f632cbaf767dc80608cc0a8e1d1df3ecd6f5d8bc0ca6703e4f4002c7dc9e731fc5f6456b2a70b4e636ac17d5e0cd36d3a591116a9e124f735863f0000000000000000000000000000000000000000000000000000000000202000000000000000000000000000000000000000000000000000000000000020200a0000000000000000000000000000000000000000000000000000000000202001000000000000000000000000000000000000000000000000000000000020200b0000000000000000000000000000000000000000000000000000000000202002000000000000000000000000000000000000000000000000000000000020200c0000000000000000000000000000000000000000000000000000000000202003000000000000000000000000000000000000000000000000000000000020200d0000000000000000000000000000000000000000000000000000000000202004000000000000000000000000000000000000000000000000000000000020200e0000000000000000000000000000000000000000000000000000000000202005000000000000000000000000000000000000000000000000000000000020200f00000000000000000000000000000000000000000000000000000000002020060000000000000000000000000000000000000000000000000000000000202010000000000000000000000000000000000000000000000000000000000020200700000000000000000000000000000000000000000000000000000000002020110000000000000000000000000000000000000000000000000000000000202008000000000000000000000000000000000000000000000000000000000020201200000000000000000000000000000000000000000000000000000000002020090000000000000000000000000000000000000000000000000000000000202013000000000000000000000000000000000000000000000000000000000020200a0000000000000000000000000000000000000000000000000000000000202014000000000000000000000000000000000000000000000000000000000020200b0000000000000000000000000000000000000000000000000000000000202015000000000000000000000000000000000000000000000000000000000020200c0000000000000000000000000000000000000000000000000000000000202016000000000000000000000000000000000000000000000000000000000020200d0000000000000000000000000000000000000000000000000000000000202017000000000000000000000000000000000000000000000000000000000020200e0000000000000000000000000000000000000000000000000000000000202018000000000000000000000000000000000000000000000000000000000020200f00000000000000000000000000000000000000000000000000000000002020190000000000000000000000000000000000000000000000000000000000202010000000000000000000000000000000000000000000000000000000000020201a0000000000000000000000000000000000000000000000000000000000202011000000000000000000000000000000000000000000000000000000000020201b0000000000000000000000000000000000000000000000000000000000202012000000000000000000000000000000000000000000000000000000000020201c0000000000000000000000000000000000000000000000000000000000202013000000000000000000000000000000000000000000000000000000000020201d0000000000000000000000000000000000000000000000000000000000202014000000000000000000000000000000000000000000000000000000000020201e0000000000000000000000000000000000000000000000000000000000202015000000000000000000000000000000000000000000000000000000000020201f00000000000000000000000000000000000000000000000000000000002020160000000000000000000000000000000000000000000000000000000000202020000000000000000000000000000000000000000000000000000000000020201700000000000000000000000000000000000000000000000000000000002020210000000000000000000000000000000000000000000000000000000000202018000000000000000000000000000000000000000000000000000000000020202200000000000000000000000000000000000000000000000000000000002020190000000000000000000000000000000000000000000000000000000000202023000000000000000000000000000000000000000000000000000000000020201a0000000000000000000000000000000000000000000000000000000000202024000000000000000000000000000000000000000000000000000000000020201b0000000000000000000000000000000000000000000000000000000000202025000000000000000000000000000000000000000000000000000000000020201c0000000000000000000000000000000000000000000000000000000000202026000000000000000000000000000000000000000000000000000000000020201d0000000000000000000000000000000000000000000000000000000000202027000000000000000000000000000000000000000000000000000000000020201e0000000000000000000000000000000000000000000000000000000000202028000000000000000000000000000000000000000000000000000000000020201f00000000000000000000000000000000000000000000000000000000002020290000000000000000000000000000000000000000000000000000000000202020000000000000000000000000000000000000000000000000000000000020202a0000000000000000000000000000000000000000000000000000000000202021000000000000000000000000000000000000000000000000000000000020202b0000000000000000000000000000000000000000000000000000000000202022000000000000000000000000000000000000000000000000000000000020202c0000000000000000000000000000000000000000000000000000000000202023000000000000000000000000000000000000000000000000000000000020202d0000000000000000000000000000000000000000000000000000000000202024000000000000000000000000000000000000000000000000000000000020202e0000000000000000000000000000000000000000000000000000000000202025000000000000000000000000000000000000000000000000000000000020202f00000000000000000000000000000000000000000000000000000000002020260000000000000000000000000000000000000000000000000000000000202030000000000000000000000000000000000000000000000000000000000020202700000000000000000000000000000000000000000000000000000000002020310000000000000000000000000000000000000000000000000000000000202028000000000000000000000000000000000000000000000000000000000020203200000000000000000000000000000000000000000000000000000000002020290000000000000000000000000000000000000000000000000000000000202033000000000000000000000000000000000000000000000000000000000020202a0000000000000000000000000000000000000000000000000000000000202034000000000000000000000000000000000000000000000000000000000020202b0000000000000000000000000000000000000000000000000000000000202035000000000000000000000000000000000000000000000000000000000020202c0000000000000000000000000000000000000000000000000000000000202036000000000000000000000000000000000000000000000000000000000020202d0000000000000000000000000000000000000000000000000000000000202037000000000000000000000000000000000000000000000000000000000020202e0000000000000000000000000000000000000000000000000000000000202038000000000000000000000000000000000000000000000000000000000020202f00000000000000000000000000000000000000000000000000000000002020390000000000000000000000000000000000000000000000000000000000202030000000000000000000000000000000000000000000000000000000000020203a0000000000000000000000000000000000000000000000000000000000202031000000000000000000000000000000000000000000000000000000000020203b0000000000000000000000000000000000000000000000000000000000202032000000000000000000000000000000000000000000000000000000000020203c0000000000000000000000000000000000000000000000000000000000202033000000000000000000000000000000000000000000000000000000000020203d0000000000000000000000000000000000000000000000000000000000202034000000000000000000000000000000000000000000000000000000000020203e0000000000000000000000000000000000000000000000000000000000202035000000000000000000000000000000000000000000000000000000000020203f00000000000000000000000000000000000000000000000000000000002020360000000000000000000000000000000000000000000000000000000000202040000000000000000000000000000000000000000000000000000000000020203700000000000000000000000000000000000000000000000000000000002020410000000000000000000000000000000000000000000000000000000000202038000000000000000000000000000000000000000000000000000000000020204200000000000000000000000000000000000000000000000000000000002020390000000000000000000000000000000000000000000000000000000000202043000000000000000000000000000000000000000000000000000000000020203a0000000000000000000000000000000000000000000000000000000000202044000000000000000000000000000000000000000000000000000000000020203b0000000000000000000000000000000000000000000000000000000000202045000000000000000000000000000000000000000000000000000000000020203c0000000000000000000000000000000000000000000000000000000000202046000000000000000000000000000000000000000000000000000000000020203d0000000000000000000000000000000000000000000000000000000000202047000000000000000000000000000000000000000000000000000000000020203e0000000000000000000000000000000000000000000000000000000000202048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "txsEffectsHash": "0x00d2d12b4d0c6202124a7625c585097078920e09dd2c650401a91b564234a6b4", + "archive": "0x1a67606f67cc90d680873608c953ab58de942279a740dd8f4221cbd39327449a", + "blockHash": "0x0a3664a7aa5b6e62973e4b7be7807869ada474cc3aacd49dacc82e55dd1ccd26", + "body": "0x00000004000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000141000000000000000000000000000000000000000000000000000000000000014100100000000000000000000000000000000000000000000000000000000001410020000000000000000000000000000000000000000000000000000000000141003000000000000000000000000000000000000000000000000000000000014100400000000000000000000000000000000000000000000000000000000001410050000000000000000000000000000000000000000000000000000000000141006000000000000000000000000000000000000000000000000000000000014100700000000000000000000000000000000000000000000000000000000001410080000000000000000000000000000000000000000000000000000000000141009000000000000000000000000000000000000000000000000000000000014100a000000000000000000000000000000000000000000000000000000000014100b000000000000000000000000000000000000000000000000000000000014100c000000000000000000000000000000000000000000000000000000000014100d000000000000000000000000000000000000000000000000000000000014100e000000000000000000000000000000000000000000000000000000000014100f0000000000000000000000000000000000000000000000000000000000141010000000000000000000000000000000000000000000000000000000000014101100000000000000000000000000000000000000000000000000000000001410120000000000000000000000000000000000000000000000000000000000141013000000000000000000000000000000000000000000000000000000000014101400000000000000000000000000000000000000000000000000000000001410150000000000000000000000000000000000000000000000000000000000141016000000000000000000000000000000000000000000000000000000000014101700000000000000000000000000000000000000000000000000000000001410180000000000000000000000000000000000000000000000000000000000141019000000000000000000000000000000000000000000000000000000000014101a000000000000000000000000000000000000000000000000000000000014101b000000000000000000000000000000000000000000000000000000000014101c000000000000000000000000000000000000000000000000000000000014101d000000000000000000000000000000000000000000000000000000000014101e000000000000000000000000000000000000000000000000000000000014101f0000000000000000000000000000000000000000000000000000000000141020000000000000000000000000000000000000000000000000000000000014102100000000000000000000000000000000000000000000000000000000001410220000000000000000000000000000000000000000000000000000000000141023000000000000000000000000000000000000000000000000000000000014102400000000000000000000000000000000000000000000000000000000001410250000000000000000000000000000000000000000000000000000000000141026000000000000000000000000000000000000000000000000000000000014102700000000000000000000000000000000000000000000000000000000001410280000000000000000000000000000000000000000000000000000000000141029000000000000000000000000000000000000000000000000000000000014102a000000000000000000000000000000000000000000000000000000000014102b000000000000000000000000000000000000000000000000000000000014102c000000000000000000000000000000000000000000000000000000000014102d000000000000000000000000000000000000000000000000000000000014102e000000000000000000000000000000000000000000000000000000000014102f0000000000000000000000000000000000000000000000000000000000141030000000000000000000000000000000000000000000000000000000000014103100000000000000000000000000000000000000000000000000000000001410320000000000000000000000000000000000000000000000000000000000141033000000000000000000000000000000000000000000000000000000000014103400000000000000000000000000000000000000000000000000000000001410350000000000000000000000000000000000000000000000000000000000141036000000000000000000000000000000000000000000000000000000000014103700000000000000000000000000000000000000000000000000000000001410380000000000000000000000000000000000000000000000000000000000141039000000000000000000000000000000000000000000000000000000000014103a000000000000000000000000000000000000000000000000000000000014103b000000000000000000000000000000000000000000000000000000000014103c000000000000000000000000000000000000000000000000000000000014103d000000000000000000000000000000000000000000000000000000000014103e000000000000000000000000000000000000000000000000000000000014103f3f0000000000000000000000000000000000000000000000000000000000141100000000000000000000000000000000000000000000000000000000000014110100000000000000000000000000000000000000000000000000000000001411020000000000000000000000000000000000000000000000000000000000141103000000000000000000000000000000000000000000000000000000000014110400000000000000000000000000000000000000000000000000000000001411050000000000000000000000000000000000000000000000000000000000141106000000000000000000000000000000000000000000000000000000000014110700000000000000000000000000000000000000000000000000000000001411080000000000000000000000000000000000000000000000000000000000141109000000000000000000000000000000000000000000000000000000000014110a000000000000000000000000000000000000000000000000000000000014110b000000000000000000000000000000000000000000000000000000000014110c000000000000000000000000000000000000000000000000000000000014110d000000000000000000000000000000000000000000000000000000000014110e000000000000000000000000000000000000000000000000000000000014110f0000000000000000000000000000000000000000000000000000000000141110000000000000000000000000000000000000000000000000000000000014111100000000000000000000000000000000000000000000000000000000001411120000000000000000000000000000000000000000000000000000000000141113000000000000000000000000000000000000000000000000000000000014111400000000000000000000000000000000000000000000000000000000001411150000000000000000000000000000000000000000000000000000000000141116000000000000000000000000000000000000000000000000000000000014111700000000000000000000000000000000000000000000000000000000001411180000000000000000000000000000000000000000000000000000000000141119000000000000000000000000000000000000000000000000000000000014111a000000000000000000000000000000000000000000000000000000000014111b000000000000000000000000000000000000000000000000000000000014111c000000000000000000000000000000000000000000000000000000000014111d000000000000000000000000000000000000000000000000000000000014111e000000000000000000000000000000000000000000000000000000000014111f0000000000000000000000000000000000000000000000000000000000141120000000000000000000000000000000000000000000000000000000000014112100000000000000000000000000000000000000000000000000000000001411220000000000000000000000000000000000000000000000000000000000141123000000000000000000000000000000000000000000000000000000000014112400000000000000000000000000000000000000000000000000000000001411250000000000000000000000000000000000000000000000000000000000141126000000000000000000000000000000000000000000000000000000000014112700000000000000000000000000000000000000000000000000000000001411280000000000000000000000000000000000000000000000000000000000141129000000000000000000000000000000000000000000000000000000000014112a000000000000000000000000000000000000000000000000000000000014112b000000000000000000000000000000000000000000000000000000000014112c000000000000000000000000000000000000000000000000000000000014112d000000000000000000000000000000000000000000000000000000000014112e000000000000000000000000000000000000000000000000000000000014112f0000000000000000000000000000000000000000000000000000000000141130000000000000000000000000000000000000000000000000000000000014113100000000000000000000000000000000000000000000000000000000001411320000000000000000000000000000000000000000000000000000000000141133000000000000000000000000000000000000000000000000000000000014113400000000000000000000000000000000000000000000000000000000001411350000000000000000000000000000000000000000000000000000000000141136000000000000000000000000000000000000000000000000000000000014113700000000000000000000000000000000000000000000000000000000001411380000000000000000000000000000000000000000000000000000000000141139000000000000000000000000000000000000000000000000000000000014113a000000000000000000000000000000000000000000000000000000000014113b000000000000000000000000000000000000000000000000000000000014113c000000000000000000000000000000000000000000000000000000000014113d000000000000000000000000000000000000000000000000000000000014113e08005c015113cb57d67dd6c0febd596819ac0298b6a23fc80aba17d445d540059a00f20b7d1308051fe7b68031a7c336b0b4b56738928b6510133aff1b818d5a9a0063eec1883a4f95f4933f9275e850d84b3d035f5061ed986c437a07331fd30e00d3a32d6bbc4fd843686fd0c5e118a73b847529977dca5b9e0e81f6604f22ca00c2f4f5133d9194d41e853e5e951e16690babce8461f25342c0bad20f2aa1e3000a6bf4739e7eb387913d955dc2e8f14f8cce27696b9d2e128b6acefafb80ee005763f7e0648f958b559677622a648f318fc79ebc0cb539170d49c26456e69200302e2b8a92cda941e9af8761b89899a58a587656d9710594e1d865b16522993f0000000000000000000000000000000000000000000000000000000000142000000000000000000000000000000000000000000000000000000000000014200a0000000000000000000000000000000000000000000000000000000000142001000000000000000000000000000000000000000000000000000000000014200b0000000000000000000000000000000000000000000000000000000000142002000000000000000000000000000000000000000000000000000000000014200c0000000000000000000000000000000000000000000000000000000000142003000000000000000000000000000000000000000000000000000000000014200d0000000000000000000000000000000000000000000000000000000000142004000000000000000000000000000000000000000000000000000000000014200e0000000000000000000000000000000000000000000000000000000000142005000000000000000000000000000000000000000000000000000000000014200f00000000000000000000000000000000000000000000000000000000001420060000000000000000000000000000000000000000000000000000000000142010000000000000000000000000000000000000000000000000000000000014200700000000000000000000000000000000000000000000000000000000001420110000000000000000000000000000000000000000000000000000000000142008000000000000000000000000000000000000000000000000000000000014201200000000000000000000000000000000000000000000000000000000001420090000000000000000000000000000000000000000000000000000000000142013000000000000000000000000000000000000000000000000000000000014200a0000000000000000000000000000000000000000000000000000000000142014000000000000000000000000000000000000000000000000000000000014200b0000000000000000000000000000000000000000000000000000000000142015000000000000000000000000000000000000000000000000000000000014200c0000000000000000000000000000000000000000000000000000000000142016000000000000000000000000000000000000000000000000000000000014200d0000000000000000000000000000000000000000000000000000000000142017000000000000000000000000000000000000000000000000000000000014200e0000000000000000000000000000000000000000000000000000000000142018000000000000000000000000000000000000000000000000000000000014200f00000000000000000000000000000000000000000000000000000000001420190000000000000000000000000000000000000000000000000000000000142010000000000000000000000000000000000000000000000000000000000014201a0000000000000000000000000000000000000000000000000000000000142011000000000000000000000000000000000000000000000000000000000014201b0000000000000000000000000000000000000000000000000000000000142012000000000000000000000000000000000000000000000000000000000014201c0000000000000000000000000000000000000000000000000000000000142013000000000000000000000000000000000000000000000000000000000014201d0000000000000000000000000000000000000000000000000000000000142014000000000000000000000000000000000000000000000000000000000014201e0000000000000000000000000000000000000000000000000000000000142015000000000000000000000000000000000000000000000000000000000014201f00000000000000000000000000000000000000000000000000000000001420160000000000000000000000000000000000000000000000000000000000142020000000000000000000000000000000000000000000000000000000000014201700000000000000000000000000000000000000000000000000000000001420210000000000000000000000000000000000000000000000000000000000142018000000000000000000000000000000000000000000000000000000000014202200000000000000000000000000000000000000000000000000000000001420190000000000000000000000000000000000000000000000000000000000142023000000000000000000000000000000000000000000000000000000000014201a0000000000000000000000000000000000000000000000000000000000142024000000000000000000000000000000000000000000000000000000000014201b0000000000000000000000000000000000000000000000000000000000142025000000000000000000000000000000000000000000000000000000000014201c0000000000000000000000000000000000000000000000000000000000142026000000000000000000000000000000000000000000000000000000000014201d0000000000000000000000000000000000000000000000000000000000142027000000000000000000000000000000000000000000000000000000000014201e0000000000000000000000000000000000000000000000000000000000142028000000000000000000000000000000000000000000000000000000000014201f00000000000000000000000000000000000000000000000000000000001420290000000000000000000000000000000000000000000000000000000000142020000000000000000000000000000000000000000000000000000000000014202a0000000000000000000000000000000000000000000000000000000000142021000000000000000000000000000000000000000000000000000000000014202b0000000000000000000000000000000000000000000000000000000000142022000000000000000000000000000000000000000000000000000000000014202c0000000000000000000000000000000000000000000000000000000000142023000000000000000000000000000000000000000000000000000000000014202d0000000000000000000000000000000000000000000000000000000000142024000000000000000000000000000000000000000000000000000000000014202e0000000000000000000000000000000000000000000000000000000000142025000000000000000000000000000000000000000000000000000000000014202f00000000000000000000000000000000000000000000000000000000001420260000000000000000000000000000000000000000000000000000000000142030000000000000000000000000000000000000000000000000000000000014202700000000000000000000000000000000000000000000000000000000001420310000000000000000000000000000000000000000000000000000000000142028000000000000000000000000000000000000000000000000000000000014203200000000000000000000000000000000000000000000000000000000001420290000000000000000000000000000000000000000000000000000000000142033000000000000000000000000000000000000000000000000000000000014202a0000000000000000000000000000000000000000000000000000000000142034000000000000000000000000000000000000000000000000000000000014202b0000000000000000000000000000000000000000000000000000000000142035000000000000000000000000000000000000000000000000000000000014202c0000000000000000000000000000000000000000000000000000000000142036000000000000000000000000000000000000000000000000000000000014202d0000000000000000000000000000000000000000000000000000000000142037000000000000000000000000000000000000000000000000000000000014202e0000000000000000000000000000000000000000000000000000000000142038000000000000000000000000000000000000000000000000000000000014202f00000000000000000000000000000000000000000000000000000000001420390000000000000000000000000000000000000000000000000000000000142030000000000000000000000000000000000000000000000000000000000014203a0000000000000000000000000000000000000000000000000000000000142031000000000000000000000000000000000000000000000000000000000014203b0000000000000000000000000000000000000000000000000000000000142032000000000000000000000000000000000000000000000000000000000014203c0000000000000000000000000000000000000000000000000000000000142033000000000000000000000000000000000000000000000000000000000014203d0000000000000000000000000000000000000000000000000000000000142034000000000000000000000000000000000000000000000000000000000014203e0000000000000000000000000000000000000000000000000000000000142035000000000000000000000000000000000000000000000000000000000014203f00000000000000000000000000000000000000000000000000000000001420360000000000000000000000000000000000000000000000000000000000142040000000000000000000000000000000000000000000000000000000000014203700000000000000000000000000000000000000000000000000000000001420410000000000000000000000000000000000000000000000000000000000142038000000000000000000000000000000000000000000000000000000000014204200000000000000000000000000000000000000000000000000000000001420390000000000000000000000000000000000000000000000000000000000142043000000000000000000000000000000000000000000000000000000000014203a0000000000000000000000000000000000000000000000000000000000142044000000000000000000000000000000000000000000000000000000000014203b0000000000000000000000000000000000000000000000000000000000142045000000000000000000000000000000000000000000000000000000000014203c0000000000000000000000000000000000000000000000000000000000142046000000000000000000000000000000000000000000000000000000000014203d0000000000000000000000000000000000000000000000000000000000142047000000000000000000000000000000000000000000000000000000000014203e0000000000000000000000000000000000000000000000000000000000142048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000181000000000000000000000000000000000000000000000000000000000000018100100000000000000000000000000000000000000000000000000000000001810020000000000000000000000000000000000000000000000000000000000181003000000000000000000000000000000000000000000000000000000000018100400000000000000000000000000000000000000000000000000000000001810050000000000000000000000000000000000000000000000000000000000181006000000000000000000000000000000000000000000000000000000000018100700000000000000000000000000000000000000000000000000000000001810080000000000000000000000000000000000000000000000000000000000181009000000000000000000000000000000000000000000000000000000000018100a000000000000000000000000000000000000000000000000000000000018100b000000000000000000000000000000000000000000000000000000000018100c000000000000000000000000000000000000000000000000000000000018100d000000000000000000000000000000000000000000000000000000000018100e000000000000000000000000000000000000000000000000000000000018100f0000000000000000000000000000000000000000000000000000000000181010000000000000000000000000000000000000000000000000000000000018101100000000000000000000000000000000000000000000000000000000001810120000000000000000000000000000000000000000000000000000000000181013000000000000000000000000000000000000000000000000000000000018101400000000000000000000000000000000000000000000000000000000001810150000000000000000000000000000000000000000000000000000000000181016000000000000000000000000000000000000000000000000000000000018101700000000000000000000000000000000000000000000000000000000001810180000000000000000000000000000000000000000000000000000000000181019000000000000000000000000000000000000000000000000000000000018101a000000000000000000000000000000000000000000000000000000000018101b000000000000000000000000000000000000000000000000000000000018101c000000000000000000000000000000000000000000000000000000000018101d000000000000000000000000000000000000000000000000000000000018101e000000000000000000000000000000000000000000000000000000000018101f0000000000000000000000000000000000000000000000000000000000181020000000000000000000000000000000000000000000000000000000000018102100000000000000000000000000000000000000000000000000000000001810220000000000000000000000000000000000000000000000000000000000181023000000000000000000000000000000000000000000000000000000000018102400000000000000000000000000000000000000000000000000000000001810250000000000000000000000000000000000000000000000000000000000181026000000000000000000000000000000000000000000000000000000000018102700000000000000000000000000000000000000000000000000000000001810280000000000000000000000000000000000000000000000000000000000181029000000000000000000000000000000000000000000000000000000000018102a000000000000000000000000000000000000000000000000000000000018102b000000000000000000000000000000000000000000000000000000000018102c000000000000000000000000000000000000000000000000000000000018102d000000000000000000000000000000000000000000000000000000000018102e000000000000000000000000000000000000000000000000000000000018102f0000000000000000000000000000000000000000000000000000000000181030000000000000000000000000000000000000000000000000000000000018103100000000000000000000000000000000000000000000000000000000001810320000000000000000000000000000000000000000000000000000000000181033000000000000000000000000000000000000000000000000000000000018103400000000000000000000000000000000000000000000000000000000001810350000000000000000000000000000000000000000000000000000000000181036000000000000000000000000000000000000000000000000000000000018103700000000000000000000000000000000000000000000000000000000001810380000000000000000000000000000000000000000000000000000000000181039000000000000000000000000000000000000000000000000000000000018103a000000000000000000000000000000000000000000000000000000000018103b000000000000000000000000000000000000000000000000000000000018103c000000000000000000000000000000000000000000000000000000000018103d000000000000000000000000000000000000000000000000000000000018103e000000000000000000000000000000000000000000000000000000000018103f3f0000000000000000000000000000000000000000000000000000000000181100000000000000000000000000000000000000000000000000000000000018110100000000000000000000000000000000000000000000000000000000001811020000000000000000000000000000000000000000000000000000000000181103000000000000000000000000000000000000000000000000000000000018110400000000000000000000000000000000000000000000000000000000001811050000000000000000000000000000000000000000000000000000000000181106000000000000000000000000000000000000000000000000000000000018110700000000000000000000000000000000000000000000000000000000001811080000000000000000000000000000000000000000000000000000000000181109000000000000000000000000000000000000000000000000000000000018110a000000000000000000000000000000000000000000000000000000000018110b000000000000000000000000000000000000000000000000000000000018110c000000000000000000000000000000000000000000000000000000000018110d000000000000000000000000000000000000000000000000000000000018110e000000000000000000000000000000000000000000000000000000000018110f0000000000000000000000000000000000000000000000000000000000181110000000000000000000000000000000000000000000000000000000000018111100000000000000000000000000000000000000000000000000000000001811120000000000000000000000000000000000000000000000000000000000181113000000000000000000000000000000000000000000000000000000000018111400000000000000000000000000000000000000000000000000000000001811150000000000000000000000000000000000000000000000000000000000181116000000000000000000000000000000000000000000000000000000000018111700000000000000000000000000000000000000000000000000000000001811180000000000000000000000000000000000000000000000000000000000181119000000000000000000000000000000000000000000000000000000000018111a000000000000000000000000000000000000000000000000000000000018111b000000000000000000000000000000000000000000000000000000000018111c000000000000000000000000000000000000000000000000000000000018111d000000000000000000000000000000000000000000000000000000000018111e000000000000000000000000000000000000000000000000000000000018111f0000000000000000000000000000000000000000000000000000000000181120000000000000000000000000000000000000000000000000000000000018112100000000000000000000000000000000000000000000000000000000001811220000000000000000000000000000000000000000000000000000000000181123000000000000000000000000000000000000000000000000000000000018112400000000000000000000000000000000000000000000000000000000001811250000000000000000000000000000000000000000000000000000000000181126000000000000000000000000000000000000000000000000000000000018112700000000000000000000000000000000000000000000000000000000001811280000000000000000000000000000000000000000000000000000000000181129000000000000000000000000000000000000000000000000000000000018112a000000000000000000000000000000000000000000000000000000000018112b000000000000000000000000000000000000000000000000000000000018112c000000000000000000000000000000000000000000000000000000000018112d000000000000000000000000000000000000000000000000000000000018112e000000000000000000000000000000000000000000000000000000000018112f0000000000000000000000000000000000000000000000000000000000181130000000000000000000000000000000000000000000000000000000000018113100000000000000000000000000000000000000000000000000000000001811320000000000000000000000000000000000000000000000000000000000181133000000000000000000000000000000000000000000000000000000000018113400000000000000000000000000000000000000000000000000000000001811350000000000000000000000000000000000000000000000000000000000181136000000000000000000000000000000000000000000000000000000000018113700000000000000000000000000000000000000000000000000000000001811380000000000000000000000000000000000000000000000000000000000181139000000000000000000000000000000000000000000000000000000000018113a000000000000000000000000000000000000000000000000000000000018113b000000000000000000000000000000000000000000000000000000000018113c000000000000000000000000000000000000000000000000000000000018113d000000000000000000000000000000000000000000000000000000000018113e0800f872eb9653f03af10f331da1361fa1524d3cd958cb72dacea1d424f19df3af00ffc548a17cd6ba1f2d228f30e4ddb19ecc46ad3b609977d52bb0f49e1206410032f8058bd779c520eabae2743b02ec4f71670428506fcceb2d4b69f26fb11800c0283e15fbf74ffa4eafb984030394f3c2ea6733cc0eacb0431a9475eff28f00b7f55314bfd9d441c1c624e241908228fe4da3d3a0a7fbd56814e1c8cd5d3e00f430f33a786675271736fd728c7bf7428b8c24ac948d7faf76ddb8783a496c0048fc235ead8d4b9d44929662a6384074fc4e5076bec5b7deb34f612393684300fd9b61cb1ad9b4b28f58399906e73933e3cccee8fc98a393f0eedb95b13ee63f0000000000000000000000000000000000000000000000000000000000182000000000000000000000000000000000000000000000000000000000000018200a0000000000000000000000000000000000000000000000000000000000182001000000000000000000000000000000000000000000000000000000000018200b0000000000000000000000000000000000000000000000000000000000182002000000000000000000000000000000000000000000000000000000000018200c0000000000000000000000000000000000000000000000000000000000182003000000000000000000000000000000000000000000000000000000000018200d0000000000000000000000000000000000000000000000000000000000182004000000000000000000000000000000000000000000000000000000000018200e0000000000000000000000000000000000000000000000000000000000182005000000000000000000000000000000000000000000000000000000000018200f00000000000000000000000000000000000000000000000000000000001820060000000000000000000000000000000000000000000000000000000000182010000000000000000000000000000000000000000000000000000000000018200700000000000000000000000000000000000000000000000000000000001820110000000000000000000000000000000000000000000000000000000000182008000000000000000000000000000000000000000000000000000000000018201200000000000000000000000000000000000000000000000000000000001820090000000000000000000000000000000000000000000000000000000000182013000000000000000000000000000000000000000000000000000000000018200a0000000000000000000000000000000000000000000000000000000000182014000000000000000000000000000000000000000000000000000000000018200b0000000000000000000000000000000000000000000000000000000000182015000000000000000000000000000000000000000000000000000000000018200c0000000000000000000000000000000000000000000000000000000000182016000000000000000000000000000000000000000000000000000000000018200d0000000000000000000000000000000000000000000000000000000000182017000000000000000000000000000000000000000000000000000000000018200e0000000000000000000000000000000000000000000000000000000000182018000000000000000000000000000000000000000000000000000000000018200f00000000000000000000000000000000000000000000000000000000001820190000000000000000000000000000000000000000000000000000000000182010000000000000000000000000000000000000000000000000000000000018201a0000000000000000000000000000000000000000000000000000000000182011000000000000000000000000000000000000000000000000000000000018201b0000000000000000000000000000000000000000000000000000000000182012000000000000000000000000000000000000000000000000000000000018201c0000000000000000000000000000000000000000000000000000000000182013000000000000000000000000000000000000000000000000000000000018201d0000000000000000000000000000000000000000000000000000000000182014000000000000000000000000000000000000000000000000000000000018201e0000000000000000000000000000000000000000000000000000000000182015000000000000000000000000000000000000000000000000000000000018201f00000000000000000000000000000000000000000000000000000000001820160000000000000000000000000000000000000000000000000000000000182020000000000000000000000000000000000000000000000000000000000018201700000000000000000000000000000000000000000000000000000000001820210000000000000000000000000000000000000000000000000000000000182018000000000000000000000000000000000000000000000000000000000018202200000000000000000000000000000000000000000000000000000000001820190000000000000000000000000000000000000000000000000000000000182023000000000000000000000000000000000000000000000000000000000018201a0000000000000000000000000000000000000000000000000000000000182024000000000000000000000000000000000000000000000000000000000018201b0000000000000000000000000000000000000000000000000000000000182025000000000000000000000000000000000000000000000000000000000018201c0000000000000000000000000000000000000000000000000000000000182026000000000000000000000000000000000000000000000000000000000018201d0000000000000000000000000000000000000000000000000000000000182027000000000000000000000000000000000000000000000000000000000018201e0000000000000000000000000000000000000000000000000000000000182028000000000000000000000000000000000000000000000000000000000018201f00000000000000000000000000000000000000000000000000000000001820290000000000000000000000000000000000000000000000000000000000182020000000000000000000000000000000000000000000000000000000000018202a0000000000000000000000000000000000000000000000000000000000182021000000000000000000000000000000000000000000000000000000000018202b0000000000000000000000000000000000000000000000000000000000182022000000000000000000000000000000000000000000000000000000000018202c0000000000000000000000000000000000000000000000000000000000182023000000000000000000000000000000000000000000000000000000000018202d0000000000000000000000000000000000000000000000000000000000182024000000000000000000000000000000000000000000000000000000000018202e0000000000000000000000000000000000000000000000000000000000182025000000000000000000000000000000000000000000000000000000000018202f00000000000000000000000000000000000000000000000000000000001820260000000000000000000000000000000000000000000000000000000000182030000000000000000000000000000000000000000000000000000000000018202700000000000000000000000000000000000000000000000000000000001820310000000000000000000000000000000000000000000000000000000000182028000000000000000000000000000000000000000000000000000000000018203200000000000000000000000000000000000000000000000000000000001820290000000000000000000000000000000000000000000000000000000000182033000000000000000000000000000000000000000000000000000000000018202a0000000000000000000000000000000000000000000000000000000000182034000000000000000000000000000000000000000000000000000000000018202b0000000000000000000000000000000000000000000000000000000000182035000000000000000000000000000000000000000000000000000000000018202c0000000000000000000000000000000000000000000000000000000000182036000000000000000000000000000000000000000000000000000000000018202d0000000000000000000000000000000000000000000000000000000000182037000000000000000000000000000000000000000000000000000000000018202e0000000000000000000000000000000000000000000000000000000000182038000000000000000000000000000000000000000000000000000000000018202f00000000000000000000000000000000000000000000000000000000001820390000000000000000000000000000000000000000000000000000000000182030000000000000000000000000000000000000000000000000000000000018203a0000000000000000000000000000000000000000000000000000000000182031000000000000000000000000000000000000000000000000000000000018203b0000000000000000000000000000000000000000000000000000000000182032000000000000000000000000000000000000000000000000000000000018203c0000000000000000000000000000000000000000000000000000000000182033000000000000000000000000000000000000000000000000000000000018203d0000000000000000000000000000000000000000000000000000000000182034000000000000000000000000000000000000000000000000000000000018203e0000000000000000000000000000000000000000000000000000000000182035000000000000000000000000000000000000000000000000000000000018203f00000000000000000000000000000000000000000000000000000000001820360000000000000000000000000000000000000000000000000000000000182040000000000000000000000000000000000000000000000000000000000018203700000000000000000000000000000000000000000000000000000000001820410000000000000000000000000000000000000000000000000000000000182038000000000000000000000000000000000000000000000000000000000018204200000000000000000000000000000000000000000000000000000000001820390000000000000000000000000000000000000000000000000000000000182043000000000000000000000000000000000000000000000000000000000018203a0000000000000000000000000000000000000000000000000000000000182044000000000000000000000000000000000000000000000000000000000018203b0000000000000000000000000000000000000000000000000000000000182045000000000000000000000000000000000000000000000000000000000018203c0000000000000000000000000000000000000000000000000000000000182046000000000000000000000000000000000000000000000000000000000018203d0000000000000000000000000000000000000000000000000000000000182047000000000000000000000000000000000000000000000000000000000018203e00000000000000000000000000000000000000000000000000000000001820480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000001c100000000000000000000000000000000000000000000000000000000000001c100100000000000000000000000000000000000000000000000000000000001c100200000000000000000000000000000000000000000000000000000000001c100300000000000000000000000000000000000000000000000000000000001c100400000000000000000000000000000000000000000000000000000000001c100500000000000000000000000000000000000000000000000000000000001c100600000000000000000000000000000000000000000000000000000000001c100700000000000000000000000000000000000000000000000000000000001c100800000000000000000000000000000000000000000000000000000000001c100900000000000000000000000000000000000000000000000000000000001c100a00000000000000000000000000000000000000000000000000000000001c100b00000000000000000000000000000000000000000000000000000000001c100c00000000000000000000000000000000000000000000000000000000001c100d00000000000000000000000000000000000000000000000000000000001c100e00000000000000000000000000000000000000000000000000000000001c100f00000000000000000000000000000000000000000000000000000000001c101000000000000000000000000000000000000000000000000000000000001c101100000000000000000000000000000000000000000000000000000000001c101200000000000000000000000000000000000000000000000000000000001c101300000000000000000000000000000000000000000000000000000000001c101400000000000000000000000000000000000000000000000000000000001c101500000000000000000000000000000000000000000000000000000000001c101600000000000000000000000000000000000000000000000000000000001c101700000000000000000000000000000000000000000000000000000000001c101800000000000000000000000000000000000000000000000000000000001c101900000000000000000000000000000000000000000000000000000000001c101a00000000000000000000000000000000000000000000000000000000001c101b00000000000000000000000000000000000000000000000000000000001c101c00000000000000000000000000000000000000000000000000000000001c101d00000000000000000000000000000000000000000000000000000000001c101e00000000000000000000000000000000000000000000000000000000001c101f00000000000000000000000000000000000000000000000000000000001c102000000000000000000000000000000000000000000000000000000000001c102100000000000000000000000000000000000000000000000000000000001c102200000000000000000000000000000000000000000000000000000000001c102300000000000000000000000000000000000000000000000000000000001c102400000000000000000000000000000000000000000000000000000000001c102500000000000000000000000000000000000000000000000000000000001c102600000000000000000000000000000000000000000000000000000000001c102700000000000000000000000000000000000000000000000000000000001c102800000000000000000000000000000000000000000000000000000000001c102900000000000000000000000000000000000000000000000000000000001c102a00000000000000000000000000000000000000000000000000000000001c102b00000000000000000000000000000000000000000000000000000000001c102c00000000000000000000000000000000000000000000000000000000001c102d00000000000000000000000000000000000000000000000000000000001c102e00000000000000000000000000000000000000000000000000000000001c102f00000000000000000000000000000000000000000000000000000000001c103000000000000000000000000000000000000000000000000000000000001c103100000000000000000000000000000000000000000000000000000000001c103200000000000000000000000000000000000000000000000000000000001c103300000000000000000000000000000000000000000000000000000000001c103400000000000000000000000000000000000000000000000000000000001c103500000000000000000000000000000000000000000000000000000000001c103600000000000000000000000000000000000000000000000000000000001c103700000000000000000000000000000000000000000000000000000000001c103800000000000000000000000000000000000000000000000000000000001c103900000000000000000000000000000000000000000000000000000000001c103a00000000000000000000000000000000000000000000000000000000001c103b00000000000000000000000000000000000000000000000000000000001c103c00000000000000000000000000000000000000000000000000000000001c103d00000000000000000000000000000000000000000000000000000000001c103e00000000000000000000000000000000000000000000000000000000001c103f3f00000000000000000000000000000000000000000000000000000000001c110000000000000000000000000000000000000000000000000000000000001c110100000000000000000000000000000000000000000000000000000000001c110200000000000000000000000000000000000000000000000000000000001c110300000000000000000000000000000000000000000000000000000000001c110400000000000000000000000000000000000000000000000000000000001c110500000000000000000000000000000000000000000000000000000000001c110600000000000000000000000000000000000000000000000000000000001c110700000000000000000000000000000000000000000000000000000000001c110800000000000000000000000000000000000000000000000000000000001c110900000000000000000000000000000000000000000000000000000000001c110a00000000000000000000000000000000000000000000000000000000001c110b00000000000000000000000000000000000000000000000000000000001c110c00000000000000000000000000000000000000000000000000000000001c110d00000000000000000000000000000000000000000000000000000000001c110e00000000000000000000000000000000000000000000000000000000001c110f00000000000000000000000000000000000000000000000000000000001c111000000000000000000000000000000000000000000000000000000000001c111100000000000000000000000000000000000000000000000000000000001c111200000000000000000000000000000000000000000000000000000000001c111300000000000000000000000000000000000000000000000000000000001c111400000000000000000000000000000000000000000000000000000000001c111500000000000000000000000000000000000000000000000000000000001c111600000000000000000000000000000000000000000000000000000000001c111700000000000000000000000000000000000000000000000000000000001c111800000000000000000000000000000000000000000000000000000000001c111900000000000000000000000000000000000000000000000000000000001c111a00000000000000000000000000000000000000000000000000000000001c111b00000000000000000000000000000000000000000000000000000000001c111c00000000000000000000000000000000000000000000000000000000001c111d00000000000000000000000000000000000000000000000000000000001c111e00000000000000000000000000000000000000000000000000000000001c111f00000000000000000000000000000000000000000000000000000000001c112000000000000000000000000000000000000000000000000000000000001c112100000000000000000000000000000000000000000000000000000000001c112200000000000000000000000000000000000000000000000000000000001c112300000000000000000000000000000000000000000000000000000000001c112400000000000000000000000000000000000000000000000000000000001c112500000000000000000000000000000000000000000000000000000000001c112600000000000000000000000000000000000000000000000000000000001c112700000000000000000000000000000000000000000000000000000000001c112800000000000000000000000000000000000000000000000000000000001c112900000000000000000000000000000000000000000000000000000000001c112a00000000000000000000000000000000000000000000000000000000001c112b00000000000000000000000000000000000000000000000000000000001c112c00000000000000000000000000000000000000000000000000000000001c112d00000000000000000000000000000000000000000000000000000000001c112e00000000000000000000000000000000000000000000000000000000001c112f00000000000000000000000000000000000000000000000000000000001c113000000000000000000000000000000000000000000000000000000000001c113100000000000000000000000000000000000000000000000000000000001c113200000000000000000000000000000000000000000000000000000000001c113300000000000000000000000000000000000000000000000000000000001c113400000000000000000000000000000000000000000000000000000000001c113500000000000000000000000000000000000000000000000000000000001c113600000000000000000000000000000000000000000000000000000000001c113700000000000000000000000000000000000000000000000000000000001c113800000000000000000000000000000000000000000000000000000000001c113900000000000000000000000000000000000000000000000000000000001c113a00000000000000000000000000000000000000000000000000000000001c113b00000000000000000000000000000000000000000000000000000000001c113c00000000000000000000000000000000000000000000000000000000001c113d00000000000000000000000000000000000000000000000000000000001c113e08006838aa99533bea0d4204cad17cb3c147e99c2f9089e54a4289d54733eeada2002ab314bd11ace2494a3fb0970d276da39f0fe7da19c9a2438b9c7c334d32470071703d79d8425a7eca52006df6a8f9728508a83639e3e1c2ebae2b853a087c00c9501ac04a78ac5413c9131b08708064ed2c2515b8893f12c2d1cda15a44f100a0955f93e109778d26f9e5b0d46e45c539e59b0941517bfa888eb2d7d2d8a6005adc3be9406cc5f102c6adb44746e8529a256e2396353a8659344cc3e914c4007a5fe572cf6af804f472dabf095c5eb6b30efc5fd627ad3245a8ef0f3f578c003dcaa91dfc9fdad7ba8da68a48fc662dfc0a995cbb0c1bc62099c8257d240d3f00000000000000000000000000000000000000000000000000000000001c200000000000000000000000000000000000000000000000000000000000001c200a00000000000000000000000000000000000000000000000000000000001c200100000000000000000000000000000000000000000000000000000000001c200b00000000000000000000000000000000000000000000000000000000001c200200000000000000000000000000000000000000000000000000000000001c200c00000000000000000000000000000000000000000000000000000000001c200300000000000000000000000000000000000000000000000000000000001c200d00000000000000000000000000000000000000000000000000000000001c200400000000000000000000000000000000000000000000000000000000001c200e00000000000000000000000000000000000000000000000000000000001c200500000000000000000000000000000000000000000000000000000000001c200f00000000000000000000000000000000000000000000000000000000001c200600000000000000000000000000000000000000000000000000000000001c201000000000000000000000000000000000000000000000000000000000001c200700000000000000000000000000000000000000000000000000000000001c201100000000000000000000000000000000000000000000000000000000001c200800000000000000000000000000000000000000000000000000000000001c201200000000000000000000000000000000000000000000000000000000001c200900000000000000000000000000000000000000000000000000000000001c201300000000000000000000000000000000000000000000000000000000001c200a00000000000000000000000000000000000000000000000000000000001c201400000000000000000000000000000000000000000000000000000000001c200b00000000000000000000000000000000000000000000000000000000001c201500000000000000000000000000000000000000000000000000000000001c200c00000000000000000000000000000000000000000000000000000000001c201600000000000000000000000000000000000000000000000000000000001c200d00000000000000000000000000000000000000000000000000000000001c201700000000000000000000000000000000000000000000000000000000001c200e00000000000000000000000000000000000000000000000000000000001c201800000000000000000000000000000000000000000000000000000000001c200f00000000000000000000000000000000000000000000000000000000001c201900000000000000000000000000000000000000000000000000000000001c201000000000000000000000000000000000000000000000000000000000001c201a00000000000000000000000000000000000000000000000000000000001c201100000000000000000000000000000000000000000000000000000000001c201b00000000000000000000000000000000000000000000000000000000001c201200000000000000000000000000000000000000000000000000000000001c201c00000000000000000000000000000000000000000000000000000000001c201300000000000000000000000000000000000000000000000000000000001c201d00000000000000000000000000000000000000000000000000000000001c201400000000000000000000000000000000000000000000000000000000001c201e00000000000000000000000000000000000000000000000000000000001c201500000000000000000000000000000000000000000000000000000000001c201f00000000000000000000000000000000000000000000000000000000001c201600000000000000000000000000000000000000000000000000000000001c202000000000000000000000000000000000000000000000000000000000001c201700000000000000000000000000000000000000000000000000000000001c202100000000000000000000000000000000000000000000000000000000001c201800000000000000000000000000000000000000000000000000000000001c202200000000000000000000000000000000000000000000000000000000001c201900000000000000000000000000000000000000000000000000000000001c202300000000000000000000000000000000000000000000000000000000001c201a00000000000000000000000000000000000000000000000000000000001c202400000000000000000000000000000000000000000000000000000000001c201b00000000000000000000000000000000000000000000000000000000001c202500000000000000000000000000000000000000000000000000000000001c201c00000000000000000000000000000000000000000000000000000000001c202600000000000000000000000000000000000000000000000000000000001c201d00000000000000000000000000000000000000000000000000000000001c202700000000000000000000000000000000000000000000000000000000001c201e00000000000000000000000000000000000000000000000000000000001c202800000000000000000000000000000000000000000000000000000000001c201f00000000000000000000000000000000000000000000000000000000001c202900000000000000000000000000000000000000000000000000000000001c202000000000000000000000000000000000000000000000000000000000001c202a00000000000000000000000000000000000000000000000000000000001c202100000000000000000000000000000000000000000000000000000000001c202b00000000000000000000000000000000000000000000000000000000001c202200000000000000000000000000000000000000000000000000000000001c202c00000000000000000000000000000000000000000000000000000000001c202300000000000000000000000000000000000000000000000000000000001c202d00000000000000000000000000000000000000000000000000000000001c202400000000000000000000000000000000000000000000000000000000001c202e00000000000000000000000000000000000000000000000000000000001c202500000000000000000000000000000000000000000000000000000000001c202f00000000000000000000000000000000000000000000000000000000001c202600000000000000000000000000000000000000000000000000000000001c203000000000000000000000000000000000000000000000000000000000001c202700000000000000000000000000000000000000000000000000000000001c203100000000000000000000000000000000000000000000000000000000001c202800000000000000000000000000000000000000000000000000000000001c203200000000000000000000000000000000000000000000000000000000001c202900000000000000000000000000000000000000000000000000000000001c203300000000000000000000000000000000000000000000000000000000001c202a00000000000000000000000000000000000000000000000000000000001c203400000000000000000000000000000000000000000000000000000000001c202b00000000000000000000000000000000000000000000000000000000001c203500000000000000000000000000000000000000000000000000000000001c202c00000000000000000000000000000000000000000000000000000000001c203600000000000000000000000000000000000000000000000000000000001c202d00000000000000000000000000000000000000000000000000000000001c203700000000000000000000000000000000000000000000000000000000001c202e00000000000000000000000000000000000000000000000000000000001c203800000000000000000000000000000000000000000000000000000000001c202f00000000000000000000000000000000000000000000000000000000001c203900000000000000000000000000000000000000000000000000000000001c203000000000000000000000000000000000000000000000000000000000001c203a00000000000000000000000000000000000000000000000000000000001c203100000000000000000000000000000000000000000000000000000000001c203b00000000000000000000000000000000000000000000000000000000001c203200000000000000000000000000000000000000000000000000000000001c203c00000000000000000000000000000000000000000000000000000000001c203300000000000000000000000000000000000000000000000000000000001c203d00000000000000000000000000000000000000000000000000000000001c203400000000000000000000000000000000000000000000000000000000001c203e00000000000000000000000000000000000000000000000000000000001c203500000000000000000000000000000000000000000000000000000000001c203f00000000000000000000000000000000000000000000000000000000001c203600000000000000000000000000000000000000000000000000000000001c204000000000000000000000000000000000000000000000000000000000001c203700000000000000000000000000000000000000000000000000000000001c204100000000000000000000000000000000000000000000000000000000001c203800000000000000000000000000000000000000000000000000000000001c204200000000000000000000000000000000000000000000000000000000001c203900000000000000000000000000000000000000000000000000000000001c204300000000000000000000000000000000000000000000000000000000001c203a00000000000000000000000000000000000000000000000000000000001c204400000000000000000000000000000000000000000000000000000000001c203b00000000000000000000000000000000000000000000000000000000001c204500000000000000000000000000000000000000000000000000000000001c203c00000000000000000000000000000000000000000000000000000000001c204600000000000000000000000000000000000000000000000000000000001c203d00000000000000000000000000000000000000000000000000000000001c204700000000000000000000000000000000000000000000000000000000001c203e00000000000000000000000000000000000000000000000000000000001c2048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000201000000000000000000000000000000000000000000000000000000000000020100100000000000000000000000000000000000000000000000000000000002010020000000000000000000000000000000000000000000000000000000000201003000000000000000000000000000000000000000000000000000000000020100400000000000000000000000000000000000000000000000000000000002010050000000000000000000000000000000000000000000000000000000000201006000000000000000000000000000000000000000000000000000000000020100700000000000000000000000000000000000000000000000000000000002010080000000000000000000000000000000000000000000000000000000000201009000000000000000000000000000000000000000000000000000000000020100a000000000000000000000000000000000000000000000000000000000020100b000000000000000000000000000000000000000000000000000000000020100c000000000000000000000000000000000000000000000000000000000020100d000000000000000000000000000000000000000000000000000000000020100e000000000000000000000000000000000000000000000000000000000020100f0000000000000000000000000000000000000000000000000000000000201010000000000000000000000000000000000000000000000000000000000020101100000000000000000000000000000000000000000000000000000000002010120000000000000000000000000000000000000000000000000000000000201013000000000000000000000000000000000000000000000000000000000020101400000000000000000000000000000000000000000000000000000000002010150000000000000000000000000000000000000000000000000000000000201016000000000000000000000000000000000000000000000000000000000020101700000000000000000000000000000000000000000000000000000000002010180000000000000000000000000000000000000000000000000000000000201019000000000000000000000000000000000000000000000000000000000020101a000000000000000000000000000000000000000000000000000000000020101b000000000000000000000000000000000000000000000000000000000020101c000000000000000000000000000000000000000000000000000000000020101d000000000000000000000000000000000000000000000000000000000020101e000000000000000000000000000000000000000000000000000000000020101f0000000000000000000000000000000000000000000000000000000000201020000000000000000000000000000000000000000000000000000000000020102100000000000000000000000000000000000000000000000000000000002010220000000000000000000000000000000000000000000000000000000000201023000000000000000000000000000000000000000000000000000000000020102400000000000000000000000000000000000000000000000000000000002010250000000000000000000000000000000000000000000000000000000000201026000000000000000000000000000000000000000000000000000000000020102700000000000000000000000000000000000000000000000000000000002010280000000000000000000000000000000000000000000000000000000000201029000000000000000000000000000000000000000000000000000000000020102a000000000000000000000000000000000000000000000000000000000020102b000000000000000000000000000000000000000000000000000000000020102c000000000000000000000000000000000000000000000000000000000020102d000000000000000000000000000000000000000000000000000000000020102e000000000000000000000000000000000000000000000000000000000020102f0000000000000000000000000000000000000000000000000000000000201030000000000000000000000000000000000000000000000000000000000020103100000000000000000000000000000000000000000000000000000000002010320000000000000000000000000000000000000000000000000000000000201033000000000000000000000000000000000000000000000000000000000020103400000000000000000000000000000000000000000000000000000000002010350000000000000000000000000000000000000000000000000000000000201036000000000000000000000000000000000000000000000000000000000020103700000000000000000000000000000000000000000000000000000000002010380000000000000000000000000000000000000000000000000000000000201039000000000000000000000000000000000000000000000000000000000020103a000000000000000000000000000000000000000000000000000000000020103b000000000000000000000000000000000000000000000000000000000020103c000000000000000000000000000000000000000000000000000000000020103d000000000000000000000000000000000000000000000000000000000020103e000000000000000000000000000000000000000000000000000000000020103f3f0000000000000000000000000000000000000000000000000000000000201100000000000000000000000000000000000000000000000000000000000020110100000000000000000000000000000000000000000000000000000000002011020000000000000000000000000000000000000000000000000000000000201103000000000000000000000000000000000000000000000000000000000020110400000000000000000000000000000000000000000000000000000000002011050000000000000000000000000000000000000000000000000000000000201106000000000000000000000000000000000000000000000000000000000020110700000000000000000000000000000000000000000000000000000000002011080000000000000000000000000000000000000000000000000000000000201109000000000000000000000000000000000000000000000000000000000020110a000000000000000000000000000000000000000000000000000000000020110b000000000000000000000000000000000000000000000000000000000020110c000000000000000000000000000000000000000000000000000000000020110d000000000000000000000000000000000000000000000000000000000020110e000000000000000000000000000000000000000000000000000000000020110f0000000000000000000000000000000000000000000000000000000000201110000000000000000000000000000000000000000000000000000000000020111100000000000000000000000000000000000000000000000000000000002011120000000000000000000000000000000000000000000000000000000000201113000000000000000000000000000000000000000000000000000000000020111400000000000000000000000000000000000000000000000000000000002011150000000000000000000000000000000000000000000000000000000000201116000000000000000000000000000000000000000000000000000000000020111700000000000000000000000000000000000000000000000000000000002011180000000000000000000000000000000000000000000000000000000000201119000000000000000000000000000000000000000000000000000000000020111a000000000000000000000000000000000000000000000000000000000020111b000000000000000000000000000000000000000000000000000000000020111c000000000000000000000000000000000000000000000000000000000020111d000000000000000000000000000000000000000000000000000000000020111e000000000000000000000000000000000000000000000000000000000020111f0000000000000000000000000000000000000000000000000000000000201120000000000000000000000000000000000000000000000000000000000020112100000000000000000000000000000000000000000000000000000000002011220000000000000000000000000000000000000000000000000000000000201123000000000000000000000000000000000000000000000000000000000020112400000000000000000000000000000000000000000000000000000000002011250000000000000000000000000000000000000000000000000000000000201126000000000000000000000000000000000000000000000000000000000020112700000000000000000000000000000000000000000000000000000000002011280000000000000000000000000000000000000000000000000000000000201129000000000000000000000000000000000000000000000000000000000020112a000000000000000000000000000000000000000000000000000000000020112b000000000000000000000000000000000000000000000000000000000020112c000000000000000000000000000000000000000000000000000000000020112d000000000000000000000000000000000000000000000000000000000020112e000000000000000000000000000000000000000000000000000000000020112f0000000000000000000000000000000000000000000000000000000000201130000000000000000000000000000000000000000000000000000000000020113100000000000000000000000000000000000000000000000000000000002011320000000000000000000000000000000000000000000000000000000000201133000000000000000000000000000000000000000000000000000000000020113400000000000000000000000000000000000000000000000000000000002011350000000000000000000000000000000000000000000000000000000000201136000000000000000000000000000000000000000000000000000000000020113700000000000000000000000000000000000000000000000000000000002011380000000000000000000000000000000000000000000000000000000000201139000000000000000000000000000000000000000000000000000000000020113a000000000000000000000000000000000000000000000000000000000020113b000000000000000000000000000000000000000000000000000000000020113c000000000000000000000000000000000000000000000000000000000020113d000000000000000000000000000000000000000000000000000000000020113e0800e9805e8a4faa87fc419af08a6d956f18976c46ea694bbd4cf6946e6d02033200e0925a6b172b4b01bb76eb1d3f7dd2ced118bca70d223a6d61afa1b75915ae00383590492d2f99a0283d1de57015b4b6b0759a8023af2c68fb4929dee2f303007ed57100dd77e2b6405f780503ef61b7b53e13f344b6e6a6eff3e3c13de0d0001ab1b0c348c46184dbc86ff79f248e7da1b09d3f9c6a986e98fe45389f060d0023d134bc68d7efa25e255001069827dc0bee766c08c988d6300071ed27fe6c0031cbb780b07f632cbaf767dc80608cc0a8e1d1df3ecd6f5d8bc0ca6703e4f4002c7dc9e731fc5f6456b2a70b4e636ac17d5e0cd36d3a591116a9e124f735863f0000000000000000000000000000000000000000000000000000000000202000000000000000000000000000000000000000000000000000000000000020200a0000000000000000000000000000000000000000000000000000000000202001000000000000000000000000000000000000000000000000000000000020200b0000000000000000000000000000000000000000000000000000000000202002000000000000000000000000000000000000000000000000000000000020200c0000000000000000000000000000000000000000000000000000000000202003000000000000000000000000000000000000000000000000000000000020200d0000000000000000000000000000000000000000000000000000000000202004000000000000000000000000000000000000000000000000000000000020200e0000000000000000000000000000000000000000000000000000000000202005000000000000000000000000000000000000000000000000000000000020200f00000000000000000000000000000000000000000000000000000000002020060000000000000000000000000000000000000000000000000000000000202010000000000000000000000000000000000000000000000000000000000020200700000000000000000000000000000000000000000000000000000000002020110000000000000000000000000000000000000000000000000000000000202008000000000000000000000000000000000000000000000000000000000020201200000000000000000000000000000000000000000000000000000000002020090000000000000000000000000000000000000000000000000000000000202013000000000000000000000000000000000000000000000000000000000020200a0000000000000000000000000000000000000000000000000000000000202014000000000000000000000000000000000000000000000000000000000020200b0000000000000000000000000000000000000000000000000000000000202015000000000000000000000000000000000000000000000000000000000020200c0000000000000000000000000000000000000000000000000000000000202016000000000000000000000000000000000000000000000000000000000020200d0000000000000000000000000000000000000000000000000000000000202017000000000000000000000000000000000000000000000000000000000020200e0000000000000000000000000000000000000000000000000000000000202018000000000000000000000000000000000000000000000000000000000020200f00000000000000000000000000000000000000000000000000000000002020190000000000000000000000000000000000000000000000000000000000202010000000000000000000000000000000000000000000000000000000000020201a0000000000000000000000000000000000000000000000000000000000202011000000000000000000000000000000000000000000000000000000000020201b0000000000000000000000000000000000000000000000000000000000202012000000000000000000000000000000000000000000000000000000000020201c0000000000000000000000000000000000000000000000000000000000202013000000000000000000000000000000000000000000000000000000000020201d0000000000000000000000000000000000000000000000000000000000202014000000000000000000000000000000000000000000000000000000000020201e0000000000000000000000000000000000000000000000000000000000202015000000000000000000000000000000000000000000000000000000000020201f00000000000000000000000000000000000000000000000000000000002020160000000000000000000000000000000000000000000000000000000000202020000000000000000000000000000000000000000000000000000000000020201700000000000000000000000000000000000000000000000000000000002020210000000000000000000000000000000000000000000000000000000000202018000000000000000000000000000000000000000000000000000000000020202200000000000000000000000000000000000000000000000000000000002020190000000000000000000000000000000000000000000000000000000000202023000000000000000000000000000000000000000000000000000000000020201a0000000000000000000000000000000000000000000000000000000000202024000000000000000000000000000000000000000000000000000000000020201b0000000000000000000000000000000000000000000000000000000000202025000000000000000000000000000000000000000000000000000000000020201c0000000000000000000000000000000000000000000000000000000000202026000000000000000000000000000000000000000000000000000000000020201d0000000000000000000000000000000000000000000000000000000000202027000000000000000000000000000000000000000000000000000000000020201e0000000000000000000000000000000000000000000000000000000000202028000000000000000000000000000000000000000000000000000000000020201f00000000000000000000000000000000000000000000000000000000002020290000000000000000000000000000000000000000000000000000000000202020000000000000000000000000000000000000000000000000000000000020202a0000000000000000000000000000000000000000000000000000000000202021000000000000000000000000000000000000000000000000000000000020202b0000000000000000000000000000000000000000000000000000000000202022000000000000000000000000000000000000000000000000000000000020202c0000000000000000000000000000000000000000000000000000000000202023000000000000000000000000000000000000000000000000000000000020202d0000000000000000000000000000000000000000000000000000000000202024000000000000000000000000000000000000000000000000000000000020202e0000000000000000000000000000000000000000000000000000000000202025000000000000000000000000000000000000000000000000000000000020202f00000000000000000000000000000000000000000000000000000000002020260000000000000000000000000000000000000000000000000000000000202030000000000000000000000000000000000000000000000000000000000020202700000000000000000000000000000000000000000000000000000000002020310000000000000000000000000000000000000000000000000000000000202028000000000000000000000000000000000000000000000000000000000020203200000000000000000000000000000000000000000000000000000000002020290000000000000000000000000000000000000000000000000000000000202033000000000000000000000000000000000000000000000000000000000020202a0000000000000000000000000000000000000000000000000000000000202034000000000000000000000000000000000000000000000000000000000020202b0000000000000000000000000000000000000000000000000000000000202035000000000000000000000000000000000000000000000000000000000020202c0000000000000000000000000000000000000000000000000000000000202036000000000000000000000000000000000000000000000000000000000020202d0000000000000000000000000000000000000000000000000000000000202037000000000000000000000000000000000000000000000000000000000020202e0000000000000000000000000000000000000000000000000000000000202038000000000000000000000000000000000000000000000000000000000020202f00000000000000000000000000000000000000000000000000000000002020390000000000000000000000000000000000000000000000000000000000202030000000000000000000000000000000000000000000000000000000000020203a0000000000000000000000000000000000000000000000000000000000202031000000000000000000000000000000000000000000000000000000000020203b0000000000000000000000000000000000000000000000000000000000202032000000000000000000000000000000000000000000000000000000000020203c0000000000000000000000000000000000000000000000000000000000202033000000000000000000000000000000000000000000000000000000000020203d0000000000000000000000000000000000000000000000000000000000202034000000000000000000000000000000000000000000000000000000000020203e0000000000000000000000000000000000000000000000000000000000202035000000000000000000000000000000000000000000000000000000000020203f00000000000000000000000000000000000000000000000000000000002020360000000000000000000000000000000000000000000000000000000000202040000000000000000000000000000000000000000000000000000000000020203700000000000000000000000000000000000000000000000000000000002020410000000000000000000000000000000000000000000000000000000000202038000000000000000000000000000000000000000000000000000000000020204200000000000000000000000000000000000000000000000000000000002020390000000000000000000000000000000000000000000000000000000000202043000000000000000000000000000000000000000000000000000000000020203a0000000000000000000000000000000000000000000000000000000000202044000000000000000000000000000000000000000000000000000000000020203b0000000000000000000000000000000000000000000000000000000000202045000000000000000000000000000000000000000000000000000000000020203c0000000000000000000000000000000000000000000000000000000000202046000000000000000000000000000000000000000000000000000000000020203d0000000000000000000000000000000000000000000000000000000000202047000000000000000000000000000000000000000000000000000000000020203e0000000000000000000000000000000000000000000000000000000000202048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "txsEffectsHash": "0x00e0afd1e2cddfe35e364bde6047d93fec56b54e7b925edc28b31546b645822d", "decodedHeader": { "contentCommitment": { "inHash": "0x00e1371045bd7d2c3e1f19cba5f536f0e82042ba4bc257d4ba19c146215e8242", - "outHash": "0x009514581058b2b6aae79574cc9129a801904407c6d869a5f168b02cebffecfe", - "numTxs": 8, - "txsEffectsHash": "0x00d2d12b4d0c6202124a7625c585097078920e09dd2c650401a91b564234a6b4" + "outHash": "0x00a5c37986316b1f5f2df53fa9ddf4965f539e872f5e1374f28d225540faca26", + "numTxs": 4, + "txsEffectsHash": "0x00e0afd1e2cddfe35e364bde6047d93fec56b54e7b925edc28b31546b645822d" }, "globalVariables": { "blockNumber": 2, "slotNumber": "0x0000000000000000000000000000000000000000000000000000000000000023", "chainId": 31337, - "timestamp": 1731434221, + "timestamp": 1732579254, "version": 1, - "coinbase": "0xa8f1a4313bc15dcd3681ed2b6fdd042f1ee1f823", - "feeRecipient": "0x2abdc96d2ec8465dfd2bb7401f90dd3af0db16c3cece57bd5de2b63a3d25140b", + "coinbase": "0x7bf63a9118e60cc630c4faa654223f715d4bd20e", + "feeRecipient": "0x2f2bacf41d88061f8a9e9234dfb8f6cdf5287e15eeeb4a6af5b0691d846bad5d", "gasFees": { "feePerDaGas": 0, - "feePerL2Gas": 0 + "feePerL2Gas": 54154341830 } }, + "totalFees": "0x0000000000000000000000000000000000000000000000000000000000000000", + "totalManaUsed": "0x0000000000000000000000000000000000000000000000000000000000000000", "lastArchive": { "nextAvailableLeafIndex": 2, - "root": "0x13232b1c92fcfba5f94aee813d7e454764f93d6292215552b8c973ef42c8e396" + "root": "0x0dd5f1f4c97e09c3d85323d27343341b245c49c5e7032c43c8b7c70d8b79629a" }, "stateReference": { "l1ToL2MessageTree": { @@ -133,14 +103,14 @@ "root": "0x2ed5c359f01d6a1cacfa324bc48b7fcc6fe75a95ad66bdb1a6e32d6907550957" }, "publicDataTree": { - "nextAvailableLeafIndex": 640, - "root": "0x23a39db7c42fa47a6df2b9deea545155c39f6066cbbc2701a12c60af95b6cdf9" + "nextAvailableLeafIndex": 632, + "root": "0x0c5783f9fe3a18bb5abd12daca67d280f6b5dfef250b7433dc059ce0d868b319" } } } }, - "header": "0x13232b1c92fcfba5f94aee813d7e454764f93d6292215552b8c973ef42c8e39600000002000000000000000000000000000000000000000000000000000000000000000800d2d12b4d0c6202124a7625c585097078920e09dd2c650401a91b564234a6b400e1371045bd7d2c3e1f19cba5f536f0e82042ba4bc257d4ba19c146215e8242009514581058b2b6aae79574cc9129a801904407c6d869a5f168b02cebffecfe026efb6c2a517de2448119d0f1255757265dbec7cdd2952df929ede666e10944000000202494d2575971bca59a28ddc774d19136f4a294951ab67258c7e9c2d8f9805924000002002ed5c359f01d6a1cacfa324bc48b7fcc6fe75a95ad66bdb1a6e32d69075509570000028023a39db7c42fa47a6df2b9deea545155c39f6066cbbc2701a12c60af95b6cdf9000002800000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002300000000000000000000000000000000000000000000000000000000673396eda8f1a4313bc15dcd3681ed2b6fdd042f1ee1f8232abdc96d2ec8465dfd2bb7401f90dd3af0db16c3cece57bd5de2b63a3d25140b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "publicInputsHash": "0x0010b7371af5e28ae8d1d0385e2ad3e28322dc403bfab0a6196947e5bb95143b", - "numTxs": 8 + "header": "0x0dd5f1f4c97e09c3d85323d27343341b245c49c5e7032c43c8b7c70d8b79629a00000002000000000000000000000000000000000000000000000000000000000000000400e0afd1e2cddfe35e364bde6047d93fec56b54e7b925edc28b31546b645822d00e1371045bd7d2c3e1f19cba5f536f0e82042ba4bc257d4ba19c146215e824200a5c37986316b1f5f2df53fa9ddf4965f539e872f5e1374f28d225540faca26026efb6c2a517de2448119d0f1255757265dbec7cdd2952df929ede666e10944000000202494d2575971bca59a28ddc774d19136f4a294951ab67258c7e9c2d8f9805924000002002ed5c359f01d6a1cacfa324bc48b7fcc6fe75a95ad66bdb1a6e32d6907550957000002800c5783f9fe3a18bb5abd12daca67d280f6b5dfef250b7433dc059ce0d868b319000002780000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000230000000000000000000000000000000000000000000000000000000067450fb67bf63a9118e60cc630c4faa654223f715d4bd20e2f2bacf41d88061f8a9e9234dfb8f6cdf5287e15eeeb4a6af5b0691d846bad5d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c9bd9adc600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "publicInputsHash": "0x00b2ae527c16d61b9ab56a964e90e6cf16142b95d0fc73dd966e5748c296c197", + "numTxs": 4 } } \ No newline at end of file diff --git a/l1-contracts/test/sparta/Sparta.t.sol b/l1-contracts/test/sparta/Sparta.t.sol index d94238a3a4f..9dff6c5babb 100644 --- a/l1-contracts/test/sparta/Sparta.t.sol +++ b/l1-contracts/test/sparta/Sparta.t.sol @@ -135,9 +135,9 @@ contract SpartaTest is DecoderBase { function testValidatorSetLargerThanCommittee(bool _insufficientSigs) public setup(100) { assertGt(rollup.getValidators().length, rollup.TARGET_COMMITTEE_SIZE(), "Not enough validators"); - uint256 committeSize = rollup.TARGET_COMMITTEE_SIZE() * 2 / 3 + (_insufficientSigs ? 0 : 1); + uint256 committeeSize = rollup.TARGET_COMMITTEE_SIZE() * 2 / 3 + (_insufficientSigs ? 0 : 1); - _testBlock("mixed_block_1", _insufficientSigs, committeSize, false); + _testBlock("mixed_block_1", _insufficientSigs, committeeSize, false); assertEq( rollup.getEpochCommittee(rollup.getCurrentEpoch()).length, @@ -163,7 +163,7 @@ contract SpartaTest is DecoderBase { string memory _name, bool _expectRevert, uint256 _signatureCount, - bool _invalidaProposer + bool _invalidProposer ) internal { DecoderBase.Full memory full = load(_name); bytes memory header = full.block.header; @@ -182,6 +182,11 @@ contract SpartaTest is DecoderBase { bytes32[] memory txHashes = new bytes32[](0); + // We update the header to have 0 as the base fee + assembly { + mstore(add(add(header, 0x20), 0x0228), 0) + } + ProposeArgs memory args = ProposeArgs({ header: header, archive: full.block.archive, @@ -216,7 +221,7 @@ contract SpartaTest is DecoderBase { // @todo Handle Leonidas__InsufficientAttestations case } - if (_expectRevert && _invalidaProposer) { + if (_expectRevert && _invalidProposer) { address realProposer = ree.proposer; ree.proposer = address(uint160(uint256(keccak256(abi.encode("invalid", ree.proposer))))); vm.expectRevert( diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/base_or_merge_rollup_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/base_or_merge_rollup_public_inputs.nr index ca62021ee1e..40a7a09f8fb 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/base_or_merge_rollup_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/base_or_merge_rollup_public_inputs.nr @@ -28,6 +28,7 @@ pub struct BaseOrMergeRollupPublicInputs { out_hash: Field, accumulated_fees: Field, + accumulated_mana_used: Field, } impl Empty for BaseOrMergeRollupPublicInputs { @@ -41,6 +42,7 @@ impl Empty for BaseOrMergeRollupPublicInputs { txs_effects_hash: 0, out_hash: 0, accumulated_fees: 0, + accumulated_mana_used: 0, } } } @@ -55,6 +57,7 @@ impl Eq for BaseOrMergeRollupPublicInputs { & (self.txs_effects_hash == other.txs_effects_hash) & (self.out_hash == other.out_hash) & (self.accumulated_fees == other.accumulated_fees) + & (self.accumulated_mana_used == other.accumulated_mana_used) } } @@ -70,7 +73,7 @@ impl Serialize for BaseOrMergeRollupPublicIn fields.push(self.txs_effects_hash as Field); fields.push(self.out_hash as Field); fields.push(self.accumulated_fees as Field); - + fields.push(self.accumulated_mana_used as Field); assert_eq(fields.len(), BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH); fields.storage() @@ -91,6 +94,7 @@ impl Deserialize for BaseOrMergeRollupPublic txs_effects_hash: reader.read(), out_hash: reader.read(), accumulated_fees: reader.read(), + accumulated_mana_used: reader.read(), }; reader.finish(); diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/private_base_rollup.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/private_base_rollup.nr index 6afb8711abc..e1c000a7b78 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/private_base_rollup.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/private_base_rollup.nr @@ -140,6 +140,7 @@ impl PrivateBaseRollupInputs { txs_effects_hash: tx_effects_hash, out_hash, accumulated_fees: transaction_fee, + accumulated_mana_used: self.tube_data.public_inputs.gas_used.l2_gas as Field, } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/public_base_rollup.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/public_base_rollup.nr index 8996d5200d5..c7a689749da 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/public_base_rollup.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/public_base_rollup.nr @@ -212,6 +212,7 @@ impl PublicBaseRollupInputs { txs_effects_hash: tx_effects_hash, out_hash, accumulated_fees: self.avm_proof_data.public_inputs.transaction_fee, + accumulated_mana_used: self.avm_proof_data.public_inputs.end_gas_used.l2_gas as Field, } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_rollup_inputs.nr index bf64b16d093..751dc299204 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_rollup_inputs.nr @@ -96,6 +96,8 @@ impl BlockRootRollupInputs { let total_fees = components::accumulate_fees(left, right); + let total_mana_used = components::accumulate_mana_used(left, right); + // unsafe { // debug_log_format("Assembling header in block root rollup", []); // debug_log_format( @@ -112,6 +114,7 @@ impl BlockRootRollupInputs { // left.constants.global_variables.serialize() // ); // debug_log_format("header.total_fees={0}", [total_fees]); + // debug_log_format("header.total_mana_used={0}", [total_mana_used]); // } let header = Header { last_archive: left.constants.last_archive, @@ -119,6 +122,7 @@ impl BlockRootRollupInputs { state, global_variables: left.constants.global_variables, total_fees, + total_mana_used, }; // Build the block hash for this by hashing the header and then insert the new leaf to archive tree. diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr index 217ba2e1b37..b64c764295a 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr @@ -139,6 +139,13 @@ pub fn accumulate_fees( left.accumulated_fees + right.accumulated_fees } +pub fn accumulate_mana_used( + left: BaseOrMergeRollupPublicInputs, + right: BaseOrMergeRollupPublicInputs, +) -> Field { + left.accumulated_mana_used + right.accumulated_mana_used +} + pub fn accumulate_blocks_fees( left: BlockRootOrBlockMergePublicInputs, right: BlockRootOrBlockMergePublicInputs, diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/merge/merge_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/merge/merge_rollup_inputs.nr index cc45af921a1..0b4867533f8 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/merge/merge_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/merge/merge_rollup_inputs.nr @@ -48,6 +48,8 @@ impl MergeRollupInputs { let accumulated_fees = components::accumulate_fees(left, right); + let accumulated_mana_used = components::accumulate_mana_used(left, right); + let public_inputs = BaseOrMergeRollupPublicInputs { rollup_type: MERGE_ROLLUP_TYPE, num_txs: left.num_txs + right.num_txs, @@ -57,6 +59,7 @@ impl MergeRollupInputs { txs_effects_hash, out_hash, accumulated_fees, + accumulated_mana_used, }; public_inputs diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr index 33ceb64fc60..f66f0418fe7 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr @@ -201,6 +201,14 @@ fn compute_address_from_partial_and_pub_keys() { assert(address.to_field() == expected_computed_address_from_partial_and_pubkeys); } +#[test] +fn compute_preaddress_from_partial_and_pub_keys() { + let pre_address = poseidon2_hash_with_separator([1, 2], GENERATOR_INDEX__CONTRACT_ADDRESS_V1); + let expected_computed_preaddress_from_partial_and_pubkey = + 0x23ce9be3fa3c846b0f9245cc796902e731d04f086e8a42473bb29e405fc98075; + assert(pre_address == expected_computed_preaddress_from_partial_and_pubkey); +} + #[test] fn from_field_to_field() { let address = AztecAddress { inner: 37 }; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index a42e4d82145..130633113da 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -135,7 +135,7 @@ pub global AZTEC_MAX_EPOCH_DURATION: u32 = 32; // The following is taken from building a block and looking at the `lastArchive` value in it. // You can run the `integration_l1_publisher.test.ts` and look at the first blocks in the fixtures. pub global GENESIS_ARCHIVE_ROOT: Field = - 0x2a05cb8aeefe9b9797f90650eae072f5ab7437807e62f9724ce1900467779860; + 0x0237797d6a2c04d20d4fa06b74482bd970ccd51a43d9b05b57e9b91fa1ae1cae; // The following and the value in `deploy_l1_contracts` must match. We should not have the code both places, but // we are running into circular dependency issues. #3342 global FEE_JUICE_INITIAL_MINT: Field = 20000000000000000000; @@ -306,11 +306,13 @@ pub global TREE_SNAPSHOTS_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH * 4; pub global TX_CONTEXT_LENGTH: u32 = 2 + GAS_SETTINGS_LENGTH; pub global TX_REQUEST_LENGTH: u32 = 2 + TX_CONTEXT_LENGTH + FUNCTION_DATA_LENGTH; pub global TOTAL_FEES_LENGTH: u32 = 1; +pub global TOTAL_MANA_USED_LENGTH: u32 = 1; pub global HEADER_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + CONTENT_COMMITMENT_LENGTH + STATE_REFERENCE_LENGTH + GLOBAL_VARIABLES_LENGTH - + TOTAL_FEES_LENGTH; + + TOTAL_FEES_LENGTH + + TOTAL_MANA_USED_LENGTH; pub global PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = CALL_CONTEXT_LENGTH + 4 + MAX_BLOCK_NUMBER_LENGTH @@ -450,11 +452,11 @@ pub global CONSTANT_ROLLUP_DATA_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + 1 /* protocol_contract_tree_root */ + GLOBAL_VARIABLES_LENGTH; -// + 5 for rollup_type, height_in_block_tree, txs_effects_hash, out_hash, accumulated_fees +// + 5 for rollup_type, height_in_block_tree, txs_effects_hash, out_hash, accumulated_fees, accumulated_mana_used pub global BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH: u32 = CONSTANT_ROLLUP_DATA_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH - + 5; + + 6; pub global BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH: u32 = 2 * APPEND_ONLY_TREE_SNAPSHOT_LENGTH + 1 /* previous_block_hash */ diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/header.nr b/noir-projects/noir-protocol-circuits/crates/types/src/header.nr index 23e9c6a2a87..5817cdb7e18 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/header.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/header.nr @@ -21,6 +21,7 @@ pub struct Header { pub state: StateReference, pub global_variables: GlobalVariables, pub total_fees: Field, + pub total_mana_used: Field, } // docs:end:header @@ -31,6 +32,7 @@ impl Eq for Header { & self.state.eq(other.state) & self.global_variables.eq(other.global_variables) & self.total_fees.eq(other.total_fees) + & self.total_mana_used.eq(other.total_mana_used) } } @@ -43,7 +45,7 @@ impl Serialize for Header { fields.extend_from_array(self.state.serialize()); fields.extend_from_array(self.global_variables.serialize()); fields.push(self.total_fees); - + fields.push(self.total_mana_used); fields.storage() } } @@ -68,6 +70,9 @@ impl Deserialize for Header { offset = offset + GLOBAL_VARIABLES_LENGTH; let total_fees = serialized[offset]; + offset = offset + 1; + + let total_mana_used = serialized[offset]; Header { last_archive: AppendOnlyTreeSnapshot::deserialize(last_archive_fields), @@ -75,6 +80,7 @@ impl Deserialize for Header { state: StateReference::deserialize(state_fields), global_variables: GlobalVariables::deserialize(global_variables_fields), total_fees, + total_mana_used, } } } @@ -87,6 +93,7 @@ impl Empty for Header { state: StateReference::empty(), global_variables: GlobalVariables::empty(), total_fees: 0, + total_mana_used: 0, } } } @@ -117,6 +124,6 @@ fn empty_hash_is_zero() { let hash = header.hash(); // Value from new_contract_data.test.ts "computes empty hash" test - let test_data_empty_hash = 0x1c97ed6fbc35f8b400d31bd38ce5cc938921e0cf2e20159d316f8c7011f9f42c; + let test_data_empty_hash = 0x28e48e620bc00817609b5fc765bc74864561f25a3c941b33e5ee05266b752839; assert_eq(hash, test_data_empty_hash); } diff --git a/yarn-project/archiver/src/archiver/data_retrieval.ts b/yarn-project/archiver/src/archiver/data_retrieval.ts index d6ce1653c4c..3249a5fc541 100644 --- a/yarn-project/archiver/src/archiver/data_retrieval.ts +++ b/yarn-project/archiver/src/archiver/data_retrieval.ts @@ -291,11 +291,20 @@ export async function getProofFromSubmitProofTx( let proof: Proof; if (functionName === 'submitEpochRootProof') { - const [_epochSize, nestedArgs, _fees, aggregationObjectHex, proofHex] = args!; - aggregationObject = Buffer.from(hexToBytes(aggregationObjectHex)); - proverId = Fr.fromString(nestedArgs[6]); - archiveRoot = Fr.fromString(nestedArgs[1]); - proof = Proof.fromBuffer(Buffer.from(hexToBytes(proofHex))); + const [decodedArgs] = args as readonly [ + { + epochSize: bigint; + args: readonly [Hex, Hex, Hex, Hex, Hex, Hex, Hex]; + fees: readonly Hex[]; + aggregationObject: Hex; + proof: Hex; + }, + ]; + + aggregationObject = Buffer.from(hexToBytes(decodedArgs.aggregationObject)); + proverId = Fr.fromString(decodedArgs.args[6]); + archiveRoot = Fr.fromString(decodedArgs.args[1]); + proof = Proof.fromBuffer(Buffer.from(hexToBytes(decodedArgs.proof))); } else { throw new Error(`Unexpected proof method called ${functionName}`); } diff --git a/yarn-project/aztec.js/src/contract/base_contract_interaction.ts b/yarn-project/aztec.js/src/contract/base_contract_interaction.ts index b62583c13ca..d36ea1fc2d2 100644 --- a/yarn-project/aztec.js/src/contract/base_contract_interaction.ts +++ b/yarn-project/aztec.js/src/contract/base_contract_interaction.ts @@ -19,6 +19,8 @@ export type SendMethodOptions = { fee?: FeeOptions; /** Whether to run an initial simulation of the tx with high gas limit to figure out actual gas settings (will default to true later down the road). */ estimateGas?: boolean; + /** Percentage to pad the suggested gas limits by, if empty, defaults to 10%. */ + estimatedGasPad?: number; /** Custom nonce to inject into the app payload of the transaction. Useful when trying to cancel an ongoing transaction by creating a new one with a higher fee */ nonce?: Fr; /** Whether the transaction can be cancelled. If true, an extra nullifier will be emitted: H(nonce, GENERATOR_INDEX__TX_NULLIFIER) */ @@ -84,6 +86,7 @@ export abstract class BaseContractInteraction { /** * Estimates gas for a given tx request and returns gas limits for it. * @param opts - Options. + * @param pad - Percentage to pad the suggested gas limits by, if empty, defaults to 10%. * @returns Gas limits. */ public async estimateGas( @@ -91,21 +94,25 @@ export abstract class BaseContractInteraction { ): Promise> { const txRequest = await this.create({ ...opts, estimateGas: false }); const simulationResult = await this.wallet.simulateTx(txRequest, true); - const { totalGas: gasLimits, teardownGas: teardownGasLimits } = getGasLimits(simulationResult); + const { totalGas: gasLimits, teardownGas: teardownGasLimits } = getGasLimits( + simulationResult, + opts?.estimatedGasPad, + ); return { gasLimits, teardownGasLimits }; } /** * Helper method to return fee options based on the user opts, estimating tx gas if needed. * @param request - Request to execute for this interaction. + * @param pad - Percentage to pad the suggested gas limits by, as decimal (e.g., 0.10 for 10%). * @returns Fee options for the actual transaction. */ - protected async getFeeOptionsFromEstimatedGas(request: ExecutionRequestInit) { + protected async getFeeOptionsFromEstimatedGas(request: ExecutionRequestInit, pad?: number) { const fee = request.fee; if (fee) { const txRequest = await this.wallet.createTxExecutionRequest(request); const simulationResult = await this.wallet.simulateTx(txRequest, true); - const { totalGas: gasLimits, teardownGas: teardownGasLimits } = getGasLimits(simulationResult); + const { totalGas: gasLimits, teardownGas: teardownGasLimits } = getGasLimits(simulationResult, pad); this.log.debug( `Estimated gas limits for tx: DA=${gasLimits.daGas} L2=${gasLimits.l2Gas} teardownDA=${teardownGasLimits.daGas} teardownL2=${teardownGasLimits.l2Gas}`, ); diff --git a/yarn-project/aztec.js/src/contract/batch_call.ts b/yarn-project/aztec.js/src/contract/batch_call.ts index 31f6ce37df1..501711e4400 100644 --- a/yarn-project/aztec.js/src/contract/batch_call.ts +++ b/yarn-project/aztec.js/src/contract/batch_call.ts @@ -19,7 +19,9 @@ export class BatchCall extends BaseContractInteraction { */ public async create(opts?: SendMethodOptions): Promise { const calls = this.calls; - const fee = opts?.estimateGas ? await this.getFeeOptionsFromEstimatedGas({ calls, fee: opts?.fee }) : opts?.fee; + const fee = opts?.estimateGas + ? await this.getFeeOptionsFromEstimatedGas({ calls, fee: opts?.fee }, opts?.estimatedGasPad) + : opts?.fee; return await this.wallet.createTxExecutionRequest({ calls, fee }); } diff --git a/yarn-project/aztec.js/src/contract/contract_function_interaction.ts b/yarn-project/aztec.js/src/contract/contract_function_interaction.ts index d9bf7ff2192..ba033b21b1a 100644 --- a/yarn-project/aztec.js/src/contract/contract_function_interaction.ts +++ b/yarn-project/aztec.js/src/contract/contract_function_interaction.ts @@ -63,7 +63,9 @@ export class ContractFunctionInteraction extends BaseContractInteraction { throw new Error("Can't call `create` on an unconstrained function."); } const calls = [this.request()]; - const fee = opts?.estimateGas ? await this.getFeeOptionsFromEstimatedGas({ calls, fee: opts?.fee }) : opts?.fee; + const fee = opts?.estimateGas + ? await this.getFeeOptionsFromEstimatedGas({ calls, fee: opts?.fee }, opts?.estimatedGasPad) + : opts?.fee; const txRequest = await this.wallet.createTxExecutionRequest({ calls, fee, diff --git a/yarn-project/aztec.js/src/contract/deploy_method.ts b/yarn-project/aztec.js/src/contract/deploy_method.ts index 96651e470e4..caf696cb5f9 100644 --- a/yarn-project/aztec.js/src/contract/deploy_method.ts +++ b/yarn-project/aztec.js/src/contract/deploy_method.ts @@ -112,7 +112,7 @@ export class DeployMethod extends Bas }; if (options.estimateGas) { - request.fee = await this.getFeeOptionsFromEstimatedGas(request); + request.fee = await this.getFeeOptionsFromEstimatedGas(request, options.estimatedGasPad); } return request; diff --git a/yarn-project/aztec.js/src/contract/get_gas_limits.ts b/yarn-project/aztec.js/src/contract/get_gas_limits.ts index 1d740c558bc..a6e0e7196fb 100644 --- a/yarn-project/aztec.js/src/contract/get_gas_limits.ts +++ b/yarn-project/aztec.js/src/contract/get_gas_limits.ts @@ -3,7 +3,7 @@ import { type GasUsed, type TxSimulationResult } from '@aztec/circuit-types'; /** * Returns suggested total and teardown gas limits for a simulated tx. * Note that public gas usage is only accounted for if the publicOutput is present. - * @param pad - Percentage to pad the suggested gas limits by, defaults to 10%. + * @param pad - Percentage to pad the suggested gas limits by, (as decimal, e.g., 0.10 for 10%). */ export function getGasLimits(simulationResult: TxSimulationResult, pad = 0.1): GasUsed { return { diff --git a/yarn-project/circuit-types/src/l2_block_code_to_purge.ts b/yarn-project/circuit-types/src/l2_block_code_to_purge.ts index 68b0cc3528a..64e2e06db9e 100644 --- a/yarn-project/circuit-types/src/l2_block_code_to_purge.ts +++ b/yarn-project/circuit-types/src/l2_block_code_to_purge.ts @@ -30,6 +30,7 @@ export function makeHeader( makeStateReference(seed + 0x600), makeGlobalVariables((seed += 0x700), blockNumber, slotNumber ?? blockNumber), fr(seed + 0x800), + fr(seed + 0x900), ); } diff --git a/yarn-project/circuit-types/src/test/factories.ts b/yarn-project/circuit-types/src/test/factories.ts index 41aeb67306c..a9e4335a2e1 100644 --- a/yarn-project/circuit-types/src/test/factories.ts +++ b/yarn-project/circuit-types/src/test/factories.ts @@ -18,7 +18,7 @@ import { ScopedLogHash, TxConstantData, } from '@aztec/circuits.js'; -import { makeCombinedAccumulatedData, makeGas, makePrivateToPublicAccumulatedData } from '@aztec/circuits.js/testing'; +import { makeCombinedAccumulatedData, makePrivateToPublicAccumulatedData } from '@aztec/circuits.js/testing'; import { makeTuple } from '@aztec/foundation/array'; import { type MerkleTreeReadOperations } from '../interfaces/merkle_tree_operations.js'; @@ -124,8 +124,8 @@ export function makeBloatedProcessedTx({ ); const gasUsed = { - totalGas: makeGas(), - teardownGas: makeGas(), + totalGas: Gas.empty(), + teardownGas: Gas.empty(), }; return makeProcessedTxFromTxWithPublicCalls( diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 75878e5adc9..f015aacd3a2 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -82,7 +82,7 @@ export const INITIAL_L2_BLOCK_NUM = 1; export const PRIVATE_LOG_SIZE_IN_BYTES = 576; export const BLOB_SIZE_IN_BYTES = 126976; export const AZTEC_MAX_EPOCH_DURATION = 32; -export const GENESIS_ARCHIVE_ROOT = 19007378675971183768036762391356802220352606103602592933942074152320327194720n; +export const GENESIS_ARCHIVE_ROOT = 1002640778211850180189505934749257244705296832326768971348723156503780793518n; export const FEE_JUICE_INITIAL_MINT = 20000000000000000000n; export const FEE_FUNDING_FOR_TESTER_ACCOUNT = 100000000000000000000n; export const PUBLIC_DISPATCH_SELECTOR = 3578010381; @@ -179,29 +179,30 @@ export const TREE_SNAPSHOTS_LENGTH = 8; export const TX_CONTEXT_LENGTH = 8; export const TX_REQUEST_LENGTH = 12; export const TOTAL_FEES_LENGTH = 1; -export const HEADER_LENGTH = 24; -export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 490; -export const PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 866; -export const PRIVATE_CONTEXT_INPUTS_LENGTH = 37; +export const TOTAL_MANA_USED_LENGTH = 1; +export const HEADER_LENGTH = 25; +export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 491; +export const PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 867; +export const PRIVATE_CONTEXT_INPUTS_LENGTH = 38; export const FEE_RECIPIENT_LENGTH = 2; export const AGGREGATION_OBJECT_LENGTH = 16; export const SCOPED_READ_REQUEST_LEN = 3; export const PUBLIC_DATA_READ_LENGTH = 3; export const PRIVATE_VALIDATION_REQUESTS_LENGTH = 772; export const COMBINED_ACCUMULATED_DATA_LENGTH = 550; -export const TX_CONSTANT_DATA_LENGTH = 34; -export const COMBINED_CONSTANT_DATA_LENGTH = 43; +export const TX_CONSTANT_DATA_LENGTH = 35; +export const COMBINED_CONSTANT_DATA_LENGTH = 44; export const PRIVATE_ACCUMULATED_DATA_LENGTH = 1036; -export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1849; +export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1850; export const PRIVATE_TO_PUBLIC_ACCUMULATED_DATA_LENGTH = 548; export const PRIVATE_TO_AVM_ACCUMULATED_DATA_LENGTH = 160; export const NUM_PRIVATE_TO_AVM_ACCUMULATED_DATA_ARRAYS = 3; export const AVM_ACCUMULATED_DATA_LENGTH = 318; -export const PRIVATE_TO_PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1140; -export const KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 605; +export const PRIVATE_TO_PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1141; +export const KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 606; export const AVM_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1006; export const CONSTANT_ROLLUP_DATA_LENGTH = 13; -export const BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH = 30; +export const BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH = 31; export const BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH = 90; export const ROOT_ROLLUP_PUBLIC_INPUTS_LENGTH = 76; export const GET_NOTES_ORACLE_RETURN_LENGTH = 674; @@ -223,7 +224,7 @@ export const CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS = 143; export const AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS = 86; export const AVM_PROOF_LENGTH_IN_FIELDS = 4166; export const AVM_PUBLIC_COLUMN_MAX_SIZE = 1024; -export const AVM_PUBLIC_INPUTS_FLATTENED_SIZE = 2914; +export const AVM_PUBLIC_INPUTS_FLATTENED_SIZE = 2915; export const MEM_TAG_FF = 0; export const MEM_TAG_U1 = 1; export const MEM_TAG_U8 = 2; diff --git a/yarn-project/circuits.js/src/contract/artifact_hash.test.ts b/yarn-project/circuits.js/src/contract/artifact_hash.test.ts index 74b7db7c485..070ca03ba9b 100644 --- a/yarn-project/circuits.js/src/contract/artifact_hash.test.ts +++ b/yarn-project/circuits.js/src/contract/artifact_hash.test.ts @@ -7,6 +7,8 @@ import { readFileSync } from 'fs'; import { getPathToFixture, getTestContractArtifact } from '../tests/fixtures.js'; import { computeArtifactHash } from './artifact_hash.js'; +const TEST_CONTRACT_ARTIFACT_HASH = `"0x08f4e5d2a0be9dc5c31894f88aaa93d353918078cd7fdfbbc7818ec3f2268b77"`; + describe('ArtifactHash', () => { it('calculates the artifact hash', () => { const emptyArtifact: ContractArtifact = { @@ -29,9 +31,7 @@ describe('ArtifactHash', () => { const testArtifact = getTestContractArtifact(); for (let i = 0; i < 1000; i++) { - expect(computeArtifactHash(testArtifact).toString()).toMatchInlineSnapshot( - `"0x21070d88558fdc3906322f267cf6f0f632caf3949295520fe1f71f156fbb0d0b"`, - ); + expect(computeArtifactHash(testArtifact).toString()).toMatchInlineSnapshot(TEST_CONTRACT_ARTIFACT_HASH); } }); @@ -42,8 +42,6 @@ describe('ArtifactHash', () => { const testArtifact = loadContractArtifact(content); - expect(computeArtifactHash(testArtifact).toString()).toMatchInlineSnapshot( - `"0x21070d88558fdc3906322f267cf6f0f632caf3949295520fe1f71f156fbb0d0b"`, - ); + expect(computeArtifactHash(testArtifact).toString()).toMatchInlineSnapshot(TEST_CONTRACT_ARTIFACT_HASH); }); }); diff --git a/yarn-project/circuits.js/src/keys/derivation.test.ts b/yarn-project/circuits.js/src/keys/derivation.test.ts index bc84cb8b17f..23a230a4f2c 100644 --- a/yarn-project/circuits.js/src/keys/derivation.test.ts +++ b/yarn-project/circuits.js/src/keys/derivation.test.ts @@ -23,7 +23,7 @@ describe('🔑', () => { // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data updateInlineTestData( - 'noir-projects/aztec-nr/aztec/src/keys/public_keys.nr', + 'noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr', 'expected_public_keys_hash', expected.toString(), ); diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/header.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/header.test.ts.snap index b8d2132567f..175c31be182 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/header.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/__snapshots__/header.test.ts.snap @@ -1,5 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Header computes empty hash 1`] = `Fr<0x1c97ed6fbc35f8b400d31bd38ce5cc938921e0cf2e20159d316f8c7011f9f42c>`; +exports[`Header computes empty hash 1`] = `Fr<0x28e48e620bc00817609b5fc765bc74864561f25a3c941b33e5ee05266b752839>`; -exports[`Header computes hash 1`] = `Fr<0x305c2bb392f94210b9505dda720c1295cc625634c30f47f2798ccac9985d016e>`; +exports[`Header computes hash 1`] = `Fr<0x2352a779093c231d53586b8c09d3d63033327f5f80029f007fe9deedc67c4be3>`; diff --git a/yarn-project/circuits.js/src/structs/header.ts b/yarn-project/circuits.js/src/structs/header.ts index 654d202eb51..21be70c0717 100644 --- a/yarn-project/circuits.js/src/structs/header.ts +++ b/yarn-project/circuits.js/src/structs/header.ts @@ -27,6 +27,8 @@ export class Header { public globalVariables: GlobalVariables, /** Total fees in the block, computed by the root rollup circuit */ public totalFees: Fr, + /** Total mana used in the block, computed by the root rollup circuit */ + public totalManaUsed: Fr, ) {} static get schema() { @@ -37,6 +39,7 @@ export class Header { state: StateReference.schema, globalVariables: GlobalVariables.schema, totalFees: schemas.Fr, + totalManaUsed: schemas.Fr, }) .transform(Header.from); } @@ -49,6 +52,7 @@ export class Header { fields.state, fields.globalVariables, fields.totalFees, + fields.totalManaUsed, ] as const; } @@ -62,7 +66,8 @@ export class Header { this.contentCommitment.getSize() + this.state.getSize() + this.globalVariables.getSize() + - this.totalFees.size + this.totalFees.size + + this.totalManaUsed.size ); } @@ -91,6 +96,7 @@ export class Header { reader.readObject(StateReference), reader.readObject(GlobalVariables), reader.readObject(Fr), + reader.readObject(Fr), ); } @@ -103,6 +109,7 @@ export class Header { StateReference.fromFields(reader), GlobalVariables.fromFields(reader), reader.readField(), + reader.readField(), ); } @@ -113,6 +120,7 @@ export class Header { state: StateReference.empty(), globalVariables: GlobalVariables.empty(), totalFees: Fr.ZERO, + totalManaUsed: Fr.ZERO, ...fields, }); } @@ -122,7 +130,9 @@ export class Header { this.lastArchive.isZero() && this.contentCommitment.isEmpty() && this.state.isEmpty() && - this.globalVariables.isEmpty() + this.globalVariables.isEmpty() && + this.totalFees.isZero() && + this.totalManaUsed.isZero() ); } @@ -155,6 +165,7 @@ export class Header { state.publicDataTree: ${inspect(this.state.partial.publicDataTree)}, globalVariables: ${inspect(this.globalVariables)}, totalFees: ${this.totalFees}, + totalManaUsed: ${this.totalManaUsed}, }`; } @@ -164,6 +175,7 @@ export class Header { this.state.equals(other.state) && this.globalVariables.equals(other.globalVariables) && this.totalFees.equals(other.totalFees) && + this.totalManaUsed.equals(other.totalManaUsed) && this.lastArchive.equals(other.lastArchive) ); } diff --git a/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts index c42337e1c0f..4ad09b59c2c 100644 --- a/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts @@ -47,6 +47,10 @@ export class BaseOrMergeRollupPublicInputs { * The summed `transaction_fee` of the constituent transactions. */ public accumulatedFees: Fr, + /** + * The summed `mana_used` of the constituent transactions. + */ + public accumulatedManaUsed: Fr, ) {} /** Returns an empty instance. */ @@ -60,6 +64,7 @@ export class BaseOrMergeRollupPublicInputs { Fr.zero(), Fr.zero(), Fr.zero(), + Fr.zero(), ); } @@ -81,6 +86,7 @@ export class BaseOrMergeRollupPublicInputs { Fr.fromBuffer(reader), Fr.fromBuffer(reader), Fr.fromBuffer(reader), + Fr.fromBuffer(reader), ); } @@ -101,6 +107,7 @@ export class BaseOrMergeRollupPublicInputs { this.outHash, this.accumulatedFees, + this.accumulatedManaUsed, ); } diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 3a2da20f3e9..1fce585ae3b 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -691,6 +691,7 @@ export function makeBaseOrMergeRollupPublicInputs( fr(seed + 0x901), fr(seed + 0x902), fr(seed + 0x903), + fr(seed + 0x904), ); } @@ -894,6 +895,7 @@ export function makeHeader( ...(slotNumber ? { slotNumber: new Fr(slotNumber) } : {}), }), fr(seed + 0x800), + fr(seed + 0x900), ); } diff --git a/yarn-project/cli/src/utils/inspect.ts b/yarn-project/cli/src/utils/inspect.ts index 77d6c067a7e..4423b9bc882 100644 --- a/yarn-project/cli/src/utils/inspect.ts +++ b/yarn-project/cli/src/utils/inspect.ts @@ -15,6 +15,7 @@ export async function inspectBlock(pxe: PXE, blockNumber: number, log: LogFn, op log(`Block ${blockNumber} (${block.hash().toString()})`); log(` Total fees: ${block.header.totalFees.toBigInt()}`); + log(` Total mana used: ${block.header.totalManaUsed.toBigInt()}`); log( ` Fee per gas unit: DA=${block.header.globalVariables.gasFees.feePerDaGas.toBigInt()} L2=${block.header.globalVariables.gasFees.feePerL2Gas.toBigInt()}`, ); diff --git a/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts index c14e843afb2..b0bdace0d02 100644 --- a/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/composed/integration_l1_publisher.test.ts @@ -3,8 +3,7 @@ import { getConfigEnvVars } from '@aztec/aztec-node'; import { AztecAddress, EthCheatCodes, Fr, GlobalVariables, type L2Block, createDebugLogger } from '@aztec/aztec.js'; // eslint-disable-next-line no-restricted-imports import { - type BlockBuilder, - type MerkleTreeWriteOperations, + type L2Tips, type ProcessedTx, makeEmptyProcessedTx as makeEmptyProcessedTxFromHistoricalTreeRoots, } from '@aztec/circuit-types'; @@ -81,14 +80,13 @@ describe('L1Publisher integration', () => { let publisher: L1Publisher; - let builder: BlockBuilder; let builderDb: MerkleTreeAdminDatabase; - let fork: MerkleTreeWriteOperations; // The header of the last block let prevHeader: Header; let blockSource: MockProxy; + let blocks: L2Block[] = []; const chainId = createEthereumChain(config.l1RpcUrl, config.l1ChainId).chainInfo.id; @@ -139,12 +137,30 @@ describe('L1Publisher integration', () => { }); builderDb = await NativeWorldStateService.tmp(EthAddress.fromString(rollupAddress)); - blockSource = mock(); - blockSource.getBlocks.mockResolvedValue([]); + blocks = []; + blockSource = mock({ + getBlocks(from, limit, _proven) { + return Promise.resolve(blocks.slice(from - 1, from - 1 + limit)); + }, + getL2Tips(): Promise { + const latestBlock = blocks.at(-1); + const res = latestBlock + ? { number: latestBlock.number, hash: latestBlock.hash.toString() } + : { number: 0, hash: undefined }; + + return Promise.resolve({ + latest: res, + proven: res, + finalized: res, + } as L2Tips); + }, + }); + const worldStateConfig: WorldStateConfig = { worldStateBlockCheckIntervalMS: 10000, worldStateProvenBlocksOnly: false, worldStateDbMapSizeKb: 10 * 1024 * 1024, + worldStateBlockHistory: 0, }; worldStateSynchronizer = new ServerWorldStateSynchronizer( builderDb, @@ -153,8 +169,6 @@ describe('L1Publisher integration', () => { new NoopTelemetryClient(), ); await worldStateSynchronizer.start(); - fork = await worldStateSynchronizer.fork(); - builder = new LightweightBlockBuilder(fork, new NoopTelemetryClient()); publisher = new L1Publisher( { @@ -173,7 +187,10 @@ describe('L1Publisher integration', () => { coinbase = config.coinbase || EthAddress.random(); feeRecipient = config.feeRecipient || AztecAddress.random(); + const fork = await worldStateSynchronizer.fork(); + prevHeader = fork.getInitialHeader(); + await fork.close(); // We jump to the next epoch such that the committee can be setup. const timeToJump = await rollup.read.EPOCH_DURATION(); @@ -181,7 +198,6 @@ describe('L1Publisher integration', () => { }); afterEach(async () => { - await fork.close(); await worldStateSynchronizer.stop(); }); @@ -266,6 +282,8 @@ describe('L1Publisher integration', () => { feePerL2Gas: block.header.globalVariables.gasFees.feePerL2Gas.toNumber(), }, }, + totalFees: `0x${block.header.totalFees.toBuffer().toString('hex').padStart(64, '0')}`, + totalManaUsed: `0x${block.header.totalManaUsed.toBuffer().toString('hex').padStart(64, '0')}`, lastArchive: { nextAvailableLeafIndex: block.header.lastArchive.nextAvailableLeafIndex, root: `0x${block.header.lastArchive.root.toBuffer().toString('hex').padStart(64, '0')}`, @@ -305,11 +323,16 @@ describe('L1Publisher integration', () => { }; const buildBlock = async (globalVariables: GlobalVariables, txs: ProcessedTx[], l1ToL2Messages: Fr[]) => { - await builder.startNewBlock(txs.length, globalVariables, l1ToL2Messages); + await worldStateSynchronizer.syncImmediate(); + const tempFork = await worldStateSynchronizer.fork(); + const tempBuilder = new LightweightBlockBuilder(tempFork, new NoopTelemetryClient()); + await tempBuilder.startNewBlock(txs.length, globalVariables, l1ToL2Messages); for (const tx of txs) { - await builder.addNewTx(tx); + await tempBuilder.addNewTx(tx); } - return builder.setBlockCompleted(); + const block = await tempBuilder.setBlockCompleted(); + await tempFork.close(); + return block; }; describe('block building', () => { @@ -327,9 +350,6 @@ describe('L1Publisher integration', () => { let nextL1ToL2Messages: Fr[] = []; for (let i = 0; i < numberOfConsecutiveBlocks; i++) { - // @note Make sure that the state is up to date before we start building. - await worldStateSynchronizer.syncImmediate(); - const l1ToL2Content = range(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, 128 * i + 1 + 0x400).map(fr); for (let j = 0; j < l1ToL2Content.length; j++) { @@ -360,9 +380,11 @@ describe('L1Publisher integration', () => { ); const block = await buildBlock(globalVariables, txs, currentL1ToL2Messages); + const totalManaUsed = txs.reduce((acc, tx) => acc.add(new Fr(tx.gasUsed.totalGas.l2Gas)), Fr.ZERO); + expect(totalManaUsed.toBigInt()).toEqual(block.header.totalManaUsed.toBigInt()); + prevHeader = block.header; blockSource.getL1ToL2Messages.mockResolvedValueOnce(currentL1ToL2Messages); - blockSource.getBlocks.mockResolvedValueOnce([block]); const l2ToL1MsgsArray = block.body.txEffects.flatMap(txEffect => txEffect.l2ToL1Msgs); @@ -374,6 +396,7 @@ describe('L1Publisher integration', () => { writeJson(`mixed_block_${block.number}`, block, l1ToL2Content, recipientAddress, deployerAccount.address); await publisher.proposeL2Block(block); + blocks.push(block); const logs = await publicClient.getLogs({ address: rollupAddress, @@ -451,9 +474,6 @@ describe('L1Publisher integration', () => { const blockNumber = await publicClient.getBlockNumber(); for (let i = 0; i < numberOfConsecutiveBlocks; i++) { - // @note Make sure that the state is up to date before we start building. - await worldStateSynchronizer.syncImmediate(); - const l1ToL2Messages = new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(0n)); const txs = [makeEmptyProcessedTx(), makeEmptyProcessedTx()]; @@ -472,11 +492,11 @@ describe('L1Publisher integration', () => { const block = await buildBlock(globalVariables, txs, l1ToL2Messages); prevHeader = block.header; blockSource.getL1ToL2Messages.mockResolvedValueOnce(l1ToL2Messages); - blockSource.getBlocks.mockResolvedValueOnce([block]); writeJson(`empty_block_${block.number}`, block, [], AztecAddress.ZERO, deployerAccount.address); await publisher.proposeL2Block(block); + blocks.push(block); const logs = await publicClient.getLogs({ address: rollupAddress, @@ -525,7 +545,6 @@ describe('L1Publisher integration', () => { // REFACTOR: code below is duplicated from "builds blocks of 2 empty txs building on each other" const archiveInRollup_ = await rollup.read.archive(); expect(hexStringToBuffer(archiveInRollup_.toString())).toEqual(new Fr(GENESIS_ARCHIVE_ROOT).toBuffer()); - await worldStateSynchronizer.syncImmediate(); // Set up different l1-to-l2 messages than the ones on the inbox, so this submission reverts // because the INBOX.consume does not match the header.contentCommitment.inHash and we get @@ -548,7 +567,6 @@ describe('L1Publisher integration', () => { const block = await buildBlock(globalVariables, txs, l1ToL2Messages); prevHeader = block.header; blockSource.getL1ToL2Messages.mockResolvedValueOnce(l1ToL2Messages); - blockSource.getBlocks.mockResolvedValueOnce([block]); // Inspect logger loggerErrorSpy = jest.spyOn((publisher as any).log, 'error'); diff --git a/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts b/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts index 57089425c7c..cdf5b5d1f8a 100644 --- a/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/gas_estimation.test.ts @@ -1,3 +1,4 @@ +import { type AztecNodeService } from '@aztec/aztec-node'; import { type AccountWallet, type AztecAddress, @@ -5,7 +6,7 @@ import { type FeePaymentMethod, PublicFeePaymentMethod, } from '@aztec/aztec.js'; -import { Gas, GasSettings } from '@aztec/circuits.js'; +import { GasSettings } from '@aztec/circuits.js'; import { type Logger } from '@aztec/foundation/log'; import { TokenContract as BananaCoin, type FPCContract } from '@aztec/noir-contracts.js'; @@ -54,7 +55,7 @@ describe('e2e_fees gas_estimation', () => { const sendTransfers = (paymentMethod: FeePaymentMethod) => Promise.all( [true, false].map(estimateGas => - makeTransferRequest().send({ estimateGas, fee: { gasSettings, paymentMethod } }).wait(), + makeTransferRequest().send({ estimateGas, fee: { gasSettings, paymentMethod }, estimatedGasPad: 0 }).wait(), ), ); @@ -64,45 +65,43 @@ describe('e2e_fees gas_estimation', () => { teardownGasLimits: inspect(estimatedGas.teardownGasLimits), }); - const expectGreaterFeeFromEstimatedGas = ( - estimatedGas: Pick, - actualFee: bigint, - ) => { - const feeFromEstimatedGas = estimatedGas.gasLimits.computeFee(gasSettings.maxFeesPerGas).toBigInt(); - - // The actual fee should be under the estimate, since we add 10% by default to the estimated gas (see aztec.js/src/contract/get_gas_limits.ts). - const adjustedForFloatingPoint = new Gas(1, 1).computeFee(gasSettings.maxFeesPerGas).toBigInt(); - expect(feeFromEstimatedGas).toBeLessThanOrEqual((actualFee * 110n) / 100n + adjustedForFloatingPoint); - expect(feeFromEstimatedGas).toBeGreaterThan(actualFee); - }; - it('estimates gas with Fee Juice payment method', async () => { const paymentMethod = new FeeJuicePaymentMethod(aliceAddress); - const estimatedGas = await makeTransferRequest().estimateGas({ fee: { gasSettings, paymentMethod } }); + const estimatedGas = await makeTransferRequest().estimateGas({ + fee: { gasSettings, paymentMethod }, + estimatedGasPad: 0, + }); logGasEstimate(estimatedGas); + (t.aztecNode as AztecNodeService).getSequencer()!.updateSequencerConfig({ minTxsPerBlock: 2, maxTxsPerBlock: 2 }); + const [withEstimate, withoutEstimate] = await sendTransfers(paymentMethod); - const actualFee = withEstimate.transactionFee!; + + // This is the interesting case, which we hit most of the time. + const block = await t.pxe.getBlock(withEstimate.blockNumber!); + expect(block!.header.totalManaUsed.toNumber()).toBe(estimatedGas.gasLimits.l2Gas * 2); // Tx has no teardown cost, so both fees should just reflect the actual gas cost. - expect(actualFee).toEqual(withoutEstimate.transactionFee!); + expect(withEstimate.transactionFee!).toEqual(withoutEstimate.transactionFee!); // Check that estimated gas for teardown are zero expect(estimatedGas.teardownGasLimits.l2Gas).toEqual(0); expect(estimatedGas.teardownGasLimits.daGas).toEqual(0); - // Check that the estimate was close to the actual gas used by recomputing the tx fee from it - expectGreaterFeeFromEstimatedGas(estimatedGas, actualFee); + const estimatedFee = estimatedGas.gasLimits.computeFee(gasSettings.maxFeesPerGas).toBigInt(); + expect(estimatedFee).toEqual(withEstimate.transactionFee!); }); it('estimates gas with public payment method', async () => { const teardownFixedFee = gasSettings.teardownGasLimits.computeFee(gasSettings.maxFeesPerGas).toBigInt(); const paymentMethod = new PublicFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet); - const estimatedGas = await makeTransferRequest().estimateGas({ fee: { gasSettings, paymentMethod } }); + const estimatedGas = await makeTransferRequest().estimateGas({ + fee: { gasSettings, paymentMethod }, + estimatedGasPad: 0, + }); logGasEstimate(estimatedGas); const [withEstimate, withoutEstimate] = await sendTransfers(paymentMethod); - const actualFee = withEstimate.transactionFee!; // Actual teardown gas used is less than the limits. expect(estimatedGas.teardownGasLimits.l2Gas).toBeLessThan(gasSettings.teardownGasLimits.l2Gas); @@ -115,15 +114,15 @@ describe('e2e_fees gas_estimation', () => { // Check that estimated gas for teardown are not zero since we're doing work there expect(estimatedGas.teardownGasLimits.l2Gas).toBeGreaterThan(0); - // Check that the estimate was close to the actual gas used by recomputing the tx fee from it - expectGreaterFeeFromEstimatedGas(estimatedGas, actualFee); + const estimatedFee = estimatedGas.gasLimits.computeFee(gasSettings.maxFeesPerGas).toBigInt(); + expect(estimatedFee).toEqual(withEstimate.transactionFee!); }); it('estimates gas for public contract initialization with Fee Juice payment method', async () => { const paymentMethod = new FeeJuicePaymentMethod(aliceAddress); const deployMethod = () => BananaCoin.deploy(aliceWallet, aliceAddress, 'TKN', 'TKN', 8); const deployOpts = { fee: { gasSettings, paymentMethod }, skipClassRegistration: true }; - const estimatedGas = await deployMethod().estimateGas(deployOpts); + const estimatedGas = await deployMethod().estimateGas({ ...deployOpts, estimatedGasPad: 0 }); logGasEstimate(estimatedGas); const [withEstimate, withoutEstimate] = await Promise.all([ @@ -136,14 +135,13 @@ describe('e2e_fees gas_estimation', () => { ]); // Estimation should yield that teardown has no cost, so should send the tx with zero for teardown - const actualFee = withEstimate.transactionFee!; - expect(actualFee).toEqual(withoutEstimate.transactionFee!); + expect(withEstimate.transactionFee!).toEqual(withoutEstimate.transactionFee!); // Check that estimated gas for teardown are zero expect(estimatedGas.teardownGasLimits.l2Gas).toEqual(0); expect(estimatedGas.teardownGasLimits.daGas).toEqual(0); - // Check that the estimate was close to the actual gas used by recomputing the tx fee from it - expectGreaterFeeFromEstimatedGas(estimatedGas, actualFee); + const estimatedFee = estimatedGas.gasLimits.computeFee(gasSettings.maxFeesPerGas).toBigInt(); + expect(estimatedFee).toEqual(withEstimate.transactionFee!); }); }); diff --git a/yarn-project/ethereum/src/deploy_l1_contracts.ts b/yarn-project/ethereum/src/deploy_l1_contracts.ts index d1b8dc91687..cb647ffda9c 100644 --- a/yarn-project/ethereum/src/deploy_l1_contracts.ts +++ b/yarn-project/ethereum/src/deploy_l1_contracts.ts @@ -22,6 +22,8 @@ import { RollupAbi, RollupBytecode, RollupLinkReferences, + SampleLibAbi, + SampleLibBytecode, TestERC20Abi, TestERC20Bytecode, TxsDecoderAbi, @@ -173,6 +175,10 @@ export const l1Artifacts: L1ContractArtifactsForDeployment = { contractAbi: TxsDecoderAbi, contractBytecode: TxsDecoderBytecode, }, + SampleLib: { + contractAbi: SampleLibAbi, + contractBytecode: SampleLibBytecode, + }, }, }, }, @@ -623,9 +629,15 @@ export async function deployL1Contract( ); for (const linkRef in libraries.linkReferences) { - for (const c in libraries.linkReferences[linkRef]) { - const start = 2 + 2 * libraries.linkReferences[linkRef][c][0].start; - const length = 2 * libraries.linkReferences[linkRef][c][0].length; + for (const contractName in libraries.linkReferences[linkRef]) { + // If the library name matches the one we just deployed, we replace it. + if (contractName !== libraryName) { + continue; + } + + // We read the first instance to figure out what we are to replace. + const start = 2 + 2 * libraries.linkReferences[linkRef][contractName][0].start; + const length = 2 * libraries.linkReferences[linkRef][contractName][0].length; const toReplace = bytecode.slice(start, start + length); replacements[toReplace] = address; diff --git a/yarn-project/foundation/src/config/env_var.ts b/yarn-project/foundation/src/config/env_var.ts index 4a2015ddd0f..165d98d7b6c 100644 --- a/yarn-project/foundation/src/config/env_var.ts +++ b/yarn-project/foundation/src/config/env_var.ts @@ -155,6 +155,7 @@ export type EnvVar = | 'SEQ_VIEM_POLLING_INTERVAL_MS' | 'WS_DB_MAP_SIZE_KB' | 'WS_DATA_DIRECTORY' + | 'WS_NUM_HISTORIC_BLOCKS' | 'ETHEREUM_SLOT_DURATION' | 'AZTEC_SLOT_DURATION' | 'AZTEC_EPOCH_DURATION' diff --git a/yarn-project/foundation/src/testing/test_data.ts b/yarn-project/foundation/src/testing/test_data.ts index 79961ae988e..1268d4473b1 100644 --- a/yarn-project/foundation/src/testing/test_data.ts +++ b/yarn-project/foundation/src/testing/test_data.ts @@ -66,7 +66,7 @@ export function updateInlineTestData(targetFileFromRepoRoot: string, itemName: s const logger = createConsoleLogger('aztec:testing:test_data'); const targetFile = getPathToFile(targetFileFromRepoRoot); const contents = readFileSync(targetFile, 'utf8').toString(); - const regex = new RegExp(`let ${itemName} = [\\s\\S]*?;`, 'g'); + const regex = new RegExp(`let ${itemName} =[\\s\\S]*?;`, 'g'); if (!regex.exec(contents)) { throw new Error(`Test data marker for ${itemName} not found in ${targetFile}`); } diff --git a/yarn-project/l1-artifacts/scripts/generate-artifacts.sh b/yarn-project/l1-artifacts/scripts/generate-artifacts.sh index 4ddefda991c..ef0892de022 100755 --- a/yarn-project/l1-artifacts/scripts/generate-artifacts.sh +++ b/yarn-project/l1-artifacts/scripts/generate-artifacts.sh @@ -29,6 +29,7 @@ CONTRACTS=( "l1-contracts:Governance" "l1-contracts:NewGovernanceProposerPayload" "l1-contracts:TxsDecoder" + "l1-contracts:SampleLib" ) diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index 27391eb641f..f21c013e30e 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -1643,6 +1643,7 @@ export function mapBaseOrMergeRollupPublicInputsToNoir( txs_effects_hash: mapFieldToNoir(baseOrMergeRollupPublicInputs.txsEffectsHash), out_hash: mapFieldToNoir(baseOrMergeRollupPublicInputs.outHash), accumulated_fees: mapFieldToNoir(baseOrMergeRollupPublicInputs.accumulatedFees), + accumulated_mana_used: mapFieldToNoir(baseOrMergeRollupPublicInputs.accumulatedManaUsed), }; } @@ -1715,6 +1716,7 @@ export function mapBaseOrMergeRollupPublicInputsFromNoir( mapFieldFromNoir(baseOrMergeRollupPublicInputs.txs_effects_hash), mapFieldFromNoir(baseOrMergeRollupPublicInputs.out_hash), mapFieldFromNoir(baseOrMergeRollupPublicInputs.accumulated_fees), + mapFieldFromNoir(baseOrMergeRollupPublicInputs.accumulated_mana_used), ); } @@ -1943,6 +1945,7 @@ export function mapHeaderToNoir(header: Header): HeaderNoir { state: mapStateReferenceToNoir(header.state), global_variables: mapGlobalVariablesToNoir(header.globalVariables), total_fees: mapFieldToNoir(header.totalFees), + total_mana_used: mapFieldToNoir(header.totalManaUsed), }; } @@ -1958,6 +1961,7 @@ export function mapHeaderFromNoir(header: HeaderNoir): Header { mapStateReferenceFromNoir(header.state), mapGlobalVariablesFromNoir(header.global_variables), mapFieldFromNoir(header.total_fees), + mapFieldFromNoir(header.total_mana_used), ); } diff --git a/yarn-project/p2p/src/service/data_store.test.ts b/yarn-project/p2p/src/service/data_store.test.ts index f46ecf32525..3b7620f0b59 100644 --- a/yarn-project/p2p/src/service/data_store.test.ts +++ b/yarn-project/p2p/src/service/data_store.test.ts @@ -17,7 +17,7 @@ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'; import { AztecDatastore } from './data_store.js'; -const CLEANUP_TIMEOUT = 30_000; +const CLEANUP_TIMEOUT = 60_000; describe('AztecDatastore with AztecLmdbStore', () => { let datastore: AztecDatastore; diff --git a/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts b/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts index 121d13a00d2..a5f081d6687 100644 --- a/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts +++ b/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts @@ -1,5 +1,5 @@ import { - type Body, + Body, MerkleTreeId, type MerkleTreeWriteOperations, type ProcessedTx, @@ -316,6 +316,7 @@ export function buildHeaderFromCircuitOutputs( state, previousMergeData[0].constants.globalVariables, previousMergeData[0].accumulatedFees.add(previousMergeData[1].accumulatedFees), + previousMergeData[0].accumulatedManaUsed.add(previousMergeData[1].accumulatedManaUsed), ); if (!header.hash().equals(rootRollupOutputs.endBlockHash)) { logger?.error( @@ -328,8 +329,8 @@ export function buildHeaderFromCircuitOutputs( return header; } -export async function buildHeaderFromTxEffects( - body: Body, +export async function buildHeaderAndBodyFromTxs( + txs: ProcessedTx[], globalVariables: GlobalVariables, l1ToL2Messages: Fr[], db: MerkleTreeReadOperations, @@ -345,6 +346,9 @@ export async function buildHeaderFromTxEffects( const previousArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db); + const nonEmptyTxEffects: TxEffect[] = txs.map(tx => tx.txEffect).filter(txEffect => !txEffect.isEmpty()); + const body = new Body(nonEmptyTxEffects); + const outHash = computeUnbalancedMerkleRoot( body.txEffects.map(tx => tx.txOutHash()), TxEffect.empty().txOutHash(), @@ -365,7 +369,11 @@ export async function buildHeaderFromTxEffects( ); const fees = body.txEffects.reduce((acc, tx) => acc.add(tx.transactionFee), Fr.ZERO); - return new Header(previousArchive, contentCommitment, stateReference, globalVariables, fees); + const manaUsed = txs.reduce((acc, tx) => acc.add(new Fr(tx.gasUsed.totalGas.l2Gas)), Fr.ZERO); + + const header = new Header(previousArchive, contentCommitment, stateReference, globalVariables, fees, manaUsed); + + return { header, body }; } // Validate that the roots of all local trees match the output of the root circuit simulation diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator.ts b/yarn-project/prover-client/src/orchestrator/orchestrator.ts index 84cfa185945..85c71b7f8ba 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator.ts @@ -1,10 +1,8 @@ import { - Body, L2Block, MerkleTreeId, type ProcessedTx, type ServerCircuitProver, - type TxEffect, makeEmptyProcessedTx, } from '@aztec/circuit-types'; import { @@ -55,8 +53,8 @@ import { inspect } from 'util'; import { buildBaseRollupHints, + buildHeaderAndBodyFromTxs, buildHeaderFromCircuitOutputs, - buildHeaderFromTxEffects, createBlockMergeRollupInputs, createMergeRollupInputs, getPreviousRollupDataFromPublicInputs, @@ -416,15 +414,12 @@ export class ProvingOrchestrator implements EpochProver { private async buildBlock(provingState: BlockProvingState, expectedHeader?: Header) { // Collect all new nullifiers, commitments, and contracts from all txs in this block to build body - const nonEmptyTxEffects: TxEffect[] = provingState!.allTxs - .map(txProvingState => txProvingState.processedTx.txEffect) - .filter(txEffect => !txEffect.isEmpty()); - const body = new Body(nonEmptyTxEffects); + const txs = provingState!.allTxs.map(a => a.processedTx); // Given we've applied every change from this block, now assemble the block header // and update the archive tree, so we're ready to start processing the next block - const header = await buildHeaderFromTxEffects( - body, + const { header, body } = await buildHeaderAndBodyFromTxs( + txs, provingState.globalVariables, provingState.newL1ToL2Messages, this.db, diff --git a/yarn-project/sequencer-client/src/block_builder/light.test.ts b/yarn-project/sequencer-client/src/block_builder/light.test.ts index 43cbd91a83b..76f4714823a 100644 --- a/yarn-project/sequencer-client/src/block_builder/light.test.ts +++ b/yarn-project/sequencer-client/src/block_builder/light.test.ts @@ -244,6 +244,10 @@ describe('LightBlockBuilder', () => { logger, ); + // Ensure that the expected mana used is the sum of the txs' gas used + const expectedManaUsed = txs.reduce((acc, tx) => acc + tx.gasUsed.totalGas.l2Gas, 0); + expect(expectedHeader.totalManaUsed.toNumber()).toBe(expectedManaUsed); + expect(expectedHeader.hash()).toEqual(rootOutput.endBlockHash); return expectedHeader; }; diff --git a/yarn-project/sequencer-client/src/block_builder/light.ts b/yarn-project/sequencer-client/src/block_builder/light.ts index 35ac23d476a..4087b1623bb 100644 --- a/yarn-project/sequencer-client/src/block_builder/light.ts +++ b/yarn-project/sequencer-client/src/block_builder/light.ts @@ -1,19 +1,17 @@ import { createDebugLogger } from '@aztec/aztec.js'; import { type BlockBuilder, - Body, L2Block, MerkleTreeId, type MerkleTreeWriteOperations, type ProcessedTx, - type TxEffect, makeEmptyProcessedTx, } from '@aztec/circuit-types'; import { Fr, type GlobalVariables, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/circuits.js'; import { padArrayEnd } from '@aztec/foundation/collection'; import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types'; import { protocolContractTreeRoot } from '@aztec/protocol-contracts'; -import { buildBaseRollupHints, buildHeaderFromTxEffects, getTreeSnapshot } from '@aztec/prover-client/helpers'; +import { buildBaseRollupHints, buildHeaderAndBodyFromTxs, getTreeSnapshot } from '@aztec/prover-client/helpers'; import { type TelemetryClient } from '@aztec/telemetry-client'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; @@ -69,9 +67,13 @@ export class LightweightBlockBuilder implements BlockBuilder { private async buildBlock(): Promise { this.logger.verbose(`Finalising block`); - const nonEmptyTxEffects: TxEffect[] = this.txs.map(tx => tx.txEffect).filter(txEffect => !txEffect.isEmpty()); - const body = new Body(nonEmptyTxEffects); - const header = await buildHeaderFromTxEffects(body, this.globalVariables!, this.l1ToL2Messages!, this.db); + + const { header, body } = await buildHeaderAndBodyFromTxs( + this.txs, + this.globalVariables!, + this.l1ToL2Messages!, + this.db, + ); await this.db.updateArchive(header); const newArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.db); diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts index 2bc6c67d9b8..b1e0aa5a50c 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts @@ -707,7 +707,18 @@ export class L1Publisher { }): Promise { try { const proofHex: Hex = `0x${args.proof.withoutPublicInputs().toString('hex')}`; - const txArgs = [...this.getSubmitEpochProofArgs(args), proofHex] as const; + const argsArray = this.getSubmitEpochProofArgs(args); + + const txArgs = [ + { + epochSize: argsArray[0], + args: argsArray[1], + fees: argsArray[2], + aggregationObject: argsArray[3], + proof: proofHex, + }, + ] as const; + this.log.info(`SubmitEpochProof proofSize=${args.proof.withoutPublicInputs().length} bytes`); await this.rollupContract.simulate.submitEpochRootProof(txArgs, { account: this.account }); return await this.rollupContract.write.submitEpochRootProof(txArgs, { account: this.account }); diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index 0ccd5c4ca23..3380025bb3c 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -296,6 +296,7 @@ export class Sequencer { StateReference.empty(), newGlobalVariables, Fr.ZERO, + Fr.ZERO, ); // TODO: It should be responsibility of the P2P layer to validate txs before passing them on here diff --git a/yarn-project/simulator/src/avm/avm_memory_types.ts b/yarn-project/simulator/src/avm/avm_memory_types.ts index 96420655547..3acd3160083 100644 --- a/yarn-project/simulator/src/avm/avm_memory_types.ts +++ b/yarn-project/simulator/src/avm/avm_memory_types.ts @@ -15,7 +15,7 @@ import { type FunctionsOf } from '@aztec/foundation/types'; import { strict as assert } from 'assert'; -import { InstructionExecutionError, TagCheckError } from './errors.js'; +import { InstructionExecutionError, InvalidTagValueError, TagCheckError } from './errors.js'; import { Addressing, AddressingMode } from './opcodes/addressing_mode.js'; /** MemoryValue gathers the common operations for all memory types. */ @@ -241,6 +241,10 @@ export class TaggedMemory implements TaggedMemoryInterface { this._mem = []; } + public getMaxMemorySize(): number { + return TaggedMemory.MAX_MEMORY_SIZE; + } + /** Returns a MeteredTaggedMemory instance to track the number of reads and writes if TRACK_MEMORY_ACCESSES is set. */ public track(type: string = 'instruction'): TaggedMemoryInterface { return TaggedMemory.TRACK_MEMORY_ACCESSES ? new MeteredTaggedMemory(this, type) : this; @@ -327,6 +331,22 @@ export class TaggedMemory implements TaggedMemoryInterface { } } + public static checkIsValidTag(tagNumber: number) { + if ( + ![ + TypeTag.UINT1, + TypeTag.UINT8, + TypeTag.UINT16, + TypeTag.UINT32, + TypeTag.UINT64, + TypeTag.UINT128, + TypeTag.FIELD, + ].includes(tagNumber) + ) { + throw new InvalidTagValueError(tagNumber); + } + } + /** * Check tags for memory at all of the specified offsets. */ @@ -400,29 +420,7 @@ export class TaggedMemory implements TaggedMemoryInterface { case TypeTag.UINT128: return new Uint128(v & ((1n << 128n) - 1n)); default: - throw new Error(`${TypeTag[tag]} is not a valid tag.`); - } - } - - // Does not truncate. Type constructor will check that it fits. - public static buildFromTagOrDie(v: bigint | number, tag: TypeTag): MemoryValue { - switch (tag) { - case TypeTag.FIELD: - return new Field(v); - case TypeTag.UINT1: - return new Uint1(v); - case TypeTag.UINT8: - return new Uint8(v); - case TypeTag.UINT16: - return new Uint16(v); - case TypeTag.UINT32: - return new Uint32(v); - case TypeTag.UINT64: - return new Uint64(v); - case TypeTag.UINT128: - return new Uint128(v); - default: - throw new Error(`${TypeTag[tag]} is not a valid integral type.`); + throw new InvalidTagValueError(tag); } } @@ -471,6 +469,10 @@ export class MeteredTaggedMemory implements TaggedMemoryInterface { } } + public getMaxMemorySize(): number { + return this.wrapped.getMaxMemorySize(); + } + public track(type: string = 'instruction'): MeteredTaggedMemory { return new MeteredTaggedMemory(this.wrapped, type); } diff --git a/yarn-project/simulator/src/avm/avm_simulator.ts b/yarn-project/simulator/src/avm/avm_simulator.ts index d6def2e96fc..643fae72da0 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.ts @@ -141,11 +141,6 @@ export class AvmSimulator { let instrCounter = 0; while (!machineState.getHalted()) { const [instruction, bytesRead] = decodeInstructionFromBytecode(bytecode, machineState.pc, this.instructionSet); - assert( - !!instruction, - 'AVM attempted to execute non-existent instruction. This should never happen (invalid bytecode or AVM simulator bug)!', - ); - const instrStartGas = machineState.gasLeft; // Save gas before executing instruction (for profiling) const instrPc = machineState.pc; // Save PC before executing instruction (for profiling) diff --git a/yarn-project/simulator/src/avm/errors.ts b/yarn-project/simulator/src/avm/errors.ts index 8df7a7d7303..a147aefe922 100644 --- a/yarn-project/simulator/src/avm/errors.ts +++ b/yarn-project/simulator/src/avm/errors.ts @@ -39,6 +39,37 @@ export class InvalidProgramCounterError extends AvmExecutionError { } } +/** + * Error is thrown when the program counter points to a byte + * of an invalid opcode. + */ +export class InvalidOpcodeError extends AvmExecutionError { + constructor(str: string) { + super(str); + this.name = 'InvalidOpcodeError'; + } +} + +/** + * Error is thrown during parsing. + */ +export class AvmParsingError extends AvmExecutionError { + constructor(str: string) { + super(str); + this.name = 'AvmParsingError'; + } +} + +/** + * Error is thrown when the tag has an invalid value. + */ +export class InvalidTagValueError extends AvmExecutionError { + constructor(tagValue: number) { + super(`Tag value ${tagValue} is invalid.`); + this.name = 'InvalidTagValueError'; + } +} + /** * Error thrown during an instruction's execution (during its execute()). */ diff --git a/yarn-project/simulator/src/avm/opcodes/memory.ts b/yarn-project/simulator/src/avm/opcodes/memory.ts index c79d7b7e1af..1a0c6c03ca3 100644 --- a/yarn-project/simulator/src/avm/opcodes/memory.ts +++ b/yarn-project/simulator/src/avm/opcodes/memory.ts @@ -59,16 +59,19 @@ export class Set extends Instruction { private value: bigint | number, ) { super(); + TaggedMemory.checkIsValidTag(inTag); } public async execute(context: AvmContext): Promise { + // Constructor ensured that this.inTag is a valid tag + const res = TaggedMemory.buildFromTagTruncating(this.value, this.inTag); + const memory = context.machineState.memory.track(this.type); context.machineState.consumeGas(this.gasCost()); const operands = [this.dstOffset]; const addressing = Addressing.fromWire(this.indirect, operands.length); const [dstOffset] = addressing.resolve(operands, memory); - const res = TaggedMemory.buildFromTagTruncating(this.value, this.inTag); memory.set(dstOffset, res); memory.assert({ writes: 1, addressing }); @@ -96,6 +99,7 @@ export class Cast extends Instruction { constructor(private indirect: number, private srcOffset: number, private dstOffset: number, private dstTag: number) { super(); + TaggedMemory.checkIsValidTag(dstTag); } public async execute(context: AvmContext): Promise { @@ -107,6 +111,7 @@ export class Cast extends Instruction { const [srcOffset, dstOffset] = addressing.resolve(operands, memory); const a = memory.get(srcOffset); + // Constructor ensured that this.dstTag is a valid tag const casted = TaggedMemory.buildFromTagTruncating(a.toBigInt(), this.dstTag); memory.set(dstOffset, casted); diff --git a/yarn-project/simulator/src/avm/serialization/buffer_cursor.ts b/yarn-project/simulator/src/avm/serialization/buffer_cursor.ts index 005a3d6599f..5beef814332 100644 --- a/yarn-project/simulator/src/avm/serialization/buffer_cursor.ts +++ b/yarn-project/simulator/src/avm/serialization/buffer_cursor.ts @@ -1,5 +1,3 @@ -import { strict as assert } from 'assert'; - /* * A Buffer-like class that automatically advances the position. */ @@ -24,7 +22,6 @@ export class BufferCursor { public advance(n: number): void { this._position += n; - assert(n < this._buffer.length); } public peekUint8(): number { diff --git a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.test.ts b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.test.ts index ce451ff92b0..ac84cfa19dd 100644 --- a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.test.ts +++ b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.test.ts @@ -1,9 +1,10 @@ import { strict as assert } from 'assert'; +import { AvmParsingError, InvalidOpcodeError, InvalidTagValueError } from '../errors.js'; import { Add, Call, EnvironmentVariable, GetEnvVar, StaticCall, Sub } from '../opcodes/index.js'; import { type BufferCursor } from './buffer_cursor.js'; import { type InstructionSet, decodeFromBytecode, encodeToBytecode } from './bytecode_serialization.js'; -import { Opcode } from './instruction_serialization.js'; +import { MAX_OPCODE_VALUE, Opcode } from './instruction_serialization.js'; class InstA { constructor(private n: number) {} @@ -133,4 +134,87 @@ describe('Bytecode Serialization', () => { const expected = Buffer.concat(instructions.map(i => i.serialize())); expect(actual).toEqual(expected); }); + + it('Should throw an InvalidOpcodeError while deserializing an out-of-range opcode value', () => { + const decodeInvalid = () => { + const wrongOpcode: number = MAX_OPCODE_VALUE + 1; + const buf = Buffer.alloc(1); + buf.writeUint8(wrongOpcode); + decodeFromBytecode(buf); + }; + + expect(decodeInvalid).toThrow(InvalidOpcodeError); + }); + + it('Should throw an InvalidOpcodeError while deserializing an opcode value not in instruction set', () => { + const decodeInvalid = () => { + const instructionSet: InstructionSet = new Map([ + [InstA.opcode, InstA.deserialize], + [InstB.opcode, InstB.deserialize], + ]); + const buf = Buffer.alloc(1); + buf.writeUint8(Opcode.AND_8); // Valid opcode but not in supplied instruction set. + decodeFromBytecode(buf, instructionSet); + }; + + expect(decodeInvalid).toThrow(InvalidOpcodeError); + }); + + it('Should throw an AvmParsingError while deserializing an incomplete instruction', () => { + const decodeIncomplete = (truncated: Buffer) => { + return () => decodeFromBytecode(truncated); + }; + + const instructions = [ + new Call( + /*indirect=*/ 0x01, + /*gasOffset=*/ 0x1234, + /*addrOffset=*/ 0xa234, + /*argsOffset=*/ 0xb234, + /*argsSize=*/ 0xc234, + /*successOffset=*/ 0xf234, + ), + ]; + + const bytecode = encodeToBytecode(instructions); + + for (let i = 1; i < bytecode.length; i++) { + const truncated = bytecode.subarray(0, bytecode.length - i); + expect(decodeIncomplete(truncated)).toThrow(AvmParsingError); + } + }); + + it('Should throw an InvalidTagValueError while deserializing a tag value out of range', () => { + const decodeInvalidTag = (buf: Buffer) => { + return () => decodeFromBytecode(buf); + }; + + const bufCast8 = Buffer.from([ + Opcode.CAST_8, // opcode + 0x01, // indirect + 0x10, // aOffset + 0x32, // dstOffset + 0x12, // dstTag (invalid tag) + ]); + + const bufCast16 = Buffer.from([ + Opcode.CAST_16, // opcode + 0x00, // indirect + ...Buffer.from('1234', 'hex'), // aOffset + ...Buffer.from('3456', 'hex'), // dstOffset + 0x65, // dstTag (invalid tag) + ]); + + const bufSet16 = Buffer.from([ + Opcode.SET_16, //opcode + 0x02, // indirect + ...Buffer.from('3456', 'hex'), // dstOffset + 0x21, //tag (invalid) + ...Buffer.from('2397', 'hex'), // value + ]); + + for (const buf of [bufCast8, bufCast16, bufSet16]) { + expect(decodeInvalidTag(buf)).toThrow(InvalidTagValueError); + } + }); }); diff --git a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts index 27b603664d8..aaade1ead23 100644 --- a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts @@ -1,3 +1,4 @@ +import { AvmExecutionError, AvmParsingError, InvalidOpcodeError, InvalidProgramCounterError } from '../errors.js'; import { Add, And, @@ -48,7 +49,7 @@ import { } from '../opcodes/index.js'; import { MultiScalarMul } from '../opcodes/multi_scalar_mul.js'; import { BufferCursor } from './buffer_cursor.js'; -import { Opcode } from './instruction_serialization.js'; +import { MAX_OPCODE_VALUE, Opcode } from './instruction_serialization.js'; export type InstructionDeserializer = (buf: BufferCursor | Buffer) => Instruction; @@ -179,18 +180,33 @@ export function decodeInstructionFromBytecode( instructionSet: InstructionSet = INSTRUCTION_SET(), ): [Instruction, number] { if (pc >= bytecode.length) { - throw new Error(`pc ${pc} is out of bounds for bytecode of length ${bytecode.length}`); + throw new InvalidProgramCounterError(pc, bytecode.length); } - const cursor = new BufferCursor(bytecode, pc); - const startingPosition = cursor.position(); - const opcode: Opcode = cursor.bufferAtPosition().readUint8(); // peek. - const instructionDeserializerOrUndef = instructionSet.get(opcode); - if (instructionDeserializerOrUndef === undefined) { - throw new Error(`Opcode ${Opcode[opcode]} (0x${opcode.toString(16)}) not implemented`); + try { + const cursor = new BufferCursor(bytecode, pc); + const startingPosition = cursor.position(); + const opcode: number = cursor.bufferAtPosition().readUint8(); // peek. + + if (opcode > MAX_OPCODE_VALUE) { + throw new InvalidOpcodeError( + `Opcode ${opcode} (0x${opcode.toString(16)}) value is not in the range of valid opcodes.`, + ); + } + + const instructionDeserializerOrUndef = instructionSet.get(opcode); + if (instructionDeserializerOrUndef === undefined) { + throw new InvalidOpcodeError(`Opcode ${Opcode[opcode]} (0x${opcode.toString(16)}) is not implemented`); + } + + const instructionDeserializer: InstructionDeserializer = instructionDeserializerOrUndef; + const instruction = instructionDeserializer(cursor); + return [instruction, cursor.position() - startingPosition]; + } catch (error) { + if (error instanceof InvalidOpcodeError || error instanceof AvmExecutionError) { + throw error; + } else { + throw new AvmParsingError(`${error}`); + } } - - const instructionDeserializer: InstructionDeserializer = instructionDeserializerOrUndef; - const instruction = instructionDeserializer(cursor); - return [instruction, cursor.position() - startingPosition]; } diff --git a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts index 20c25b2c999..50d6a4e2a56 100644 --- a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts @@ -86,6 +86,12 @@ export enum Opcode { TORADIXBE, } +export const MAX_OPCODE_VALUE = Math.max( + ...Object.values(Opcode) + .map(k => +k) + .filter(k => !isNaN(k)), +); + // Possible types for an instruction's operand in its wire format. (Keep in sync with CPP code. // See vm/avm_trace/deserialization.cpp) // Note that cpp code introduced an additional enum value TAG to express the instruction tag. In TS, diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index 2d35d94c7f0..9dbbddea2ea 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -169,6 +169,7 @@ describe('Private Execution test suite', () => { ), header.globalVariables, header.totalFees, + header.totalManaUsed, ); } else { header = new Header( @@ -177,6 +178,7 @@ describe('Private Execution test suite', () => { new StateReference(newSnap, header.state.partial), header.globalVariables, header.totalFees, + header.totalManaUsed, ); } diff --git a/yarn-project/update-snapshots.sh b/yarn-project/update-snapshots.sh index b166a092691..f175fe5f2b5 100755 --- a/yarn-project/update-snapshots.sh +++ b/yarn-project/update-snapshots.sh @@ -13,6 +13,11 @@ yarn workspace @aztec/end-to-end test e2e_nested_contract -t 'performs nested ca # only enable if needed # yarn workspace @aztec/end-to-end test e2e_prover -yarn workspace @aztec/circuits.js test -u -yarn workspace @aztec/noir-protocol-circuits-types test -u -yarn workspace @aztec/protocol-contracts test -u +yarn workspace @aztec/circuits.js test -u --max-workers 8 +yarn workspace @aztec/noir-protocol-circuits-types test -u --max-workers 8 +yarn workspace @aztec/protocol-contracts test -u --max-workers 8 + +# format the noir code in noir-projects (outside of yarn-project) +cd ../noir-projects +./scripts/format.sh +cd ../yarn-project diff --git a/yarn-project/world-state/src/native/native_world_state.test.ts b/yarn-project/world-state/src/native/native_world_state.test.ts index a2093fe23ee..97f9a929814 100644 --- a/yarn-project/world-state/src/native/native_world_state.test.ts +++ b/yarn-project/world-state/src/native/native_world_state.test.ts @@ -194,6 +194,7 @@ describe('NativeWorldState', () => { stateReference, makeGlobalVariables(), Fr.ZERO, + Fr.ZERO, ); await fork.updateArchive(header); @@ -223,6 +224,7 @@ describe('NativeWorldState', () => { stateReference, makeGlobalVariables(), Fr.ZERO, + Fr.ZERO, ); await fork.updateArchive(header); @@ -346,9 +348,11 @@ describe('NativeWorldState', () => { } //can't prune what has already been pruned - for (let i = 0; i < highestPrunedBlockNumber; i++) { + for (let i = 0; i <= highestPrunedBlockNumber; i++) { await expect(ws.removeHistoricalBlocks(BigInt(i + 1))).rejects.toThrow( - 'Unable to remove historical block, block not found', + `Unable to remove historical blocks to block number ${BigInt( + i + 1, + )}, blocks not found. Current oldest block: ${highestPrunedBlockNumber + 1}`, ); } }); diff --git a/yarn-project/world-state/src/synchronizer/config.ts b/yarn-project/world-state/src/synchronizer/config.ts index bdd96365da9..3714126cb5c 100644 --- a/yarn-project/world-state/src/synchronizer/config.ts +++ b/yarn-project/world-state/src/synchronizer/config.ts @@ -1,4 +1,9 @@ -import { type ConfigMappingsType, booleanConfigHelper, getConfigFromMappings } from '@aztec/foundation/config'; +import { + type ConfigMappingsType, + booleanConfigHelper, + getConfigFromMappings, + numberConfigHelper, +} from '@aztec/foundation/config'; /** World State synchronizer configuration values. */ export interface WorldStateConfig { @@ -16,6 +21,9 @@ export interface WorldStateConfig { /** Optional directory for the world state DB, if unspecified will default to the general data directory */ worldStateDataDirectory?: string; + + /** The number of historic blocks to maintain */ + worldStateBlockHistory: number; } export const worldStateConfigMappings: ConfigMappingsType = { @@ -44,6 +52,11 @@ export const worldStateConfigMappings: ConfigMappingsType = { env: 'WS_DATA_DIRECTORY', description: 'Optional directory for the world state database', }, + worldStateBlockHistory: { + env: 'WS_NUM_HISTORIC_BLOCKS', + description: 'The number of historic blocks to maintain. Values less than 1 mean all history is maintained', + ...numberConfigHelper(64), + }, }; /** diff --git a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts index 2cdcd42e1e1..08023782278 100644 --- a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts +++ b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts @@ -76,6 +76,7 @@ describe('ServerWorldStateSynchronizer', () => { worldStateBlockCheckIntervalMS: 100, worldStateProvenBlocksOnly: false, worldStateDbMapSizeKb: 1024 * 1024, + worldStateBlockHistory: 0, }; server = new TestWorldStateSynchronizer(merkleTreeDb, blockAndMessagesSource, config, l2BlockStream); diff --git a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts index 086c7cf534c..ae344f4144a 100644 --- a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts +++ b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.ts @@ -41,6 +41,7 @@ export class ServerWorldStateSynchronizer private readonly merkleTreeCommitted: MerkleTreeReadOperations; private latestBlockNumberAtStart = 0; + private historyToKeep: number | undefined; private currentState: WorldStateRunningState = WorldStateRunningState.IDLE; private latestBlockHashQuery: { blockNumber: number; hash: string | undefined } | undefined = undefined; @@ -57,6 +58,12 @@ export class ServerWorldStateSynchronizer ) { this.instrumentation = new WorldStateInstrumentation(telemetry); this.merkleTreeCommitted = this.merkleTreeDb.getCommitted(); + this.historyToKeep = config.worldStateBlockHistory < 1 ? undefined : config.worldStateBlockHistory; + this.log.info( + `Created world state synchroniser with block history of ${ + this.historyToKeep === undefined ? 'infinity' : this.historyToKeep + }`, + ); } public getCommitted(): MerkleTreeReadOperations { @@ -266,7 +273,16 @@ export class ServerWorldStateSynchronizer private async handleChainFinalized(blockNumber: number) { this.log.verbose(`Chain finalized at block ${blockNumber}`); - await this.merkleTreeDb.setFinalised(BigInt(blockNumber)); + const summary = await this.merkleTreeDb.setFinalised(BigInt(blockNumber)); + if (this.historyToKeep === undefined) { + return; + } + const newHistoricBlock = summary.finalisedBlockNumber - BigInt(this.historyToKeep) + 1n; + if (newHistoricBlock <= 1) { + return; + } + this.log.verbose(`Pruning historic blocks to ${newHistoricBlock}`); + await this.merkleTreeDb.removeHistoricalBlocks(newHistoricBlock); } private handleChainProven(blockNumber: number) { diff --git a/yarn-project/world-state/src/test/integration.test.ts b/yarn-project/world-state/src/test/integration.test.ts index 68a6bc4b225..0d6afa61ede 100644 --- a/yarn-project/world-state/src/test/integration.test.ts +++ b/yarn-project/world-state/src/test/integration.test.ts @@ -47,6 +47,7 @@ describe('world-state integration', () => { worldStateProvenBlocksOnly: false, worldStateBlockRequestBatchSize: 5, worldStateDbMapSizeKb: 1024 * 1024, + worldStateBlockHistory: 0, }; archiver = new MockPrefilledArchiver(blocks, messages); @@ -61,7 +62,7 @@ describe('world-state integration', () => { await db.close(); }); - const awaitSync = async (blockToSyncTo: number, finalized?: number, maxTimeoutMS = 2000) => { + const awaitSync = async (blockToSyncTo: number, finalized?: number, maxTimeoutMS = 5000) => { const startTime = Date.now(); let sleepTime = 0; let tips = await synchronizer.getL2Tips();