From a3fba8442fdd62f429054c3367984fd4206bbbeb Mon Sep 17 00:00:00 2001 From: PhilWindle <60546371+PhilWindle@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:20:05 +0000 Subject: [PATCH 01/34] feat: Don't store every block number in block indices DB (#10658) The block indices DB is what enables clients to query the block number for a given index. Where there were blocks of zero size (so multiple block numbers against an index) it was storing every block number against that index. This could result in an unbounded values size in the DB. We now just store the block range in this scenario. --- .../lmdb_store/lmdb_tree_store.cpp | 16 +--- .../lmdb_store/lmdb_tree_store.hpp | 85 +++++++++++++++---- .../lmdb_store/lmdb_tree_store.test.cpp | 67 +++++++++++---- 3 files changed, 124 insertions(+), 44 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.cpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.cpp index 09f87cae606..45802caf358 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.cpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.cpp @@ -161,15 +161,7 @@ void LMDBTreeStore::write_block_index_data(const block_number_t& blockNumber, msgpack::unpack((const char*)data.data(), data.size()).get().convert(payload); } - // Double check it's not already present (it shouldn't be) - // We then add the block number and sort - // Sorting shouldn't be necessary as we add blocks in ascending order, but we will make sure - // Sorting here and when we unwind blocks means that looking up the block number for an index becomes O(1) - // These lookups are much more frequent than adds or deletes so we take the hit here - if (!payload.contains(blockNumber)) { - payload.blockNumbers.emplace_back(blockNumber); - payload.sort(); - } + payload.add_block(blockNumber); // Write the new payload back down msgpack::sbuffer buffer; @@ -189,11 +181,11 @@ bool LMDBTreeStore::find_block_for_index(const index_t& index, block_number_t& b } BlockIndexPayload payload; msgpack::unpack((const char*)data.data(), data.size()).get().convert(payload); - if (payload.blockNumbers.empty()) { + if (payload.is_empty()) { return false; } // The block numbers are sorted so we simply return the lowest - blockNumber = payload.blockNumbers[0]; + blockNumber = payload.get_min_block_number(); return true; } @@ -217,7 +209,7 @@ void LMDBTreeStore::delete_block_index(const index_t& sizeAtBlock, payload.delete_block(blockNumber); // if it's now empty, delete it - if (payload.blockNumbers.empty()) { + if (payload.is_empty()) { tx.delete_value(key, *_indexToBlockDatabase); return; } diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp index a28ce245967..c67e13f5130 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.hpp @@ -1,4 +1,5 @@ #pragma once +#include "barretenberg/common/log.hpp" #include "barretenberg/common/serialize.hpp" #include "barretenberg/crypto/merkle_tree/indexed_tree/indexed_leaf.hpp" #include "barretenberg/crypto/merkle_tree/lmdb_store/callbacks.hpp" @@ -15,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -63,39 +65,90 @@ struct BlockIndexPayload { bool operator==(const BlockIndexPayload& other) const { return blockNumbers == other.blockNumbers; } - void sort() { std::sort(blockNumbers.begin(), blockNumbers.end()); } + bool is_empty() const { return blockNumbers.empty(); } + + block_number_t get_min_block_number() { return blockNumbers[0]; } bool contains(const block_number_t& blockNumber) { - auto it = std::lower_bound(blockNumbers.begin(), blockNumbers.end(), blockNumber); - if (it == blockNumbers.end()) { - // The block was not found, we can return + if (is_empty()) { return false; } - return *it == blockNumber; + if (blockNumbers.size() == 1) { + return blockNumbers[0] == blockNumber; + } + return blockNumber >= blockNumbers[0] && blockNumber <= blockNumbers[1]; } void delete_block(const block_number_t& blockNumber) { + // Shouldn't be possible, but no need to do anything here if (blockNumbers.empty()) { return; } - // shuffle the block number down, removing the one we want to remove and then pop the end item - auto it = std::lower_bound(blockNumbers.begin(), blockNumbers.end(), blockNumber); - if (it == blockNumbers.end()) { - // The block was not found, we can return + + // If the size is 1, the blocknumber must match that in index 0, if it does remove it + if (blockNumbers.size() == 1) { + if (blockNumbers[0] == blockNumber) { + blockNumbers.pop_back(); + } return; } - // It could be a block higher than the one we are looking for - if (*it != blockNumber) { + + // we have 2 entries, we must verify that the block number is equal to the item in index 1 + if (blockNumbers[1] != blockNumber) { + throw std::runtime_error(format("Unable to delete block number ", + blockNumber, + " for retrieval by index, current max block number at that index: ", + blockNumbers[1])); + } + // It is equal, decrement it, we know that the new block number must have been added previously + --blockNumbers[1]; + + // We have modified the high block. If it is now equal to the low block then pop it + if (blockNumbers[0] == blockNumbers[1]) { + blockNumbers.pop_back(); + } + } + + void add_block(const block_number_t& blockNumber) + { + // If empty, just add the block number + if (blockNumbers.empty()) { + blockNumbers.emplace_back(blockNumber); + return; + } + + // If the size is 1, then we must be adding the block 1 larger than that in index 0 + if (blockNumbers.size() == 1) { + if (blockNumber != blockNumbers[0] + 1) { + // We can't accept a block number for this index that does not immediately follow the block before + throw std::runtime_error(format("Unable to store block number ", + blockNumber, + " for retrieval by index, current max block number at that index: ", + blockNumbers[0])); + } + blockNumbers.emplace_back(blockNumber); return; } - // we have found our block, shuffle blocks after this one down - auto readIt = it + 1; - while (readIt != blockNumbers.end()) { - *it++ = *readIt++; + + // Size must be 2 here, if larger, this is an error + if (blockNumbers.size() != 2) { + throw std::runtime_error(format("Unable to store block number ", + blockNumber, + " for retrieval by index, block numbers is of invalid size: ", + blockNumbers.size())); + } + + // If the size is 2, then we must be adding the block 1 larger than that in index 1 + if (blockNumber != blockNumbers[1] + 1) { + // We can't accept a block number for this index that does not immediately follow the block before + throw std::runtime_error(format("Unable to store block number ", + blockNumber, + " for retrieval by index, current max block number at that index: ", + blockNumbers[1])); } - blockNumbers.pop_back(); + blockNumbers[1] = blockNumber; } }; /** diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.test.cpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.test.cpp index e9b85aa5bbc..c33eb42bc23 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.test.cpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/lmdb_store/lmdb_tree_store.test.cpp @@ -273,11 +273,10 @@ TEST_F(LMDBTreeStoreTest, can_write_and_retrieve_block_numbers_by_index) BlockAndIndex{ .blockNumber = 5, .index = 130 } }; LMDBTreeStore store(_directory, "DB1", _mapSize, _maxReaders); { - // write all of the blocks. we will write them in reverse order + // write all of the blocks. LMDBTreeWriteTransaction::Ptr transaction = store.create_write_transaction(); - for (int i = int(blocks.size()) - 1; i >= 0; i--) { + for (auto block : blocks) { // the arg is block size so add 1 - const BlockAndIndex& block = blocks[size_t(i)]; store.write_block_index_data(block.blockNumber, block.index + 1, *transaction); } transaction->commit(); @@ -409,14 +408,24 @@ TEST_F(LMDBTreeStoreTest, can_write_and_retrieve_block_numbers_with_duplicate_in { // write all of the blocks. we will write them in reverse order LMDBTreeWriteTransaction::Ptr transaction = store.create_write_transaction(); - for (int i = int(blocks.size()) - 1; i >= 0; i--) { + for (auto block : blocks) { // the arg is block size so add 1 - const BlockAndIndex& block = blocks[size_t(i)]; store.write_block_index_data(block.blockNumber, block.index + 1, *transaction); } transaction->commit(); } + { + // we can't add a duplicate block at an index if it is not the next block number + LMDBTreeWriteTransaction::Ptr transaction = store.create_write_transaction(); + // the arg is block size so add 1 + EXPECT_THROW(store.write_block_index_data(3, 60 + 1, *transaction), std::runtime_error); + EXPECT_THROW(store.write_block_index_data(6, 60 + 1, *transaction), std::runtime_error); + EXPECT_THROW(store.write_block_index_data(1, 25 + 1, *transaction), std::runtime_error); + EXPECT_THROW(store.write_block_index_data(3, 25 + 1, *transaction), std::runtime_error); + transaction->abort(); + } + { // read back some blocks and check them LMDBTreeReadTransaction::Ptr transaction = store.create_read_transaction(); @@ -435,11 +444,12 @@ TEST_F(LMDBTreeStoreTest, can_write_and_retrieve_block_numbers_with_duplicate_in } { - // delete block 2 at index 60 + // attempting to delete block 2 at index 60 should fail as it is not the last block in the series at index 60 LMDBTreeWriteTransaction::Ptr transaction = store.create_write_transaction(); // the arg is block size so add 1 - store.delete_block_index(blocks[1].index + 1, blocks[1].blockNumber, *transaction); - transaction->commit(); + EXPECT_THROW(store.delete_block_index(blocks[1].index + 1, blocks[1].blockNumber, *transaction), + std::runtime_error); + transaction->abort(); } { @@ -449,9 +459,9 @@ TEST_F(LMDBTreeStoreTest, can_write_and_retrieve_block_numbers_with_duplicate_in EXPECT_TRUE(store.find_block_for_index(5, readBack, *transaction)); EXPECT_EQ(readBack, 1); - // should be the new lowest block at this index + // should still be the lowest block at this index EXPECT_TRUE(store.find_block_for_index(30, readBack, *transaction)); - EXPECT_EQ(readBack, 3); + EXPECT_EQ(readBack, 2); EXPECT_TRUE(store.find_block_for_index(82, readBack, *transaction)); EXPECT_EQ(readBack, 5); @@ -463,9 +473,9 @@ TEST_F(LMDBTreeStoreTest, can_write_and_retrieve_block_numbers_with_duplicate_in // try and delete blocks that don't exist at index 60 LMDBTreeWriteTransaction::Ptr transaction = store.create_write_transaction(); // the arg is block size so add 1 - store.delete_block_index(blocks[1].index + 1, 2, *transaction); - store.delete_block_index(blocks[1].index + 1, 5, *transaction); - transaction->commit(); + EXPECT_THROW(store.delete_block_index(blocks[1].index + 1, 2, *transaction), std::runtime_error); + EXPECT_THROW(store.delete_block_index(blocks[1].index + 1, 5, *transaction), std::runtime_error); + transaction->abort(); } { @@ -475,9 +485,8 @@ TEST_F(LMDBTreeStoreTest, can_write_and_retrieve_block_numbers_with_duplicate_in EXPECT_TRUE(store.find_block_for_index(5, readBack, *transaction)); EXPECT_EQ(readBack, 1); - // should be the new lowest block at this index EXPECT_TRUE(store.find_block_for_index(30, readBack, *transaction)); - EXPECT_EQ(readBack, 3); + EXPECT_EQ(readBack, 2); EXPECT_TRUE(store.find_block_for_index(82, readBack, *transaction)); EXPECT_EQ(readBack, 5); @@ -486,7 +495,7 @@ TEST_F(LMDBTreeStoreTest, can_write_and_retrieve_block_numbers_with_duplicate_in } { - // delete 2 more blocks + // delete the last 2 blocks at index 60 LMDBTreeWriteTransaction::Ptr transaction = store.create_write_transaction(); // the arg is block size so add 1 store.delete_block_index(blocks[3].index + 1, blocks[3].blockNumber, *transaction); @@ -494,6 +503,32 @@ TEST_F(LMDBTreeStoreTest, can_write_and_retrieve_block_numbers_with_duplicate_in transaction->commit(); } + { + // check the blocks again + LMDBTreeReadTransaction::Ptr transaction = store.create_read_transaction(); + block_number_t readBack = 0; + EXPECT_TRUE(store.find_block_for_index(5, readBack, *transaction)); + EXPECT_EQ(readBack, 1); + + EXPECT_TRUE(store.find_block_for_index(30, readBack, *transaction)); + EXPECT_EQ(readBack, 2); + + EXPECT_TRUE(store.find_block_for_index(82, readBack, *transaction)); + EXPECT_EQ(readBack, 5); + } + + { + // delete the last final block at index 60 + LMDBTreeWriteTransaction::Ptr transaction = store.create_write_transaction(); + // the arg is block size so add 1 + // Only one block remains at index 60, try and delete one that doesn't exist, it should do nothing + store.delete_block_index(blocks[3].index + 1, blocks[3].blockNumber, *transaction); + + // Now delete the last block + store.delete_block_index(blocks[1].index + 1, blocks[1].blockNumber, *transaction); + transaction->commit(); + } + { // check the blocks again LMDBTreeReadTransaction::Ptr transaction = store.create_read_transaction(); From 2cad3e59765a67ed14158ce556433120e9efd809 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Tue, 17 Dec 2024 17:36:45 -0300 Subject: [PATCH 02/34] fix: Block building test timeout (#10812) The test `can simulate public txs while building a block` would, in some cases, build blocks with varying tx sizes. An example run built blocks with 4, 12, and 12 txs. This totals 28 txs, so the remaining 2 txs never get mined and the test timeout. This fixes it by forcing the sequencer to build with just 4 txs consistently, and making the total number of txs a multiple of it. --- yarn-project/end-to-end/src/e2e_block_building.test.ts | 10 +++++----- .../sequencer-client/src/sequencer/sequencer.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn-project/end-to-end/src/e2e_block_building.test.ts b/yarn-project/end-to-end/src/e2e_block_building.test.ts index 71ae0eeab25..d80f7f1ff87 100644 --- a/yarn-project/end-to-end/src/e2e_block_building.test.ts +++ b/yarn-project/end-to-end/src/e2e_block_building.test.ts @@ -287,6 +287,8 @@ describe('e2e_block_building', () => { testContract = await TestContract.deploy(owner).send().deployed(); }, 60_000); + afterEach(() => teardown()); + it('calls a method with nested note encrypted logs', async () => { // account setup const privateKey = new Fr(7n); @@ -394,14 +396,12 @@ describe('e2e_block_building', () => { .send() .deployed(); - // We set the maximum number of txs per block to 12 to ensure that the sequencer will start building a block before it receives all the txs - // and also to avoid it building - logger.info('Updating min txs per block to 4, and max txs per block to 12'); - await aztecNode.setConfig({ minTxsPerBlock: 4, maxTxsPerBlock: 12 }); + logger.info('Updating txs per block to 4'); + await aztecNode.setConfig({ minTxsPerBlock: 4, maxTxsPerBlock: 4 }); logger.info('Spamming the network with public txs'); const txs = []; - for (let i = 0; i < 30; i++) { + for (let i = 0; i < 24; i++) { const tx = token.methods.mint_to_public(owner.getAddress(), 10n); txs.push(tx.send({ skipPublicSimulation: false })); } diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index c6961d59953..adc3bda49e2 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -128,7 +128,7 @@ export class Sequencer { * @param config - New parameters. */ public updateConfig(config: SequencerConfig) { - this.log.info(`Sequencer config set`, omit(pickFromSchema(this.config, SequencerConfigSchema), 'allowedInSetup')); + this.log.info(`Sequencer config set`, omit(pickFromSchema(config, SequencerConfigSchema), 'allowedInSetup')); if (config.transactionPollingIntervalMS !== undefined) { this.pollingIntervalMs = config.transactionPollingIntervalMS; From dacef9f7f9f11c8ec35ecd333748a9ae8c24d428 Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> Date: Wed, 18 Dec 2024 04:52:00 +0800 Subject: [PATCH 03/34] feat(p2p): attestation pool persistence (#10667) --- yarn-project/kv-store/src/interfaces/map.ts | 21 ++ yarn-project/kv-store/src/interfaces/store.ts | 23 +- yarn-project/kv-store/src/lmdb/map.test.ts | 53 ++++ yarn-project/kv-store/src/lmdb/map.ts | 119 +++++++-- yarn-project/kv-store/src/lmdb/store.ts | 28 ++- yarn-project/p2p/src/client/index.ts | 4 +- .../attestation_pool/attestation_pool.ts | 10 + .../attestation_pool_test_suite.ts | 237 ++++++++++++++++++ .../kv_attestation_pool.test.ts | 18 ++ .../attestation_pool/kv_attestation_pool.ts | 153 +++++++++++ .../memory_attestation_pool.test.ts | 202 +-------------- .../reqresp/reqresp.integration.test.ts | 1 + 12 files changed, 645 insertions(+), 224 deletions(-) create mode 100644 yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts create mode 100644 yarn-project/p2p/src/mem_pools/attestation_pool/kv_attestation_pool.test.ts create mode 100644 yarn-project/p2p/src/mem_pools/attestation_pool/kv_attestation_pool.ts diff --git a/yarn-project/kv-store/src/interfaces/map.ts b/yarn-project/kv-store/src/interfaces/map.ts index 6ded76080db..f63505dae9f 100644 --- a/yarn-project/kv-store/src/interfaces/map.ts +++ b/yarn-project/kv-store/src/interfaces/map.ts @@ -62,6 +62,19 @@ export interface AztecMap extends AztecBaseMap { * @param range - The range of keys to iterate over */ keys(range?: Range): IterableIterator; + + /** + * Clears the map. + */ + clear(): Promise; +} + +export interface AztecMapWithSize extends AztecMap { + /** + * Gets the size of the map. + * @returns The size of the map + */ + size(): number; } /** @@ -82,6 +95,14 @@ export interface AztecMultiMap extends AztecMap { deleteValue(key: K, val: V): Promise; } +export interface AztecMultiMapWithSize extends AztecMultiMap { + /** + * Gets the size of the map. + * @returns The size of the map + */ + size(): number; +} + /** * A map backed by a persistent store. */ diff --git a/yarn-project/kv-store/src/interfaces/store.ts b/yarn-project/kv-store/src/interfaces/store.ts index 81c4d956bed..bee1e2e0e8a 100644 --- a/yarn-project/kv-store/src/interfaces/store.ts +++ b/yarn-project/kv-store/src/interfaces/store.ts @@ -1,7 +1,14 @@ import { type AztecArray, type AztecAsyncArray } from './array.js'; import { type Key } from './common.js'; import { type AztecAsyncCounter, type AztecCounter } from './counter.js'; -import { type AztecAsyncMap, type AztecAsyncMultiMap, type AztecMap, type AztecMultiMap } from './map.js'; +import { + type AztecAsyncMap, + type AztecAsyncMultiMap, + type AztecMap, + type AztecMapWithSize, + type AztecMultiMap, + type AztecMultiMapWithSize, +} from './map.js'; import { type AztecAsyncSet, type AztecSet } from './set.js'; import { type AztecAsyncSingleton, type AztecSingleton } from './singleton.js'; @@ -29,6 +36,20 @@ export interface AztecKVStore { */ openMultiMap(name: string): AztecMultiMap; + /** + * Creates a new multi-map with size. + * @param name - The name of the multi-map + * @returns The multi-map + */ + openMultiMapWithSize(name: string): AztecMultiMapWithSize; + + /** + * Creates a new map with size. + * @param name - The name of the map + * @returns The map + */ + openMapWithSize(name: string): AztecMapWithSize; + /** * Creates a new array. * @param name - The name of the array diff --git a/yarn-project/kv-store/src/lmdb/map.test.ts b/yarn-project/kv-store/src/lmdb/map.test.ts index 224750df8e9..2f78d4aca63 100644 --- a/yarn-project/kv-store/src/lmdb/map.test.ts +++ b/yarn-project/kv-store/src/lmdb/map.test.ts @@ -1,3 +1,6 @@ +import { expect } from 'chai'; + +import { type AztecMapWithSize, type AztecMultiMapWithSize } from '../interfaces/map.js'; import { describeAztecMap } from '../interfaces/map_test_suite.js'; import { openTmpStore } from './index.js'; @@ -6,3 +9,53 @@ describe('LMDBMap', () => { describeAztecMap('Async AztecMap', () => Promise.resolve(openTmpStore(true)), true); }); + +describe('AztecMultiMapWithSize', () => { + let map: AztecMultiMapWithSize; + let map2: AztecMultiMapWithSize; + + beforeEach(() => { + const store = openTmpStore(true); + map = store.openMultiMapWithSize('test'); + map2 = store.openMultiMapWithSize('test2'); + }); + + it('should be able to delete values', async () => { + await map.set('foo', 'bar'); + await map.set('foo', 'baz'); + + await map2.set('foo', 'bar'); + await map2.set('foo', 'baz'); + + expect(map.size()).to.equal(2); + expect(map2.size()).to.equal(2); + + await map.deleteValue('foo', 'bar'); + + expect(map.size()).to.equal(1); + expect(map.get('foo')).to.equal('baz'); + + expect(map2.size()).to.equal(2); + }); +}); + +describe('AztecMapWithSize', () => { + let map: AztecMapWithSize; + + beforeEach(() => { + const store = openTmpStore(true); + map = store.openMapWithSize('test'); + }); + + it('should be able to delete values', async () => { + await map.set('foo', 'bar'); + await map.set('fizz', 'buzz'); + + expect(map.size()).to.equal(2); + + await map.delete('foo'); + + expect(map.size()).to.equal(1); + expect(map.get('fizz')).to.equal('buzz'); + }); +}); diff --git a/yarn-project/kv-store/src/lmdb/map.ts b/yarn-project/kv-store/src/lmdb/map.ts index 38d87cf9c6b..4458c3c3539 100644 --- a/yarn-project/kv-store/src/lmdb/map.ts +++ b/yarn-project/kv-store/src/lmdb/map.ts @@ -1,7 +1,7 @@ import { type Database, type RangeOptions } from 'lmdb'; import { type Key, type Range } from '../interfaces/common.js'; -import { type AztecAsyncMultiMap, type AztecMultiMap } from '../interfaces/map.js'; +import { type AztecAsyncMultiMap, type AztecMapWithSize, type AztecMultiMap } from '../interfaces/map.js'; /** The slot where a key-value entry would be stored */ type MapValueSlot = ['map', string, 'slot', K]; @@ -13,8 +13,8 @@ export class LmdbAztecMap implements AztecMultiMap, Azte protected db: Database<[K, V], MapValueSlot>; protected name: string; - #startSentinel: MapValueSlot; - #endSentinel: MapValueSlot; + protected startSentinel: MapValueSlot; + protected endSentinel: MapValueSlot; constructor(rootDb: Database, mapName: string) { this.name = mapName; @@ -23,8 +23,8 @@ export class LmdbAztecMap implements AztecMultiMap, Azte // sentinels are used to define the start and end of the map // with LMDB's key encoding, no _primitive value_ can be "less than" an empty buffer or greater than Byte 255 // these will be used later to answer range queries - this.#startSentinel = ['map', this.name, 'slot', Buffer.from([])]; - this.#endSentinel = ['map', this.name, 'slot', Buffer.from([255])]; + this.startSentinel = ['map', this.name, 'slot', Buffer.from([])]; + this.endSentinel = ['map', this.name, 'slot', Buffer.from([255])]; } close(): Promise { @@ -32,7 +32,7 @@ export class LmdbAztecMap implements AztecMultiMap, Azte } get(key: K): V | undefined { - return this.db.get(this.#slot(key))?.[1]; + return this.db.get(this.slot(key))?.[1]; } getAsync(key: K): Promise { @@ -40,7 +40,7 @@ export class LmdbAztecMap implements AztecMultiMap, Azte } *getValues(key: K): IterableIterator { - const values = this.db.getValues(this.#slot(key)); + const values = this.db.getValues(this.slot(key)); for (const value of values) { yield value?.[1]; } @@ -53,7 +53,7 @@ export class LmdbAztecMap implements AztecMultiMap, Azte } has(key: K): boolean { - return this.db.doesExist(this.#slot(key)); + return this.db.doesExist(this.slot(key)); } hasAsync(key: K): Promise { @@ -61,30 +61,30 @@ export class LmdbAztecMap implements AztecMultiMap, Azte } async set(key: K, val: V): Promise { - await this.db.put(this.#slot(key), [key, val]); + await this.db.put(this.slot(key), [key, val]); } swap(key: K, fn: (val: V | undefined) => V): Promise { return this.db.childTransaction(() => { - const slot = this.#slot(key); + const slot = this.slot(key); const entry = this.db.get(slot); void this.db.put(slot, [key, fn(entry?.[1])]); }); } setIfNotExists(key: K, val: V): Promise { - const slot = this.#slot(key); + const slot = this.slot(key); return this.db.ifNoExists(slot, () => { void this.db.put(slot, [key, val]); }); } async delete(key: K): Promise { - await this.db.remove(this.#slot(key)); + await this.db.remove(this.slot(key)); } async deleteValue(key: K, val: V): Promise { - await this.db.remove(this.#slot(key), [key, val]); + await this.db.remove(this.slot(key), [key, val]); } *entries(range: Range = {}): IterableIterator<[K, V]> { @@ -93,19 +93,19 @@ export class LmdbAztecMap implements AztecMultiMap, Azte // in that case, we need to swap the start and end sentinels const start = reverse ? range.end - ? this.#slot(range.end) - : this.#endSentinel + ? this.slot(range.end) + : this.endSentinel : range.start - ? this.#slot(range.start) - : this.#startSentinel; + ? this.slot(range.start) + : this.startSentinel; const end = reverse ? range.start - ? this.#slot(range.start) - : this.#startSentinel + ? this.slot(range.start) + : this.startSentinel : range.end - ? this.#slot(range.end) - : this.#endSentinel; + ? this.slot(range.end) + : this.endSentinel; const lmdbRange: RangeOptions = { start, @@ -153,7 +153,82 @@ export class LmdbAztecMap implements AztecMultiMap, Azte } } - #slot(key: K): MapValueSlot { + protected slot(key: K): MapValueSlot { return ['map', this.name, 'slot', key]; } + + async clear(): Promise { + const lmdbRange: RangeOptions = { + start: this.startSentinel, + end: this.endSentinel, + }; + + const iterator = this.db.getRange(lmdbRange); + + for (const { key } of iterator) { + await this.db.remove(key); + } + } +} + +export class LmdbAztecMapWithSize + extends LmdbAztecMap + implements AztecMapWithSize, AztecAsyncMultiMap +{ + #sizeCache?: number; + + constructor(rootDb: Database, mapName: string) { + super(rootDb, mapName); + } + + override async set(key: K, val: V): Promise { + await this.db.childTransaction(() => { + const exists = this.db.doesExist(this.slot(key)); + this.db.putSync(this.slot(key), [key, val], { + appendDup: true, + }); + if (!exists) { + this.#sizeCache = undefined; // Invalidate cache + } + }); + } + + override async delete(key: K): Promise { + await this.db.childTransaction(async () => { + const exists = this.db.doesExist(this.slot(key)); + if (exists) { + await this.db.remove(this.slot(key)); + this.#sizeCache = undefined; // Invalidate cache + } + }); + } + + override async deleteValue(key: K, val: V): Promise { + await this.db.childTransaction(async () => { + const exists = this.db.doesExist(this.slot(key)); + if (exists) { + await this.db.remove(this.slot(key), [key, val]); + this.#sizeCache = undefined; // Invalidate cache + } + }); + } + + /** + * Gets the size of the map by counting entries. + * @returns The number of entries in the map + */ + size(): number { + if (this.#sizeCache === undefined) { + this.#sizeCache = this.db.getCount({ + start: this.startSentinel, + end: this.endSentinel, + }); + } + return this.#sizeCache; + } + + // Reset cache on clear/drop operations + clearCache() { + this.#sizeCache = undefined; + } } diff --git a/yarn-project/kv-store/src/lmdb/store.ts b/yarn-project/kv-store/src/lmdb/store.ts index f0f453a98ad..d78030ec373 100644 --- a/yarn-project/kv-store/src/lmdb/store.ts +++ b/yarn-project/kv-store/src/lmdb/store.ts @@ -9,13 +9,20 @@ import { join } from 'path'; import { type AztecArray, type AztecAsyncArray } from '../interfaces/array.js'; import { type Key } from '../interfaces/common.js'; import { type AztecAsyncCounter, type AztecCounter } from '../interfaces/counter.js'; -import { type AztecAsyncMap, type AztecAsyncMultiMap, type AztecMap, type AztecMultiMap } from '../interfaces/map.js'; +import { + type AztecAsyncMap, + type AztecAsyncMultiMap, + type AztecMap, + type AztecMapWithSize, + type AztecMultiMap, + type AztecMultiMapWithSize, +} from '../interfaces/map.js'; import { type AztecAsyncSet, type AztecSet } from '../interfaces/set.js'; import { type AztecAsyncSingleton, type AztecSingleton } from '../interfaces/singleton.js'; import { type AztecAsyncKVStore, type AztecKVStore } from '../interfaces/store.js'; import { LmdbAztecArray } from './array.js'; import { LmdbAztecCounter } from './counter.js'; -import { LmdbAztecMap } from './map.js'; +import { LmdbAztecMap, LmdbAztecMapWithSize } from './map.js'; import { LmdbAztecSet } from './set.js'; import { LmdbAztecSingleton } from './singleton.js'; @@ -118,6 +125,23 @@ export class AztecLmdbStore implements AztecKVStore, AztecAsyncKVStore { openCounter(name: string): AztecCounter & AztecAsyncCounter { return new LmdbAztecCounter(this.#data, name); } + /** + * Creates a new AztecMultiMapWithSize in the store. A multi-map with size stores multiple values for a single key automatically. + * @param name - Name of the map + * @returns A new AztecMultiMapWithSize + */ + openMultiMapWithSize(name: string): AztecMultiMapWithSize { + return new LmdbAztecMapWithSize(this.#multiMapData, name); + } + + /** + * Creates a new AztecMapWithSize in the store. + * @param name - Name of the map + * @returns A new AztecMapWithSize + */ + openMapWithSize(name: string): AztecMapWithSize { + return new LmdbAztecMapWithSize(this.#data, name); + } /** * Creates a new AztecArray in the store. diff --git a/yarn-project/p2p/src/client/index.ts b/yarn-project/p2p/src/client/index.ts index c2a01ff4294..9c4cca388db 100644 --- a/yarn-project/p2p/src/client/index.ts +++ b/yarn-project/p2p/src/client/index.ts @@ -14,7 +14,7 @@ import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { P2PClient } from '../client/p2p_client.js'; import { type P2PConfig } from '../config.js'; import { type AttestationPool } from '../mem_pools/attestation_pool/attestation_pool.js'; -import { InMemoryAttestationPool } from '../mem_pools/attestation_pool/memory_attestation_pool.js'; +import { KvAttestationPool } from '../mem_pools/attestation_pool/kv_attestation_pool.js'; import { type EpochProofQuotePool } from '../mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.js'; import { MemoryEpochProofQuotePool } from '../mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.js'; import { type MemPools } from '../mem_pools/interface.js'; @@ -51,7 +51,7 @@ export const createP2PClient = async ( epochProofQuotePool: deps.epochProofQuotePool ?? new MemoryEpochProofQuotePool(telemetry), attestationPool: clientType === P2PClientType.Full - ? ((deps.attestationPool ?? new InMemoryAttestationPool(telemetry)) as T extends P2PClientType.Full + ? ((deps.attestationPool ?? new KvAttestationPool(store, telemetry)) as T extends P2PClientType.Full ? AttestationPool : undefined) : undefined, diff --git a/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool.ts b/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool.ts index bb7ecb5b704..d7f3e434d09 100644 --- a/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool.ts +++ b/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool.ts @@ -39,6 +39,16 @@ export interface AttestationPool { */ deleteAttestationsForSlot(slot: bigint): Promise; + /** + * Delete Attestations for slot and proposal + * + * Removes all attestations associated with a slot and proposal + * + * @param slot - The slot to delete. + * @param proposalId - The proposal to delete. + */ + deleteAttestationsForSlotAndProposal(slot: bigint, proposalId: string): Promise; + /** * Get Attestations for slot * diff --git a/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts b/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts new file mode 100644 index 00000000000..f8f838a08ab --- /dev/null +++ b/yarn-project/p2p/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts @@ -0,0 +1,237 @@ +import { type BlockAttestation, TxHash } from '@aztec/circuit-types'; +import { Secp256k1Signer } from '@aztec/foundation/crypto'; +import { Fr } from '@aztec/foundation/fields'; + +import { jest } from '@jest/globals'; +import { type MockProxy, mock } from 'jest-mock-extended'; + +import { type PoolInstrumentation } from '../instrumentation.js'; +import { type AttestationPool } from './attestation_pool.js'; +import { mockAttestation } from './mocks.js'; + +const NUMBER_OF_SIGNERS_PER_TEST = 4; + +export function describeAttestationPool(getAttestationPool: () => AttestationPool) { + let ap: AttestationPool; + let signers: Secp256k1Signer[]; + + // Check that metrics are recorded correctly + let metricsMock: MockProxy>; + + beforeEach(() => { + ap = getAttestationPool(); + signers = Array.from({ length: NUMBER_OF_SIGNERS_PER_TEST }, () => Secp256k1Signer.random()); + + metricsMock = mock>(); + // Can i overwrite this like this?? + (ap as any).metrics = metricsMock; + }); + + const createAttestationsForSlot = (slotNumber: number) => { + const archive = Fr.random(); + return signers.map(signer => mockAttestation(signer, slotNumber, archive)); + }; + + // We compare buffers as the objects can have cached values attached to them which are not serialised + // using array containing as the kv store does not respect insertion order + const compareAttestations = (a1: BlockAttestation[], a2: BlockAttestation[]) => { + const a1Buffer = a1.map(attestation => attestation.toBuffer()); + const a2Buffer = a2.map(attestation => attestation.toBuffer()); + expect(a1Buffer.length).toBe(a2Buffer.length); + expect(a1Buffer).toEqual(expect.arrayContaining(a2Buffer)); + }; + + it('should add attestations to pool', async () => { + const slotNumber = 420; + const archive = Fr.random(); + const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive)); + + await ap.addAttestations(attestations); + + // Check metrics have been updated. + expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length); + + const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), archive.toString()); + + expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST); + + compareAttestations(retreivedAttestations, attestations); + + // Delete by slot + await ap.deleteAttestationsForSlot(BigInt(slotNumber)); + + expect(metricsMock.recordRemovedObjects).toHaveBeenCalledWith(attestations.length); + + const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), archive.toString()); + expect(retreivedAttestationsAfterDelete.length).toBe(0); + }); + + it('Should handle duplicate proposals in a slot', async () => { + const slotNumber = 420; + const archive = Fr.random(); + const txs = [0, 1, 2, 3, 4, 5].map(() => TxHash.random()); + + // Use the same signer for all attestations + const attestations: BlockAttestation[] = []; + const signer = signers[0]; + for (let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++) { + attestations.push(mockAttestation(signer, slotNumber, archive, txs)); + } + + await ap.addAttestations(attestations); + + const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), archive.toString()); + expect(retreivedAttestations.length).toBe(1); + expect(retreivedAttestations[0].toBuffer()).toEqual(attestations[0].toBuffer()); + expect(retreivedAttestations[0].payload.txHashes).toEqual(txs); + expect(retreivedAttestations[0].getSender().toString()).toEqual(signer.address.toString()); + }); + + it('Should store attestations by differing slot', async () => { + const slotNumbers = [1, 2, 3, 4]; + const attestations = signers.map((signer, i) => mockAttestation(signer, slotNumbers[i])); + + await ap.addAttestations(attestations); + + for (const attestation of attestations) { + const slot = attestation.payload.header.globalVariables.slotNumber; + const archive = attestation.archive.toString(); + + const retreivedAttestations = await ap.getAttestationsForSlot(slot.toBigInt(), archive); + expect(retreivedAttestations.length).toBe(1); + expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer()); + expect(retreivedAttestations[0].payload.header.globalVariables.slotNumber).toEqual(slot); + } + }); + + it('Should store attestations by differing slot and archive', async () => { + const slotNumbers = [1, 1, 2, 3]; + const archives = [Fr.random(), Fr.random(), Fr.random(), Fr.random()]; + const attestations = signers.map((signer, i) => mockAttestation(signer, slotNumbers[i], archives[i])); + + await ap.addAttestations(attestations); + + for (const attestation of attestations) { + const slot = attestation.payload.header.globalVariables.slotNumber; + const proposalId = attestation.archive.toString(); + + const retreivedAttestations = await ap.getAttestationsForSlot(slot.toBigInt(), proposalId); + expect(retreivedAttestations.length).toBe(1); + expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer()); + expect(retreivedAttestations[0].payload.header.globalVariables.slotNumber).toEqual(slot); + } + }); + + it('Should delete attestations', async () => { + const slotNumber = 420; + const archive = Fr.random(); + const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive)); + const proposalId = attestations[0].archive.toString(); + + await ap.addAttestations(attestations); + + expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length); + + const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId); + expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST); + compareAttestations(retreivedAttestations, attestations); + + await ap.deleteAttestations(attestations); + + expect(metricsMock.recordRemovedObjects).toHaveBeenCalledWith(attestations.length); + + const gottenAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId); + expect(gottenAfterDelete.length).toBe(0); + }); + + it('Should blanket delete attestations per slot', async () => { + const slotNumber = 420; + const archive = Fr.random(); + const attestations = await Promise.all(signers.map(signer => mockAttestation(signer, slotNumber, archive))); + const proposalId = attestations[0].archive.toString(); + + await ap.addAttestations(attestations); + + const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId); + expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST); + compareAttestations(retreivedAttestations, attestations); + + await ap.deleteAttestationsForSlot(BigInt(slotNumber)); + + const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId); + expect(retreivedAttestationsAfterDelete.length).toBe(0); + }); + + it('Should blanket delete attestations per slot and proposal', async () => { + const slotNumber = 420; + const archive = Fr.random(); + const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive)); + const proposalId = attestations[0].archive.toString(); + + // Add another set of attestations with a different proposalId, yet the same slot + const archive2 = Fr.random(); + const attestations2 = signers.map(signer => mockAttestation(signer, slotNumber, archive2)); + const proposalId2 = attestations2[0].archive.toString(); + + await ap.addAttestations(attestations); + await ap.addAttestations(attestations2); + + expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length); + expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations2.length); + + const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId); + expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST); + compareAttestations(retreivedAttestations, attestations); + + await ap.deleteAttestationsForSlotAndProposal(BigInt(slotNumber), proposalId); + + expect(metricsMock.recordRemovedObjects).toHaveBeenCalledWith(attestations.length); + + const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId); + expect(retreivedAttestationsAfterDelete.length).toBe(0); + + const retreivedAttestationsAfterDeleteForOtherProposal = await ap.getAttestationsForSlot( + BigInt(slotNumber), + proposalId2, + ); + expect(retreivedAttestationsAfterDeleteForOtherProposal.length).toBe(NUMBER_OF_SIGNERS_PER_TEST); + compareAttestations(retreivedAttestationsAfterDeleteForOtherProposal, attestations2); + }); + + it('Should blanket delete attestations per slot and proposal (does not perform db ops if there are no attestations)', async () => { + const slotNumber = 420; + const proposalId = 'proposalId'; + + const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId); + expect(retreivedAttestations.length).toBe(0); + + await ap.deleteAttestationsForSlotAndProposal(BigInt(slotNumber), proposalId); + + expect(metricsMock.recordRemovedObjects).toHaveBeenCalledTimes(0); + }); + + it('Should delete attestations older than a given slot', async () => { + const slotNumbers = [1, 2, 3, 69, 72, 74, 88, 420]; + const attestations = slotNumbers.map(slotNumber => createAttestationsForSlot(slotNumber)).flat(); + const proposalId = attestations[0].archive.toString(); + + await ap.addAttestations(attestations); + + const attestationsForSlot1 = await ap.getAttestationsForSlot(BigInt(1), proposalId); + expect(attestationsForSlot1.length).toBe(signers.length); + + const deleteAttestationsSpy = jest.spyOn(ap, 'deleteAttestationsForSlot'); + + await ap.deleteAttestationsOlderThan(BigInt(73)); + + const attestationsForSlot1AfterDelete = await ap.getAttestationsForSlot(BigInt(1), proposalId); + expect(attestationsForSlot1AfterDelete.length).toBe(0); + + expect(deleteAttestationsSpy).toHaveBeenCalledTimes(5); + expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(1)); + expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(2)); + expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(3)); + expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(69)); + expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(72)); + }); +} diff --git a/yarn-project/p2p/src/mem_pools/attestation_pool/kv_attestation_pool.test.ts b/yarn-project/p2p/src/mem_pools/attestation_pool/kv_attestation_pool.test.ts new file mode 100644 index 00000000000..2832694784c --- /dev/null +++ b/yarn-project/p2p/src/mem_pools/attestation_pool/kv_attestation_pool.test.ts @@ -0,0 +1,18 @@ +import { type AztecKVStore } from '@aztec/kv-store'; +import { openTmpStore } from '@aztec/kv-store/lmdb'; +import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; + +import { describeAttestationPool } from './attestation_pool_test_suite.js'; +import { KvAttestationPool } from './kv_attestation_pool.js'; + +describe('KV Attestation Pool', () => { + let kvAttestationPool: KvAttestationPool; + let store: AztecKVStore; + + beforeEach(() => { + store = openTmpStore(); + kvAttestationPool = new KvAttestationPool(store, new NoopTelemetryClient()); + }); + + describeAttestationPool(() => kvAttestationPool); +}); diff --git a/yarn-project/p2p/src/mem_pools/attestation_pool/kv_attestation_pool.ts b/yarn-project/p2p/src/mem_pools/attestation_pool/kv_attestation_pool.ts new file mode 100644 index 00000000000..8de98828eed --- /dev/null +++ b/yarn-project/p2p/src/mem_pools/attestation_pool/kv_attestation_pool.ts @@ -0,0 +1,153 @@ +import { BlockAttestation } from '@aztec/circuit-types'; +import { Fr } from '@aztec/foundation/fields'; +import { createLogger } from '@aztec/foundation/log'; +import { type AztecKVStore, type AztecMapWithSize, type AztecMultiMap } from '@aztec/kv-store'; +import { type TelemetryClient } from '@aztec/telemetry-client'; + +import { PoolInstrumentation, PoolName } from '../instrumentation.js'; +import { type AttestationPool } from './attestation_pool.js'; + +export class KvAttestationPool implements AttestationPool { + private metrics: PoolInstrumentation; + + // Index of all proposal ids in a slot + private attestations: AztecMultiMap; + + constructor( + private store: AztecKVStore, + telemetry: TelemetryClient, + private log = createLogger('aztec:attestation_pool'), + ) { + this.attestations = store.openMultiMap('attestations'); + this.metrics = new PoolInstrumentation(telemetry, PoolName.ATTESTATION_POOL); + } + + private getProposalMapKey(slot: string, proposalId: string): string { + return `proposal-${slot}-${proposalId}`; + } + + /** + * Get the proposal map for a given slot and proposalId + * + * Essentially a nested mapping of address -> attestation + * + * @param slot - The slot to get the proposal map for + * @param proposalId - The proposalId to get the map for + * @returns The proposal map + */ + private getProposalMap(slot: string, proposalId: string): AztecMapWithSize { + const mapKey = this.getProposalMapKey(slot, proposalId); + return this.store.openMapWithSize(mapKey); + } + + public async addAttestations(attestations: BlockAttestation[]): Promise { + for (const attestation of attestations) { + const slotNumber = attestation.payload.header.globalVariables.slotNumber.toString(); + const proposalId = attestation.archive.toString(); + const address = attestation.getSender().toString(); + + // Index the proposalId in the slot map + await this.attestations.set(slotNumber, proposalId); + + // Store the actual attestation in the proposal map + const proposalMap = this.getProposalMap(slotNumber, proposalId); + await proposalMap.set(address, attestation.toBuffer()); + + this.log.verbose(`Added attestation for slot ${slotNumber} from ${address}`); + } + + this.metrics.recordAddedObjects(attestations.length); + } + + public getAttestationsForSlot(slot: bigint, proposalId: string): Promise { + const slotNumber = new Fr(slot).toString(); + const proposalMap = this.getProposalMap(slotNumber, proposalId); + const attestations = proposalMap.values(); + const attestationsArray = Array.from(attestations).map(attestation => BlockAttestation.fromBuffer(attestation)); + return Promise.resolve(attestationsArray); + } + + public async deleteAttestationsOlderThan(oldestSlot: bigint): Promise { + const olderThan = []; + + const slots = this.attestations.keys(); + for (const slot of slots) { + if (BigInt(slot) < oldestSlot) { + olderThan.push(slot); + } + } + + await Promise.all(olderThan.map(oldSlot => this.deleteAttestationsForSlot(BigInt(oldSlot)))); + return Promise.resolve(); + } + + public async deleteAttestationsForSlot(slot: bigint): Promise { + const deletionPromises = []; + + const slotString = new Fr(slot).toString(); + let numberOfAttestations = 0; + const proposalIds = this.attestations.getValues(slotString); + + if (proposalIds) { + for (const proposalId of proposalIds) { + const proposalMap = this.getProposalMap(slotString, proposalId); + numberOfAttestations += proposalMap.size(); + deletionPromises.push(proposalMap.clear()); + } + } + + await Promise.all(deletionPromises); + + this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot}`); + this.metrics.recordRemovedObjects(numberOfAttestations); + return Promise.resolve(); + } + + public async deleteAttestationsForSlotAndProposal(slot: bigint, proposalId: string): Promise { + const deletionPromises = []; + + const slotString = new Fr(slot).toString(); + const exists = this.attestations.get(slotString); + + if (exists) { + // Remove the proposalId from the slot index + deletionPromises.push(this.attestations.deleteValue(slotString, proposalId)); + + // Delete all attestations for the proposalId + const proposalMap = this.getProposalMap(slotString, proposalId); + const numberOfAttestations = proposalMap.size(); + deletionPromises.push(proposalMap.clear()); + + this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot} and proposal ${proposalId}`); + this.metrics.recordRemovedObjects(numberOfAttestations); + } + + await Promise.all(deletionPromises); + return Promise.resolve(); + } + + public async deleteAttestations(attestations: BlockAttestation[]): Promise { + const deletionPromises = []; + + for (const attestation of attestations) { + const slotNumber = attestation.payload.header.globalVariables.slotNumber.toString(); + const proposalId = attestation.archive.toString(); + const proposalMap = this.getProposalMap(slotNumber, proposalId); + + if (proposalMap) { + const address = attestation.getSender().toString(); + deletionPromises.push(proposalMap.delete(address)); + this.log.debug(`Deleted attestation for slot ${slotNumber} from ${address}`); + } + + if (proposalMap.size() === 0) { + deletionPromises.push(this.attestations.deleteValue(slotNumber, proposalId)); + } + } + + await Promise.all(deletionPromises); + + this.metrics.recordRemovedObjects(attestations.length); + return Promise.resolve(); + } +} diff --git a/yarn-project/p2p/src/mem_pools/attestation_pool/memory_attestation_pool.test.ts b/yarn-project/p2p/src/mem_pools/attestation_pool/memory_attestation_pool.test.ts index ef80dad21ec..5d2cd81b625 100644 --- a/yarn-project/p2p/src/mem_pools/attestation_pool/memory_attestation_pool.test.ts +++ b/yarn-project/p2p/src/mem_pools/attestation_pool/memory_attestation_pool.test.ts @@ -1,205 +1,13 @@ -import { type BlockAttestation, TxHash } from '@aztec/circuit-types'; -import { Secp256k1Signer } from '@aztec/foundation/crypto'; -import { Fr } from '@aztec/foundation/fields'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; -import { jest } from '@jest/globals'; -import { type MockProxy, mock } from 'jest-mock-extended'; - -import { type PoolInstrumentation } from '../instrumentation.js'; +import { describeAttestationPool } from './attestation_pool_test_suite.js'; import { InMemoryAttestationPool } from './memory_attestation_pool.js'; -import { mockAttestation } from './mocks.js'; - -const NUMBER_OF_SIGNERS_PER_TEST = 4; - -describe('MemoryAttestationPool', () => { - let ap: InMemoryAttestationPool; - let signers: Secp256k1Signer[]; - const telemetry = new NoopTelemetryClient(); - - // Check that metrics are recorded correctly - let metricsMock: MockProxy>; +describe('In-Memory Attestation Pool', () => { + let inMemoryAttestationPool: InMemoryAttestationPool; beforeEach(() => { - // Use noop telemetry client while testing. - - ap = new InMemoryAttestationPool(telemetry); - signers = Array.from({ length: NUMBER_OF_SIGNERS_PER_TEST }, () => Secp256k1Signer.random()); - - metricsMock = mock>(); - // Can i overwrite this like this?? - (ap as any).metrics = metricsMock; - }); - - const createAttestationsForSlot = (slotNumber: number) => { - const archive = Fr.random(); - return signers.map(signer => mockAttestation(signer, slotNumber, archive)); - }; - - it('should add attestations to pool', async () => { - const slotNumber = 420; - const archive = Fr.random(); - const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive)); - - await ap.addAttestations(attestations); - - // Check metrics have been updated. - expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length); - - const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), archive.toString()); - - expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST); - expect(retreivedAttestations).toEqual(attestations); - - // Delete by slot - await ap.deleteAttestationsForSlot(BigInt(slotNumber)); - - expect(metricsMock.recordRemovedObjects).toHaveBeenCalledWith(attestations.length); - - const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), archive.toString()); - expect(retreivedAttestationsAfterDelete.length).toBe(0); - }); - - it('Should handle duplicate proposals in a slot', async () => { - const slotNumber = 420; - const archive = Fr.random(); - const txs = [0, 1, 2, 3, 4, 5].map(() => TxHash.random()); - - // Use the same signer for all attestations - const attestations: BlockAttestation[] = []; - const signer = signers[0]; - for (let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++) { - attestations.push(mockAttestation(signer, slotNumber, archive, txs)); - } - - await ap.addAttestations(attestations); - - const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), archive.toString()); - expect(retreivedAttestations.length).toBe(1); - expect(retreivedAttestations[0]).toEqual(attestations[0]); - expect(retreivedAttestations[0].payload.txHashes).toEqual(txs); - expect(retreivedAttestations[0].getSender().toString()).toEqual(signer.address.toString()); - }); - - it('Should store attestations by differing slot', async () => { - const slotNumbers = [1, 2, 3, 4]; - const attestations = signers.map((signer, i) => mockAttestation(signer, slotNumbers[i])); - - await ap.addAttestations(attestations); - - for (const attestation of attestations) { - const slot = attestation.payload.header.globalVariables.slotNumber; - const archive = attestation.archive.toString(); - - const retreivedAttestations = await ap.getAttestationsForSlot(slot.toBigInt(), archive); - expect(retreivedAttestations.length).toBe(1); - expect(retreivedAttestations[0]).toEqual(attestation); - expect(retreivedAttestations[0].payload.header.globalVariables.slotNumber).toEqual(slot); - } - }); - - it('Should store attestations by differing slot and archive', async () => { - const slotNumbers = [1, 2, 3, 4]; - const archives = [Fr.random(), Fr.random(), Fr.random(), Fr.random()]; - const attestations = signers.map((signer, i) => mockAttestation(signer, slotNumbers[i], archives[i])); - - await ap.addAttestations(attestations); - - for (const attestation of attestations) { - const slot = attestation.payload.header.globalVariables.slotNumber; - const proposalId = attestation.archive.toString(); - - const retreivedAttestations = await ap.getAttestationsForSlot(slot.toBigInt(), proposalId); - expect(retreivedAttestations.length).toBe(1); - expect(retreivedAttestations[0]).toEqual(attestation); - expect(retreivedAttestations[0].payload.header.globalVariables.slotNumber).toEqual(slot); - } - }); - - it('Should delete attestations', async () => { - const slotNumber = 420; - const archive = Fr.random(); - const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive)); - const proposalId = attestations[0].archive.toString(); - - await ap.addAttestations(attestations); - - expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length); - - const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId); - expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST); - expect(retreivedAttestations).toEqual(attestations); - - await ap.deleteAttestations(attestations); - - expect(metricsMock.recordRemovedObjects).toHaveBeenCalledWith(attestations.length); - - const gottenAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId); - expect(gottenAfterDelete.length).toBe(0); - }); - - it('Should blanket delete attestations per slot', async () => { - const slotNumber = 420; - const archive = Fr.random(); - const attestations = await Promise.all(signers.map(signer => mockAttestation(signer, slotNumber, archive))); - const proposalId = attestations[0].archive.toString(); - - await ap.addAttestations(attestations); - - const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId); - expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST); - expect(retreivedAttestations).toEqual(attestations); - - await ap.deleteAttestationsForSlot(BigInt(slotNumber)); - - const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId); - expect(retreivedAttestationsAfterDelete.length).toBe(0); + inMemoryAttestationPool = new InMemoryAttestationPool(new NoopTelemetryClient()); }); - it('Should blanket delete attestations per slot and proposal', async () => { - const slotNumber = 420; - const archive = Fr.random(); - const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive)); - const proposalId = attestations[0].archive.toString(); - - await ap.addAttestations(attestations); - - expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length); - - const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId); - expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST); - expect(retreivedAttestations).toEqual(attestations); - - await ap.deleteAttestationsForSlotAndProposal(BigInt(slotNumber), proposalId); - - expect(metricsMock.recordRemovedObjects).toHaveBeenCalledWith(attestations.length); - - const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId); - expect(retreivedAttestationsAfterDelete.length).toBe(0); - }); - - it('Should delete attestations older than a given slot', async () => { - const slotNumbers = [1, 2, 3, 69, 72, 74, 88, 420]; - const attestations = slotNumbers.map(slotNumber => createAttestationsForSlot(slotNumber)).flat(); - const proposalId = attestations[0].archive.toString(); - - await ap.addAttestations(attestations); - - const attestationsForSlot1 = await ap.getAttestationsForSlot(BigInt(1), proposalId); - expect(attestationsForSlot1.length).toBe(signers.length); - - const deleteAttestationsSpy = jest.spyOn(ap, 'deleteAttestationsForSlot'); - - await ap.deleteAttestationsOlderThan(BigInt(73)); - - const attestationsForSlot1AfterDelete = await ap.getAttestationsForSlot(BigInt(1), proposalId); - expect(attestationsForSlot1AfterDelete.length).toBe(0); - - expect(deleteAttestationsSpy).toHaveBeenCalledTimes(5); - expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(1)); - expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(2)); - expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(3)); - expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(69)); - expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(72)); - }); + describeAttestationPool(() => inMemoryAttestationPool); }); diff --git a/yarn-project/p2p/src/services/reqresp/reqresp.integration.test.ts b/yarn-project/p2p/src/services/reqresp/reqresp.integration.test.ts index 6b11f5b01c6..d94075e288c 100644 --- a/yarn-project/p2p/src/services/reqresp/reqresp.integration.test.ts +++ b/yarn-project/p2p/src/services/reqresp/reqresp.integration.test.ts @@ -69,6 +69,7 @@ const makeMockPools = () => { deleteAttestations: jest.fn(), deleteAttestationsForSlot: jest.fn(), deleteAttestationsOlderThan: jest.fn(), + deleteAttestationsForSlotAndProposal: jest.fn(), getAttestationsForSlot: jest.fn().mockReturnValue(undefined), }, epochProofQuotePool: { From 4ac13e642c958392ce5606684c044ea014325e26 Mon Sep 17 00:00:00 2001 From: Jean M <132435771+jeanmon@users.noreply.github.com> Date: Tue, 17 Dec 2024 22:45:48 +0100 Subject: [PATCH 04/34] chore(avm): radix opcode - remove immediates (#10696) Resolves #10371 --- avm-transpiler/src/transpile.rs | 19 +-- .../dsl/acir_format/serde/acir.hpp | 16 ++- .../vm/avm/tests/execution.test.cpp | 115 ++++++------------ .../vm/avm/trace/deserialization.cpp | 4 +- .../barretenberg/vm/avm/trace/execution.cpp | 4 +- .../src/barretenberg/vm/avm/trace/trace.cpp | 47 ++++--- .../src/barretenberg/vm/avm/trace/trace.hpp | 8 +- .../noir-repo/acvm-repo/acir/codegen/acir.cpp | 14 ++- .../acvm-repo/brillig/src/black_box.rs | 5 +- .../acvm-repo/brillig_vm/src/black_box.rs | 16 ++- .../brillig/brillig_ir/codegen_intrinsic.rs | 16 ++- .../src/brillig/brillig_ir/debug_show.rs | 7 +- .../src/avm/opcodes/conversion.test.ts | 88 +++++++++----- .../simulator/src/avm/opcodes/conversion.ts | 37 +++--- 14 files changed, 206 insertions(+), 190 deletions(-) diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index 79f4a3f02bb..d8b9c9509c9 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -1064,29 +1064,30 @@ fn handle_black_box_function(avm_instrs: &mut Vec, operation: &B ..Default::default() }); } - BlackBoxOp::ToRadix { input, radix, output, output_bits } => { - let num_limbs = output.size as u32; + BlackBoxOp::ToRadix { input, radix, output_pointer, num_limbs, output_bits } => { let input_offset = input.to_usize() as u32; - let output_offset = output.pointer.to_usize() as u32; let radix_offset = radix.to_usize() as u32; + let output_offset = output_pointer.to_usize() as u32; + let num_limbs_offset = num_limbs.to_usize() as u32; + let output_bits_offset = output_bits.to_usize() as u32; avm_instrs.push(AvmInstruction { opcode: AvmOpcode::TORADIXBE, indirect: Some( AddressingModeBuilder::default() .direct_operand(input) - .indirect_operand(&output.pointer) .direct_operand(radix) + .direct_operand(num_limbs) + .direct_operand(output_bits) + .indirect_operand(output_pointer) .build(), ), operands: vec![ AvmOperand::U16 { value: input_offset as u16 }, - AvmOperand::U16 { value: output_offset as u16 }, AvmOperand::U16 { value: radix_offset as u16 }, - ], - immediates: vec![ - AvmOperand::U16 { value: num_limbs as u16 }, - AvmOperand::U8 { value: *output_bits as u8 }, + AvmOperand::U16 { value: num_limbs_offset as u16 }, + AvmOperand::U16 { value: output_bits_offset as u16 }, + AvmOperand::U16 { value: output_offset as u16 }, ], ..Default::default() }); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp index fda8739c9fb..5d9d94d25e3 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -424,8 +424,9 @@ struct BlackBoxOp { struct ToRadix { Program::MemoryAddress input; Program::MemoryAddress radix; - Program::HeapArray output; - bool output_bits; + Program::MemoryAddress output_pointer; + Program::MemoryAddress num_limbs; + Program::MemoryAddress output_bits; friend bool operator==(const ToRadix&, const ToRadix&); std::vector bincodeSerialize() const; @@ -4611,7 +4612,10 @@ inline bool operator==(const BlackBoxOp::ToRadix& lhs, const BlackBoxOp::ToRadix if (!(lhs.radix == rhs.radix)) { return false; } - if (!(lhs.output == rhs.output)) { + if (!(lhs.output_pointer == rhs.output_pointer)) { + return false; + } + if (!(lhs.num_limbs == rhs.num_limbs)) { return false; } if (!(lhs.output_bits == rhs.output_bits)) { @@ -4646,7 +4650,8 @@ void serde::Serializable::serialize(const Program: { serde::Serializable::serialize(obj.input, serializer); serde::Serializable::serialize(obj.radix, serializer); - serde::Serializable::serialize(obj.output, serializer); + serde::Serializable::serialize(obj.output_pointer, serializer); + serde::Serializable::serialize(obj.num_limbs, serializer); serde::Serializable::serialize(obj.output_bits, serializer); } @@ -4658,7 +4663,8 @@ Program::BlackBoxOp::ToRadix serde::Deserializable Program::BlackBoxOp::ToRadix obj; obj.input = serde::Deserializable::deserialize(deserializer); obj.radix = serde::Deserializable::deserialize(deserializer); - obj.output = serde::Deserializable::deserialize(deserializer); + obj.output_pointer = serde::Deserializable::deserialize(deserializer); + obj.num_limbs = serde::Deserializable::deserialize(deserializer); obj.output_bits = serde::Deserializable::deserialize(deserializer); return obj; } 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 89946de9b53..86b62b8a64e 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp @@ -130,6 +130,8 @@ class AvmExecutionTests : public ::testing::Test { } }; +class AvmExecutionTestsToRadix : public AvmExecutionTests, public testing::WithParamInterface {}; + // Basic positive test with an ADD and RETURN opcode. // Parsing, trace generation and proving is verified. TEST_F(AvmExecutionTests, basicAddReturn) @@ -854,85 +856,15 @@ TEST_F(AvmExecutionTests, setAndCastOpcodes) validate_trace(std::move(trace), public_inputs); } -// Positive test with TO_RADIX_BE. -TEST_F(AvmExecutionTests, toRadixBeOpcodeBytes) -{ - std::string bytecode_hex = - to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "00" // dst_offset - + to_hex(AvmMemoryTag::U32) + "00" // val - + to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "01" // dst_offset - + to_hex(AvmMemoryTag::U32) + "01" // val - + to_hex(OpCode::CALLDATACOPY) + // opcode CALLDATACOPY - "00" // Indirect flag - "0000" // cd_offset - "0001" // copy_size - "0001" // dst_offset - + to_hex(OpCode::SET_8) + // opcode SET for indirect src - "00" // Indirect flag - "11" // dst_offset 17 - + to_hex(AvmMemoryTag::U32) + "01" // value 1 (i.e. where the src from calldata is copied) - + to_hex(OpCode::SET_8) + // opcode SET for indirect dst - "00" // Indirect flag - "15" // dst_offset 21 - + to_hex(AvmMemoryTag::U32) + "05" // value 5 (i.e. where the dst will be written to) - + to_hex(OpCode::SET_8) + // opcode SET for indirect dst - "00" // Indirect flag - "80" // radix_offset 80 - + to_hex(AvmMemoryTag::U32) + "02" // value 2 (i.e. radix 2 - perform bitwise decomposition) - + to_hex(OpCode::TORADIXBE) + // opcode TO_RADIX_BE - "03" // Indirect flag - "0011" // src_offset 17 (indirect) - "0015" // dst_offset 21 (indirect) - "0080" // radix_offset 80 (direct) - "0100" // limbs: 256 - "00" // output_bits: false - + to_hex(OpCode::SET_16) + // opcode SET (for return size) - "00" // Indirect flag - "0200" // dst_offset=512 - + to_hex(AvmMemoryTag::U32) + // - "0100" // val: 256 - + to_hex(OpCode::RETURN) + // opcode RETURN - "00" // Indirect flag - "0005" // ret offset 5 - "0200"; // ret size offset 512 - - auto bytecode = hex_to_bytes(bytecode_hex); - 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; - ExecutionHints execution_hints; - auto trace = - gen_trace(bytecode, std::vector{ FF::modulus - FF(1) }, public_inputs, returndata, execution_hints); - - // Find the first row enabling the TORADIXBE selector - // Expected output is bitwise decomposition of MODULUS - 1..could hardcode the result but it's a bit long - size_t num_limbs = 256; - std::vector expected_output(num_limbs); - // Extract each bit. - for (size_t i = 0; i < num_limbs; i++) { - auto byte_index = num_limbs - i - 1; - FF expected_limb = (FF::modulus - 1) >> i & 1; - expected_output[byte_index] = expected_limb; - } - EXPECT_EQ(returndata, expected_output); - - validate_trace(std::move(trace), public_inputs, { FF::modulus - FF(1) }, returndata); -} - -// Positive test with TO_RADIX_BE. -TEST_F(AvmExecutionTests, toRadixBeOpcodeBitsMode) +namespace { +std::vector gen_bytecode_radix(bool is_bit_mode) { + const std::string bit_mode_hex = is_bit_mode ? "01" : "00"; std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET "00" // Indirect flag "00" // dst_offset - + to_hex(AvmMemoryTag::U32) // - + "00" // val + + to_hex(AvmMemoryTag::U32) + // + "00" // val + to_hex(OpCode::SET_8) + // opcode SET "00" // Indirect flag "01" // dst_offset @@ -953,18 +885,28 @@ TEST_F(AvmExecutionTests, toRadixBeOpcodeBitsMode) "15" // dst_offset 21 + to_hex(AvmMemoryTag::U32) + // "05" // value 5 (i.e. where the dst will be written to) - + to_hex(OpCode::SET_8) + // opcode SET for indirect dst + + to_hex(OpCode::SET_8) + // opcode SET (direct radix_offset) "00" // Indirect flag "80" // radix_offset 80 + to_hex(AvmMemoryTag::U32) + // "02" // value 2 (i.e. radix 2 - perform bitwise decomposition) + + to_hex(OpCode::SET_16) + // opcode SET (direct number_limbs_offset) + "00" // Indirect flag + "0090" // number_limbs_offset 0x90 + + to_hex(AvmMemoryTag::U32) + // + "0100" // value 256 + + to_hex(OpCode::SET_8) + // opcode SET (direct output_bits_offset) + "00" // Indirect flag + "95" // output_bits_offset 0x95 + + to_hex(AvmMemoryTag::U1) + // + bit_mode_hex // bit 1 (true for bits mode) + to_hex(OpCode::TORADIXBE) + // opcode TO_RADIX_BE - "03" // Indirect flag + "0011" // Indirect flag "0011" // src_offset 17 (indirect) - "0015" // dst_offset 21 (indirect) "0080" // radix_offset 80 (direct) - "0100" // limbs: 256 - "01" // output_bits: true + "0090" // num_limbs_offset (direct) + "0095" // output_bits_offset (direct) + "0015" // dst_offset 21 (indirect) + to_hex(OpCode::SET_16) + // opcode SET (for return size) "00" // Indirect flag "0200" // dst_offset=512 @@ -975,7 +917,15 @@ TEST_F(AvmExecutionTests, toRadixBeOpcodeBitsMode) "0005" // ret offset 5 "0200"; // ret size offset 512 - auto bytecode = hex_to_bytes(bytecode_hex); + return hex_to_bytes(bytecode_hex); +} +} // namespace + +// Positive test for TORADIXBE opcode parametrized by a boolean toggling bit vs bytes mode. +TEST_P(AvmExecutionTestsToRadix, ParamTest) +{ + const bool is_bit_mode = GetParam(); + auto bytecode = gen_bytecode_radix(is_bit_mode); auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode); ASSERT_TRUE(is_ok(error)); @@ -1000,6 +950,9 @@ TEST_F(AvmExecutionTests, toRadixBeOpcodeBitsMode) validate_trace(std::move(trace), public_inputs, { FF::modulus - FF(1) }, returndata); } +// Run the test for TORADIXBE in bit mode and then in bytes mode. +INSTANTIATE_TEST_SUITE_P(AvmExecutionTests, AvmExecutionTestsToRadix, testing::ValuesIn({ true, false })); + // // Positive test with SHA256COMPRESSION. TEST_F(AvmExecutionTests, sha256CompressionOpcode) { diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp index ba6a60397ae..2478ba93dd3 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp @@ -179,12 +179,12 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = { OperandType::INDIRECT8, OperandType::UINT16, OperandType::UINT16, OperandType::UINT16, OperandType::UINT16 } }, // Gadget - Conversion { OpCode::TORADIXBE, - { OperandType::INDIRECT8, + { OperandType::INDIRECT16, OperandType::UINT16, OperandType::UINT16, OperandType::UINT16, OperandType::UINT16, - OperandType::UINT8 } }, + OperandType::UINT16 } }, }; const std::unordered_map OPERAND_TYPE_SIZE = { diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp index 6b8f7ae0b0e..ba9b71cef20 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp @@ -974,12 +974,12 @@ AvmError Execution::execute_enqueued_call(AvmTraceBuilder& trace_builder, // Conversions case OpCode::TORADIXBE: - error = trace_builder.op_to_radix_be(std::get(inst.operands.at(0)), + error = trace_builder.op_to_radix_be(std::get(inst.operands.at(0)), std::get(inst.operands.at(1)), std::get(inst.operands.at(2)), std::get(inst.operands.at(3)), std::get(inst.operands.at(4)), - std::get(inst.operands.at(5))); + std::get(inst.operands.at(5))); break; default: diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp index 3874a9cab8c..8aadc08d280 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp @@ -4429,35 +4429,50 @@ AvmError AvmTraceBuilder::op_variable_msm(uint8_t indirect, * * @param indirect A byte encoding information about indirect/direct memory access. * @param src_offset An index in memory pointing to the input of the To_Radix_BE conversion. - * @param dst_offset An index in memory pointing to the output of the To_Radix_BE conversion. * @param radix_offset An index in memory pointing to the strict upper bound of each converted limb, i.e., 0 <= limb * < radix. - * @param num_limbs The number of limbs to the value into. - * @param output_bits Should the output be U1s instead of U8s? + * @param num_limbs_offset Offset pointing to the number of limbs to the value into. + * @param output_bits_offset Offset pointing to a boolean telling whether bits (U1) or bytes (U8) are in the output + * @param dst_offset An index in memory pointing to the output of the To_Radix_BE conversion. */ -AvmError AvmTraceBuilder::op_to_radix_be(uint8_t indirect, +AvmError AvmTraceBuilder::op_to_radix_be(uint16_t indirect, uint32_t src_offset, - uint32_t dst_offset, uint32_t radix_offset, - uint32_t num_limbs, - uint8_t output_bits) + uint32_t num_limbs_offset, + uint32_t output_bits_offset, + uint32_t dst_offset) { // We keep the first encountered error AvmError error = AvmError::NO_ERROR; auto clk = static_cast(main_trace.size()) + 1; - // write output as bits or bytes - AvmMemoryTag w_in_tag = output_bits > 0 ? AvmMemoryTag::U1 // bits mode - : AvmMemoryTag::U8; - - auto [resolved_addrs, res_error] = Addressing<3>::fromWire(indirect, call_ptr) - .resolve({ src_offset, dst_offset, radix_offset }, mem_trace_builder); - auto [resolved_src_offset, resolved_dst_offset, resolved_radix_offset] = resolved_addrs; + auto [resolved_addrs, res_error] = + Addressing<5>::fromWire(indirect, call_ptr) + .resolve({ src_offset, radix_offset, num_limbs_offset, output_bits_offset, dst_offset }, mem_trace_builder); + auto [resolved_src_offset, + resolved_radix_offset, + resolved_num_limbs_offset, + resolved_output_bits_offset, + resolved_dst_offset] = resolved_addrs; error = res_error; + if (is_ok(error) && !check_tag(AvmMemoryTag::U32, resolved_radix_offset) && + !check_tag(AvmMemoryTag::U32, resolved_num_limbs_offset) && + !check_tag(AvmMemoryTag::U1, resolved_output_bits_offset)) { + error = AvmError::CHECK_TAG_ERROR; + } + + const auto num_limbs = static_cast(unconstrained_read_from_memory(resolved_num_limbs_offset)); + // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::TORADIXBE, num_limbs); + const auto output_bits = static_cast(unconstrained_read_from_memory(resolved_output_bits_offset)); + + // write output as bits or bytes + AvmMemoryTag w_in_tag = output_bits > 0 ? AvmMemoryTag::U1 // bits mode + : AvmMemoryTag::U8; + auto read_src = constrained_read_from_memory( call_ptr, clk, resolved_src_offset, AvmMemoryTag::FF, w_in_tag, IntermRegister::IA); // TODO(8603): once instructions can have multiple different tags for reads, constrain the radix's read @@ -4465,10 +4480,6 @@ AvmError AvmTraceBuilder::op_to_radix_be(uint8_t indirect, // auto read_radix = constrained_read_from_memory( // 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::CHECK_TAG_ERROR; - } - auto read_radix = unconstrained_read_from_memory(resolved_radix_offset); FF input = read_src.val; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp index b30e7d2c104..840de69fb1b 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp @@ -220,12 +220,12 @@ class AvmTraceBuilder { uint32_t output_offset, uint32_t point_length_offset); // Conversions - AvmError op_to_radix_be(uint8_t indirect, + AvmError op_to_radix_be(uint16_t indirect, uint32_t src_offset, - uint32_t dst_offset, uint32_t radix_offset, - uint32_t num_limbs, - uint8_t output_bits); + uint32_t num_limbs_offset, + uint32_t output_bits_offset, + uint32_t dst_offset); std::vector finalize(bool apply_end_gas_assertions = false); void reset(); diff --git a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp index e94f36535d2..2ae15f9f5a3 100644 --- a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp +++ b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp @@ -424,8 +424,9 @@ namespace Program { struct ToRadix { Program::MemoryAddress input; Program::MemoryAddress radix; - Program::HeapArray output; - bool output_bits; + Program::MemoryAddress output_pointer; + Program::MemoryAddress num_limbs; + Program::MemoryAddress output_bits; friend bool operator==(const ToRadix&, const ToRadix&); std::vector bincodeSerialize() const; @@ -3898,7 +3899,8 @@ namespace Program { inline bool operator==(const BlackBoxOp::ToRadix &lhs, const BlackBoxOp::ToRadix &rhs) { if (!(lhs.input == rhs.input)) { return false; } if (!(lhs.radix == rhs.radix)) { return false; } - if (!(lhs.output == rhs.output)) { return false; } + if (!(lhs.output_pointer == rhs.output_pointer)) { return false; } + if (!(lhs.num_limbs == rhs.num_limbs)) { return false; } if (!(lhs.output_bits == rhs.output_bits)) { return false; } return true; } @@ -3925,7 +3927,8 @@ template void serde::Serializable::serialize(const Program::BlackBoxOp::ToRadix &obj, Serializer &serializer) { serde::Serializable::serialize(obj.input, serializer); serde::Serializable::serialize(obj.radix, serializer); - serde::Serializable::serialize(obj.output, serializer); + serde::Serializable::serialize(obj.output_pointer, serializer); + serde::Serializable::serialize(obj.num_limbs, serializer); serde::Serializable::serialize(obj.output_bits, serializer); } @@ -3935,7 +3938,8 @@ Program::BlackBoxOp::ToRadix serde::Deserializable Program::BlackBoxOp::ToRadix obj; obj.input = serde::Deserializable::deserialize(deserializer); obj.radix = serde::Deserializable::deserialize(deserializer); - obj.output = serde::Deserializable::deserialize(deserializer); + obj.output_pointer = serde::Deserializable::deserialize(deserializer); + obj.num_limbs = serde::Deserializable::deserialize(deserializer); obj.output_bits = serde::Deserializable::deserialize(deserializer); return obj; } diff --git a/noir/noir-repo/acvm-repo/brillig/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig/src/black_box.rs index f185b36e6c8..be9ba20ed49 100644 --- a/noir/noir-repo/acvm-repo/brillig/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig/src/black_box.rs @@ -102,7 +102,8 @@ pub enum BlackBoxOp { ToRadix { input: MemoryAddress, radix: MemoryAddress, - output: HeapArray, - output_bits: bool, + output_pointer: MemoryAddress, + num_limbs: MemoryAddress, + output_bits: MemoryAddress, }, } diff --git a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs index 79aea2adf76..9ebbbd3f087 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs @@ -310,21 +310,27 @@ pub(crate) fn evaluate_black_box memory.write_slice(memory.read_ref(output.pointer), &state); Ok(()) } - BlackBoxOp::ToRadix { input, radix, output, output_bits } => { + BlackBoxOp::ToRadix { input, radix, output_pointer, num_limbs, output_bits } => { let input: F = *memory.read(*input).extract_field().expect("ToRadix input not a field"); let radix = memory .read(*radix) .expect_integer_with_bit_size(IntegerBitSize::U32) .expect("ToRadix opcode's radix bit size does not match expected bit size 32"); + let num_limbs = memory.read(*num_limbs).to_usize(); + let output_bits = !memory + .read(*output_bits) + .expect_integer_with_bit_size(IntegerBitSize::U1) + .expect("ToRadix opcode's output_bits size does not match expected bit size 1") + .is_zero(); let mut input = BigUint::from_bytes_be(&input.to_be_bytes()); let radix = BigUint::from_bytes_be(&radix.to_be_bytes()); - let mut limbs: Vec> = vec![MemoryValue::default(); output.size]; + let mut limbs: Vec> = vec![MemoryValue::default(); num_limbs]; - for i in (0..output.size).rev() { + for i in (0..num_limbs).rev() { let limb = &input % &radix; - if *output_bits { + if output_bits { limbs[i] = MemoryValue::new_integer( if limb.is_zero() { 0 } else { 1 }, IntegerBitSize::U1, @@ -336,7 +342,7 @@ pub(crate) fn evaluate_black_box input /= &radix; } - memory.write_slice(memory.read_ref(output.pointer), &limbs); + memory.write_slice(memory.read_ref(*output_pointer), &limbs); Ok(()) } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs index ba89823ef13..42c13a3c235 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs @@ -75,23 +75,27 @@ impl BrilligContext< assert!(source_field.bit_size == F::max_num_bits()); assert!(radix.bit_size == 32); + let bits_register = self.make_constant_instruction(output_bits.into(), 1); self.codegen_initialize_array(target_array); - - let heap_array = self.codegen_brillig_array_to_heap_array(target_array); + let pointer = self.codegen_make_array_items_pointer(target_array); + let num_limbs = self.make_usize_constant_instruction(target_array.size.into()); // Perform big-endian ToRadix self.black_box_op_instruction(BlackBoxOp::ToRadix { input: source_field.address, radix: radix.address, - output: heap_array, - output_bits, + output_pointer: pointer, + num_limbs: num_limbs.address, + output_bits: bits_register.address, }); if little_endian { let items_len = self.make_usize_constant_instruction(target_array.size.into()); - self.codegen_array_reverse(heap_array.pointer, items_len.address); + self.codegen_array_reverse(pointer, items_len.address); self.deallocate_single_addr(items_len); } - self.deallocate_register(heap_array.pointer); + self.deallocate_register(pointer); + self.deallocate_single_addr(bits_register); + self.deallocate_single_addr(num_limbs); } } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs index ef1b5432128..283c0d67eb8 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs @@ -397,13 +397,14 @@ impl DebugShow { output ); } - BlackBoxOp::ToRadix { input, radix, output, output_bits: _ } => { + BlackBoxOp::ToRadix { input, radix, output_pointer, num_limbs, output_bits: _ } => { debug_println!( self.enable_debug_trace, - " TO_RADIX {} {} -> {}", + " TO_RADIX {} {} {} -> {}", input, radix, - output + num_limbs, + output_pointer ); } } diff --git a/yarn-project/simulator/src/avm/opcodes/conversion.test.ts b/yarn-project/simulator/src/avm/opcodes/conversion.test.ts index 8db134f6d09..873ab29db5b 100644 --- a/yarn-project/simulator/src/avm/opcodes/conversion.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/conversion.test.ts @@ -1,5 +1,5 @@ import { type AvmContext } from '../avm_context.js'; -import { Field, type Uint1, type Uint8, Uint32 } from '../avm_memory_types.js'; +import { Field, Uint1, type Uint8, Uint32 } from '../avm_memory_types.js'; import { initContext } from '../fixtures/index.js'; import { Addressing, AddressingMode } from './addressing_mode.js'; import { ToRadixBE } from './conversion.js'; @@ -15,20 +15,20 @@ describe('Conversion Opcodes', () => { it('Should (de)serialize correctly', () => { const buf = Buffer.from([ ToRadixBE.opcode, // opcode - 1, // indirect + ...Buffer.from('0001', 'hex'), // indirect ...Buffer.from('1234', 'hex'), // inputStateOffset - ...Buffer.from('2345', 'hex'), // outputStateOffset - ...Buffer.from('3456', 'hex'), // radixOffset - ...Buffer.from('0100', 'hex'), // numLimbs - ...Buffer.from('01', 'hex'), // outputBits + ...Buffer.from('2345', 'hex'), // radixOffset + ...Buffer.from('3456', 'hex'), // numLimbsOffset + ...Buffer.from('4567', 'hex'), // outputBitsOffset + ...Buffer.from('5678', 'hex'), // outputStateOffset ]); const inst = new ToRadixBE( - /*indirect=*/ 1, + /*indirect=*/ 0x0001, /*srcOffset=*/ 0x1234, - /*dstOffset=*/ 0x2345, - /*radixOffset=*/ 0x3456, - /*numLimbs=*/ 256, - /*outputBits=*/ 1, + /*radixOffset=*/ 0x2345, + /*numLimbsOffset=*/ 0x3456, + /*outputBitsOffset=*/ 0x4567, + /*dstOffset=*/ 0x5678, ); expect(ToRadixBE.deserialize(buf)).toEqual(inst); @@ -42,21 +42,27 @@ describe('Conversion Opcodes', () => { const srcOffset = 0; const dstOffset = 20; const radixOffset = 1; - const numLimbs = 10; // only the first 10 bits - const outputBits = 0; // false, output as bytes + const numLimbs = new Uint32(10); // only the first 10 bits + const numLimbsOffset = 100; + const outputBits = new Uint1(0); // false, output as bytes + const outputBitsOffset = 200; context.machineState.memory.set(srcOffset, arg); context.machineState.memory.set(radixOffset, radix); + context.machineState.memory.set(numLimbsOffset, numLimbs); + context.machineState.memory.set(outputBitsOffset, outputBits); - await new ToRadixBE(indirect, srcOffset, dstOffset, radixOffset, numLimbs, outputBits).execute(context); + await new ToRadixBE(indirect, srcOffset, radixOffset, numLimbsOffset, outputBitsOffset, dstOffset).execute( + context, + ); const resultBuffer: Buffer = Buffer.concat( - context.machineState.memory.getSliceAs(dstOffset, numLimbs).map(byte => byte.toBuffer()), + context.machineState.memory.getSliceAs(dstOffset, numLimbs.toNumber()).map(byte => byte.toBuffer()), ); // The expected result is the first 10 bits of the input // Reverse before slice because still only care about the first `numLimb` bytes. // Then reverse back since we want big endian (as the original string is). - const expectedResults = '1011101010100'.split('').reverse().slice(0, numLimbs).reverse().map(Number); - for (let i = 0; i < numLimbs; i++) { + const expectedResults = '1011101010100'.split('').reverse().slice(0, numLimbs.toNumber()).reverse().map(Number); + for (let i = 0; i < numLimbs.toNumber(); i++) { expect(resultBuffer.readUInt8(i)).toEqual(expectedResults[i]); } }); @@ -68,21 +74,27 @@ describe('Conversion Opcodes', () => { const srcOffset = 0; const dstOffset = 20; const radixOffset = 1; - const numLimbs = 10; // only the first 10 bits - const outputBits = 1; // true, output as bits + const numLimbs = new Uint32(10); // only the first 10 bits + const numLimbsOffset = 100; + const outputBits = new Uint1(1); // true, output as bits + const outputBitsOffset = 200; context.machineState.memory.set(srcOffset, arg); context.machineState.memory.set(radixOffset, radix); + context.machineState.memory.set(numLimbsOffset, numLimbs); + context.machineState.memory.set(outputBitsOffset, outputBits); - await new ToRadixBE(indirect, srcOffset, dstOffset, radixOffset, numLimbs, outputBits).execute(context); + await new ToRadixBE(indirect, srcOffset, radixOffset, numLimbsOffset, outputBitsOffset, dstOffset).execute( + context, + ); const resultBuffer: Buffer = Buffer.concat( - context.machineState.memory.getSliceAs(dstOffset, numLimbs).map(byte => byte.toBuffer()), + context.machineState.memory.getSliceAs(dstOffset, numLimbs.toNumber()).map(byte => byte.toBuffer()), ); // The expected result is the first 10 bits of the input // Reverse before slice because still only care about the first `numLimb` bytes. // Then reverse back since we want big endian (as the original string is). - const expectedResults = '1011101010100'.split('').reverse().slice(0, numLimbs).reverse().map(Number); - for (let i = 0; i < numLimbs; i++) { + const expectedResults = '1011101010100'.split('').reverse().slice(0, numLimbs.toNumber()).reverse().map(Number); + for (let i = 0; i < numLimbs.toNumber(); i++) { expect(resultBuffer.readUInt8(i)).toEqual(expectedResults[i]); } }); @@ -91,29 +103,41 @@ describe('Conversion Opcodes', () => { const arg = new Field(Buffer.from('1234567890abcdef', 'hex')); const indirect = new Addressing([ /*srcOffset=*/ AddressingMode.INDIRECT, - /*dstOffset*/ AddressingMode.INDIRECT, /*radixOffset*/ AddressingMode.INDIRECT, + /*numLimbsOffset*/ AddressingMode.INDIRECT, + /*outputBitsOffset*/ AddressingMode.INDIRECT, + /*dstOffset*/ AddressingMode.INDIRECT, ]).toWire(); const srcOffset = 0; - const srcOffsetReal = 10; + const srcOffsetReal = 1000; const dstOffset = 2; - const dstOffsetReal = 30; + const dstOffsetReal = 2000; const radixOffset = 3; const radix = new Uint32(1 << 8); // Byte decomposition - const radixOffsetReal = 50; + const radixOffsetReal = 3000; + const numLimbsOffset = 4; + const numLimbsOffsetReal = 4000; + const numLimbs = new Uint32(32); // 256-bit decomposition + const outputBitsOffset = 5; + const outputBitsOffsetReal = 5000; + const outputBits = new Uint1(0); // false, output as bytes context.machineState.memory.set(srcOffset, new Uint32(srcOffsetReal)); context.machineState.memory.set(dstOffset, new Uint32(dstOffsetReal)); context.machineState.memory.set(radixOffset, new Uint32(radixOffsetReal)); + context.machineState.memory.set(numLimbsOffset, new Uint32(numLimbsOffsetReal)); + context.machineState.memory.set(outputBitsOffset, new Uint32(outputBitsOffsetReal)); context.machineState.memory.set(srcOffsetReal, arg); context.machineState.memory.set(radixOffsetReal, radix); + context.machineState.memory.set(numLimbsOffsetReal, numLimbs); + context.machineState.memory.set(outputBitsOffsetReal, outputBits); - const numLimbs = 32; // 256-bit decomposition - const outputBits = 0; // false, output as bytes - await new ToRadixBE(indirect, srcOffset, dstOffset, radixOffset, numLimbs, outputBits).execute(context); + await new ToRadixBE(indirect, srcOffset, radixOffset, numLimbsOffset, outputBitsOffset, dstOffset).execute( + context, + ); const resultBuffer: Buffer = Buffer.concat( - context.machineState.memory.getSliceAs(dstOffsetReal, numLimbs).map(byte => byte.toBuffer()), + context.machineState.memory.getSliceAs(dstOffsetReal, numLimbs.toNumber()).map(byte => byte.toBuffer()), ); // The expected result is the input (padded to 256 bits) const expectedResults = '1234567890abcdef' @@ -121,7 +145,7 @@ describe('Conversion Opcodes', () => { .split('') .map(a => parseInt(a, 16)); // Checking the value in each byte of the buffer is correct - for (let i = 0; i < numLimbs; i++) { + for (let i = 0; i < numLimbs.toNumber(); i++) { // Compute the expected byte's numerical value from its two hex digits expect(resultBuffer.readUInt8(i)).toEqual(expectedResults[2 * i] * 16 + expectedResults[2 * i + 1]); } diff --git a/yarn-project/simulator/src/avm/opcodes/conversion.ts b/yarn-project/simulator/src/avm/opcodes/conversion.ts index f7a954d5e6c..3699c6f75b1 100644 --- a/yarn-project/simulator/src/avm/opcodes/conversion.ts +++ b/yarn-project/simulator/src/avm/opcodes/conversion.ts @@ -12,57 +12,62 @@ export class ToRadixBE extends Instruction { // Informs (de)serialization. See Instruction.deserialize. static readonly wireFormat: OperandType[] = [ OperandType.UINT8, // Opcode - OperandType.UINT8, // Indirect + OperandType.UINT16, // Indirect OperandType.UINT16, // src memory address - OperandType.UINT16, // dst memory address OperandType.UINT16, // radix memory address - OperandType.UINT16, // number of limbs (Immediate) - OperandType.UINT8, // output is in "bits" mode (Immediate - Uint1 still takes up a whole byte) + OperandType.UINT16, // number of limbs address + OperandType.UINT16, // output is in "bits" mode memory address (boolean/Uint1 is stored) + OperandType.UINT16, // dst memory address ]; constructor( private indirect: number, private srcOffset: number, - private dstOffset: number, private radixOffset: number, - private numLimbs: number, - private outputBits: number, // effectively a bool + private numLimbsOffset: number, + private outputBitsOffset: number, + private dstOffset: number, ) { super(); } public async execute(context: AvmContext): Promise { const memory = context.machineState.memory.track(this.type); - const operands = [this.srcOffset, this.dstOffset, this.radixOffset]; + const operands = [this.srcOffset, this.radixOffset, this.numLimbsOffset, this.outputBitsOffset, this.dstOffset]; const addressing = Addressing.fromWire(this.indirect, operands.length); - const [srcOffset, dstOffset, radixOffset] = addressing.resolve(operands, memory); - context.machineState.consumeGas(this.gasCost(this.numLimbs)); + const [srcOffset, radixOffset, numLimbsOffset, outputBitsOffset, dstOffset] = addressing.resolve(operands, memory); // The radix gadget only takes in a Field memory.checkTag(TypeTag.FIELD, srcOffset); memory.checkTag(TypeTag.UINT32, radixOffset); + memory.checkTag(TypeTag.UINT32, numLimbsOffset); + memory.checkTag(TypeTag.UINT1, outputBitsOffset); + + const numLimbs = memory.get(numLimbsOffset).toNumber(); + context.machineState.consumeGas(this.gasCost(numLimbs)); + const outputBits = memory.get(outputBitsOffset).toNumber(); let value: bigint = memory.get(srcOffset).toBigInt(); const radix: bigint = memory.get(radixOffset).toBigInt(); - if (this.numLimbs < 1) { - throw new InstructionExecutionError(`ToRadixBE instruction's numLimbs should be > 0 (was ${this.numLimbs})`); + if (numLimbs < 1) { + throw new InstructionExecutionError(`ToRadixBE instruction's numLimbs should be > 0 (was ${numLimbs})`); } if (radix > 256) { throw new InstructionExecutionError(`ToRadixBE instruction's radix should be <= 256 (was ${radix})`); } const radixBN: bigint = BigInt(radix); - const limbArray = new Array(this.numLimbs); + const limbArray = new Array(numLimbs); - for (let i = this.numLimbs - 1; i >= 0; i--) { + for (let i = numLimbs - 1; i >= 0; i--) { const limb = value % radixBN; limbArray[i] = limb; value /= radixBN; } - const outputType = this.outputBits != 0 ? Uint1 : Uint8; + const outputType = outputBits != 0 ? Uint1 : Uint8; const res = limbArray.map(byte => new outputType(byte)); memory.setSlice(dstOffset, res); - memory.assert({ reads: 2, writes: this.numLimbs, addressing }); + memory.assert({ reads: 4, writes: numLimbs, addressing }); } } From 962a7a25d71d208992b16fcfd21e86874db5ec05 Mon Sep 17 00:00:00 2001 From: just-mitch <68168980+just-mitch@users.noreply.github.com> Date: Tue, 17 Dec 2024 16:58:31 -0500 Subject: [PATCH 05/34] chore: average alerts across namespace for 1 hour (#10827) We now require the *average* of the increase in proven chain across a namespace to be 0 for an *hour* to trigger a slack alert. --- spartan/metrics/terraform/grafana.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spartan/metrics/terraform/grafana.tf b/spartan/metrics/terraform/grafana.tf index 5279eea54da..13a8bcf0698 100644 --- a/spartan/metrics/terraform/grafana.tf +++ b/spartan/metrics/terraform/grafana.tf @@ -59,11 +59,11 @@ resource "grafana_mute_timing" "mute_timing_always" { } } -resource "grafana_rule_group" "rule_group_minutely" { +resource "grafana_rule_group" "rule_group_hourly" { org_id = 1 - name = "minutely-evaluation-group" + name = "hourly-evaluation-group" folder_uid = grafana_folder.rule_folder.uid - interval_seconds = 60 + interval_seconds = 3600 rule { name = "Proven Chain is Live" @@ -81,7 +81,7 @@ resource "grafana_rule_group" "rule_group_minutely" { model = jsonencode({ disableTextWrap = false, editorMode = "code", - expr = "increase(aztec_archiver_block_height{aztec_status=\"proven\"}[30m])", + expr = "avg by(k8s_namespace_name) (increase(aztec_archiver_block_height{aztec_status=\"proven\"}[60m]))", fullMetaSearch = false, includeNullMetadata = true, instant = true, @@ -118,7 +118,7 @@ resource "grafana_rule_group" "rule_group_minutely" { expression = "A", intervalMs = 1000, maxDataPoints = 43200, - refId = "C", + refId = "B", type = "threshold" } ) @@ -126,7 +126,7 @@ resource "grafana_rule_group" "rule_group_minutely" { no_data_state = "NoData" exec_err_state = "Error" - for = "1m" + for = "1h" annotations = {} labels = {} is_paused = false From b8bdb529719c1f72244e904ea667462458a43317 Mon Sep 17 00:00:00 2001 From: David Banks <47112877+dbanks12@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:14:42 -0500 Subject: [PATCH 06/34] fix: AVM witgen track gas for nested calls and external halts (#10731) Resolves https://github.com/AztecProtocol/aztec-packages/issues/10033 Resolves https://github.com/AztecProtocol/aztec-packages/issues/10374 This PR does the following: - Witgen handles out-of-gas errors for all opcodes - all halts (return/revert/exceptional) work as follows: - charge gas for the problematic instruction as always, adding a row to the gas trace - pop the parent/caller's latest gas from the stack - call a helper function on the gas trace to mutate that most recent gas row, returning to the parent's latest gas minus any consumed gas (all gas consumed on exceptional halt) - `GasTraceEntry` includes a field `is_halt_or_first_row_in_nested_call` which lets us break gas rules on a halt or when starting a nested call because in both cases gas will jump. - `constrain_gas` returns a bool `out_of_gas` so that opcode implementations can handle out of gas - `write_to_memory` now has an option to skip the "jump back to correct pc" which was problematic when halting because the `jump` wouldn't result in a next row with the right pc Explanation on how gas works for calls: - Parent snapshots its gas right before a nested call in `ctx.*_gas_left` - Nested call is given a `ctx.start_*_gas_left` and the gas trace is forced to that same value - throughout the nested call, the gas trace operates normally, charging per instruction - when any halt is encountered, the instruction that halted must have its gas charged normally, but then we call a helper function on the gas trace to mutate the most recent row, flagging it to eventually become a sort of "fake" row that skips some constraints - the mutation of the halting row resets the gas to the parents last gas before the call (minus however much gas was consumed by the nested call... if exceptional halt, that is _all_ allocated gas) Follow-up work - properly constrain gas for nested calls, returns, reverts and exceptional halts - if `jump` exceptionally halts (i.e. out of gas), it should be okay that the next row doesn't have the target pc - Handle the edge case when an error is encountered on return/revert/call, but after the stack has already been modified --- barretenberg/cpp/pil/avm/gas.pil | 8 +- .../vm/avm/generated/relations/gas.hpp | 50 +- .../vm/avm/tests/arithmetic.test.cpp | 6 +- .../barretenberg/vm/avm/tests/cast.test.cpp | 12 +- .../barretenberg/vm/avm/tests/slice.test.cpp | 6 +- .../src/barretenberg/vm/avm/trace/errors.hpp | 1 + .../barretenberg/vm/avm/trace/execution.cpp | 97 ++-- .../barretenberg/vm/avm/trace/gas_trace.cpp | 187 +++++-- .../barretenberg/vm/avm/trace/gas_trace.hpp | 11 +- .../src/barretenberg/vm/avm/trace/helper.cpp | 2 + .../src/barretenberg/vm/avm/trace/trace.cpp | 502 ++++++++++++++---- .../src/barretenberg/vm/avm/trace/trace.hpp | 10 +- .../contracts/avm_test_contract/src/main.nr | 26 +- .../bb-prover/src/avm_proving.test.ts | 25 + .../simulator/src/avm/avm_simulator.test.ts | 20 +- .../simulator/src/avm/avm_simulator.ts | 6 +- 16 files changed, 738 insertions(+), 231 deletions(-) diff --git a/barretenberg/cpp/pil/avm/gas.pil b/barretenberg/cpp/pil/avm/gas.pil index 32b1a858c86..5e7c809b942 100644 --- a/barretenberg/cpp/pil/avm/gas.pil +++ b/barretenberg/cpp/pil/avm/gas.pil @@ -64,10 +64,10 @@ namespace main(256); is_fake_row * (1 - is_fake_row) = 0; // Temporary //TODO(8945): clean up fake row related code - #[L2_GAS_NO_DECREMENT_FAKE_ROW] - is_fake_row * (l2_gas_remaining - l2_gas_remaining') = 0; - #[DA_GAS_NO_DECREMENT_FAKE_ROW] - is_fake_row * (da_gas_remaining - da_gas_remaining') = 0; + //#[L2_GAS_NO_DECREMENT_FAKE_ROW] + //is_fake_row * (l2_gas_remaining - l2_gas_remaining') = 0; + //#[DA_GAS_NO_DECREMENT_FAKE_ROW] + //is_fake_row * (da_gas_remaining - da_gas_remaining') = 0; // Constrain that the gas decrements correctly per instruction #[L2_GAS_REMAINING_DECREMENT_NOT_CALL] diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/gas.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/gas.hpp index f8e68f6b0b2..5ac772aa28a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/gas.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/gas.hpp @@ -10,7 +10,7 @@ template class gasImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 3, 3, 5, 5, 4, 4, 2, 2 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 3, 3, 5, 5, 4, 4, 2, 2 }; template void static accumulate(ContainerOverSubrelations& evals, @@ -46,67 +46,53 @@ template class gasImpl { } { using Accumulator = typename std::tuple_element_t<4, ContainerOverSubrelations>; - auto tmp = - (new_term.main_is_fake_row * (new_term.main_l2_gas_remaining - new_term.main_l2_gas_remaining_shift)); - tmp *= scaling_factor; - std::get<4>(evals) += typename Accumulator::View(tmp); - } - { - using Accumulator = typename std::tuple_element_t<5, ContainerOverSubrelations>; - auto tmp = - (new_term.main_is_fake_row * (new_term.main_da_gas_remaining - new_term.main_da_gas_remaining_shift)); - tmp *= scaling_factor; - std::get<5>(evals) += typename Accumulator::View(tmp); - } - { - using Accumulator = typename std::tuple_element_t<6, ContainerOverSubrelations>; auto tmp = ((new_term.main_is_gas_accounted * ((FF(1) - new_term.main_sel_op_external_call) - new_term.main_sel_op_static_call)) * (((new_term.main_l2_gas_remaining_shift - new_term.main_l2_gas_remaining) + new_term.main_base_l2_gas_op_cost) + (new_term.main_dyn_l2_gas_op_cost * new_term.main_dyn_gas_multiplier))); tmp *= scaling_factor; - std::get<6>(evals) += typename Accumulator::View(tmp); + std::get<4>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<7, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<5, ContainerOverSubrelations>; auto tmp = ((new_term.main_is_gas_accounted * ((FF(1) - new_term.main_sel_op_external_call) - new_term.main_sel_op_static_call)) * (((new_term.main_da_gas_remaining_shift - new_term.main_da_gas_remaining) + new_term.main_base_da_gas_op_cost) + (new_term.main_dyn_da_gas_op_cost * new_term.main_dyn_gas_multiplier))); tmp *= scaling_factor; - std::get<7>(evals) += typename Accumulator::View(tmp); + std::get<5>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<8, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<6, ContainerOverSubrelations>; auto tmp = (new_term.main_is_gas_accounted * (((FF(1) - (FF(2) * new_term.main_l2_out_of_gas)) * new_term.main_l2_gas_remaining_shift) - new_term.main_abs_l2_rem_gas)); tmp *= scaling_factor; - std::get<8>(evals) += typename Accumulator::View(tmp); + std::get<6>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<9, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<7, ContainerOverSubrelations>; auto tmp = (new_term.main_is_gas_accounted * (((FF(1) - (FF(2) * new_term.main_da_out_of_gas)) * new_term.main_da_gas_remaining_shift) - new_term.main_abs_da_rem_gas)); tmp *= scaling_factor; - std::get<9>(evals) += typename Accumulator::View(tmp); + std::get<7>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<10, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<8, ContainerOverSubrelations>; auto tmp = (new_term.main_abs_l2_rem_gas - (new_term.main_l2_gas_u16_r0 + (new_term.main_l2_gas_u16_r1 * FF(65536)))); tmp *= scaling_factor; - std::get<10>(evals) += typename Accumulator::View(tmp); + std::get<8>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<11, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<9, ContainerOverSubrelations>; auto tmp = (new_term.main_abs_da_rem_gas - (new_term.main_da_gas_u16_r0 + (new_term.main_da_gas_u16_r1 * FF(65536)))); tmp *= scaling_factor; - std::get<11>(evals) += typename Accumulator::View(tmp); + std::get<9>(evals) += typename Accumulator::View(tmp); } } }; @@ -121,12 +107,8 @@ template class gas : public Relation> { case 0: return "IS_GAS_ACCOUNTED"; case 4: - return "L2_GAS_NO_DECREMENT_FAKE_ROW"; - case 5: - return "DA_GAS_NO_DECREMENT_FAKE_ROW"; - case 6: return "L2_GAS_REMAINING_DECREMENT_NOT_CALL"; - case 7: + case 5: return "DA_GAS_REMAINING_DECREMENT_NOT_CALL"; } return std::to_string(index); @@ -134,10 +116,8 @@ template class gas : public Relation> { // Subrelation indices constants, to be used in tests. static constexpr size_t SR_IS_GAS_ACCOUNTED = 0; - static constexpr size_t SR_L2_GAS_NO_DECREMENT_FAKE_ROW = 4; - static constexpr size_t SR_DA_GAS_NO_DECREMENT_FAKE_ROW = 5; - static constexpr size_t SR_L2_GAS_REMAINING_DECREMENT_NOT_CALL = 6; - static constexpr size_t SR_DA_GAS_REMAINING_DECREMENT_NOT_CALL = 7; + static constexpr size_t SR_L2_GAS_REMAINING_DECREMENT_NOT_CALL = 4; + static constexpr size_t SR_DA_GAS_REMAINING_DECREMENT_NOT_CALL = 5; }; } // namespace bb::avm \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/arithmetic.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/arithmetic.test.cpp index 26de359d82f..8c69de39672 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/arithmetic.test.cpp @@ -227,8 +227,10 @@ class AvmArithmeticTests : public ::testing::Test { .nested_returndata = {}, .last_pc = 0, .success_offset = 0, - .l2_gas = 0, - .da_gas = 0, + .start_l2_gas_left = 0, + .start_da_gas_left = 0, + .l2_gas_left = 0, + .da_gas_left = 0, .internal_return_ptr_stack = {} }); trace_builder.current_ext_call_ctx = ext_call_ctx; } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/cast.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/cast.test.cpp index 726a17af205..8086db12147 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/cast.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/cast.test.cpp @@ -193,8 +193,10 @@ TEST_F(AvmCastTests, truncationFFToU16ModMinus1) .nested_returndata = {}, .last_pc = 0, .success_offset = 0, - .l2_gas = 0, - .da_gas = 0, + .start_l2_gas_left = 0, + .start_da_gas_left = 0, + .l2_gas_left = 0, + .da_gas_left = 0, .internal_return_ptr_stack = {} }); trace_builder.current_ext_call_ctx = ext_call_ctx; trace_builder.op_set(0, 0, 0, AvmMemoryTag::U32); @@ -222,8 +224,10 @@ TEST_F(AvmCastTests, truncationFFToU16ModMinus2) .nested_returndata = {}, .last_pc = 0, .success_offset = 0, - .l2_gas = 0, - .da_gas = 0, + .start_l2_gas_left = 0, + .start_da_gas_left = 0, + .l2_gas_left = 0, + .da_gas_left = 0, .internal_return_ptr_stack = {} }); trace_builder.current_ext_call_ctx = ext_call_ctx; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/slice.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/slice.test.cpp index 5e2b759bba7..ea8830a353c 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/slice.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/slice.test.cpp @@ -37,8 +37,10 @@ class AvmSliceTests : public ::testing::Test { .nested_returndata = {}, .last_pc = 0, .success_offset = 0, - .l2_gas = 0, - .da_gas = 0, + .start_l2_gas_left = 0, + .start_da_gas_left = 0, + .l2_gas_left = 0, + .da_gas_left = 0, .internal_return_ptr_stack = {} }); trace_builder.current_ext_call_ctx = ext_call_ctx; this->calldata = calldata; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/errors.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/errors.hpp index ca121ebefa2..d1d4550edfa 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/errors.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/errors.hpp @@ -20,6 +20,7 @@ enum class AvmError : uint32_t { RADIX_OUT_OF_BOUNDS, DUPLICATE_NULLIFIER, SIDE_EFFECT_LIMIT_REACHED, + OUT_OF_GAS, }; } // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp index ba9b71cef20..a2478a292ef 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp @@ -428,6 +428,8 @@ AvmError Execution::execute_enqueued_call(AvmTraceBuilder& trace_builder, // These hints help us to set up first call ctx uint32_t clk = trace_builder.get_clk(); auto context_id = static_cast(clk); + uint32_t l2_gas_allocated_to_enqueued_call = trace_builder.get_l2_gas_left(); + uint32_t da_gas_allocated_to_enqueued_call = trace_builder.get_da_gas_left(); trace_builder.current_ext_call_ctx = AvmTraceBuilder::ExtCallCtx{ .context_id = context_id, .parent_id = 0, @@ -436,10 +438,13 @@ AvmError Execution::execute_enqueued_call(AvmTraceBuilder& trace_builder, .nested_returndata = {}, .last_pc = 0, .success_offset = 0, - .l2_gas = 0, - .da_gas = 0, + .start_l2_gas_left = l2_gas_allocated_to_enqueued_call, + .start_da_gas_left = da_gas_allocated_to_enqueued_call, + .l2_gas_left = l2_gas_allocated_to_enqueued_call, + .da_gas_left = da_gas_allocated_to_enqueued_call, .internal_return_ptr_stack = {}, }; + trace_builder.allocate_gas_for_call(l2_gas_allocated_to_enqueued_call, da_gas_allocated_to_enqueued_call); // Find the bytecode based on contract address of the public call request std::vector bytecode = trace_builder.get_bytecode(trace_builder.current_ext_call_ctx.contract_address, check_bytecode_membership); @@ -451,11 +456,13 @@ AvmError Execution::execute_enqueued_call(AvmTraceBuilder& trace_builder, std::stack debug_counter_stack; uint32_t counter = 0; trace_builder.set_call_ptr(context_id); - while (is_ok(error) && (pc = trace_builder.get_pc()) < bytecode.size()) { + while ((pc = trace_builder.get_pc()) < bytecode.size()) { auto [inst, parse_error] = Deserialization::parse(bytecode, pc); - error = parse_error; + // FIXME: properly handle case when an instruction fails parsing + // especially first instruction in bytecode if (!is_ok(error)) { + error = parse_error; break; } @@ -848,9 +855,10 @@ AvmError Execution::execute_enqueued_call(AvmTraceBuilder& trace_builder, std::get(inst.operands.at(3)), std::get(inst.operands.at(4)), std::get(inst.operands.at(5))); + // TODO: what if an error is encountered on return or call which have already modified stack? // We hack it in here the logic to change contract address that we are processing bytecode = trace_builder.get_bytecode(trace_builder.current_ext_call_ctx.contract_address, - check_bytecode_membership); + /*check_membership=*/false); debug_counter_stack.push(counter); counter = 0; break; @@ -864,7 +872,7 @@ AvmError Execution::execute_enqueued_call(AvmTraceBuilder& trace_builder, std::get(inst.operands.at(5))); // We hack it in here the logic to change contract address that we are processing bytecode = trace_builder.get_bytecode(trace_builder.current_ext_call_ctx.contract_address, - check_bytecode_membership); + /*check_membership=*/false); debug_counter_stack.push(counter); counter = 0; break; @@ -873,17 +881,18 @@ AvmError Execution::execute_enqueued_call(AvmTraceBuilder& trace_builder, auto ret = trace_builder.op_return(std::get(inst.operands.at(0)), std::get(inst.operands.at(1)), std::get(inst.operands.at(2))); - // We hack it in here the logic to change contract address that we are processing + // did the return opcode hit an exceptional halt? + error = ret.error; if (ret.is_top_level) { - error = ret.error; returndata.insert(returndata.end(), ret.return_data.begin(), ret.return_data.end()); - - } else { + } else if (is_ok(error)) { + // switch back to caller's bytecode bytecode = trace_builder.get_bytecode(trace_builder.current_ext_call_ctx.contract_address, - check_bytecode_membership); + /*check_membership=*/false); counter = debug_counter_stack.top(); debug_counter_stack.pop(); } + // on error/exceptional-halt, jumping back to parent code is handled at bottom of execution loop break; } case OpCode::REVERT_8: { @@ -891,17 +900,19 @@ AvmError Execution::execute_enqueued_call(AvmTraceBuilder& trace_builder, auto ret = trace_builder.op_revert(std::get(inst.operands.at(0)), std::get(inst.operands.at(1)), std::get(inst.operands.at(2))); + // error is only set here if the revert opcode hit an exceptional halt + // revert itself does not trigger "error" + error = ret.error; if (ret.is_top_level) { - error = ret.error; returndata.insert(returndata.end(), ret.return_data.begin(), ret.return_data.end()); - } else { - // change to the current ext call ctx + } else if (is_ok(error)) { + // switch back to caller's bytecode bytecode = trace_builder.get_bytecode(trace_builder.current_ext_call_ctx.contract_address, - check_bytecode_membership); + /*check_membership=*/false); counter = debug_counter_stack.top(); debug_counter_stack.pop(); } - + // on error/exceptional-halt, jumping back to parent code is handled at bottom of execution loop break; } case OpCode::REVERT_16: { @@ -909,17 +920,19 @@ AvmError Execution::execute_enqueued_call(AvmTraceBuilder& trace_builder, auto ret = trace_builder.op_revert(std::get(inst.operands.at(0)), std::get(inst.operands.at(1)), std::get(inst.operands.at(2))); + // error is only set here if the revert opcode hit an exceptional halt + // revert itself does not trigger "error" + error = ret.error; if (ret.is_top_level) { - error = ret.error; returndata.insert(returndata.end(), ret.return_data.begin(), ret.return_data.end()); - } else { - // change to the current ext call ctx + } else if (is_ok(error)) { + // switch back to caller's bytecode bytecode = trace_builder.get_bytecode(trace_builder.current_ext_call_ctx.contract_address, - check_bytecode_membership); + /*check_membership=*/false); counter = debug_counter_stack.top(); debug_counter_stack.pop(); } - + // on error/exceptional-halt, jumping back to parent code is handled at bottom of execution loop break; } @@ -987,18 +1000,36 @@ AvmError Execution::execute_enqueued_call(AvmTraceBuilder& trace_builder, "."); break; } - } - if (!is_ok(error)) { - auto const error_ic = counter - 1; // Need adjustement as counter increment occurs in loop body - std::string reason_prefix = exceptionally_halted(error) ? "exceptional halt" : "REVERT opcode"; - info("AVM enqueued call halted due to ", - reason_prefix, - ". Error: ", - to_name(error), - " at PC: ", - pc, - " IC: ", - error_ic); + + if (!is_ok(error)) { + const bool is_top_level = trace_builder.current_ext_call_ctx.context_id == 0; + + auto const error_ic = counter - 1; // Need adjustement as counter increment occurs in loop body + std::string call_type = is_top_level ? "enqueued" : "nested"; + info("AVM ", + call_type, + " call exceptionally halted. Error: ", + to_name(error), + " at PC: ", + pc, + " IC: ", + error_ic); + + trace_builder.handle_exceptional_halt(); + + if (is_top_level) { + break; + } + // otherwise, handle exceptional halt and proceed with execution in caller/parent + // We hack it in here the logic to change contract address that we are processing + bytecode = trace_builder.get_bytecode(trace_builder.current_ext_call_ctx.contract_address, + /*check_membership=*/false); + counter = debug_counter_stack.top(); + debug_counter_stack.pop(); + + // reset error as we've now returned to caller + error = AvmError::NO_ERROR; + } } return error; } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.cpp index fc52f9f00bd..3bc5b3a6754 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.cpp @@ -24,6 +24,15 @@ void AvmGasTraceBuilder::set_initial_gas(uint32_t l2_gas, uint32_t da_gas) remaining_da_gas = da_gas; } +void AvmGasTraceBuilder::allocate_gas_for_call(uint32_t l2_gas, uint32_t da_gas) +{ + // Remaining gas will be mutated on each opcode + remaining_l2_gas = l2_gas; + remaining_da_gas = da_gas; + // set flag so that the next row will be properly tagged as the first in a nested call + next_row_is_first_in_nested_call = true; +} + uint32_t AvmGasTraceBuilder::get_l2_gas_left() const { if (gas_trace.empty()) { @@ -54,7 +63,7 @@ std::tuple AvmGasTraceBuilder::unconstrained_compute_gas(OpC base_da_gas_cost + dyn_gas_multiplier * dyn_da_gas_cost }; } -void AvmGasTraceBuilder::constrain_gas( +bool AvmGasTraceBuilder::constrain_gas( uint32_t clk, OpCode opcode, uint32_t dyn_gas_multiplier, uint32_t nested_l2_gas_cost, uint32_t nested_da_gas_cost) { uint32_t effective_nested_l2_gas_cost = 0; @@ -65,8 +74,6 @@ void AvmGasTraceBuilder::constrain_gas( effective_nested_da_gas_cost = nested_da_gas_cost; } - gas_opcode_lookup_counter[opcode]++; - // Get the gas prices for this opcode const auto& GAS_COST_TABLE = FixedGasTable::get(); const auto& gas_info = GAS_COST_TABLE.at(opcode); @@ -76,8 +83,17 @@ void AvmGasTraceBuilder::constrain_gas( auto dyn_da_gas_cost = static_cast(gas_info.dyn_da_gas_fixed_table); // Decrease the gas left - remaining_l2_gas -= (base_l2_gas_cost + dyn_gas_multiplier * dyn_l2_gas_cost) + effective_nested_l2_gas_cost; - remaining_da_gas -= (base_da_gas_cost + dyn_gas_multiplier * dyn_da_gas_cost) + effective_nested_da_gas_cost; + bool out_of_gas = false; + const auto l2_cost = (base_l2_gas_cost + dyn_gas_multiplier * dyn_l2_gas_cost) + effective_nested_l2_gas_cost; + const auto da_cost = (base_da_gas_cost + dyn_gas_multiplier * dyn_da_gas_cost) + effective_nested_da_gas_cost; + if (l2_cost > remaining_l2_gas) { + remaining_l2_gas = 0; + remaining_da_gas = 0; + out_of_gas = true; + } else { + remaining_l2_gas -= l2_cost; + remaining_da_gas -= da_cost; + } // Create a gas trace entry gas_trace.push_back({ @@ -90,7 +106,72 @@ void AvmGasTraceBuilder::constrain_gas( .dyn_gas_multiplier = dyn_gas_multiplier, .remaining_l2_gas = remaining_l2_gas, .remaining_da_gas = remaining_da_gas, + .is_halt_or_first_row_in_nested_call = next_row_is_first_in_nested_call, }); + + if (next_row_is_first_in_nested_call) { + next_row_is_first_in_nested_call = false; + } else { + gas_opcode_lookup_counter[opcode]++; + } + + return out_of_gas; +} + +void AvmGasTraceBuilder::constrain_gas_for_halt(bool exceptional_halt, + uint32_t parent_l2_gas_left, + uint32_t parent_da_gas_left, + uint32_t l2_gas_allocated_to_nested_call, + uint32_t da_gas_allocated_to_nested_call) +{ + debug("Resetting to parent's L2 gas left (", parent_l2_gas_left, ") before consuming gas allocated to nested call"); + debug("Resetting to parent's DA gas left (", parent_da_gas_left, ") before consuming gas allocated to nested call"); + // how much gas did the nested call consume + auto l2_gas_consumed = l2_gas_allocated_to_nested_call - remaining_l2_gas; + auto da_gas_consumed = da_gas_allocated_to_nested_call - remaining_da_gas; + if (exceptional_halt) { + // on error (exceptional halt), consume all gas allocated to nested call + l2_gas_consumed = l2_gas_allocated_to_nested_call; + da_gas_consumed = da_gas_allocated_to_nested_call; + debug("Consuming L2 gas used by nested call: ", l2_gas_consumed); + debug("Consuming DA gas used by nested call: ", da_gas_consumed); + } else { + debug("Consuming all L2 gas allocated to nested call: ", l2_gas_allocated_to_nested_call); + debug("Consuming all DA gas allocated to nested call: ", da_gas_allocated_to_nested_call); + } + + // We reload to the parent's l2 gas left minus however much gas consumed by the nested call + remaining_l2_gas = parent_l2_gas_left - l2_gas_consumed; + remaining_da_gas = parent_da_gas_left - da_gas_consumed; + debug("L2 gas remaining after nested call: ", remaining_l2_gas); + debug("DA gas remaining after nested call: ", remaining_da_gas); + + // modify the last row of the gas trace to return to the parent's latest gas + // with the nested call's gas consumption applied + auto& halting_entry = gas_trace.back(); + halting_entry.remaining_l2_gas = remaining_l2_gas; + halting_entry.remaining_da_gas = remaining_da_gas; + halting_entry.is_halt_or_first_row_in_nested_call = true; + + gas_opcode_lookup_counter[halting_entry.opcode]--; +} + +void AvmGasTraceBuilder::constrain_gas_for_top_level_exceptional_halt(uint32_t l2_gas_allocated, + uint32_t da_gas_allocated) +{ + debug("Consuming all L2 gas allocated to top-level call: ", l2_gas_allocated); + debug("Consuming all DA gas allocated to top-level call: ", da_gas_allocated); + + remaining_l2_gas = 0; + remaining_da_gas = 0; + + // modify the last row of the gas trace to consume all remaining gas + auto& halting_entry = gas_trace.back(); + halting_entry.remaining_l2_gas = remaining_l2_gas; + halting_entry.remaining_da_gas = remaining_da_gas; + halting_entry.is_halt_or_first_row_in_nested_call = true; + + gas_opcode_lookup_counter[halting_entry.opcode]--; } void AvmGasTraceBuilder::finalize(std::vector>& main_trace) @@ -131,52 +212,64 @@ void AvmGasTraceBuilder::finalize(std::vector>& main_trace) main_trace.at(current_clk).main_da_gas_remaining = current_da_gas_remaining; main_trace.at(current_clk - 1).main_is_fake_row = 1; } else { - const auto& gas_entry = *gas_it; auto& dest = main_trace.at(gas_entry.clk - 1); auto& next = main_trace.at(gas_entry.clk); - // Temporary. Will be removed once "fake" rows are purged. - dest.main_is_gas_accounted = 1; - - // Write each of the relevant gas accounting values - dest.main_opcode_val = static_cast(gas_entry.opcode); - dest.main_base_l2_gas_op_cost = gas_entry.base_l2_gas_cost; - dest.main_base_da_gas_op_cost = gas_entry.base_da_gas_cost; - dest.main_dyn_l2_gas_op_cost = gas_entry.dyn_l2_gas_cost; - dest.main_dyn_da_gas_op_cost = gas_entry.dyn_da_gas_cost; - dest.main_dyn_gas_multiplier = gas_entry.dyn_gas_multiplier; - - // If gas remaining is increasing, it means we underflowed in uint32_t - bool l2_out_of_gas = current_l2_gas_remaining < gas_entry.remaining_l2_gas; - bool da_out_of_gas = current_da_gas_remaining < gas_entry.remaining_da_gas; - - uint32_t abs_l2_gas_remaining = l2_out_of_gas ? -gas_entry.remaining_l2_gas : gas_entry.remaining_l2_gas; - uint32_t abs_da_gas_remaining = da_out_of_gas ? -gas_entry.remaining_da_gas : gas_entry.remaining_da_gas; - - dest.main_abs_l2_rem_gas = abs_l2_gas_remaining; - dest.main_l2_gas_u16_r0 = static_cast(abs_l2_gas_remaining); - rem_gas_rng_check_counts.at(0)[static_cast(abs_l2_gas_remaining)]++; - - dest.main_l2_gas_u16_r1 = static_cast(abs_l2_gas_remaining >> 16); - rem_gas_rng_check_counts.at(1)[static_cast(abs_l2_gas_remaining >> 16)]++; - - dest.main_abs_da_rem_gas = abs_da_gas_remaining; - dest.main_da_gas_u16_r0 = static_cast(abs_da_gas_remaining); - rem_gas_rng_check_counts.at(2)[static_cast(abs_da_gas_remaining)]++; - dest.main_da_gas_u16_r1 = static_cast(abs_da_gas_remaining >> 16); - rem_gas_rng_check_counts.at(3)[static_cast(abs_da_gas_remaining >> 16)]++; - - dest.main_l2_out_of_gas = static_cast(l2_out_of_gas); - dest.main_da_out_of_gas = static_cast(da_out_of_gas); - - current_l2_gas_remaining = gas_entry.remaining_l2_gas; - current_da_gas_remaining = gas_entry.remaining_da_gas; - next.main_l2_gas_remaining = - l2_out_of_gas ? FF::modulus - uint256_t(abs_l2_gas_remaining) : current_l2_gas_remaining; - next.main_da_gas_remaining = - da_out_of_gas ? FF::modulus - uint256_t(abs_da_gas_remaining) : current_da_gas_remaining; - + if (gas_entry.is_halt_or_first_row_in_nested_call) { + dest.main_is_fake_row = 1; + next.main_l2_gas_remaining = gas_entry.remaining_l2_gas; + next.main_da_gas_remaining = gas_entry.remaining_da_gas; + current_l2_gas_remaining = gas_entry.remaining_l2_gas; + current_da_gas_remaining = gas_entry.remaining_da_gas; + dest.main_opcode_val = static_cast(gas_entry.opcode); + dest.main_base_l2_gas_op_cost = gas_entry.base_l2_gas_cost; + dest.main_base_da_gas_op_cost = gas_entry.base_da_gas_cost; + dest.main_dyn_l2_gas_op_cost = gas_entry.dyn_l2_gas_cost; + dest.main_dyn_da_gas_op_cost = gas_entry.dyn_da_gas_cost; + } else { + dest.main_is_gas_accounted = 1; + + // Write each of the relevant gas accounting values + dest.main_opcode_val = static_cast(gas_entry.opcode); + dest.main_base_l2_gas_op_cost = gas_entry.base_l2_gas_cost; + dest.main_base_da_gas_op_cost = gas_entry.base_da_gas_cost; + dest.main_dyn_l2_gas_op_cost = gas_entry.dyn_l2_gas_cost; + dest.main_dyn_da_gas_op_cost = gas_entry.dyn_da_gas_cost; + dest.main_dyn_gas_multiplier = gas_entry.dyn_gas_multiplier; + + // If gas remaining is increasing, it means we underflowed in uint32_t + bool l2_out_of_gas = current_l2_gas_remaining < gas_entry.remaining_l2_gas; + bool da_out_of_gas = current_da_gas_remaining < gas_entry.remaining_da_gas; + + uint32_t abs_l2_gas_remaining = + l2_out_of_gas ? -gas_entry.remaining_l2_gas : gas_entry.remaining_l2_gas; + uint32_t abs_da_gas_remaining = + da_out_of_gas ? -gas_entry.remaining_da_gas : gas_entry.remaining_da_gas; + + dest.main_abs_l2_rem_gas = abs_l2_gas_remaining; + dest.main_l2_gas_u16_r0 = static_cast(abs_l2_gas_remaining); + rem_gas_rng_check_counts.at(0)[static_cast(abs_l2_gas_remaining)]++; + + dest.main_l2_gas_u16_r1 = static_cast(abs_l2_gas_remaining >> 16); + rem_gas_rng_check_counts.at(1)[static_cast(abs_l2_gas_remaining >> 16)]++; + + dest.main_abs_da_rem_gas = abs_da_gas_remaining; + dest.main_da_gas_u16_r0 = static_cast(abs_da_gas_remaining); + rem_gas_rng_check_counts.at(2)[static_cast(abs_da_gas_remaining)]++; + dest.main_da_gas_u16_r1 = static_cast(abs_da_gas_remaining >> 16); + rem_gas_rng_check_counts.at(3)[static_cast(abs_da_gas_remaining >> 16)]++; + + dest.main_l2_out_of_gas = static_cast(l2_out_of_gas); + dest.main_da_out_of_gas = static_cast(da_out_of_gas); + + current_l2_gas_remaining = gas_entry.remaining_l2_gas; + current_da_gas_remaining = gas_entry.remaining_da_gas; + next.main_l2_gas_remaining = + l2_out_of_gas ? FF::modulus - uint256_t(abs_l2_gas_remaining) : current_l2_gas_remaining; + next.main_da_gas_remaining = + da_out_of_gas ? FF::modulus - uint256_t(abs_da_gas_remaining) : current_da_gas_remaining; + } gas_it++; } } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.hpp index abf3ee586a6..6fdc47d4e7c 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gas_trace.hpp @@ -21,6 +21,7 @@ class AvmGasTraceBuilder { uint32_t dyn_gas_multiplier = 0; uint32_t remaining_l2_gas = 0; uint32_t remaining_da_gas = 0; + bool is_halt_or_first_row_in_nested_call = false; }; AvmGasTraceBuilder() = default; @@ -33,12 +34,19 @@ class AvmGasTraceBuilder { void finalize_lookups(std::vector>& trace); static std::tuple unconstrained_compute_gas(OpCode opcode, uint32_t dyn_gas_multiplier); - void constrain_gas(uint32_t clk, + bool constrain_gas(uint32_t clk, OpCode opcode, uint32_t dyn_gas_multiplier = 0, uint32_t nested_l2_gas_cost = 0, uint32_t nested_da_gas_cost = 0); + void constrain_gas_for_halt(bool exceptional_halt, + uint32_t parent_l2_gas_left, + uint32_t parent_da_gas_left, + uint32_t l2_gas_allocated_to_nested_call, + uint32_t da_gas_allocated_to_nested_call); + void constrain_gas_for_top_level_exceptional_halt(uint32_t l2_gas_allocated, uint32_t da_gas_allocated); void set_initial_gas(uint32_t l2_gas, uint32_t da_gas); + void allocate_gas_for_call(uint32_t l2_gas, uint32_t da_gas); uint32_t get_l2_gas_left() const; uint32_t get_da_gas_left() const; @@ -55,6 +63,7 @@ class AvmGasTraceBuilder { uint32_t initial_da_gas = 0; uint32_t remaining_l2_gas = 0; uint32_t remaining_da_gas = 0; + bool next_row_is_first_in_nested_call = false; }; } // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp index 28a540f69aa..1028bad79fc 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp @@ -133,6 +133,8 @@ std::string to_name(AvmError error) return "DUPLICATE NULLIFIER"; case AvmError::SIDE_EFFECT_LIMIT_REACHED: return "SIDE EFFECT LIMIT REACHED"; + case AvmError::OUT_OF_GAS: + return "OUT OF GAS"; default: throw std::runtime_error("Invalid error type"); break; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp index 8aadc08d280..95a26c9cd0f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp @@ -132,7 +132,7 @@ bool check_tag_integral(AvmMemoryTag tag) } } -bool isCanonical(FF contract_address) +bool is_canonical(FF contract_address) { // TODO: constrain this! return contract_address == CANONICAL_AUTH_REGISTRY_ADDRESS || contract_address == DEPLOYER_CONTRACT_ADDRESS || @@ -166,7 +166,7 @@ std::vector AvmTraceBuilder::get_bytecode(const FF contract_address, bo }); bool exists = true; - if (check_membership && !isCanonical(contract_address)) { + if (check_membership && !is_canonical(contract_address)) { if (bytecode_membership_cache.find(contract_address) != bytecode_membership_cache.end()) { // If we have already seen the contract address, we can skip the membership check and used the cached // membership proof @@ -329,6 +329,55 @@ void AvmTraceBuilder::pad_trees() merkle_tree_trace_builder.set_nullifier_tree_size(padded_nullifier_size); } +void AvmTraceBuilder::allocate_gas_for_call(uint32_t l2_gas, uint32_t da_gas) +{ + gas_trace_builder.allocate_gas_for_call(l2_gas, da_gas); +} + +void AvmTraceBuilder::handle_exceptional_halt() +{ + const bool is_top_level = current_ext_call_ctx.context_id == 0; + if (is_top_level) { + vinfo("Handling exceptional halt in top-level call. Consuming all allocated gas:"); + // Consume all remaining gas. + gas_trace_builder.constrain_gas_for_top_level_exceptional_halt(current_ext_call_ctx.start_l2_gas_left, + current_ext_call_ctx.start_da_gas_left); + + // max out the pc to signify "done" + pc = UINT32_MAX; + } else { + vinfo("Handling exceptional halt in nested call"); + // before the nested call was made, how much gas does the parent have? + const auto l2_gas_allocated_to_nested_call = current_ext_call_ctx.start_l2_gas_left; + const auto da_gas_allocated_to_nested_call = current_ext_call_ctx.start_da_gas_left; + + // Pop the caller/parent's context from the stack to proceed with execution there + current_ext_call_ctx = external_call_ctx_stack.top(); + external_call_ctx_stack.pop(); + + // Grab the saved-off gas remaining in the parent from before the nested call + // now that we have popped its context from the stack. + auto parent_l2_gas_left = current_ext_call_ctx.l2_gas_left; + auto parent_da_gas_left = current_ext_call_ctx.da_gas_left; + + // now modify the last row of the gas trace to return to the parent's latest gas + // with the nested call's entire allocation consumed + gas_trace_builder.constrain_gas_for_halt(/*exceptional_halt=*/true, + parent_l2_gas_left, + parent_da_gas_left, + l2_gas_allocated_to_nested_call, + da_gas_allocated_to_nested_call); + + // Update the call_ptr before we write the success flag + set_call_ptr(static_cast(current_ext_call_ctx.context_id)); + write_to_memory( + current_ext_call_ctx.success_offset, /*success=*/FF::zero(), AvmMemoryTag::U1, /*fix_pc=*/false); + + // Jump back to the parent's last pc + pc = current_ext_call_ctx.last_pc; + } +} + /** * @brief Loads a value from memory into a given intermediate register at a specified clock cycle. * Handles both direct and indirect memory access. @@ -444,13 +493,15 @@ FF AvmTraceBuilder::unconstrained_read_from_memory(AddressWithMode addr) return mem_trace_builder.unconstrained_read(call_ptr, offset); } -void AvmTraceBuilder::write_to_memory(AddressWithMode addr, FF val, AvmMemoryTag w_tag) +void AvmTraceBuilder::write_to_memory(AddressWithMode addr, FF val, AvmMemoryTag w_tag, bool fix_pc) { // op_set increments the pc, so we need to store the current pc and then jump back to it // to legally reset the pc. auto current_pc = pc; op_set(static_cast(addr.mode), val, addr.offset, w_tag, OpCode::SET_FF, true); - op_jump(current_pc, true); + if (fix_pc) { + op_jump(current_pc, true); + } } template @@ -568,7 +619,10 @@ AvmError AvmTraceBuilder::op_add( auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::ADD_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::ADD_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -651,7 +705,10 @@ AvmError AvmTraceBuilder::op_sub( auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::SUB_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::SUB_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -732,7 +789,10 @@ AvmError AvmTraceBuilder::op_mul( auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::MUL_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::MUL_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -827,7 +887,10 @@ AvmError AvmTraceBuilder::op_div( auto write_dst = constrained_write_to_memory(call_ptr, clk, resolved_dst, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::DIV_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::DIV_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -919,7 +982,10 @@ AvmError AvmTraceBuilder::op_fdiv( call_ptr, clk, resolved_c, c, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::FDIV_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::FDIV_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -1004,7 +1070,10 @@ AvmError AvmTraceBuilder::op_eq( constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, AvmMemoryTag::U1, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::EQ_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::EQ_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -1072,7 +1141,10 @@ AvmError AvmTraceBuilder::op_lt( constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, AvmMemoryTag::U1, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::LT_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::LT_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -1141,7 +1213,10 @@ AvmError AvmTraceBuilder::op_lte( constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, AvmMemoryTag::U1, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::LTE_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::LTE_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -1214,7 +1289,10 @@ AvmError AvmTraceBuilder::op_and( auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::AND_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::AND_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -1284,7 +1362,10 @@ AvmError AvmTraceBuilder::op_or( auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::OR_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::OR_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -1354,7 +1435,10 @@ AvmError AvmTraceBuilder::op_xor( auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::XOR_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::XOR_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -1431,7 +1515,10 @@ AvmError AvmTraceBuilder::op_not(uint8_t indirect, uint32_t a_offset, uint32_t d auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::NOT_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::NOT_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -1494,7 +1581,10 @@ AvmError AvmTraceBuilder::op_shl( // Write into memory value c from intermediate register ic. auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::SHL_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::SHL_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -1561,7 +1651,10 @@ AvmError AvmTraceBuilder::op_shr( // Write into memory value c from intermediate register ic. auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::SHR_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::SHR_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -1616,6 +1709,8 @@ AvmError AvmTraceBuilder::op_shr( AvmError AvmTraceBuilder::op_cast( uint8_t indirect, uint32_t a_offset, uint32_t dst_offset, AvmMemoryTag dst_tag, OpCode op_code) { + // We keep the first encountered error + AvmError error = AvmError::NO_ERROR; auto const clk = static_cast(main_trace.size()) + 1; auto [resolved_addrs, res_error] = @@ -1635,7 +1730,10 @@ AvmError AvmTraceBuilder::op_cast( mem_trace_builder.write_into_memory(call_ptr, clk, IntermRegister::IC, resolved_c, c, memEntry.tag, dst_tag); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::CAST_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::CAST_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -1726,8 +1824,6 @@ AvmError AvmTraceBuilder::op_get_env_var(uint8_t indirect, uint32_t dst_offset, .main_sel_op_address = FF(1), // TODO(9407): what selector should this be? }; - // Constrain gas cost - gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); main_trace.push_back(row); return AvmError::ENV_VAR_UNKNOWN; } else { @@ -1789,7 +1885,10 @@ AvmError AvmTraceBuilder::op_address(uint8_t indirect, uint32_t dst_offset) row.main_sel_op_address = FF(1); // Constrain gas cost - gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + bool out_of_gas = gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); return error; @@ -1802,7 +1901,10 @@ AvmError AvmTraceBuilder::op_sender(uint8_t indirect, uint32_t dst_offset) row.main_sel_op_sender = FF(1); // Constrain gas cost - gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + bool out_of_gas = gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); return error; @@ -1815,7 +1917,10 @@ AvmError AvmTraceBuilder::op_transaction_fee(uint8_t indirect, uint32_t dst_offs row.main_sel_op_transaction_fee = FF(1); // Constrain gas cost - gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + bool out_of_gas = gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); return error; @@ -1828,7 +1933,10 @@ AvmError AvmTraceBuilder::op_is_static_call(uint8_t indirect, uint32_t dst_offse row.main_sel_op_is_static_call = FF(1); // Constrain gas cost - gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + bool out_of_gas = gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); return error; @@ -1845,7 +1953,10 @@ AvmError AvmTraceBuilder::op_chain_id(uint8_t indirect, uint32_t dst_offset) row.main_sel_op_chain_id = FF(1); // Constrain gas cost - gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + bool out_of_gas = gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); return error; @@ -1858,7 +1969,10 @@ AvmError AvmTraceBuilder::op_version(uint8_t indirect, uint32_t dst_offset) row.main_sel_op_version = FF(1); // Constrain gas cost - gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + bool out_of_gas = gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); return error; @@ -1871,7 +1985,10 @@ AvmError AvmTraceBuilder::op_block_number(uint8_t indirect, uint32_t dst_offset) row.main_sel_op_block_number = FF(1); // Constrain gas cost - gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + bool out_of_gas = gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); return error; @@ -1884,7 +2001,10 @@ AvmError AvmTraceBuilder::op_timestamp(uint8_t indirect, uint32_t dst_offset) row.main_sel_op_timestamp = FF(1); // Constrain gas cost - gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + bool out_of_gas = gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); return error; @@ -1897,7 +2017,10 @@ AvmError AvmTraceBuilder::op_fee_per_l2_gas(uint8_t indirect, uint32_t dst_offse row.main_sel_op_fee_per_l2_gas = FF(1); // Constrain gas cost - gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + bool out_of_gas = gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); return error; @@ -1910,7 +2033,10 @@ AvmError AvmTraceBuilder::op_fee_per_da_gas(uint8_t indirect, uint32_t dst_offse row.main_sel_op_fee_per_da_gas = FF(1); // Constrain gas cost - gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + bool out_of_gas = gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); return error; @@ -1980,7 +2106,10 @@ AvmError AvmTraceBuilder::op_calldata_copy(uint8_t indirect, } // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::CALLDATACOPY, copy_size); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::CALLDATACOPY, copy_size); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -2024,7 +2153,10 @@ AvmError AvmTraceBuilder::op_returndata_size(uint8_t indirect, uint32_t dst_offs write_to_memory(resolved_dst_offset, returndata_size, AvmMemoryTag::U32); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::RETURNDATASIZE); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::RETURNDATASIZE); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -2067,9 +2199,12 @@ AvmError AvmTraceBuilder::op_returndata_copy(uint8_t indirect, const uint32_t rd_offset = static_cast(unconstrained_read_from_memory(rd_offset_resolved)); const uint32_t copy_size = static_cast(unconstrained_read_from_memory(copy_size_offset_resolved)); - gas_trace_builder.constrain_gas(clk, - OpCode::RETURNDATACOPY, - /*dyn_gas_multiplier=*/copy_size); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, + OpCode::RETURNDATACOPY, + /*dyn_gas_multiplier=*/copy_size); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -2102,6 +2237,8 @@ AvmError AvmTraceBuilder::op_returndata_copy(uint8_t indirect, // Helper for "gas left" related opcodes AvmError AvmTraceBuilder::execute_gasleft(EnvironmentVariable var, uint8_t indirect, uint32_t dst_offset) { + // We keep the first encountered error + AvmError error = AvmError::NO_ERROR; ASSERT(var == EnvironmentVariable::L2GASLEFT || var == EnvironmentVariable::DAGASLEFT); auto clk = static_cast(main_trace.size()) + 1; @@ -2111,7 +2248,10 @@ AvmError AvmTraceBuilder::execute_gasleft(EnvironmentVariable var, uint8_t indir auto [resolved_dst] = resolved_addrs; // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::GETENVVAR_16); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::GETENVVAR_16); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } uint32_t gas_remaining = 0; @@ -2171,11 +2311,16 @@ AvmError AvmTraceBuilder::op_dagasleft(uint8_t indirect, uint32_t dst_offset) */ AvmError AvmTraceBuilder::op_jump(uint32_t jmp_dest, bool skip_gas) { + // We keep the first encountered error + AvmError error = AvmError::NO_ERROR; auto clk = static_cast(main_trace.size()) + 1; // Constrain gas cost if (!skip_gas) { - gas_trace_builder.constrain_gas(clk, OpCode::JUMP_32); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::JUMP_32); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } } main_trace.push_back(Row{ @@ -2183,13 +2328,14 @@ AvmError AvmTraceBuilder::op_jump(uint32_t jmp_dest, bool skip_gas) .main_call_ptr = call_ptr, .main_ia = FF(jmp_dest), .main_internal_return_ptr = FF(internal_return_ptr), + .main_op_err = static_cast(!is_ok(error)), .main_pc = FF(pc), .main_sel_op_jump = FF(1), }); // Adjust parameters for the next row pc = jmp_dest; - return AvmError::NO_ERROR; + return error; } /** @@ -2228,7 +2374,10 @@ AvmError AvmTraceBuilder::op_jumpi(uint8_t indirect, uint32_t cond_offset, uint3 uint32_t next_pc = !id_zero ? jmp_dest : pc + Deserialization::get_pc_increment(OpCode::JUMPI_32); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::JUMPI_32); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::JUMPI_32); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -2265,6 +2414,8 @@ AvmError AvmTraceBuilder::op_jumpi(uint8_t indirect, uint32_t cond_offset, uint3 */ AvmError AvmTraceBuilder::op_internal_call(uint32_t jmp_dest) { + // We keep the first encountered error + AvmError error = AvmError::NO_ERROR; auto clk = static_cast(main_trace.size()) + 1; const auto next_pc = pc + Deserialization::get_pc_increment(OpCode::INTERNALCALL); // We store the next instruction as the return location @@ -2272,7 +2423,10 @@ AvmError AvmTraceBuilder::op_internal_call(uint32_t jmp_dest) // We push the next pc onto the internal return stack of the current context current_ext_call_ctx.internal_return_ptr_stack.emplace(next_pc); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::INTERNALCALL); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::INTERNALCALL); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -2280,13 +2434,14 @@ AvmError AvmTraceBuilder::op_internal_call(uint32_t jmp_dest) .main_ia = FF(jmp_dest), .main_ib = FF(next_pc), .main_internal_return_ptr = FF(internal_return_ptr), + .main_op_err = static_cast(!is_ok(error)), .main_pc = FF(pc), .main_sel_op_internal_call = FF(1), }); // Adjust parameters for the next row pc = jmp_dest; - return AvmError::NO_ERROR; + return error; } /** @@ -2301,6 +2456,8 @@ AvmError AvmTraceBuilder::op_internal_call(uint32_t jmp_dest) */ AvmError AvmTraceBuilder::op_internal_return() { + // We keep the first encountered error + AvmError error = AvmError::NO_ERROR; auto clk = static_cast(main_trace.size()) + 1; // We pop the return location from the internal return stack of the current context @@ -2308,19 +2465,23 @@ AvmError AvmTraceBuilder::op_internal_return() current_ext_call_ctx.internal_return_ptr_stack.pop(); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::INTERNALRETURN); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::INTERNALRETURN); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, .main_call_ptr = call_ptr, .main_ia = next_pc, .main_internal_return_ptr = FF(internal_return_ptr), + .main_op_err = static_cast(!is_ok(error)), .main_pc = pc, .main_sel_op_internal_return = FF(1), }); pc = next_pc; - return AvmError::NO_ERROR; + return error; } /************************************************************************************************** @@ -2362,7 +2523,10 @@ AvmError AvmTraceBuilder::op_set( // Constrain gas cost // FIXME: not great that we are having to choose one specific opcode here! if (!skip_gas) { - gas_trace_builder.constrain_gas(clk, OpCode::SET_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::SET_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } } main_trace.push_back(Row{ @@ -2423,7 +2587,10 @@ AvmError AvmTraceBuilder::op_mov(uint8_t indirect, uint32_t src_offset, uint32_t // Constrain gas cost // FIXME: not great that we are having to choose one specific opcode here! - gas_trace_builder.constrain_gas(clk, OpCode::MOV_8); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::MOV_8); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -2565,10 +2732,10 @@ RowWithError AvmTraceBuilder::create_kernel_output_opcode_with_metadata(uint8_t AvmError AvmTraceBuilder::op_sload(uint8_t indirect, uint32_t slot_offset, uint32_t dest_offset) { - auto clk = static_cast(main_trace.size()) + 1; - // We keep the first encountered error AvmError error = AvmError::NO_ERROR; + auto clk = static_cast(main_trace.size()) + 1; + 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; @@ -2626,7 +2793,10 @@ AvmError AvmTraceBuilder::op_sload(uint8_t indirect, uint32_t slot_offset, uint3 // Constrain gas cost // TODO: when/if we move this to its own gadget, and we have 1 row only, we should pass the size as // n_multiplier here. - gas_trace_builder.constrain_gas(clk, OpCode::SLOAD); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::SLOAD); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); @@ -2656,7 +2826,6 @@ AvmError AvmTraceBuilder::op_sstore(uint8_t indirect, uint32_t src_offset, uint3 .main_pc = pc, .main_sel_op_sstore = FF(1), }; - gas_trace_builder.constrain_gas(clk, OpCode::SSTORE); main_trace.push_back(row); pc += Deserialization::get_pc_increment(OpCode::SSTORE); return error; @@ -2714,7 +2883,10 @@ AvmError AvmTraceBuilder::op_sstore(uint8_t indirect, uint32_t src_offset, uint3 row.main_sel_op_sstore = FF(1); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::SSTORE); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::SSTORE); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); @@ -2809,7 +2981,10 @@ AvmError AvmTraceBuilder::op_note_hash_exists(uint8_t indirect, } // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::NOTEHASHEXISTS); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::NOTEHASHEXISTS); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); @@ -2831,7 +3006,6 @@ AvmError AvmTraceBuilder::op_emit_note_hash(uint8_t indirect, uint32_t note_hash .main_pc = pc, .main_sel_op_emit_note_hash = FF(1), }; - gas_trace_builder.constrain_gas(clk, OpCode::EMITNOTEHASH); main_trace.push_back(row); pc += Deserialization::get_pc_increment(OpCode::EMITNOTEHASH); return error; @@ -2858,7 +3032,10 @@ AvmError AvmTraceBuilder::op_emit_note_hash(uint8_t indirect, uint32_t note_hash merkle_tree_trace_builder.perform_note_hash_append(clk, unique_note_hash, note_hash_write_hint.sibling_path); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::EMITNOTEHASH); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::EMITNOTEHASH); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); @@ -2956,7 +3133,10 @@ AvmError AvmTraceBuilder::op_nullifier_exists(uint8_t indirect, } // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::NULLIFIEREXISTS); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::NULLIFIEREXISTS); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); @@ -2982,7 +3162,6 @@ AvmError AvmTraceBuilder::op_emit_nullifier(uint8_t indirect, uint32_t nullifier .main_pc = pc, .main_sel_op_emit_nullifier = FF(1), }; - gas_trace_builder.constrain_gas(clk, OpCode::EMITNULLIFIER); main_trace.push_back(row); pc += Deserialization::get_pc_increment(OpCode::EMITNULLIFIER); return error; @@ -3031,7 +3210,10 @@ AvmError AvmTraceBuilder::op_emit_nullifier(uint8_t indirect, uint32_t nullifier row.main_op_err = FF(static_cast(!is_ok(error))); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::EMITNULLIFIER); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::EMITNULLIFIER); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); @@ -3126,7 +3308,10 @@ AvmError AvmTraceBuilder::op_l1_to_l2_msg_exists(uint8_t indirect, } // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::L1TOL2MSGEXISTS); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::L1TOL2MSGEXISTS); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); @@ -3143,7 +3328,10 @@ AvmError AvmTraceBuilder::op_get_contract_instance( AvmError error = AvmError::NO_ERROR; auto clk = static_cast(main_trace.size()) + 1; // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::GETCONTRACTINSTANCE); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::GETCONTRACTINSTANCE); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } if (member_enum >= static_cast(ContractInstanceMember::MAX_MEMBER)) { // Error, bad enum operand @@ -3185,7 +3373,7 @@ AvmError AvmTraceBuilder::op_get_contract_instance( // Read the contract instance hint ContractInstanceHint instance = execution_hints.contract_instance_hints.at(contract_address); - if (isCanonical(contract_address)) { + if (is_canonical(contract_address)) { // skip membership check for canonical contracts exists = true; } else { @@ -3354,8 +3542,6 @@ AvmError AvmTraceBuilder::op_emit_unencrypted_log(uint8_t indirect, uint32_t log .main_pc = pc, .main_sel_op_emit_unencrypted_log = FF(1), }; - // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::EMITUNENCRYPTEDLOG, static_cast(log_size)); main_trace.push_back(row); pc += Deserialization::get_pc_increment(OpCode::EMITUNENCRYPTEDLOG); return error; @@ -3404,7 +3590,10 @@ AvmError AvmTraceBuilder::op_emit_unencrypted_log(uint8_t indirect, uint32_t log } // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::EMITUNENCRYPTEDLOG, static_cast(log_size)); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::EMITUNENCRYPTEDLOG, static_cast(log_size)); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); @@ -3429,7 +3618,6 @@ AvmError AvmTraceBuilder::op_emit_l2_to_l1_msg(uint8_t indirect, uint32_t recipi .main_pc = pc, .main_sel_op_emit_l2_to_l1_msg = FF(1), }; - gas_trace_builder.constrain_gas(clk, OpCode::SENDL2TOL1MSG); main_trace.push_back(row); pc += Deserialization::get_pc_increment(OpCode::SENDL2TOL1MSG); return error; @@ -3450,7 +3638,10 @@ AvmError AvmTraceBuilder::op_emit_l2_to_l1_msg(uint8_t indirect, uint32_t recipi row.main_op_err = FF(static_cast(!is_ok(error))); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::SENDL2TOL1MSG); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::SENDL2TOL1MSG); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(row); @@ -3509,9 +3700,13 @@ AvmError AvmTraceBuilder::constrain_external_call(OpCode opcode, is_ok(error) ? static_cast(unconstrained_read_from_memory(resolved_args_size_offset)) : 0; // We need to consume the the gas cost of call, and then handle the amount allocated to the call - gas_trace_builder.constrain_gas(clk, - opcode, - /*dyn_gas_multiplier=*/args_size); + // TODO: is cast okay? Should gas be read from memory as u32? + bool out_of_gas = gas_trace_builder.constrain_gas(clk, opcode, /*dyn_gas_multiplier=*/args_size); + // NOTE: we don't run out of gas if the gas specified by user code is > gas left. + // In that case we just cap the gas allocation by gas left. + if (is_ok(error) && out_of_gas) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -3544,6 +3739,11 @@ AvmError AvmTraceBuilder::constrain_external_call(OpCode opcode, pc += Deserialization::get_pc_increment(opcode); + // Save the current gas left in the context before pushing it to stack + // It will be used on RETURN/REVERT/halt to remember how much gas the caller had left. + current_ext_call_ctx.l2_gas_left = gas_trace_builder.get_l2_gas_left(); + current_ext_call_ctx.da_gas_left = gas_trace_builder.get_da_gas_left(); + // We push the current ext call ctx onto the stack and initialize a new one current_ext_call_ctx.last_pc = pc; current_ext_call_ctx.success_offset = resolved_success_offset, @@ -3555,6 +3755,11 @@ AvmError AvmTraceBuilder::constrain_external_call(OpCode opcode, set_call_ptr(static_cast(clk)); + // Don't try allocating more than the gas that is actually left + const auto l2_gas_allocated_to_nested_call = + std::min(static_cast(read_gas_l2.val), gas_trace_builder.get_l2_gas_left()); + const auto da_gas_allocated_to_nested_call = + std::min(static_cast(read_gas_da.val), gas_trace_builder.get_da_gas_left()); current_ext_call_ctx = ExtCallCtx{ .context_id = static_cast(clk), .parent_id = current_ext_call_ctx.context_id, @@ -3563,10 +3768,14 @@ AvmError AvmTraceBuilder::constrain_external_call(OpCode opcode, .nested_returndata = {}, .last_pc = 0, .success_offset = 0, - .l2_gas = static_cast(read_gas_l2.val), - .da_gas = static_cast(read_gas_da.val), + .start_l2_gas_left = l2_gas_allocated_to_nested_call, + .start_da_gas_left = da_gas_allocated_to_nested_call, + .l2_gas_left = l2_gas_allocated_to_nested_call, + .da_gas_left = da_gas_allocated_to_nested_call, .internal_return_ptr_stack = {}, }; + + allocate_gas_for_call(l2_gas_allocated_to_nested_call, da_gas_allocated_to_nested_call); set_pc(0); return error; @@ -3657,7 +3866,34 @@ ReturnDataError AvmTraceBuilder::op_return(uint8_t indirect, uint32_t ret_offset const auto ret_size = static_cast(unconstrained_read_from_memory(resolved_ret_size_offset)); - bool is_top_level = current_ext_call_ctx.context_id == 0; + const bool is_top_level = current_ext_call_ctx.context_id == 0; + + const auto [l2_gas_cost, da_gas_cost] = gas_trace_builder.unconstrained_compute_gas(OpCode::RETURN, ret_size); + bool out_of_gas = + l2_gas_cost > gas_trace_builder.get_l2_gas_left() || da_gas_cost > gas_trace_builder.get_da_gas_left(); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } + if (!is_ok(error)) { + main_trace.push_back(Row{ + .main_clk = clk, + .main_call_ptr = call_ptr, + .main_ib = ret_size, + .main_internal_return_ptr = FF(internal_return_ptr), + .main_op_err = static_cast(!is_ok(error)), + .main_pc = pc, + .main_sel_op_external_return = 1, + }); + return ReturnDataError{ + .return_data = {}, + .error = error, + .is_top_level = is_top_level, + }; + } + + // Charge gas normally. The gas row will be modified later to go back to parent's gas + // minus gas consumed by nested call. + gas_trace_builder.constrain_gas(clk, OpCode::RETURN, ret_size); if (tag_match) { if (is_top_level) { @@ -3667,23 +3903,38 @@ ReturnDataError AvmTraceBuilder::op_return(uint8_t indirect, uint32_t ret_offset returndata = mem_trace_builder.read_return_opcode(clk, call_ptr, resolved_ret_offset, ret_size); slice_trace_builder.create_return_slice(returndata, clk, call_ptr, resolved_ret_offset, ret_size); all_returndata.insert(all_returndata.end(), returndata.begin(), returndata.end()); - } else { + // before the nested call was made, how much gas does the parent have? + const auto l2_gas_allocated_to_nested_call = current_ext_call_ctx.start_l2_gas_left; + const auto da_gas_allocated_to_nested_call = current_ext_call_ctx.start_da_gas_left; // We are returning from a nested call std::vector returndata{}; read_slice_from_memory(resolved_ret_offset, ret_size, returndata); - // Pop the stack + // Pop the caller/parent's context from the stack to proceed with execution there current_ext_call_ctx = external_call_ctx_stack.top(); external_call_ctx_stack.pop(); current_ext_call_ctx.nested_returndata = returndata; + + // Grab the saved-off gas remaining in the parent from before the nested call + // now that we have popped its context from the stack. + auto parent_l2_gas_left = current_ext_call_ctx.l2_gas_left; + auto parent_da_gas_left = current_ext_call_ctx.da_gas_left; + + // modify this instruction's gas row (from constrain_gas) to go back to + // parent's gas minus gas consumed by nested call. + gas_trace_builder.constrain_gas_for_halt(/*exceptional_halt=*/false, + parent_l2_gas_left, + parent_da_gas_left, + l2_gas_allocated_to_nested_call, + da_gas_allocated_to_nested_call); + // Update the call_ptr before we write the success flag set_call_ptr(static_cast(current_ext_call_ctx.context_id)); - write_to_memory(current_ext_call_ctx.success_offset, FF::one(), AvmMemoryTag::U1); + write_to_memory( + current_ext_call_ctx.success_offset, /*success=*/FF::one(), AvmMemoryTag::U1, /*fix_pc=*/false); } } - gas_trace_builder.constrain_gas(clk, OpCode::RETURN, ret_size); - if (ret_size == 0) { main_trace.push_back(Row{ .main_clk = clk, @@ -3754,7 +4005,35 @@ ReturnDataError AvmTraceBuilder::op_revert(uint8_t indirect, uint32_t ret_offset const auto ret_size = is_ok(error) ? static_cast(unconstrained_read_from_memory(resolved_ret_size_offset)) : 0; - bool is_top_level = current_ext_call_ctx.context_id == 0; + const bool is_top_level = current_ext_call_ctx.context_id == 0; + + const auto [l2_gas_cost, da_gas_cost] = gas_trace_builder.unconstrained_compute_gas(OpCode::REVERT_8, ret_size); + bool out_of_gas = + l2_gas_cost > gas_trace_builder.get_l2_gas_left() || da_gas_cost > gas_trace_builder.get_da_gas_left(); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } + if (!is_ok(error)) { + // TODO: fix and set sel_op_revert + main_trace.push_back(Row{ + .main_call_ptr = call_ptr, + .main_ib = ret_size, + .main_internal_return_ptr = FF(internal_return_ptr), + .main_op_err = static_cast(!is_ok(error)), + .main_pc = pc, + .main_sel_op_external_return = 1, + }); + return ReturnDataError{ + .return_data = {}, + .error = error, + .is_top_level = is_top_level, + }; + } + + // Charge gas normally. The gas row will be modified later to go back to parent's gas + // minus gas consumed by nested call. + gas_trace_builder.constrain_gas(clk, OpCode::REVERT_8, ret_size); + if (tag_match) { if (is_top_level) { // The only memory operation performed from the main trace is a possible indirect load for resolving the @@ -3764,21 +4043,37 @@ ReturnDataError AvmTraceBuilder::op_revert(uint8_t indirect, uint32_t ret_offset slice_trace_builder.create_return_slice(returndata, clk, call_ptr, resolved_ret_offset, ret_size); all_returndata.insert(all_returndata.end(), returndata.begin(), returndata.end()); } else { + // before the nested call was made, how much gas does the parent have? + const auto l2_gas_allocated_to_nested_call = current_ext_call_ctx.start_l2_gas_left; + const auto da_gas_allocated_to_nested_call = current_ext_call_ctx.start_da_gas_left; // We are returning from a nested call std::vector returndata{}; read_slice_from_memory(resolved_ret_offset, ret_size, returndata); - // Pop the stack + // Pop the caller/parent's context from the stack to proceed with execution there current_ext_call_ctx = external_call_ctx_stack.top(); external_call_ctx_stack.pop(); current_ext_call_ctx.nested_returndata = returndata; + + // Grab the saved-off gas remaining in the parent from before the nested call + // now that we have popped its context from the stack. + auto parent_l2_gas_left = current_ext_call_ctx.l2_gas_left; + auto parent_da_gas_left = current_ext_call_ctx.da_gas_left; + + // modify this instruction's gas row (from constrain_gas) to go back to + // parent's gas minus gas consumed by nested call. + gas_trace_builder.constrain_gas_for_halt(/*exceptional_halt=*/false, + parent_l2_gas_left, + parent_da_gas_left, + l2_gas_allocated_to_nested_call, + da_gas_allocated_to_nested_call); + // Update the call_ptr before we write the success flag set_call_ptr(static_cast(current_ext_call_ctx.context_id)); - write_to_memory(current_ext_call_ctx.success_offset, FF::one(), AvmMemoryTag::U1); + write_to_memory( + current_ext_call_ctx.success_offset, /*success=*/FF::one(), AvmMemoryTag::U1, /*fix_pc=*/false); } } - gas_trace_builder.constrain_gas(clk, OpCode::REVERT_8, ret_size); - // TODO: fix and set sel_op_revert if (ret_size == 0) { main_trace.push_back(Row{ @@ -3819,10 +4114,6 @@ ReturnDataError AvmTraceBuilder::op_revert(uint8_t indirect, uint32_t ret_offset pc = is_top_level ? UINT32_MAX : current_ext_call_ctx.last_pc; auto return_data = is_top_level ? returndata : current_ext_call_ctx.nested_returndata; - if (is_ok(error)) { - error = AvmError::REVERT_OPCODE; - } - // op_valid == true otherwise, ret_size == 0 and we would have returned above. return ReturnDataError{ .return_data = return_data, @@ -3859,7 +4150,10 @@ AvmError AvmTraceBuilder::op_debug_log(uint8_t indirect, is_ok(error) ? static_cast(unconstrained_read_from_memory(resolved_fields_size_offset)) : 0; // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::DEBUGLOG, message_size + fields_size); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::DEBUGLOG, message_size + fields_size); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } if (is_ok(error) && !(check_tag_range(AvmMemoryTag::U8, resolved_message_offset, message_size) && check_tag_range(AvmMemoryTag::FF, resolved_fields_offset, fields_size))) { @@ -3909,7 +4203,10 @@ AvmError AvmTraceBuilder::op_poseidon2_permutation(uint8_t indirect, uint32_t in // Resolve indirects in the main trace. Do not resolve the value stored in direct addresses. // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::POSEIDON2PERM); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::POSEIDON2PERM); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } // These read patterns will be refactored - we perform them here instead of in the poseidon gadget trace // even though they are "performed" by the gadget. @@ -4036,12 +4333,12 @@ AvmError AvmTraceBuilder::op_sha256_compression(uint8_t indirect, const uint32_t STATE_SIZE = 8; const uint32_t INPUTS_SIZE = 16; - // The clk plays a crucial role in this function as we attempt to write across multiple lines in the main trace. - auto clk = static_cast(main_trace.size()) + 1; - // We keep the first encountered error AvmError error = AvmError::NO_ERROR; + // The clk plays a crucial role in this function as we attempt to write across multiple lines in the main trace. + auto clk = static_cast(main_trace.size()) + 1; + // Resolve the indirect flags, the results of this function are used to determine the memory offsets // that point to the starting memory addresses for the input and output values. auto [resolved_addrs, res_error] = Addressing<3>::fromWire(indirect, call_ptr) @@ -4061,7 +4358,10 @@ AvmError AvmTraceBuilder::op_sha256_compression(uint8_t indirect, } // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::SHA256COMPRESSION); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::SHA256COMPRESSION); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } // Since the above adds mem_reads in the mem_trace_builder at clk, we need to follow up resolving the reads in // the main trace at the same clk cycle to preserve the cross-table permutation @@ -4160,7 +4460,10 @@ AvmError AvmTraceBuilder::op_keccakf1600(uint8_t indirect, uint32_t output_offse } // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::KECCAKF1600); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::KECCAKF1600); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } main_trace.push_back(Row{ .main_clk = clk, @@ -4244,7 +4547,10 @@ AvmError AvmTraceBuilder::op_ec_add(uint16_t indirect, error = AvmError::CHECK_TAG_ERROR; } - gas_trace_builder.constrain_gas(clk, OpCode::ECADD); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::ECADD); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } if (!is_ok(error)) { main_trace.push_back(Row{ @@ -4342,7 +4648,10 @@ AvmError AvmTraceBuilder::op_variable_msm(uint8_t indirect, // TODO(dbanks12): length needs to fit into u32 here or it will certainly // run out of gas. Casting/truncating here is not secure. - gas_trace_builder.constrain_gas(clk, OpCode::MSM, static_cast(points_length)); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::MSM, static_cast(points_length)); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } if (!is_ok(error)) { main_trace.push_back(Row{ @@ -4465,7 +4774,10 @@ AvmError AvmTraceBuilder::op_to_radix_be(uint16_t indirect, const auto num_limbs = static_cast(unconstrained_read_from_memory(resolved_num_limbs_offset)); // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::TORADIXBE, num_limbs); + bool out_of_gas = gas_trace_builder.constrain_gas(clk, OpCode::TORADIXBE, num_limbs); + if (out_of_gas && is_ok(error)) { + error = AvmError::OUT_OF_GAS; + } const auto output_bits = static_cast(unconstrained_read_from_memory(resolved_output_bits_offset)); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp index 840de69fb1b..3f5c9297acd 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp @@ -239,6 +239,8 @@ class AvmTraceBuilder { const std::vector& siloed_note_hashes); void pay_fee(); void pad_trees(); + void allocate_gas_for_call(uint32_t l2_gas, uint32_t da_gas); + void handle_exceptional_halt(); // These are used for testing only. AvmTraceBuilder& set_range_check_required(bool required) @@ -269,8 +271,10 @@ class AvmTraceBuilder { std::vector nested_returndata; uint32_t last_pc; uint32_t success_offset; - uint32_t l2_gas; - uint32_t da_gas; + uint32_t start_l2_gas_left; + uint32_t start_da_gas_left; + uint32_t l2_gas_left; // as of start of latest nested call + uint32_t da_gas_left; // as of start of latest nested call std::stack internal_return_ptr_stack; }; @@ -371,7 +375,7 @@ class AvmTraceBuilder { bool check_tag_range(AvmMemoryTag tag, AddressWithMode start_offset, uint32_t size); FF unconstrained_read_from_memory(AddressWithMode addr); template void read_slice_from_memory(AddressWithMode addr, size_t slice_len, std::vector& slice); - void write_to_memory(AddressWithMode addr, FF val, AvmMemoryTag w_tag); + void write_to_memory(AddressWithMode addr, FF val, AvmMemoryTag w_tag, bool fix_pc = true); template void write_slice_to_memory(AddressWithMode addr, AvmMemoryTag w_tag, const T& slice); }; diff --git a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr index d2e5ba81c7b..149cfae9aec 100644 --- a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr @@ -30,7 +30,7 @@ contract AvmTest { // Libs use dep::aztec::context::gas::GasOpts; - use dep::aztec::context::public_context::call; + use dep::aztec::context::public_context::{call, gas_for_call, returndata_size}; use dep::aztec::macros::{functions::{private, public}, storage::storage}; use dep::aztec::oracle::get_contract_instance::{ get_contract_instance_class_id_avm, get_contract_instance_deployer_avm, @@ -38,6 +38,7 @@ contract AvmTest { }; use dep::aztec::prelude::Map; use dep::aztec::protocol_types::{ + abis::function_selector::FunctionSelector, address::{AztecAddress, EthAddress}, point::Point, scalar::Scalar, @@ -243,6 +244,29 @@ contract AvmTest { AvmTest::at(context.this_address()).divide_by_zero().call(&mut context); } + #[public] + fn external_call_to_divide_by_zero_recovers() { + // Be sure to allocate ~200k+ gas to this function~ + + // Get the gas remaining and allocate some smaller amount to nested call. + // We don't want to allocate too much to the nested call + // since it will all be consumed on exceptional halt. + let l2_gas_left = context.l2_gas_left(); + let da_gas_left = context.da_gas_left(); + let gas_allocation: [Field; 2] = [l2_gas_left - 200_000, da_gas_left - 200_000]; + let selector = FunctionSelector::from_signature("divide_by_zero()"); + let success = call( + gas_allocation, + context.this_address(), + &[selector.to_field()], + ); + assert(!success, "Nested CALL instruction should return failure on exceptional halt"); + assert( + returndata_size() == 0, + "Returndata should be empty when nested call exceptionally halts", + ); + } + #[public] fn debug_logging() { dep::aztec::oracle::debug_log::debug_log("just text"); diff --git a/yarn-project/bb-prover/src/avm_proving.test.ts b/yarn-project/bb-prover/src/avm_proving.test.ts index 4986339dda7..f0c5582c996 100644 --- a/yarn-project/bb-prover/src/avm_proving.test.ts +++ b/yarn-project/bb-prover/src/avm_proving.test.ts @@ -85,6 +85,31 @@ describe('AVM WitGen, proof generation and verification', () => { }, TIMEOUT, ); + it( + 'Should prove and verify a top-level exceptional halt', + async () => { + await proveAndVerifyAvmTestContract('divide_by_zero', /*calldata=*/ [], /*expectRevert=*/ true); + }, + TIMEOUT, + ); + it( + 'Should prove and verify a nested exceptional halt that propagates to top-level', + async () => { + await proveAndVerifyAvmTestContract('external_call_to_divide_by_zero', /*calldata=*/ [], /*expectRevert=*/ true); + }, + TIMEOUT, + ); + it( + 'Should prove and verify a nested exceptional halt that is recovered from in caller', + async () => { + await proveAndVerifyAvmTestContract( + 'external_call_to_divide_by_zero_recovers', + /*calldata=*/ [], + /*expectRevert=*/ false, + ); + }, + TIMEOUT, + ); }); async function proveAndVerifyAvmTestContract(functionName: string, calldata: Fr[] = [], expectRevert = false) { diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index 8b6f89fcca5..8ce5ae1cffb 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -56,6 +56,7 @@ import { type AvmPersistableStateManager } from './journal/journal.js'; import { Add, CalldataCopy, + Div, EmitNoteHash, EmitNullifier, EmitUnencryptedLog, @@ -127,8 +128,23 @@ describe('AVM simulator: injected bytecode', () => { expect(results.reverted).toBe(true); expect(results.output).toEqual([]); expect(results.revertReason?.message).toEqual('Not enough L2GAS gas left'); - expect(context.machineState.l2GasLeft).toEqual(0); - expect(context.machineState.daGasLeft).toEqual(0); + expect(results.gasLeft.l2Gas).toEqual(0); + expect(results.gasLeft.daGas).toEqual(0); + }); + + it('An exceptional halt should consume all allocated gas', async () => { + const context = initContext(); + + // should halt with tag mismatch + const badBytecode = encodeToBytecode([ + new Div(/*indirect=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 0).as(Opcode.DIV_8, Div.wireFormat8), + ]); + const results = await new AvmSimulator(context).executeBytecode(markBytecodeAsAvm(badBytecode)); + expect(results.reverted).toBe(true); + expect(results.output).toEqual([]); + expect(results.revertReason?.message).toMatch(/Tag mismatch/); + expect(results.gasLeft.l2Gas).toEqual(0); + expect(results.gasLeft.daGas).toEqual(0); }); }); diff --git a/yarn-project/simulator/src/avm/avm_simulator.ts b/yarn-project/simulator/src/avm/avm_simulator.ts index 4e5a963019c..1ff7cf60d61 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.ts @@ -114,7 +114,7 @@ export class AvmSimulator { return new AvmContractCallResult( /*reverted=*/ true, /*output=*/ [], - /*gasLeft=*/ { l2Gas: 0, daGas: 0 }, + /*gasLeft=*/ { l2Gas: 0, daGas: 0 }, // consumes all allocated gas revertReason, ); } @@ -195,8 +195,10 @@ export class AvmSimulator { } const revertReason = await revertReasonFromExceptionalHalt(err, this.context); + // Exceptional halts consume all allocated gas + const noGasLeft = { l2Gas: 0, daGas: 0 }; // Note: "exceptional halts" cannot return data, hence []. - const results = new AvmContractCallResult(/*reverted=*/ true, /*output=*/ [], machineState.gasLeft, revertReason); + const results = new AvmContractCallResult(/*reverted=*/ true, /*output=*/ [], noGasLeft, revertReason); this.log.debug(`Context execution results: ${results.toString()}`); this.tallyPrintFunction(); From ba28788de22b3209ec324633e91875b3b4b86332 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Tue, 17 Dec 2024 19:14:54 -0300 Subject: [PATCH 07/34] fix: Try fix e2e epochs in CI (#10804) Attempts two fixes at e2e epochs test. First, it increases the L1 block time, to account for general CI slowness. Second, it adds more retries to the L1 gas utils getTx, since the e2e epochs test works using the tx delayer, which artificially introduces a delay between a tx being sent and it being available in anvil, so it triggered a timeout in the utils. **Update**: Increasing the retries caused the error to change, we were getting a timeout in teardown. This was caused because the sequencer got stuck in waiting for the tx to be mined for way too long (more than 5 minutes, the afterAll hook timeout), and the `node.stop()` waits for the current loops to end before returning. But what's interesting is _why_ the sequencer got stuck in waiting for its tx to be mined. The tx was being delayed by the tx-delayer, which intercepts txs, manually computes their tx hash to return it to the caller immediately, and holds on the tx to submit it to anvil at a later point in time. What came up is that the tx hash we were manually computing over txs with blobs did not match the tx hash returned by anvil. This has been logged as #10824. However, we can sidestep this issue by just choosing a reasonable value for max attempts so teardown doesn't timeout. --------- Co-authored-by: ludamad --- .../end-to-end/src/e2e_epochs.test.ts | 34 +++++++++++-------- yarn-project/ethereum/src/l1_tx_utils.ts | 17 ++++++++-- yarn-project/ethereum/src/test/tx_delayer.ts | 20 ++++++++--- yarn-project/foundation/src/config/env_var.ts | 1 + 4 files changed, 52 insertions(+), 20 deletions(-) diff --git a/yarn-project/end-to-end/src/e2e_epochs.test.ts b/yarn-project/end-to-end/src/e2e_epochs.test.ts index c64ff2d6eda..9f71bfdac2b 100644 --- a/yarn-project/end-to-end/src/e2e_epochs.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs.test.ts @@ -24,9 +24,9 @@ describe('e2e_epochs', () => { let l1BlockNumber: number; let handle: NodeJS.Timeout; - const EPOCH_DURATION = 4; - const L1_BLOCK_TIME = 5; - const L2_SLOT_DURATION_IN_L1_BLOCKS = 2; + const EPOCH_DURATION_IN_L2_SLOTS = 4; + const L2_SLOT_DURATION_IN_L1_SLOTS = 2; + const L1_BLOCK_TIME_IN_S = 8; beforeAll(async () => { // Set up system without any account nor protocol contracts @@ -35,13 +35,16 @@ describe('e2e_epochs', () => { assumeProvenThrough: undefined, skipProtocolContracts: true, salt: 1, - aztecEpochDuration: EPOCH_DURATION, - aztecSlotDuration: L1_BLOCK_TIME * L2_SLOT_DURATION_IN_L1_BLOCKS, - ethereumSlotDuration: L1_BLOCK_TIME, - aztecEpochProofClaimWindowInL2Slots: EPOCH_DURATION / 2, + aztecEpochDuration: EPOCH_DURATION_IN_L2_SLOTS, + aztecSlotDuration: L1_BLOCK_TIME_IN_S * L2_SLOT_DURATION_IN_L1_SLOTS, + ethereumSlotDuration: L1_BLOCK_TIME_IN_S, + aztecEpochProofClaimWindowInL2Slots: EPOCH_DURATION_IN_L2_SLOTS / 2, minTxsPerBlock: 0, realProofs: false, startProverNode: true, + // This must be enough so that the tx from the prover is delayed properly, + // but not so much to hang the sequencer and timeout the teardown + txPropagationMaxQueryAttempts: 12, }); logger = context.logger; @@ -87,8 +90,8 @@ describe('e2e_epochs', () => { // Constants used for time calculation constants = { - epochDuration: EPOCH_DURATION, - slotDuration: L1_BLOCK_TIME * L2_SLOT_DURATION_IN_L1_BLOCKS, + epochDuration: EPOCH_DURATION_IN_L2_SLOTS, + slotDuration: L1_BLOCK_TIME_IN_S * L2_SLOT_DURATION_IN_L1_SLOTS, l1GenesisBlock: await rollup.getL1StartBlock(), l1GenesisTime: await rollup.getL1GenesisTime(), }; @@ -105,7 +108,7 @@ describe('e2e_epochs', () => { const waitUntilEpochStarts = async (epoch: number) => { const [start] = getTimestampRangeForEpoch(BigInt(epoch), constants); logger.info(`Waiting until L1 timestamp ${start} is reached as the start of epoch ${epoch}`); - await waitUntilL1Timestamp(l1Client, start - BigInt(L1_BLOCK_TIME)); + await waitUntilL1Timestamp(l1Client, start - BigInt(L1_BLOCK_TIME_IN_S)); return start; }; @@ -124,12 +127,14 @@ describe('e2e_epochs', () => { proverDelayer.pauseNextTxUntilTimestamp(epoch2Start); logger.info(`Delayed prover tx until epoch 2 starts at ${epoch2Start}`); - // Wait until the last block of epoch 1 is published and then hold off the sequencer - await waitUntilL2BlockNumber(blockNumberAtEndOfEpoch0 + EPOCH_DURATION); - sequencerDelayer.pauseNextTxUntilTimestamp(epoch2Start + BigInt(L1_BLOCK_TIME)); + // Wait until the last block of epoch 1 is published and then hold off the sequencer. + // Note that the tx below will block the sequencer until it times out + // the txPropagationMaxQueryAttempts until #10824 is fixed. + await waitUntilL2BlockNumber(blockNumberAtEndOfEpoch0 + EPOCH_DURATION_IN_L2_SLOTS); + sequencerDelayer.pauseNextTxUntilTimestamp(epoch2Start + BigInt(L1_BLOCK_TIME_IN_S)); // Next sequencer to publish a block should trigger a rollback to block 1 - await waitUntilL1Timestamp(l1Client, epoch2Start + BigInt(L1_BLOCK_TIME)); + await waitUntilL1Timestamp(l1Client, epoch2Start + BigInt(L1_BLOCK_TIME_IN_S)); expect(await rollup.getBlockNumber()).toEqual(1n); expect(await rollup.getSlotNumber()).toEqual(8n); @@ -142,5 +147,6 @@ describe('e2e_epochs', () => { const lastL2BlockTxReceipt = await l1Client.getTransactionReceipt({ hash: lastL2BlockTxHash! }); expect(lastL2BlockTxReceipt.status).toEqual('success'); expect(lastL2BlockTxReceipt.blockNumber).toBeGreaterThan(lastProverTxReceipt!.blockNumber); + logger.info(`Test succeeded`); }); }); diff --git a/yarn-project/ethereum/src/l1_tx_utils.ts b/yarn-project/ethereum/src/l1_tx_utils.ts index b7eb9493a31..607f06b9567 100644 --- a/yarn-project/ethereum/src/l1_tx_utils.ts +++ b/yarn-project/ethereum/src/l1_tx_utils.ts @@ -1,3 +1,4 @@ +import { times } from '@aztec/foundation/collection'; import { type ConfigMappingsType, bigintConfigHelper, @@ -71,6 +72,11 @@ export interface L1TxUtilsConfig { * How long to wait for a tx to be mined before giving up */ txTimeoutMs?: number; + /** + * How many attempts will be done to get a tx after it was sent? + * First attempt is done at 1s, second at 2s, third at 3s, etc. + */ + txPropagationMaxQueryAttempts?: number; } export const l1TxUtilsConfigMappings: ConfigMappingsType = { @@ -119,6 +125,11 @@ export const l1TxUtilsConfigMappings: ConfigMappingsType = { env: 'L1_TX_MONITOR_TX_TIMEOUT_MS', ...numberConfigHelper(300_000), // 5 mins }, + txPropagationMaxQueryAttempts: { + description: 'How many attempts will be done to get a tx after it was sent', + env: 'L1_TX_PROPAGATION_MAX_QUERY_ATTEMPTS', + ...numberConfigHelper(3), + }, }; export const defaultL1TxUtilsConfig = getDefaultConfig(l1TxUtilsConfigMappings); @@ -213,12 +224,14 @@ export class L1TxUtils { const gasConfig = { ...this.config, ..._gasConfig }; const account = this.walletClient.account; const blobInputs = _blobInputs || {}; + const makeGetTransactionBackoff = () => + makeBackoff(times(gasConfig.txPropagationMaxQueryAttempts ?? 3, i => i + 1)); // Retry a few times, in case the tx is not yet propagated. const tx = await retry( () => this.publicClient.getTransaction({ hash: initialTxHash }), `Getting L1 transaction ${initialTxHash}`, - makeBackoff([1, 2, 3]), + makeGetTransactionBackoff(), this.logger, true, ); @@ -261,7 +274,7 @@ export class L1TxUtils { const tx = await retry( () => this.publicClient.getTransaction({ hash: currentTxHash }), `Getting L1 transaction ${currentTxHash}`, - makeBackoff([1, 2, 3]), + makeGetTransactionBackoff(), this.logger, true, ); diff --git a/yarn-project/ethereum/src/test/tx_delayer.ts b/yarn-project/ethereum/src/test/tx_delayer.ts index f96523dc797..afb117f4ea2 100644 --- a/yarn-project/ethereum/src/test/tx_delayer.ts +++ b/yarn-project/ethereum/src/test/tx_delayer.ts @@ -1,3 +1,4 @@ +import { omit } from '@aztec/foundation/collection'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { retryUntil } from '@aztec/foundation/retry'; @@ -8,6 +9,7 @@ import { type PublicClient, type WalletClient, keccak256, + parseTransaction, publicActions, walletActions, } from 'viem'; @@ -89,6 +91,7 @@ class DelayerImpl implements Delayer { /** * Returns a new client (without modifying the one passed in) with an injected tx delayer. * The delayer can be used to hold off the next tx to be sent until a given block number. + * TODO(#10824): This doesn't play along well with blob txs for some reason. */ export function withDelayer( client: T, @@ -116,16 +119,25 @@ export function withDelayer( // Compute the tx hash manually so we emulate sendRawTransaction response const { serializedTransaction } = args[0]; const txHash = keccak256(serializedTransaction); - logger.info(`Delaying tx ${txHash} until ${inspect(waitUntil)}`); + logger.info(`Delaying tx ${txHash} until ${inspect(waitUntil)}`, { + argsLen: args.length, + ...omit(parseTransaction(serializedTransaction), 'data', 'sidecars'), + }); // Do not await here so we can return the tx hash immediately as if it had been sent on the spot. // Instead, delay it so it lands on the desired block number or timestamp, assuming anvil will // mine it immediately. void wait .then(async () => { - const txHash = await client.sendRawTransaction(...args); - logger.info(`Sent previously delayed tx ${txHash} to land on ${inspect(waitUntil)}`); - delayer.txs.push(txHash); + const clientTxHash = await client.sendRawTransaction(...args); + if (clientTxHash !== txHash) { + logger.error(`Tx hash returned by the client does not match computed one`, { + clientTxHash, + computedTxHash: txHash, + }); + } + logger.info(`Sent previously delayed tx ${clientTxHash} to land on ${inspect(waitUntil)}`); + delayer.txs.push(clientTxHash); }) .catch(err => logger.error(`Error sending tx after delay`, err)); diff --git a/yarn-project/foundation/src/config/env_var.ts b/yarn-project/foundation/src/config/env_var.ts index ad999367e4f..76c58270b1f 100644 --- a/yarn-project/foundation/src/config/env_var.ts +++ b/yarn-project/foundation/src/config/env_var.ts @@ -183,6 +183,7 @@ export type EnvVar = | 'L1_TX_MONITOR_CHECK_INTERVAL_MS' | 'L1_TX_MONITOR_STALL_TIME_MS' | 'L1_TX_MONITOR_TX_TIMEOUT_MS' + | 'L1_TX_PROPAGATION_MAX_QUERY_ATTEMPTS' | 'FAUCET_MNEMONIC_ACCOUNT_INDEX' | 'FAUCET_ETH_AMOUNT' | 'FAUCET_INTERVAL_MS' From be7cadf12d25042d39e6a500ae32a5002102d3da Mon Sep 17 00:00:00 2001 From: josh crites Date: Tue, 17 Dec 2024 17:51:29 -0500 Subject: [PATCH 08/34] chore(docs): update migration notes (#10829) Please read [contributing guidelines](CONTRIBUTING.md) and remove this line. --- docs/docs/migration_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/migration_notes.md b/docs/docs/migration_notes.md index 5e376e4909a..b7817ae8bd7 100644 --- a/docs/docs/migration_notes.md +++ b/docs/docs/migration_notes.md @@ -6,7 +6,7 @@ keywords: [sandbox, aztec, notes, migration, updating, upgrading] Aztec is in full-speed development. Literally every version breaks compatibility with the previous ones. This page attempts to target errors and difficulties you might encounter when upgrading, and how to resolve them. -## 0.68.0 +## 0.67.1 ### Noir contracts package no longer exposes artifacts as default export From c90bb16a5880c42752809f383f517181e6f8a53a Mon Sep 17 00:00:00 2001 From: Aztec Bot <49558828+AztecBot@users.noreply.github.com> Date: Tue, 17 Dec 2024 20:03:03 -0500 Subject: [PATCH 09/34] chore(master): Release 0.67.1 (#10684) :robot: I have created a release *beep* *boop* ---
aztec-package: 0.67.1 ## [0.67.1](https://github.com/AztecProtocol/aztec-packages/compare/aztec-package-v0.67.0...aztec-package-v0.67.1) (2024-12-17) ### Miscellaneous * Granular CLI imports to reduce start time ([#10778](https://github.com/AztecProtocol/aztec-packages/issues/10778)) ([e2fd046](https://github.com/AztecProtocol/aztec-packages/commit/e2fd046250664cd785269a718b036c0310dfcda7)) * Split up protocol contract artifacts ([#10765](https://github.com/AztecProtocol/aztec-packages/issues/10765)) ([5a9ca18](https://github.com/AztecProtocol/aztec-packages/commit/5a9ca18ceee03ca2175605d1029153a7bf228ea9)) * Trace and handle errors in running promises ([#10645](https://github.com/AztecProtocol/aztec-packages/issues/10645)) ([4cc0a6d](https://github.com/AztecProtocol/aztec-packages/commit/4cc0a6d832e6ee1c3fcc6876517ed3f743f59d4b))
barretenberg.js: 0.67.1 ## [0.67.1](https://github.com/AztecProtocol/aztec-packages/compare/barretenberg.js-v0.67.0...barretenberg.js-v0.67.1) (2024-12-17) ### Features * PXE browser proving ([#10704](https://github.com/AztecProtocol/aztec-packages/issues/10704)) ([46da3cc](https://github.com/AztecProtocol/aztec-packages/commit/46da3cc8a9c1c407a8ad2857695eea794e334efd)) ### Bug Fixes * **bb.js:** Use globalThis instead of self ([#10747](https://github.com/AztecProtocol/aztec-packages/issues/10747)) ([309b5f7](https://github.com/AztecProtocol/aztec-packages/commit/309b5f74862089001e3159bdb52cbc8b60c71dc1)), closes [#10741](https://github.com/AztecProtocol/aztec-packages/issues/10741) * Casting vk to rawbuffer before wasm so it reads from the correct offset ([#10769](https://github.com/AztecProtocol/aztec-packages/issues/10769)) ([6a5bcfd](https://github.com/AztecProtocol/aztec-packages/commit/6a5bcfd2dc1a2bef6df2b93e9afa137a9b4ea315))
aztec-packages: 0.67.1 ## [0.67.1](https://github.com/AztecProtocol/aztec-packages/compare/aztec-packages-v0.67.0...aztec-packages-v0.67.1) (2024-12-17) ### Features * `nargo test -q` (or `nargo test --format terse`) (https://github.com/noir-lang/noir/pull/6776) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) * Add `(x | 1)` optimization for booleans (https://github.com/noir-lang/noir/pull/6795) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) * Add `nargo test --format json` (https://github.com/noir-lang/noir/pull/6796) ([d74d0fc](https://github.com/AztecProtocol/aztec-packages/commit/d74d0fcec24c533abc28320302e027470843e80c)) * Add tree equality assertions ([#10756](https://github.com/AztecProtocol/aztec-packages/issues/10756)) ([923826a](https://github.com/AztecProtocol/aztec-packages/commit/923826a9d1bbed6739527a82b34d5610600eca1b)) * **avm:** Migrate simulator memory to a map ([#10715](https://github.com/AztecProtocol/aztec-packages/issues/10715)) ([64d5f2b](https://github.com/AztecProtocol/aztec-packages/commit/64d5f2bd0dffe637fbff436ea651eb240256ab2c)), closes [#10370](https://github.com/AztecProtocol/aztec-packages/issues/10370) * Better initialization for permutation mapping components ([#10750](https://github.com/AztecProtocol/aztec-packages/issues/10750)) ([1516d7f](https://github.com/AztecProtocol/aztec-packages/commit/1516d7f7bd6a2adbb650bd7cdd572b33db98dbfc)) * Blobs 2. ([#10188](https://github.com/AztecProtocol/aztec-packages/issues/10188)) ([d0a4b2f](https://github.com/AztecProtocol/aztec-packages/commit/d0a4b2f011a25e59d5ef077cfefae4490ae1c263)) * **blobs:** Add consensus client url to config ([#10059](https://github.com/AztecProtocol/aztec-packages/issues/10059)) ([1e15bf5](https://github.com/AztecProtocol/aztec-packages/commit/1e15bf58390f6c15afc3b430edd89b4c28137c2b)) * Check max fees per gas ([#10283](https://github.com/AztecProtocol/aztec-packages/issues/10283)) ([4e59b06](https://github.com/AztecProtocol/aztec-packages/commit/4e59b06cd1956d43bc44a219448603b4bcf58d27)) * **cli:** Verify `return` against ABI and `Prover.toml` (https://github.com/noir-lang/noir/pull/6765) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) * Don't store every block number in block indices DB ([#10658](https://github.com/AztecProtocol/aztec-packages/issues/10658)) ([a3fba84](https://github.com/AztecProtocol/aztec-packages/commit/a3fba8442fdd62f429054c3367984fd4206bbbeb)) * Json output for get_node_info ([#10771](https://github.com/AztecProtocol/aztec-packages/issues/10771)) ([b086c52](https://github.com/AztecProtocol/aztec-packages/commit/b086c52110e5bc79a3d8eccbc2bc50cd68b3dc9b)) * Leaf index requests to the native world state can now be performed as a batch query ([#10649](https://github.com/AztecProtocol/aztec-packages/issues/10649)) ([a437e73](https://github.com/AztecProtocol/aztec-packages/commit/a437e73558a936981f3eb3ba022b0770b75d9060)) * New 17 in 20 IVC bench added to actions ([#10777](https://github.com/AztecProtocol/aztec-packages/issues/10777)) ([9fbcff6](https://github.com/AztecProtocol/aztec-packages/commit/9fbcff60a63e0eca14c4e28677aed1fc5e6f2c14)) * Note hash management in the AVM ([#10666](https://github.com/AztecProtocol/aztec-packages/issues/10666)) ([e077980](https://github.com/AztecProtocol/aztec-packages/commit/e077980f8cce1fc7922c27d368b6dbced956aad2)) * **p2p:** Activate gossipsub tx validators ([#10695](https://github.com/AztecProtocol/aztec-packages/issues/10695)) ([9cce2c6](https://github.com/AztecProtocol/aztec-packages/commit/9cce2c6fbae00008451940157690e0b5b99d9e59)) * **p2p:** Attestation pool persistence ([#10667](https://github.com/AztecProtocol/aztec-packages/issues/10667)) ([dacef9f](https://github.com/AztecProtocol/aztec-packages/commit/dacef9f7f9f11c8ec35ecd333748a9ae8c24d428)) * PXE browser proving ([#10704](https://github.com/AztecProtocol/aztec-packages/issues/10704)) ([46da3cc](https://github.com/AztecProtocol/aztec-packages/commit/46da3cc8a9c1c407a8ad2857695eea794e334efd)) * **ssa:** Bring back tracking of RC instructions during DIE (https://github.com/noir-lang/noir/pull/6783) ([308c5ce](https://github.com/AztecProtocol/aztec-packages/commit/308c5cef519b68f5951750851124c0bf8f4ba7ee)) * **ssa:** Hoist MakeArray instructions during loop invariant code motion (https://github.com/noir-lang/noir/pull/6782) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) * Sumcheck with disabled rows ([#10068](https://github.com/AztecProtocol/aztec-packages/issues/10068)) ([abd2226](https://github.com/AztecProtocol/aztec-packages/commit/abd2226da3a159e7efb7cbef099e41739f665ef1)) * TXE detects duplicate nullifiers ([#10764](https://github.com/AztecProtocol/aztec-packages/issues/10764)) ([7f70110](https://github.com/AztecProtocol/aztec-packages/commit/7f701105c2ac44df9cafedc834d77d4eabd92710)) ### Bug Fixes * Always remove nullified notes ([#10722](https://github.com/AztecProtocol/aztec-packages/issues/10722)) ([5e4b46d](https://github.com/AztecProtocol/aztec-packages/commit/5e4b46d577ebf63114a5a5a1c5b6d2947d3b2567)) * Avm gas and non-member ([#10709](https://github.com/AztecProtocol/aztec-packages/issues/10709)) ([dd8cc7b](https://github.com/AztecProtocol/aztec-packages/commit/dd8cc7b93119c0376873a366a8310d2ebd2641de)) * AVM witgen track gas for nested calls and external halts ([#10731](https://github.com/AztecProtocol/aztec-packages/issues/10731)) ([b8bdb52](https://github.com/AztecProtocol/aztec-packages/commit/b8bdb529719c1f72244e904ea667462458a43317)) * **bb.js:** Use globalThis instead of self ([#10747](https://github.com/AztecProtocol/aztec-packages/issues/10747)) ([309b5f7](https://github.com/AztecProtocol/aztec-packages/commit/309b5f74862089001e3159bdb52cbc8b60c71dc1)), closes [#10741](https://github.com/AztecProtocol/aztec-packages/issues/10741) * Block building test timeout ([#10812](https://github.com/AztecProtocol/aztec-packages/issues/10812)) ([2cad3e5](https://github.com/AztecProtocol/aztec-packages/commit/2cad3e59765a67ed14158ce556433120e9efd809)) * Cache ([#10692](https://github.com/AztecProtocol/aztec-packages/issues/10692)) ([1b1306c](https://github.com/AztecProtocol/aztec-packages/commit/1b1306c7dbd9d363181146e02181af4727779b42)) * Casting vk to rawbuffer before wasm so it reads from the correct offset ([#10769](https://github.com/AztecProtocol/aztec-packages/issues/10769)) ([6a5bcfd](https://github.com/AztecProtocol/aztec-packages/commit/6a5bcfd2dc1a2bef6df2b93e9afa137a9b4ea315)) * **ci:** Network-test timing ([#10725](https://github.com/AztecProtocol/aztec-packages/issues/10725)) ([9c9a2dc](https://github.com/AztecProtocol/aztec-packages/commit/9c9a2dcac8f7e14c1c5ec5d54d48a04a80284497)) * Disable failure persistance in nargo test fuzzing (https://github.com/noir-lang/noir/pull/6777) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) * Get e2e jobs ([#10689](https://github.com/AztecProtocol/aztec-packages/issues/10689)) ([37e1999](https://github.com/AztecProtocol/aztec-packages/commit/37e1999f9f96271faa8cba2fda44858276266a0c)) * Give build:fast a try in build ([#10702](https://github.com/AztecProtocol/aztec-packages/issues/10702)) ([32095f6](https://github.com/AztecProtocol/aztec-packages/commit/32095f63f4e1585e66251369e234c742aab0fa04)) * Minimal change to avoid reverting entire PR [#6685](https://github.com/AztecProtocol/aztec-packages/issues/6685) (https://github.com/noir-lang/noir/pull/6778) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) * Optimizer to keep track of changing opcode locations (https://github.com/noir-lang/noir/pull/6781) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) * Race condition in block stream ([#10779](https://github.com/AztecProtocol/aztec-packages/issues/10779)) ([64bccd0](https://github.com/AztecProtocol/aztec-packages/commit/64bccd0e3423856aadc58890e6a689db4af08356)) * Race condition when cleaning epoch proof quotes ([#10795](https://github.com/AztecProtocol/aztec-packages/issues/10795)) ([f540fbe](https://github.com/AztecProtocol/aztec-packages/commit/f540fbee724c2bfe29e0b0bca7759c721a8aaec8)) * **testdata:** Relative path calculation ([#10791](https://github.com/AztecProtocol/aztec-packages/issues/10791)) ([5a530db](https://github.com/AztecProtocol/aztec-packages/commit/5a530db5c42743e6eff846669141527ae1344bfe)) * Try fix e2e epochs in CI ([#10804](https://github.com/AztecProtocol/aztec-packages/issues/10804)) ([ba28788](https://github.com/AztecProtocol/aztec-packages/commit/ba28788de22b3209ec324633e91875b3b4b86332)) * Use correct size for databus_id ([#10673](https://github.com/AztecProtocol/aztec-packages/issues/10673)) ([95eb658](https://github.com/AztecProtocol/aztec-packages/commit/95eb658f90687c75589b345f95a904d96e2a8e62)) * Use extension in docs link so it also works on GitHub (https://github.com/noir-lang/noir/pull/6787) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) * Use throw instead of reject in broker facade ([#10735](https://github.com/AztecProtocol/aztec-packages/issues/10735)) ([cc6a72b](https://github.com/AztecProtocol/aztec-packages/commit/cc6a72be1c8dd5b133b5d82eac5224eef89d4ede)) ### Miscellaneous * `getLogsByTags` request batching in `syncTaggedLogs` ([#10716](https://github.com/AztecProtocol/aztec-packages/issues/10716)) ([bbbf38b](https://github.com/AztecProtocol/aztec-packages/commit/bbbf38b35c7f04414eeb7991a1ee45b19b16664f)) * Add `Instruction::map_values_mut` (https://github.com/noir-lang/noir/pull/6756) ([308c5ce](https://github.com/AztecProtocol/aztec-packages/commit/308c5cef519b68f5951750851124c0bf8f4ba7ee)) * Add errors to abis ([#10697](https://github.com/AztecProtocol/aztec-packages/issues/10697)) ([5c8e017](https://github.com/AztecProtocol/aztec-packages/commit/5c8e0174aade70c418a2d02cd9dc0ded3baa0745)) * Add retries for prover node p2p test ([#10699](https://github.com/AztecProtocol/aztec-packages/issues/10699)) ([4115bf9](https://github.com/AztecProtocol/aztec-packages/commit/4115bf985108e183f8a57aaf76289326251b8c7b)) * Add spans to proving job ([#10794](https://github.com/AztecProtocol/aztec-packages/issues/10794)) ([df3c51b](https://github.com/AztecProtocol/aztec-packages/commit/df3c51bfdb9770a95f6223fc85baf8632ca93279)) * Average alerts across namespace for 1 hour ([#10827](https://github.com/AztecProtocol/aztec-packages/issues/10827)) ([962a7a2](https://github.com/AztecProtocol/aztec-packages/commit/962a7a25d71d208992b16fcfd21e86874db5ec05)) * **avm:** Disable fake avm recursive verifier from the public base rollup ([#10690](https://github.com/AztecProtocol/aztec-packages/issues/10690)) ([b6c9c41](https://github.com/AztecProtocol/aztec-packages/commit/b6c9c4141b4ca6b1fc847068d352ee17590dea09)) * **avm:** Radix opcode - remove immediates ([#10696](https://github.com/AztecProtocol/aztec-packages/issues/10696)) ([4ac13e6](https://github.com/AztecProtocol/aztec-packages/commit/4ac13e642c958392ce5606684c044ea014325e26)), closes [#10371](https://github.com/AztecProtocol/aztec-packages/issues/10371) * Better reqresp logging + handle empty responses in snappy ([#10657](https://github.com/AztecProtocol/aztec-packages/issues/10657)) ([934107f](https://github.com/AztecProtocol/aztec-packages/commit/934107f35c2f2772ad422bfa34357bbd64f5049d)) * Bump metrics and node pool ([#10745](https://github.com/AztecProtocol/aztec-packages/issues/10745)) ([9bb88bf](https://github.com/AztecProtocol/aztec-packages/commit/9bb88bf323e68f42f34cba74ec270681d76d9bd4)) * Change Id to use a u32 (https://github.com/noir-lang/noir/pull/6807) ([d74d0fc](https://github.com/AztecProtocol/aztec-packages/commit/d74d0fcec24c533abc28320302e027470843e80c)) * **ci:** Active rollup circuits in compilation report (https://github.com/noir-lang/noir/pull/6813) ([308c5ce](https://github.com/AztecProtocol/aztec-packages/commit/308c5cef519b68f5951750851124c0bf8f4ba7ee)) * **ci:** Add bloblib to external checks (https://github.com/noir-lang/noir/pull/6818) ([381b0b8](https://github.com/AztecProtocol/aztec-packages/commit/381b0b84d87dd31f8ab5a3e62928f9992837d4c0)) * Cleanup after e2e tests ([#10748](https://github.com/AztecProtocol/aztec-packages/issues/10748)) ([284b0a4](https://github.com/AztecProtocol/aztec-packages/commit/284b0a496f42813b956e55fbcd41c864dd278241)) * Disable ARM CI ([#10682](https://github.com/AztecProtocol/aztec-packages/issues/10682)) ([b16945b](https://github.com/AztecProtocol/aztec-packages/commit/b16945b9c9e26d8de5502f698d2bd71e22c53807)) * Do not print entire functions when running debug trace (https://github.com/noir-lang/noir/pull/6814) ([308c5ce](https://github.com/AztecProtocol/aztec-packages/commit/308c5cef519b68f5951750851124c0bf8f4ba7ee)) * **docs:** Update migration notes ([#10829](https://github.com/AztecProtocol/aztec-packages/issues/10829)) ([be7cadf](https://github.com/AztecProtocol/aztec-packages/commit/be7cadf12d25042d39e6a500ae32a5002102d3da)) * **docs:** Workaround (https://github.com/noir-lang/noir/pull/6819) ([381b0b8](https://github.com/AztecProtocol/aztec-packages/commit/381b0b84d87dd31f8ab5a3e62928f9992837d4c0)) * Granular CLI imports to reduce start time ([#10778](https://github.com/AztecProtocol/aztec-packages/issues/10778)) ([e2fd046](https://github.com/AztecProtocol/aztec-packages/commit/e2fd046250664cd785269a718b036c0310dfcda7)) * Log error in retry module ([#10719](https://github.com/AztecProtocol/aztec-packages/issues/10719)) ([84ea539](https://github.com/AztecProtocol/aztec-packages/commit/84ea539145173a88bddfdc617051f16a7aba9834)) * Manage call stacks using a tree (https://github.com/noir-lang/noir/pull/6791) ([381b0b8](https://github.com/AztecProtocol/aztec-packages/commit/381b0b84d87dd31f8ab5a3e62928f9992837d4c0)) * Move decider PK allocation to methods ([#10670](https://github.com/AztecProtocol/aztec-packages/issues/10670)) ([1ab9e30](https://github.com/AztecProtocol/aztec-packages/commit/1ab9e30d339cfd7a80f333e408c367c1f8bf49f8)) * **p2p:** Move services into folders ([#10694](https://github.com/AztecProtocol/aztec-packages/issues/10694)) ([e28d12a](https://github.com/AztecProtocol/aztec-packages/commit/e28d12a3cdb182c905995a5ece4cc1b3d1d09482)) * **prover:** Prover node should not gossip attestations ([#10672](https://github.com/AztecProtocol/aztec-packages/issues/10672)) ([41fc0f0](https://github.com/AztecProtocol/aztec-packages/commit/41fc0f047a6412b824dc33b49cf8fd98c99598aa)) * Remove default export for noir contracts js ([#10762](https://github.com/AztecProtocol/aztec-packages/issues/10762)) ([c8e7763](https://github.com/AztecProtocol/aztec-packages/commit/c8e77639bf7f30dffe98ae335d5d1137da838e55)) * Remove sinon in favor of a date provider ([#10705](https://github.com/AztecProtocol/aztec-packages/issues/10705)) ([3d3fabb](https://github.com/AztecProtocol/aztec-packages/commit/3d3fabb38b160c7f98636d0f4d7c6d3c22c6227e)) * Remove spurious echo ([#10774](https://github.com/AztecProtocol/aztec-packages/issues/10774)) ([5538f8c](https://github.com/AztecProtocol/aztec-packages/commit/5538f8cfc94f617a5604706b53357f9018af1096)) * Replace relative paths to noir-protocol-circuits ([f85fa3f](https://github.com/AztecProtocol/aztec-packages/commit/f85fa3f9078fc4f3626c564e06161bf9398e87a4)) * Replace relative paths to noir-protocol-circuits ([b19c561](https://github.com/AztecProtocol/aztec-packages/commit/b19c56154d32050affa786620f95459bb5c29a6e)) * Set max txs in spam test ([#10717](https://github.com/AztecProtocol/aztec-packages/issues/10717)) ([a50ff6c](https://github.com/AztecProtocol/aztec-packages/commit/a50ff6cf968f459ae09620d0e5b2e955ea56512f)) * Slack notifications for networks ([#10784](https://github.com/AztecProtocol/aztec-packages/issues/10784)) ([bab9f85](https://github.com/AztecProtocol/aztec-packages/commit/bab9f852c08f29f022bf526aacb8350732fcf4ac)) * Split up protocol contract artifacts ([#10765](https://github.com/AztecProtocol/aztec-packages/issues/10765)) ([5a9ca18](https://github.com/AztecProtocol/aztec-packages/commit/5a9ca18ceee03ca2175605d1029153a7bf228ea9)) * **ssa:** Activate loop invariant code motion on ACIR functions (https://github.com/noir-lang/noir/pull/6785) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) * Sync grafana dashboard ([#10792](https://github.com/AztecProtocol/aztec-packages/issues/10792)) ([421fb65](https://github.com/AztecProtocol/aztec-packages/commit/421fb65d9f14b86df281b0d0dc0934859aa924bc)) * Tagging cleanup ([#10675](https://github.com/AztecProtocol/aztec-packages/issues/10675)) ([52b541a](https://github.com/AztecProtocol/aztec-packages/commit/52b541ab4e6295aea199a2181575208f20eaa7fc)) * Trace and handle errors in running promises ([#10645](https://github.com/AztecProtocol/aztec-packages/issues/10645)) ([4cc0a6d](https://github.com/AztecProtocol/aztec-packages/commit/4cc0a6d832e6ee1c3fcc6876517ed3f743f59d4b)) * Update external joiner script for new networks ([#10810](https://github.com/AztecProtocol/aztec-packages/issues/10810)) ([5f11cf4](https://github.com/AztecProtocol/aztec-packages/commit/5f11cf4bdc51fd21b8bd219ad1e81bf3afe585d9))
barretenberg: 0.67.1 ## [0.67.1](https://github.com/AztecProtocol/aztec-packages/compare/barretenberg-v0.67.0...barretenberg-v0.67.1) (2024-12-17) ### Features * Add tree equality assertions ([#10756](https://github.com/AztecProtocol/aztec-packages/issues/10756)) ([923826a](https://github.com/AztecProtocol/aztec-packages/commit/923826a9d1bbed6739527a82b34d5610600eca1b)) * Better initialization for permutation mapping components ([#10750](https://github.com/AztecProtocol/aztec-packages/issues/10750)) ([1516d7f](https://github.com/AztecProtocol/aztec-packages/commit/1516d7f7bd6a2adbb650bd7cdd572b33db98dbfc)) * Don't store every block number in block indices DB ([#10658](https://github.com/AztecProtocol/aztec-packages/issues/10658)) ([a3fba84](https://github.com/AztecProtocol/aztec-packages/commit/a3fba8442fdd62f429054c3367984fd4206bbbeb)) * Leaf index requests to the native world state can now be performed as a batch query ([#10649](https://github.com/AztecProtocol/aztec-packages/issues/10649)) ([a437e73](https://github.com/AztecProtocol/aztec-packages/commit/a437e73558a936981f3eb3ba022b0770b75d9060)) * New 17 in 20 IVC bench added to actions ([#10777](https://github.com/AztecProtocol/aztec-packages/issues/10777)) ([9fbcff6](https://github.com/AztecProtocol/aztec-packages/commit/9fbcff60a63e0eca14c4e28677aed1fc5e6f2c14)) * Note hash management in the AVM ([#10666](https://github.com/AztecProtocol/aztec-packages/issues/10666)) ([e077980](https://github.com/AztecProtocol/aztec-packages/commit/e077980f8cce1fc7922c27d368b6dbced956aad2)) * Sumcheck with disabled rows ([#10068](https://github.com/AztecProtocol/aztec-packages/issues/10068)) ([abd2226](https://github.com/AztecProtocol/aztec-packages/commit/abd2226da3a159e7efb7cbef099e41739f665ef1)) ### Bug Fixes * Avm gas and non-member ([#10709](https://github.com/AztecProtocol/aztec-packages/issues/10709)) ([dd8cc7b](https://github.com/AztecProtocol/aztec-packages/commit/dd8cc7b93119c0376873a366a8310d2ebd2641de)) * AVM witgen track gas for nested calls and external halts ([#10731](https://github.com/AztecProtocol/aztec-packages/issues/10731)) ([b8bdb52](https://github.com/AztecProtocol/aztec-packages/commit/b8bdb529719c1f72244e904ea667462458a43317)) * Use correct size for databus_id ([#10673](https://github.com/AztecProtocol/aztec-packages/issues/10673)) ([95eb658](https://github.com/AztecProtocol/aztec-packages/commit/95eb658f90687c75589b345f95a904d96e2a8e62)) ### Miscellaneous * **avm:** Radix opcode - remove immediates ([#10696](https://github.com/AztecProtocol/aztec-packages/issues/10696)) ([4ac13e6](https://github.com/AztecProtocol/aztec-packages/commit/4ac13e642c958392ce5606684c044ea014325e26)), closes [#10371](https://github.com/AztecProtocol/aztec-packages/issues/10371) * Move decider PK allocation to methods ([#10670](https://github.com/AztecProtocol/aztec-packages/issues/10670)) ([1ab9e30](https://github.com/AztecProtocol/aztec-packages/commit/1ab9e30d339cfd7a80f333e408c367c1f8bf49f8))
--- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --- .release-please-manifest.json | 8 +-- CHANGELOG.md | 93 +++++++++++++++++++++++++++++++++ barretenberg/CHANGELOG.md | 26 +++++++++ barretenberg/cpp/CMakeLists.txt | 2 +- barretenberg/ts/CHANGELOG.md | 13 +++++ barretenberg/ts/package.json | 2 +- yarn-project/aztec/CHANGELOG.md | 9 ++++ yarn-project/aztec/package.json | 2 +- 8 files changed, 148 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c13d5455245..8ce7b21d8c6 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,7 +1,7 @@ { - ".": "0.67.0", + ".": "0.67.1", "yarn-project/cli": "0.35.1", - "yarn-project/aztec": "0.67.0", - "barretenberg": "0.67.0", - "barretenberg/ts": "0.67.0" + "yarn-project/aztec": "0.67.1", + "barretenberg": "0.67.1", + "barretenberg/ts": "0.67.1" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 19d1e9989fd..54fb5c843e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,98 @@ # Changelog +## [0.67.1](https://github.com/AztecProtocol/aztec-packages/compare/aztec-packages-v0.67.0...aztec-packages-v0.67.1) (2024-12-17) + + +### Features + +* `nargo test -q` (or `nargo test --format terse`) (https://github.com/noir-lang/noir/pull/6776) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) +* Add `(x | 1)` optimization for booleans (https://github.com/noir-lang/noir/pull/6795) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) +* Add `nargo test --format json` (https://github.com/noir-lang/noir/pull/6796) ([d74d0fc](https://github.com/AztecProtocol/aztec-packages/commit/d74d0fcec24c533abc28320302e027470843e80c)) +* Add tree equality assertions ([#10756](https://github.com/AztecProtocol/aztec-packages/issues/10756)) ([923826a](https://github.com/AztecProtocol/aztec-packages/commit/923826a9d1bbed6739527a82b34d5610600eca1b)) +* **avm:** Migrate simulator memory to a map ([#10715](https://github.com/AztecProtocol/aztec-packages/issues/10715)) ([64d5f2b](https://github.com/AztecProtocol/aztec-packages/commit/64d5f2bd0dffe637fbff436ea651eb240256ab2c)), closes [#10370](https://github.com/AztecProtocol/aztec-packages/issues/10370) +* Better initialization for permutation mapping components ([#10750](https://github.com/AztecProtocol/aztec-packages/issues/10750)) ([1516d7f](https://github.com/AztecProtocol/aztec-packages/commit/1516d7f7bd6a2adbb650bd7cdd572b33db98dbfc)) +* Blobs 2. ([#10188](https://github.com/AztecProtocol/aztec-packages/issues/10188)) ([d0a4b2f](https://github.com/AztecProtocol/aztec-packages/commit/d0a4b2f011a25e59d5ef077cfefae4490ae1c263)) +* **blobs:** Add consensus client url to config ([#10059](https://github.com/AztecProtocol/aztec-packages/issues/10059)) ([1e15bf5](https://github.com/AztecProtocol/aztec-packages/commit/1e15bf58390f6c15afc3b430edd89b4c28137c2b)) +* Check max fees per gas ([#10283](https://github.com/AztecProtocol/aztec-packages/issues/10283)) ([4e59b06](https://github.com/AztecProtocol/aztec-packages/commit/4e59b06cd1956d43bc44a219448603b4bcf58d27)) +* **cli:** Verify `return` against ABI and `Prover.toml` (https://github.com/noir-lang/noir/pull/6765) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) +* Don't store every block number in block indices DB ([#10658](https://github.com/AztecProtocol/aztec-packages/issues/10658)) ([a3fba84](https://github.com/AztecProtocol/aztec-packages/commit/a3fba8442fdd62f429054c3367984fd4206bbbeb)) +* Json output for get_node_info ([#10771](https://github.com/AztecProtocol/aztec-packages/issues/10771)) ([b086c52](https://github.com/AztecProtocol/aztec-packages/commit/b086c52110e5bc79a3d8eccbc2bc50cd68b3dc9b)) +* Leaf index requests to the native world state can now be performed as a batch query ([#10649](https://github.com/AztecProtocol/aztec-packages/issues/10649)) ([a437e73](https://github.com/AztecProtocol/aztec-packages/commit/a437e73558a936981f3eb3ba022b0770b75d9060)) +* New 17 in 20 IVC bench added to actions ([#10777](https://github.com/AztecProtocol/aztec-packages/issues/10777)) ([9fbcff6](https://github.com/AztecProtocol/aztec-packages/commit/9fbcff60a63e0eca14c4e28677aed1fc5e6f2c14)) +* Note hash management in the AVM ([#10666](https://github.com/AztecProtocol/aztec-packages/issues/10666)) ([e077980](https://github.com/AztecProtocol/aztec-packages/commit/e077980f8cce1fc7922c27d368b6dbced956aad2)) +* **p2p:** Activate gossipsub tx validators ([#10695](https://github.com/AztecProtocol/aztec-packages/issues/10695)) ([9cce2c6](https://github.com/AztecProtocol/aztec-packages/commit/9cce2c6fbae00008451940157690e0b5b99d9e59)) +* **p2p:** Attestation pool persistence ([#10667](https://github.com/AztecProtocol/aztec-packages/issues/10667)) ([dacef9f](https://github.com/AztecProtocol/aztec-packages/commit/dacef9f7f9f11c8ec35ecd333748a9ae8c24d428)) +* PXE browser proving ([#10704](https://github.com/AztecProtocol/aztec-packages/issues/10704)) ([46da3cc](https://github.com/AztecProtocol/aztec-packages/commit/46da3cc8a9c1c407a8ad2857695eea794e334efd)) +* **ssa:** Bring back tracking of RC instructions during DIE (https://github.com/noir-lang/noir/pull/6783) ([308c5ce](https://github.com/AztecProtocol/aztec-packages/commit/308c5cef519b68f5951750851124c0bf8f4ba7ee)) +* **ssa:** Hoist MakeArray instructions during loop invariant code motion (https://github.com/noir-lang/noir/pull/6782) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) +* Sumcheck with disabled rows ([#10068](https://github.com/AztecProtocol/aztec-packages/issues/10068)) ([abd2226](https://github.com/AztecProtocol/aztec-packages/commit/abd2226da3a159e7efb7cbef099e41739f665ef1)) +* TXE detects duplicate nullifiers ([#10764](https://github.com/AztecProtocol/aztec-packages/issues/10764)) ([7f70110](https://github.com/AztecProtocol/aztec-packages/commit/7f701105c2ac44df9cafedc834d77d4eabd92710)) + + +### Bug Fixes + +* Always remove nullified notes ([#10722](https://github.com/AztecProtocol/aztec-packages/issues/10722)) ([5e4b46d](https://github.com/AztecProtocol/aztec-packages/commit/5e4b46d577ebf63114a5a5a1c5b6d2947d3b2567)) +* Avm gas and non-member ([#10709](https://github.com/AztecProtocol/aztec-packages/issues/10709)) ([dd8cc7b](https://github.com/AztecProtocol/aztec-packages/commit/dd8cc7b93119c0376873a366a8310d2ebd2641de)) +* AVM witgen track gas for nested calls and external halts ([#10731](https://github.com/AztecProtocol/aztec-packages/issues/10731)) ([b8bdb52](https://github.com/AztecProtocol/aztec-packages/commit/b8bdb529719c1f72244e904ea667462458a43317)) +* **bb.js:** Use globalThis instead of self ([#10747](https://github.com/AztecProtocol/aztec-packages/issues/10747)) ([309b5f7](https://github.com/AztecProtocol/aztec-packages/commit/309b5f74862089001e3159bdb52cbc8b60c71dc1)), closes [#10741](https://github.com/AztecProtocol/aztec-packages/issues/10741) +* Block building test timeout ([#10812](https://github.com/AztecProtocol/aztec-packages/issues/10812)) ([2cad3e5](https://github.com/AztecProtocol/aztec-packages/commit/2cad3e59765a67ed14158ce556433120e9efd809)) +* Cache ([#10692](https://github.com/AztecProtocol/aztec-packages/issues/10692)) ([1b1306c](https://github.com/AztecProtocol/aztec-packages/commit/1b1306c7dbd9d363181146e02181af4727779b42)) +* Casting vk to rawbuffer before wasm so it reads from the correct offset ([#10769](https://github.com/AztecProtocol/aztec-packages/issues/10769)) ([6a5bcfd](https://github.com/AztecProtocol/aztec-packages/commit/6a5bcfd2dc1a2bef6df2b93e9afa137a9b4ea315)) +* **ci:** Network-test timing ([#10725](https://github.com/AztecProtocol/aztec-packages/issues/10725)) ([9c9a2dc](https://github.com/AztecProtocol/aztec-packages/commit/9c9a2dcac8f7e14c1c5ec5d54d48a04a80284497)) +* Disable failure persistance in nargo test fuzzing (https://github.com/noir-lang/noir/pull/6777) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) +* Get e2e jobs ([#10689](https://github.com/AztecProtocol/aztec-packages/issues/10689)) ([37e1999](https://github.com/AztecProtocol/aztec-packages/commit/37e1999f9f96271faa8cba2fda44858276266a0c)) +* Give build:fast a try in build ([#10702](https://github.com/AztecProtocol/aztec-packages/issues/10702)) ([32095f6](https://github.com/AztecProtocol/aztec-packages/commit/32095f63f4e1585e66251369e234c742aab0fa04)) +* Minimal change to avoid reverting entire PR [#6685](https://github.com/AztecProtocol/aztec-packages/issues/6685) (https://github.com/noir-lang/noir/pull/6778) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) +* Optimizer to keep track of changing opcode locations (https://github.com/noir-lang/noir/pull/6781) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) +* Race condition in block stream ([#10779](https://github.com/AztecProtocol/aztec-packages/issues/10779)) ([64bccd0](https://github.com/AztecProtocol/aztec-packages/commit/64bccd0e3423856aadc58890e6a689db4af08356)) +* Race condition when cleaning epoch proof quotes ([#10795](https://github.com/AztecProtocol/aztec-packages/issues/10795)) ([f540fbe](https://github.com/AztecProtocol/aztec-packages/commit/f540fbee724c2bfe29e0b0bca7759c721a8aaec8)) +* **testdata:** Relative path calculation ([#10791](https://github.com/AztecProtocol/aztec-packages/issues/10791)) ([5a530db](https://github.com/AztecProtocol/aztec-packages/commit/5a530db5c42743e6eff846669141527ae1344bfe)) +* Try fix e2e epochs in CI ([#10804](https://github.com/AztecProtocol/aztec-packages/issues/10804)) ([ba28788](https://github.com/AztecProtocol/aztec-packages/commit/ba28788de22b3209ec324633e91875b3b4b86332)) +* Use correct size for databus_id ([#10673](https://github.com/AztecProtocol/aztec-packages/issues/10673)) ([95eb658](https://github.com/AztecProtocol/aztec-packages/commit/95eb658f90687c75589b345f95a904d96e2a8e62)) +* Use extension in docs link so it also works on GitHub (https://github.com/noir-lang/noir/pull/6787) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) +* Use throw instead of reject in broker facade ([#10735](https://github.com/AztecProtocol/aztec-packages/issues/10735)) ([cc6a72b](https://github.com/AztecProtocol/aztec-packages/commit/cc6a72be1c8dd5b133b5d82eac5224eef89d4ede)) + + +### Miscellaneous + +* `getLogsByTags` request batching in `syncTaggedLogs` ([#10716](https://github.com/AztecProtocol/aztec-packages/issues/10716)) ([bbbf38b](https://github.com/AztecProtocol/aztec-packages/commit/bbbf38b35c7f04414eeb7991a1ee45b19b16664f)) +* Add `Instruction::map_values_mut` (https://github.com/noir-lang/noir/pull/6756) ([308c5ce](https://github.com/AztecProtocol/aztec-packages/commit/308c5cef519b68f5951750851124c0bf8f4ba7ee)) +* Add errors to abis ([#10697](https://github.com/AztecProtocol/aztec-packages/issues/10697)) ([5c8e017](https://github.com/AztecProtocol/aztec-packages/commit/5c8e0174aade70c418a2d02cd9dc0ded3baa0745)) +* Add retries for prover node p2p test ([#10699](https://github.com/AztecProtocol/aztec-packages/issues/10699)) ([4115bf9](https://github.com/AztecProtocol/aztec-packages/commit/4115bf985108e183f8a57aaf76289326251b8c7b)) +* Add spans to proving job ([#10794](https://github.com/AztecProtocol/aztec-packages/issues/10794)) ([df3c51b](https://github.com/AztecProtocol/aztec-packages/commit/df3c51bfdb9770a95f6223fc85baf8632ca93279)) +* Average alerts across namespace for 1 hour ([#10827](https://github.com/AztecProtocol/aztec-packages/issues/10827)) ([962a7a2](https://github.com/AztecProtocol/aztec-packages/commit/962a7a25d71d208992b16fcfd21e86874db5ec05)) +* **avm:** Disable fake avm recursive verifier from the public base rollup ([#10690](https://github.com/AztecProtocol/aztec-packages/issues/10690)) ([b6c9c41](https://github.com/AztecProtocol/aztec-packages/commit/b6c9c4141b4ca6b1fc847068d352ee17590dea09)) +* **avm:** Radix opcode - remove immediates ([#10696](https://github.com/AztecProtocol/aztec-packages/issues/10696)) ([4ac13e6](https://github.com/AztecProtocol/aztec-packages/commit/4ac13e642c958392ce5606684c044ea014325e26)), closes [#10371](https://github.com/AztecProtocol/aztec-packages/issues/10371) +* Better reqresp logging + handle empty responses in snappy ([#10657](https://github.com/AztecProtocol/aztec-packages/issues/10657)) ([934107f](https://github.com/AztecProtocol/aztec-packages/commit/934107f35c2f2772ad422bfa34357bbd64f5049d)) +* Bump metrics and node pool ([#10745](https://github.com/AztecProtocol/aztec-packages/issues/10745)) ([9bb88bf](https://github.com/AztecProtocol/aztec-packages/commit/9bb88bf323e68f42f34cba74ec270681d76d9bd4)) +* Change Id to use a u32 (https://github.com/noir-lang/noir/pull/6807) ([d74d0fc](https://github.com/AztecProtocol/aztec-packages/commit/d74d0fcec24c533abc28320302e027470843e80c)) +* **ci:** Active rollup circuits in compilation report (https://github.com/noir-lang/noir/pull/6813) ([308c5ce](https://github.com/AztecProtocol/aztec-packages/commit/308c5cef519b68f5951750851124c0bf8f4ba7ee)) +* **ci:** Add bloblib to external checks (https://github.com/noir-lang/noir/pull/6818) ([381b0b8](https://github.com/AztecProtocol/aztec-packages/commit/381b0b84d87dd31f8ab5a3e62928f9992837d4c0)) +* Cleanup after e2e tests ([#10748](https://github.com/AztecProtocol/aztec-packages/issues/10748)) ([284b0a4](https://github.com/AztecProtocol/aztec-packages/commit/284b0a496f42813b956e55fbcd41c864dd278241)) +* Disable ARM CI ([#10682](https://github.com/AztecProtocol/aztec-packages/issues/10682)) ([b16945b](https://github.com/AztecProtocol/aztec-packages/commit/b16945b9c9e26d8de5502f698d2bd71e22c53807)) +* Do not print entire functions when running debug trace (https://github.com/noir-lang/noir/pull/6814) ([308c5ce](https://github.com/AztecProtocol/aztec-packages/commit/308c5cef519b68f5951750851124c0bf8f4ba7ee)) +* **docs:** Update migration notes ([#10829](https://github.com/AztecProtocol/aztec-packages/issues/10829)) ([be7cadf](https://github.com/AztecProtocol/aztec-packages/commit/be7cadf12d25042d39e6a500ae32a5002102d3da)) +* **docs:** Workaround (https://github.com/noir-lang/noir/pull/6819) ([381b0b8](https://github.com/AztecProtocol/aztec-packages/commit/381b0b84d87dd31f8ab5a3e62928f9992837d4c0)) +* Granular CLI imports to reduce start time ([#10778](https://github.com/AztecProtocol/aztec-packages/issues/10778)) ([e2fd046](https://github.com/AztecProtocol/aztec-packages/commit/e2fd046250664cd785269a718b036c0310dfcda7)) +* Log error in retry module ([#10719](https://github.com/AztecProtocol/aztec-packages/issues/10719)) ([84ea539](https://github.com/AztecProtocol/aztec-packages/commit/84ea539145173a88bddfdc617051f16a7aba9834)) +* Manage call stacks using a tree (https://github.com/noir-lang/noir/pull/6791) ([381b0b8](https://github.com/AztecProtocol/aztec-packages/commit/381b0b84d87dd31f8ab5a3e62928f9992837d4c0)) +* Move decider PK allocation to methods ([#10670](https://github.com/AztecProtocol/aztec-packages/issues/10670)) ([1ab9e30](https://github.com/AztecProtocol/aztec-packages/commit/1ab9e30d339cfd7a80f333e408c367c1f8bf49f8)) +* **p2p:** Move services into folders ([#10694](https://github.com/AztecProtocol/aztec-packages/issues/10694)) ([e28d12a](https://github.com/AztecProtocol/aztec-packages/commit/e28d12a3cdb182c905995a5ece4cc1b3d1d09482)) +* **prover:** Prover node should not gossip attestations ([#10672](https://github.com/AztecProtocol/aztec-packages/issues/10672)) ([41fc0f0](https://github.com/AztecProtocol/aztec-packages/commit/41fc0f047a6412b824dc33b49cf8fd98c99598aa)) +* Remove default export for noir contracts js ([#10762](https://github.com/AztecProtocol/aztec-packages/issues/10762)) ([c8e7763](https://github.com/AztecProtocol/aztec-packages/commit/c8e77639bf7f30dffe98ae335d5d1137da838e55)) +* Remove sinon in favor of a date provider ([#10705](https://github.com/AztecProtocol/aztec-packages/issues/10705)) ([3d3fabb](https://github.com/AztecProtocol/aztec-packages/commit/3d3fabb38b160c7f98636d0f4d7c6d3c22c6227e)) +* Remove spurious echo ([#10774](https://github.com/AztecProtocol/aztec-packages/issues/10774)) ([5538f8c](https://github.com/AztecProtocol/aztec-packages/commit/5538f8cfc94f617a5604706b53357f9018af1096)) +* Replace relative paths to noir-protocol-circuits ([f85fa3f](https://github.com/AztecProtocol/aztec-packages/commit/f85fa3f9078fc4f3626c564e06161bf9398e87a4)) +* Replace relative paths to noir-protocol-circuits ([b19c561](https://github.com/AztecProtocol/aztec-packages/commit/b19c56154d32050affa786620f95459bb5c29a6e)) +* Set max txs in spam test ([#10717](https://github.com/AztecProtocol/aztec-packages/issues/10717)) ([a50ff6c](https://github.com/AztecProtocol/aztec-packages/commit/a50ff6cf968f459ae09620d0e5b2e955ea56512f)) +* Slack notifications for networks ([#10784](https://github.com/AztecProtocol/aztec-packages/issues/10784)) ([bab9f85](https://github.com/AztecProtocol/aztec-packages/commit/bab9f852c08f29f022bf526aacb8350732fcf4ac)) +* Split up protocol contract artifacts ([#10765](https://github.com/AztecProtocol/aztec-packages/issues/10765)) ([5a9ca18](https://github.com/AztecProtocol/aztec-packages/commit/5a9ca18ceee03ca2175605d1029153a7bf228ea9)) +* **ssa:** Activate loop invariant code motion on ACIR functions (https://github.com/noir-lang/noir/pull/6785) ([8956e28](https://github.com/AztecProtocol/aztec-packages/commit/8956e28269a045732e733b5197bdab5e46cdf354)) +* Sync grafana dashboard ([#10792](https://github.com/AztecProtocol/aztec-packages/issues/10792)) ([421fb65](https://github.com/AztecProtocol/aztec-packages/commit/421fb65d9f14b86df281b0d0dc0934859aa924bc)) +* Tagging cleanup ([#10675](https://github.com/AztecProtocol/aztec-packages/issues/10675)) ([52b541a](https://github.com/AztecProtocol/aztec-packages/commit/52b541ab4e6295aea199a2181575208f20eaa7fc)) +* Trace and handle errors in running promises ([#10645](https://github.com/AztecProtocol/aztec-packages/issues/10645)) ([4cc0a6d](https://github.com/AztecProtocol/aztec-packages/commit/4cc0a6d832e6ee1c3fcc6876517ed3f743f59d4b)) +* Update external joiner script for new networks ([#10810](https://github.com/AztecProtocol/aztec-packages/issues/10810)) ([5f11cf4](https://github.com/AztecProtocol/aztec-packages/commit/5f11cf4bdc51fd21b8bd219ad1e81bf3afe585d9)) + ## [0.67.0](https://github.com/AztecProtocol/aztec-packages/compare/aztec-packages-v0.66.0...aztec-packages-v0.67.0) (2024-12-13) diff --git a/barretenberg/CHANGELOG.md b/barretenberg/CHANGELOG.md index 9d88cb0e649..ce20f60b5c6 100644 --- a/barretenberg/CHANGELOG.md +++ b/barretenberg/CHANGELOG.md @@ -1,5 +1,31 @@ # Changelog +## [0.67.1](https://github.com/AztecProtocol/aztec-packages/compare/barretenberg-v0.67.0...barretenberg-v0.67.1) (2024-12-17) + + +### Features + +* Add tree equality assertions ([#10756](https://github.com/AztecProtocol/aztec-packages/issues/10756)) ([923826a](https://github.com/AztecProtocol/aztec-packages/commit/923826a9d1bbed6739527a82b34d5610600eca1b)) +* Better initialization for permutation mapping components ([#10750](https://github.com/AztecProtocol/aztec-packages/issues/10750)) ([1516d7f](https://github.com/AztecProtocol/aztec-packages/commit/1516d7f7bd6a2adbb650bd7cdd572b33db98dbfc)) +* Don't store every block number in block indices DB ([#10658](https://github.com/AztecProtocol/aztec-packages/issues/10658)) ([a3fba84](https://github.com/AztecProtocol/aztec-packages/commit/a3fba8442fdd62f429054c3367984fd4206bbbeb)) +* Leaf index requests to the native world state can now be performed as a batch query ([#10649](https://github.com/AztecProtocol/aztec-packages/issues/10649)) ([a437e73](https://github.com/AztecProtocol/aztec-packages/commit/a437e73558a936981f3eb3ba022b0770b75d9060)) +* New 17 in 20 IVC bench added to actions ([#10777](https://github.com/AztecProtocol/aztec-packages/issues/10777)) ([9fbcff6](https://github.com/AztecProtocol/aztec-packages/commit/9fbcff60a63e0eca14c4e28677aed1fc5e6f2c14)) +* Note hash management in the AVM ([#10666](https://github.com/AztecProtocol/aztec-packages/issues/10666)) ([e077980](https://github.com/AztecProtocol/aztec-packages/commit/e077980f8cce1fc7922c27d368b6dbced956aad2)) +* Sumcheck with disabled rows ([#10068](https://github.com/AztecProtocol/aztec-packages/issues/10068)) ([abd2226](https://github.com/AztecProtocol/aztec-packages/commit/abd2226da3a159e7efb7cbef099e41739f665ef1)) + + +### Bug Fixes + +* Avm gas and non-member ([#10709](https://github.com/AztecProtocol/aztec-packages/issues/10709)) ([dd8cc7b](https://github.com/AztecProtocol/aztec-packages/commit/dd8cc7b93119c0376873a366a8310d2ebd2641de)) +* AVM witgen track gas for nested calls and external halts ([#10731](https://github.com/AztecProtocol/aztec-packages/issues/10731)) ([b8bdb52](https://github.com/AztecProtocol/aztec-packages/commit/b8bdb529719c1f72244e904ea667462458a43317)) +* Use correct size for databus_id ([#10673](https://github.com/AztecProtocol/aztec-packages/issues/10673)) ([95eb658](https://github.com/AztecProtocol/aztec-packages/commit/95eb658f90687c75589b345f95a904d96e2a8e62)) + + +### Miscellaneous + +* **avm:** Radix opcode - remove immediates ([#10696](https://github.com/AztecProtocol/aztec-packages/issues/10696)) ([4ac13e6](https://github.com/AztecProtocol/aztec-packages/commit/4ac13e642c958392ce5606684c044ea014325e26)), closes [#10371](https://github.com/AztecProtocol/aztec-packages/issues/10371) +* Move decider PK allocation to methods ([#10670](https://github.com/AztecProtocol/aztec-packages/issues/10670)) ([1ab9e30](https://github.com/AztecProtocol/aztec-packages/commit/1ab9e30d339cfd7a80f333e408c367c1f8bf49f8)) + ## [0.67.0](https://github.com/AztecProtocol/aztec-packages/compare/barretenberg-v0.66.0...barretenberg-v0.67.0) (2024-12-13) diff --git a/barretenberg/cpp/CMakeLists.txt b/barretenberg/cpp/CMakeLists.txt index 079ac155ea6..6e35eb87c15 100644 --- a/barretenberg/cpp/CMakeLists.txt +++ b/barretenberg/cpp/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.24 FATAL_ERROR) project( Barretenberg DESCRIPTION "BN254 elliptic curve library, and PLONK SNARK prover" - VERSION 0.67.0 # x-release-please-version + VERSION 0.67.1 # x-release-please-version LANGUAGES CXX C ) # Insert version into `bb` config file diff --git a/barretenberg/ts/CHANGELOG.md b/barretenberg/ts/CHANGELOG.md index fb0c6d47332..1758b9d134e 100644 --- a/barretenberg/ts/CHANGELOG.md +++ b/barretenberg/ts/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [0.67.1](https://github.com/AztecProtocol/aztec-packages/compare/barretenberg.js-v0.67.0...barretenberg.js-v0.67.1) (2024-12-17) + + +### Features + +* PXE browser proving ([#10704](https://github.com/AztecProtocol/aztec-packages/issues/10704)) ([46da3cc](https://github.com/AztecProtocol/aztec-packages/commit/46da3cc8a9c1c407a8ad2857695eea794e334efd)) + + +### Bug Fixes + +* **bb.js:** Use globalThis instead of self ([#10747](https://github.com/AztecProtocol/aztec-packages/issues/10747)) ([309b5f7](https://github.com/AztecProtocol/aztec-packages/commit/309b5f74862089001e3159bdb52cbc8b60c71dc1)), closes [#10741](https://github.com/AztecProtocol/aztec-packages/issues/10741) +* Casting vk to rawbuffer before wasm so it reads from the correct offset ([#10769](https://github.com/AztecProtocol/aztec-packages/issues/10769)) ([6a5bcfd](https://github.com/AztecProtocol/aztec-packages/commit/6a5bcfd2dc1a2bef6df2b93e9afa137a9b4ea315)) + ## [0.67.0](https://github.com/AztecProtocol/aztec-packages/compare/barretenberg.js-v0.66.0...barretenberg.js-v0.67.0) (2024-12-13) diff --git a/barretenberg/ts/package.json b/barretenberg/ts/package.json index 8ccaf5540dc..b21aeede008 100644 --- a/barretenberg/ts/package.json +++ b/barretenberg/ts/package.json @@ -1,7 +1,7 @@ { "name": "@aztec/bb.js", "packageManager": "yarn@1.22.22", - "version": "0.67.0", + "version": "0.67.1", "homepage": "https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg/ts", "license": "MIT", "type": "module", diff --git a/yarn-project/aztec/CHANGELOG.md b/yarn-project/aztec/CHANGELOG.md index d6f2ae04a8d..b0d385fd159 100644 --- a/yarn-project/aztec/CHANGELOG.md +++ b/yarn-project/aztec/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [0.67.1](https://github.com/AztecProtocol/aztec-packages/compare/aztec-package-v0.67.0...aztec-package-v0.67.1) (2024-12-17) + + +### Miscellaneous + +* Granular CLI imports to reduce start time ([#10778](https://github.com/AztecProtocol/aztec-packages/issues/10778)) ([e2fd046](https://github.com/AztecProtocol/aztec-packages/commit/e2fd046250664cd785269a718b036c0310dfcda7)) +* Split up protocol contract artifacts ([#10765](https://github.com/AztecProtocol/aztec-packages/issues/10765)) ([5a9ca18](https://github.com/AztecProtocol/aztec-packages/commit/5a9ca18ceee03ca2175605d1029153a7bf228ea9)) +* Trace and handle errors in running promises ([#10645](https://github.com/AztecProtocol/aztec-packages/issues/10645)) ([4cc0a6d](https://github.com/AztecProtocol/aztec-packages/commit/4cc0a6d832e6ee1c3fcc6876517ed3f743f59d4b)) + ## [0.67.0](https://github.com/AztecProtocol/aztec-packages/compare/aztec-package-v0.66.0...aztec-package-v0.67.0) (2024-12-13) diff --git a/yarn-project/aztec/package.json b/yarn-project/aztec/package.json index 3db042507ba..5e9a1e1ef52 100644 --- a/yarn-project/aztec/package.json +++ b/yarn-project/aztec/package.json @@ -1,6 +1,6 @@ { "name": "@aztec/aztec", - "version": "0.67.0", + "version": "0.67.1", "type": "module", "exports": { ".": "./dest/index.js" From 995a519a9ef1be0fe40120f6f15b090c051f0a6c Mon Sep 17 00:00:00 2001 From: AztecBot Date: Wed, 18 Dec 2024 02:27:36 +0000 Subject: [PATCH 10/34] git subrepo push --branch=master barretenberg subrepo: subdir: "barretenberg" merged: "c6f0e4997c" upstream: origin: "https://github.com/AztecProtocol/barretenberg" branch: "master" commit: "c6f0e4997c" git-subrepo: version: "0.4.6" origin: "???" commit: "???" [skip ci] --- barretenberg/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/barretenberg/.gitrepo b/barretenberg/.gitrepo index 9655867464a..76b852eee72 100644 --- a/barretenberg/.gitrepo +++ b/barretenberg/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/AztecProtocol/barretenberg branch = master - commit = 9f6fda1a3d99c75532767eaac8ea3b783a450acb - parent = bab9f852c08f29f022bf526aacb8350732fcf4ac + commit = c6f0e4997cda15c88022515563f9dceaab31f018 + parent = c90bb16a5880c42752809f383f517181e6f8a53a method = merge cmdver = 0.4.6 From 8b3eb340d82f558326a6f6fa25544395c39eec29 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Wed, 18 Dec 2024 02:28:09 +0000 Subject: [PATCH 11/34] chore: replace relative paths to noir-protocol-circuits --- noir-projects/aztec-nr/aztec/Nargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir-projects/aztec-nr/aztec/Nargo.toml b/noir-projects/aztec-nr/aztec/Nargo.toml index 7a1f1af5863..b2031323496 100644 --- a/noir-projects/aztec-nr/aztec/Nargo.toml +++ b/noir-projects/aztec-nr/aztec/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.18.0" type = "lib" [dependencies] -protocol_types = { path = "../../noir-protocol-circuits/crates/types" } +protocol_types = { git="https://github.com/AztecProtocol/aztec-packages", tag="aztec-packages-v0.67.1", directory="noir-projects/noir-protocol-circuits/crates/types" } From f3dd71ab82122d95454cf664d0e0ca3ad00db308 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Wed, 18 Dec 2024 02:28:09 +0000 Subject: [PATCH 12/34] git_subrepo.sh: Fix parent in .gitrepo file. [skip ci] --- noir-projects/aztec-nr/.gitrepo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir-projects/aztec-nr/.gitrepo b/noir-projects/aztec-nr/.gitrepo index c26967f18a9..5af18686bbc 100644 --- a/noir-projects/aztec-nr/.gitrepo +++ b/noir-projects/aztec-nr/.gitrepo @@ -9,4 +9,4 @@ remote = https://github.com/AztecProtocol/aztec-nr commit = a234b3c5ac1a38589e7cd51ba6361bfd62b8711c method = merge cmdver = 0.4.6 - parent = c020ede81bb75693de20a1f122ec04e33faaf18c + parent = 3fd4275bdbf6c23173359430fe96a62a643c4d77 From 9c4c23c0f25ef37abcd9511270bada5fa4163503 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Wed, 18 Dec 2024 02:28:14 +0000 Subject: [PATCH 13/34] git subrepo push --branch=master noir-projects/aztec-nr subrepo: subdir: "noir-projects/aztec-nr" merged: "8f1b670dc3" upstream: origin: "https://github.com/AztecProtocol/aztec-nr" branch: "master" commit: "8f1b670dc3" git-subrepo: version: "0.4.6" origin: "???" commit: "???" [skip ci] --- noir-projects/aztec-nr/.gitrepo | 4 ++-- noir-projects/aztec-nr/aztec/Nargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/noir-projects/aztec-nr/.gitrepo b/noir-projects/aztec-nr/.gitrepo index 5af18686bbc..5e54b8ecc1b 100644 --- a/noir-projects/aztec-nr/.gitrepo +++ b/noir-projects/aztec-nr/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/AztecProtocol/aztec-nr branch = master - commit = a234b3c5ac1a38589e7cd51ba6361bfd62b8711c + commit = 8f1b670dc383873499a5f2014a2179e8dbeb131f method = merge cmdver = 0.4.6 - parent = 3fd4275bdbf6c23173359430fe96a62a643c4d77 + parent = 8e3948e6bf38cbadc247d192db06020d5deb3538 diff --git a/noir-projects/aztec-nr/aztec/Nargo.toml b/noir-projects/aztec-nr/aztec/Nargo.toml index b2031323496..7a1f1af5863 100644 --- a/noir-projects/aztec-nr/aztec/Nargo.toml +++ b/noir-projects/aztec-nr/aztec/Nargo.toml @@ -5,4 +5,4 @@ compiler_version = ">=0.18.0" type = "lib" [dependencies] -protocol_types = { git="https://github.com/AztecProtocol/aztec-packages", tag="aztec-packages-v0.67.1", directory="noir-projects/noir-protocol-circuits/crates/types" } +protocol_types = { path = "../../noir-protocol-circuits/crates/types" } From 469476bc73606659da58d492b2640dea4ac924c2 Mon Sep 17 00:00:00 2001 From: maramihali Date: Wed, 18 Dec 2024 09:11:20 +0000 Subject: [PATCH 14/34] fix: remove table shifts (#10814) Table shifts have been obsolete since we moved to a log derivative lookup argument and the table polynomials were still incorrectly considered part of the `to_be_shifted` polynomials set. This PR addresses the issue and, in turn, the proof size because smaller by 4 frs. Additionally, this brings some flavor simplifications. --- .../regenerate_verify_honk_proof_inputs.sh | 2 +- .../acir_tests/sol-test/package-lock.json | 198 ++++++++++++++++++ barretenberg/acir_tests/sol-test/src/index.js | 3 +- barretenberg/acir_tests/sol-test/yarn.lock | 34 +-- barretenberg/cpp/src/barretenberg/bb/main.cpp | 3 + .../commitment_schemes/ipa/ipa.hpp | 68 +++--- .../acir_format/honk_recursion_constraint.cpp | 2 +- .../dsl/acir_proofs/honk_contract.hpp | 22 +- .../protogalaxy/combiner_example_gen.py | 1 - .../ultra_relation_consistency.test.cpp | 18 +- .../stdlib_circuit_builders/mega_flavor.hpp | 67 ++---- .../stdlib_circuit_builders/ultra_flavor.hpp | 65 +----- barretenberg/sol/src/honk/HonkTypes.sol | 8 +- barretenberg/sol/src/honk/Relations.sol | 1 + .../sol/src/honk/instance/Add2Honk.sol | 14 +- .../sol/src/honk/instance/BlakeHonk.sol | 14 +- .../sol/src/honk/instance/EcdsaHonk.sol | 14 +- .../src/honk/keys/Add2HonkVerificationKey.sol | 166 ++++++++------- .../honk/keys/BlakeHonkVerificationKey.sol | 166 ++++++++------- .../honk/keys/EcdsaHonkVerificationKey.sol | 166 ++++++++------- .../src/core/libraries/ConstantsGen.sol | 6 +- .../crates/types/src/constants.nr | 4 +- .../double_verify_honk_proof/Prover.toml | 6 +- .../double_verify_honk_proof/src/main.nr | 2 +- .../verify_honk_proof/Prover.toml | 4 +- .../verify_honk_proof/src/main.nr | 2 +- yarn-project/circuits.js/src/constants.gen.ts | 6 +- 27 files changed, 572 insertions(+), 490 deletions(-) create mode 100644 barretenberg/acir_tests/sol-test/package-lock.json diff --git a/barretenberg/acir_tests/regenerate_verify_honk_proof_inputs.sh b/barretenberg/acir_tests/regenerate_verify_honk_proof_inputs.sh index 57d25637295..da1d1b43496 100755 --- a/barretenberg/acir_tests/regenerate_verify_honk_proof_inputs.sh +++ b/barretenberg/acir_tests/regenerate_verify_honk_proof_inputs.sh @@ -31,7 +31,7 @@ if [ ! -d "$TOML_DIR" ]; then fi echo "Generating recursion inputs and writing to directory $TOML_DIR" -$BIN write_recursion_inputs_honk $VERBOSE -c $CRS_PATH -b ./target/program.json -o "$TOML_DIR" +$BIN write_recursion_inputs_honk --recursive $VERBOSE -c $CRS_PATH -b ./target/program.json -o "$TOML_DIR" cd ../.. ./reset_acir_tests.sh --programs "$RECURSIVE_PROGRAM" \ No newline at end of file diff --git a/barretenberg/acir_tests/sol-test/package-lock.json b/barretenberg/acir_tests/sol-test/package-lock.json new file mode 100644 index 00000000000..020ba3eed74 --- /dev/null +++ b/barretenberg/acir_tests/sol-test/package-lock.json @@ -0,0 +1,198 @@ +{ + "name": "headless-test", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "headless-test", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "ethers": "^6.8.1", + "solc": "^0.8.27" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", + "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==" + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ethers": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.8.1.tgz", + "integrity": "sha512-iEKm6zox5h1lDn6scuRWdIdFJUCGg3+/aQWu0F4K0GVyEZiktFkqrJbRjTn1FlYEPz7RKA707D6g5Kdk6j7Ljg==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@adraffy/ens-normalize": "1.10.0", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solc": { + "version": "0.8.27", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.27.tgz", + "integrity": "sha512-BNxMol2tUAbkH7HKlXBcBqrGi2aqgv+uMHz26mJyTtlVgWmBA4ktiw0qVKHfkjf2oaHbwtbtaSeE2dhn/gTAKw==", + "dependencies": { + "command-exists": "^1.2.8", + "commander": "^8.1.0", + "follow-redirects": "^1.12.1", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solc.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/barretenberg/acir_tests/sol-test/src/index.js b/barretenberg/acir_tests/sol-test/src/index.js index 42749f88d96..ceb1373dd41 100644 --- a/barretenberg/acir_tests/sol-test/src/index.js +++ b/barretenberg/acir_tests/sol-test/src/index.js @@ -4,8 +4,9 @@ import { spawn } from "child_process"; import { ethers } from "ethers"; import solc from "solc"; +// Size excluding number of public inputs const NUMBER_OF_FIELDS_IN_PLONK_PROOF = 93; -const NUMBER_OF_FIELDS_IN_HONK_PROOF = 447; +const NUMBER_OF_FIELDS_IN_HONK_PROOF = 443; // We use the solcjs compiler version in this test, although it is slower than foundry, to run the test end to end // it simplifies of parallelising the test suite diff --git a/barretenberg/acir_tests/sol-test/yarn.lock b/barretenberg/acir_tests/sol-test/yarn.lock index c0a90997654..f8410d95c1a 100644 --- a/barretenberg/acir_tests/sol-test/yarn.lock +++ b/barretenberg/acir_tests/sol-test/yarn.lock @@ -4,44 +4,44 @@ "@adraffy/ens-normalize@1.10.0": version "1.10.0" - resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" + resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz" integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== "@noble/curves@1.2.0": version "1.2.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" + resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz" integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== dependencies: "@noble/hashes" "1.3.2" "@noble/hashes@1.3.2": version "1.3.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz" integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== "@types/node@18.15.13": version "18.15.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + resolved "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz" integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== aes-js@4.0.0-beta.5: version "4.0.0-beta.5" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" + resolved "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz" integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== command-exists@^1.2.8: version "1.2.9" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" + resolved "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz" integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== commander@^8.1.0: version "8.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== ethers@^6.8.1: version "6.8.1" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.8.1.tgz#ee2a1a39b5f62a13678f90ccd879175391d0a2b4" + resolved "https://registry.npmjs.org/ethers/-/ethers-6.8.1.tgz" integrity sha512-iEKm6zox5h1lDn6scuRWdIdFJUCGg3+/aQWu0F4K0GVyEZiktFkqrJbRjTn1FlYEPz7RKA707D6g5Kdk6j7Ljg== dependencies: "@adraffy/ens-normalize" "1.10.0" @@ -54,32 +54,32 @@ ethers@^6.8.1: follow-redirects@^1.12.1: version "1.15.3" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz" integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== js-sha3@0.8.0: version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== memorystream@^0.3.1: version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + resolved "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz" integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== os-tmpdir@~1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== semver@^5.5.0: version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== solc@^0.8.27: version "0.8.27" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.27.tgz#cb8e7246cceadad8df65ceccffe640e106106bb4" + resolved "https://registry.npmjs.org/solc/-/solc-0.8.27.tgz" integrity sha512-BNxMol2tUAbkH7HKlXBcBqrGi2aqgv+uMHz26mJyTtlVgWmBA4ktiw0qVKHfkjf2oaHbwtbtaSeE2dhn/gTAKw== dependencies: command-exists "^1.2.8" @@ -92,17 +92,17 @@ solc@^0.8.27: tmp@0.0.33: version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: os-tmpdir "~1.0.2" tslib@2.4.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== ws@8.5.0: version "8.5.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + resolved "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz" integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== diff --git a/barretenberg/cpp/src/barretenberg/bb/main.cpp b/barretenberg/cpp/src/barretenberg/bb/main.cpp index f4fcba969fb..73f3078c2ba 100644 --- a/barretenberg/cpp/src/barretenberg/bb/main.cpp +++ b/barretenberg/cpp/src/barretenberg/bb/main.cpp @@ -243,6 +243,7 @@ void prove_tube(const std::string& output_path) using Verifier = UltraVerifier_; Prover tube_prover{ *builder }; auto tube_proof = tube_prover.construct_proof(); + info("tube proof length: ", tube_proof.size()); std::string tubeProofPath = output_path + "/proof"; write_file(tubeProofPath, to_buffer(tube_proof)); @@ -883,6 +884,8 @@ void write_vk_for_ivc(const std::string& bytecodePath, const std::string& output * @param witnessPath Path to the file containing the serialized witness * @param outputPath Path to write toml file */ +// TODO(https://github.com/AztecProtocol/barretenberg/issues/1172): update the flow to generate recursion inputs for +// double_verify_honk_proof as well template void write_recursion_inputs_honk(const std::string& bytecodePath, const std::string& witnessPath, diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp index 6c9aea63316..2322375fba3 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp @@ -202,7 +202,7 @@ template class IPA { auto log_poly_length = static_cast(numeric::get_msb(poly_length)); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1159): Decouple constant from IPA. if (log_poly_length > CONST_ECCVM_LOG_N) { - throw_or_abort("IPA log_poly_length is too large"); + throw_or_abort("IPA log_poly_length is too large: " + std::to_string(log_poly_length)); } // Allocate space for L_i and R_i elements @@ -329,7 +329,7 @@ template class IPA { "IPA:poly_degree_plus_1")); // note this is base field because this is a uint32_t, which should map // to a bb::fr, not a grumpkin::fr, which is a BaseField element for // Grumpkin - + // Step 2. // Receive generator challenge u and compute auxiliary generator const Fr generator_challenge = transcript->template get_challenge("IPA:generator_challenge"); @@ -342,7 +342,7 @@ template class IPA { auto log_poly_length = static_cast(numeric::get_msb(poly_length)); if (log_poly_length > CONST_ECCVM_LOG_N) { - throw_or_abort("IPA log_poly_length is too large"); + throw_or_abort("IPA log_poly_length is too large " + std::to_string(log_poly_length)); } // Step 3. // Compute C' = C + f(\beta) ⋅ U @@ -465,7 +465,7 @@ template class IPA { const auto log_poly_length = numeric::get_msb(static_cast(poly_length)); if (log_poly_length > CONST_ECCVM_LOG_N) { - throw_or_abort("IPA log_poly_length is too large"); + throw_or_abort("IPA log_poly_length is too large: " + std::to_string(log_poly_length)); } auto pippenger_size = 2 * CONST_ECCVM_LOG_N; std::vector round_challenges(CONST_ECCVM_LOG_N); @@ -608,7 +608,7 @@ template class IPA { * @todo (https://github.com/AztecProtocol/barretenberg/issues/1018): simulator should use the native verify * function with parallelisation */ - static bool full_verify_recursive(const std::shared_ptr& vk, + static bool full_verify_recursive(const std::shared_ptr& vk, const OpeningClaim& opening_claim, auto& transcript) requires Curve::is_stdlib_type @@ -630,7 +630,7 @@ template class IPA { const auto log_poly_length = numeric::get_msb(static_cast(poly_length)); if (log_poly_length > CONST_ECCVM_LOG_N) { - throw_or_abort("IPA log_poly_length is too large"); + throw_or_abort("IPA log_poly_length is too large: " + std::to_string(log_poly_length)); } auto pippenger_size = 2 * CONST_ECCVM_LOG_N; std::vector round_challenges(CONST_ECCVM_LOG_N); @@ -794,11 +794,11 @@ template class IPA { /** * @brief Evaluates the polynomial created from the challenge scalars u_challenges_inv at a challenge r. - * @details This polynomial is defined as challenge_poly(X) = ∏_{i ∈ [k]} (1 + u_{len-i}^{-1}.X^{2^{i-1}}), + * @details This polynomial is defined as challenge_poly(X) = ∏_{i ∈ [k]} (1 + u_{len-i}^{-1}.X^{2^{i-1}}), * so the evaluation is just ∏_{i ∈ [k]} (1 + u_{len-i}^{-1}.r^{2^{i-1}}). - * @param u_challenges_inv - * @param r - * @return Fr + * @param u_challenges_inv + * @param r + * @return Fr */ static Fr evaluate_challenge_poly(Fr log_poly_length, const std::vector& u_challenges_inv, Fr r) { using Builder = typename Curve::Builder; @@ -807,12 +807,12 @@ template class IPA { Fr challenge_poly_eval = 1; Fr r_pow = r; if (uint32_t(log_poly_length.get_value()) > CONST_ECCVM_LOG_N) { - throw_or_abort("IPA log_poly_length is too large"); + throw_or_abort("IPA log_poly_length is too large: " + std::to_string(uint32_t(log_poly_length.get_value()))); } for (size_t i = 0; i < CONST_ECCVM_LOG_N; i++) { // TODO(https://github.com/AztecProtocol/barretenberg/issues/1114): insecure dummy_round derivation! stdlib::bool_t dummy_round = stdlib::witness_t(builder, i < CONST_ECCVM_LOG_N - uint32_t(log_poly_length.get_value())); - + Fr monomial = Fr::conditional_assign(dummy_round, Fr(0), u_challenges_inv[CONST_ECCVM_LOG_N - 1 - i] * r_pow); challenge_poly_eval *= (Fr(1) + monomial); @@ -823,12 +823,12 @@ template class IPA { /** * @brief Combines the challenge_poly evaluations using the challenge alpha. - * - * @param u_challenges_inv_1 - * @param u_challenges_inv_2 - * @param r - * @param alpha - * @return Fr + * + * @param u_challenges_inv_1 + * @param u_challenges_inv_2 + * @param r + * @param alpha + * @return Fr */ static Fr evaluate_and_accumulate_challenge_polys(Fr log_poly_length_1, std::vector u_challenges_inv_1, Fr log_poly_length_2, std::vector u_challenges_inv_2, Fr r, Fr alpha) { auto result = evaluate_challenge_poly(log_poly_length_1, u_challenges_inv_1, r) + alpha * evaluate_challenge_poly(log_poly_length_2, u_challenges_inv_2, r); @@ -837,9 +837,9 @@ template class IPA { /** * @brief Constructs challenge_poly(X) = ∏_{i ∈ [k]} (1 + u_{len-i}^{-1}.X^{2^{i-1}}). - * - * @param u_challenges_inv - * @return Polynomial + * + * @param u_challenges_inv + * @return Polynomial */ static Polynomial construct_poly_from_u_challenges_inv(const size_t log_poly_length, const std::span& u_challenges_inv) { const size_t poly_length = (1 << log_poly_length); @@ -874,11 +874,11 @@ template class IPA { /** * @brief Combines two challenge_polys using the challenge alpha. - * - * @param u_challenges_inv_1 - * @param u_challenges_inv_2 - * @param alpha - * @return Polynomial + * + * @param u_challenges_inv_1 + * @param u_challenges_inv_2 + * @param alpha + * @return Polynomial */ static Polynomial create_challenge_poly(const size_t log_poly_length_1, const std::vector& u_challenges_inv_1, const size_t log_poly_length_2, const std::vector& u_challenges_inv_2, bb::fq alpha) { // Always extend each to 1< class IPA { * @brief Takes two IPA claims and accumulates them into 1 IPA claim. Also computes IPA proof for the claim. * @details We create an IPA accumulator by running the IPA recursive verifier on each claim. Then, we generate challenges, and use these challenges to compute the new accumulator. We also create the accumulated polynomial, and generate the IPA proof for the accumulated claim. * More details are described here: https://hackmd.io/IXoLIPhVT_ej8yhZ_Ehvuw?both. - * - * @param verifier_ck - * @param transcript_1 - * @param claim_1 - * @param transcript_2 - * @param claim_2 - * @return std::pair, HonkProof> + * + * @param verifier_ck + * @param transcript_1 + * @param claim_1 + * @param transcript_2 + * @param claim_2 + * @return std::pair, HonkProof> */ static std::pair, HonkProof> accumulate(const std::shared_ptr>& ck, auto& transcript_1, OpeningClaim claim_1, auto& transcript_2, OpeningClaim claim_2) requires Curve::is_stdlib_type @@ -936,7 +936,7 @@ template class IPA { for (Fr u_inv_i : pair_2.u_challenges_inv) { native_u_challenges_inv_2.push_back(bb::fq(u_inv_i.get_value())); } - + // Compute proof for the claim auto prover_transcript = std::make_shared(); const OpeningPair opening_pair{ bb::fq(output_claim.opening_pair.challenge.get_value()), diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp index c79535ad7d4..4e34694eb2d 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.cpp @@ -250,7 +250,7 @@ HonkRecursionConstraintOutput create_honk_recursion_constraints( HonkRecursionConstraintOutput output; if (is_rollup_honk_recursion_constraint) { // TODO(https://github.com/AztecProtocol/barretenberg/issues/1168): Add formula to flavor - const size_t HONK_PROOF_LENGTH = 473; + const size_t HONK_PROOF_LENGTH = 469; // The extra calculation is for the IPA proof length. ASSERT(input.proof.size() == HONK_PROOF_LENGTH + 1 + 4 * (CONST_ECCVM_LOG_N) + 2 + 2); ASSERT(proof_fields.size() == HONK_PROOF_LENGTH + 65 + input.public_inputs.size()); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp index 95e37c1fbeb..e074cb956bf 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp @@ -147,9 +147,9 @@ uint256 constant CONST_PROOF_SIZE_LOG_N = 28; uint256 constant NUMBER_OF_SUBRELATIONS = 26; uint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8; -uint256 constant NUMBER_OF_ENTITIES = 44; +uint256 constant NUMBER_OF_ENTITIES = 40; uint256 constant NUMBER_UNSHIFTED = 35; -uint256 constant NUMBER_TO_BE_SHIFTED = 9; +uint256 constant NUMBER_TO_BE_SHIFTED = 5; // Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1 uint256 constant NUMBER_OF_ALPHAS = 25; @@ -195,10 +195,6 @@ enum WIRE { LOOKUP_INVERSES, LOOKUP_READ_COUNTS, LOOKUP_READ_TAGS, - TABLE_1_SHIFT, - TABLE_2_SHIFT, - TABLE_3_SHIFT, - TABLE_4_SHIFT, W_L_SHIFT, W_R_SHIFT, W_O_SHIFT, @@ -1691,15 +1687,11 @@ contract HonkVerifier is IVerifier commitments[35] = convertProofPoint(proof.lookupReadTags); // to be Shifted - commitments[36] = vk.t1; - commitments[37] = vk.t2; - commitments[38] = vk.t3; - commitments[39] = vk.t4; - commitments[40] = convertProofPoint(proof.w1); - commitments[41] = convertProofPoint(proof.w2); - commitments[42] = convertProofPoint(proof.w3); - commitments[43] = convertProofPoint(proof.w4); - commitments[44] = convertProofPoint(proof.zPerm); + commitments[36] = convertProofPoint(proof.w1); + commitments[37] = convertProofPoint(proof.w2); + commitments[38] = convertProofPoint(proof.w3); + commitments[39] = convertProofPoint(proof.w4); + commitments[40] = convertProofPoint(proof.zPerm); /* Batch gemini claims from the prover * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/combiner_example_gen.py b/barretenberg/cpp/src/barretenberg/protogalaxy/combiner_example_gen.py index 19577972e5b..69a66a79e03 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/combiner_example_gen.py +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/combiner_example_gen.py @@ -23,7 +23,6 @@ def __init__(self, base_poly): 'secondary_calldata', 'secondary_calldata_read_counts', 'secondary_calldata_read_tags', 'secondary_calldata_inverses', 'return_data', 'return_data_read_counts', 'return_data_read_tags', 'return_data_inverses', - 'table_1_shift', 'table_2_shift', 'table_3_shift', 'table_4_shift', 'w_l_shift', 'w_r_shift', 'w_o_shift', 'w_4_shift', 'z_perm_shift' ] diff --git a/barretenberg/cpp/src/barretenberg/relations/ultra_relation_consistency.test.cpp b/barretenberg/cpp/src/barretenberg/relations/ultra_relation_consistency.test.cpp index b40b45da3c6..981bb789209 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ultra_relation_consistency.test.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/ultra_relation_consistency.test.cpp @@ -82,17 +82,13 @@ struct InputElements { FF& sorted_accum = std::get<31>(_data); FF& z_perm = std::get<32>(_data); FF& z_lookup = std::get<33>(_data); - FF& table_1_shift = std::get<34>(_data); - FF& table_2_shift = std::get<35>(_data); - FF& table_3_shift = std::get<36>(_data); - FF& table_4_shift = std::get<37>(_data); - FF& w_l_shift = std::get<38>(_data); - FF& w_r_shift = std::get<39>(_data); - FF& w_o_shift = std::get<40>(_data); - FF& w_4_shift = std::get<41>(_data); - FF& sorted_accum_shift = std::get<42>(_data); - FF& z_perm_shift = std::get<43>(_data); - FF& z_lookup_shift = std::get<44>(_data); + FF& w_l_shift = std::get<34>(_data); + FF& w_r_shift = std::get<35>(_data); + FF& w_o_shift = std::get<36>(_data); + FF& w_4_shift = std::get<37>(_data); + FF& sorted_accum_shift = std::get<38>(_data); + FF& z_perm_shift = std::get<39>(_data); + FF& z_lookup_shift = std::get<40>(_data); }; class UltraRelationConsistency : public testing::Test { diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp index 24919feb257..6035a698fe3 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -43,7 +43,7 @@ class MegaFlavor { static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`. - static constexpr size_t NUM_ALL_ENTITIES = 63; + static constexpr size_t NUM_ALL_ENTITIES = 59; // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying // assignment of witnesses. We again choose a neutral name. static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 30; @@ -53,13 +53,9 @@ class MegaFlavor { static constexpr size_t NUM_FOLDED_ENTITIES = NUM_PRECOMPUTED_ENTITIES + NUM_WITNESS_ENTITIES; // The number of shifted witness entities including derived witness entities static constexpr size_t NUM_SHIFTED_WITNESSES = 5; - // The number of shifted tables - static constexpr size_t NUM_SHIFTED_TABLES = 4; - static constexpr RepeatedCommitmentsData REPEATED_COMMITMENTS = - RepeatedCommitmentsData(NUM_PRECOMPUTED_ENTITIES, - NUM_PRECOMPUTED_ENTITIES + NUM_WITNESS_ENTITIES + NUM_SHIFTED_TABLES, - NUM_SHIFTED_WITNESSES); + static constexpr RepeatedCommitmentsData REPEATED_COMMITMENTS = RepeatedCommitmentsData( + NUM_PRECOMPUTED_ENTITIES, NUM_PRECOMPUTED_ENTITIES + NUM_WITNESS_ENTITIES, NUM_SHIFTED_WITNESSES); // define the tuple of Relations that comprise the Sumcheck relation // Note: made generic for use in MegaRecursive. @@ -237,7 +233,10 @@ class MegaFlavor { this->return_data_inverses, }; } - auto get_to_be_shifted() { return DerivedEntities::get_to_be_shifted(); } + auto get_to_be_shifted() + { + return concatenate(WireEntities::get_all(), DerivedEntities::get_to_be_shifted()); + } MSGPACK_FIELDS(this->w_l, this->w_r, @@ -266,9 +265,9 @@ class MegaFlavor { }; /** - * @brief Class for ShiftedWitnessEntities, containing only shifted witness polynomials. + * @brief Class for ShiftedEntities, containing the shifted witness polynomials. */ - template class ShiftedWitnessEntities { + template class ShiftedEntities { public: DEFINE_FLAVOR_MEMBERS(DataType, w_l_shift, // column 0 @@ -277,33 +276,7 @@ class MegaFlavor { w_4_shift, // column 3 z_perm_shift) // column 4 - auto get_shifted_witnesses() { return RefArray{ w_l_shift, w_r_shift, w_o_shift, w_4_shift, z_perm_shift }; }; - }; - - /** - * @brief Class for ShiftedEntities, containing shifted witness and table polynomials. - * TODO: Remove NUM_SHIFTED_TABLES once these entities are deprecated. - */ - template class ShiftedTables { - public: - DEFINE_FLAVOR_MEMBERS(DataType, - table_1_shift, // column 0 - table_2_shift, // column 1 - table_3_shift, // column 2 - table_4_shift // column 3 - ) - }; - - /** - * @brief Class for ShiftedEntities, containing shifted witness and table polynomials. - */ - template - class ShiftedEntities : public ShiftedTables, public ShiftedWitnessEntities { - public: - DEFINE_COMPOUND_GET_ALL(ShiftedTables, ShiftedWitnessEntities) - - auto get_shifted_witnesses() { return ShiftedWitnessEntities::get_all(); }; - auto get_shifted_tables() { return ShiftedTables::get_all(); }; + auto get_shifted() { return RefArray{ w_l_shift, w_r_shift, w_o_shift, w_4_shift, z_perm_shift }; }; }; public: @@ -336,29 +309,15 @@ class MegaFlavor { }; auto get_precomputed() { return PrecomputedEntities::get_all(); } auto get_witness() { return WitnessEntities::get_all(); }; - auto get_to_be_shifted() - { - return concatenate(PrecomputedEntities::get_table_polynomials(), - WitnessEntities::get_wires(), - WitnessEntities::get_to_be_shifted()); - }; + auto get_to_be_shifted() { return WitnessEntities::get_to_be_shifted(); }; auto get_shifted() { return ShiftedEntities::get_all(); }; - // getter for shifted witnesses - auto get_shifted_witnesses() { return ShiftedWitnessEntities::get_all(); }; - // getter for shifted tables - auto get_shifted_tables() { return ShiftedEntities::get_shifted_tables(); }; // this getter is used in ZK Sumcheck, where all witness evaluations (including shifts) have to be masked auto get_all_witnesses() { - return concatenate(WitnessEntities::get_all(), - ShiftedEntities::get_shifted_witnesses()); + return concatenate(WitnessEntities::get_all(), ShiftedEntities::get_all()); }; // getter for the complement of all witnesses inside all entities - auto get_non_witnesses() - { - return concatenate(PrecomputedEntities::get_all(), - ShiftedEntities::get_shifted_tables()); - }; + auto get_non_witnesses() { return PrecomputedEntities::get_all(); }; }; /** diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp index f34d0b48733..bfa61280c64 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp @@ -42,7 +42,7 @@ class UltraFlavor { // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (witness polynomials, // precomputed polynomials and shifts). We often need containers of this size to hold related data, so we choose a // name more agnostic than `NUM_POLYNOMIALS`. - static constexpr size_t NUM_ALL_ENTITIES = 44; + static constexpr size_t NUM_ALL_ENTITIES = 40; // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying // assignment of witnesses. We again choose a neutral name. static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 27; @@ -52,14 +52,10 @@ class UltraFlavor { static constexpr size_t NUM_FOLDED_ENTITIES = NUM_PRECOMPUTED_ENTITIES + NUM_WITNESS_ENTITIES; // The number of shifted witness entities including derived witness entities static constexpr size_t NUM_SHIFTED_WITNESSES = 5; - // The number of shifted tables - static constexpr size_t NUM_SHIFTED_TABLES = 4; // A container to be fed to ShpleminiVerifier to avoid redundant scalar muls - static constexpr RepeatedCommitmentsData REPEATED_COMMITMENTS = - RepeatedCommitmentsData(NUM_PRECOMPUTED_ENTITIES, - NUM_PRECOMPUTED_ENTITIES + NUM_WITNESS_ENTITIES + NUM_SHIFTED_TABLES, - NUM_SHIFTED_WITNESSES); + static constexpr RepeatedCommitmentsData REPEATED_COMMITMENTS = RepeatedCommitmentsData( + NUM_PRECOMPUTED_ENTITIES, NUM_PRECOMPUTED_ENTITIES + NUM_WITNESS_ENTITIES, NUM_SHIFTED_WITNESSES); // The total number of witnesses including shifts and derived entities. static constexpr size_t NUM_ALL_WITNESS_ENTITIES = NUM_WITNESS_ENTITIES + NUM_SHIFTED_WITNESSES; @@ -183,15 +179,15 @@ class UltraFlavor { lookup_read_tags) // column 7 auto get_wires() { return RefArray{ w_l, w_r, w_o, w_4 }; }; - auto get_to_be_shifted() { return RefArray{ z_perm }; }; + auto get_to_be_shifted() { return RefArray{ w_l, w_r, w_o, w_4, z_perm }; }; MSGPACK_FIELDS(w_l, w_r, w_o, w_4, z_perm, lookup_inverses, lookup_read_counts, lookup_read_tags); }; /** - * @brief Class for ShiftedWitnessEntities, containing only shifted witness polynomials. + * @brief Class for ShitftedEntities, containing shifted witness polynomials. */ - template class ShiftedWitnessEntities { + template class ShiftedEntities { public: DEFINE_FLAVOR_MEMBERS(DataType, w_l_shift, // column 0 @@ -200,33 +196,7 @@ class UltraFlavor { w_4_shift, // column 3 z_perm_shift) // column 4 - auto get_shifted_witnesses() { return RefArray{ w_l_shift, w_r_shift, w_o_shift, w_4_shift, z_perm_shift }; }; - }; - - /** - * @brief Class for ShiftedEntities, containing shifted witness and table polynomials. - * TODO: Remove NUM_SHIFTED_TABLES once these entities are deprecated. - */ - template class ShiftedTables { - public: - DEFINE_FLAVOR_MEMBERS(DataType, - table_1_shift, // column 0 - table_2_shift, // column 1 - table_3_shift, // column 2 - table_4_shift // column 3 - ) - }; - - /** - * @brief Class for ShiftedEntities, containing shifted witness and table polynomials. - */ - template - class ShiftedEntities : public ShiftedTables, public ShiftedWitnessEntities { - public: - DEFINE_COMPOUND_GET_ALL(ShiftedTables, ShiftedWitnessEntities) - - auto get_shifted_witnesses() { return ShiftedWitnessEntities::get_all(); }; - auto get_shifted_tables() { return ShiftedTables::get_all(); }; + auto get_shifted() { return RefArray{ w_l_shift, w_r_shift, w_o_shift, w_4_shift, z_perm_shift }; }; }; /** @@ -258,30 +228,15 @@ class UltraFlavor { }; auto get_precomputed() { return PrecomputedEntities::get_all(); } auto get_witness() { return WitnessEntities::get_all(); }; - auto get_to_be_shifted() - { - return concatenate(PrecomputedEntities::get_table_polynomials(), - WitnessEntities::get_wires(), - WitnessEntities::get_to_be_shifted()); - }; + auto get_to_be_shifted() { return WitnessEntities::get_to_be_shifted(); }; - auto get_shifted() { return ShiftedEntities::get_all(); }; - // getter for shifted witnesses - auto get_shifted_witnesses() { return ShiftedEntities::get_shifted_witnesses(); }; - // getter for shifted tables - auto get_shifted_tables() { return ShiftedEntities::get_shifted_tables(); }; // getter for all witnesses including shifted ones auto get_all_witnesses() { - return concatenate(WitnessEntities::get_all(), - ShiftedEntities::get_shifted_witnesses()); + return concatenate(WitnessEntities::get_all(), ShiftedEntities::get_shifted()); }; // getter for the complement of all witnesses inside all entities - auto get_non_witnesses() - { - return concatenate(PrecomputedEntities::get_all(), - ShiftedEntities::get_shifted_tables()); - }; + auto get_non_witnesses() { return PrecomputedEntities::get_all(); }; }; /** diff --git a/barretenberg/sol/src/honk/HonkTypes.sol b/barretenberg/sol/src/honk/HonkTypes.sol index 55176738d07..abe8e1f4612 100644 --- a/barretenberg/sol/src/honk/HonkTypes.sol +++ b/barretenberg/sol/src/honk/HonkTypes.sol @@ -10,9 +10,9 @@ uint256 constant CONST_PROOF_SIZE_LOG_N = 28; uint256 constant NUMBER_OF_SUBRELATIONS = 26; uint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8; -uint256 constant NUMBER_OF_ENTITIES = 44; +uint256 constant NUMBER_OF_ENTITIES = 40; uint256 constant NUMBER_UNSHIFTED = 35; -uint256 constant NUMBER_TO_BE_SHIFTED = 9; +uint256 constant NUMBER_TO_BE_SHIFTED = 5; // Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1 uint256 constant NUMBER_OF_ALPHAS = 25; @@ -54,10 +54,6 @@ enum WIRE { LOOKUP_INVERSES, LOOKUP_READ_COUNTS, LOOKUP_READ_TAGS, - TABLE_1_SHIFT, - TABLE_2_SHIFT, - TABLE_3_SHIFT, - TABLE_4_SHIFT, W_L_SHIFT, W_R_SHIFT, W_O_SHIFT, diff --git a/barretenberg/sol/src/honk/Relations.sol b/barretenberg/sol/src/honk/Relations.sol index 9ca4868cc44..251dbe8245a 100644 --- a/barretenberg/sol/src/honk/Relations.sol +++ b/barretenberg/sol/src/honk/Relations.sol @@ -57,6 +57,7 @@ library RelationsLib { * Ultra Arithmetic Relation * */ + function accumulateArithmeticRelation( Fr[NUMBER_OF_ENTITIES] memory p, Fr[NUMBER_OF_SUBRELATIONS] memory evals, diff --git a/barretenberg/sol/src/honk/instance/Add2Honk.sol b/barretenberg/sol/src/honk/instance/Add2Honk.sol index 00e26a8ca1b..0d0f124102e 100644 --- a/barretenberg/sol/src/honk/instance/Add2Honk.sol +++ b/barretenberg/sol/src/honk/instance/Add2Honk.sol @@ -309,15 +309,11 @@ contract Add2HonkVerifier is IVerifier { commitments[35] = convertProofPoint(proof.lookupReadTags); // to be Shifted - commitments[36] = vk.t1; - commitments[37] = vk.t2; - commitments[38] = vk.t3; - commitments[39] = vk.t4; - commitments[40] = convertProofPoint(proof.w1); - commitments[41] = convertProofPoint(proof.w2); - commitments[42] = convertProofPoint(proof.w3); - commitments[43] = convertProofPoint(proof.w4); - commitments[44] = convertProofPoint(proof.zPerm); + commitments[36] = convertProofPoint(proof.w1); + commitments[37] = convertProofPoint(proof.w2); + commitments[38] = convertProofPoint(proof.w3); + commitments[39] = convertProofPoint(proof.w4); + commitments[40] = convertProofPoint(proof.zPerm); /* Batch gemini claims from the prover * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from diff --git a/barretenberg/sol/src/honk/instance/BlakeHonk.sol b/barretenberg/sol/src/honk/instance/BlakeHonk.sol index 6e617946e06..2d52e2513d8 100644 --- a/barretenberg/sol/src/honk/instance/BlakeHonk.sol +++ b/barretenberg/sol/src/honk/instance/BlakeHonk.sol @@ -310,15 +310,11 @@ contract BlakeHonkVerifier is IVerifier { commitments[35] = convertProofPoint(proof.lookupReadTags); // to be Shifted - commitments[36] = vk.t1; - commitments[37] = vk.t2; - commitments[38] = vk.t3; - commitments[39] = vk.t4; - commitments[40] = convertProofPoint(proof.w1); - commitments[41] = convertProofPoint(proof.w2); - commitments[42] = convertProofPoint(proof.w3); - commitments[43] = convertProofPoint(proof.w4); - commitments[44] = convertProofPoint(proof.zPerm); + commitments[36] = convertProofPoint(proof.w1); + commitments[37] = convertProofPoint(proof.w2); + commitments[38] = convertProofPoint(proof.w3); + commitments[39] = convertProofPoint(proof.w4); + commitments[40] = convertProofPoint(proof.zPerm); /* Batch gemini claims from the prover * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from diff --git a/barretenberg/sol/src/honk/instance/EcdsaHonk.sol b/barretenberg/sol/src/honk/instance/EcdsaHonk.sol index 6d8a4a39c02..acd2a04f518 100644 --- a/barretenberg/sol/src/honk/instance/EcdsaHonk.sol +++ b/barretenberg/sol/src/honk/instance/EcdsaHonk.sol @@ -312,15 +312,11 @@ contract EcdsaHonkVerifier is IVerifier { commitments[35] = convertProofPoint(proof.lookupReadTags); // to be Shifted - commitments[36] = vk.t1; - commitments[37] = vk.t2; - commitments[38] = vk.t3; - commitments[39] = vk.t4; - commitments[40] = convertProofPoint(proof.w1); - commitments[41] = convertProofPoint(proof.w2); - commitments[42] = convertProofPoint(proof.w3); - commitments[43] = convertProofPoint(proof.w4); - commitments[44] = convertProofPoint(proof.zPerm); + commitments[36] = convertProofPoint(proof.w1); + commitments[37] = convertProofPoint(proof.w2); + commitments[38] = convertProofPoint(proof.w3); + commitments[39] = convertProofPoint(proof.w4); + commitments[40] = convertProofPoint(proof.zPerm); /* Batch gemini claims from the prover * place the commitments to gemini aᵢ to the vector of commitments, compute the contributions from diff --git a/barretenberg/sol/src/honk/keys/Add2HonkVerificationKey.sol b/barretenberg/sol/src/honk/keys/Add2HonkVerificationKey.sol index 2402e0a4069..2317f2a511f 100644 --- a/barretenberg/sol/src/honk/keys/Add2HonkVerificationKey.sol +++ b/barretenberg/sol/src/honk/keys/Add2HonkVerificationKey.sol @@ -2,125 +2,123 @@ // Copyright 2022 Aztec pragma solidity >=0.8.21; -import {Honk} from "../HonkTypes.sol"; - +import { Honk } from "../HonkTypes.sol"; uint256 constant N = 32; uint256 constant LOG_N = 5; uint256 constant NUMBER_OF_PUBLIC_INPUTS = 3; - library Add2HonkVerificationKey { function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) { Honk.VerificationKey memory vk = Honk.VerificationKey({ circuitSize: uint256(32), logCircuitSize: uint256(5), publicInputsSize: uint256(3), - ql: Honk.G1Point({ - x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce), - y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854) + ql: Honk.G1Point({ + x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce), + y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854) }), - qr: Honk.G1Point({ - x: uint256(0x291338e99e7857222c76c5e4ba8b954f5fde09fd2f05634d622ba379657cd501), - y: uint256(0x137030ce3236d7c12307adf650a73b87fc95a774ec43ac0a3a341ef26b7f56c9) + qr: Honk.G1Point({ + x: uint256(0x291338e99e7857222c76c5e4ba8b954f5fde09fd2f05634d622ba379657cd501), + y: uint256(0x137030ce3236d7c12307adf650a73b87fc95a774ec43ac0a3a341ef26b7f56c9) }), - qo: Honk.G1Point({ - x: uint256(0x0f90f4bb16b330b82ef51e7ce3f70a9310ea2d3c5ef855f07b6f58081b5ef41f), - y: uint256(0x0e09412eea75978da57db1d3fa6b7d14c0e282c378be9a6d0efc5770863ed70b) + qo: Honk.G1Point({ + x: uint256(0x0f90f4bb16b330b82ef51e7ce3f70a9310ea2d3c5ef855f07b6f58081b5ef41f), + y: uint256(0x0e09412eea75978da57db1d3fa6b7d14c0e282c378be9a6d0efc5770863ed70b) }), - q4: Honk.G1Point({ - x: uint256(0x1eec247154ced5c29b0836528d7c19eda11399dc21e23df4bee4b5cd0bec659f), - y: uint256(0x107cc382fdee2f6530d39b072a2bc50bdb0c0ac4b054a905b03b9d53bebef404) + q4: Honk.G1Point({ + x: uint256(0x1eec247154ced5c29b0836528d7c19eda11399dc21e23df4bee4b5cd0bec659f), + y: uint256(0x107cc382fdee2f6530d39b072a2bc50bdb0c0ac4b054a905b03b9d53bebef404) }), - qm: Honk.G1Point({ - x: uint256(0x0c17b7ba3864cabe287a2b121b5cb3f8ee4ede87a7f656b8d9b470be025007c8), - y: uint256(0x09590397bf354089980bd40f5d84f4c12faa8b4646425fa660ab7c4c76fb4859) + qm: Honk.G1Point({ + x: uint256(0x0c17b7ba3864cabe287a2b121b5cb3f8ee4ede87a7f656b8d9b470be025007c8), + y: uint256(0x09590397bf354089980bd40f5d84f4c12faa8b4646425fa660ab7c4c76fb4859) }), - qc: Honk.G1Point({ - x: uint256(0x2ac1a00b4c9bb4e7deef8d7a6bf9e26e61f2b935409e41c5770c074303b6d142), - y: uint256(0x192d962de288fb26f3d68052b2f475e884ca47e595de1184171cd1500249fa66) + qc: Honk.G1Point({ + x: uint256(0x2ac1a00b4c9bb4e7deef8d7a6bf9e26e61f2b935409e41c5770c074303b6d142), + y: uint256(0x192d962de288fb26f3d68052b2f475e884ca47e595de1184171cd1500249fa66) }), - qArith: Honk.G1Point({ - x: uint256(0x1797e3e7ee9e4f42b42bd375f13f2ccb395b827e9079e999b6c128d9b083c395), - y: uint256(0x101a60efaab1c8564add45d41b9147efacf45941c3efe93c3568bde1e08e1919) + qArith: Honk.G1Point({ + x: uint256(0x1797e3e7ee9e4f42b42bd375f13f2ccb395b827e9079e999b6c128d9b083c395), + y: uint256(0x101a60efaab1c8564add45d41b9147efacf45941c3efe93c3568bde1e08e1919) }), - qDeltaRange: Honk.G1Point({ - x: uint256(0x0e84090add56f2500ab518c655cae63896ea793e6b3f6a14218d476534109610), - y: uint256(0x2b78a584bd6ae88cf4ec7c65c90e0b65df446fdddba972f3c4414ad3c901f4f9) + qDeltaRange: Honk.G1Point({ + x: uint256(0x0e84090add56f2500ab518c655cae63896ea793e6b3f6a14218d476534109610), + y: uint256(0x2b78a584bd6ae88cf4ec7c65c90e0b65df446fdddba972f3c4414ad3c901f4f9) }), - qElliptic: Honk.G1Point({ - x: uint256(0x1bd6129f9646aa21af0d77e7b1cc9794e611b5d59a27773f744710b476fbd30f), - y: uint256(0x2f8d492d76a22b6834f0b88e2d4096139a9d1593d56e65e710b2f344756b721e) + qElliptic: Honk.G1Point({ + x: uint256(0x1bd6129f9646aa21af0d77e7b1cc9794e611b5d59a27773f744710b476fbd30f), + y: uint256(0x2f8d492d76a22b6834f0b88e2d4096139a9d1593d56e65e710b2f344756b721e) }), - qAux: Honk.G1Point({ - x: uint256(0x056ab50282da428d93b17cbd1c81267dcebcfbabdedb47b2d715b5baa6520bff), - y: uint256(0x10b4e7bd9d6d91a57b0695be166ffd27cbeee602bcb5a9ed32c8d9440912cb72) + qAux: Honk.G1Point({ + x: uint256(0x056ab50282da428d93b17cbd1c81267dcebcfbabdedb47b2d715b5baa6520bff), + y: uint256(0x10b4e7bd9d6d91a57b0695be166ffd27cbeee602bcb5a9ed32c8d9440912cb72) }), - qLookup: Honk.G1Point({ - x: uint256(0x19e2d786ebad24caf1bef735441e58525a2f9b5807b2102f295c58cde00f5c97), - y: uint256(0x085713ce7bac807a084a66904ebc6e695840e8cf405a6fd0c325f8bfcf7c2dd8) + qLookup: Honk.G1Point({ + x: uint256(0x19e2d786ebad24caf1bef735441e58525a2f9b5807b2102f295c58cde00f5c97), + y: uint256(0x085713ce7bac807a084a66904ebc6e695840e8cf405a6fd0c325f8bfcf7c2dd8) }), - qPoseidon2External: Honk.G1Point({ - x: uint256(0x0ca0bc4b1cd9eadbbf49eae56a99a4502ef13d965226a634d0981555e4a4da56), - y: uint256(0x1a8a818e6c61f68cefa329f2fabc95c80ad56a538d852f75eda858ed1a616c74) + qPoseidon2External: Honk.G1Point({ + x: uint256(0x0ca0bc4b1cd9eadbbf49eae56a99a4502ef13d965226a634d0981555e4a4da56), + y: uint256(0x1a8a818e6c61f68cefa329f2fabc95c80ad56a538d852f75eda858ed1a616c74) }), - qPoseidon2Internal: Honk.G1Point({ - x: uint256(0x09dfd2992ac1708f0dd1d28c2ad910d9cf21a1510948580f406bc9416113d620), - y: uint256(0x205f76eebda12f565c98c775c4e4f3534b5dcc29e57eed899b1a1a880534dcb9) + qPoseidon2Internal: Honk.G1Point({ + x: uint256(0x09dfd2992ac1708f0dd1d28c2ad910d9cf21a1510948580f406bc9416113d620), + y: uint256(0x205f76eebda12f565c98c775c4e4f3534b5dcc29e57eed899b1a1a880534dcb9) }), - s1: Honk.G1Point({ - x: uint256(0x19a07402ffcc103c3d8fbfbc7e9a660147d7380e65c34f64b75701b8d4868c11), - y: uint256(0x0b7ab8c749a4af75d6100dba9246d7f993748b326d23791a595e21a17653fe30) + s1: Honk.G1Point({ + x: uint256(0x19a07402ffcc103c3d8fbfbc7e9a660147d7380e65c34f64b75701b8d4868c11), + y: uint256(0x0b7ab8c749a4af75d6100dba9246d7f993748b326d23791a595e21a17653fe30) }), - s2: Honk.G1Point({ - x: uint256(0x027234cb39eacbf2ebe98907cf433e429a37933e429d4f24df14274b5c4d2549), - y: uint256(0x2c1ea0996e3fd6cfabcfc6bbd4c86c65fb19c3dda2ded5c4f973af397e8e5c8b) + s2: Honk.G1Point({ + x: uint256(0x027234cb39eacbf2ebe98907cf433e429a37933e429d4f24df14274b5c4d2549), + y: uint256(0x2c1ea0996e3fd6cfabcfc6bbd4c86c65fb19c3dda2ded5c4f973af397e8e5c8b) }), - s3: Honk.G1Point({ - x: uint256(0x243daee8a40861aba1ef660929ee9e874e52cd8e8d75f8c0245852369a731491), - y: uint256(0x0a20f23c0697fb0698478f7a861dde5e18bf5aa34f4731178e74f7460df49a88) + s3: Honk.G1Point({ + x: uint256(0x243daee8a40861aba1ef660929ee9e874e52cd8e8d75f8c0245852369a731491), + y: uint256(0x0a20f23c0697fb0698478f7a861dde5e18bf5aa34f4731178e74f7460df49a88) }), - s4: Honk.G1Point({ - x: uint256(0x18b8202abb615440b5544d88092245911d2b5ff3b5a4a80bb15dbabafdfb56a7), - y: uint256(0x096a6685f36b1ca09a62820ae3be7538128093440fa943ea7412617a6d927916) + s4: Honk.G1Point({ + x: uint256(0x18b8202abb615440b5544d88092245911d2b5ff3b5a4a80bb15dbabafdfb56a7), + y: uint256(0x096a6685f36b1ca09a62820ae3be7538128093440fa943ea7412617a6d927916) }), - t1: Honk.G1Point({ - x: uint256(0x2e0cddbc5712d79b59cb3b41ebbcdd494997477ab161763e46601d95844837ef), - y: uint256(0x303126892f664d8d505964d14315ec426db4c64531d350750df62dbbc41a1bd9) + t1: Honk.G1Point({ + x: uint256(0x004067623374b7c3965c7d8444b57ac2d81269c7eb3cb4f7b16568b2f8234c96), + y: uint256(0x0e605f3ad72203e21301ef1b5333cae1d8063220d1996854beb0c4fbc33bba9d) }), - t2: Honk.G1Point({ - x: uint256(0x00874a5ad262eecc6b565e0b08507476a6b2c6040c0c62bd59acfe3e3e125672), - y: uint256(0x127b2a745a1b74968c3edc18982b9bef082fb517183c9c6841c2b8ef2ca1df04) + t2: Honk.G1Point({ + x: uint256(0x17aafa80bf54a7e6cc66472f9ccd70efa5044207a95191716ba0195b5a432266), + y: uint256(0x233ecaca2ddbebb0484a44e6f55b8c8614c7b5e0ce31b51d59d6b21322a307a1) }), - t3: Honk.G1Point({ - x: uint256(0x15a18748490ff4c2b1871081954e86c9efd4f8c3d56e1eb23d789a8f710d5be6), - y: uint256(0x2097c84955059442a95df075833071a0011ef987dc016ab110eacd554a1d8bbf) + t3: Honk.G1Point({ + x: uint256(0x0f808f231e43f089639e05c235642b43ef91df7b6b2d51f3b34d17450bf4a536), + y: uint256(0x079b5c6882eb75200d55f88b75280a34c2ec6fe94d3660254afc72f390dc7567) }), - t4: Honk.G1Point({ - x: uint256(0x2aecd48089890ea0798eb952c66824d38e9426ad3085b68b00a93c17897c2877), - y: uint256(0x1216bdb2f0d961bb8a7a23331d215078d8a9ce405ce559f441f2e71477ff3ddb) + t4: Honk.G1Point({ + x: uint256(0x0765bf6645e4cf63f05d9b0efd06acebce309c685a3b05e613574ccd7316677c), + y: uint256(0x09770f145625290cdcb08bae4e6f0a26897b5988fbaf9529e0a3326bfdb537ae) }), - id1: Honk.G1Point({ - x: uint256(0x292298ecab24d2b6f6999cac29848def2665a62342170311f44c08708db0fe1f), - y: uint256(0x277022c35d3145de166b139aa94609551122915366ba42ff7c5157b748fb7f9d) + id1: Honk.G1Point({ + x: uint256(0x292298ecab24d2b6f6999cac29848def2665a62342170311f44c08708db0fe1f), + y: uint256(0x277022c35d3145de166b139aa94609551122915366ba42ff7c5157b748fb7f9d) }), - id2: Honk.G1Point({ - x: uint256(0x2ddc6a05ccd584bdfc65d642b39a3be3075e7a370602112dbf9fc644789acace), - y: uint256(0x1a4167481d5f295af9921741bd0e32dda7a78cb391132b31ab4a77559c297c2e) + id2: Honk.G1Point({ + x: uint256(0x2ddc6a05ccd584bdfc65d642b39a3be3075e7a370602112dbf9fc644789acace), + y: uint256(0x1a4167481d5f295af9921741bd0e32dda7a78cb391132b31ab4a77559c297c2e) }), - id3: Honk.G1Point({ - x: uint256(0x19629b85ab2acf9713223ff4f758882af6247963bbf2f6ec4f9cbcde13675b87), - y: uint256(0x165063fe922948bf1d065a882242724c1bde5fdfd93be29586b45e1ce2cc750c) + id3: Honk.G1Point({ + x: uint256(0x19629b85ab2acf9713223ff4f758882af6247963bbf2f6ec4f9cbcde13675b87), + y: uint256(0x165063fe922948bf1d065a882242724c1bde5fdfd93be29586b45e1ce2cc750c) }), - id4: Honk.G1Point({ - x: uint256(0x2493c99a3d068b03f8f2b8d28b57cea3ee22dd60456277b86c32a18982dcb185), - y: uint256(0x1ded39c4c8366469843cd63f09ecacf6c3731486320082c20ec71bbdc92196c1) + id4: Honk.G1Point({ + x: uint256(0x2493c99a3d068b03f8f2b8d28b57cea3ee22dd60456277b86c32a18982dcb185), + y: uint256(0x1ded39c4c8366469843cd63f09ecacf6c3731486320082c20ec71bbdc92196c1) }), - lagrangeFirst: Honk.G1Point({ - x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001), - y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002) + lagrangeFirst: Honk.G1Point({ + x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001), + y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002) }), - lagrangeLast: Honk.G1Point({ - x: uint256(0x140b0936c323fd2471155617b6af56ee40d90bea71fba7a412dd61fcf34e8ceb), - y: uint256(0x2b6c10790a5f6631c87d652e059df42b90071823185c5ff8e440fd3d73b6fefc) + lagrangeLast: Honk.G1Point({ + x: uint256(0x2d855b5b9eda31247e5c717ce51db5b7b0f74ed8027eddb28bb72f061415e49e), + y: uint256(0x1e857d997cc8bd0b6558b670690358ad63520266c81078227f33651c341b7704) }) }); return vk; diff --git a/barretenberg/sol/src/honk/keys/BlakeHonkVerificationKey.sol b/barretenberg/sol/src/honk/keys/BlakeHonkVerificationKey.sol index 0eaeba194f1..e343d875afa 100644 --- a/barretenberg/sol/src/honk/keys/BlakeHonkVerificationKey.sol +++ b/barretenberg/sol/src/honk/keys/BlakeHonkVerificationKey.sol @@ -2,125 +2,123 @@ // Copyright 2022 Aztec pragma solidity >=0.8.21; -import {Honk} from "../HonkTypes.sol"; - +import { Honk } from "../HonkTypes.sol"; uint256 constant N = 32768; uint256 constant LOG_N = 15; uint256 constant NUMBER_OF_PUBLIC_INPUTS = 4; - library BlakeHonkVerificationKey { function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) { Honk.VerificationKey memory vk = Honk.VerificationKey({ circuitSize: uint256(32768), logCircuitSize: uint256(15), publicInputsSize: uint256(4), - ql: Honk.G1Point({ - x: uint256(0x2e5f133c25f7e05bd6660196c892121f7fa686cb9a8717a5deea6cd0881e618e), - y: uint256(0x1189bba9eeea96ba8935052434f4b0a60b0a481e3464dd81dfcd89e23def001b) + ql: Honk.G1Point({ + x: uint256(0x2e5f133c25f7e05bd6660196c892121f7fa686cb9a8717a5deea6cd0881e618e), + y: uint256(0x1189bba9eeea96ba8935052434f4b0a60b0a481e3464dd81dfcd89e23def001b) }), - qr: Honk.G1Point({ - x: uint256(0x2a93ffb34002da94f5b156ba5a212ac3616c848bd9c44c9821bbdd64cfd848af), - y: uint256(0x015699dcc0b28766d45f5ddce8258393e84c40619d26034e76f778460a1e4d89) + qr: Honk.G1Point({ + x: uint256(0x2a93ffb34002da94f5b156ba5a212ac3616c848bd9c44c9821bbdd64cfd848af), + y: uint256(0x015699dcc0b28766d45f5ddce8258393e84c40619d26034e76f778460a1e4d89) }), - qo: Honk.G1Point({ - x: uint256(0x2057928e8c5eb539c32c3025007b7be1e1663c358f59540c6f949794c274f886), - y: uint256(0x12bf0b15c3aa92792330f58b04512714c4a902e537fe87cc438293e1805eaabf) + qo: Honk.G1Point({ + x: uint256(0x2057928e8c5eb539c32c3025007b7be1e1663c358f59540c6f949794c274f886), + y: uint256(0x12bf0b15c3aa92792330f58b04512714c4a902e537fe87cc438293e1805eaabf) }), - q4: Honk.G1Point({ - x: uint256(0x304f47a08d4687afa0e2502a9782c32c458bf873ef50c169b732a367e567aaf3), - y: uint256(0x0bb37044594e7de200408a4db6bc46adf7790b06f17dce6f38b7deed480aa9f0) + q4: Honk.G1Point({ + x: uint256(0x304f47a08d4687afa0e2502a9782c32c458bf873ef50c169b732a367e567aaf3), + y: uint256(0x0bb37044594e7de200408a4db6bc46adf7790b06f17dce6f38b7deed480aa9f0) }), - qm: Honk.G1Point({ - x: uint256(0x0aea5b04332ad8781411f7edde21266857ffe11e93af334b14a2b948429afaa4), - y: uint256(0x2bd2e3884d486b387122effa12e8698daef82e9b99d7d25b7d5df91a9d738495) + qm: Honk.G1Point({ + x: uint256(0x0aea5b04332ad8781411f7edde21266857ffe11e93af334b14a2b948429afaa4), + y: uint256(0x2bd2e3884d486b387122effa12e8698daef82e9b99d7d25b7d5df91a9d738495) }), - qc: Honk.G1Point({ - x: uint256(0x0e3b418ea1924b4514d5009cd983b5a8074fa95cd1fb200f019fdebe944e4225), - y: uint256(0x1e6ef5bde7a9727f1c1d07c91461ae1b40524650b35fdd92ac7a129f263b1beb) + qc: Honk.G1Point({ + x: uint256(0x0e3b418ea1924b4514d5009cd983b5a8074fa95cd1fb200f019fdebe944e4225), + y: uint256(0x1e6ef5bde7a9727f1c1d07c91461ae1b40524650b35fdd92ac7a129f263b1beb) }), - qArith: Honk.G1Point({ - x: uint256(0x096841bfa8ec2295a5af5bf69ec539c31a05b221c84ed1d24c702e31ce1cbc95), - y: uint256(0x10b14cca7e9ff05fcf1e3084f4fc9ab098cf379864b2e2e2e0d33fc5df9d9a50) + qArith: Honk.G1Point({ + x: uint256(0x096841bfa8ec2295a5af5bf69ec539c31a05b221c84ed1d24c702e31ce1cbc95), + y: uint256(0x10b14cca7e9ff05fcf1e3084f4fc9ab098cf379864b2e2e2e0d33fc5df9d9a50) }), - qDeltaRange: Honk.G1Point({ - x: uint256(0x2d27fd1a30a0ab04a05144c27ac41187d5cf89a6022e47b263d1ccb93b3cbea5), - y: uint256(0x238eb233e9aebc81285a2647f2598bab00a4367da47b12c2b0476afc2d94ab1d) + qDeltaRange: Honk.G1Point({ + x: uint256(0x2d27fd1a30a0ab04a05144c27ac41187d5cf89a6022e47b263d1ccb93b3cbea5), + y: uint256(0x238eb233e9aebc81285a2647f2598bab00a4367da47b12c2b0476afc2d94ab1d) }), - qElliptic: Honk.G1Point({ - x: uint256(0x1c6fc8e14453adf64e6d9643ef9f1fb55e3a307ac1ec84f86cd736fc866e05ab), - y: uint256(0x1bf8619b1704b99ab8820ed94dd760da2945e8e1c771c0bdeadbe40aa5700cdd) + qElliptic: Honk.G1Point({ + x: uint256(0x1c6fc8e14453adf64e6d9643ef9f1fb55e3a307ac1ec84f86cd736fc866e05ab), + y: uint256(0x1bf8619b1704b99ab8820ed94dd760da2945e8e1c771c0bdeadbe40aa5700cdd) }), - qAux: Honk.G1Point({ - x: uint256(0x023fe0703623b99c93358348d76eb620f26ceafa58df018e3a8f1d599a61e76f), - y: uint256(0x2ceb9c4c4ca12ea769157ef10cde9644f9f0549805e48d5fd5d73a634d2cdcb5) + qAux: Honk.G1Point({ + x: uint256(0x023fe0703623b99c93358348d76eb620f26ceafa58df018e3a8f1d599a61e76f), + y: uint256(0x2ceb9c4c4ca12ea769157ef10cde9644f9f0549805e48d5fd5d73a634d2cdcb5) }), - qLookup: Honk.G1Point({ - x: uint256(0x1375bbfbf5ed31b38460f46a43ac14e2cda93a3bc5cfd6e8a93cca356694a346), - y: uint256(0x204c5173892c19a97a04b5f8419898063df5136489809ddb9f7eabb58d6858ab) + qLookup: Honk.G1Point({ + x: uint256(0x1375bbfbf5ed31b38460f46a43ac14e2cda93a3bc5cfd6e8a93cca356694a346), + y: uint256(0x204c5173892c19a97a04b5f8419898063df5136489809ddb9f7eabb58d6858ab) }), - qPoseidon2External: Honk.G1Point({ - x: uint256(0x1fa8529236d7eacdab8dcd8169af30d334be103357577353e9ef08dfda841785), - y: uint256(0x055251b013746385e921b4620e55ef4f08b4d8afc4dbca7e6c3ca0f1b52c5a2b) + qPoseidon2External: Honk.G1Point({ + x: uint256(0x1fa8529236d7eacdab8dcd8169af30d334be103357577353e9ef08dfda841785), + y: uint256(0x055251b013746385e921b4620e55ef4f08b4d8afc4dbca7e6c3ca0f1b52c5a2b) }), - qPoseidon2Internal: Honk.G1Point({ - x: uint256(0x1515283648ab8622ac6447f1fcf201a598d8df325279bfac9a6564924df97ee5), - y: uint256(0x0335bb595984ad38686009bca08f5f420e3b4cf888fad5af4a99eca08190a315) + qPoseidon2Internal: Honk.G1Point({ + x: uint256(0x1515283648ab8622ac6447f1fcf201a598d8df325279bfac9a6564924df97ee5), + y: uint256(0x0335bb595984ad38686009bca08f5f420e3b4cf888fad5af4a99eca08190a315) }), - s1: Honk.G1Point({ - x: uint256(0x26cec5ff3eb1b803c52fa1fefaac7a2be5cd13c1a1cc20bb9f22049c7f8597d2), - y: uint256(0x07e80e74eb0e06d7c0c9a3fbbdea4e86e5934faa8142625f175320778bcba65f) + s1: Honk.G1Point({ + x: uint256(0x26cec5ff3eb1b803c52fa1fefaac7a2be5cd13c1a1cc20bb9f22049c7f8597d2), + y: uint256(0x07e80e74eb0e06d7c0c9a3fbbdea4e86e5934faa8142625f175320778bcba65f) }), - s2: Honk.G1Point({ - x: uint256(0x140b2faaf30cb5fc528621f4a395943e7fab8198dc734ac13253dd249682dd2a), - y: uint256(0x12709c4a13428f4704d284c90a81cc83280680185ae6298187e86debcd3e00f7) + s2: Honk.G1Point({ + x: uint256(0x140b2faaf30cb5fc528621f4a395943e7fab8198dc734ac13253dd249682dd2a), + y: uint256(0x12709c4a13428f4704d284c90a81cc83280680185ae6298187e86debcd3e00f7) }), - s3: Honk.G1Point({ - x: uint256(0x0aca5621e9f49279969497b3da0eb8a74c68c3513f4cf98e8b1d6f88567557a8), - y: uint256(0x2664811311f75057a16267bc0479eaeea2424156417cc4d3f8bd286fac9aa5d2) + s3: Honk.G1Point({ + x: uint256(0x0aca5621e9f49279969497b3da0eb8a74c68c3513f4cf98e8b1d6f88567557a8), + y: uint256(0x2664811311f75057a16267bc0479eaeea2424156417cc4d3f8bd286fac9aa5d2) }), - s4: Honk.G1Point({ - x: uint256(0x04417c606a41393e73113ec3f834883dbeb302889199b888c0f5ea58a008ff98), - y: uint256(0x0865670de7962d29b6a9012f28ea52113c4e2b55d7de44e829edec87dba1d5c2) + s4: Honk.G1Point({ + x: uint256(0x04417c606a41393e73113ec3f834883dbeb302889199b888c0f5ea58a008ff98), + y: uint256(0x0865670de7962d29b6a9012f28ea52113c4e2b55d7de44e829edec87dba1d5c2) }), - t1: Honk.G1Point({ - x: uint256(0x1ec1b607634e31421b5047dc99d7674d6505fed978df0f42a3504f9771a8a7fa), - y: uint256(0x1da802c6dc2fe6cffc6f9ae983080c66690ceee40c181b4d51fdba6c5c360297) + t1: Honk.G1Point({ + x: uint256(0x1d4e30cc33125c72bc1a31ebff8c7ba5c5b34c2d3db26658f8f7a4c1a8917596), + y: uint256(0x24b630ad1c505f3a97aa5461310b4a291aa7fa696c1040ecbc0f1d0cab88b1c5) }), - t2: Honk.G1Point({ - x: uint256(0x1e38a0a482b7174f429a3bef25fb0a7656abc88cfd215b8e8404132601620784), - y: uint256(0x2e9ea07a995fa6d589e37fba2715f3f1fa338652ddf84d4e2e4f33dccadb9156) + t2: Honk.G1Point({ + x: uint256(0x14d7f3319ed85d18dcac134fbc88f55a46cef0e5e7a6d02feb1cbff52cfa6e9d), + y: uint256(0x2a8f8123f428e35766ee7e966f24ec27a2633400ede745386475dd10c4c17d2a) }), - t3: Honk.G1Point({ - x: uint256(0x211a0833bb3c6f9ae6c94519b6878ed6157c4a080df786a053d9a19796b9a7f8), - y: uint256(0x1a3a450e1a272aa1fe9f097acf359502ff69df617de4918b37a497def94db2b5) + t3: Honk.G1Point({ + x: uint256(0x11061c55e2e00e034fc719cc1c4caa69e1f30657a6bb0967911e2a760efa4a77), + y: uint256(0x10be7ab8fa1f76943b2cc162dd50e4acd000d9b1ab2a0020abd1267b4b9be410) }), - t4: Honk.G1Point({ - x: uint256(0x281a984aef14716cd5d8fc2759eb8ea2464909b5c57d97b6bc50e4dad74d92d3), - y: uint256(0x169160e1505685aabd5bd60e994bac45162c6868235cc4252c8b87d0f12603fd) + t4: Honk.G1Point({ + x: uint256(0x1154b181349afd6acd7366b4640b40e08dcbebc684265d5308253042542ee558), + y: uint256(0x08bc724f607bcf3fe89b6ae24fb50290667cb2e8f5c12fb905fc86fbec0e0c18) }), - id1: Honk.G1Point({ - x: uint256(0x01c082a85908fea4c69c4e51436fba7d965e1d88e485da16e35d8f4e8af3b8bd), - y: uint256(0x11b0ada021468b059aa6c27f4d4950ef65b98d4d8808ae21718bd8b90f9bb365) + id1: Honk.G1Point({ + x: uint256(0x01c082a85908fea4c69c4e51436fba7d965e1d88e485da16e35d8f4e8af3b8bd), + y: uint256(0x11b0ada021468b059aa6c27f4d4950ef65b98d4d8808ae21718bd8b90f9bb365) }), - id2: Honk.G1Point({ - x: uint256(0x0b8667619755bd09c7970defeae2c920df2b17b41608303ae1d7393615dd04e4), - y: uint256(0x1c5419cd435c5516ac566a9d1dfecdb4e10190c63f2dbd8a1932785caf022e2c) + id2: Honk.G1Point({ + x: uint256(0x0b8667619755bd09c7970defeae2c920df2b17b41608303ae1d7393615dd04e4), + y: uint256(0x1c5419cd435c5516ac566a9d1dfecdb4e10190c63f2dbd8a1932785caf022e2c) }), - id3: Honk.G1Point({ - x: uint256(0x110aee72793c4b4ede92c1375f058b4170fcf01bf18f8f1ee934f7ae0fa26da5), - y: uint256(0x15c4f6a01ff04ef6b5225c896dfb7060a7a2c320395bda410e756d6b507b7eb8) + id3: Honk.G1Point({ + x: uint256(0x110aee72793c4b4ede92c1375f058b4170fcf01bf18f8f1ee934f7ae0fa26da5), + y: uint256(0x15c4f6a01ff04ef6b5225c896dfb7060a7a2c320395bda410e756d6b507b7eb8) }), - id4: Honk.G1Point({ - x: uint256(0x2472aba130e7ed2aefad128109415ec2bdeb56e81e3cbeacc93e00c95f203579), - y: uint256(0x0c867d0f8e2f9c861574383b89020980358d898497f80c198a6c17c2f4daf9a4) + id4: Honk.G1Point({ + x: uint256(0x2472aba130e7ed2aefad128109415ec2bdeb56e81e3cbeacc93e00c95f203579), + y: uint256(0x0c867d0f8e2f9c861574383b89020980358d898497f80c198a6c17c2f4daf9a4) }), - lagrangeFirst: Honk.G1Point({ - x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001), - y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002) + lagrangeFirst: Honk.G1Point({ + x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001), + y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002) }), - lagrangeLast: Honk.G1Point({ - x: uint256(0x13b825e996cc8d600f363dca4481a54d6dd3da85900cd9f0a61fa02600851998), - y: uint256(0x151cb86205f2dc38a5651840c1a4b4928f3f3c98f77c2abd08336562986dc404) + lagrangeLast: Honk.G1Point({ + x: uint256(0x2c3e8add0e69c3bb940ffe92b6d3bdbbe0c8ac0c95866da586d857c73a0556ba), + y: uint256(0x22ed2a9c8e4ee1ecde6e7285f21cb4fe0a23131c9ee50f22e367f7c8cc2ac84a) }) }); return vk; diff --git a/barretenberg/sol/src/honk/keys/EcdsaHonkVerificationKey.sol b/barretenberg/sol/src/honk/keys/EcdsaHonkVerificationKey.sol index 26207d04184..c415f2f717c 100644 --- a/barretenberg/sol/src/honk/keys/EcdsaHonkVerificationKey.sol +++ b/barretenberg/sol/src/honk/keys/EcdsaHonkVerificationKey.sol @@ -2,125 +2,123 @@ // Copyright 2022 Aztec pragma solidity >=0.8.21; -import {Honk} from "../HonkTypes.sol"; - +import { Honk } from "../HonkTypes.sol"; uint256 constant N = 65536; uint256 constant LOG_N = 16; uint256 constant NUMBER_OF_PUBLIC_INPUTS = 6; - library EcdsaHonkVerificationKey { function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) { Honk.VerificationKey memory vk = Honk.VerificationKey({ circuitSize: uint256(65536), logCircuitSize: uint256(16), publicInputsSize: uint256(6), - ql: Honk.G1Point({ - x: uint256(0x051ccdb8069f35f4ef85ad098e95681736a7bed10a7bee1b76a506235dc0b579), - y: uint256(0x05e168c2e4f90231545f5b24c1a84c1419b8798e4235cc2036c9e101e462b71d) + ql: Honk.G1Point({ + x: uint256(0x0d26081764ddeabfed843e3c5557f131e164ef80202b29336be0ee6cd7b8bb09), + y: uint256(0x1f119104ae836c47196ac80dd48d743fe8dbc00b90a732e8850cf39ebc057fd6) }), - qr: Honk.G1Point({ - x: uint256(0x2c99eed1f855cd5152942cc090aabf15308eb00ac549e965eb3e1950479cce58), - y: uint256(0x170bf8541390153bf5807bc022c9369f99d8bc1fd87922a0627b144fec0414e2) + qr: Honk.G1Point({ + x: uint256(0x0a5832561bc20ca6c3bd6a45383192ceea476369cf1409dcc923ad0db043bd1f), + y: uint256(0x191a108202c6f5d4d6b6fae14259b7849ee8e0a483d3aeada8f12c19e6977d30) }), - qo: Honk.G1Point({ - x: uint256(0x1594abb7debcf41e3296178eeec941dbb6242ba13f50f4549734657ee5ebb8b1), - y: uint256(0x262e1469c56c719bdc4eaab93cc95868eed9fea1fa9ded03b46f2c061a341d4f) + qo: Honk.G1Point({ + x: uint256(0x0e8a61ac645f4b74493df26d9e888fcefc3649cc1f6d925a48091faeca3f9cbd), + y: uint256(0x09a0a2a584c84de3e86235217b3a31e40d871a815232c1cfd02343fa03c83e84) }), - q4: Honk.G1Point({ - x: uint256(0x16b49bbcd37e15ed89b2f6f5b97d021abe440ba7cbc69904484991fa7e6058a9), - y: uint256(0x197b14cb5d037642b27ed7cd79b9568e5853ad1e3508453c0ed1f30c1962fd52) + q4: Honk.G1Point({ + x: uint256(0x1dbccae2d56db0ee959d57572c7da6dea1853fbae2bc8fa8c862eb163dae0bb2), + y: uint256(0x2f1f1c14f8a981a256c96e72e8d18393bb11da62223f18cf72fe5639ce9704a4) }), - qm: Honk.G1Point({ - x: uint256(0x175280d74e116a82ad6ccc34f640a5b3dda74b17372c9a0941d57749e37068a6), - y: uint256(0x0827b11a78b8a625ba940983effbcf7354aa0388bd472481c0a8a088653b9769) + qm: Honk.G1Point({ + x: uint256(0x1da7f877a5a897c91204a2c894f8d121c6a054318427025f87556aeba16fff02), + y: uint256(0x0438f74fa9432220b697edfc8be7efd8d9773d6c6208c908db13c41095de5f37) }), - qc: Honk.G1Point({ - x: uint256(0x2a262a7189292da31f3f4a7926c4d9fcae883188aafe9cf3ba2a623f0004a67a), - y: uint256(0x0d90b8808180521422b90889592111434dd5bbc0e5deb27419c1f5e6d0bf9883) + qc: Honk.G1Point({ + x: uint256(0x028fab352dd75db278f199638256453cacbf277e1bdf2e82115e09718a2b26da), + y: uint256(0x2c537e1ee36b91fbd25a6250a37332a93d6bda95890df6d9501d4bea885796b7) }), - qArith: Honk.G1Point({ - x: uint256(0x2026f95bb8f7b6ed57287e4833e2789cce8ec9a95b829e6a2abbf5d13d681d22), - y: uint256(0x19cea5af7d9b39a4ad86a0ab52f8a358f7f35236561a50cdf6f2860f0b3426a8) + qArith: Honk.G1Point({ + x: uint256(0x035c79ae9870ae41757c5e34b582b1c56ede35aaae59ca00404d721d88207e7c), + y: uint256(0x2d4d7bdef0e2cbbc267bb99b645d1626bdf8f42adb4503798a34cae5c09e9f8c) }), - qDeltaRange: Honk.G1Point({ - x: uint256(0x02d0f736b422d74d9aa2ef26deedb67fdd2e798aae001c4292dabd2c5df31249), - y: uint256(0x0ae6265d6dcc9da8d3b23f088c6fb062c9be10bfa79e9d0463d4a7785ea4a5f9) + qDeltaRange: Honk.G1Point({ + x: uint256(0x07de3043acee4e9209cdbc0e4a8b6f6a535b1937f721d39d530e0ce232fa8287), + y: uint256(0x274ff9766cb2ebb15e8971dd046080d167743a825438eb577c1ac5a3cc9c54d6) }), - qElliptic: Honk.G1Point({ - x: uint256(0x0ffa449a9d6e6c6f3e302eb3f16ce9d3d3711b9102ecf0e303ff91f3f9eb25f5), - y: uint256(0x095ef997439bccdd1234b2431a520823bcfe3e77f50190e66e70e2c51e906193) + qElliptic: Honk.G1Point({ + x: uint256(0x1534a28b15c98473424fe8f04b314269e2ceb84b2ba03d9233e5621e392ec778), + y: uint256(0x21383bb1156fec27094fbe8b470bb9bd38f09050b54000b9e8210d495c303c50) }), - qAux: Honk.G1Point({ - x: uint256(0x09023d45c436e756762d8b3527cfcb3f694cdbafd192ccae59210740bdf03ad3), - y: uint256(0x020c9b591603814f1815038e25d1bb3fb85261bf699abfc8921f48954f0bc2b0) + qAux: Honk.G1Point({ + x: uint256(0x12d0e6d9b6385ab7ecd2dca74f9bb94f6242c9182d64ec7b243c364e3ab623b2), + y: uint256(0x1c2ccee3dfb933fd21007ac4fb913c021d4f606373c172cb7f65e7b65c8a19a9) }), - qLookup: Honk.G1Point({ - x: uint256(0x08c0d34ca72136661975f3b1ad658bfda38661b9ff320b60e2974496e03fd62e), - y: uint256(0x236caf48f4c3a7ca207f5c0ec75f304657e49780015cf40ff9be37f8ba3c6624) + qLookup: Honk.G1Point({ + x: uint256(0x0c1d4485ea10a2e7ac60989c6b89adb46cfe368c3aea2e98dd23dda8c0177eeb), + y: uint256(0x2ec88245a56ced2a57fd11e8a75055c828da386b922da330779817f4c389a7ea) }), - qPoseidon2External: Honk.G1Point({ - x: uint256(0x09d58ddd055d3d65b4f36a347c18c11956b7d43c4f15434ded62bdf1224ff37d), - y: uint256(0x3002f0782d68214149ae47ee94771a6509709499ca06a8421eeeae97ea37e2a9) + qPoseidon2External: Honk.G1Point({ + x: uint256(0x2c1c2ccda8b91666f7bd30eb4a992c3e4c729adcf73e008348e8c97083d56242), + y: uint256(0x2b418829be00d02f2e01a1fbf110420b328a44416e889990f1e81b735023ff1d) }), - qPoseidon2Internal: Honk.G1Point({ - x: uint256(0x1d11dbf6b2ced628ad64ea9d8afef60b6ea2e246160b6525915eb0ab7bdc94aa), - y: uint256(0x1ecef8438441a2565ee641757bdc6739da7389d913453eee0aaac561fb08495c) + qPoseidon2Internal: Honk.G1Point({ + x: uint256(0x1f60a709d42d5e2c7b406365072a764300c610a5a8d2be21f9a0242dde7bd485), + y: uint256(0x2c5af44525879b9580e7687e6a93dd55fd6aa9251d90a5c2c4fc0ea971e1448b) }), - s1: Honk.G1Point({ - x: uint256(0x105eb99bfd557812572f2a5ec5b6eff27375b4ed5ce4e7a9649fe3038cfacbac), - y: uint256(0x1efd910252f319f9c0dc21c7688b92d80fd0a8636f152e0d9c8e0afb5c9a6d2e) + s1: Honk.G1Point({ + x: uint256(0x282bd3a32dfbf5fcb1123602ee8bb334fcae9fe4d32fcffe565701fea25c84da), + y: uint256(0x26d6de44e383b5cfcb046b54d5b88b4c840f85bf6b355de813cfc82946b01696) }), - s2: Honk.G1Point({ - x: uint256(0x2bbbf5e8a2f7feb08ee64585bf3da54db0da09b211f726adda93020a2ae23e56), - y: uint256(0x2a9e8e1c3850c66da60224163dc4846ea6f37ed48f9d6dfd40b450fa61081484) + s2: Honk.G1Point({ + x: uint256(0x00def638e4fdad7089dd2cc99e003e101ff5ed89c0f4d3842821a6636abeac0f), + y: uint256(0x216b4b4bdcef902c4aa149e4c5e5ef69b4b2fa7909b03e6c527befddf9aea208) }), - s3: Honk.G1Point({ - x: uint256(0x0d264ba46f4a7bafd0ba9d9f9f4827109e1da2cfdb11835b9fc65aaafe9f9f20), - y: uint256(0x0f9ff6e122bcacd091ffd98d8caf249ab216e9c784e667475e2184ed34892272) + s3: Honk.G1Point({ + x: uint256(0x0e5217dc5c6f84fcae20d18267fe3aa126f1c78bdc848d5d155e965ee46d57ab), + y: uint256(0x1c9d0fd84b8792f7fc102309d8298d734793efe6f917d6983495f8a327a4d836) }), - s4: Honk.G1Point({ - x: uint256(0x2556809f13dc85764a5e4ea8fda1bbba54f36dad477124915fc8c198db16f496), - y: uint256(0x27461805fb3a7ee919331973984491c36cc83eee61d3664d5319922902327750) + s4: Honk.G1Point({ + x: uint256(0x2aa0999747c3673174ec7eb488e5e18dc9c0cc066677941ba659f8ff8b381db1), + y: uint256(0x29abc69897e1af84be5d94015bd6fd94c6612cb259c7c9f2e2c72f76c900c5bd) }), - t1: Honk.G1Point({ - x: uint256(0x1ddc9ef86584375e5998d9f6fc16a4e646dc315ab86b477abc2f18a723dc24f6), - y: uint256(0x03a3b132ca6590c4ffdf35e1acd932da680a4247a55c88dd2284af78cb047906) + t1: Honk.G1Point({ + x: uint256(0x1ca80e2d80c4058457bf2ddce67adec85e9d147eea6b130f11d37d3b80f977a6), + y: uint256(0x2812e987a2950af642c89d778f1d8f0bc5b24e1f30dd454b883d4bb2696fada8) }), - t2: Honk.G1Point({ - x: uint256(0x1e4cde3e410660193bacdf1db498ffb6bf1618c4d7b355415858d7d996e8bd03), - y: uint256(0x18d7f0300f961521ead0cb3c81a2a43a2dea0fdcb17bd772aef6c7b908be4273) + t2: Honk.G1Point({ + x: uint256(0x0e3ff1d0e58dbe4c2ad55e0b4ac9d28a78a504e26ed2d1468432d01f52f35003), + y: uint256(0x03d5da7641a7698a0e7c920f0ab4ca4760ee05fdfaa8ea5b2a6fa0c1f7d15a0a) }), - t3: Honk.G1Point({ - x: uint256(0x0e77f28b07af551fea1ad81b304fd41013850e8b3539309c20bb2fa115289642), - y: uint256(0x15f92fde2f0d7a77c27daeb397336220ffc07b99f710980253e84f8ae94afd4d) + t3: Honk.G1Point({ + x: uint256(0x14a9f5aba97157d82f64938a827361a91cc94b66f88a9c0ca65be9b56e3f9821), + y: uint256(0x1a6dbba0f10b19e540a198c66e04a35ee95ae33ee43b01852d294f06a4a08d4f) }), - t4: Honk.G1Point({ - x: uint256(0x2285ea4116ca00b673b2daadf596052b6d9ba6d231a4bea8af5a3c0f28c44aa4), - y: uint256(0x076bf1e1f682badebfca083e25d808e8dae96372631c0721a7ee238c333a862a) + t4: Honk.G1Point({ + x: uint256(0x0934b14b98eab15c73b9ecc3453229fd602408a75d6b8b59242fa0eeeb3a4230), + y: uint256(0x1c7079581fa387fd07d23e144ba9161cb2428e1ed84d1b61547a3688baad41ae) }), - id1: Honk.G1Point({ - x: uint256(0x0b034b231d25a2e152b830397a59c97e02175212a6c5ce00129625cfb2e5c53d), - y: uint256(0x22e1842515d4569ca06477f4b2685d0a767bfa1eecca343c889840af8c086db9) + id1: Honk.G1Point({ + x: uint256(0x17fcf5224da2d584726a7b80972a622c6b982121c33a71fd400da52c8df37924), + y: uint256(0x114b4bce95cd9f2aa6f7c8653e855406c1da5e44a3ef692c4435d888a315f359) }), - id2: Honk.G1Point({ - x: uint256(0x0e82a73cd55280503e70d5bdd855071d202ff65f31a65996955a7661775ff290), - y: uint256(0x1325a665dfee8e1247f3129ca943e12736f800afc1a9dcfa0476050b8e3c87f8) + id2: Honk.G1Point({ + x: uint256(0x2fef8b3fd63b5ca8faf76f47f6c73652a47df0b42cdea3abdc06c59aec2f3b21), + y: uint256(0x01b2c58279557c3b4b1019d7700f9c1a69f255df49ca874728d18a6843eb581f) }), - id3: Honk.G1Point({ - x: uint256(0x2ad12a1238e051fba16108022b5e58bba1fc7966fe759016a93fae5397e8c403), - y: uint256(0x257cfc281b0135bb8dfb0df6a7b69ca39835af544007eb61ace84ce7014c1fea) + id3: Honk.G1Point({ + x: uint256(0x0713316ad4da65b28be231d997fc27558c9663cba7aeaa24dd2a94e5cfecb88b), + y: uint256(0x2ab0460a36b81cf33745d9ac0cc66f46c22a2c0f22b97e78de63b0f94d746453) }), - id4: Honk.G1Point({ - x: uint256(0x058bf4de2f71f4d2e11235d140d05db461fb50d8aef64c8c52e2c0f57438dcce), - y: uint256(0x1e90ce7ec8cca2e65d7deafb655e6c7b0c4b964cd2cb1e5b4ef5ad78ab2f4b46) + id4: Honk.G1Point({ + x: uint256(0x00022bd8bd7328e7449214b7ada33e0991108ad45b30afaef78f30bea2091f38), + y: uint256(0x18a83d47716f4f134e9d29db7acc812e89cb7578a36e05b5043bb21ccc93f81d) }), - lagrangeFirst: Honk.G1Point({ - x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001), - y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002) + lagrangeFirst: Honk.G1Point({ + x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001), + y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002) }), - lagrangeLast: Honk.G1Point({ - x: uint256(0x28bf8c9eeae6946902ee08351768a3e4f67d812e6465f55f16bf69fad16cf46d), - y: uint256(0x12dab1c326b33ea63ec6651324077c0ea2cb0ddfafd63fb8f9fbcc70bd53d7e0) + lagrangeLast: Honk.G1Point({ + x: uint256(0x27949ee1c2c701a8ee2e8c253ae9e3a429f03da04547f6e17fd7d0d27ae07689), + y: uint256(0x08e6579e77d56473d9b459c4265b407d29913310d4f155fd19348efe52bdd1d2) }) }); return vk; diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index 4962db414a3..d68316c16df 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -220,9 +220,9 @@ library Constants { uint256 internal constant LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 64; uint256 internal constant NUM_MSGS_PER_BASE_PARITY = 4; uint256 internal constant NUM_BASE_PARITY_PER_ROOT_PARITY = 4; - uint256 internal constant RECURSIVE_PROOF_LENGTH = 463; - uint256 internal constant NESTED_RECURSIVE_PROOF_LENGTH = 463; - uint256 internal constant TUBE_PROOF_LENGTH = 463; + uint256 internal constant RECURSIVE_PROOF_LENGTH = 459; + uint256 internal constant NESTED_RECURSIVE_PROOF_LENGTH = 459; + uint256 internal constant TUBE_PROOF_LENGTH = 459; uint256 internal constant HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS = 128; uint256 internal constant CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS = 143; uint256 internal constant MEM_TAG_FF = 0; 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 52bd8702477..7586a274d62 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -457,8 +457,8 @@ pub global NUM_MSGS_PER_BASE_PARITY: u32 = 4; pub global NUM_BASE_PARITY_PER_ROOT_PARITY: u32 = 4; // Lengths of the different types of proofs in fields -pub global RECURSIVE_PROOF_LENGTH: u32 = 463; -pub global NESTED_RECURSIVE_PROOF_LENGTH: u32 = 463; +pub global RECURSIVE_PROOF_LENGTH: u32 = 459; +pub global NESTED_RECURSIVE_PROOF_LENGTH: u32 = 459; pub global TUBE_PROOF_LENGTH: u32 = RECURSIVE_PROOF_LENGTH; // in the future these can differ pub global HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS: u32 = 128; // size of an Ultra verification key diff --git a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/Prover.toml b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/Prover.toml index f8e7ba41a18..8804a5e1ebf 100644 --- a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/Prover.toml +++ b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/Prover.toml @@ -1,5 +1,5 @@ key_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" -proof = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf", "0x00000000000000000000000000000000000000000000000b75c020998797da78", "0x0000000000000000000000000000000000000000000000005a107acb64952eca", "0x000000000000000000000000000000000000000000000000000031e97a575e9d", "0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4", "0x00000000000000000000000000000000000000000000000c410db10a01750aeb", "0x00000000000000000000000000000000000000000000000d722669117f9758a4", "0x000000000000000000000000000000000000000000000000000178cbf4206471", "0x000000000000000000000000000000000000000000000000e91b8a11e7842c38", "0x000000000000000000000000000000000000000000000007fd51009034b3357f", "0x000000000000000000000000000000000000000000000009889939f81e9c7402", "0x0000000000000000000000000000000000000000000000000000f94656a2ca48", "0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f", "0x0000000000000000000000000000000000000000000000093fe27776f50224bd", "0x000000000000000000000000000000000000000000000004a0c80c0da527a081", "0x0000000000000000000000000000000000000000000000000001b52c2020d746", "0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632", "0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc", "0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62", "0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c", "0x000000000000000000000000000000b0804efd6573805f991458295f510a2004", "0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e", "0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47", "0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15", "0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd", "0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383", "0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4", "0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x000000000000000000000000000000f968b227a358a305607f3efc933823d288", "0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08", "0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f", "0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1", "0x00000000000000000000000000000052eebbd1f6f7554e837f60c44000ed14b6", "0x00000000000000000000000000000000001c1c045a3ec94b8801f2272cc0b3f4", "0x0000000000000000000000000000004d2ef74134578f6b431a9df071ffca4292", "0x0000000000000000000000000000000000291326ade7aa6f0dfc8900eab5580b", "0x0000000000000000000000000000002433eec6418a6dba820c9527e2581fc8bc", "0x00000000000000000000000000000000000e88b7daad19af2ac2f9bdf9e50ee2", "0x000000000000000000000000000000dcfce2c427155cc3e4d035735d3dd5ece8", "0x00000000000000000000000000000000002d7d473cac1a15d0fee8b22c1a7b3e", "0x1a4249b90be4602c8ff40c7c276160ee41b2a0f8a238ce7706e9face2db03d48", "0x162204b9d54d3ffd285c393a5a1ff76ee681474fd780a21a3cf7fac5c24fc2b9", "0x30279eb953d8ee79b2155c69c04e6443c5de6bf7e02886256dd7b3cd3c9502a4", "0x0d32c1bd21baf43e72d5d82d461ef54833807ff81a877adc822f27a6db88d754", "0x0fe15e055c0803d5ebe6dd77689b70cfd82138f008810ce24535c992daaff27d", "0x1fba82c012671212ce2fc13fd09bf8fba4f7d5875ab8d37495d1ccfcff287331", "0x090738a5842fa4d2699b3726aa0dd97cb59569b4be2c6825335ec4969f859dc2", "0x0c6cb72dabbc28abcf4a50c203534e066c29f48c24ca64d672092f263df3f9d7", "0x0f27fbea0d9145f815c288b50fe7e8c10b8185d325b5264624fd57102855d05d", "0x2a815cd3fd1c43c72ee0130465250ff771d1e7be2347e4ada331b83265a03450", "0x148b4ecf2ad7ed17409417086867ee27bc1b0906dbc9cbb3714c285071e2db70", "0x08e700a42b1d6d36ee65f8ebedf47d3a44463ff9fa579dce13b7492e20142c3a", "0x2e23c69521d572ff2152c50f8c9a9191535f4cf37f95f1e0428692e78842b642", "0x14519e0354365923fb41400c19866135b45e975d56a0980260bc99f0390b1d5f", "0x04caded1f05738f736cb5bcf08d785e395e58eb7738523a20638aa16bc51593e", "0x28787eaccd38383215ea21ec02895c32d979f68ca155f534a2e2d377bff6698b", "0x20a1b81fa96c58cf11c5762c5ceb731efdcb081fca2d34d5c463d2cf40e6da18", "0x11789a06fe3bf53833741d180f068d29534d5bb58a5c64b8119542e62b189fb4", "0x23d00fcd032ace719ffcbc513bfa177a55b04377d76455c2788d999d05d011e2", "0x01f0e81b57b4a73cc118e51ede18f8724debf25c2d109db6ef45280f99f1a3fa", "0x156d1c9b61749810de728f259c2c1c1fd4dbff97101426e26087ca461c93307c", "0x1c5d619ac3a478cfd06d5eebfd879960bb321236be173813f5e78d1366d32c69", "0x250cfae4e1dfc551406f1f3d10b649a637dcb7bcb0f6f697994cf96afd35d0c1", "0x242b999f58cf5f53c874d1092bd38725aa9ea076f5bc8f176efa9ea23393874b", "0x2e15748255c4a5e0e9fe38047341b692a967257de27a85a3a38681bc9f1602ea", "0x01ef83886ea7017253699cb6371988eb8e21b4f7023d7479ece4907fe6d4a6fd", "0x08db2dbc271e375b9312f695c59c48f313235b3432cad50921c8d9ad6dd7ad7a", "0x199309f2c2cd45c15a4abb0e6554a1615ff5a6e9488a8d900bbf835fc8f664ef", "0x074be7a3d88e31ab1b59c9208c012bcfb1f85f351c709e68134996891db52b57", "0x301b1011354d2ebf46134fc4d6d734bb6ed8542d719f38f5e09a376a580cad7f", "0x12968f3eccaa27e44f14d5aaac6ecb70c00d040e07536292e685d7cab03fc563", "0x2110a023c8c22fd2ed70270a2d0a265b92a32ce2217ffe1be9a5d7d5c25f512f", "0x1e8cf4c60c53900f0430d5b44de5804fe8b38299bc803beeb4216e1a289cf624", "0x12301cb908ccb28a2616e29b831ec7105b5d3ebf45ff5fe91d50a9dd53a50b52", "0x0f1029ed107d84ff2d6d4a416cbd01da3f3d7bf5b2209ce93ba424f4b85616fc", "0x1b431d016611b8abd684afd9e92331c3325967b1116bfa91d4f44e2f8e2c9fc2", "0x281e335a0fd117064c8ace3f01e02b134a19e9b9220571ebfaaaa0e3a12d34db", "0x22559c106f77e2ae95677d5e38e288343e3b7168371aec7d3aaab9ef8150af70", "0x13f113b1d9b590149cf08c3f6e90589cda5c7b98528866b891256cb9d5d814e7", "0x10252ef388e4c80246962e98b9e976fab2cd25e1e6f1e3fd2a7d4786c5218a97", "0x16b890723dfdebd9912a9207255f95cb800222165b6fae97ec46e461f23e83f3", "0x25caf77c7d2e8e069341ec90f3c8f6d64319cfd2d77cab0625cf0377285ba11c", "0x016c84288b0bc3c50eebbe250cdd5a4ee50b2c65a24ac64d0c930cbdecb95141", "0x20a537c045b069d47dc6315f45b391f60681222381e5059ec7c8b17bf677d911", "0x2594c0edfcd4064d215a3d797bc8e3b2f401c61f3961ae96ccbec8f8fd29e81f", "0x1c831d7047483ca00ed59bdb84c47ffb8bbebbae92aa164c7b35fcffbb8a35d3", "0x2ea7f60de52b8cd6b0bd06f861fc1f2c5ed1d1fbfa53caccdb836400a03df434", "0x275c6c8bd115f7d2ce196439e2330fad305c6745bab0bf1ce3f2fa32dadc3c43", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x2b3f4e210619347288731e7f0eea1ae60dd8696fe87319044864d099a03a9536", "0x0fecd3d2aebedeb8be2b0b7e3a74de9ec8bd2cb72851541463729e0715aef48b", "0x10bee385ad0c2cd3ff88ef4d630840749e4367f9add4a300fc4f545a7778e92c", "0x1fe792730eeafbd22c4eb80e86e2b40108b1e55b2a08db786289eea5745b9e3b", "0x04d411679da432816b213cd5580dda1fd6c2f258684c036be19b5b26baca583c", "0x159f17b655d2b8a803e0cfb564918628be52d3baa950ca1b127854491624f8f4", "0x225340463867d9252a1269013536e2e1dd219aa18eadef13c324b63d44679334", "0x1885e231554e02abb40ed54b72ebf09b883d0298a6bc06fc645a30365f370ef2", "0x233344517f25170972b8ba35d01f2df2e073d322993abce7df26796126e93498", "0x08990e8faa13b18b4433ec417c5cc596885e11ffd372d5f612c08cc79a5d5c80", "0x1e960a0c892b755c28e21dcbed816c1b182d7da43bae07f8ee622bd4485f79e7", "0x27b58e2ee290a179d349ace82752528b2ff946d60c092b99ef42f53c25d0c99f", "0x2a5cf8a3193107d982edd253002c7a52ab876b445dde8307ab78fbdca022d93c", "0x2b1ab4d5277f8c82750c1c7bd043889b71465ec64a9afc1bfa37d06b1ebd0725", "0x2a0dbf5c4373a58a83d5f2a031ea0615bf12800e33b70c3191a7cbb15966ced8", "0x1f272bb4a19d14a0abdfebc9fc83125e10623b9aef730f8d25f2bf5bead38ea9", "0x2c2339cf0ae7aff56091a568c1e2c3f01f52d8ed13400737fd31eaabcaffb9bd", "0x21f5fefe6b5fa0b5da71089befb74a1a39e52b4f830cb330c3c284e154614dfd", "0x1e6f6ba4b2444586b380dc4e2b3fad111ff1f4754420a846f53ea0789ebfb0ad", "0x1193d170b0b2dd0c4a04331a4b4aa3f12920f182ec3ab547837e30f1116ca584", "0x00000000000000000000000000000025704a15c9e2ce8a69558e7bbcdcbc7784", "0x2e5d36112770fb6c985681cafe40a8c99ad13f702309e7969801dd0ed080e727", "0x0eefc2585f591bb457183134e19ad643966272234d645514bf7868d6dd8ae2cb", "0x300803e4e2339ad39b9c31f228949bbeaf9c74b7101e7be1930b088126247eaa", "0x2bb562a50ed944b438b83b01f200101a34faef7f296a75c84c731755ebddbc1a", "0x1288e0b9c742af39cbcac21357c1b29511b0bbdd3d0e3cf5e14b2eef68a28ab3", "0x20f089131cc96d86ff1cfb67fa3f51670f4bad30158751b2587354bbec76cdf9", "0x1a26c6d3e633f9bf8434cf755b5f1217dad0d455071a97a7bcf85b824f5cf07a", "0x0d7e9b8a51fccf910ec25bdbd13e70b34bd6ea6f4d629fa744f9cdf5f2beb1cf", "0x0b40f28ce428e64df9cf5a024133fc420f39decf5f6af020cc3211ab298d4631", "0x0ca4f189dde7a55fe829f46681232904f6670249a22e0deb47222bd309523a8a", "0x2c544f2e31143783977645edb2a6bdb39b875053963bfa1a5b3ae9de204a7ebe", "0x00aae4454eb48fb18ff60db6b9d015abea2e770a2f7d86d121522b834c791ba5", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x2d9e5bff47207d82533e2445959941181cc890c5779bc7f24d6e8a7b9e425b5c", "0x0aea3c0c317c441a5775a9849108d7a6889b39128235f717b09b184aa08e4eb7", "0x1ca5bc6fb37c55a562f4991901c39902f42d14db71284116df74cb4e7d55e493", "0x220fed26d64cd69f40e6d145a423e4a3c8cd0dce747e7d51647441270ad4d774", "0x15be574c9358889257aa2a30ff7b5fcc31a57da7032296e2c1201c49a44bbdb6", "0x2de539925525bedd3b7f43a9c6bf0f713151a17f79ac7ff4a9cd27b15ffe892a", "0x083086693dbf465211741e2cbff70ff38eb08383faf22d397eb2742c8ad7396a", "0x1fdfa258a890598816e807c50058d7a1462edd5ff196a2eae0f862e454b49aa1", "0x10c434c6daaa8226fa8e3e302123dfdc4455cf68063df518949df5a65a945213", "0x0000000000000000000000000000006472a7874de2c454a4591ed7784df1c104", "0x000000000000000000000000000000000008c46ac53d2c4ad0c26a5d6c790082", "0x0000000000000000000000000000005e422f9cfb8725800de60dfe0a8d4104c0", "0x000000000000000000000000000000000000f10fd4e4de81a0c00073ec91c274", "0x000000000000000000000000000000b20813090eca76bc6aa4a699b1ec8d5d6d", "0x0000000000000000000000000000000000292cc9f8a744eb00e0903c29ce87a7", "0x000000000000000000000000000000350a368b415fbb99fa90a26a42b1a3affd", "0x0000000000000000000000000000000000280eb9275cb05a3435f464d1dc369d", "0x000000000000000000000000000000280df6505e20c7725fe6d29439f96ee05d", "0x000000000000000000000000000000000017ef5033a08535451e2747827aa94b", "0x0000000000000000000000000000002f9ba89ae91b4e4a4ff8ccbd0526faad2f", "0x00000000000000000000000000000000001c2013561dafcc02cb03220bdf23c4", "0x000000000000000000000000000000aac102c400f9e5da0321ded4510994434b", "0x00000000000000000000000000000000001ec8ab9cc834b492fde124962f04a1", "0x0000000000000000000000000000000673dbd698da8b8cce450d2a083aba9987", "0x00000000000000000000000000000000000a49e55bb040249cb41c63cea901cd", "0x000000000000000000000000000000133d92af8d76ee0c74a12081ee7b2ef8c4", "0x0000000000000000000000000000000000240f552d1c6cbb007650e4b142e0a5", "0x000000000000000000000000000000e29c6e7d982ec08d51c79d6261c28d742d", "0x000000000000000000000000000000000021baeec04d9be419c923626034e7b3", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x1e940a528b42d8230e7d4dff76262a80986c0d00b2c02a9bc0559e36212d1547", "0x1ceccf21ac39f70d76ad6f7fe0dcb33b6af04555a0b1959e4714d65925e4e253", "0x096139d757046cdbdb7ee89a95f112f70882a43a46c2f739d9be115dda013420", "0x2f9c8ac67c7825b08eff0e7f7656a671f4c64e5601f2efab35b1b795801eec04", "0x2077e648e1704851cdffd7e6e56311634a7b741bab77ca34d9dff12a6a2bfe99", "0x115d48c4a97aeb3c447a060f9e0d675b0dc7f4a05a3f5776e2f279f3a165d7dc", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000000000fd38c45c3ec5b841482a80e3a56ce82555", "0x00000000000000000000000000000000000ad70b03f092f60af3e0ce1bb29d2c", "0x0000000000000000000000000000007a184d5342c90c634c0b1a050f0b97c9fb", "0x0000000000000000000000000000000000271f42abcb3bc1f0332e4b3ca85e1d", "0x0000000000000000000000000000008256322bbe2c1b8cd9d84e5ff6123477f2", "0x000000000000000000000000000000000025cab962761681dd9547f4c78814df", "0x0000000000000000000000000000008c4234510e5825c02b9ac427bcbf8e279a", "0x000000000000000000000000000000000013a14e0d7fc073c44643af38cc5396"] +proof = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf", "0x00000000000000000000000000000000000000000000000b75c020998797da78", "0x0000000000000000000000000000000000000000000000005a107acb64952eca", "0x000000000000000000000000000000000000000000000000000031e97a575e9d", "0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4", "0x00000000000000000000000000000000000000000000000c410db10a01750aeb", "0x00000000000000000000000000000000000000000000000d722669117f9758a4", "0x000000000000000000000000000000000000000000000000000178cbf4206471", "0x000000000000000000000000000000000000000000000000e91b8a11e7842c38", "0x000000000000000000000000000000000000000000000007fd51009034b3357f", "0x000000000000000000000000000000000000000000000009889939f81e9c7402", "0x0000000000000000000000000000000000000000000000000000f94656a2ca48", "0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f", "0x0000000000000000000000000000000000000000000000093fe27776f50224bd", "0x000000000000000000000000000000000000000000000004a0c80c0da527a081", "0x0000000000000000000000000000000000000000000000000001b52c2020d746", "0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632", "0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc", "0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62", "0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c", "0x000000000000000000000000000000b0804efd6573805f991458295f510a2004", "0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e", "0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47", "0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15", "0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd", "0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383", "0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4", "0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98", "0x0000000000000000000000000000004ae614a40d61d28f36aaf03d00a064355d", "0x000000000000000000000000000000000010edd34b6c69cb31a6a833a1d040d2", "0x000000000000000000000000000000f4976ee83b95241474007fdc30b06ebdd7", "0x000000000000000000000000000000000019cd0d7e4577008a8335c6260be826", "0x0000000000000000000000000000004ae614a40d61d28f36aaf03d00a064355d", "0x000000000000000000000000000000000010edd34b6c69cb31a6a833a1d040d2", "0x000000000000000000000000000000f4976ee83b95241474007fdc30b06ebdd7", "0x000000000000000000000000000000000019cd0d7e4577008a8335c6260be826", "0x000000000000000000000000000000f968b227a358a305607f3efc933823d288", "0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08", "0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f", "0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1", "0x0000000000000000000000000000007376c0278bcc77156c008b389f6bd12e8f", "0x0000000000000000000000000000000000176ebed74bf3b57ca42a2fac842809", "0x000000000000000000000000000000fc4a601439d45b9ce23c9d9cc37cb21dd2", "0x000000000000000000000000000000000017dc6f8c53261c44cd0348a9970d88", "0x000000000000000000000000000000292042e9c3c101d8dd41b3acfc0db429a2", "0x0000000000000000000000000000000000114f6b3755c65915e12f13533cdd41", "0x0000000000000000000000000000007bb311a6bd5f4f3d543ca30a1a0201614f", "0x00000000000000000000000000000000000871a5a04dda33543cf59b3babf733", "0x03ecb02e48ba68818287222348fc537135b6426d4580ea31cdd540250a7a95fb", "0x2c779e44987737a835c92393388504ebf27da5db3438865f760cb56ee5856a06", "0x0ac17380181974c0082ef0fada047fc7906a94dc18e5be249dd29e52961522e0", "0x206c623397f11ed76a292c7c605fe56c1ae4f6babb6889786aaff461535cf79e", "0x11dfbe6d0977046fd72b55bdb9b41f983fc06ea6404cb36efdf1786d6f0dcbf7", "0x1081a4f21029bfcf4f8388257bf88d932963b2368c4fde96836fb6f023f16622", "0x2e981de982d368f04b0a49e537a05ed5583080c3eafed9617bd06e1214641be9", "0x2571d21e04b1d59935490270a4789e53042f18e15fc7b94dfd267c8deadfc74e", "0x0f70f3f5319d3564bcc6fad428552eefce8f341ced5187fa186d0f099315f225", "0x18f7ee010c96f63d18d2a277e5f5a8ef19b525907817d69616d24495ad804021", "0x1cf7e347bae24a2c1a93b5fd11ff79e68bd2c1bd32056df6d2e1582d17db1d8d", "0x01c451a702451ea9871b7e19d3e2052d8fa49a571ae46616453f27d324cfc907", "0x0614dbf2404cb5fef2e5408f1115502954097981a5ea67d1f80812fa247b1f93", "0x09884374bb354fdb4b118f4da44cd37e75ba7a655201f94cc4064acbdc35887d", "0x158211f68576bcafd791ff02039bb8246b1ba94d99f30a0f282565dd8d82ce0b", "0x0a5231e4039c7b7e0ad77d319958403997a33a0be31e71032733cd70067b14db", "0x2803fc0a9f60d9e202eb6caddcacfbb94a5a7df2695c2a0c909815093ca1864c", "0x0faa80f3cef0e86746df7518f865936959d65eb64ccb05bfb574ac5561683eae", "0x298544d77ee6f4cae7aaa4e9203a233fa18dab360d6f54daf9f8801802586d58", "0x0ba76e9cadf0380b82a3b5ec1c71b80295ce3caeec73aefecffed90f28c1b012", "0x0d965885fc07c4a140f50a83cb750c876191651ee47462d0931e0e67bc9ab5cb", "0x0aad443f96fbde49595f31a47d233ca83ed2bcda86801a8fd7a596ea666c7716", "0x298ef11d346c061b8899cb10c0cd7150aa2d6c554340cf2ee6aa76125e7d1e7f", "0x27518b0512f1efb3a79650941d3adb015b357c92a8c06e086be7b3e7666cea47", "0x0cd6b10a38d5af7f0a5fa97c0ffcba406e8a65a92fe050b3b79f3f1f45d723e2", "0x2f5e1210a841f9c6a7ee7d7f290479696387a58192cb775a64adf0dc225e3d4f", "0x2ffd390be1aecefc25137d01e5b7a85410254ae9e21e7067a9869217cb828ee1", "0x244a77246b5beb3e0e38c8dda39a516050303e83c051300d08bbe5450320b47f", "0x16ed38ff1019df1d168974833ccc96d8648d05c2823021d45e1d5599998a8aec", "0x24cbbf8ca1a5bb082c1081d9252a5e964ff7aae4d83e04468db55960b80a585f", "0x01b3a78bcc6e7529c6ded587b8958d903ef990421d5706afbef64a7976a51084", "0x2c3a013cdecd027b32c8c99c163dd822df374ef018aac8f3d1fb8d57335f9503", "0x0ad83466928e5d70e1e0bb26633a1e0c61399733c15fffafb22df18029e583d6", "0x095023de752480ca3edd408d3c34d732bd9836919e84931d3f42a978867bc53e", "0x283d221f0a2e6b6616bc3eda23e15bb8c8b459010014db7608e646c70ea1da2e", "0x1390c81536ca3d71228eeccf9844702aa3df012bbc3902fe30323f55ee8c7872", "0x0ef66f0302753884f05043080104589e1bf036566a9a00d4688d3c7910631508", "0x15eceeed97d9267597c028fafac72dba40f3ea441880bdd2202b30846a243044", "0x2b38e3f3b5193811df1bafd58432d5abd1c5f575a5d9c2a449682a0f2f035034", "0x2bbcc40d11d6a96c85a63162143ec53314573bb0af7c32d89b791394c80d14a5", "0x22d909e8fb5152b5b98f7cb3fc38f4ef7d7e8f2a857347da59ba2e979bd2ec96", "0x29e3f7a95437fe6ea1e72cd4c7c2fcf1892ab22ba69387f1a6a795e91bcc26f2", "0x02d8c8d031ada707d85693ed106135cecb7fe52de73eedbc54a91a2c856d0de1", "0x28020fb768c50bf52497832c04fb0e14cdb651b98b80864d0b68228ddfd922a0", "0x24d61051f82ff93eb42b5afdcad9e236c669f9f849bf811a853f1e9cc302f8ce", "0x250e89de38769cf70e6cb3685f99e39f44d8ebc1a468930f49e1d80342092b6a", "0x0ad45df677495b9199c57f620db716c543fb6437d574453b7721c2faee6316ba", "0x043d8715e16e3f2dc5a537355c0576254a36db25002f13958696ed13c24add46", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0bb8cb6a256f110f134a15b66b644eb49dc8e0239f92489408e6265a323bb513", "0x18f02f61683cf6a7492291a7041ee1b3cfa8dfb5aa40e2f6571d13750f0f459a", "0x0a982c10c93ae173751f4165e6456c9b85e2551bd503919acae78c801ccc0e1e", "0x0b6e6266bdc6d44d05ae76d2db249877a46ad978fc758654a3a6a7208d2725a6", "0x20de00721f30db8280aa6804c90f3fbe23477e1f746a8eff61c4c5b2af7e821c", "0x1321548f766ded3432627a50704d233455c61d8e59afec2883dbe2f381c033f9", "0x00c56c902b14aa59f6f59badf20f59c51b08aeb6afbdd97a5ac7b98b998b0a56", "0x1745c01290e99476fa655e5fcf2e5b3d24f42624cbd25a40f60af3f3e8489512", "0x08e915bebf8f6c86b332a681d35c57dcd0e0804f22e4e78884ab5edc0a41d6d0", "0x0c77b29e3a0c4368ce5231f94d13fa9b84a6e350cc8f2a57b3f6920a2bf0e879", "0x07ab821c4f07e1dd1cce43b9d9dbf4c9da2e22fea675a57ecf5a47a6992059a2", "0x0bcf85d1f4e34e7598a68bc09cfacf119b0afa1193ad4163096e44ca8eef7a22", "0x0c8a367da01b9097d24eb7b5471c6bd049f7938080bb8cc6fb92945fa934faf9", "0x2cda5caa3a93dcc134cf176f4ad6c79577d273bd2706da3fcaad92a9bc336ac8", "0x2c19cbfce048ef9bb9efb5b9875645b0bc7825aa1a05ad71dbbd3a34d1d76501", "0x28d7f11c2b6b7ff8717b79b098e5bd37eb39a8ea5d03b15339c86fb93e497d97", "0x21ba86c3baacb0fe4270c64c1a5f2861af2f5aa1d6391afe8214e1ce9eac8dfa", "0x0c5289ff2fe581ccf0caa97b4041d381e384c4aef0417edd4dafa7f64a3bfa6f", "0x0c744b0b301542ec4f334696945d7b89b137c5b9434bec277dc938c3dc9ca7aa", "0x006d246e7b0ad18157fa925981f097121fe34cc769128fd8993c4d15cfdf0aee", "0x00000000000000000000000000000022a7ebdc5723cfdb5d73c4c0392e43c407", "0x160d495d0b4462662665faccb1d65d81f0c3f006254a6082a0ceffc49483d76a", "0x24a5a2b9bef1abc3a818d2f27ca5cca7e1b3da34ea6056f338ac54638e26c3b0", "0x0a3dcf45eb6c14391ed8aeab11cb9460f85cb11a1ecb868ad75095796c0f5dac", "0x160c8087a99bf109389ca20d0ce624f71dd2e40fe64d62712e45669ed550fd61", "0x1a65519621040c52fdec5594d095add265c99210929eeb29a3a8180b480bb313", "0x09bf095c40c00dce181347b0d8eaa83ecd0f1f8fcb5dab34ffe19e219672e681", "0x10f3444d7a623e54ad2e882c436191975143217e9f8121c8770a3bbd3ec183ce", "0x0cd68d59322f30bdaf0a6a628f095f880ff716b157ef9a2d589f2cfc40b53e3d", "0x20732eab49adfd109626e0e84496a929a690377e98ee03f13f66ad4541949300", "0x28c850b8bc7f6ae88835bed342eda477e8d1f013a4db34b7ff33198e0a9f8e09", "0x14d234765f29b713df4d1291d452c73a5dc00458242df1be96e04ffb0a3c396e", "0x162572b68ab59291f430cf3113d4fcd3ddca59c4808c134345f6765693f8e1ce", "0x0bc37cb2ffd0f1691bf4d8c621d49f8c23ff58989d09d96c019cc6fc9a46e155", "0x0bc37cb2ffd0f1691bf4d8c621d49f8c23ff58989d09d96c019cc6fc9a46e155", "0x2aa58bd9f811c2970dcefde8c31c2c6db2349eed5161f80c0280a3acbd9f4f0d", "0x141198df3b9c1917d2e7a136ca3438fd9630719591c24388a0559873756d288b", "0x1975864b97d6ff0ace3d600020772ea32181c2f3e413ae67bac22e4a3bbcba9c", "0x2023d432e6630619c99c25a2f293f5ed78f373ee5212bff02b92f00a43bab0e0", "0x23cbaa3113b7265b926bc8811fccce701b3d4e4006ae6b66cefffd0e2f059fd4", "0x00000000000000000000000000000061e09b904168dcad01e82d26f8a21bb884", "0x000000000000000000000000000000000027a29682b86d1b09daa382868b245a", "0x000000000000000000000000000000efc6d7071b6c8cf492bc3ba72f4eda84c5", "0x000000000000000000000000000000000010860d04901949ad63a94863c77149", "0x00000000000000000000000000000036cacf503222db1b5d0edd58aafc1e74f9", "0x00000000000000000000000000000000000fef16ca13117c1f45f6df0782c273", "0x000000000000000000000000000000013704a507a82f6224d7c369d3d6c3929e", "0x00000000000000000000000000000000002887168ff50b7339d4d181d2a84cc0", "0x000000000000000000000000000000e57f500eab5f7d08ac3c93ce080dc1f15e", "0x00000000000000000000000000000000000c720872540cd88fec315c3e6a7625", "0x0000000000000000000000000000004b6897120d1858d29ac10cba52cf73dc44", "0x000000000000000000000000000000000019a9523d9a2481b5dbb1c23cb9686e", "0x00000000000000000000000000000052442fa24d3d5c3b9a608d8259757905a4", "0x00000000000000000000000000000000001c58b3787ffa3edd9f049c1c775a85", "0x000000000000000000000000000000f5737a5b8d278973356217e75bdc986ea2", "0x00000000000000000000000000000000001e0959f30c996ac7e3b265bac2de9d", "0x00000000000000000000000000000030122ef6c7a097b6b2ea6efa763797b8b4", "0x0000000000000000000000000000000000191344dd8af6c1c1c3beef933de271", "0x0000000000000000000000000000002f38961e4eb47676a42a5b59457e19a7b1", "0x000000000000000000000000000000000002936d1fa64f399018fbf60a1f2001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0f349727b02c8c3916e6904450b4db7d748c746d693f12acfd44757e349ae543", "0x109b539e615d399af085519623a8f0ea43fd3e672e8b3397deb033110b896ba7", "0x1d2d7546c079198782bc8c1ecf377c86567d90d05988acd013af254a84ccfca2", "0x11922ebe299248b1a194ff41750bbad0297b8e4db3944036983764ba171195a1", "0x14cb035cb0d920e42127d67ed6763fd0cdadeac07c0aa57ab5c038a501aca88c", "0x2e82b6bc3d9337d1f2c080ed47e935308317c159408ff3a054718e737f827a49", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000000000c883c136e90256f3059fb812416fe61171", "0x00000000000000000000000000000000002cbe86e3f824a75195f942b5de0abe", "0x000000000000000000000000000000ff2335151394b16f671dcfdc5ee78485f3", "0x00000000000000000000000000000000000fceb210dd93cd99b7bb225af47ae8", "0x0000000000000000000000000000001a95675079e3f1508e636cf69b7978db7f", "0x0000000000000000000000000000000000079f7a59ed7b4a3dda951fa8fbad98", "0x000000000000000000000000000000b15ed33e983574376efe5ae0c29c6bdd1f", "0x000000000000000000000000000000000004031f5fd23cf82aad9e5d0bfd0363"] public_inputs = ["0x0000000000000000000000000000000000000000000000000000000000000003"] -verification_key = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000000000000000000000000000004", "0x0000000000000000000000000000000000000000000000000000000000000005", "0x0000000000000000000000000000000000000000000000000000000000000006", "0x0000000000000000000000000000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000000000000000000000000000008", "0x0000000000000000000000000000000000000000000000000000000000000009", "0x000000000000000000000000000000000000000000000000000000000000000a", "0x000000000000000000000000000000000000000000000000000000000000000b", "0x000000000000000000000000000000000000000000000000000000000000000c", "0x000000000000000000000000000000000000000000000000000000000000000d", "0x000000000000000000000000000000000000000000000000000000000000000e", "0x000000000000000000000000000000000000000000000000000000000000000f", "0x0000000000000000000000000000000000000000000000000000000000000010", "0x00000000000000000000000000000060e430ad1c23bfcf3514323aae3f206e84", "0x00000000000000000000000000000000001b5c3ff4c2458d8f481b1c068f27ae", "0x000000000000000000000000000000bb510ab2112def34980e4fc6998ad9dd16", "0x00000000000000000000000000000000000576e7c105b43e061e13cb877fefe1", "0x000000000000000000000000000000ced074785d11857b065d8199e6669a601c", "0x00000000000000000000000000000000000053b48a4098c1c0ae268f273952f7", "0x000000000000000000000000000000d1d4b26e941db8168cee8f6de548ae0fd8", "0x00000000000000000000000000000000001a9adf5a6dadc3d948bb61dfd63f4c", "0x0000000000000000000000000000009ce1faac6f8de6ebb18f1db17372c82ad5", "0x00000000000000000000000000000000002002681bb417184b2df070a16a3858", "0x000000000000000000000000000000161baa651a8092e0e84725594de5aba511", "0x00000000000000000000000000000000000be0064399c2a1efff9eb0cdcb2223", "0x0000000000000000000000000000008673be6fd1bdbe980a29d8c1ded54381e7", "0x000000000000000000000000000000000008a5158a7d9648cf1d234524c9fa0c", "0x0000000000000000000000000000002b4fce6e4b1c72062b296d49bca2aa4130", "0x00000000000000000000000000000000002e45a9eff4b6769e55fb710cded44f", "0x00000000000000000000000000000072b85bf733758b76bcf97333efb85a23e3", "0x000000000000000000000000000000000017da0ea508994fc82862715e4b5592", "0x00000000000000000000000000000094fa74695cf058dba8ff35aec95456c6c3", "0x0000000000000000000000000000000000211acddb851061c24b8f159e832bd1", "0x000000000000000000000000000000303b5e5c531384b9a792e11702ad3bcab0", "0x00000000000000000000000000000000000d336dff51a60b8833d5d7f6d4314c", "0x0000000000000000000000000000009f825dde88092070747180d581c342444a", "0x0000000000000000000000000000000000237fbd6511a03cca8cac01b555fe01", "0x0000000000000000000000000000007c313205159495df6d8de292079a4844ff", "0x000000000000000000000000000000000018facdfc468530dd45e8f7a1d38ce9", "0x0000000000000000000000000000000d1ce33446fc3dc4ab40ca38d92dac74e1", "0x00000000000000000000000000000000000852d8e3e0e8f4435af3e94222688b", "0x0000000000000000000000000000006c04ee19ec1dfec87ed47d6d04aa158de2", "0x000000000000000000000000000000000013240f97a584b45184c8ec31319b5f", "0x000000000000000000000000000000cefb5d240b07ceb4be26ea429b6dc9d9e0", "0x00000000000000000000000000000000002dad22022121d689f57fb38ca21349", "0x000000000000000000000000000000c9f189f2a91aeb664ce376d8b157ba98f8", "0x00000000000000000000000000000000002531a51ad54f124d58094b219818d2", "0x000000000000000000000000000000ef1e6db71809307f677677e62b4163f556", "0x0000000000000000000000000000000000272da4396fb2a7ee0638b9140e523d", "0x0000000000000000000000000000002e54c0244a7732c87bc4712a76dd8c83fb", "0x000000000000000000000000000000000007db77b3e04b7eba9643da57cbbe4d", "0x000000000000000000000000000000e0dfe1ddd7f74ae0d636c910c3e85830d8", "0x00000000000000000000000000000000000466fa9b57ec4664abd1505b490862", "0x0000000000000000000000000000009ee55ae8a32fe5384c79907067cc27192e", "0x00000000000000000000000000000000000799d0e465cec07ecb5238c854e830", "0x0000000000000000000000000000001d5910ad361e76e1c241247a823733c39f", "0x00000000000000000000000000000000002b03f2ccf7507564da2e6678bef8fe", "0x000000000000000000000000000000ee40d90bea71fba7a412dd61fcf34e8ceb", "0x0000000000000000000000000000000000140b0936c323fd2471155617b6af56", "0x0000000000000000000000000000002b90071823185c5ff8e440fd3d73b6fefc", "0x00000000000000000000000000000000002b6c10790a5f6631c87d652e059df4", "0x00000000000000000000000000000029a17181c7934fc3fdbd352eac5cb521b9", "0x00000000000000000000000000000000001f497cbf5284ff29a2d336e5991999", "0x000000000000000000000000000000072bd9c0c6beda1fdee6d4ff0432ba9e1b", "0x000000000000000000000000000000000013ea38a0bd2aa751a490a724fac818", "0x000000000000000000000000000000c599f63dcd3edd49f08ae5c3141c1e3493", "0x00000000000000000000000000000000002bdb36be0bea09950dd32a8ccf6fbc", "0x00000000000000000000000000000047f27f29724e7f19eba0340256a0bd4b7d", "0x00000000000000000000000000000000001c1c5ccf87a962129ca785f8f35120", "0x000000000000000000000000000000c5c71efdae00679bbe4a95096e012b1817", "0x000000000000000000000000000000000017a365de041e317817d0135f2b48e0", "0x0000000000000000000000000000008ae711ac402f7848d719c93a89ba8d39f1", "0x00000000000000000000000000000000002b6fb40ed8a1935226f4f9786a0499", "0x0000000000000000000000000000002f03a71501d83de1da5715a4e9462d6198", "0x00000000000000000000000000000000001644064443b8546f48eae693af47b8", "0x00000000000000000000000000000083763ab1b6e8fe269b2fe4c7b9c448c08d", "0x000000000000000000000000000000000021d7cc18c59676a8eeb47c0111c251", "0x000000000000000000000000000000b5f937153073e03ea7d51a996e0ebc2e6b", "0x000000000000000000000000000000000011ddd0e26457373eb06e0493177672", "0x000000000000000000000000000000c5f6eb9f6fc8fa99811a4a88c74a6d018b", "0x000000000000000000000000000000000025bcd07a0732c123567834f5109558", "0x000000000000000000000000000000aeb08a0b1a4442189448b4e97490568146", "0x000000000000000000000000000000000002a1744e4771705536a88f07e0f90f", "0x000000000000000000000000000000b938568293bd0724b0ea76c2ec34c4a829", "0x0000000000000000000000000000000000053296e8f3b9ad3af877dfa9c7c2a7", "0x000000000000000000000000000000f0ca1db6323996eba26bdc86dafef9d10b", "0x00000000000000000000000000000000001441a46c58af03d5645d52721d956a", "0x0000000000000000000000000000008bbf8f884013c66c28ba09c2fbd573b656", "0x0000000000000000000000000000000000206c391ca06fac27d1908e94570243", "0x0000000000000000000000000000002d4f5aaed88ba4f79612d53b804ca8f194", "0x00000000000000000000000000000000001674011c96392df08970fa6b7b4cb8", "0x0000000000000000000000000000009f88297c1729d76c4d9306853598c91325", "0x0000000000000000000000000000000000256f51adfcacc3c1e340be4d32d3e9", "0x0000000000000000000000000000000ab9955eec0d74eb799afed2a802b24d75", "0x00000000000000000000000000000000001fcbe43ea105b30d36ed0b21b03411", "0x000000000000000000000000000000d66b1d5433f1aa5305cd1edce7c22de466", "0x00000000000000000000000000000000002331546a256b8a3b751956806680d4", "0x000000000000000000000000000000e97954ad6cd6f45fb15c91434121db4304", "0x00000000000000000000000000000000002e20a97e09d50f227ced47e7a98250", "0x0000000000000000000000000000001ebbc27eb9ebededefba79522eb58ae89b", "0x0000000000000000000000000000000000090efa4974e566e81d1177b85a30be", "0x0000000000000000000000000000005eafa070b9c9632404052642e3bc14f9fd", "0x00000000000000000000000000000000001489068864102daca6a6b8bc4d448b", "0x0000000000000000000000000000009ebc91aaaac036a6477cadbe54e8556dfd", "0x00000000000000000000000000000000000ef6d835e2ed3343b95c82c8c54037", "0x00000000000000000000000000000033b28b529dff46e93af4e7422530478e4a", "0x000000000000000000000000000000000020a86c2f8591bf190bcddcc03c42fb", "0x000000000000000000000000000000a9679d0acc088f7dc27bf6d866bcd2dda2", "0x00000000000000000000000000000000002fb9d0d2d4099402bed74f738f64cc", "0x00000000000000000000000000000023b09f876a29a061582848a8b9a5870c12", "0x00000000000000000000000000000000001d5bb906f03f0d49e9c4791bc43af9", "0x00000000000000000000000000000017aac9854ea240d8ec97bf760c4d4ba870", "0x00000000000000000000000000000000000b227a556c414ada0dc75bb303e30e", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000009b624fa65d1a24b7f14a8f25f3789622af", "0x000000000000000000000000000000000013d47bff8c630e847b70e2732fd3f0", "0x00000000000000000000000000000061d21663e93132f32921075f4c936a84df", "0x00000000000000000000000000000000001a74ca4e118fb480b9b999902989a3"] -proof_b = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf", "0x00000000000000000000000000000000000000000000000b75c020998797da78", "0x0000000000000000000000000000000000000000000000005a107acb64952eca", "0x000000000000000000000000000000000000000000000000000031e97a575e9d", "0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4", "0x00000000000000000000000000000000000000000000000c410db10a01750aeb", "0x00000000000000000000000000000000000000000000000d722669117f9758a4", "0x000000000000000000000000000000000000000000000000000178cbf4206471", "0x000000000000000000000000000000000000000000000000e91b8a11e7842c38", "0x000000000000000000000000000000000000000000000007fd51009034b3357f", "0x000000000000000000000000000000000000000000000009889939f81e9c7402", "0x0000000000000000000000000000000000000000000000000000f94656a2ca48", "0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f", "0x0000000000000000000000000000000000000000000000093fe27776f50224bd", "0x000000000000000000000000000000000000000000000004a0c80c0da527a081", "0x0000000000000000000000000000000000000000000000000001b52c2020d746", "0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632", "0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc", "0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62", "0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c", "0x000000000000000000000000000000b0804efd6573805f991458295f510a2004", "0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e", "0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47", "0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15", "0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd", "0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383", "0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4", "0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x000000000000000000000000000000f968b227a358a305607f3efc933823d288", "0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08", "0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f", "0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1", "0x00000000000000000000000000000052eebbd1f6f7554e837f60c44000ed14b6", "0x00000000000000000000000000000000001c1c045a3ec94b8801f2272cc0b3f4", "0x0000000000000000000000000000004d2ef74134578f6b431a9df071ffca4292", "0x0000000000000000000000000000000000291326ade7aa6f0dfc8900eab5580b", "0x0000000000000000000000000000002433eec6418a6dba820c9527e2581fc8bc", "0x00000000000000000000000000000000000e88b7daad19af2ac2f9bdf9e50ee2", "0x000000000000000000000000000000dcfce2c427155cc3e4d035735d3dd5ece8", "0x00000000000000000000000000000000002d7d473cac1a15d0fee8b22c1a7b3e", "0x1a4249b90be4602c8ff40c7c276160ee41b2a0f8a238ce7706e9face2db03d48", "0x162204b9d54d3ffd285c393a5a1ff76ee681474fd780a21a3cf7fac5c24fc2b9", "0x30279eb953d8ee79b2155c69c04e6443c5de6bf7e02886256dd7b3cd3c9502a4", "0x0d32c1bd21baf43e72d5d82d461ef54833807ff81a877adc822f27a6db88d754", "0x0fe15e055c0803d5ebe6dd77689b70cfd82138f008810ce24535c992daaff27d", "0x1fba82c012671212ce2fc13fd09bf8fba4f7d5875ab8d37495d1ccfcff287331", "0x090738a5842fa4d2699b3726aa0dd97cb59569b4be2c6825335ec4969f859dc2", "0x0c6cb72dabbc28abcf4a50c203534e066c29f48c24ca64d672092f263df3f9d7", "0x0f27fbea0d9145f815c288b50fe7e8c10b8185d325b5264624fd57102855d05d", "0x2a815cd3fd1c43c72ee0130465250ff771d1e7be2347e4ada331b83265a03450", "0x148b4ecf2ad7ed17409417086867ee27bc1b0906dbc9cbb3714c285071e2db70", "0x08e700a42b1d6d36ee65f8ebedf47d3a44463ff9fa579dce13b7492e20142c3a", "0x2e23c69521d572ff2152c50f8c9a9191535f4cf37f95f1e0428692e78842b642", "0x14519e0354365923fb41400c19866135b45e975d56a0980260bc99f0390b1d5f", "0x04caded1f05738f736cb5bcf08d785e395e58eb7738523a20638aa16bc51593e", "0x28787eaccd38383215ea21ec02895c32d979f68ca155f534a2e2d377bff6698b", "0x20a1b81fa96c58cf11c5762c5ceb731efdcb081fca2d34d5c463d2cf40e6da18", "0x11789a06fe3bf53833741d180f068d29534d5bb58a5c64b8119542e62b189fb4", "0x23d00fcd032ace719ffcbc513bfa177a55b04377d76455c2788d999d05d011e2", "0x01f0e81b57b4a73cc118e51ede18f8724debf25c2d109db6ef45280f99f1a3fa", "0x156d1c9b61749810de728f259c2c1c1fd4dbff97101426e26087ca461c93307c", "0x1c5d619ac3a478cfd06d5eebfd879960bb321236be173813f5e78d1366d32c69", "0x250cfae4e1dfc551406f1f3d10b649a637dcb7bcb0f6f697994cf96afd35d0c1", "0x242b999f58cf5f53c874d1092bd38725aa9ea076f5bc8f176efa9ea23393874b", "0x2e15748255c4a5e0e9fe38047341b692a967257de27a85a3a38681bc9f1602ea", "0x01ef83886ea7017253699cb6371988eb8e21b4f7023d7479ece4907fe6d4a6fd", "0x08db2dbc271e375b9312f695c59c48f313235b3432cad50921c8d9ad6dd7ad7a", "0x199309f2c2cd45c15a4abb0e6554a1615ff5a6e9488a8d900bbf835fc8f664ef", "0x074be7a3d88e31ab1b59c9208c012bcfb1f85f351c709e68134996891db52b57", "0x301b1011354d2ebf46134fc4d6d734bb6ed8542d719f38f5e09a376a580cad7f", "0x12968f3eccaa27e44f14d5aaac6ecb70c00d040e07536292e685d7cab03fc563", "0x2110a023c8c22fd2ed70270a2d0a265b92a32ce2217ffe1be9a5d7d5c25f512f", "0x1e8cf4c60c53900f0430d5b44de5804fe8b38299bc803beeb4216e1a289cf624", "0x12301cb908ccb28a2616e29b831ec7105b5d3ebf45ff5fe91d50a9dd53a50b52", "0x0f1029ed107d84ff2d6d4a416cbd01da3f3d7bf5b2209ce93ba424f4b85616fc", "0x1b431d016611b8abd684afd9e92331c3325967b1116bfa91d4f44e2f8e2c9fc2", "0x281e335a0fd117064c8ace3f01e02b134a19e9b9220571ebfaaaa0e3a12d34db", "0x22559c106f77e2ae95677d5e38e288343e3b7168371aec7d3aaab9ef8150af70", "0x13f113b1d9b590149cf08c3f6e90589cda5c7b98528866b891256cb9d5d814e7", "0x10252ef388e4c80246962e98b9e976fab2cd25e1e6f1e3fd2a7d4786c5218a97", "0x16b890723dfdebd9912a9207255f95cb800222165b6fae97ec46e461f23e83f3", "0x25caf77c7d2e8e069341ec90f3c8f6d64319cfd2d77cab0625cf0377285ba11c", "0x016c84288b0bc3c50eebbe250cdd5a4ee50b2c65a24ac64d0c930cbdecb95141", "0x20a537c045b069d47dc6315f45b391f60681222381e5059ec7c8b17bf677d911", "0x2594c0edfcd4064d215a3d797bc8e3b2f401c61f3961ae96ccbec8f8fd29e81f", "0x1c831d7047483ca00ed59bdb84c47ffb8bbebbae92aa164c7b35fcffbb8a35d3", "0x2ea7f60de52b8cd6b0bd06f861fc1f2c5ed1d1fbfa53caccdb836400a03df434", "0x275c6c8bd115f7d2ce196439e2330fad305c6745bab0bf1ce3f2fa32dadc3c43", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x2b3f4e210619347288731e7f0eea1ae60dd8696fe87319044864d099a03a9536", "0x0fecd3d2aebedeb8be2b0b7e3a74de9ec8bd2cb72851541463729e0715aef48b", "0x10bee385ad0c2cd3ff88ef4d630840749e4367f9add4a300fc4f545a7778e92c", "0x1fe792730eeafbd22c4eb80e86e2b40108b1e55b2a08db786289eea5745b9e3b", "0x04d411679da432816b213cd5580dda1fd6c2f258684c036be19b5b26baca583c", "0x159f17b655d2b8a803e0cfb564918628be52d3baa950ca1b127854491624f8f4", "0x225340463867d9252a1269013536e2e1dd219aa18eadef13c324b63d44679334", "0x1885e231554e02abb40ed54b72ebf09b883d0298a6bc06fc645a30365f370ef2", "0x233344517f25170972b8ba35d01f2df2e073d322993abce7df26796126e93498", "0x08990e8faa13b18b4433ec417c5cc596885e11ffd372d5f612c08cc79a5d5c80", "0x1e960a0c892b755c28e21dcbed816c1b182d7da43bae07f8ee622bd4485f79e7", "0x27b58e2ee290a179d349ace82752528b2ff946d60c092b99ef42f53c25d0c99f", "0x2a5cf8a3193107d982edd253002c7a52ab876b445dde8307ab78fbdca022d93c", "0x2b1ab4d5277f8c82750c1c7bd043889b71465ec64a9afc1bfa37d06b1ebd0725", "0x2a0dbf5c4373a58a83d5f2a031ea0615bf12800e33b70c3191a7cbb15966ced8", "0x1f272bb4a19d14a0abdfebc9fc83125e10623b9aef730f8d25f2bf5bead38ea9", "0x2c2339cf0ae7aff56091a568c1e2c3f01f52d8ed13400737fd31eaabcaffb9bd", "0x21f5fefe6b5fa0b5da71089befb74a1a39e52b4f830cb330c3c284e154614dfd", "0x1e6f6ba4b2444586b380dc4e2b3fad111ff1f4754420a846f53ea0789ebfb0ad", "0x1193d170b0b2dd0c4a04331a4b4aa3f12920f182ec3ab547837e30f1116ca584", "0x00000000000000000000000000000025704a15c9e2ce8a69558e7bbcdcbc7784", "0x2e5d36112770fb6c985681cafe40a8c99ad13f702309e7969801dd0ed080e727", "0x0eefc2585f591bb457183134e19ad643966272234d645514bf7868d6dd8ae2cb", "0x300803e4e2339ad39b9c31f228949bbeaf9c74b7101e7be1930b088126247eaa", "0x2bb562a50ed944b438b83b01f200101a34faef7f296a75c84c731755ebddbc1a", "0x1288e0b9c742af39cbcac21357c1b29511b0bbdd3d0e3cf5e14b2eef68a28ab3", "0x20f089131cc96d86ff1cfb67fa3f51670f4bad30158751b2587354bbec76cdf9", "0x1a26c6d3e633f9bf8434cf755b5f1217dad0d455071a97a7bcf85b824f5cf07a", "0x0d7e9b8a51fccf910ec25bdbd13e70b34bd6ea6f4d629fa744f9cdf5f2beb1cf", "0x0b40f28ce428e64df9cf5a024133fc420f39decf5f6af020cc3211ab298d4631", "0x0ca4f189dde7a55fe829f46681232904f6670249a22e0deb47222bd309523a8a", "0x2c544f2e31143783977645edb2a6bdb39b875053963bfa1a5b3ae9de204a7ebe", "0x00aae4454eb48fb18ff60db6b9d015abea2e770a2f7d86d121522b834c791ba5", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x2d9e5bff47207d82533e2445959941181cc890c5779bc7f24d6e8a7b9e425b5c", "0x0aea3c0c317c441a5775a9849108d7a6889b39128235f717b09b184aa08e4eb7", "0x1ca5bc6fb37c55a562f4991901c39902f42d14db71284116df74cb4e7d55e493", "0x220fed26d64cd69f40e6d145a423e4a3c8cd0dce747e7d51647441270ad4d774", "0x15be574c9358889257aa2a30ff7b5fcc31a57da7032296e2c1201c49a44bbdb6", "0x2de539925525bedd3b7f43a9c6bf0f713151a17f79ac7ff4a9cd27b15ffe892a", "0x083086693dbf465211741e2cbff70ff38eb08383faf22d397eb2742c8ad7396a", "0x1fdfa258a890598816e807c50058d7a1462edd5ff196a2eae0f862e454b49aa1", "0x10c434c6daaa8226fa8e3e302123dfdc4455cf68063df518949df5a65a945213", "0x0000000000000000000000000000006472a7874de2c454a4591ed7784df1c104", "0x000000000000000000000000000000000008c46ac53d2c4ad0c26a5d6c790082", "0x0000000000000000000000000000005e422f9cfb8725800de60dfe0a8d4104c0", "0x000000000000000000000000000000000000f10fd4e4de81a0c00073ec91c274", "0x000000000000000000000000000000b20813090eca76bc6aa4a699b1ec8d5d6d", "0x0000000000000000000000000000000000292cc9f8a744eb00e0903c29ce87a7", "0x000000000000000000000000000000350a368b415fbb99fa90a26a42b1a3affd", "0x0000000000000000000000000000000000280eb9275cb05a3435f464d1dc369d", "0x000000000000000000000000000000280df6505e20c7725fe6d29439f96ee05d", "0x000000000000000000000000000000000017ef5033a08535451e2747827aa94b", "0x0000000000000000000000000000002f9ba89ae91b4e4a4ff8ccbd0526faad2f", "0x00000000000000000000000000000000001c2013561dafcc02cb03220bdf23c4", "0x000000000000000000000000000000aac102c400f9e5da0321ded4510994434b", "0x00000000000000000000000000000000001ec8ab9cc834b492fde124962f04a1", "0x0000000000000000000000000000000673dbd698da8b8cce450d2a083aba9987", "0x00000000000000000000000000000000000a49e55bb040249cb41c63cea901cd", "0x000000000000000000000000000000133d92af8d76ee0c74a12081ee7b2ef8c4", "0x0000000000000000000000000000000000240f552d1c6cbb007650e4b142e0a5", "0x000000000000000000000000000000e29c6e7d982ec08d51c79d6261c28d742d", "0x000000000000000000000000000000000021baeec04d9be419c923626034e7b3", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x1e940a528b42d8230e7d4dff76262a80986c0d00b2c02a9bc0559e36212d1547", "0x1ceccf21ac39f70d76ad6f7fe0dcb33b6af04555a0b1959e4714d65925e4e253", "0x096139d757046cdbdb7ee89a95f112f70882a43a46c2f739d9be115dda013420", "0x2f9c8ac67c7825b08eff0e7f7656a671f4c64e5601f2efab35b1b795801eec04", "0x2077e648e1704851cdffd7e6e56311634a7b741bab77ca34d9dff12a6a2bfe99", "0x115d48c4a97aeb3c447a060f9e0d675b0dc7f4a05a3f5776e2f279f3a165d7dc", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000000000fd38c45c3ec5b841482a80e3a56ce82555", "0x00000000000000000000000000000000000ad70b03f092f60af3e0ce1bb29d2c", "0x0000000000000000000000000000007a184d5342c90c634c0b1a050f0b97c9fb", "0x0000000000000000000000000000000000271f42abcb3bc1f0332e4b3ca85e1d", "0x0000000000000000000000000000008256322bbe2c1b8cd9d84e5ff6123477f2", "0x000000000000000000000000000000000025cab962761681dd9547f4c78814df", "0x0000000000000000000000000000008c4234510e5825c02b9ac427bcbf8e279a", "0x000000000000000000000000000000000013a14e0d7fc073c44643af38cc5396"] \ No newline at end of file +verification_key = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000000000000000000000000000004", "0x0000000000000000000000000000000000000000000000000000000000000005", "0x0000000000000000000000000000000000000000000000000000000000000006", "0x0000000000000000000000000000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000000000000000000000000000008", "0x0000000000000000000000000000000000000000000000000000000000000009", "0x000000000000000000000000000000000000000000000000000000000000000a", "0x000000000000000000000000000000000000000000000000000000000000000b", "0x000000000000000000000000000000000000000000000000000000000000000c", "0x000000000000000000000000000000000000000000000000000000000000000d", "0x000000000000000000000000000000000000000000000000000000000000000e", "0x000000000000000000000000000000000000000000000000000000000000000f", "0x0000000000000000000000000000000000000000000000000000000000000010", "0x00000000000000000000000000000060e430ad1c23bfcf3514323aae3f206e84", "0x00000000000000000000000000000000001b5c3ff4c2458d8f481b1c068f27ae", "0x000000000000000000000000000000bb510ab2112def34980e4fc6998ad9dd16", "0x00000000000000000000000000000000000576e7c105b43e061e13cb877fefe1", "0x000000000000000000000000000000ced074785d11857b065d8199e6669a601c", "0x00000000000000000000000000000000000053b48a4098c1c0ae268f273952f7", "0x000000000000000000000000000000d1d4b26e941db8168cee8f6de548ae0fd8", "0x00000000000000000000000000000000001a9adf5a6dadc3d948bb61dfd63f4c", "0x0000000000000000000000000000009ce1faac6f8de6ebb18f1db17372c82ad5", "0x00000000000000000000000000000000002002681bb417184b2df070a16a3858", "0x000000000000000000000000000000161baa651a8092e0e84725594de5aba511", "0x00000000000000000000000000000000000be0064399c2a1efff9eb0cdcb2223", "0x0000000000000000000000000000008673be6fd1bdbe980a29d8c1ded54381e7", "0x000000000000000000000000000000000008a5158a7d9648cf1d234524c9fa0c", "0x0000000000000000000000000000002b4fce6e4b1c72062b296d49bca2aa4130", "0x00000000000000000000000000000000002e45a9eff4b6769e55fb710cded44f", "0x00000000000000000000000000000072b85bf733758b76bcf97333efb85a23e3", "0x000000000000000000000000000000000017da0ea508994fc82862715e4b5592", "0x00000000000000000000000000000094fa74695cf058dba8ff35aec95456c6c3", "0x0000000000000000000000000000000000211acddb851061c24b8f159e832bd1", "0x000000000000000000000000000000303b5e5c531384b9a792e11702ad3bcab0", "0x00000000000000000000000000000000000d336dff51a60b8833d5d7f6d4314c", "0x0000000000000000000000000000009f825dde88092070747180d581c342444a", "0x0000000000000000000000000000000000237fbd6511a03cca8cac01b555fe01", "0x0000000000000000000000000000007c313205159495df6d8de292079a4844ff", "0x000000000000000000000000000000000018facdfc468530dd45e8f7a1d38ce9", "0x0000000000000000000000000000000d1ce33446fc3dc4ab40ca38d92dac74e1", "0x00000000000000000000000000000000000852d8e3e0e8f4435af3e94222688b", "0x0000000000000000000000000000006c04ee19ec1dfec87ed47d6d04aa158de2", "0x000000000000000000000000000000000013240f97a584b45184c8ec31319b5f", "0x000000000000000000000000000000cefb5d240b07ceb4be26ea429b6dc9d9e0", "0x00000000000000000000000000000000002dad22022121d689f57fb38ca21349", "0x000000000000000000000000000000c9f189f2a91aeb664ce376d8b157ba98f8", "0x00000000000000000000000000000000002531a51ad54f124d58094b219818d2", "0x000000000000000000000000000000ef1e6db71809307f677677e62b4163f556", "0x0000000000000000000000000000000000272da4396fb2a7ee0638b9140e523d", "0x0000000000000000000000000000002e54c0244a7732c87bc4712a76dd8c83fb", "0x000000000000000000000000000000000007db77b3e04b7eba9643da57cbbe4d", "0x000000000000000000000000000000e0dfe1ddd7f74ae0d636c910c3e85830d8", "0x00000000000000000000000000000000000466fa9b57ec4664abd1505b490862", "0x0000000000000000000000000000009ee55ae8a32fe5384c79907067cc27192e", "0x00000000000000000000000000000000000799d0e465cec07ecb5238c854e830", "0x0000000000000000000000000000001d5910ad361e76e1c241247a823733c39f", "0x00000000000000000000000000000000002b03f2ccf7507564da2e6678bef8fe", "0x000000000000000000000000000000ee40d90bea71fba7a412dd61fcf34e8ceb", "0x0000000000000000000000000000000000140b0936c323fd2471155617b6af56", "0x0000000000000000000000000000002b90071823185c5ff8e440fd3d73b6fefc", "0x00000000000000000000000000000000002b6c10790a5f6631c87d652e059df4", "0x00000000000000000000000000000029a17181c7934fc3fdbd352eac5cb521b9", "0x00000000000000000000000000000000001f497cbf5284ff29a2d336e5991999", "0x000000000000000000000000000000072bd9c0c6beda1fdee6d4ff0432ba9e1b", "0x000000000000000000000000000000000013ea38a0bd2aa751a490a724fac818", "0x000000000000000000000000000000c599f63dcd3edd49f08ae5c3141c1e3493", "0x00000000000000000000000000000000002bdb36be0bea09950dd32a8ccf6fbc", "0x00000000000000000000000000000047f27f29724e7f19eba0340256a0bd4b7d", "0x00000000000000000000000000000000001c1c5ccf87a962129ca785f8f35120", "0x000000000000000000000000000000c5c71efdae00679bbe4a95096e012b1817", "0x000000000000000000000000000000000017a365de041e317817d0135f2b48e0", "0x0000000000000000000000000000008ae711ac402f7848d719c93a89ba8d39f1", "0x00000000000000000000000000000000002b6fb40ed8a1935226f4f9786a0499", "0x0000000000000000000000000000002f03a71501d83de1da5715a4e9462d6198", "0x00000000000000000000000000000000001644064443b8546f48eae693af47b8", "0x00000000000000000000000000000083763ab1b6e8fe269b2fe4c7b9c448c08d", "0x000000000000000000000000000000000021d7cc18c59676a8eeb47c0111c251", "0x000000000000000000000000000000b5f937153073e03ea7d51a996e0ebc2e6b", "0x000000000000000000000000000000000011ddd0e26457373eb06e0493177672", "0x000000000000000000000000000000c5f6eb9f6fc8fa99811a4a88c74a6d018b", "0x000000000000000000000000000000000025bcd07a0732c123567834f5109558", "0x000000000000000000000000000000aeb08a0b1a4442189448b4e97490568146", "0x000000000000000000000000000000000002a1744e4771705536a88f07e0f90f", "0x000000000000000000000000000000b938568293bd0724b0ea76c2ec34c4a829", "0x0000000000000000000000000000000000053296e8f3b9ad3af877dfa9c7c2a7", "0x000000000000000000000000000000f0ca1db6323996eba26bdc86dafef9d10b", "0x00000000000000000000000000000000001441a46c58af03d5645d52721d956a", "0x0000000000000000000000000000008bbf8f884013c66c28ba09c2fbd573b656", "0x0000000000000000000000000000000000206c391ca06fac27d1908e94570243", "0x0000000000000000000000000000002d4f5aaed88ba4f79612d53b804ca8f194", "0x00000000000000000000000000000000001674011c96392df08970fa6b7b4cb8", "0x0000000000000000000000000000009f88297c1729d76c4d9306853598c91325", "0x0000000000000000000000000000000000256f51adfcacc3c1e340be4d32d3e9", "0x0000000000000000000000000000000ab9955eec0d74eb799afed2a802b24d75", "0x00000000000000000000000000000000001fcbe43ea105b30d36ed0b21b03411", "0x000000000000000000000000000000d66b1d5433f1aa5305cd1edce7c22de466", "0x00000000000000000000000000000000002331546a256b8a3b751956806680d4", "0x000000000000000000000000000000292b512a940306c9b122a0feb4e9780af9", "0x00000000000000000000000000000000000904e02f0334f3a3f72e65ce82f34b", "0x000000000000000000000000000000778103226eff8f576eba0a0a2ffa134d57", "0x000000000000000000000000000000000001fe54f93991aa61a056f75e5137b0", "0x00000000000000000000000000000089058e539eb10c10fa13dd50e39517555d", "0x000000000000000000000000000000000009e91383ce6118cef78093d2c550fc", "0x000000000000000000000000000000d95e2e1bf12461b508cc8d63fee4a8613d", "0x00000000000000000000000000000000000ab28965260d651673541f10f2e02f", "0x0000000000000000000000000000008f6f361c7fe163277c1022dacf2a0f307b", "0x00000000000000000000000000000000001e47e6531c4ec673e9c18a9062c1df", "0x000000000000000000000000000000e55ba7b44de2c0927d4df995625325c68c", "0x000000000000000000000000000000000005d3e2113696d710431294256dab1a", "0x000000000000000000000000000000150b1462a7b440ef041dc9e7af7e1d1f15", "0x000000000000000000000000000000000017b03e1a64b4988e05ca4291f3ce6a", "0x0000000000000000000000000000008d494ccfb05451bea33fe43623c45a9d7b", "0x000000000000000000000000000000000001ed433638a57a66f8205daea09e50", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000000000f68b70e0e4b0cb9e2c7bd64fa4b75b32dd", "0x00000000000000000000000000000000001bcedd9106bdd4e13e0b751c672a83", "0x00000000000000000000000000000042fd857eb4bf620db08b0e181807df9f59", "0x00000000000000000000000000000000001ccfa89524772b4bd5b6bf6741d71f"] +proof_b = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf", "0x00000000000000000000000000000000000000000000000b75c020998797da78", "0x0000000000000000000000000000000000000000000000005a107acb64952eca", "0x000000000000000000000000000000000000000000000000000031e97a575e9d", "0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4", "0x00000000000000000000000000000000000000000000000c410db10a01750aeb", "0x00000000000000000000000000000000000000000000000d722669117f9758a4", "0x000000000000000000000000000000000000000000000000000178cbf4206471", "0x000000000000000000000000000000000000000000000000e91b8a11e7842c38", "0x000000000000000000000000000000000000000000000007fd51009034b3357f", "0x000000000000000000000000000000000000000000000009889939f81e9c7402", "0x0000000000000000000000000000000000000000000000000000f94656a2ca48", "0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f", "0x0000000000000000000000000000000000000000000000093fe27776f50224bd", "0x000000000000000000000000000000000000000000000004a0c80c0da527a081", "0x0000000000000000000000000000000000000000000000000001b52c2020d746", "0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632", "0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc", "0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62", "0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c", "0x000000000000000000000000000000b0804efd6573805f991458295f510a2004", "0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e", "0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47", "0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15", "0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd", "0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383", "0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4", "0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98", "0x0000000000000000000000000000004ae614a40d61d28f36aaf03d00a064355d", "0x000000000000000000000000000000000010edd34b6c69cb31a6a833a1d040d2", "0x000000000000000000000000000000f4976ee83b95241474007fdc30b06ebdd7", "0x000000000000000000000000000000000019cd0d7e4577008a8335c6260be826", "0x0000000000000000000000000000004ae614a40d61d28f36aaf03d00a064355d", "0x000000000000000000000000000000000010edd34b6c69cb31a6a833a1d040d2", "0x000000000000000000000000000000f4976ee83b95241474007fdc30b06ebdd7", "0x000000000000000000000000000000000019cd0d7e4577008a8335c6260be826", "0x000000000000000000000000000000f968b227a358a305607f3efc933823d288", "0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08", "0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f", "0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1", "0x0000000000000000000000000000007376c0278bcc77156c008b389f6bd12e8f", "0x0000000000000000000000000000000000176ebed74bf3b57ca42a2fac842809", "0x000000000000000000000000000000fc4a601439d45b9ce23c9d9cc37cb21dd2", "0x000000000000000000000000000000000017dc6f8c53261c44cd0348a9970d88", "0x000000000000000000000000000000292042e9c3c101d8dd41b3acfc0db429a2", "0x0000000000000000000000000000000000114f6b3755c65915e12f13533cdd41", "0x0000000000000000000000000000007bb311a6bd5f4f3d543ca30a1a0201614f", "0x00000000000000000000000000000000000871a5a04dda33543cf59b3babf733", "0x03ecb02e48ba68818287222348fc537135b6426d4580ea31cdd540250a7a95fb", "0x2c779e44987737a835c92393388504ebf27da5db3438865f760cb56ee5856a06", "0x0ac17380181974c0082ef0fada047fc7906a94dc18e5be249dd29e52961522e0", "0x206c623397f11ed76a292c7c605fe56c1ae4f6babb6889786aaff461535cf79e", "0x11dfbe6d0977046fd72b55bdb9b41f983fc06ea6404cb36efdf1786d6f0dcbf7", "0x1081a4f21029bfcf4f8388257bf88d932963b2368c4fde96836fb6f023f16622", "0x2e981de982d368f04b0a49e537a05ed5583080c3eafed9617bd06e1214641be9", "0x2571d21e04b1d59935490270a4789e53042f18e15fc7b94dfd267c8deadfc74e", "0x0f70f3f5319d3564bcc6fad428552eefce8f341ced5187fa186d0f099315f225", "0x18f7ee010c96f63d18d2a277e5f5a8ef19b525907817d69616d24495ad804021", "0x1cf7e347bae24a2c1a93b5fd11ff79e68bd2c1bd32056df6d2e1582d17db1d8d", "0x01c451a702451ea9871b7e19d3e2052d8fa49a571ae46616453f27d324cfc907", "0x0614dbf2404cb5fef2e5408f1115502954097981a5ea67d1f80812fa247b1f93", "0x09884374bb354fdb4b118f4da44cd37e75ba7a655201f94cc4064acbdc35887d", "0x158211f68576bcafd791ff02039bb8246b1ba94d99f30a0f282565dd8d82ce0b", "0x0a5231e4039c7b7e0ad77d319958403997a33a0be31e71032733cd70067b14db", "0x2803fc0a9f60d9e202eb6caddcacfbb94a5a7df2695c2a0c909815093ca1864c", "0x0faa80f3cef0e86746df7518f865936959d65eb64ccb05bfb574ac5561683eae", "0x298544d77ee6f4cae7aaa4e9203a233fa18dab360d6f54daf9f8801802586d58", "0x0ba76e9cadf0380b82a3b5ec1c71b80295ce3caeec73aefecffed90f28c1b012", "0x0d965885fc07c4a140f50a83cb750c876191651ee47462d0931e0e67bc9ab5cb", "0x0aad443f96fbde49595f31a47d233ca83ed2bcda86801a8fd7a596ea666c7716", "0x298ef11d346c061b8899cb10c0cd7150aa2d6c554340cf2ee6aa76125e7d1e7f", "0x27518b0512f1efb3a79650941d3adb015b357c92a8c06e086be7b3e7666cea47", "0x0cd6b10a38d5af7f0a5fa97c0ffcba406e8a65a92fe050b3b79f3f1f45d723e2", "0x2f5e1210a841f9c6a7ee7d7f290479696387a58192cb775a64adf0dc225e3d4f", "0x2ffd390be1aecefc25137d01e5b7a85410254ae9e21e7067a9869217cb828ee1", "0x244a77246b5beb3e0e38c8dda39a516050303e83c051300d08bbe5450320b47f", "0x16ed38ff1019df1d168974833ccc96d8648d05c2823021d45e1d5599998a8aec", "0x24cbbf8ca1a5bb082c1081d9252a5e964ff7aae4d83e04468db55960b80a585f", "0x01b3a78bcc6e7529c6ded587b8958d903ef990421d5706afbef64a7976a51084", "0x2c3a013cdecd027b32c8c99c163dd822df374ef018aac8f3d1fb8d57335f9503", "0x0ad83466928e5d70e1e0bb26633a1e0c61399733c15fffafb22df18029e583d6", "0x095023de752480ca3edd408d3c34d732bd9836919e84931d3f42a978867bc53e", "0x283d221f0a2e6b6616bc3eda23e15bb8c8b459010014db7608e646c70ea1da2e", "0x1390c81536ca3d71228eeccf9844702aa3df012bbc3902fe30323f55ee8c7872", "0x0ef66f0302753884f05043080104589e1bf036566a9a00d4688d3c7910631508", "0x15eceeed97d9267597c028fafac72dba40f3ea441880bdd2202b30846a243044", "0x2b38e3f3b5193811df1bafd58432d5abd1c5f575a5d9c2a449682a0f2f035034", "0x2bbcc40d11d6a96c85a63162143ec53314573bb0af7c32d89b791394c80d14a5", "0x22d909e8fb5152b5b98f7cb3fc38f4ef7d7e8f2a857347da59ba2e979bd2ec96", "0x29e3f7a95437fe6ea1e72cd4c7c2fcf1892ab22ba69387f1a6a795e91bcc26f2", "0x02d8c8d031ada707d85693ed106135cecb7fe52de73eedbc54a91a2c856d0de1", "0x28020fb768c50bf52497832c04fb0e14cdb651b98b80864d0b68228ddfd922a0", "0x24d61051f82ff93eb42b5afdcad9e236c669f9f849bf811a853f1e9cc302f8ce", "0x250e89de38769cf70e6cb3685f99e39f44d8ebc1a468930f49e1d80342092b6a", "0x0ad45df677495b9199c57f620db716c543fb6437d574453b7721c2faee6316ba", "0x043d8715e16e3f2dc5a537355c0576254a36db25002f13958696ed13c24add46", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0bb8cb6a256f110f134a15b66b644eb49dc8e0239f92489408e6265a323bb513", "0x18f02f61683cf6a7492291a7041ee1b3cfa8dfb5aa40e2f6571d13750f0f459a", "0x0a982c10c93ae173751f4165e6456c9b85e2551bd503919acae78c801ccc0e1e", "0x0b6e6266bdc6d44d05ae76d2db249877a46ad978fc758654a3a6a7208d2725a6", "0x20de00721f30db8280aa6804c90f3fbe23477e1f746a8eff61c4c5b2af7e821c", "0x1321548f766ded3432627a50704d233455c61d8e59afec2883dbe2f381c033f9", "0x00c56c902b14aa59f6f59badf20f59c51b08aeb6afbdd97a5ac7b98b998b0a56", "0x1745c01290e99476fa655e5fcf2e5b3d24f42624cbd25a40f60af3f3e8489512", "0x08e915bebf8f6c86b332a681d35c57dcd0e0804f22e4e78884ab5edc0a41d6d0", "0x0c77b29e3a0c4368ce5231f94d13fa9b84a6e350cc8f2a57b3f6920a2bf0e879", "0x07ab821c4f07e1dd1cce43b9d9dbf4c9da2e22fea675a57ecf5a47a6992059a2", "0x0bcf85d1f4e34e7598a68bc09cfacf119b0afa1193ad4163096e44ca8eef7a22", "0x0c8a367da01b9097d24eb7b5471c6bd049f7938080bb8cc6fb92945fa934faf9", "0x2cda5caa3a93dcc134cf176f4ad6c79577d273bd2706da3fcaad92a9bc336ac8", "0x2c19cbfce048ef9bb9efb5b9875645b0bc7825aa1a05ad71dbbd3a34d1d76501", "0x28d7f11c2b6b7ff8717b79b098e5bd37eb39a8ea5d03b15339c86fb93e497d97", "0x21ba86c3baacb0fe4270c64c1a5f2861af2f5aa1d6391afe8214e1ce9eac8dfa", "0x0c5289ff2fe581ccf0caa97b4041d381e384c4aef0417edd4dafa7f64a3bfa6f", "0x0c744b0b301542ec4f334696945d7b89b137c5b9434bec277dc938c3dc9ca7aa", "0x006d246e7b0ad18157fa925981f097121fe34cc769128fd8993c4d15cfdf0aee", "0x00000000000000000000000000000022a7ebdc5723cfdb5d73c4c0392e43c407", "0x160d495d0b4462662665faccb1d65d81f0c3f006254a6082a0ceffc49483d76a", "0x24a5a2b9bef1abc3a818d2f27ca5cca7e1b3da34ea6056f338ac54638e26c3b0", "0x0a3dcf45eb6c14391ed8aeab11cb9460f85cb11a1ecb868ad75095796c0f5dac", "0x160c8087a99bf109389ca20d0ce624f71dd2e40fe64d62712e45669ed550fd61", "0x1a65519621040c52fdec5594d095add265c99210929eeb29a3a8180b480bb313", "0x09bf095c40c00dce181347b0d8eaa83ecd0f1f8fcb5dab34ffe19e219672e681", "0x10f3444d7a623e54ad2e882c436191975143217e9f8121c8770a3bbd3ec183ce", "0x0cd68d59322f30bdaf0a6a628f095f880ff716b157ef9a2d589f2cfc40b53e3d", "0x20732eab49adfd109626e0e84496a929a690377e98ee03f13f66ad4541949300", "0x28c850b8bc7f6ae88835bed342eda477e8d1f013a4db34b7ff33198e0a9f8e09", "0x14d234765f29b713df4d1291d452c73a5dc00458242df1be96e04ffb0a3c396e", "0x162572b68ab59291f430cf3113d4fcd3ddca59c4808c134345f6765693f8e1ce", "0x0bc37cb2ffd0f1691bf4d8c621d49f8c23ff58989d09d96c019cc6fc9a46e155", "0x0bc37cb2ffd0f1691bf4d8c621d49f8c23ff58989d09d96c019cc6fc9a46e155", "0x2aa58bd9f811c2970dcefde8c31c2c6db2349eed5161f80c0280a3acbd9f4f0d", "0x141198df3b9c1917d2e7a136ca3438fd9630719591c24388a0559873756d288b", "0x1975864b97d6ff0ace3d600020772ea32181c2f3e413ae67bac22e4a3bbcba9c", "0x2023d432e6630619c99c25a2f293f5ed78f373ee5212bff02b92f00a43bab0e0", "0x23cbaa3113b7265b926bc8811fccce701b3d4e4006ae6b66cefffd0e2f059fd4", "0x00000000000000000000000000000061e09b904168dcad01e82d26f8a21bb884", "0x000000000000000000000000000000000027a29682b86d1b09daa382868b245a", "0x000000000000000000000000000000efc6d7071b6c8cf492bc3ba72f4eda84c5", "0x000000000000000000000000000000000010860d04901949ad63a94863c77149", "0x00000000000000000000000000000036cacf503222db1b5d0edd58aafc1e74f9", "0x00000000000000000000000000000000000fef16ca13117c1f45f6df0782c273", "0x000000000000000000000000000000013704a507a82f6224d7c369d3d6c3929e", "0x00000000000000000000000000000000002887168ff50b7339d4d181d2a84cc0", "0x000000000000000000000000000000e57f500eab5f7d08ac3c93ce080dc1f15e", "0x00000000000000000000000000000000000c720872540cd88fec315c3e6a7625", "0x0000000000000000000000000000004b6897120d1858d29ac10cba52cf73dc44", "0x000000000000000000000000000000000019a9523d9a2481b5dbb1c23cb9686e", "0x00000000000000000000000000000052442fa24d3d5c3b9a608d8259757905a4", "0x00000000000000000000000000000000001c58b3787ffa3edd9f049c1c775a85", "0x000000000000000000000000000000f5737a5b8d278973356217e75bdc986ea2", "0x00000000000000000000000000000000001e0959f30c996ac7e3b265bac2de9d", "0x00000000000000000000000000000030122ef6c7a097b6b2ea6efa763797b8b4", "0x0000000000000000000000000000000000191344dd8af6c1c1c3beef933de271", "0x0000000000000000000000000000002f38961e4eb47676a42a5b59457e19a7b1", "0x000000000000000000000000000000000002936d1fa64f399018fbf60a1f2001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0f349727b02c8c3916e6904450b4db7d748c746d693f12acfd44757e349ae543", "0x109b539e615d399af085519623a8f0ea43fd3e672e8b3397deb033110b896ba7", "0x1d2d7546c079198782bc8c1ecf377c86567d90d05988acd013af254a84ccfca2", "0x11922ebe299248b1a194ff41750bbad0297b8e4db3944036983764ba171195a1", "0x14cb035cb0d920e42127d67ed6763fd0cdadeac07c0aa57ab5c038a501aca88c", "0x2e82b6bc3d9337d1f2c080ed47e935308317c159408ff3a054718e737f827a49", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000000000c883c136e90256f3059fb812416fe61171", "0x00000000000000000000000000000000002cbe86e3f824a75195f942b5de0abe", "0x000000000000000000000000000000ff2335151394b16f671dcfdc5ee78485f3", "0x00000000000000000000000000000000000fceb210dd93cd99b7bb225af47ae8", "0x0000000000000000000000000000001a95675079e3f1508e636cf69b7978db7f", "0x0000000000000000000000000000000000079f7a59ed7b4a3dda951fa8fbad98", "0x000000000000000000000000000000b15ed33e983574376efe5ae0c29c6bdd1f", "0x000000000000000000000000000000000004031f5fd23cf82aad9e5d0bfd0363"] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/src/main.nr b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/src/main.nr index 82090bb8602..91f7bb214b1 100644 --- a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/src/main.nr @@ -1,5 +1,5 @@ // This circuit aggregates two Honk proof from `assert_statement`. -global SIZE_OF_PROOF_IF_LOGN_IS_28: u32 = 463; +global SIZE_OF_PROOF_IF_LOGN_IS_28: u32 = 459; global HONK_IDENTIFIER: u32 = 1; fn main( verification_key: [Field; 128], diff --git a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml index 45a84c26eb8..33b300afae7 100644 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml +++ b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml @@ -1,4 +1,4 @@ key_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" -proof = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf", "0x00000000000000000000000000000000000000000000000b75c020998797da78", "0x0000000000000000000000000000000000000000000000005a107acb64952eca", "0x000000000000000000000000000000000000000000000000000031e97a575e9d", "0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4", "0x00000000000000000000000000000000000000000000000c410db10a01750aeb", "0x00000000000000000000000000000000000000000000000d722669117f9758a4", "0x000000000000000000000000000000000000000000000000000178cbf4206471", "0x000000000000000000000000000000000000000000000000e91b8a11e7842c38", "0x000000000000000000000000000000000000000000000007fd51009034b3357f", "0x000000000000000000000000000000000000000000000009889939f81e9c7402", "0x0000000000000000000000000000000000000000000000000000f94656a2ca48", "0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f", "0x0000000000000000000000000000000000000000000000093fe27776f50224bd", "0x000000000000000000000000000000000000000000000004a0c80c0da527a081", "0x0000000000000000000000000000000000000000000000000001b52c2020d746", "0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632", "0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc", "0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62", "0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c", "0x000000000000000000000000000000b0804efd6573805f991458295f510a2004", "0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e", "0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47", "0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15", "0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd", "0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383", "0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4", "0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", "0x000000000000000000000000000000f968b227a358a305607f3efc933823d288", "0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08", "0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f", "0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1", "0x00000000000000000000000000000052eebbd1f6f7554e837f60c44000ed14b6", "0x00000000000000000000000000000000001c1c045a3ec94b8801f2272cc0b3f4", "0x0000000000000000000000000000004d2ef74134578f6b431a9df071ffca4292", "0x0000000000000000000000000000000000291326ade7aa6f0dfc8900eab5580b", "0x0000000000000000000000000000002433eec6418a6dba820c9527e2581fc8bc", "0x00000000000000000000000000000000000e88b7daad19af2ac2f9bdf9e50ee2", "0x000000000000000000000000000000dcfce2c427155cc3e4d035735d3dd5ece8", "0x00000000000000000000000000000000002d7d473cac1a15d0fee8b22c1a7b3e", "0x1a4249b90be4602c8ff40c7c276160ee41b2a0f8a238ce7706e9face2db03d48", "0x162204b9d54d3ffd285c393a5a1ff76ee681474fd780a21a3cf7fac5c24fc2b9", "0x30279eb953d8ee79b2155c69c04e6443c5de6bf7e02886256dd7b3cd3c9502a4", "0x0d32c1bd21baf43e72d5d82d461ef54833807ff81a877adc822f27a6db88d754", "0x0fe15e055c0803d5ebe6dd77689b70cfd82138f008810ce24535c992daaff27d", "0x1fba82c012671212ce2fc13fd09bf8fba4f7d5875ab8d37495d1ccfcff287331", "0x090738a5842fa4d2699b3726aa0dd97cb59569b4be2c6825335ec4969f859dc2", "0x0c6cb72dabbc28abcf4a50c203534e066c29f48c24ca64d672092f263df3f9d7", "0x0f27fbea0d9145f815c288b50fe7e8c10b8185d325b5264624fd57102855d05d", "0x2a815cd3fd1c43c72ee0130465250ff771d1e7be2347e4ada331b83265a03450", "0x148b4ecf2ad7ed17409417086867ee27bc1b0906dbc9cbb3714c285071e2db70", "0x08e700a42b1d6d36ee65f8ebedf47d3a44463ff9fa579dce13b7492e20142c3a", "0x2e23c69521d572ff2152c50f8c9a9191535f4cf37f95f1e0428692e78842b642", "0x14519e0354365923fb41400c19866135b45e975d56a0980260bc99f0390b1d5f", "0x04caded1f05738f736cb5bcf08d785e395e58eb7738523a20638aa16bc51593e", "0x28787eaccd38383215ea21ec02895c32d979f68ca155f534a2e2d377bff6698b", "0x20a1b81fa96c58cf11c5762c5ceb731efdcb081fca2d34d5c463d2cf40e6da18", "0x11789a06fe3bf53833741d180f068d29534d5bb58a5c64b8119542e62b189fb4", "0x23d00fcd032ace719ffcbc513bfa177a55b04377d76455c2788d999d05d011e2", "0x01f0e81b57b4a73cc118e51ede18f8724debf25c2d109db6ef45280f99f1a3fa", "0x156d1c9b61749810de728f259c2c1c1fd4dbff97101426e26087ca461c93307c", "0x1c5d619ac3a478cfd06d5eebfd879960bb321236be173813f5e78d1366d32c69", "0x250cfae4e1dfc551406f1f3d10b649a637dcb7bcb0f6f697994cf96afd35d0c1", "0x242b999f58cf5f53c874d1092bd38725aa9ea076f5bc8f176efa9ea23393874b", "0x2e15748255c4a5e0e9fe38047341b692a967257de27a85a3a38681bc9f1602ea", "0x01ef83886ea7017253699cb6371988eb8e21b4f7023d7479ece4907fe6d4a6fd", "0x08db2dbc271e375b9312f695c59c48f313235b3432cad50921c8d9ad6dd7ad7a", "0x199309f2c2cd45c15a4abb0e6554a1615ff5a6e9488a8d900bbf835fc8f664ef", "0x074be7a3d88e31ab1b59c9208c012bcfb1f85f351c709e68134996891db52b57", "0x301b1011354d2ebf46134fc4d6d734bb6ed8542d719f38f5e09a376a580cad7f", "0x12968f3eccaa27e44f14d5aaac6ecb70c00d040e07536292e685d7cab03fc563", "0x2110a023c8c22fd2ed70270a2d0a265b92a32ce2217ffe1be9a5d7d5c25f512f", "0x1e8cf4c60c53900f0430d5b44de5804fe8b38299bc803beeb4216e1a289cf624", "0x12301cb908ccb28a2616e29b831ec7105b5d3ebf45ff5fe91d50a9dd53a50b52", "0x0f1029ed107d84ff2d6d4a416cbd01da3f3d7bf5b2209ce93ba424f4b85616fc", "0x1b431d016611b8abd684afd9e92331c3325967b1116bfa91d4f44e2f8e2c9fc2", "0x281e335a0fd117064c8ace3f01e02b134a19e9b9220571ebfaaaa0e3a12d34db", "0x22559c106f77e2ae95677d5e38e288343e3b7168371aec7d3aaab9ef8150af70", "0x13f113b1d9b590149cf08c3f6e90589cda5c7b98528866b891256cb9d5d814e7", "0x10252ef388e4c80246962e98b9e976fab2cd25e1e6f1e3fd2a7d4786c5218a97", "0x16b890723dfdebd9912a9207255f95cb800222165b6fae97ec46e461f23e83f3", "0x25caf77c7d2e8e069341ec90f3c8f6d64319cfd2d77cab0625cf0377285ba11c", "0x016c84288b0bc3c50eebbe250cdd5a4ee50b2c65a24ac64d0c930cbdecb95141", "0x20a537c045b069d47dc6315f45b391f60681222381e5059ec7c8b17bf677d911", "0x2594c0edfcd4064d215a3d797bc8e3b2f401c61f3961ae96ccbec8f8fd29e81f", "0x1c831d7047483ca00ed59bdb84c47ffb8bbebbae92aa164c7b35fcffbb8a35d3", "0x2ea7f60de52b8cd6b0bd06f861fc1f2c5ed1d1fbfa53caccdb836400a03df434", "0x275c6c8bd115f7d2ce196439e2330fad305c6745bab0bf1ce3f2fa32dadc3c43", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x2b3f4e210619347288731e7f0eea1ae60dd8696fe87319044864d099a03a9536", "0x0fecd3d2aebedeb8be2b0b7e3a74de9ec8bd2cb72851541463729e0715aef48b", "0x10bee385ad0c2cd3ff88ef4d630840749e4367f9add4a300fc4f545a7778e92c", "0x1fe792730eeafbd22c4eb80e86e2b40108b1e55b2a08db786289eea5745b9e3b", "0x04d411679da432816b213cd5580dda1fd6c2f258684c036be19b5b26baca583c", "0x159f17b655d2b8a803e0cfb564918628be52d3baa950ca1b127854491624f8f4", "0x225340463867d9252a1269013536e2e1dd219aa18eadef13c324b63d44679334", "0x1885e231554e02abb40ed54b72ebf09b883d0298a6bc06fc645a30365f370ef2", "0x233344517f25170972b8ba35d01f2df2e073d322993abce7df26796126e93498", "0x08990e8faa13b18b4433ec417c5cc596885e11ffd372d5f612c08cc79a5d5c80", "0x1e960a0c892b755c28e21dcbed816c1b182d7da43bae07f8ee622bd4485f79e7", "0x27b58e2ee290a179d349ace82752528b2ff946d60c092b99ef42f53c25d0c99f", "0x2a5cf8a3193107d982edd253002c7a52ab876b445dde8307ab78fbdca022d93c", "0x2b1ab4d5277f8c82750c1c7bd043889b71465ec64a9afc1bfa37d06b1ebd0725", "0x2a0dbf5c4373a58a83d5f2a031ea0615bf12800e33b70c3191a7cbb15966ced8", "0x1f272bb4a19d14a0abdfebc9fc83125e10623b9aef730f8d25f2bf5bead38ea9", "0x2c2339cf0ae7aff56091a568c1e2c3f01f52d8ed13400737fd31eaabcaffb9bd", "0x21f5fefe6b5fa0b5da71089befb74a1a39e52b4f830cb330c3c284e154614dfd", "0x1e6f6ba4b2444586b380dc4e2b3fad111ff1f4754420a846f53ea0789ebfb0ad", "0x1193d170b0b2dd0c4a04331a4b4aa3f12920f182ec3ab547837e30f1116ca584", "0x00000000000000000000000000000025704a15c9e2ce8a69558e7bbcdcbc7784", "0x2e5d36112770fb6c985681cafe40a8c99ad13f702309e7969801dd0ed080e727", "0x0eefc2585f591bb457183134e19ad643966272234d645514bf7868d6dd8ae2cb", "0x300803e4e2339ad39b9c31f228949bbeaf9c74b7101e7be1930b088126247eaa", "0x2bb562a50ed944b438b83b01f200101a34faef7f296a75c84c731755ebddbc1a", "0x1288e0b9c742af39cbcac21357c1b29511b0bbdd3d0e3cf5e14b2eef68a28ab3", "0x20f089131cc96d86ff1cfb67fa3f51670f4bad30158751b2587354bbec76cdf9", "0x1a26c6d3e633f9bf8434cf755b5f1217dad0d455071a97a7bcf85b824f5cf07a", "0x0d7e9b8a51fccf910ec25bdbd13e70b34bd6ea6f4d629fa744f9cdf5f2beb1cf", "0x0b40f28ce428e64df9cf5a024133fc420f39decf5f6af020cc3211ab298d4631", "0x0ca4f189dde7a55fe829f46681232904f6670249a22e0deb47222bd309523a8a", "0x2c544f2e31143783977645edb2a6bdb39b875053963bfa1a5b3ae9de204a7ebe", "0x00aae4454eb48fb18ff60db6b9d015abea2e770a2f7d86d121522b834c791ba5", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x07d74e351fd4cccf4e18475d25211efa8a359066fc693a5c8505ddb507e4b74b", "0x2d9e5bff47207d82533e2445959941181cc890c5779bc7f24d6e8a7b9e425b5c", "0x0aea3c0c317c441a5775a9849108d7a6889b39128235f717b09b184aa08e4eb7", "0x1ca5bc6fb37c55a562f4991901c39902f42d14db71284116df74cb4e7d55e493", "0x220fed26d64cd69f40e6d145a423e4a3c8cd0dce747e7d51647441270ad4d774", "0x15be574c9358889257aa2a30ff7b5fcc31a57da7032296e2c1201c49a44bbdb6", "0x2de539925525bedd3b7f43a9c6bf0f713151a17f79ac7ff4a9cd27b15ffe892a", "0x083086693dbf465211741e2cbff70ff38eb08383faf22d397eb2742c8ad7396a", "0x1fdfa258a890598816e807c50058d7a1462edd5ff196a2eae0f862e454b49aa1", "0x10c434c6daaa8226fa8e3e302123dfdc4455cf68063df518949df5a65a945213", "0x0000000000000000000000000000006472a7874de2c454a4591ed7784df1c104", "0x000000000000000000000000000000000008c46ac53d2c4ad0c26a5d6c790082", "0x0000000000000000000000000000005e422f9cfb8725800de60dfe0a8d4104c0", "0x000000000000000000000000000000000000f10fd4e4de81a0c00073ec91c274", "0x000000000000000000000000000000b20813090eca76bc6aa4a699b1ec8d5d6d", "0x0000000000000000000000000000000000292cc9f8a744eb00e0903c29ce87a7", "0x000000000000000000000000000000350a368b415fbb99fa90a26a42b1a3affd", "0x0000000000000000000000000000000000280eb9275cb05a3435f464d1dc369d", "0x000000000000000000000000000000280df6505e20c7725fe6d29439f96ee05d", "0x000000000000000000000000000000000017ef5033a08535451e2747827aa94b", "0x0000000000000000000000000000002f9ba89ae91b4e4a4ff8ccbd0526faad2f", "0x00000000000000000000000000000000001c2013561dafcc02cb03220bdf23c4", "0x000000000000000000000000000000aac102c400f9e5da0321ded4510994434b", "0x00000000000000000000000000000000001ec8ab9cc834b492fde124962f04a1", "0x0000000000000000000000000000000673dbd698da8b8cce450d2a083aba9987", "0x00000000000000000000000000000000000a49e55bb040249cb41c63cea901cd", "0x000000000000000000000000000000133d92af8d76ee0c74a12081ee7b2ef8c4", "0x0000000000000000000000000000000000240f552d1c6cbb007650e4b142e0a5", "0x000000000000000000000000000000e29c6e7d982ec08d51c79d6261c28d742d", "0x000000000000000000000000000000000021baeec04d9be419c923626034e7b3", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x1e940a528b42d8230e7d4dff76262a80986c0d00b2c02a9bc0559e36212d1547", "0x1ceccf21ac39f70d76ad6f7fe0dcb33b6af04555a0b1959e4714d65925e4e253", "0x096139d757046cdbdb7ee89a95f112f70882a43a46c2f739d9be115dda013420", "0x2f9c8ac67c7825b08eff0e7f7656a671f4c64e5601f2efab35b1b795801eec04", "0x2077e648e1704851cdffd7e6e56311634a7b741bab77ca34d9dff12a6a2bfe99", "0x115d48c4a97aeb3c447a060f9e0d675b0dc7f4a05a3f5776e2f279f3a165d7dc", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000000000fd38c45c3ec5b841482a80e3a56ce82555", "0x00000000000000000000000000000000000ad70b03f092f60af3e0ce1bb29d2c", "0x0000000000000000000000000000007a184d5342c90c634c0b1a050f0b97c9fb", "0x0000000000000000000000000000000000271f42abcb3bc1f0332e4b3ca85e1d", "0x0000000000000000000000000000008256322bbe2c1b8cd9d84e5ff6123477f2", "0x000000000000000000000000000000000025cab962761681dd9547f4c78814df", "0x0000000000000000000000000000008c4234510e5825c02b9ac427bcbf8e279a", "0x000000000000000000000000000000000013a14e0d7fc073c44643af38cc5396"] +proof = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf", "0x00000000000000000000000000000000000000000000000b75c020998797da78", "0x0000000000000000000000000000000000000000000000005a107acb64952eca", "0x000000000000000000000000000000000000000000000000000031e97a575e9d", "0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4", "0x00000000000000000000000000000000000000000000000c410db10a01750aeb", "0x00000000000000000000000000000000000000000000000d722669117f9758a4", "0x000000000000000000000000000000000000000000000000000178cbf4206471", "0x000000000000000000000000000000000000000000000000e91b8a11e7842c38", "0x000000000000000000000000000000000000000000000007fd51009034b3357f", "0x000000000000000000000000000000000000000000000009889939f81e9c7402", "0x0000000000000000000000000000000000000000000000000000f94656a2ca48", "0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f", "0x0000000000000000000000000000000000000000000000093fe27776f50224bd", "0x000000000000000000000000000000000000000000000004a0c80c0da527a081", "0x0000000000000000000000000000000000000000000000000001b52c2020d746", "0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632", "0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc", "0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62", "0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c", "0x000000000000000000000000000000b0804efd6573805f991458295f510a2004", "0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e", "0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47", "0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15", "0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd", "0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383", "0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4", "0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98", "0x0000000000000000000000000000004ae614a40d61d28f36aaf03d00a064355d", "0x000000000000000000000000000000000010edd34b6c69cb31a6a833a1d040d2", "0x000000000000000000000000000000f4976ee83b95241474007fdc30b06ebdd7", "0x000000000000000000000000000000000019cd0d7e4577008a8335c6260be826", "0x0000000000000000000000000000004ae614a40d61d28f36aaf03d00a064355d", "0x000000000000000000000000000000000010edd34b6c69cb31a6a833a1d040d2", "0x000000000000000000000000000000f4976ee83b95241474007fdc30b06ebdd7", "0x000000000000000000000000000000000019cd0d7e4577008a8335c6260be826", "0x000000000000000000000000000000f968b227a358a305607f3efc933823d288", "0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08", "0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f", "0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1", "0x0000000000000000000000000000007376c0278bcc77156c008b389f6bd12e8f", "0x0000000000000000000000000000000000176ebed74bf3b57ca42a2fac842809", "0x000000000000000000000000000000fc4a601439d45b9ce23c9d9cc37cb21dd2", "0x000000000000000000000000000000000017dc6f8c53261c44cd0348a9970d88", "0x000000000000000000000000000000292042e9c3c101d8dd41b3acfc0db429a2", "0x0000000000000000000000000000000000114f6b3755c65915e12f13533cdd41", "0x0000000000000000000000000000007bb311a6bd5f4f3d543ca30a1a0201614f", "0x00000000000000000000000000000000000871a5a04dda33543cf59b3babf733", "0x03ecb02e48ba68818287222348fc537135b6426d4580ea31cdd540250a7a95fb", "0x2c779e44987737a835c92393388504ebf27da5db3438865f760cb56ee5856a06", "0x0ac17380181974c0082ef0fada047fc7906a94dc18e5be249dd29e52961522e0", "0x206c623397f11ed76a292c7c605fe56c1ae4f6babb6889786aaff461535cf79e", "0x11dfbe6d0977046fd72b55bdb9b41f983fc06ea6404cb36efdf1786d6f0dcbf7", "0x1081a4f21029bfcf4f8388257bf88d932963b2368c4fde96836fb6f023f16622", "0x2e981de982d368f04b0a49e537a05ed5583080c3eafed9617bd06e1214641be9", "0x2571d21e04b1d59935490270a4789e53042f18e15fc7b94dfd267c8deadfc74e", "0x0f70f3f5319d3564bcc6fad428552eefce8f341ced5187fa186d0f099315f225", "0x18f7ee010c96f63d18d2a277e5f5a8ef19b525907817d69616d24495ad804021", "0x1cf7e347bae24a2c1a93b5fd11ff79e68bd2c1bd32056df6d2e1582d17db1d8d", "0x01c451a702451ea9871b7e19d3e2052d8fa49a571ae46616453f27d324cfc907", "0x0614dbf2404cb5fef2e5408f1115502954097981a5ea67d1f80812fa247b1f93", "0x09884374bb354fdb4b118f4da44cd37e75ba7a655201f94cc4064acbdc35887d", "0x158211f68576bcafd791ff02039bb8246b1ba94d99f30a0f282565dd8d82ce0b", "0x0a5231e4039c7b7e0ad77d319958403997a33a0be31e71032733cd70067b14db", "0x2803fc0a9f60d9e202eb6caddcacfbb94a5a7df2695c2a0c909815093ca1864c", "0x0faa80f3cef0e86746df7518f865936959d65eb64ccb05bfb574ac5561683eae", "0x298544d77ee6f4cae7aaa4e9203a233fa18dab360d6f54daf9f8801802586d58", "0x0ba76e9cadf0380b82a3b5ec1c71b80295ce3caeec73aefecffed90f28c1b012", "0x0d965885fc07c4a140f50a83cb750c876191651ee47462d0931e0e67bc9ab5cb", "0x0aad443f96fbde49595f31a47d233ca83ed2bcda86801a8fd7a596ea666c7716", "0x298ef11d346c061b8899cb10c0cd7150aa2d6c554340cf2ee6aa76125e7d1e7f", "0x27518b0512f1efb3a79650941d3adb015b357c92a8c06e086be7b3e7666cea47", "0x0cd6b10a38d5af7f0a5fa97c0ffcba406e8a65a92fe050b3b79f3f1f45d723e2", "0x2f5e1210a841f9c6a7ee7d7f290479696387a58192cb775a64adf0dc225e3d4f", "0x2ffd390be1aecefc25137d01e5b7a85410254ae9e21e7067a9869217cb828ee1", "0x244a77246b5beb3e0e38c8dda39a516050303e83c051300d08bbe5450320b47f", "0x16ed38ff1019df1d168974833ccc96d8648d05c2823021d45e1d5599998a8aec", "0x24cbbf8ca1a5bb082c1081d9252a5e964ff7aae4d83e04468db55960b80a585f", "0x01b3a78bcc6e7529c6ded587b8958d903ef990421d5706afbef64a7976a51084", "0x2c3a013cdecd027b32c8c99c163dd822df374ef018aac8f3d1fb8d57335f9503", "0x0ad83466928e5d70e1e0bb26633a1e0c61399733c15fffafb22df18029e583d6", "0x095023de752480ca3edd408d3c34d732bd9836919e84931d3f42a978867bc53e", "0x283d221f0a2e6b6616bc3eda23e15bb8c8b459010014db7608e646c70ea1da2e", "0x1390c81536ca3d71228eeccf9844702aa3df012bbc3902fe30323f55ee8c7872", "0x0ef66f0302753884f05043080104589e1bf036566a9a00d4688d3c7910631508", "0x15eceeed97d9267597c028fafac72dba40f3ea441880bdd2202b30846a243044", "0x2b38e3f3b5193811df1bafd58432d5abd1c5f575a5d9c2a449682a0f2f035034", "0x2bbcc40d11d6a96c85a63162143ec53314573bb0af7c32d89b791394c80d14a5", "0x22d909e8fb5152b5b98f7cb3fc38f4ef7d7e8f2a857347da59ba2e979bd2ec96", "0x29e3f7a95437fe6ea1e72cd4c7c2fcf1892ab22ba69387f1a6a795e91bcc26f2", "0x02d8c8d031ada707d85693ed106135cecb7fe52de73eedbc54a91a2c856d0de1", "0x28020fb768c50bf52497832c04fb0e14cdb651b98b80864d0b68228ddfd922a0", "0x24d61051f82ff93eb42b5afdcad9e236c669f9f849bf811a853f1e9cc302f8ce", "0x250e89de38769cf70e6cb3685f99e39f44d8ebc1a468930f49e1d80342092b6a", "0x0ad45df677495b9199c57f620db716c543fb6437d574453b7721c2faee6316ba", "0x043d8715e16e3f2dc5a537355c0576254a36db25002f13958696ed13c24add46", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0bb8cb6a256f110f134a15b66b644eb49dc8e0239f92489408e6265a323bb513", "0x18f02f61683cf6a7492291a7041ee1b3cfa8dfb5aa40e2f6571d13750f0f459a", "0x0a982c10c93ae173751f4165e6456c9b85e2551bd503919acae78c801ccc0e1e", "0x0b6e6266bdc6d44d05ae76d2db249877a46ad978fc758654a3a6a7208d2725a6", "0x20de00721f30db8280aa6804c90f3fbe23477e1f746a8eff61c4c5b2af7e821c", "0x1321548f766ded3432627a50704d233455c61d8e59afec2883dbe2f381c033f9", "0x00c56c902b14aa59f6f59badf20f59c51b08aeb6afbdd97a5ac7b98b998b0a56", "0x1745c01290e99476fa655e5fcf2e5b3d24f42624cbd25a40f60af3f3e8489512", "0x08e915bebf8f6c86b332a681d35c57dcd0e0804f22e4e78884ab5edc0a41d6d0", "0x0c77b29e3a0c4368ce5231f94d13fa9b84a6e350cc8f2a57b3f6920a2bf0e879", "0x07ab821c4f07e1dd1cce43b9d9dbf4c9da2e22fea675a57ecf5a47a6992059a2", "0x0bcf85d1f4e34e7598a68bc09cfacf119b0afa1193ad4163096e44ca8eef7a22", "0x0c8a367da01b9097d24eb7b5471c6bd049f7938080bb8cc6fb92945fa934faf9", "0x2cda5caa3a93dcc134cf176f4ad6c79577d273bd2706da3fcaad92a9bc336ac8", "0x2c19cbfce048ef9bb9efb5b9875645b0bc7825aa1a05ad71dbbd3a34d1d76501", "0x28d7f11c2b6b7ff8717b79b098e5bd37eb39a8ea5d03b15339c86fb93e497d97", "0x21ba86c3baacb0fe4270c64c1a5f2861af2f5aa1d6391afe8214e1ce9eac8dfa", "0x0c5289ff2fe581ccf0caa97b4041d381e384c4aef0417edd4dafa7f64a3bfa6f", "0x0c744b0b301542ec4f334696945d7b89b137c5b9434bec277dc938c3dc9ca7aa", "0x006d246e7b0ad18157fa925981f097121fe34cc769128fd8993c4d15cfdf0aee", "0x00000000000000000000000000000022a7ebdc5723cfdb5d73c4c0392e43c407", "0x160d495d0b4462662665faccb1d65d81f0c3f006254a6082a0ceffc49483d76a", "0x24a5a2b9bef1abc3a818d2f27ca5cca7e1b3da34ea6056f338ac54638e26c3b0", "0x0a3dcf45eb6c14391ed8aeab11cb9460f85cb11a1ecb868ad75095796c0f5dac", "0x160c8087a99bf109389ca20d0ce624f71dd2e40fe64d62712e45669ed550fd61", "0x1a65519621040c52fdec5594d095add265c99210929eeb29a3a8180b480bb313", "0x09bf095c40c00dce181347b0d8eaa83ecd0f1f8fcb5dab34ffe19e219672e681", "0x10f3444d7a623e54ad2e882c436191975143217e9f8121c8770a3bbd3ec183ce", "0x0cd68d59322f30bdaf0a6a628f095f880ff716b157ef9a2d589f2cfc40b53e3d", "0x20732eab49adfd109626e0e84496a929a690377e98ee03f13f66ad4541949300", "0x28c850b8bc7f6ae88835bed342eda477e8d1f013a4db34b7ff33198e0a9f8e09", "0x14d234765f29b713df4d1291d452c73a5dc00458242df1be96e04ffb0a3c396e", "0x162572b68ab59291f430cf3113d4fcd3ddca59c4808c134345f6765693f8e1ce", "0x0bc37cb2ffd0f1691bf4d8c621d49f8c23ff58989d09d96c019cc6fc9a46e155", "0x0bc37cb2ffd0f1691bf4d8c621d49f8c23ff58989d09d96c019cc6fc9a46e155", "0x2aa58bd9f811c2970dcefde8c31c2c6db2349eed5161f80c0280a3acbd9f4f0d", "0x141198df3b9c1917d2e7a136ca3438fd9630719591c24388a0559873756d288b", "0x1975864b97d6ff0ace3d600020772ea32181c2f3e413ae67bac22e4a3bbcba9c", "0x2023d432e6630619c99c25a2f293f5ed78f373ee5212bff02b92f00a43bab0e0", "0x23cbaa3113b7265b926bc8811fccce701b3d4e4006ae6b66cefffd0e2f059fd4", "0x00000000000000000000000000000061e09b904168dcad01e82d26f8a21bb884", "0x000000000000000000000000000000000027a29682b86d1b09daa382868b245a", "0x000000000000000000000000000000efc6d7071b6c8cf492bc3ba72f4eda84c5", "0x000000000000000000000000000000000010860d04901949ad63a94863c77149", "0x00000000000000000000000000000036cacf503222db1b5d0edd58aafc1e74f9", "0x00000000000000000000000000000000000fef16ca13117c1f45f6df0782c273", "0x000000000000000000000000000000013704a507a82f6224d7c369d3d6c3929e", "0x00000000000000000000000000000000002887168ff50b7339d4d181d2a84cc0", "0x000000000000000000000000000000e57f500eab5f7d08ac3c93ce080dc1f15e", "0x00000000000000000000000000000000000c720872540cd88fec315c3e6a7625", "0x0000000000000000000000000000004b6897120d1858d29ac10cba52cf73dc44", "0x000000000000000000000000000000000019a9523d9a2481b5dbb1c23cb9686e", "0x00000000000000000000000000000052442fa24d3d5c3b9a608d8259757905a4", "0x00000000000000000000000000000000001c58b3787ffa3edd9f049c1c775a85", "0x000000000000000000000000000000f5737a5b8d278973356217e75bdc986ea2", "0x00000000000000000000000000000000001e0959f30c996ac7e3b265bac2de9d", "0x00000000000000000000000000000030122ef6c7a097b6b2ea6efa763797b8b4", "0x0000000000000000000000000000000000191344dd8af6c1c1c3beef933de271", "0x0000000000000000000000000000002f38961e4eb47676a42a5b59457e19a7b1", "0x000000000000000000000000000000000002936d1fa64f399018fbf60a1f2001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0f349727b02c8c3916e6904450b4db7d748c746d693f12acfd44757e349ae543", "0x109b539e615d399af085519623a8f0ea43fd3e672e8b3397deb033110b896ba7", "0x1d2d7546c079198782bc8c1ecf377c86567d90d05988acd013af254a84ccfca2", "0x11922ebe299248b1a194ff41750bbad0297b8e4db3944036983764ba171195a1", "0x14cb035cb0d920e42127d67ed6763fd0cdadeac07c0aa57ab5c038a501aca88c", "0x2e82b6bc3d9337d1f2c080ed47e935308317c159408ff3a054718e737f827a49", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000000000c883c136e90256f3059fb812416fe61171", "0x00000000000000000000000000000000002cbe86e3f824a75195f942b5de0abe", "0x000000000000000000000000000000ff2335151394b16f671dcfdc5ee78485f3", "0x00000000000000000000000000000000000fceb210dd93cd99b7bb225af47ae8", "0x0000000000000000000000000000001a95675079e3f1508e636cf69b7978db7f", "0x0000000000000000000000000000000000079f7a59ed7b4a3dda951fa8fbad98", "0x000000000000000000000000000000b15ed33e983574376efe5ae0c29c6bdd1f", "0x000000000000000000000000000000000004031f5fd23cf82aad9e5d0bfd0363"] public_inputs = ["0x0000000000000000000000000000000000000000000000000000000000000003"] -verification_key = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000000000000000000000000000004", "0x0000000000000000000000000000000000000000000000000000000000000005", "0x0000000000000000000000000000000000000000000000000000000000000006", "0x0000000000000000000000000000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000000000000000000000000000008", "0x0000000000000000000000000000000000000000000000000000000000000009", "0x000000000000000000000000000000000000000000000000000000000000000a", "0x000000000000000000000000000000000000000000000000000000000000000b", "0x000000000000000000000000000000000000000000000000000000000000000c", "0x000000000000000000000000000000000000000000000000000000000000000d", "0x000000000000000000000000000000000000000000000000000000000000000e", "0x000000000000000000000000000000000000000000000000000000000000000f", "0x0000000000000000000000000000000000000000000000000000000000000010", "0x00000000000000000000000000000060e430ad1c23bfcf3514323aae3f206e84", "0x00000000000000000000000000000000001b5c3ff4c2458d8f481b1c068f27ae", "0x000000000000000000000000000000bb510ab2112def34980e4fc6998ad9dd16", "0x00000000000000000000000000000000000576e7c105b43e061e13cb877fefe1", "0x000000000000000000000000000000ced074785d11857b065d8199e6669a601c", "0x00000000000000000000000000000000000053b48a4098c1c0ae268f273952f7", "0x000000000000000000000000000000d1d4b26e941db8168cee8f6de548ae0fd8", "0x00000000000000000000000000000000001a9adf5a6dadc3d948bb61dfd63f4c", "0x0000000000000000000000000000009ce1faac6f8de6ebb18f1db17372c82ad5", "0x00000000000000000000000000000000002002681bb417184b2df070a16a3858", "0x000000000000000000000000000000161baa651a8092e0e84725594de5aba511", "0x00000000000000000000000000000000000be0064399c2a1efff9eb0cdcb2223", "0x0000000000000000000000000000008673be6fd1bdbe980a29d8c1ded54381e7", "0x000000000000000000000000000000000008a5158a7d9648cf1d234524c9fa0c", "0x0000000000000000000000000000002b4fce6e4b1c72062b296d49bca2aa4130", "0x00000000000000000000000000000000002e45a9eff4b6769e55fb710cded44f", "0x00000000000000000000000000000072b85bf733758b76bcf97333efb85a23e3", "0x000000000000000000000000000000000017da0ea508994fc82862715e4b5592", "0x00000000000000000000000000000094fa74695cf058dba8ff35aec95456c6c3", "0x0000000000000000000000000000000000211acddb851061c24b8f159e832bd1", "0x000000000000000000000000000000303b5e5c531384b9a792e11702ad3bcab0", "0x00000000000000000000000000000000000d336dff51a60b8833d5d7f6d4314c", "0x0000000000000000000000000000009f825dde88092070747180d581c342444a", "0x0000000000000000000000000000000000237fbd6511a03cca8cac01b555fe01", "0x0000000000000000000000000000007c313205159495df6d8de292079a4844ff", "0x000000000000000000000000000000000018facdfc468530dd45e8f7a1d38ce9", "0x0000000000000000000000000000000d1ce33446fc3dc4ab40ca38d92dac74e1", "0x00000000000000000000000000000000000852d8e3e0e8f4435af3e94222688b", "0x0000000000000000000000000000006c04ee19ec1dfec87ed47d6d04aa158de2", "0x000000000000000000000000000000000013240f97a584b45184c8ec31319b5f", "0x000000000000000000000000000000cefb5d240b07ceb4be26ea429b6dc9d9e0", "0x00000000000000000000000000000000002dad22022121d689f57fb38ca21349", "0x000000000000000000000000000000c9f189f2a91aeb664ce376d8b157ba98f8", "0x00000000000000000000000000000000002531a51ad54f124d58094b219818d2", "0x000000000000000000000000000000ef1e6db71809307f677677e62b4163f556", "0x0000000000000000000000000000000000272da4396fb2a7ee0638b9140e523d", "0x0000000000000000000000000000002e54c0244a7732c87bc4712a76dd8c83fb", "0x000000000000000000000000000000000007db77b3e04b7eba9643da57cbbe4d", "0x000000000000000000000000000000e0dfe1ddd7f74ae0d636c910c3e85830d8", "0x00000000000000000000000000000000000466fa9b57ec4664abd1505b490862", "0x0000000000000000000000000000009ee55ae8a32fe5384c79907067cc27192e", "0x00000000000000000000000000000000000799d0e465cec07ecb5238c854e830", "0x0000000000000000000000000000001d5910ad361e76e1c241247a823733c39f", "0x00000000000000000000000000000000002b03f2ccf7507564da2e6678bef8fe", "0x000000000000000000000000000000ee40d90bea71fba7a412dd61fcf34e8ceb", "0x0000000000000000000000000000000000140b0936c323fd2471155617b6af56", "0x0000000000000000000000000000002b90071823185c5ff8e440fd3d73b6fefc", "0x00000000000000000000000000000000002b6c10790a5f6631c87d652e059df4", "0x00000000000000000000000000000029a17181c7934fc3fdbd352eac5cb521b9", "0x00000000000000000000000000000000001f497cbf5284ff29a2d336e5991999", "0x000000000000000000000000000000072bd9c0c6beda1fdee6d4ff0432ba9e1b", "0x000000000000000000000000000000000013ea38a0bd2aa751a490a724fac818", "0x000000000000000000000000000000c599f63dcd3edd49f08ae5c3141c1e3493", "0x00000000000000000000000000000000002bdb36be0bea09950dd32a8ccf6fbc", "0x00000000000000000000000000000047f27f29724e7f19eba0340256a0bd4b7d", "0x00000000000000000000000000000000001c1c5ccf87a962129ca785f8f35120", "0x000000000000000000000000000000c5c71efdae00679bbe4a95096e012b1817", "0x000000000000000000000000000000000017a365de041e317817d0135f2b48e0", "0x0000000000000000000000000000008ae711ac402f7848d719c93a89ba8d39f1", "0x00000000000000000000000000000000002b6fb40ed8a1935226f4f9786a0499", "0x0000000000000000000000000000002f03a71501d83de1da5715a4e9462d6198", "0x00000000000000000000000000000000001644064443b8546f48eae693af47b8", "0x00000000000000000000000000000083763ab1b6e8fe269b2fe4c7b9c448c08d", "0x000000000000000000000000000000000021d7cc18c59676a8eeb47c0111c251", "0x000000000000000000000000000000b5f937153073e03ea7d51a996e0ebc2e6b", "0x000000000000000000000000000000000011ddd0e26457373eb06e0493177672", "0x000000000000000000000000000000c5f6eb9f6fc8fa99811a4a88c74a6d018b", "0x000000000000000000000000000000000025bcd07a0732c123567834f5109558", "0x000000000000000000000000000000aeb08a0b1a4442189448b4e97490568146", "0x000000000000000000000000000000000002a1744e4771705536a88f07e0f90f", "0x000000000000000000000000000000b938568293bd0724b0ea76c2ec34c4a829", "0x0000000000000000000000000000000000053296e8f3b9ad3af877dfa9c7c2a7", "0x000000000000000000000000000000f0ca1db6323996eba26bdc86dafef9d10b", "0x00000000000000000000000000000000001441a46c58af03d5645d52721d956a", "0x0000000000000000000000000000008bbf8f884013c66c28ba09c2fbd573b656", "0x0000000000000000000000000000000000206c391ca06fac27d1908e94570243", "0x0000000000000000000000000000002d4f5aaed88ba4f79612d53b804ca8f194", "0x00000000000000000000000000000000001674011c96392df08970fa6b7b4cb8", "0x0000000000000000000000000000009f88297c1729d76c4d9306853598c91325", "0x0000000000000000000000000000000000256f51adfcacc3c1e340be4d32d3e9", "0x0000000000000000000000000000000ab9955eec0d74eb799afed2a802b24d75", "0x00000000000000000000000000000000001fcbe43ea105b30d36ed0b21b03411", "0x000000000000000000000000000000d66b1d5433f1aa5305cd1edce7c22de466", "0x00000000000000000000000000000000002331546a256b8a3b751956806680d4", "0x000000000000000000000000000000e97954ad6cd6f45fb15c91434121db4304", "0x00000000000000000000000000000000002e20a97e09d50f227ced47e7a98250", "0x0000000000000000000000000000001ebbc27eb9ebededefba79522eb58ae89b", "0x0000000000000000000000000000000000090efa4974e566e81d1177b85a30be", "0x0000000000000000000000000000005eafa070b9c9632404052642e3bc14f9fd", "0x00000000000000000000000000000000001489068864102daca6a6b8bc4d448b", "0x0000000000000000000000000000009ebc91aaaac036a6477cadbe54e8556dfd", "0x00000000000000000000000000000000000ef6d835e2ed3343b95c82c8c54037", "0x00000000000000000000000000000033b28b529dff46e93af4e7422530478e4a", "0x000000000000000000000000000000000020a86c2f8591bf190bcddcc03c42fb", "0x000000000000000000000000000000a9679d0acc088f7dc27bf6d866bcd2dda2", "0x00000000000000000000000000000000002fb9d0d2d4099402bed74f738f64cc", "0x00000000000000000000000000000023b09f876a29a061582848a8b9a5870c12", "0x00000000000000000000000000000000001d5bb906f03f0d49e9c4791bc43af9", "0x00000000000000000000000000000017aac9854ea240d8ec97bf760c4d4ba870", "0x00000000000000000000000000000000000b227a556c414ada0dc75bb303e30e", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000009b624fa65d1a24b7f14a8f25f3789622af", "0x000000000000000000000000000000000013d47bff8c630e847b70e2732fd3f0", "0x00000000000000000000000000000061d21663e93132f32921075f4c936a84df", "0x00000000000000000000000000000000001a74ca4e118fb480b9b999902989a3"] +verification_key = ["0x0000000000000000000000000000000000000000000000000000000000000040", "0x0000000000000000000000000000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000000000000000000000000000004", "0x0000000000000000000000000000000000000000000000000000000000000005", "0x0000000000000000000000000000000000000000000000000000000000000006", "0x0000000000000000000000000000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000000000000000000000000000008", "0x0000000000000000000000000000000000000000000000000000000000000009", "0x000000000000000000000000000000000000000000000000000000000000000a", "0x000000000000000000000000000000000000000000000000000000000000000b", "0x000000000000000000000000000000000000000000000000000000000000000c", "0x000000000000000000000000000000000000000000000000000000000000000d", "0x000000000000000000000000000000000000000000000000000000000000000e", "0x000000000000000000000000000000000000000000000000000000000000000f", "0x0000000000000000000000000000000000000000000000000000000000000010", "0x00000000000000000000000000000060e430ad1c23bfcf3514323aae3f206e84", "0x00000000000000000000000000000000001b5c3ff4c2458d8f481b1c068f27ae", "0x000000000000000000000000000000bb510ab2112def34980e4fc6998ad9dd16", "0x00000000000000000000000000000000000576e7c105b43e061e13cb877fefe1", "0x000000000000000000000000000000ced074785d11857b065d8199e6669a601c", "0x00000000000000000000000000000000000053b48a4098c1c0ae268f273952f7", "0x000000000000000000000000000000d1d4b26e941db8168cee8f6de548ae0fd8", "0x00000000000000000000000000000000001a9adf5a6dadc3d948bb61dfd63f4c", "0x0000000000000000000000000000009ce1faac6f8de6ebb18f1db17372c82ad5", "0x00000000000000000000000000000000002002681bb417184b2df070a16a3858", "0x000000000000000000000000000000161baa651a8092e0e84725594de5aba511", "0x00000000000000000000000000000000000be0064399c2a1efff9eb0cdcb2223", "0x0000000000000000000000000000008673be6fd1bdbe980a29d8c1ded54381e7", "0x000000000000000000000000000000000008a5158a7d9648cf1d234524c9fa0c", "0x0000000000000000000000000000002b4fce6e4b1c72062b296d49bca2aa4130", "0x00000000000000000000000000000000002e45a9eff4b6769e55fb710cded44f", "0x00000000000000000000000000000072b85bf733758b76bcf97333efb85a23e3", "0x000000000000000000000000000000000017da0ea508994fc82862715e4b5592", "0x00000000000000000000000000000094fa74695cf058dba8ff35aec95456c6c3", "0x0000000000000000000000000000000000211acddb851061c24b8f159e832bd1", "0x000000000000000000000000000000303b5e5c531384b9a792e11702ad3bcab0", "0x00000000000000000000000000000000000d336dff51a60b8833d5d7f6d4314c", "0x0000000000000000000000000000009f825dde88092070747180d581c342444a", "0x0000000000000000000000000000000000237fbd6511a03cca8cac01b555fe01", "0x0000000000000000000000000000007c313205159495df6d8de292079a4844ff", "0x000000000000000000000000000000000018facdfc468530dd45e8f7a1d38ce9", "0x0000000000000000000000000000000d1ce33446fc3dc4ab40ca38d92dac74e1", "0x00000000000000000000000000000000000852d8e3e0e8f4435af3e94222688b", "0x0000000000000000000000000000006c04ee19ec1dfec87ed47d6d04aa158de2", "0x000000000000000000000000000000000013240f97a584b45184c8ec31319b5f", "0x000000000000000000000000000000cefb5d240b07ceb4be26ea429b6dc9d9e0", "0x00000000000000000000000000000000002dad22022121d689f57fb38ca21349", "0x000000000000000000000000000000c9f189f2a91aeb664ce376d8b157ba98f8", "0x00000000000000000000000000000000002531a51ad54f124d58094b219818d2", "0x000000000000000000000000000000ef1e6db71809307f677677e62b4163f556", "0x0000000000000000000000000000000000272da4396fb2a7ee0638b9140e523d", "0x0000000000000000000000000000002e54c0244a7732c87bc4712a76dd8c83fb", "0x000000000000000000000000000000000007db77b3e04b7eba9643da57cbbe4d", "0x000000000000000000000000000000e0dfe1ddd7f74ae0d636c910c3e85830d8", "0x00000000000000000000000000000000000466fa9b57ec4664abd1505b490862", "0x0000000000000000000000000000009ee55ae8a32fe5384c79907067cc27192e", "0x00000000000000000000000000000000000799d0e465cec07ecb5238c854e830", "0x0000000000000000000000000000001d5910ad361e76e1c241247a823733c39f", "0x00000000000000000000000000000000002b03f2ccf7507564da2e6678bef8fe", "0x000000000000000000000000000000ee40d90bea71fba7a412dd61fcf34e8ceb", "0x0000000000000000000000000000000000140b0936c323fd2471155617b6af56", "0x0000000000000000000000000000002b90071823185c5ff8e440fd3d73b6fefc", "0x00000000000000000000000000000000002b6c10790a5f6631c87d652e059df4", "0x00000000000000000000000000000029a17181c7934fc3fdbd352eac5cb521b9", "0x00000000000000000000000000000000001f497cbf5284ff29a2d336e5991999", "0x000000000000000000000000000000072bd9c0c6beda1fdee6d4ff0432ba9e1b", "0x000000000000000000000000000000000013ea38a0bd2aa751a490a724fac818", "0x000000000000000000000000000000c599f63dcd3edd49f08ae5c3141c1e3493", "0x00000000000000000000000000000000002bdb36be0bea09950dd32a8ccf6fbc", "0x00000000000000000000000000000047f27f29724e7f19eba0340256a0bd4b7d", "0x00000000000000000000000000000000001c1c5ccf87a962129ca785f8f35120", "0x000000000000000000000000000000c5c71efdae00679bbe4a95096e012b1817", "0x000000000000000000000000000000000017a365de041e317817d0135f2b48e0", "0x0000000000000000000000000000008ae711ac402f7848d719c93a89ba8d39f1", "0x00000000000000000000000000000000002b6fb40ed8a1935226f4f9786a0499", "0x0000000000000000000000000000002f03a71501d83de1da5715a4e9462d6198", "0x00000000000000000000000000000000001644064443b8546f48eae693af47b8", "0x00000000000000000000000000000083763ab1b6e8fe269b2fe4c7b9c448c08d", "0x000000000000000000000000000000000021d7cc18c59676a8eeb47c0111c251", "0x000000000000000000000000000000b5f937153073e03ea7d51a996e0ebc2e6b", "0x000000000000000000000000000000000011ddd0e26457373eb06e0493177672", "0x000000000000000000000000000000c5f6eb9f6fc8fa99811a4a88c74a6d018b", "0x000000000000000000000000000000000025bcd07a0732c123567834f5109558", "0x000000000000000000000000000000aeb08a0b1a4442189448b4e97490568146", "0x000000000000000000000000000000000002a1744e4771705536a88f07e0f90f", "0x000000000000000000000000000000b938568293bd0724b0ea76c2ec34c4a829", "0x0000000000000000000000000000000000053296e8f3b9ad3af877dfa9c7c2a7", "0x000000000000000000000000000000f0ca1db6323996eba26bdc86dafef9d10b", "0x00000000000000000000000000000000001441a46c58af03d5645d52721d956a", "0x0000000000000000000000000000008bbf8f884013c66c28ba09c2fbd573b656", "0x0000000000000000000000000000000000206c391ca06fac27d1908e94570243", "0x0000000000000000000000000000002d4f5aaed88ba4f79612d53b804ca8f194", "0x00000000000000000000000000000000001674011c96392df08970fa6b7b4cb8", "0x0000000000000000000000000000009f88297c1729d76c4d9306853598c91325", "0x0000000000000000000000000000000000256f51adfcacc3c1e340be4d32d3e9", "0x0000000000000000000000000000000ab9955eec0d74eb799afed2a802b24d75", "0x00000000000000000000000000000000001fcbe43ea105b30d36ed0b21b03411", "0x000000000000000000000000000000d66b1d5433f1aa5305cd1edce7c22de466", "0x00000000000000000000000000000000002331546a256b8a3b751956806680d4", "0x000000000000000000000000000000292b512a940306c9b122a0feb4e9780af9", "0x00000000000000000000000000000000000904e02f0334f3a3f72e65ce82f34b", "0x000000000000000000000000000000778103226eff8f576eba0a0a2ffa134d57", "0x000000000000000000000000000000000001fe54f93991aa61a056f75e5137b0", "0x00000000000000000000000000000089058e539eb10c10fa13dd50e39517555d", "0x000000000000000000000000000000000009e91383ce6118cef78093d2c550fc", "0x000000000000000000000000000000d95e2e1bf12461b508cc8d63fee4a8613d", "0x00000000000000000000000000000000000ab28965260d651673541f10f2e02f", "0x0000000000000000000000000000008f6f361c7fe163277c1022dacf2a0f307b", "0x00000000000000000000000000000000001e47e6531c4ec673e9c18a9062c1df", "0x000000000000000000000000000000e55ba7b44de2c0927d4df995625325c68c", "0x000000000000000000000000000000000005d3e2113696d710431294256dab1a", "0x000000000000000000000000000000150b1462a7b440ef041dc9e7af7e1d1f15", "0x000000000000000000000000000000000017b03e1a64b4988e05ca4291f3ce6a", "0x0000000000000000000000000000008d494ccfb05451bea33fe43623c45a9d7b", "0x000000000000000000000000000000000001ed433638a57a66f8205daea09e50", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x000000000000000000000000000000f68b70e0e4b0cb9e2c7bd64fa4b75b32dd", "0x00000000000000000000000000000000001bcedd9106bdd4e13e0b751c672a83", "0x00000000000000000000000000000042fd857eb4bf620db08b0e181807df9f59", "0x00000000000000000000000000000000001ccfa89524772b4bd5b6bf6741d71f"] diff --git a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr index 25f140a9688..bac71a580c6 100644 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr @@ -1,5 +1,5 @@ // This circuit aggregates a single Honk proof from `assert_statement`. -global SIZE_OF_PROOF_IF_LOGN_IS_28: u32 = 463; +global SIZE_OF_PROOF_IF_LOGN_IS_28: u32 = 459; global HONK_IDENTIFIER: u32 = 1; fn main( verification_key: [Field; 128], diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 35750f2ba8f..d3404675396 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -200,9 +200,9 @@ export const L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP = 256; export const LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP = 64; export const NUM_MSGS_PER_BASE_PARITY = 4; export const NUM_BASE_PARITY_PER_ROOT_PARITY = 4; -export const RECURSIVE_PROOF_LENGTH = 463; -export const NESTED_RECURSIVE_PROOF_LENGTH = 463; -export const TUBE_PROOF_LENGTH = 463; +export const RECURSIVE_PROOF_LENGTH = 459; +export const NESTED_RECURSIVE_PROOF_LENGTH = 459; +export const TUBE_PROOF_LENGTH = 459; export const HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS = 128; export const CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS = 143; export const AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS = 86; From 263eaad065d607d7af2d2c163c5090b8d73216c1 Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Wed, 18 Dec 2024 09:38:16 +0000 Subject: [PATCH 15/34] feat: add priority fees to gas settings (#10763) Please read [contributing guidelines](CONTRIBUTING.md) and remove this line. --- .../vm/avm/trace/public_inputs.hpp | 2 + .../src/barretenberg/vm/avm/trace/trace.cpp | 12 ++- .../src/barretenberg/vm/aztec_constants.hpp | 2 +- .../src/core/libraries/ConstantsGen.sol | 20 ++-- .../tail_output_validator_builder/mod.nr | 1 + .../rollup-lib/src/base/components/mod.nr | 1 + .../compute_transaction_fee.nr | 97 +++++++++++++++++++ .../mod.nr | 5 + .../src/base/private_base_rollup.nr | 17 ++-- .../crates/types/src/abis/gas_settings.nr | 20 +++- .../crates/types/src/constants.nr | 5 +- .../types/src/transaction/tx_request.nr | 9 +- .../crates/types/src/utils/field.nr | 8 ++ .../src/contract/base_contract_interaction.ts | 3 +- yarn-project/circuits.js/src/constants.gen.ts | 22 ++--- yarn-project/circuits.js/src/fees/index.ts | 1 + .../src/fees/transaction_fee.test.ts | 67 +++++++++++++ .../circuits.js/src/fees/transaction_fee.ts | 17 ++++ yarn-project/circuits.js/src/index.ts | 1 + .../__snapshots__/tx_request.test.ts.snap | 2 +- .../circuits.js/src/structs/gas_settings.ts | 61 ++++++++---- .../src/structs/tx_request.test.ts | 2 +- yarn-project/cli-wallet/src/cmds/cancel_tx.ts | 19 +++- yarn-project/cli-wallet/src/cmds/index.ts | 21 +++- yarn-project/cli-wallet/src/cmds/send.ts | 2 +- .../cli-wallet/src/utils/options/fees.ts | 22 +++-- .../end-to-end/src/e2e_fees/failures.test.ts | 3 +- .../src/type_conversion.ts | 2 + .../simulator/src/public/fixtures/index.ts | 2 +- .../simulator/src/public/public_tx_context.ts | 8 +- .../src/public/public_tx_simulator.test.ts | 51 ++++++++-- 31 files changed, 416 insertions(+), 89 deletions(-) create mode 100644 noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/private_base_rollup_output_composer/compute_transaction_fee.nr create mode 100644 noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/private_base_rollup_output_composer/mod.nr create mode 100644 yarn-project/circuits.js/src/fees/index.ts create mode 100644 yarn-project/circuits.js/src/fees/transaction_fee.test.ts create mode 100644 yarn-project/circuits.js/src/fees/transaction_fee.ts diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/public_inputs.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/public_inputs.hpp index e7b0f4d1ffe..0f41c44fc99 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/public_inputs.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/public_inputs.hpp @@ -38,6 +38,7 @@ struct GasSettings { Gas gas_limits; Gas teardown_gas_limits; GasFees max_fees_per_gas; + GasFees max_priority_fees_per_gas; }; inline void read(uint8_t const*& it, GasSettings& gas_settings) @@ -46,6 +47,7 @@ inline void read(uint8_t const*& it, GasSettings& gas_settings) read(it, gas_settings.gas_limits); read(it, gas_settings.teardown_gas_limits); read(it, gas_settings.max_fees_per_gas); + read(it, gas_settings.max_priority_fees_per_gas); } struct GlobalVariables { diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp index 95a26c9cd0f..991f14b1b1f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp @@ -259,8 +259,16 @@ void AvmTraceBuilder::pay_fee() { auto clk = static_cast(main_trace.size()) + 1; - auto tx_fee = (public_inputs.global_variables.gas_fees.fee_per_da_gas * public_inputs.end_gas_used.da_gas) + - (public_inputs.global_variables.gas_fees.fee_per_l2_gas * public_inputs.end_gas_used.l2_gas); + auto gas_settings = public_inputs.gas_settings; + auto gas_fees = public_inputs.global_variables.gas_fees; + auto priority_fee_per_da_gas = std::min(gas_settings.max_priority_fees_per_gas.fee_per_da_gas, + gas_settings.max_fees_per_gas.fee_per_da_gas - gas_fees.fee_per_da_gas); + auto priority_fee_per_l2_gas = std::min(gas_settings.max_priority_fees_per_gas.fee_per_l2_gas, + gas_settings.max_fees_per_gas.fee_per_l2_gas - gas_fees.fee_per_l2_gas); + auto total_fee_per_da_gas = gas_fees.fee_per_da_gas + priority_fee_per_da_gas; + auto total_fee_per_l2_gas = gas_fees.fee_per_l2_gas + priority_fee_per_l2_gas; + auto tx_fee = (total_fee_per_da_gas * public_inputs.end_gas_used.da_gas) + + (total_fee_per_l2_gas * public_inputs.end_gas_used.l2_gas); if (public_inputs.fee_payer == 0) { vinfo("No one is paying the fee of ", tx_fee); diff --git a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp index 24d69635058..d180cb2508b 100644 --- a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp @@ -46,7 +46,7 @@ #define TOTAL_FEES_LENGTH 1 #define PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH 867 #define AVM_ACCUMULATED_DATA_LENGTH 320 -#define AVM_CIRCUIT_PUBLIC_INPUTS_LENGTH 1009 +#define AVM_CIRCUIT_PUBLIC_INPUTS_LENGTH 1011 #define AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS 86 #define AVM_PROOF_LENGTH_IN_FIELDS 4155 #define AVM_PUBLIC_COLUMN_MAX_SIZE 1024 diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index d68316c16df..6e274c79760 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -138,7 +138,7 @@ library Constants { uint256 internal constant AZTEC_ADDRESS_LENGTH = 1; uint256 internal constant GAS_FEES_LENGTH = 2; uint256 internal constant GAS_LENGTH = 2; - uint256 internal constant GAS_SETTINGS_LENGTH = 6; + uint256 internal constant GAS_SETTINGS_LENGTH = 8; uint256 internal constant CALL_CONTEXT_LENGTH = 4; uint256 internal constant CONTENT_COMMITMENT_LENGTH = 4; uint256 internal constant CONTRACT_INSTANCE_LENGTH = 16; @@ -180,30 +180,30 @@ library Constants { uint256 internal constant ROLLUP_VALIDATION_REQUESTS_LENGTH = 2; uint256 internal constant STATE_REFERENCE_LENGTH = 8; uint256 internal constant TREE_SNAPSHOTS_LENGTH = 8; - uint256 internal constant TX_CONTEXT_LENGTH = 8; - uint256 internal constant TX_REQUEST_LENGTH = 12; + uint256 internal constant TX_CONTEXT_LENGTH = 10; + uint256 internal constant TX_REQUEST_LENGTH = 14; uint256 internal constant TOTAL_FEES_LENGTH = 1; uint256 internal constant TOTAL_MANA_USED_LENGTH = 1; uint256 internal constant BLOCK_HEADER_LENGTH = 25; uint256 internal constant BLOCK_HEADER_LENGTH_BYTES = 648; - uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 739; + uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 741; uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 867; - uint256 internal constant PRIVATE_CONTEXT_INPUTS_LENGTH = 38; + uint256 internal constant PRIVATE_CONTEXT_INPUTS_LENGTH = 40; 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 = 902; - uint256 internal constant TX_CONSTANT_DATA_LENGTH = 35; - uint256 internal constant COMBINED_CONSTANT_DATA_LENGTH = 44; + uint256 internal constant TX_CONSTANT_DATA_LENGTH = 37; + uint256 internal constant COMBINED_CONSTANT_DATA_LENGTH = 46; uint256 internal constant PRIVATE_ACCUMULATED_DATA_LENGTH = 1412; - uint256 internal constant PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2226; + uint256 internal constant PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2229; uint256 internal constant PRIVATE_TO_PUBLIC_ACCUMULATED_DATA_LENGTH = 900; 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 = 1845; - uint256 internal constant KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 958; + uint256 internal constant PRIVATE_TO_PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1847; + uint256 internal constant KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 960; uint256 internal constant CONSTANT_ROLLUP_DATA_LENGTH = 13; uint256 internal constant BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH = 52; uint256 internal constant BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH = 986; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/mod.nr index c84cbeaab2b..e147656197e 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/mod.nr @@ -30,6 +30,7 @@ impl TailOutputValidatorBuilder { Gas::new(DEFAULT_GAS_LIMIT, DEFAULT_GAS_LIMIT), Gas::new(DEFAULT_TEARDOWN_GAS_LIMIT, DEFAULT_TEARDOWN_GAS_LIMIT), GasFees::new(10, 10), + GasFees::new(3, 3), ); let mut output = FixtureBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/mod.nr index 128c7bed5bd..1831a1cc730 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/mod.nr @@ -6,6 +6,7 @@ pub(crate) mod public_data_tree; mod private_tube_data_validator; mod public_tube_data_validator; +pub(crate) mod private_base_rollup_output_composer; pub(crate) mod validate_tube_data; pub(crate) use private_tube_data_validator::PrivateTubeDataValidator; diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/private_base_rollup_output_composer/compute_transaction_fee.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/private_base_rollup_output_composer/compute_transaction_fee.nr new file mode 100644 index 00000000000..67c1b9a5eb4 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/private_base_rollup_output_composer/compute_transaction_fee.nr @@ -0,0 +1,97 @@ +use types::abis::{gas::Gas, gas_fees::GasFees, gas_settings::GasSettings}; + +pub fn compute_transaction_fee( + gas_fees: GasFees, + gas_settings: GasSettings, + gas_used: Gas, +) -> Field { + let max_priority_fees = gas_settings.max_priority_fees_per_gas; + let max_fees = gas_settings.max_fees_per_gas; + // max_fees are guaranteed to be greater than or equal to gas_fees, which is checked in tube_data_validator. + let priority_fees = GasFees::new( + dep::types::utils::field::min( + max_priority_fees.fee_per_da_gas, + max_fees.fee_per_da_gas - gas_fees.fee_per_da_gas, + ), + dep::types::utils::field::min( + max_priority_fees.fee_per_l2_gas, + max_fees.fee_per_l2_gas - gas_fees.fee_per_l2_gas, + ), + ); + + let total_fees = GasFees::new( + gas_fees.fee_per_da_gas + priority_fees.fee_per_da_gas, + gas_fees.fee_per_l2_gas + priority_fees.fee_per_l2_gas, + ); + + gas_used.compute_fee(total_fees) +} + +mod tests { + use super::compute_transaction_fee; + use types::abis::{gas::Gas, gas_fees::GasFees, gas_settings::GasSettings}; + + struct TestBuilder { + gas_fees: GasFees, + gas_settings: GasSettings, + gas_used: Gas, + } + + impl TestBuilder { + pub fn new() -> Self { + let gas_fees = GasFees::new(12, 34); + + let mut gas_settings = GasSettings::empty(); + gas_settings.max_fees_per_gas = GasFees::new(56, 78); + gas_settings.max_priority_fees_per_gas = GasFees::new(5, 7); + + let gas_used = Gas::new(2, 3); + + TestBuilder { gas_fees, gas_settings, gas_used } + } + + pub fn compute(self) -> Field { + compute_transaction_fee(self.gas_fees, self.gas_settings, self.gas_used) + } + } + + #[test] + fn compute_transaction_fee_default() { + let builder = TestBuilder::new(); + let fee = builder.compute(); + + // Make sure the following value matches the one in `transaction_fee.test.ts` in `circuits.js`. + // Paying gas_fees + max_priority_fees. + let expected_fee = 2 * (12 + 5) + 3 * (34 + 7); + assert_eq(fee, expected_fee); + } + + #[test] + fn compute_transaction_fee_zero_priority_fees() { + let mut builder = TestBuilder::new(); + + builder.gas_settings.max_priority_fees_per_gas = GasFees::empty(); + + let fee = builder.compute(); + + // Make sure the following value matches the one in `transaction_fee.test.ts` in `circuits.js`. + // Paying gas_fees only. + let expected_fee_empty_priority = 2 * 12 + 3 * 34; + assert_eq(fee, expected_fee_empty_priority); + } + + #[test] + fn compute_transaction_fee_capped_max_fees() { + let mut builder = TestBuilder::new(); + + // Increase gas_fees so that gas_fees + max_priority_fees > max_fees. + builder.gas_fees = GasFees::new(53, 74); + + let fee = builder.compute(); + + // Make sure the following value matches the one in `transaction_fee.test.ts` in `circuits.js`. + // max_fees were applied. + let expected_max_fee = 2 * 56 + 3 * 78; + assert_eq(fee, expected_max_fee); + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/private_base_rollup_output_composer/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/private_base_rollup_output_composer/mod.nr new file mode 100644 index 00000000000..83e15e4b4ee --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/private_base_rollup_output_composer/mod.nr @@ -0,0 +1,5 @@ +mod compute_transaction_fee; + +pub use compute_transaction_fee::compute_transaction_fee; + +// TODO: Move everything that composes the output of private base rollup to this component. 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 06bdc554757..d27dcd2b467 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 @@ -4,7 +4,8 @@ use crate::{ components::{ archive::perform_archive_membership_check, constants::validate_combined_constant_data, fees::compute_fee_payer_fee_juice_balance_leaf_slot, - nullifier_tree::nullifier_tree_batch_insert, PrivateTubeDataValidator, + nullifier_tree::nullifier_tree_batch_insert, + private_base_rollup_output_composer::compute_transaction_fee, PrivateTubeDataValidator, public_data_tree::public_data_tree_insert, }, state_diff_hints::PrivateBaseStateDiffHints, @@ -47,12 +48,6 @@ pub struct PrivateBaseRollupInputs { } impl PrivateBaseRollupInputs { - fn compute_transaction_fee(self) -> Field { - let gas_fees = self.constants.global_variables.gas_fees; - let gas_used = self.tube_data.public_inputs.gas_used; - gas_used.compute_fee(gas_fees) - } - pub fn execute(self) -> BaseOrMergeRollupPublicInputs { // TODO(#10311): There should be an empty base rollup. // There's at least 1 nullifier for a tx. So gas_used won't be empty if the previous circuit is private_tail. @@ -64,8 +59,6 @@ impl PrivateBaseRollupInputs { tube_data_validator.validate_with_rollup_data(self.constants); } - let transaction_fee = self.compute_transaction_fee(); - validate_combined_constant_data(self.tube_data.public_inputs.constants, self.constants); self.validate_kernel_start_state(); @@ -98,6 +91,12 @@ impl PrivateBaseRollupInputs { let end_nullifier_tree_snapshot = self.check_nullifier_tree_non_membership_and_insert_to_tree(); + let transaction_fee = compute_transaction_fee( + self.constants.global_variables.gas_fees, + self.tube_data.public_inputs.constants.tx_context.gas_settings, + self.tube_data.public_inputs.gas_used, + ); + // Write fee to public data tree let fee_public_data_write = self.build_fee_public_data_write(transaction_fee); let end_public_data_tree_snapshot = diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_settings.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_settings.nr index 42301eb096d..7957367b52c 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_settings.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_settings.nr @@ -9,11 +9,17 @@ pub struct GasSettings { pub gas_limits: Gas, pub teardown_gas_limits: Gas, pub max_fees_per_gas: GasFees, + pub max_priority_fees_per_gas: GasFees, } impl GasSettings { - pub fn new(gas_limits: Gas, teardown_gas_limits: Gas, max_fees_per_gas: GasFees) -> Self { - Self { gas_limits, teardown_gas_limits, max_fees_per_gas } + pub fn new( + gas_limits: Gas, + teardown_gas_limits: Gas, + max_fees_per_gas: GasFees, + max_priority_fees_per_gas: GasFees, + ) -> Self { + Self { gas_limits, teardown_gas_limits, max_fees_per_gas, max_priority_fees_per_gas } } } @@ -22,12 +28,18 @@ impl Eq for GasSettings { (self.gas_limits == other.gas_limits) & (self.teardown_gas_limits == other.teardown_gas_limits) & (self.max_fees_per_gas == other.max_fees_per_gas) + & (self.max_priority_fees_per_gas == other.max_priority_fees_per_gas) } } impl Empty for GasSettings { fn empty() -> Self { - GasSettings::new(Gas::empty(), Gas::empty(), GasFees::empty()) + GasSettings::new( + Gas::empty(), + Gas::empty(), + GasFees::empty(), + GasFees::empty(), + ) } } @@ -38,6 +50,7 @@ impl Serialize for GasSettings { serialized.extend_from_array(self.gas_limits.serialize()); serialized.extend_from_array(self.teardown_gas_limits.serialize()); serialized.extend_from_array(self.max_fees_per_gas.serialize()); + serialized.extend_from_array(self.max_priority_fees_per_gas.serialize()); serialized.storage() } @@ -50,6 +63,7 @@ impl Deserialize for GasSettings { reader.read_struct(Gas::deserialize), reader.read_struct(Gas::deserialize), reader.read_struct(GasFees::deserialize), + reader.read_struct(GasFees::deserialize), ) } } 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 7586a274d62..12a824936fc 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -209,7 +209,10 @@ pub global DEFAULT_TPK_M_Y: Field = pub global AZTEC_ADDRESS_LENGTH: u32 = 1; pub global GAS_FEES_LENGTH: u32 = 2; pub global GAS_LENGTH: u32 = 2; -pub global GAS_SETTINGS_LENGTH: u32 = GAS_LENGTH * 2 + GAS_FEES_LENGTH; +pub global GAS_SETTINGS_LENGTH: u32 = GAS_LENGTH /* gas_limits */ + + GAS_LENGTH /* teardown_gas_limits */ + + GAS_FEES_LENGTH /* max_fees_per_gas */ + + GAS_FEES_LENGTH /* max_priority_fees_per_gas */; pub global CALL_CONTEXT_LENGTH: u32 = 4; pub global CONTENT_COMMITMENT_LENGTH: u32 = 4; pub global CONTRACT_INSTANCE_LENGTH: u32 = 16; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_request.nr index 2d86849101f..92344807691 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_request.nr @@ -93,7 +93,12 @@ mod tests { #[test] fn compute_hash() { - let gas_settings = GasSettings::new(Gas::new(2, 2), Gas::new(1, 1), GasFees::new(3, 3)); + let gas_settings = GasSettings::new( + Gas::new(2, 2), + Gas::new(1, 1), + GasFees::new(4, 4), + GasFees::new(3, 3), + ); let tx_request = TxRequest { origin: AztecAddress::from_field(1), args_hash: 3, @@ -105,7 +110,7 @@ mod tests { }; // Value from tx_request.test.ts "compute hash" test let test_data_tx_request_hash = - 0x1b15ac8432c3c35718075a277d86f11263f057e2325afa208d6b19e37ff59a8d; + 0x2d265ee0e3b9d206873a66527485afa3c6ebbfbaf451811666c9558a9f6e3d46; assert(tx_request.hash() == test_data_tx_request_hash); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/field.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/field.nr index 796d0906e77..91ddbe290b7 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/field.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/field.nr @@ -43,6 +43,14 @@ pub fn full_field_greater_than(lhs: Field, rhs: Field) -> bool { rhs.lt(lhs) } +pub fn min(f1: Field, f2: Field) -> Field { + if f1.lt(f2) { + f1 + } else { + f2 + } +} + #[test] unconstrained fn bytes_field_test() { // Tests correctness of field_from_bytes_32_trunc against existing methods 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 8ab2f2c91bd..ad8353d0d6c 100644 --- a/yarn-project/aztec.js/src/contract/base_contract_interaction.ts +++ b/yarn-project/aztec.js/src/contract/base_contract_interaction.ts @@ -122,6 +122,7 @@ export abstract class BaseContractInteraction { const defaultFeeOptions = await this.getDefaultFeeOptions(request.fee); const paymentMethod = defaultFeeOptions.paymentMethod; const maxFeesPerGas = defaultFeeOptions.gasSettings.maxFeesPerGas; + const maxPriorityFeesPerGas = defaultFeeOptions.gasSettings.maxPriorityFeesPerGas; let gasSettings = defaultFeeOptions.gasSettings; if (request.fee?.estimateGas) { @@ -132,7 +133,7 @@ export abstract class BaseContractInteraction { simulationResult, request.fee?.estimatedGasPadding, ); - gasSettings = GasSettings.from({ maxFeesPerGas, gasLimits, teardownGasLimits }); + gasSettings = GasSettings.from({ maxFeesPerGas, maxPriorityFeesPerGas, gasLimits, teardownGasLimits }); this.log.verbose( `Estimated gas limits for tx: DA=${gasLimits.daGas} L2=${gasLimits.l2Gas} teardownDA=${teardownGasLimits.daGas} teardownL2=${teardownGasLimits.l2Gas}`, ); diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index d3404675396..ac7e24b713c 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -116,7 +116,7 @@ export const DEFAULT_TPK_M_Y = 1457571873670220605010242502922942621563166447116 export const AZTEC_ADDRESS_LENGTH = 1; export const GAS_FEES_LENGTH = 2; export const GAS_LENGTH = 2; -export const GAS_SETTINGS_LENGTH = 6; +export const GAS_SETTINGS_LENGTH = 8; export const CALL_CONTEXT_LENGTH = 4; export const CONTENT_COMMITMENT_LENGTH = 4; export const CONTRACT_INSTANCE_LENGTH = 16; @@ -158,32 +158,32 @@ export const PUBLIC_INNER_CALL_REQUEST_LENGTH = 13; export const ROLLUP_VALIDATION_REQUESTS_LENGTH = 2; export const STATE_REFERENCE_LENGTH = 8; export const TREE_SNAPSHOTS_LENGTH = 8; -export const TX_CONTEXT_LENGTH = 8; -export const TX_REQUEST_LENGTH = 12; +export const TX_CONTEXT_LENGTH = 10; +export const TX_REQUEST_LENGTH = 14; export const TOTAL_FEES_LENGTH = 1; export const TOTAL_MANA_USED_LENGTH = 1; export const BLOCK_HEADER_LENGTH = 25; export const BLOCK_HEADER_LENGTH_BYTES = 648; -export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 739; +export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 741; export const PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 867; -export const PRIVATE_CONTEXT_INPUTS_LENGTH = 38; +export const PRIVATE_CONTEXT_INPUTS_LENGTH = 40; 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 = 902; -export const TX_CONSTANT_DATA_LENGTH = 35; -export const COMBINED_CONSTANT_DATA_LENGTH = 44; +export const TX_CONSTANT_DATA_LENGTH = 37; +export const COMBINED_CONSTANT_DATA_LENGTH = 46; export const PRIVATE_ACCUMULATED_DATA_LENGTH = 1412; -export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2226; +export const PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 2229; export const PRIVATE_TO_PUBLIC_ACCUMULATED_DATA_LENGTH = 900; 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 = 320; -export const PRIVATE_TO_PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1845; -export const KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 958; -export const AVM_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1009; +export const PRIVATE_TO_PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1847; +export const KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH = 960; +export const AVM_CIRCUIT_PUBLIC_INPUTS_LENGTH = 1011; export const CONSTANT_ROLLUP_DATA_LENGTH = 13; export const BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH = 52; export const BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH = 986; diff --git a/yarn-project/circuits.js/src/fees/index.ts b/yarn-project/circuits.js/src/fees/index.ts new file mode 100644 index 00000000000..99ed046cf47 --- /dev/null +++ b/yarn-project/circuits.js/src/fees/index.ts @@ -0,0 +1 @@ +export * from './transaction_fee.js'; diff --git a/yarn-project/circuits.js/src/fees/transaction_fee.test.ts b/yarn-project/circuits.js/src/fees/transaction_fee.test.ts new file mode 100644 index 00000000000..b3c344601e1 --- /dev/null +++ b/yarn-project/circuits.js/src/fees/transaction_fee.test.ts @@ -0,0 +1,67 @@ +import { updateInlineTestData } from '@aztec/foundation/testing/files'; +import { type Writeable } from '@aztec/foundation/types'; + +import { Fr, Gas, GasFees, GasSettings } from '../structs/index.js'; +import { computeTransactionFee } from './transaction_fee.js'; + +describe('computeTransactionFee', () => { + let gasFees: GasFees; + let gasSettings: Writeable; + let gasUsed: Gas; + + const expectFee = (feeStr: string) => { + const fee = computeTransactionFee(gasFees, gasSettings, gasUsed); + expect(fee).toEqual(new Fr(BigInt(eval(feeStr)))); + }; + + beforeEach(() => { + gasFees = new GasFees(12, 34); + + const maxFeesPerGas = new GasFees(56, 78); + const maxPriorityFeesPerGas = new GasFees(5, 7); + gasSettings = GasSettings.from({ ...GasSettings.empty(), maxFeesPerGas, maxPriorityFeesPerGas }); + + gasUsed = new Gas(2, 3); + }); + + it('computes the transaction fee with priority fee', () => { + const feeStr = '2 * (12 + 5) + 3 * (34 + 7)'; + expectFee(feeStr); + + // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data + updateInlineTestData( + 'noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/private_base_rollup_output_composer/compute_transaction_fee.nr', + 'expected_fee', + feeStr, + ); + }); + + it('computes the transaction fee without priority fee', () => { + gasSettings.maxPriorityFeesPerGas = GasFees.empty(); + + const feeStr = '2 * 12 + 3 * 34'; + expectFee(feeStr); + + // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data + updateInlineTestData( + 'noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/private_base_rollup_output_composer/compute_transaction_fee.nr', + 'expected_fee_empty_priority', + feeStr, + ); + }); + + it('computes the transaction fee paying max fee', () => { + // Increase gas_fees so that gasFees + maxPriorityFeesPerGas > maxFeesPerGas. + gasFees = new GasFees(53, 74); + + const feeStr = '2 * 56 + 3 * 78'; + expectFee(feeStr); + + // Run with AZTEC_GENERATE_TEST_DATA=1 to update noir test data + updateInlineTestData( + 'noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/private_base_rollup_output_composer/compute_transaction_fee.nr', + 'expected_max_fee', + feeStr, + ); + }); +}); diff --git a/yarn-project/circuits.js/src/fees/transaction_fee.ts b/yarn-project/circuits.js/src/fees/transaction_fee.ts new file mode 100644 index 00000000000..017275091fe --- /dev/null +++ b/yarn-project/circuits.js/src/fees/transaction_fee.ts @@ -0,0 +1,17 @@ +import { type Fr, type Gas, GasFees, type GasSettings } from '../structs/index.js'; + +export function computeTransactionFee(gasFees: GasFees, gasSettings: GasSettings, gasUsed: Gas): Fr { + const { maxFeesPerGas, maxPriorityFeesPerGas } = gasSettings; + const minField = (f1: Fr, f2: Fr) => (f1.lt(f2) ? f1 : f2); + const priorityFees = new GasFees( + minField(maxPriorityFeesPerGas.feePerDaGas, maxFeesPerGas.feePerDaGas.sub(gasFees.feePerDaGas)), + minField(maxPriorityFeesPerGas.feePerL2Gas, maxFeesPerGas.feePerL2Gas.sub(gasFees.feePerL2Gas)), + ); + + const totalFees = new GasFees( + gasFees.feePerDaGas.add(priorityFees.feePerDaGas), + gasFees.feePerL2Gas.add(priorityFees.feePerL2Gas), + ); + + return gasUsed.computeFee(totalFees); +} diff --git a/yarn-project/circuits.js/src/index.ts b/yarn-project/circuits.js/src/index.ts index 9ed5971c96f..e4c04ed31fa 100644 --- a/yarn-project/circuits.js/src/index.ts +++ b/yarn-project/circuits.js/src/index.ts @@ -1,5 +1,6 @@ export * from './constants.js'; export * from './contract/index.js'; +export * from './fees/index.js'; export * from './hints/index.js'; export * from './interfaces/index.js'; export * from './keys/index.js'; diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/tx_request.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/tx_request.test.ts.snap index 89e87fba81d..73f68740498 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/tx_request.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/__snapshots__/tx_request.test.ts.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`TxRequest compute hash 1`] = `"0x1b15ac8432c3c35718075a277d86f11263f057e2325afa208d6b19e37ff59a8d"`; +exports[`TxRequest compute hash 1`] = `"0x2d265ee0e3b9d206873a66527485afa3c6ebbfbaf451811666c9558a9f6e3d46"`; diff --git a/yarn-project/circuits.js/src/structs/gas_settings.ts b/yarn-project/circuits.js/src/structs/gas_settings.ts index c5449a7ac9d..e432c8a8f8a 100644 --- a/yarn-project/circuits.js/src/structs/gas_settings.ts +++ b/yarn-project/circuits.js/src/structs/gas_settings.ts @@ -14,6 +14,7 @@ export class GasSettings { public readonly gasLimits: Gas, public readonly teardownGasLimits: Gas, public readonly maxFeesPerGas: GasFees, + public readonly maxPriorityFeesPerGas: GasFees, ) {} static get schema() { @@ -22,6 +23,7 @@ export class GasSettings { gasLimits: Gas.schema, teardownGasLimits: Gas.schema, maxFeesPerGas: GasFees.schema, + maxPriorityFeesPerGas: GasFees.schema, }) .transform(GasSettings.from); } @@ -30,16 +32,27 @@ export class GasSettings { return this.toBuffer().length; } - static from(args: { gasLimits: FieldsOf; teardownGasLimits: FieldsOf; maxFeesPerGas: FieldsOf }) { + static from(args: { + gasLimits: FieldsOf; + teardownGasLimits: FieldsOf; + maxFeesPerGas: FieldsOf; + maxPriorityFeesPerGas: FieldsOf; + }) { return new GasSettings( Gas.from(args.gasLimits), Gas.from(args.teardownGasLimits), GasFees.from(args.maxFeesPerGas), + GasFees.from(args.maxPriorityFeesPerGas), ); } clone() { - return new GasSettings(this.gasLimits.clone(), this.teardownGasLimits.clone(), this.maxFeesPerGas.clone()); + return new GasSettings( + this.gasLimits.clone(), + this.teardownGasLimits.clone(), + this.maxFeesPerGas.clone(), + this.maxPriorityFeesPerGas.clone(), + ); } /** Returns the maximum fee to be paid according to gas limits and max fees set. */ @@ -56,11 +69,16 @@ export class GasSettings { /** Zero-value gas settings. */ static empty() { - return new GasSettings(Gas.empty(), Gas.empty(), GasFees.empty()); + return new GasSettings(Gas.empty(), Gas.empty(), GasFees.empty(), GasFees.empty()); } /** Default gas settings to use when user has not provided them. Requires explicit max fees per gas. */ - static default(overrides: { gasLimits?: Gas; teardownGasLimits?: Gas; maxFeesPerGas: GasFees }) { + static default(overrides: { + gasLimits?: Gas; + teardownGasLimits?: Gas; + maxFeesPerGas: GasFees; + maxPriorityFeesPerGas?: GasFees; + }) { return GasSettings.from({ gasLimits: overrides.gasLimits ?? { l2Gas: DEFAULT_GAS_LIMIT, daGas: DEFAULT_GAS_LIMIT }, teardownGasLimits: overrides.teardownGasLimits ?? { @@ -68,32 +86,36 @@ export class GasSettings { daGas: DEFAULT_TEARDOWN_GAS_LIMIT, }, maxFeesPerGas: overrides.maxFeesPerGas, - }); - } - - /** Default gas settings with no teardown */ - static teardownless(opts: { maxFeesPerGas: GasFees }) { - return GasSettings.default({ - teardownGasLimits: Gas.from({ l2Gas: 0, daGas: 0 }), - maxFeesPerGas: opts.maxFeesPerGas, + maxPriorityFeesPerGas: overrides.maxPriorityFeesPerGas ?? GasFees.empty(), }); } isEmpty() { - return this.gasLimits.isEmpty() && this.teardownGasLimits.isEmpty() && this.maxFeesPerGas.isEmpty(); + return ( + this.gasLimits.isEmpty() && + this.teardownGasLimits.isEmpty() && + this.maxFeesPerGas.isEmpty() && + this.maxPriorityFeesPerGas.isEmpty() + ); } equals(other: GasSettings) { return ( this.gasLimits.equals(other.gasLimits) && this.teardownGasLimits.equals(other.teardownGasLimits) && - this.maxFeesPerGas.equals(other.maxFeesPerGas) + this.maxFeesPerGas.equals(other.maxFeesPerGas) && + this.maxPriorityFeesPerGas.equals(other.maxPriorityFeesPerGas) ); } static fromBuffer(buffer: Buffer | BufferReader): GasSettings { const reader = BufferReader.asReader(buffer); - return new GasSettings(reader.readObject(Gas), reader.readObject(Gas), reader.readObject(GasFees)); + return new GasSettings( + reader.readObject(Gas), + reader.readObject(Gas), + reader.readObject(GasFees), + reader.readObject(GasFees), + ); } toBuffer() { @@ -102,7 +124,12 @@ export class GasSettings { static fromFields(fields: Fr[] | FieldReader): GasSettings { const reader = FieldReader.asReader(fields); - return new GasSettings(reader.readObject(Gas), reader.readObject(Gas), reader.readObject(GasFees)); + return new GasSettings( + reader.readObject(Gas), + reader.readObject(Gas), + reader.readObject(GasFees), + reader.readObject(GasFees), + ); } toFields(): Fr[] { @@ -116,6 +143,6 @@ export class GasSettings { } static getFields(fields: FieldsOf) { - return [fields.gasLimits, fields.teardownGasLimits, fields.maxFeesPerGas] as const; + return [fields.gasLimits, fields.teardownGasLimits, fields.maxFeesPerGas, fields.maxPriorityFeesPerGas] as const; } } diff --git a/yarn-project/circuits.js/src/structs/tx_request.test.ts b/yarn-project/circuits.js/src/structs/tx_request.test.ts index 723e322817e..fec6fab23b7 100644 --- a/yarn-project/circuits.js/src/structs/tx_request.test.ts +++ b/yarn-project/circuits.js/src/structs/tx_request.test.ts @@ -35,7 +35,7 @@ describe('TxRequest', () => { }); it('compute hash', () => { - const gasSettings = new GasSettings(new Gas(2, 2), new Gas(1, 1), new GasFees(3, 3)); + const gasSettings = new GasSettings(new Gas(2, 2), new Gas(1, 1), new GasFees(4, 4), new GasFees(3, 3)); const txRequest = TxRequest.from({ origin: AztecAddress.fromBigInt(1n), functionData: new FunctionData(FunctionSelector.fromField(new Fr(2n)), /*isPrivate=*/ true), diff --git a/yarn-project/cli-wallet/src/cmds/cancel_tx.ts b/yarn-project/cli-wallet/src/cmds/cancel_tx.ts index 2d6ae924075..222fb7501cb 100644 --- a/yarn-project/cli-wallet/src/cmds/cancel_tx.ts +++ b/yarn-project/cli-wallet/src/cmds/cancel_tx.ts @@ -1,17 +1,19 @@ import { type AccountWalletWithSecretKey, type FeePaymentMethod, SentTx, type TxHash, TxStatus } from '@aztec/aztec.js'; import { type FeeOptions } from '@aztec/aztec.js/entrypoint'; -import { type Fr, type GasSettings } from '@aztec/circuits.js'; +import { type Fr, GasFees, GasSettings } from '@aztec/circuits.js'; import { type LogFn } from '@aztec/foundation/log'; export async function cancelTx( wallet: AccountWalletWithSecretKey, { txHash, - gasSettings, + gasSettings: prevTxGasSettings, nonce, cancellable, }: { txHash: TxHash; gasSettings: GasSettings; nonce: Fr; cancellable: boolean }, paymentMethod: FeePaymentMethod, + increasedFees: GasFees, + maxFeesPerGas: GasFees | undefined, log: LogFn, ) { const receipt = await wallet.getTxReceipt(txHash); @@ -20,13 +22,20 @@ export async function cancelTx( return; } + const maxPriorityFeesPerGas = new GasFees( + prevTxGasSettings.maxPriorityFeesPerGas.feePerDaGas.add(increasedFees.feePerDaGas), + prevTxGasSettings.maxPriorityFeesPerGas.feePerL2Gas.add(increasedFees.feePerL2Gas), + ); + const fee: FeeOptions = { paymentMethod, - gasSettings, + gasSettings: GasSettings.from({ + ...prevTxGasSettings, + maxPriorityFeesPerGas, + maxFeesPerGas: maxFeesPerGas ?? prevTxGasSettings.maxFeesPerGas, + }), }; - // TODO(#9805): Increase max_priority_fee_per_gas. - const txRequest = await wallet.createTxExecutionRequest({ calls: [], fee, diff --git a/yarn-project/cli-wallet/src/cmds/index.ts b/yarn-project/cli-wallet/src/cmds/index.ts index 41f280451cd..1915e080af7 100644 --- a/yarn-project/cli-wallet/src/cmds/index.ts +++ b/yarn-project/cli-wallet/src/cmds/index.ts @@ -1,6 +1,7 @@ import { getIdentities } from '@aztec/accounts/utils'; import { createCompatibleClient } from '@aztec/aztec.js/rpc'; import { TxHash } from '@aztec/aztec.js/tx_hash'; +import { GasFees } from '@aztec/circuits.js'; import { PublicKeys } from '@aztec/circuits.js/types'; import { ETHEREUM_HOST, @@ -38,6 +39,7 @@ import { createProfileOption, createTypeOption, integerArgParser, + parseGasFees, parsePaymentMethod, } from '../utils/options/index.js'; import { type PXEWrapper } from '../utils/pxe_wrapper.js'; @@ -580,7 +582,7 @@ export function injectCommands( program .command('cancel-tx') - .description('Cancels a peding tx by reusing its nonce with a higher fee and an empty payload') + .description('Cancels a pending tx by reusing its nonce with a higher fee and an empty payload') .argument('', 'A transaction hash to cancel.', txHash => aliasedTxHashParser(txHash, db)) .addOption(pxeOption) .addOption( @@ -588,21 +590,30 @@ export function injectCommands( ) .addOption(createAccountOption('Alias or address of the account to simulate from', !db, db)) .addOption(FeeOpts.paymentMethodOption().default('method=none')) + .option( + '-i --increased-fees ', + 'The amounts by which the fees are increased', + value => parseGasFees(value), + new GasFees(1, 1), + ) + .option('--max-fees-per-gas ', 'Maximum fees per gas unit for DA and L2 computation.', value => + parseGasFees(value), + ) .action(async (txHash, options) => { const { cancelTx } = await import('./cancel_tx.js'); - const { from: parsedFromAddress, rpcUrl, secretKey, payment } = options; + const { from: parsedFromAddress, rpcUrl, secretKey, payment, increasedFees, maxFeesPerGas } = options; const client = pxeWrapper?.getPXE() ?? (await createCompatibleClient(rpcUrl, debugLogger)); const account = await createOrRetrieveAccount(client, parsedFromAddress, db, secretKey); const wallet = await getWalletWithScopes(account, db); const txData = db?.retrieveTxData(txHash); - if (!txData) { - throw new Error('Transaction data not found in the database, cannnot reuse nonce'); + throw new Error('Transaction data not found in the database, cannot reuse nonce'); } + const paymentMethod = await parsePaymentMethod(payment, log, db)(wallet); - await cancelTx(wallet, txData, paymentMethod, log); + await cancelTx(wallet, txData, paymentMethod, increasedFees, maxFeesPerGas, log); }); program diff --git a/yarn-project/cli-wallet/src/cmds/send.ts b/yarn-project/cli-wallet/src/cmds/send.ts index b87097ec125..5fcdfc3a3ba 100644 --- a/yarn-project/cli-wallet/src/cmds/send.ts +++ b/yarn-project/cli-wallet/src/cmds/send.ts @@ -50,8 +50,8 @@ export async function send( log('Transaction pending. Check status with check-tx'); } const gasSettings = GasSettings.from({ + ...feeOpts.gasSettings, ...gasLimits, - maxFeesPerGas: feeOpts.gasSettings.maxFeesPerGas, }); return { txHash, diff --git a/yarn-project/cli-wallet/src/utils/options/fees.ts b/yarn-project/cli-wallet/src/utils/options/fees.ts index f0852956a22..829a2c8c67b 100644 --- a/yarn-project/cli-wallet/src/utils/options/fees.ts +++ b/yarn-project/cli-wallet/src/utils/options/fees.ts @@ -12,6 +12,7 @@ export type CliFeeArgs = { gasLimits?: string; payment?: string; maxFeesPerGas?: string; + maxPriorityFeesPerGas?: string; estimateGas?: boolean; }; @@ -69,7 +70,11 @@ export class FeeOpts implements IFeeOpts { return [ new Option('--gas-limits ', 'Gas limits for the tx.'), FeeOpts.paymentMethodOption(), - new Option('--max-fee-per-gas ', 'Maximum fee per gas unit for DA and L2 computation.'), + new Option('--max-fees-per-gas ', 'Maximum fees per gas unit for DA and L2 computation.'), + new Option( + '--max-priority-fees-per-gas ', + 'Maximum priority fees per gas unit for DA and L2 computation.', + ), new Option('--no-estimate-gas', 'Whether to automatically estimate gas limits for the tx.'), new Option('--estimate-gas-only', 'Only report gas estimation for the tx, do not send it.'), ]; @@ -77,12 +82,13 @@ export class FeeOpts implements IFeeOpts { static async fromCli(args: CliFeeArgs, pxe: PXE, log: LogFn, db?: WalletDB) { const estimateOnly = args.estimateGasOnly; - const gasFees = args.maxFeesPerGas - ? parseGasFees(args.maxFeesPerGas) - : { maxFeesPerGas: await pxe.getCurrentBaseFees() }; + const gasLimits = args.gasLimits ? parseGasLimits(args.gasLimits) : {}; + const maxFeesPerGas = args.maxFeesPerGas ? parseGasFees(args.maxFeesPerGas) : await pxe.getCurrentBaseFees(); + const maxPriorityFeesPerGas = args.maxPriorityFeesPerGas ? parseGasFees(args.maxPriorityFeesPerGas) : undefined; const gasSettings = GasSettings.default({ - ...gasFees, - ...(args.gasLimits ? parseGasLimits(args.gasLimits) : {}), + ...gasLimits, + maxFeesPerGas, + maxPriorityFeesPerGas, }); if (!args.gasLimits && !args.payment) { @@ -212,7 +218,7 @@ function parseGasLimits(gasLimits: string): { gasLimits: Gas; teardownGasLimits: }; } -function parseGasFees(gasFees: string): { maxFeesPerGas: GasFees } { +export function parseGasFees(gasFees: string): GasFees { const parsed = gasFees.split(',').reduce((acc, fee) => { const [dimension, value] = fee.split('='); acc[dimension] = parseInt(value, 10); @@ -226,5 +232,5 @@ function parseGasFees(gasFees: string): { maxFeesPerGas: GasFees } { } } - return { maxFeesPerGas: new GasFees(parsed.da, parsed.l2) }; + return new GasFees(parsed.da, parsed.l2); } diff --git a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts index 26ce82243ed..7efc18bc661 100644 --- a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts @@ -262,8 +262,7 @@ describe('e2e_fees failures', () => { await bananaCoin.methods.mint_to_public(aliceAddress, publicMintedAlicePublicBananas).send().wait(); const badGas = GasSettings.from({ - gasLimits: gasSettings.gasLimits, - maxFeesPerGas: gasSettings.maxFeesPerGas, + ...gasSettings, teardownGasLimits: Gas.empty(), }); 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 feab75d5767..e6dcafdeee5 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -524,6 +524,7 @@ export function mapGasSettingsFromNoir(gasSettings: GasSettingsNoir): GasSetting mapGasFromNoir(gasSettings.gas_limits), mapGasFromNoir(gasSettings.teardown_gas_limits), mapGasFeesFromNoir(gasSettings.max_fees_per_gas), + mapGasFeesFromNoir(gasSettings.max_priority_fees_per_gas), ); } @@ -532,6 +533,7 @@ export function mapGasSettingsToNoir(gasSettings: GasSettings): GasSettingsNoir gas_limits: mapGasToNoir(gasSettings.gasLimits), teardown_gas_limits: mapGasToNoir(gasSettings.teardownGasLimits), max_fees_per_gas: mapGasFeesToNoir(gasSettings.maxFeesPerGas), + max_priority_fees_per_gas: mapGasFeesToNoir(gasSettings.maxPriorityFeesPerGas), }; } diff --git a/yarn-project/simulator/src/public/fixtures/index.ts b/yarn-project/simulator/src/public/fixtures/index.ts index 691c0f4ae85..6789e8622d3 100644 --- a/yarn-project/simulator/src/public/fixtures/index.ts +++ b/yarn-project/simulator/src/public/fixtures/index.ts @@ -125,7 +125,7 @@ export function createTxForPublicCall( } const teardownGasLimits = isTeardown ? gasLimits : Gas.empty(); - const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty()); + const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty()); const txContext = new TxContext(Fr.zero(), Fr.zero(), gasSettings); const constantData = new TxConstantData(BlockHeader.empty(), txContext, Fr.zero(), Fr.zero()); diff --git a/yarn-project/simulator/src/public/public_tx_context.ts b/yarn-project/simulator/src/public/public_tx_context.ts index 9c3eaf60d03..ec7aaa93316 100644 --- a/yarn-project/simulator/src/public/public_tx_context.ts +++ b/yarn-project/simulator/src/public/public_tx_context.ts @@ -26,6 +26,7 @@ import { RevertCode, type StateReference, TreeSnapshots, + computeTransactionFee, countAccumulatedItems, } from '@aztec/circuits.js'; import { type Logger, createLogger } from '@aztec/foundation/log'; @@ -298,12 +299,15 @@ export class PublicTxContext { * Should only be called during or after teardown. */ private getTransactionFeeUnsafe(): Fr { - const txFee = this.getTotalGasUsed().computeFee(this.globalVariables.gasFees); + const gasUsed = this.getTotalGasUsed(); + const txFee = computeTransactionFee(this.globalVariables.gasFees, this.gasSettings, gasUsed); + this.log.debug(`Computed tx fee`, { txFee, - gasUsed: inspect(this.getTotalGasUsed()), + gasUsed: inspect(gasUsed), gasFees: inspect(this.globalVariables.gasFees), }); + return txFee; } diff --git a/yarn-project/simulator/src/public/public_tx_simulator.test.ts b/yarn-project/simulator/src/public/public_tx_simulator.test.ts index 4eca8f04d7e..2a9d1d62936 100644 --- a/yarn-project/simulator/src/public/public_tx_simulator.test.ts +++ b/yarn-project/simulator/src/public/public_tx_simulator.test.ts @@ -42,13 +42,14 @@ describe('public_tx_simulator', () => { // Nullifier must be >=128 since tree starts with 128 entries pre-filled const MIN_NULLIFIER = 128; // Gas settings. - const gasFees = GasFees.from({ feePerDaGas: new Fr(2), feePerL2Gas: new Fr(3) }); - const gasLimits = Gas.from({ daGas: 100, l2Gas: 150 }); - const teardownGasLimits = Gas.from({ daGas: 20, l2Gas: 30 }); - const maxFeesPerGas = gasFees; + const gasLimits = new Gas(100, 150); + const teardownGasLimits = new Gas(20, 30); + const gasFees = new GasFees(2, 3); + let maxFeesPerGas = gasFees; + let maxPriorityFeesPerGas = GasFees.empty(); // gasUsed for the tx after private execution, minus the teardownGasLimits. - const privateGasUsed = Gas.from({ daGas: 13, l2Gas: 17 }); + const privateGasUsed = new Gas(13, 17); // gasUsed for each enqueued call. const enqueuedCallGasUsed = new Gas(12, 34); @@ -86,7 +87,12 @@ describe('public_tx_simulator', () => { numberOfRevertiblePublicCallRequests: numberOfAppLogicCalls, hasPublicTeardownCallRequest: hasPublicTeardownCall, }); - tx.data.constants.txContext.gasSettings = GasSettings.from({ gasLimits, teardownGasLimits, maxFeesPerGas }); + tx.data.constants.txContext.gasSettings = GasSettings.from({ + gasLimits, + teardownGasLimits, + maxFeesPerGas, + maxPriorityFeesPerGas, + }); tx.data.forPublic!.nonRevertibleAccumulatedData.nullifiers[0] = new Fr(7777); tx.data.forPublic!.nonRevertibleAccumulatedData.nullifiers[1] = new Fr(8888); @@ -746,4 +752,37 @@ describe('public_tx_simulator', () => { await checkNullifierRoot(txResult); }); + + it('runs a tx with non-empty priority fees', async () => { + // gasFees = new GasFees(2, 3); + maxPriorityFeesPerGas = new GasFees(5, 7); + // The max fee is gasFee + priorityFee + 1. + maxFeesPerGas = new GasFees(2 + 5 + 1, 3 + 7 + 1); + + const tx = mockTxWithPublicCalls({ + numberOfSetupCalls: 1, + numberOfAppLogicCalls: 1, + hasPublicTeardownCall: true, + }); + + const txResult = await simulator.simulate(tx); + expect(txResult.revertCode).toEqual(RevertCode.OK); + + const expectedPublicGasUsed = enqueuedCallGasUsed.mul(2); // 1 for setup and 1 for app logic. + const expectedTeardownGasUsed = enqueuedCallGasUsed; + const expectedTotalGas = privateGasUsed.add(expectedPublicGasUsed).add(expectedTeardownGasUsed); + expect(txResult.gasUsed).toEqual({ + totalGas: expectedTotalGas, + teardownGas: expectedTeardownGasUsed, + }); + + const output = txResult.avmProvingRequest!.inputs.output; + + const expectedGasUsedForFee = expectedTotalGas.sub(expectedTeardownGasUsed).add(teardownGasLimits); + expect(output.endGasUsed).toEqual(expectedGasUsedForFee); + + const totalFees = new GasFees(2 + 5, 3 + 7); + const expectedTxFee = expectedGasUsedForFee.computeFee(totalFees); + expect(output.transactionFee).toEqual(expectedTxFee); + }); }); From e8480cbf1ecdee5d7228b08d1c9608308acdd624 Mon Sep 17 00:00:00 2001 From: maramihali Date: Wed, 18 Dec 2024 11:15:45 +0000 Subject: [PATCH 16/34] feat: move busread and lookup block construction at the top of the trace (#10707) Constructing the lookup block and lookup table data at the top of the trace removes the dependence of active ranges on the dyadic circuit size which was causing problems for the overflow scenario and also reduces the number of active rows to be close to the real size (modulo https://github.com/AztecProtocol/barretenberg/issues/1152 which still needs investigation). --- .../cpp/scripts/compare_branch_vs_baseline.sh | 2 +- .../compare_branch_vs_baseline_remote.sh | 2 +- barretenberg/cpp/src/barretenberg/bb/main.cpp | 1 - .../commitment_schemes/commitment_key.hpp | 17 +- .../dsl/acir_format/acir_integration.test.cpp | 2 +- .../dsl/acir_proofs/honk_contract.hpp | 14 +- .../examples/join_split/join_split.test.cpp | 2 +- .../src/barretenberg/goblin/mock_circuits.hpp | 4 +- .../composer/composer_lib.hpp | 10 +- .../composer/composer_lib.test.cpp | 2 +- .../execution_trace_usage_tracker.hpp | 22 ++- .../execution_trace/mega_execution_trace.hpp | 94 +++++----- .../execution_trace/ultra_execution_trace.hpp | 30 ++-- .../stdlib_circuit_builders/mega_flavor.hpp | 33 ++-- .../stdlib_circuit_builders/ultra_flavor.hpp | 25 +-- .../ultra_keccak_flavor.hpp | 6 +- .../ultra_rollup_flavor.hpp | 6 +- .../ultra_honk/decider_proving_key.cpp | 23 +-- barretenberg/sol/package-lock.json | 6 + barretenberg/sol/src/honk/HonkTypes.sol | 4 +- .../sol/src/honk/instance/Add2Honk.sol | 10 +- .../sol/src/honk/instance/BlakeHonk.sol | 10 +- .../sol/src/honk/instance/EcdsaHonk.sol | 10 +- .../src/honk/keys/Add2HonkVerificationKey.sol | 166 +++++++++--------- .../honk/keys/BlakeHonkVerificationKey.sol | 166 +++++++++--------- .../honk/keys/EcdsaHonkVerificationKey.sol | 166 +++++++++--------- 26 files changed, 424 insertions(+), 409 deletions(-) create mode 100644 barretenberg/sol/package-lock.json diff --git a/barretenberg/cpp/scripts/compare_branch_vs_baseline.sh b/barretenberg/cpp/scripts/compare_branch_vs_baseline.sh index f798893781e..717b7be7800 100755 --- a/barretenberg/cpp/scripts/compare_branch_vs_baseline.sh +++ b/barretenberg/cpp/scripts/compare_branch_vs_baseline.sh @@ -10,7 +10,7 @@ # it is up to date with local master, and run the script. # Specify the benchmark suite and the "baseline" branch against which to compare -BENCHMARK=${1:-goblin_bench} +BENCHMARK=${1:-client_ivc_bench} FILTER=${2:-""} PRESET=${3:-clang16} BUILD_DIR=${4:-build} diff --git a/barretenberg/cpp/scripts/compare_branch_vs_baseline_remote.sh b/barretenberg/cpp/scripts/compare_branch_vs_baseline_remote.sh index 7c9192fa3f7..50cf755990a 100755 --- a/barretenberg/cpp/scripts/compare_branch_vs_baseline_remote.sh +++ b/barretenberg/cpp/scripts/compare_branch_vs_baseline_remote.sh @@ -10,7 +10,7 @@ # it is up to date with local master, and run the script. # Specify the benchmark suite and the "baseline" branch against which to compare -BENCHMARK=${1:-goblin_bench} +BENCHMARK=${1:-client_ivc_bench} FILTER=${2:-"*."} PRESET=${3:-clang16} BUILD_DIR=${4:-build} diff --git a/barretenberg/cpp/src/barretenberg/bb/main.cpp b/barretenberg/cpp/src/barretenberg/bb/main.cpp index 73f3078c2ba..f5a68f710ba 100644 --- a/barretenberg/cpp/src/barretenberg/bb/main.cpp +++ b/barretenberg/cpp/src/barretenberg/bb/main.cpp @@ -243,7 +243,6 @@ void prove_tube(const std::string& output_path) using Verifier = UltraVerifier_; Prover tube_prover{ *builder }; auto tube_proof = tube_prover.construct_proof(); - info("tube proof length: ", tube_proof.size()); std::string tubeProofPath = output_path + "/proof"; write_file(tubeProofPath, to_buffer(tube_proof)); diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.hpp index 81ef54a2b9d..dca262c5edc 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.hpp @@ -232,17 +232,16 @@ template class CommitmentKey { std::vector scalars; scalars.reserve(total_num_scalars); - for (const auto& range : active_ranges) { - auto start = &polynomial[range.first]; - auto end = &polynomial[range.second]; - scalars.insert(scalars.end(), start, end); - } std::vector points; points.reserve(total_num_scalars * 2); - for (const auto& range : active_ranges) { - auto start = &point_table[2 * range.first]; - auto end = &point_table[2 * range.second]; - points.insert(points.end(), start, end); + for (const auto& [first, second] : active_ranges) { + auto poly_start = &polynomial[first]; + auto poly_end = &polynomial[second]; + scalars.insert(scalars.end(), poly_start, poly_end); + + auto pts_start = &point_table[2 * first]; + auto pts_end = &point_table[2 * second]; + points.insert(points.end(), pts_start, pts_end); } // Call pippenger diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_integration.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_integration.test.cpp index 1a0d7b5b823..4a5097a4dd4 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_integration.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_integration.test.cpp @@ -142,7 +142,7 @@ class AcirIntegrationFoldingTest : public AcirIntegrationTest, public testing::W TEST_P(AcirIntegrationSingleTest, DISABLED_ProveAndVerifyProgram) { - using Flavor = MegaFlavor; + using Flavor = UltraFlavor; // using Flavor = bb::plonk::flavor::Ultra; using Builder = Flavor::CircuitBuilder; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp index e074cb956bf..c55919b4edc 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp @@ -166,11 +166,11 @@ enum WIRE { Q_R, Q_O, Q_4, + Q_LOOKUP, Q_ARITH, Q_RANGE, Q_ELLIPTIC, Q_AUX, - Q_LOOKUP, Q_POSEIDON2_EXTERNAL, Q_POSEIDON2_INTERNAL, SIGMA_1, @@ -227,11 +227,11 @@ library Honk { G1Point qr; G1Point qo; G1Point q4; + G1Point qLookup; // Lookup G1Point qArith; // Arithmetic widget G1Point qDeltaRange; // Delta Range sort G1Point qAux; // Auxillary G1Point qElliptic; // Auxillary - G1Point qLookup; // Lookup G1Point qPoseidon2External; G1Point qPoseidon2Internal; // Copy cnstraints @@ -1654,11 +1654,11 @@ contract HonkVerifier is IVerifier commitments[4] = vk.qr; commitments[5] = vk.qo; commitments[6] = vk.q4; - commitments[7] = vk.qArith; - commitments[8] = vk.qDeltaRange; - commitments[9] = vk.qElliptic; - commitments[10] = vk.qAux; - commitments[11] = vk.qLookup; + commitments[7] = vk.qLookup; + commitments[8] = vk.qArith; + commitments[9] = vk.qDeltaRange; + commitments[10] = vk.qElliptic; + commitments[11] = vk.qAux; commitments[12] = vk.qPoseidon2External; commitments[13] = vk.qPoseidon2Internal; commitments[14] = vk.s1; diff --git a/barretenberg/cpp/src/barretenberg/examples/join_split/join_split.test.cpp b/barretenberg/cpp/src/barretenberg/examples/join_split/join_split.test.cpp index 677e30f198c..1c516b7ae9d 100644 --- a/barretenberg/cpp/src/barretenberg/examples/join_split/join_split.test.cpp +++ b/barretenberg/cpp/src/barretenberg/examples/join_split/join_split.test.cpp @@ -703,7 +703,7 @@ TEST_F(join_split_tests, test_0_input_notes_and_detect_circuit_change) // The below part detects any changes in the join-split circuit constexpr size_t DYADIC_CIRCUIT_SIZE = 1 << 16; - constexpr uint256_t CIRCUIT_HASH("0xe833d0ffaa99f39ca31ef79ded0089b0ec614eb4a528c4e1c4af6221a003fa6e"); + constexpr uint256_t CIRCUIT_HASH("0x9ffbbd2c3ebd45cba861d3da6f75e2f73c448cc5747c9e34b44d6bc8a90b4a9c"); const uint256_t circuit_hash = circuit.hash_circuit(); // circuit is finalized now diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index 03c86a55b08..237e51a46d7 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -23,15 +23,15 @@ namespace bb { * they overflow */ static constexpr TraceStructure SMALL_TEST_STRUCTURE_FOR_OVERFLOWS{ .ecc_op = 1 << 14, - .pub_inputs = 1 << 14, .busread = 1 << 14, + .lookup = 1 << 14, + .pub_inputs = 1 << 14, .arithmetic = 1 << 15, .delta_range = 1 << 14, .elliptic = 1 << 14, .aux = 1 << 14, .poseidon2_external = 1 << 14, .poseidon2_internal = 1 << 15, - .lookup = 1 << 14, .overflow = 0 }; class GoblinMockCircuits { diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.hpp index 9328260c87e..e4aa5872433 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.hpp @@ -25,7 +25,10 @@ void construct_lookup_table_polynomials(const RefArray tables_size + additional_offset); - size_t offset = dyadic_circuit_size - tables_size - additional_offset; + size_t offset = circuit.blocks.lookup.trace_offset; + if constexpr (IsPlonkFlavor) { + offset = circuit.blocks.lookup.trace_offset + additional_offset; + } for (const auto& table : circuit.lookup_tables) { const fr table_index(table.table_index); @@ -51,11 +54,10 @@ template void construct_lookup_read_counts(typename Flavor::Polynomial& read_counts, typename Flavor::Polynomial& read_tags, typename Flavor::CircuitBuilder& circuit, - const size_t dyadic_circuit_size) + [[maybe_unused]] const size_t dyadic_circuit_size) { - const size_t tables_size = circuit.get_tables_size(); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1033): construct tables and counts at top of trace - size_t table_offset = dyadic_circuit_size - tables_size - MASKING_OFFSET; + size_t table_offset = circuit.blocks.lookup.trace_offset; // loop over all tables used in the circuit; each table contains data about the lookups made on it for (auto& table : circuit.lookup_tables) { diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.test.cpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.test.cpp index 84b04a5e331..ccdc191c62a 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.test.cpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.test.cpp @@ -55,7 +55,7 @@ TEST_F(ComposerLibTests, LookupReadCounts) // The table polys are constructed at the bottom of the trace, thus so to are the counts/tags // TODO(https://github.com/AztecProtocol/barretenberg/issues/1033): construct tables and counts at top of trace - size_t offset = circuit_size - builder.get_tables_size() - MASKING_OFFSET; + size_t offset = builder.blocks.lookup.trace_offset; // The uint32 XOR lookup table is constructed for 6 bit operands via double for loop that iterates through the left // operand externally (0 to 63) then the right operand internally (0 to 63). Computing (1 XOR 5) will thus result in diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/execution_trace_usage_tracker.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/execution_trace_usage_tracker.hpp index 91837b267dd..a8bb7e892da 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/execution_trace_usage_tracker.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/execution_trace_usage_tracker.hpp @@ -33,16 +33,17 @@ struct ExecutionTraceUsageTracker { size_t max_tables_size = 0; // For printing only. Must match the order of the members in the arithmetization + static constexpr std::array block_labels{ "ecc_op", - "pub_inputs", "busread", + "lookup", + "pub_inputs", "arithmetic", "delta_range", "elliptic", "aux", "poseidon2_external", "poseidon2_internal", - "lookup", "overflow", "databus_table_data", "lookup_table_data" }; @@ -88,21 +89,18 @@ struct ExecutionTraceUsageTracker { } // The active ranges must also include the rows where the actual databus and lookup table data are stored. - // (Note: lookup tables are constructed at the end of the trace; databus data is constructed at the start) so we - // need to determine the dyadic size for this. We call the size function on the current circuit which will have - // the same fixed block sizes but might also have an overflow block potentially influencing the dyadic circuit - // size. - // TODO(https://github.com/AztecProtocol/barretenberg/issues/1160) - const size_t dyadic_circuit_size = circuit.blocks.get_structured_dyadic_size(); + // (Note: lookup tables are constructed from the beginning of the lookup block ; databus data is constructed at + // the start of the trace). // TODO(https://github.com/AztecProtocol/barretenberg/issues/1152): should be able to use simply Range{ 0, - // max_databus_size } but this breaks for certain choices of num_threads. + // max_databus_size } but this breaks for certain choices of num_threads. It should also be possible to have the + // lookup table data be Range{lookup_start, max_tables_size} but that also breaks. size_t databus_end = std::max(max_databus_size, static_cast(fixed_sizes.busread.trace_offset + max_sizes.busread)); active_ranges.push_back(Range{ 0, databus_end }); - size_t lookups_start = - std::min(dyadic_circuit_size - max_tables_size, static_cast(fixed_sizes.lookup.trace_offset)); - active_ranges.push_back(Range{ lookups_start, dyadic_circuit_size }); + size_t lookups_start = fixed_sizes.lookup.trace_offset; + size_t lookups_end = lookups_start + std::max(max_tables_size, static_cast(max_sizes.lookup)); + active_ranges.emplace_back(Range{ lookups_start, lookups_end }); } // Check whether an index is contained within the active ranges (or previous active ranges; needed for perturbator) diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/mega_execution_trace.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/mega_execution_trace.hpp index de98846ab47..e1d31a9fac1 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/mega_execution_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/mega_execution_trace.hpp @@ -14,55 +14,46 @@ namespace bb { * * @details We instantiate this both to contain the actual gates of an execution trace, and also to describe different * trace structures (i.e., sets of capacities for each block type, which we use to optimize the folding prover). + * Note: the ecc_op block has to be the first in the execution trace to not break the Goblin functionality. */ template struct MegaTraceBlockData { T ecc_op; - T pub_inputs; T busread; + T lookup; + T pub_inputs; T arithmetic; T delta_range; T elliptic; T aux; T poseidon2_external; T poseidon2_internal; - T lookup; T overflow; // block gates of arbitrary type that overflow their designated block std::vector get_labels() const { - return { "ecc_op", - "pub_inputs", - "busread", - "arithmetic", - "delta_range", - "elliptic", - "aux", - "poseidon2_external", - "poseidon2_internal", - "lookup", + return { "ecc_op", "busread", "lookup", "pub_inputs", "arithmetic", + "delta_range", "elliptic", "aux", "poseidon2_external", "poseidon2_internal", "overflow" }; } auto get() { - return RefArray{ - ecc_op, pub_inputs, busread, arithmetic, delta_range, elliptic, aux, poseidon2_external, poseidon2_internal, - lookup, overflow - }; + return RefArray{ ecc_op, busread, lookup, pub_inputs, arithmetic, + delta_range, elliptic, aux, poseidon2_external, poseidon2_internal, + overflow }; } auto get() const { - return RefArray{ - ecc_op, pub_inputs, busread, arithmetic, delta_range, elliptic, aux, poseidon2_external, poseidon2_internal, - lookup, overflow - }; + return RefArray{ ecc_op, busread, lookup, pub_inputs, arithmetic, + delta_range, elliptic, aux, poseidon2_external, poseidon2_internal, + overflow }; } auto get_gate_blocks() const { return RefArray{ - busread, arithmetic, delta_range, elliptic, aux, poseidon2_external, poseidon2_internal, lookup + busread, lookup, arithmetic, delta_range, elliptic, aux, poseidon2_external, poseidon2_internal, }; } @@ -125,24 +116,26 @@ class MegaTraceBlock : public ExecutionTraceBlockselectors[4]; }; auto& q_4() { return this->selectors[5]; }; auto& q_busread() { return this->selectors[6]; }; - auto& q_arith() { return this->selectors[7]; }; - auto& q_delta_range() { return this->selectors[8]; }; - auto& q_elliptic() { return this->selectors[9]; }; - auto& q_aux() { return this->selectors[10]; }; - auto& q_poseidon2_external() { return this->selectors[11]; }; - auto& q_poseidon2_internal() { return this->selectors[12]; }; - auto& q_lookup_type() { return this->selectors[13]; }; + auto& q_lookup_type() { return this->selectors[7]; }; + auto& q_arith() { return this->selectors[8]; }; + auto& q_delta_range() { return this->selectors[9]; }; + auto& q_elliptic() { return this->selectors[10]; }; + auto& q_aux() { return this->selectors[11]; }; + auto& q_poseidon2_external() { return this->selectors[12]; }; + auto& q_poseidon2_internal() { return this->selectors[13]; }; RefVector get_gate_selectors() { - return { q_busread(), - q_arith(), - q_delta_range(), - q_elliptic(), - q_aux(), - q_poseidon2_external(), - q_poseidon2_internal(), - q_lookup_type() }; + return { + q_busread(), + q_lookup_type(), + q_arith(), + q_delta_range(), + q_elliptic(), + q_aux(), + q_poseidon2_external(), + q_poseidon2_internal(), + }; } /** @@ -210,19 +203,19 @@ class MegaExecutionTraceBlocks : public MegaTraceBlockData { { info("Gate blocks summary: (actual gates / fixed capacity)"); info("goblin ecc op :\t", this->ecc_op.size(), "/", this->ecc_op.get_fixed_size()); + info("busread :\t", this->busread.size(), "/", this->busread.get_fixed_size()); + info("lookups :\t", this->lookup.size(), "/", this->lookup.get_fixed_size()); info("pub inputs :\t", this->pub_inputs.size(), "/", this->pub_inputs.get_fixed_size(), " (populated in decider pk constructor)"); - info("busread :\t", this->busread.size(), "/", this->busread.get_fixed_size()); info("arithmetic :\t", this->arithmetic.size(), "/", this->arithmetic.get_fixed_size()); info("delta range :\t", this->delta_range.size(), "/", this->delta_range.get_fixed_size()); info("elliptic :\t", this->elliptic.size(), "/", this->elliptic.get_fixed_size()); info("auxiliary :\t", this->aux.size(), "/", this->aux.get_fixed_size()); info("poseidon ext :\t", this->poseidon2_external.size(), "/", this->poseidon2_external.get_fixed_size()); info("poseidon int :\t", this->poseidon2_internal.size(), "/", this->poseidon2_internal.get_fixed_size()); - info("lookups :\t", this->lookup.size(), "/", this->lookup.get_fixed_size()); info("overflow :\t", this->overflow.size(), "/", this->overflow.get_fixed_size()); info(""); } @@ -251,30 +244,31 @@ class MegaExecutionTraceBlocks : public MegaTraceBlockData { * @brief A tiny structuring (for testing without recursive verifications only) */ static constexpr TraceStructure TINY_TEST_STRUCTURE{ .ecc_op = 18, - .pub_inputs = 1, .busread = 3, + .lookup = 2, + .pub_inputs = 1, .arithmetic = 1 << 14, .delta_range = 5, .elliptic = 2, .aux = 10, .poseidon2_external = 2, .poseidon2_internal = 2, - .lookup = 2, .overflow = 0 }; /** * @brief An arbitrary but small-ish structuring that can be used for generic unit testing with non-trivial circuits */ + static constexpr TraceStructure SMALL_TEST_STRUCTURE{ .ecc_op = 1 << 14, - .pub_inputs = 1 << 14, .busread = 1 << 14, + .lookup = 1 << 14, + .pub_inputs = 1 << 14, .arithmetic = 1 << 15, .delta_range = 1 << 14, .elliptic = 1 << 14, .aux = 1 << 14, .poseidon2_external = 1 << 14, .poseidon2_internal = 1 << 15, - .lookup = 1 << 14, .overflow = 0 }; /** @@ -282,60 +276,60 @@ static constexpr TraceStructure SMALL_TEST_STRUCTURE{ .ecc_op = 1 << 14, * benchmark. */ static constexpr TraceStructure CLIENT_IVC_BENCH_STRUCTURE{ .ecc_op = 1 << 10, - .pub_inputs = 1 << 7, .busread = 1 << 7, + .lookup = 72000, + .pub_inputs = 1 << 7, .arithmetic = 198000, .delta_range = 90000, .elliptic = 9000, .aux = 136000, .poseidon2_external = 2500, .poseidon2_internal = 14000, - .lookup = 72000, .overflow = 0 }; /** * @brief An example structuring of size 2^18. */ static constexpr TraceStructure EXAMPLE_18{ .ecc_op = 1 << 10, - .pub_inputs = 1 << 6, .busread = 1 << 6, + .lookup = 36000, + .pub_inputs = 1 << 6, .arithmetic = 84000, .delta_range = 45000, .elliptic = 9000, .aux = 68000, .poseidon2_external = 2500, .poseidon2_internal = 14000, - .lookup = 36000, .overflow = 0 }; /** * @brief An example structuring of size 2^20. */ static constexpr TraceStructure EXAMPLE_20{ .ecc_op = 1 << 11, - .pub_inputs = 1 << 8, .busread = 1 << 8, + .lookup = 144000, + .pub_inputs = 1 << 8, .arithmetic = 396000, .delta_range = 180000, .elliptic = 18000, .aux = 272000, .poseidon2_external = 5000, .poseidon2_internal = 28000, - .lookup = 144000, .overflow = 0 }; /** * @brief Structuring tailored to the full e2e TS test (TO BE UPDATED ACCORDINGLY) */ static constexpr TraceStructure E2E_FULL_TEST_STRUCTURE{ .ecc_op = 1 << 10, - .pub_inputs = 4000, .busread = 6000, + .lookup = 200000, + .pub_inputs = 4000, .arithmetic = 200000, .delta_range = 25000, .elliptic = 80000, .aux = 100000, .poseidon2_external = 30128, .poseidon2_internal = 172000, - .lookup = 200000, .overflow = 0 }; template diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/ultra_execution_trace.hpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/ultra_execution_trace.hpp index ccf81b1645c..0bed250dc39 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/ultra_execution_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/execution_trace/ultra_execution_trace.hpp @@ -15,25 +15,25 @@ namespace bb { * @tparam T */ template struct UltraTraceBlockData { - T pub_inputs; + T pub_inputs; // Has to be the first block otherwise Plonk breaks + T lookup; T arithmetic; T delta_range; T elliptic; T aux; - T lookup; T poseidon2_external; T poseidon2_internal; T overflow; auto get() { - return RefArray{ pub_inputs, arithmetic, delta_range, elliptic, aux, - lookup, poseidon2_external, poseidon2_internal, overflow }; + return RefArray{ pub_inputs, lookup, arithmetic, delta_range, elliptic, aux, poseidon2_external, + poseidon2_internal, overflow }; } auto get_gate_blocks() const { - return RefArray{ arithmetic, delta_range, elliptic, aux, lookup, poseidon2_external, poseidon2_internal }; + return RefArray{ lookup, arithmetic, delta_range, elliptic, aux, poseidon2_external, poseidon2_internal }; } bool operator==(const UltraTraceBlockData& other) const = default; @@ -66,18 +66,20 @@ class UltraTraceBlock : public ExecutionTraceBlockselectors[3]; }; auto& q_3() { return this->selectors[4]; }; auto& q_4() { return this->selectors[5]; }; - auto& q_arith() { return this->selectors[6]; }; - auto& q_delta_range() { return this->selectors[7]; }; - auto& q_elliptic() { return this->selectors[8]; }; - auto& q_aux() { return this->selectors[9]; }; - auto& q_lookup_type() { return this->selectors[10]; }; + auto& q_lookup_type() { return this->selectors[6]; }; + auto& q_arith() { return this->selectors[7]; }; + auto& q_delta_range() { return this->selectors[8]; }; + auto& q_elliptic() { return this->selectors[9]; }; + auto& q_aux() { return this->selectors[10]; }; auto& q_poseidon2_external() { return this->selectors[11]; }; auto& q_poseidon2_internal() { return this->selectors[12]; }; RefVector get_gate_selectors() { - return { q_arith(), q_delta_range(), q_elliptic(), q_aux(), q_poseidon2_external(), q_poseidon2_internal(), - q_lookup_type() }; + return { + q_lookup_type(), q_arith(), q_delta_range(), q_elliptic(), q_aux(), q_poseidon2_external(), + q_poseidon2_internal(), + }; } }; @@ -113,11 +115,11 @@ class UltraExecutionTraceBlocks : public UltraTraceBlockData { { info("Gate blocks summary:"); info("pub inputs :\t", this->pub_inputs.size()); + info("lookups :\t", this->lookup.size()); info("arithmetic :\t", this->arithmetic.size()); info("delta range:\t", this->delta_range.size()); info("elliptic :\t", this->elliptic.size()); info("auxiliary :\t", this->aux.size()); - info("lookups :\t", this->lookup.size()); info("poseidon ext :\t", this->poseidon2_external.size()); info("poseidon int :\t", this->poseidon2_internal.size()); info("overflow :\t", this->overflow.size()); @@ -146,11 +148,11 @@ class UltraExecutionTraceBlocks : public UltraTraceBlockData { "q_2", "q_3", "q_4", + "table_type", "q_arith", "q_sort", "q_elliptic", "q_aux", - "table_type", "q_poseidon2_external", "q_poseidon2_internal" }; }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp index 6035a698fe3..e9a1e93b6a3 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -119,13 +119,13 @@ class MegaFlavor { q_o, // column 4 q_4, // column 5 q_busread, // column 6 - q_arith, // column 7 - q_delta_range, // column 8 - q_elliptic, // column 9 - q_aux, // column 10 - q_poseidon2_external, // column 11 - q_poseidon2_internal, // column 12 - q_lookup, // column 13 + q_lookup, // column 7 + q_arith, // column 8 + q_delta_range, // column 9 + q_elliptic, // column 10 + q_aux, // column 11 + q_poseidon2_external, // column 12 + q_poseidon2_internal, // column 13 sigma_1, // column 14 sigma_2, // column 15 sigma_3, // column 16 @@ -150,8 +150,15 @@ class MegaFlavor { auto get_gate_selectors() { return RefArray{ - q_busread, q_arith, q_delta_range, q_elliptic, q_aux, q_poseidon2_external, q_poseidon2_internal, - q_lookup + q_busread, + q_lookup, + q_arith, + q_delta_range, + q_elliptic, + q_aux, + q_poseidon2_external, + q_poseidon2_internal, + }; } auto get_selectors() { return concatenate(get_non_gate_selectors(), get_gate_selectors()); } @@ -603,13 +610,13 @@ class MegaFlavor { const Commitment& q_o, const Commitment& q_4, const Commitment& q_busread, + const Commitment& q_lookup, const Commitment& q_arith, const Commitment& q_delta_range, const Commitment& q_elliptic, const Commitment& q_aux, const Commitment& q_poseidon2_external, const Commitment& q_poseidon2_internal, - const Commitment& q_lookup, const Commitment& sigma_1, const Commitment& sigma_2, const Commitment& sigma_3, @@ -641,13 +648,13 @@ class MegaFlavor { this->q_o = q_o; this->q_4 = q_4; this->q_busread = q_busread; + this->q_lookup = q_lookup; this->q_arith = q_arith; this->q_delta_range = q_delta_range; this->q_elliptic = q_elliptic; this->q_aux = q_aux; this->q_poseidon2_external = q_poseidon2_external; this->q_poseidon2_internal = q_poseidon2_internal; - this->q_lookup = q_lookup; this->sigma_1 = sigma_1; this->sigma_2 = sigma_2; this->sigma_3 = sigma_3; @@ -679,13 +686,13 @@ class MegaFlavor { q_o, q_4, q_busread, + q_lookup, q_arith, q_delta_range, q_elliptic, q_aux, q_poseidon2_external, q_poseidon2_internal, - q_lookup, sigma_1, sigma_2, sigma_3, @@ -785,13 +792,13 @@ class MegaFlavor { q_4 = "Q_4"; q_m = "Q_M"; q_busread = "Q_BUSREAD"; + q_lookup = "Q_LOOKUP"; q_arith = "Q_ARITH"; q_delta_range = "Q_SORT"; q_elliptic = "Q_ELLIPTIC"; q_aux = "Q_AUX"; q_poseidon2_external = "Q_POSEIDON2_EXTERNAL"; q_poseidon2_internal = "Q_POSEIDON2_INTERNAL"; - q_lookup = "Q_LOOKUP"; sigma_1 = "SIGMA_1"; sigma_2 = "SIGMA_2"; sigma_3 = "SIGMA_3"; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp index bfa61280c64..dbaff9cadea 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp @@ -125,11 +125,11 @@ class UltraFlavor { q_r, // column 3 q_o, // column 4 q_4, // column 5 - q_arith, // column 6 - q_delta_range, // column 7 - q_elliptic, // column 8 - q_aux, // column 9 - q_lookup, // column 10 + q_lookup, // column 6 + q_arith, // column 7 + q_delta_range, // column 8 + q_elliptic, // column 9 + q_aux, // column 10 q_poseidon2_external, // column 11 q_poseidon2_internal, // column 12 sigma_1, // column 13 @@ -152,8 +152,9 @@ class UltraFlavor { auto get_non_gate_selectors() { return RefArray{ q_m, q_c, q_l, q_r, q_o, q_4 }; } auto get_gate_selectors() { - return RefArray{ q_arith, q_delta_range, q_elliptic, q_aux, - q_lookup, q_poseidon2_external, q_poseidon2_internal }; + return RefArray{ + q_lookup, q_arith, q_delta_range, q_elliptic, q_aux, q_poseidon2_external, q_poseidon2_internal + }; } auto get_selectors() { return concatenate(get_non_gate_selectors(), get_gate_selectors()); } @@ -436,11 +437,11 @@ class UltraFlavor { const Commitment& q_r, const Commitment& q_o, const Commitment& q_4, + const Commitment& q_lookup, const Commitment& q_arith, const Commitment& q_delta_range, const Commitment& q_elliptic, const Commitment& q_aux, - const Commitment& q_lookup, const Commitment& q_poseidon2_external, const Commitment& q_poseidon2_internal, const Commitment& sigma_1, @@ -470,11 +471,11 @@ class UltraFlavor { this->q_r = q_r; this->q_o = q_o; this->q_4 = q_4; + this->q_lookup = q_lookup; this->q_arith = q_arith; this->q_delta_range = q_delta_range; this->q_elliptic = q_elliptic; this->q_aux = q_aux; - this->q_lookup = q_lookup; this->q_poseidon2_external = q_poseidon2_external; this->q_poseidon2_internal = q_poseidon2_internal; this->sigma_1 = sigma_1; @@ -506,11 +507,11 @@ class UltraFlavor { q_r, q_o, q_4, + q_lookup, q_arith, q_delta_range, q_elliptic, q_aux, - q_lookup, q_poseidon2_external, q_poseidon2_internal, sigma_1, @@ -596,11 +597,11 @@ class UltraFlavor { q_o = "Q_O"; q_4 = "Q_4"; q_m = "Q_M"; + q_lookup = "Q_LOOKUP"; q_arith = "Q_ARITH"; q_delta_range = "Q_SORT"; q_elliptic = "Q_ELLIPTIC"; q_aux = "Q_AUX"; - q_lookup = "Q_LOOKUP"; q_poseidon2_external = "Q_POSEIDON2_EXTERNAL"; q_poseidon2_internal = "Q_POSEIDON2_INTERNAL"; sigma_1 = "SIGMA_1"; @@ -637,11 +638,11 @@ class UltraFlavor { this->q_r = verification_key->q_r; this->q_o = verification_key->q_o; this->q_4 = verification_key->q_4; + this->q_lookup = verification_key->q_lookup; this->q_arith = verification_key->q_arith; this->q_delta_range = verification_key->q_delta_range; this->q_elliptic = verification_key->q_elliptic; this->q_aux = verification_key->q_aux; - this->q_lookup = verification_key->q_lookup; this->q_poseidon2_external = verification_key->q_poseidon2_external; this->q_poseidon2_internal = verification_key->q_poseidon2_internal; this->sigma_1 = verification_key->sigma_1; diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_keccak_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_keccak_flavor.hpp index 8ca7f72b418..e7b47f9235a 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_keccak_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_keccak_flavor.hpp @@ -67,11 +67,11 @@ class UltraKeccakFlavor : public bb::UltraFlavor { const Commitment& q_r, const Commitment& q_o, const Commitment& q_4, + const Commitment& q_lookup, const Commitment& q_arith, const Commitment& q_delta_range, const Commitment& q_elliptic, const Commitment& q_aux, - const Commitment& q_lookup, const Commitment& q_poseidon2_external, const Commitment& q_poseidon2_internal, const Commitment& sigma_1, @@ -99,11 +99,11 @@ class UltraKeccakFlavor : public bb::UltraFlavor { this->q_r = q_r; this->q_o = q_o; this->q_4 = q_4; + this->q_lookup = q_lookup; this->q_arith = q_arith; this->q_delta_range = q_delta_range; this->q_elliptic = q_elliptic; this->q_aux = q_aux; - this->q_lookup = q_lookup; this->q_poseidon2_external = q_poseidon2_external; this->q_poseidon2_internal = q_poseidon2_internal; this->sigma_1 = sigma_1; @@ -133,11 +133,11 @@ class UltraKeccakFlavor : public bb::UltraFlavor { q_r, q_o, q_4, + q_lookup, q_arith, q_delta_range, q_elliptic, q_aux, - q_lookup, q_poseidon2_external, q_poseidon2_internal, sigma_1, diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp index 6deb40b7020..440d1051834 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_rollup_flavor.hpp @@ -99,11 +99,11 @@ class UltraRollupFlavor : public bb::UltraFlavor { const Commitment& q_r, const Commitment& q_o, const Commitment& q_4, + const Commitment& q_lookup, const Commitment& q_arith, const Commitment& q_delta_range, const Commitment& q_elliptic, const Commitment& q_aux, - const Commitment& q_lookup, const Commitment& q_poseidon2_external, const Commitment& q_poseidon2_internal, const Commitment& sigma_1, @@ -135,11 +135,11 @@ class UltraRollupFlavor : public bb::UltraFlavor { this->q_r = q_r; this->q_o = q_o; this->q_4 = q_4; + this->q_lookup = q_lookup; this->q_arith = q_arith; this->q_delta_range = q_delta_range; this->q_elliptic = q_elliptic; this->q_aux = q_aux; - this->q_lookup = q_lookup; this->q_poseidon2_external = q_poseidon2_external; this->q_poseidon2_internal = q_poseidon2_internal; this->sigma_1 = sigma_1; @@ -173,11 +173,11 @@ class UltraRollupFlavor : public bb::UltraFlavor { q_r, q_o, q_4, + q_lookup, q_arith, q_delta_range, q_elliptic, q_aux, - q_lookup, q_poseidon2_external, q_poseidon2_internal, sigma_1, diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp index 712452585ed..bcef1fe9343 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp @@ -98,9 +98,9 @@ void DeciderProvingKey_::allocate_table_lookup_polynomials(const Circuit { PROFILE_THIS_NAME("allocate_table_lookup_polynomials"); + size_t table_offset = circuit.blocks.lookup.trace_offset; const size_t max_tables_size = - std::min(static_cast(MAX_LOOKUP_TABLES_SIZE), dyadic_circuit_size - 1 - MASKING_OFFSET); - size_t table_offset = dyadic_circuit_size - max_tables_size - MASKING_OFFSET; + std::min(static_cast(MAX_LOOKUP_TABLES_SIZE), dyadic_circuit_size - table_offset); ASSERT(dyadic_circuit_size > max_tables_size); // Allocate the polynomials containing the actual table data @@ -115,14 +115,15 @@ void DeciderProvingKey_::allocate_table_lookup_polynomials(const Circuit proving_key.polynomials.lookup_read_tags = Polynomial(max_tables_size, dyadic_circuit_size, table_offset); ZoneScopedN("allocating lookup and databus inverses"); - // Allocate the log derivative lookup argument inverse polynomial - const size_t lookup_offset = static_cast(circuit.blocks.lookup.trace_offset); - const size_t masking_offset = (std::min(lookup_offset, table_offset) > MASKING_OFFSET) ? MASKING_OFFSET : 0; - const size_t lookup_inverses_start = std::min(lookup_offset, table_offset) - masking_offset; - const size_t lookup_inverses_end = - std::min(dyadic_circuit_size, - std::max(lookup_offset + circuit.blocks.lookup.get_fixed_size(is_structured), - table_offset + MAX_LOOKUP_TABLES_SIZE)); + const size_t lookup_block_end = + static_cast(circuit.blocks.lookup.trace_offset + circuit.blocks.lookup.get_fixed_size(is_structured)); + const auto tables_end = circuit.blocks.lookup.trace_offset + max_tables_size; + + // Allocate the lookup_inverses polynomial + + const size_t lookup_inverses_start = table_offset; + const size_t lookup_inverses_end = std::max(lookup_block_end, tables_end); + proving_key.polynomials.lookup_inverses = Polynomial(lookup_inverses_end - lookup_inverses_start, dyadic_circuit_size, lookup_inverses_start); } @@ -134,8 +135,8 @@ void DeciderProvingKey_::allocate_ecc_op_polynomials(const Circuit& circ PROFILE_THIS_NAME("allocate_ecc_op_polynomials"); // Allocate the ecc op wires and selector - const size_t ecc_op_block_size = circuit.blocks.ecc_op.get_fixed_size(is_structured); const size_t op_wire_offset = circuit.blocks.ecc_op.trace_offset; + const size_t ecc_op_block_size = circuit.blocks.ecc_op.get_fixed_size(is_structured); for (auto& wire : proving_key.polynomials.get_ecc_op_wires()) { wire = Polynomial(ecc_op_block_size, proving_key.circuit_size, op_wire_offset); } diff --git a/barretenberg/sol/package-lock.json b/barretenberg/sol/package-lock.json new file mode 100644 index 00000000000..dab5c8abab1 --- /dev/null +++ b/barretenberg/sol/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "sol", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/barretenberg/sol/src/honk/HonkTypes.sol b/barretenberg/sol/src/honk/HonkTypes.sol index abe8e1f4612..7832c767fc4 100644 --- a/barretenberg/sol/src/honk/HonkTypes.sol +++ b/barretenberg/sol/src/honk/HonkTypes.sol @@ -25,11 +25,11 @@ enum WIRE { Q_R, Q_O, Q_4, + Q_LOOKUP, Q_ARITH, Q_RANGE, Q_ELLIPTIC, Q_AUX, - Q_LOOKUP, Q_POSEIDON2_EXTERNAL, Q_POSEIDON2_INTERNAL, SIGMA_1, @@ -87,11 +87,11 @@ library Honk { G1Point qr; G1Point qo; G1Point q4; + G1Point qLookup; // Lookup G1Point qArith; // Arithmetic widget G1Point qDeltaRange; // Delta Range sort G1Point qAux; // Auxillary G1Point qElliptic; // Auxillary - G1Point qLookup; // Lookup G1Point qPoseidon2External; G1Point qPoseidon2Internal; // Copy cnstraints diff --git a/barretenberg/sol/src/honk/instance/Add2Honk.sol b/barretenberg/sol/src/honk/instance/Add2Honk.sol index 0d0f124102e..9107e9d1e2a 100644 --- a/barretenberg/sol/src/honk/instance/Add2Honk.sol +++ b/barretenberg/sol/src/honk/instance/Add2Honk.sol @@ -276,11 +276,11 @@ contract Add2HonkVerifier is IVerifier { commitments[4] = vk.qr; commitments[5] = vk.qo; commitments[6] = vk.q4; - commitments[7] = vk.qArith; - commitments[8] = vk.qDeltaRange; - commitments[9] = vk.qElliptic; - commitments[10] = vk.qAux; - commitments[11] = vk.qLookup; + commitments[7] = vk.qLookup; + commitments[8] = vk.qArith; + commitments[9] = vk.qDeltaRange; + commitments[10] = vk.qElliptic; + commitments[11] = vk.qAux; commitments[12] = vk.qPoseidon2External; commitments[13] = vk.qPoseidon2Internal; commitments[14] = vk.s1; diff --git a/barretenberg/sol/src/honk/instance/BlakeHonk.sol b/barretenberg/sol/src/honk/instance/BlakeHonk.sol index 2d52e2513d8..b49ee574373 100644 --- a/barretenberg/sol/src/honk/instance/BlakeHonk.sol +++ b/barretenberg/sol/src/honk/instance/BlakeHonk.sol @@ -277,11 +277,11 @@ contract BlakeHonkVerifier is IVerifier { commitments[4] = vk.qr; commitments[5] = vk.qo; commitments[6] = vk.q4; - commitments[7] = vk.qArith; - commitments[8] = vk.qDeltaRange; - commitments[9] = vk.qElliptic; - commitments[10] = vk.qAux; - commitments[11] = vk.qLookup; + commitments[7] = vk.qLookup; + commitments[8] = vk.qArith; + commitments[9] = vk.qDeltaRange; + commitments[10] = vk.qElliptic; + commitments[11] = vk.qAux; commitments[12] = vk.qPoseidon2External; commitments[13] = vk.qPoseidon2Internal; commitments[14] = vk.s1; diff --git a/barretenberg/sol/src/honk/instance/EcdsaHonk.sol b/barretenberg/sol/src/honk/instance/EcdsaHonk.sol index acd2a04f518..5afb9bd1b28 100644 --- a/barretenberg/sol/src/honk/instance/EcdsaHonk.sol +++ b/barretenberg/sol/src/honk/instance/EcdsaHonk.sol @@ -279,11 +279,11 @@ contract EcdsaHonkVerifier is IVerifier { commitments[4] = vk.qr; commitments[5] = vk.qo; commitments[6] = vk.q4; - commitments[7] = vk.qArith; - commitments[8] = vk.qDeltaRange; - commitments[9] = vk.qElliptic; - commitments[10] = vk.qAux; - commitments[11] = vk.qLookup; + commitments[7] = vk.qLookup; + commitments[8] = vk.qArith; + commitments[9] = vk.qDeltaRange; + commitments[10] = vk.qElliptic; + commitments[11] = vk.qAux; commitments[12] = vk.qPoseidon2External; commitments[13] = vk.qPoseidon2Internal; commitments[14] = vk.s1; diff --git a/barretenberg/sol/src/honk/keys/Add2HonkVerificationKey.sol b/barretenberg/sol/src/honk/keys/Add2HonkVerificationKey.sol index 2317f2a511f..1c246dc4d6b 100644 --- a/barretenberg/sol/src/honk/keys/Add2HonkVerificationKey.sol +++ b/barretenberg/sol/src/honk/keys/Add2HonkVerificationKey.sol @@ -2,123 +2,125 @@ // Copyright 2022 Aztec pragma solidity >=0.8.21; -import { Honk } from "../HonkTypes.sol"; +import {Honk} from "../HonkTypes.sol"; + uint256 constant N = 32; uint256 constant LOG_N = 5; uint256 constant NUMBER_OF_PUBLIC_INPUTS = 3; + library Add2HonkVerificationKey { function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) { Honk.VerificationKey memory vk = Honk.VerificationKey({ circuitSize: uint256(32), logCircuitSize: uint256(5), publicInputsSize: uint256(3), - ql: Honk.G1Point({ - x: uint256(0x043d063b130adfb37342af45d0155a28edd1a7e46c840d9c943fdf45521c64ce), - y: uint256(0x261522c4089330646aff96736194949330952ae74c573d1686d9cb4a00733854) + ql: Honk.G1Point({ + x: uint256(0x27456b3a666ff24c6452657437518f7b73e854ce6c763732122a3b923bc6797b), + y: uint256(0x2ecbc0db4ae72d05db96eb72034b26275a33325b05b2dd53c33662369bcdc4e0) }), - qr: Honk.G1Point({ - x: uint256(0x291338e99e7857222c76c5e4ba8b954f5fde09fd2f05634d622ba379657cd501), - y: uint256(0x137030ce3236d7c12307adf650a73b87fc95a774ec43ac0a3a341ef26b7f56c9) + qr: Honk.G1Point({ + x: uint256(0x274db2ddab5fc87804dcb835027d293547d5fc2b6cde27990e5577a3d77aa4b0), + y: uint256(0x29d2c716e45fccb7b1d8a3fb384854408392a74a4e4fb4d3cfab460efbfdb87d) }), - qo: Honk.G1Point({ - x: uint256(0x0f90f4bb16b330b82ef51e7ce3f70a9310ea2d3c5ef855f07b6f58081b5ef41f), - y: uint256(0x0e09412eea75978da57db1d3fa6b7d14c0e282c378be9a6d0efc5770863ed70b) + qo: Honk.G1Point({ + x: uint256(0x26da077296ea89f2b0caef070f7c380bedee8f4137d8e15972888cb873b6a849), + y: uint256(0x01028d4966e7b172aca7f9c56d169a449b2326bc0293d54f3708482a8fd09d26) }), - q4: Honk.G1Point({ - x: uint256(0x1eec247154ced5c29b0836528d7c19eda11399dc21e23df4bee4b5cd0bec659f), - y: uint256(0x107cc382fdee2f6530d39b072a2bc50bdb0c0ac4b054a905b03b9d53bebef404) + q4: Honk.G1Point({ + x: uint256(0x1b87b4f288e37e4ff07f6a368177b9765eeccd1017bec74e98859fa3fbf201f3), + y: uint256(0x1d100498fbe5bd401d2eb9b77f1a887806c8251de6ccab14008a324357e5ddfb) }), - qm: Honk.G1Point({ - x: uint256(0x0c17b7ba3864cabe287a2b121b5cb3f8ee4ede87a7f656b8d9b470be025007c8), - y: uint256(0x09590397bf354089980bd40f5d84f4c12faa8b4646425fa660ab7c4c76fb4859) + qm: Honk.G1Point({ + x: uint256(0x12dda3f2df2c6774290c833772e87ec75c9a658559506fcd1d743e0e98b6e0ad), + y: uint256(0x2df9dc1c291b41624c0ae46e40238467771572731402b64d664ed641c5078105) }), - qc: Honk.G1Point({ - x: uint256(0x2ac1a00b4c9bb4e7deef8d7a6bf9e26e61f2b935409e41c5770c074303b6d142), - y: uint256(0x192d962de288fb26f3d68052b2f475e884ca47e595de1184171cd1500249fa66) + qc: Honk.G1Point({ + x: uint256(0x0963fc084e9f28db0ad8f6d9cc0fd9dfdf2704140bb42debece9b98ed4e6915b), + y: uint256(0x1e81fc7c58c0d8ae1233acb9d57c1d69a82c4c1a418494558b735fba505f6877) }), - qArith: Honk.G1Point({ - x: uint256(0x1797e3e7ee9e4f42b42bd375f13f2ccb395b827e9079e999b6c128d9b083c395), - y: uint256(0x101a60efaab1c8564add45d41b9147efacf45941c3efe93c3568bde1e08e1919) + qArith: Honk.G1Point({ + x: uint256(0x06d4ca88fe948f6b5f555d318feea69879457f1cf2b22f7d464fa8d4a8b5cd46), + y: uint256(0x155440972055e3134a5b514eccdd47b0cc217ff529b603700339d647b7e338d3) }), - qDeltaRange: Honk.G1Point({ - x: uint256(0x0e84090add56f2500ab518c655cae63896ea793e6b3f6a14218d476534109610), - y: uint256(0x2b78a584bd6ae88cf4ec7c65c90e0b65df446fdddba972f3c4414ad3c901f4f9) + qDeltaRange: Honk.G1Point({ + x: uint256(0x1bd6129f9646aa21af0d77e7b1cc9794e611b5d59a27773f744710b476fbd30f), + y: uint256(0x2f8d492d76a22b6834f0b88e2d4096139a9d1593d56e65e710b2f344756b721e) }), - qElliptic: Honk.G1Point({ - x: uint256(0x1bd6129f9646aa21af0d77e7b1cc9794e611b5d59a27773f744710b476fbd30f), - y: uint256(0x2f8d492d76a22b6834f0b88e2d4096139a9d1593d56e65e710b2f344756b721e) + qElliptic: Honk.G1Point({ + x: uint256(0x056ab50282da428d93b17cbd1c81267dcebcfbabdedb47b2d715b5baa6520bff), + y: uint256(0x10b4e7bd9d6d91a57b0695be166ffd27cbeee602bcb5a9ed32c8d9440912cb72) }), - qAux: Honk.G1Point({ - x: uint256(0x056ab50282da428d93b17cbd1c81267dcebcfbabdedb47b2d715b5baa6520bff), - y: uint256(0x10b4e7bd9d6d91a57b0695be166ffd27cbeee602bcb5a9ed32c8d9440912cb72) + qAux: Honk.G1Point({ + x: uint256(0x024236bda126650fb5228cf424a0878775499e69e8bd2c39af33bd5fa0b4079a), + y: uint256(0x233cda9292be02cfa2da9d0fc7b0eab0eb1a867b06854066589b967455259b32) }), - qLookup: Honk.G1Point({ - x: uint256(0x19e2d786ebad24caf1bef735441e58525a2f9b5807b2102f295c58cde00f5c97), - y: uint256(0x085713ce7bac807a084a66904ebc6e695840e8cf405a6fd0c325f8bfcf7c2dd8) + qLookup: Honk.G1Point({ + x: uint256(0x2594d00a131b347f472a021eac09e25eacba35749a9ba8f8c7f4a726ff63a910), + y: uint256(0x2499be5abe1cf5463534a1d0613f82449f1989f1186f2d0b67295bda7f8a0f55) }), - qPoseidon2External: Honk.G1Point({ - x: uint256(0x0ca0bc4b1cd9eadbbf49eae56a99a4502ef13d965226a634d0981555e4a4da56), - y: uint256(0x1a8a818e6c61f68cefa329f2fabc95c80ad56a538d852f75eda858ed1a616c74) + qPoseidon2External: Honk.G1Point({ + x: uint256(0x0ca0bc4b1cd9eadbbf49eae56a99a4502ef13d965226a634d0981555e4a4da56), + y: uint256(0x1a8a818e6c61f68cefa329f2fabc95c80ad56a538d852f75eda858ed1a616c74) }), - qPoseidon2Internal: Honk.G1Point({ - x: uint256(0x09dfd2992ac1708f0dd1d28c2ad910d9cf21a1510948580f406bc9416113d620), - y: uint256(0x205f76eebda12f565c98c775c4e4f3534b5dcc29e57eed899b1a1a880534dcb9) + qPoseidon2Internal: Honk.G1Point({ + x: uint256(0x09dfd2992ac1708f0dd1d28c2ad910d9cf21a1510948580f406bc9416113d620), + y: uint256(0x205f76eebda12f565c98c775c4e4f3534b5dcc29e57eed899b1a1a880534dcb9) }), - s1: Honk.G1Point({ - x: uint256(0x19a07402ffcc103c3d8fbfbc7e9a660147d7380e65c34f64b75701b8d4868c11), - y: uint256(0x0b7ab8c749a4af75d6100dba9246d7f993748b326d23791a595e21a17653fe30) + s1: Honk.G1Point({ + x: uint256(0x2183ad847a1249f41cbd3a87f40c2f430eec8e15078ebf4294072495293f623a), + y: uint256(0x18f03d44febf5942b0325bd60625eb1d407adb20bdc51e770aa1f4ca1daf767c) }), - s2: Honk.G1Point({ - x: uint256(0x027234cb39eacbf2ebe98907cf433e429a37933e429d4f24df14274b5c4d2549), - y: uint256(0x2c1ea0996e3fd6cfabcfc6bbd4c86c65fb19c3dda2ded5c4f973af397e8e5c8b) + s2: Honk.G1Point({ + x: uint256(0x2d6764e48b62f11fa745090dbc582712f8a0a16ef81cc7da6fba8b1ec52d23a1), + y: uint256(0x0289e7980be1c71d3e91a117b1d062b27bf4d711e9ab3a8ee82a64eaf4c5ac45) }), - s3: Honk.G1Point({ - x: uint256(0x243daee8a40861aba1ef660929ee9e874e52cd8e8d75f8c0245852369a731491), - y: uint256(0x0a20f23c0697fb0698478f7a861dde5e18bf5aa34f4731178e74f7460df49a88) + s3: Honk.G1Point({ + x: uint256(0x16e299d4076387afc2add98ca386b3ff7ef29b7e87bb492a02e820b6404da3de), + y: uint256(0x2b11799049c80302774a11e05c57c8f614aecbc1c9a524e48328466195f35eaf) }), - s4: Honk.G1Point({ - x: uint256(0x18b8202abb615440b5544d88092245911d2b5ff3b5a4a80bb15dbabafdfb56a7), - y: uint256(0x096a6685f36b1ca09a62820ae3be7538128093440fa943ea7412617a6d927916) + s4: Honk.G1Point({ + x: uint256(0x27c8607e808c4a94be60e9fa6e4263ab2d4b41bd866add287affd942f5879b79), + y: uint256(0x25584de7b2b270f792e86e4ca403dc6fbf31f16b1da4d3f95ed9b8231e1a7e31) }), - t1: Honk.G1Point({ - x: uint256(0x004067623374b7c3965c7d8444b57ac2d81269c7eb3cb4f7b16568b2f8234c96), - y: uint256(0x0e605f3ad72203e21301ef1b5333cae1d8063220d1996854beb0c4fbc33bba9d) + t1: Honk.G1Point({ + x: uint256(0x1fb7c5d789d32e42a08e41296286139f603c7607ce186d0cce6e472dfe021473), + y: uint256(0x09d80a7c25410f51739aadc54ad122874e4551efc35bd23807ecf23a79ef418a) }), - t2: Honk.G1Point({ - x: uint256(0x17aafa80bf54a7e6cc66472f9ccd70efa5044207a95191716ba0195b5a432266), - y: uint256(0x233ecaca2ddbebb0484a44e6f55b8c8614c7b5e0ce31b51d59d6b21322a307a1) + t2: Honk.G1Point({ + x: uint256(0x108788a192d4d3c38e445629bb550acf212f9b2049b6fb1cc76900bd482fb5b0), + y: uint256(0x195266ac0788c227762333892ad282a4679450ae72e8e8b4a1ead0e63d4f4e04) }), - t3: Honk.G1Point({ - x: uint256(0x0f808f231e43f089639e05c235642b43ef91df7b6b2d51f3b34d17450bf4a536), - y: uint256(0x079b5c6882eb75200d55f88b75280a34c2ec6fe94d3660254afc72f390dc7567) + t3: Honk.G1Point({ + x: uint256(0x1eb529bdb867a986cca8b8c0119e679b5712f4503e5d00698de6b6ae49092404), + y: uint256(0x20886f9e098437ea65110f5591661e37ac720779a376a6155f132dcd6c301a52) }), - t4: Honk.G1Point({ - x: uint256(0x0765bf6645e4cf63f05d9b0efd06acebce309c685a3b05e613574ccd7316677c), - y: uint256(0x09770f145625290cdcb08bae4e6f0a26897b5988fbaf9529e0a3326bfdb537ae) + t4: Honk.G1Point({ + x: uint256(0x1a552bd8d3265d1f23e7ff166cf20fffa5c0688c867cfd3a2ea65452d8ad60a4), + y: uint256(0x1cb1414f7b9f8edb7c7a0d61f66e24e632a4050d9b3be0d6c35109aa99693039) }), - id1: Honk.G1Point({ - x: uint256(0x292298ecab24d2b6f6999cac29848def2665a62342170311f44c08708db0fe1f), - y: uint256(0x277022c35d3145de166b139aa94609551122915366ba42ff7c5157b748fb7f9d) + id1: Honk.G1Point({ + x: uint256(0x2e286f771211f7466ea24e64484140bd5bcdcc759e88c2f4b2cc2fda221fb9c9), + y: uint256(0x21b150b35832343dd3988a32e15c404915b0cebfb762e47ad0a7ce18004bac27) }), - id2: Honk.G1Point({ - x: uint256(0x2ddc6a05ccd584bdfc65d642b39a3be3075e7a370602112dbf9fc644789acace), - y: uint256(0x1a4167481d5f295af9921741bd0e32dda7a78cb391132b31ab4a77559c297c2e) + id2: Honk.G1Point({ + x: uint256(0x18eff4656b9f83aaf418fb251334d580bc6d247b19bb2438d4c4e71ffc3db1df), + y: uint256(0x1f859be892b830da65325a465f711a12a0b777997bbbfa5baebcb9f9a0eae3f1) }), - id3: Honk.G1Point({ - x: uint256(0x19629b85ab2acf9713223ff4f758882af6247963bbf2f6ec4f9cbcde13675b87), - y: uint256(0x165063fe922948bf1d065a882242724c1bde5fdfd93be29586b45e1ce2cc750c) + id3: Honk.G1Point({ + x: uint256(0x0a0ae72496a2b188d803fb33078c15cbd3d6874f3d1dd71eeb6ff7d8f4542ed5), + y: uint256(0x15314a39e87cc4d8274dc773f73f20ec712c0fc7216fc00b016fadca84dbf785) }), - id4: Honk.G1Point({ - x: uint256(0x2493c99a3d068b03f8f2b8d28b57cea3ee22dd60456277b86c32a18982dcb185), - y: uint256(0x1ded39c4c8366469843cd63f09ecacf6c3731486320082c20ec71bbdc92196c1) + id4: Honk.G1Point({ + x: uint256(0x2493c99a3d068b03f8f2b8d28b57cea3ee22dd60456277b86c32a18982dcb185), + y: uint256(0x1ded39c4c8366469843cd63f09ecacf6c3731486320082c20ec71bbdc92196c1) }), - lagrangeFirst: Honk.G1Point({ - x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001), - y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002) + lagrangeFirst: Honk.G1Point({ + x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001), + y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002) }), - lagrangeLast: Honk.G1Point({ - x: uint256(0x2d855b5b9eda31247e5c717ce51db5b7b0f74ed8027eddb28bb72f061415e49e), - y: uint256(0x1e857d997cc8bd0b6558b670690358ad63520266c81078227f33651c341b7704) + lagrangeLast: Honk.G1Point({ + x: uint256(0x2d855b5b9eda31247e5c717ce51db5b7b0f74ed8027eddb28bb72f061415e49e), + y: uint256(0x1e857d997cc8bd0b6558b670690358ad63520266c81078227f33651c341b7704) }) }); return vk; diff --git a/barretenberg/sol/src/honk/keys/BlakeHonkVerificationKey.sol b/barretenberg/sol/src/honk/keys/BlakeHonkVerificationKey.sol index e343d875afa..fe39ba37928 100644 --- a/barretenberg/sol/src/honk/keys/BlakeHonkVerificationKey.sol +++ b/barretenberg/sol/src/honk/keys/BlakeHonkVerificationKey.sol @@ -2,123 +2,125 @@ // Copyright 2022 Aztec pragma solidity >=0.8.21; -import { Honk } from "../HonkTypes.sol"; +import {Honk} from "../HonkTypes.sol"; + uint256 constant N = 32768; uint256 constant LOG_N = 15; uint256 constant NUMBER_OF_PUBLIC_INPUTS = 4; + library BlakeHonkVerificationKey { function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) { Honk.VerificationKey memory vk = Honk.VerificationKey({ circuitSize: uint256(32768), logCircuitSize: uint256(15), publicInputsSize: uint256(4), - ql: Honk.G1Point({ - x: uint256(0x2e5f133c25f7e05bd6660196c892121f7fa686cb9a8717a5deea6cd0881e618e), - y: uint256(0x1189bba9eeea96ba8935052434f4b0a60b0a481e3464dd81dfcd89e23def001b) + ql: Honk.G1Point({ + x: uint256(0x259ccc124bd4cf494d50c802a2df9671c3a500ccc3e83b72ead3806a7e740675), + y: uint256(0x0fa82481afabca16ee5f23d7ea094b00ebbc578a716fdaf782e05fd726faf007) }), - qr: Honk.G1Point({ - x: uint256(0x2a93ffb34002da94f5b156ba5a212ac3616c848bd9c44c9821bbdd64cfd848af), - y: uint256(0x015699dcc0b28766d45f5ddce8258393e84c40619d26034e76f778460a1e4d89) + qr: Honk.G1Point({ + x: uint256(0x14ff9e75f0777269c7e1788b0c22a4995ee7aa86b57f1df85daad5dc5394c64d), + y: uint256(0x2459bcedd7bd75b357c9e5feb11de3cd8da023ce6a386b2449cd5f93758a6a3b) }), - qo: Honk.G1Point({ - x: uint256(0x2057928e8c5eb539c32c3025007b7be1e1663c358f59540c6f949794c274f886), - y: uint256(0x12bf0b15c3aa92792330f58b04512714c4a902e537fe87cc438293e1805eaabf) + qo: Honk.G1Point({ + x: uint256(0x2d45d3ef650bc8242021c0b5c7c458abbe387b5697fd64f82c07527f7d1de8c6), + y: uint256(0x0267edd43123342fda564babb7c89110ba206a7b36500e88bb7c485448e97913) }), - q4: Honk.G1Point({ - x: uint256(0x304f47a08d4687afa0e2502a9782c32c458bf873ef50c169b732a367e567aaf3), - y: uint256(0x0bb37044594e7de200408a4db6bc46adf7790b06f17dce6f38b7deed480aa9f0) + q4: Honk.G1Point({ + x: uint256(0x1ce127e531187e01b1ce284179977224b8f76fb470da6c61bf1791509a40d8b8), + y: uint256(0x22bdfdaabf4d8863c4a989a3345c7c9519af302fa6a1f67e4810d6589c2b5d6d) }), - qm: Honk.G1Point({ - x: uint256(0x0aea5b04332ad8781411f7edde21266857ffe11e93af334b14a2b948429afaa4), - y: uint256(0x2bd2e3884d486b387122effa12e8698daef82e9b99d7d25b7d5df91a9d738495) + qm: Honk.G1Point({ + x: uint256(0x0951790dc5ec21ff7bd1054fbc6c3024120f848605d10edcabbd81924ef14404), + y: uint256(0x0715c7ce615280c7629a43891bf15a2194bd659483b15333d6bc66697c59e39e) }), - qc: Honk.G1Point({ - x: uint256(0x0e3b418ea1924b4514d5009cd983b5a8074fa95cd1fb200f019fdebe944e4225), - y: uint256(0x1e6ef5bde7a9727f1c1d07c91461ae1b40524650b35fdd92ac7a129f263b1beb) + qc: Honk.G1Point({ + x: uint256(0x021f1c4697f49682d5b22a39cab4b196a822c7279551d3c86de39eecef6ee491), + y: uint256(0x170cf597b1d291c41d59d76f852fba1a7def57d9d031daf7bb0061b6b45be5b6) }), - qArith: Honk.G1Point({ - x: uint256(0x096841bfa8ec2295a5af5bf69ec539c31a05b221c84ed1d24c702e31ce1cbc95), - y: uint256(0x10b14cca7e9ff05fcf1e3084f4fc9ab098cf379864b2e2e2e0d33fc5df9d9a50) + qArith: Honk.G1Point({ + x: uint256(0x2ec15ed0cae4827b6c15a424b3409faea5a3b1488234f9970c12fe64dcd09915), + y: uint256(0x2f78d2844b0fff0faafdd1cd110d85ac77b2f7266dcbadc0e8bc6505f4248292) }), - qDeltaRange: Honk.G1Point({ - x: uint256(0x2d27fd1a30a0ab04a05144c27ac41187d5cf89a6022e47b263d1ccb93b3cbea5), - y: uint256(0x238eb233e9aebc81285a2647f2598bab00a4367da47b12c2b0476afc2d94ab1d) + qDeltaRange: Honk.G1Point({ + x: uint256(0x257905e6e6a095881dbf7de8c3a7dcff8742f161bc6ca50871aba6543e480cb8), + y: uint256(0x0cac0d52c83175f49f71af8e8bd9d6f943cd3b451b6a6683df582a0e46db170c) }), - qElliptic: Honk.G1Point({ - x: uint256(0x1c6fc8e14453adf64e6d9643ef9f1fb55e3a307ac1ec84f86cd736fc866e05ab), - y: uint256(0x1bf8619b1704b99ab8820ed94dd760da2945e8e1c771c0bdeadbe40aa5700cdd) + qElliptic: Honk.G1Point({ + x: uint256(0x08e2c3e7dcc34da5d0170141b5ed9144c9d7de8976e0e2c81ad74e3b9451f76e), + y: uint256(0x223e14628c0bb1ecd61b88d322fff7c2c2a572c3b3e16fca14fed906a65482cd) }), - qAux: Honk.G1Point({ - x: uint256(0x023fe0703623b99c93358348d76eb620f26ceafa58df018e3a8f1d599a61e76f), - y: uint256(0x2ceb9c4c4ca12ea769157ef10cde9644f9f0549805e48d5fd5d73a634d2cdcb5) + qAux: Honk.G1Point({ + x: uint256(0x1a3a5eb5a02862dc132e23eac87a937d4f9b4d3736b3d1ce2bf2aec5b8761283), + y: uint256(0x0e608d3de6c0adf6dfba886c110a388fc2059abe6f660caf3f901bd3dbe4d97d) }), - qLookup: Honk.G1Point({ - x: uint256(0x1375bbfbf5ed31b38460f46a43ac14e2cda93a3bc5cfd6e8a93cca356694a346), - y: uint256(0x204c5173892c19a97a04b5f8419898063df5136489809ddb9f7eabb58d6858ab) + qLookup: Honk.G1Point({ + x: uint256(0x22ef6b48ceec28053e1ec5bc4f0a91ae22d287d86044f15672c167ec1af91d8b), + y: uint256(0x11b828a2435dfaaa173ec009381bcd95b76c41adee995ac0c716b82879cab160) }), - qPoseidon2External: Honk.G1Point({ - x: uint256(0x1fa8529236d7eacdab8dcd8169af30d334be103357577353e9ef08dfda841785), - y: uint256(0x055251b013746385e921b4620e55ef4f08b4d8afc4dbca7e6c3ca0f1b52c5a2b) + qPoseidon2External: Honk.G1Point({ + x: uint256(0x1fa8529236d7eacdab8dcd8169af30d334be103357577353e9ef08dfda841785), + y: uint256(0x055251b013746385e921b4620e55ef4f08b4d8afc4dbca7e6c3ca0f1b52c5a2b) }), - qPoseidon2Internal: Honk.G1Point({ - x: uint256(0x1515283648ab8622ac6447f1fcf201a598d8df325279bfac9a6564924df97ee5), - y: uint256(0x0335bb595984ad38686009bca08f5f420e3b4cf888fad5af4a99eca08190a315) + qPoseidon2Internal: Honk.G1Point({ + x: uint256(0x1515283648ab8622ac6447f1fcf201a598d8df325279bfac9a6564924df97ee5), + y: uint256(0x0335bb595984ad38686009bca08f5f420e3b4cf888fad5af4a99eca08190a315) }), - s1: Honk.G1Point({ - x: uint256(0x26cec5ff3eb1b803c52fa1fefaac7a2be5cd13c1a1cc20bb9f22049c7f8597d2), - y: uint256(0x07e80e74eb0e06d7c0c9a3fbbdea4e86e5934faa8142625f175320778bcba65f) + s1: Honk.G1Point({ + x: uint256(0x259bede7c068653c0e2a16bd986e1ca97757315d3b973a494c6ca022cea60447), + y: uint256(0x2a93cb60e983030c470c044e1f156a25fe5e1941d38f4d8c91594e0eaa8858ae) }), - s2: Honk.G1Point({ - x: uint256(0x140b2faaf30cb5fc528621f4a395943e7fab8198dc734ac13253dd249682dd2a), - y: uint256(0x12709c4a13428f4704d284c90a81cc83280680185ae6298187e86debcd3e00f7) + s2: Honk.G1Point({ + x: uint256(0x11df397e5ad916749343c5be9797f2b6e3c0450714a1d5fa8a3f55ef32586940), + y: uint256(0x046a6da96359bd452f9f3c3ccc15b9f59c26bab349a02faa1f1d34517282ef6c) }), - s3: Honk.G1Point({ - x: uint256(0x0aca5621e9f49279969497b3da0eb8a74c68c3513f4cf98e8b1d6f88567557a8), - y: uint256(0x2664811311f75057a16267bc0479eaeea2424156417cc4d3f8bd286fac9aa5d2) + s3: Honk.G1Point({ + x: uint256(0x1ed35d2fd753212e17554522ac3d692ae25cb581f54adf02f99a5d6f71969d5d), + y: uint256(0x08352d3f6a0fb619cfd1a960514fe3394d9018f0388f631df9f5af9fcfd0efbe) }), - s4: Honk.G1Point({ - x: uint256(0x04417c606a41393e73113ec3f834883dbeb302889199b888c0f5ea58a008ff98), - y: uint256(0x0865670de7962d29b6a9012f28ea52113c4e2b55d7de44e829edec87dba1d5c2) + s4: Honk.G1Point({ + x: uint256(0x15365aa0c1d6bce15408f45f0251c9472f78297ec2cc5ab508f5c568980a893d), + y: uint256(0x2385c2920ad544f0be29c68152bc7ae98031aee831ddad561a45a95b31ae6ef5) }), - t1: Honk.G1Point({ - x: uint256(0x1d4e30cc33125c72bc1a31ebff8c7ba5c5b34c2d3db26658f8f7a4c1a8917596), - y: uint256(0x24b630ad1c505f3a97aa5461310b4a291aa7fa696c1040ecbc0f1d0cab88b1c5) + t1: Honk.G1Point({ + x: uint256(0x25bdb78d4e315a031ab7b6cb0dfdee32d86f4845ef1f837cdafa6c45f9ccae56), + y: uint256(0x0e68860fb89d3a366d4b7244a172f5a7e79147d8f09d3249b1555df77ef64ac9) }), - t2: Honk.G1Point({ - x: uint256(0x14d7f3319ed85d18dcac134fbc88f55a46cef0e5e7a6d02feb1cbff52cfa6e9d), - y: uint256(0x2a8f8123f428e35766ee7e966f24ec27a2633400ede745386475dd10c4c17d2a) + t2: Honk.G1Point({ + x: uint256(0x0c0b5c83cfca189b7560979cbb59e4450d970a226e703fa090fc0fba87094c82), + y: uint256(0x290a615d73d77f18f3a7483bd4f7d9ba22ad1c1e28980012e5bb3c9660b96086) }), - t3: Honk.G1Point({ - x: uint256(0x11061c55e2e00e034fc719cc1c4caa69e1f30657a6bb0967911e2a760efa4a77), - y: uint256(0x10be7ab8fa1f76943b2cc162dd50e4acd000d9b1ab2a0020abd1267b4b9be410) + t3: Honk.G1Point({ + x: uint256(0x09d24c7501264da486f4ddbe6fee4a104edbfbcc8b3b7ea185db69c5e1a6c38b), + y: uint256(0x132e749bb80fdc19494cec612ce529b810d672d471253ffb5ab0ada355163fd3) }), - t4: Honk.G1Point({ - x: uint256(0x1154b181349afd6acd7366b4640b40e08dcbebc684265d5308253042542ee558), - y: uint256(0x08bc724f607bcf3fe89b6ae24fb50290667cb2e8f5c12fb905fc86fbec0e0c18) + t4: Honk.G1Point({ + x: uint256(0x044ff357ea1fbf33738fc570145106a3f6acc496c748b0b58f4615e1b0626e10), + y: uint256(0x2816e550d752b97bd0a5c2ed5369a652088981b3e92e3d6238b0c63b203aa3f4) }), - id1: Honk.G1Point({ - x: uint256(0x01c082a85908fea4c69c4e51436fba7d965e1d88e485da16e35d8f4e8af3b8bd), - y: uint256(0x11b0ada021468b059aa6c27f4d4950ef65b98d4d8808ae21718bd8b90f9bb365) + id1: Honk.G1Point({ + x: uint256(0x2a2b95a34bb20d564d0b1ba33afdfe5ad95a8128ddfd8faec40b7bc2faf642e2), + y: uint256(0x1355384c7b2deba5fb394e25d297d5f37ccfaacfacd57aac61259bc1e87ea6ed) }), - id2: Honk.G1Point({ - x: uint256(0x0b8667619755bd09c7970defeae2c920df2b17b41608303ae1d7393615dd04e4), - y: uint256(0x1c5419cd435c5516ac566a9d1dfecdb4e10190c63f2dbd8a1932785caf022e2c) + id2: Honk.G1Point({ + x: uint256(0x279ce3dbe9564e5fd66014fbedb03f538e23b5effe8bf1c3ca394eba651d25fc), + y: uint256(0x0d130ad41878eba2d8da55ed688de58a3b8edf7b237e4ead56deebd56d11344c) }), - id3: Honk.G1Point({ - x: uint256(0x110aee72793c4b4ede92c1375f058b4170fcf01bf18f8f1ee934f7ae0fa26da5), - y: uint256(0x15c4f6a01ff04ef6b5225c896dfb7060a7a2c320395bda410e756d6b507b7eb8) + id3: Honk.G1Point({ + x: uint256(0x1f3ca856540e150992ef85a64d5bb2ddc643a53f15dad567e08fc5a61307a2c3), + y: uint256(0x0f44b87f30b55235f069ad5d06f23915c19bf6194c0e6f54e2a4b41ef357e214) }), - id4: Honk.G1Point({ - x: uint256(0x2472aba130e7ed2aefad128109415ec2bdeb56e81e3cbeacc93e00c95f203579), - y: uint256(0x0c867d0f8e2f9c861574383b89020980358d898497f80c198a6c17c2f4daf9a4) + id4: Honk.G1Point({ + x: uint256(0x2b85159a22ab90cb83642950f0240a403dac1dc50a970d1113be0cf8a8b5d63d), + y: uint256(0x1287b2e8e4ee3f0a9afbf798230ea32388a6e90924f13d7c78d5aed275095c79) }), - lagrangeFirst: Honk.G1Point({ - x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001), - y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002) + lagrangeFirst: Honk.G1Point({ + x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001), + y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002) }), - lagrangeLast: Honk.G1Point({ - x: uint256(0x2c3e8add0e69c3bb940ffe92b6d3bdbbe0c8ac0c95866da586d857c73a0556ba), - y: uint256(0x22ed2a9c8e4ee1ecde6e7285f21cb4fe0a23131c9ee50f22e367f7c8cc2ac84a) + lagrangeLast: Honk.G1Point({ + x: uint256(0x2c3e8add0e69c3bb940ffe92b6d3bdbbe0c8ac0c95866da586d857c73a0556ba), + y: uint256(0x22ed2a9c8e4ee1ecde6e7285f21cb4fe0a23131c9ee50f22e367f7c8cc2ac84a) }) }); return vk; diff --git a/barretenberg/sol/src/honk/keys/EcdsaHonkVerificationKey.sol b/barretenberg/sol/src/honk/keys/EcdsaHonkVerificationKey.sol index c415f2f717c..bd19e368249 100644 --- a/barretenberg/sol/src/honk/keys/EcdsaHonkVerificationKey.sol +++ b/barretenberg/sol/src/honk/keys/EcdsaHonkVerificationKey.sol @@ -2,123 +2,125 @@ // Copyright 2022 Aztec pragma solidity >=0.8.21; -import { Honk } from "../HonkTypes.sol"; +import {Honk} from "../HonkTypes.sol"; + uint256 constant N = 65536; uint256 constant LOG_N = 16; uint256 constant NUMBER_OF_PUBLIC_INPUTS = 6; + library EcdsaHonkVerificationKey { function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) { Honk.VerificationKey memory vk = Honk.VerificationKey({ circuitSize: uint256(65536), logCircuitSize: uint256(16), publicInputsSize: uint256(6), - ql: Honk.G1Point({ - x: uint256(0x0d26081764ddeabfed843e3c5557f131e164ef80202b29336be0ee6cd7b8bb09), - y: uint256(0x1f119104ae836c47196ac80dd48d743fe8dbc00b90a732e8850cf39ebc057fd6) + ql: Honk.G1Point({ + x: uint256(0x092e1a5431e67f41abd28c9b103ef1fb90a93ff2474f2f5bd2550387fac4b6d6), + y: uint256(0x272df56e1a1740f88fe789b1e63112068687fdc95ef7612024d550202bcbe41f) }), - qr: Honk.G1Point({ - x: uint256(0x0a5832561bc20ca6c3bd6a45383192ceea476369cf1409dcc923ad0db043bd1f), - y: uint256(0x191a108202c6f5d4d6b6fae14259b7849ee8e0a483d3aeada8f12c19e6977d30) + qr: Honk.G1Point({ + x: uint256(0x1d22d883b1f1bb07cbc1339682a92e3d96cf09e1c53a881fa283045587ce00fe), + y: uint256(0x12fdb565b8d174d018dede5197be30c94835fa581ed969f40433f65a84222a4a) }), - qo: Honk.G1Point({ - x: uint256(0x0e8a61ac645f4b74493df26d9e888fcefc3649cc1f6d925a48091faeca3f9cbd), - y: uint256(0x09a0a2a584c84de3e86235217b3a31e40d871a815232c1cfd02343fa03c83e84) + qo: Honk.G1Point({ + x: uint256(0x2d928f55abc1f8f5f9e29011fa8c802eb5a94989042b3d5560f013a779e5d193), + y: uint256(0x1086b7bcf22b95fc94f063af74498dd4bac214e0459d68379a1008261358ddd7) }), - q4: Honk.G1Point({ - x: uint256(0x1dbccae2d56db0ee959d57572c7da6dea1853fbae2bc8fa8c862eb163dae0bb2), - y: uint256(0x2f1f1c14f8a981a256c96e72e8d18393bb11da62223f18cf72fe5639ce9704a4) + q4: Honk.G1Point({ + x: uint256(0x0a4e034f2d3b73ae4eb6ff0db3fe8e7b0357e6dd375a3107d1e4d9eb5ceb1e5b), + y: uint256(0x1266512c0da5b14ede1f1d5b80ad9dfa43b3c71b2c0bb11c9c123c70eabc62ad) }), - qm: Honk.G1Point({ - x: uint256(0x1da7f877a5a897c91204a2c894f8d121c6a054318427025f87556aeba16fff02), - y: uint256(0x0438f74fa9432220b697edfc8be7efd8d9773d6c6208c908db13c41095de5f37) + qm: Honk.G1Point({ + x: uint256(0x1279a8faed8a7d782856985a20218fbcd73a8e8fb2574622210169b3b4eec159), + y: uint256(0x063271b597aa97880532cff9e2ccea5a6bf13d947f4c310c39be452010d59cb9) }), - qc: Honk.G1Point({ - x: uint256(0x028fab352dd75db278f199638256453cacbf277e1bdf2e82115e09718a2b26da), - y: uint256(0x2c537e1ee36b91fbd25a6250a37332a93d6bda95890df6d9501d4bea885796b7) + qc: Honk.G1Point({ + x: uint256(0x1892791334caee5906d99a8c6dc6dc8636e0c667893b8cdd8067ee565028e396), + y: uint256(0x2f86193c2778a4c33d144fbf2803260b1df44d4ad82390dea131bc2b11ad1855) }), - qArith: Honk.G1Point({ - x: uint256(0x035c79ae9870ae41757c5e34b582b1c56ede35aaae59ca00404d721d88207e7c), - y: uint256(0x2d4d7bdef0e2cbbc267bb99b645d1626bdf8f42adb4503798a34cae5c09e9f8c) + qArith: Honk.G1Point({ + x: uint256(0x11ff48b12a216298b2f8efe8dc2f269c1e9f62917ae7ac83c92ff6aea3a2d2fc), + y: uint256(0x2df51751329a326d1374b05e3326d25e145fb20804d78127bf42146799959cd5) }), - qDeltaRange: Honk.G1Point({ - x: uint256(0x07de3043acee4e9209cdbc0e4a8b6f6a535b1937f721d39d530e0ce232fa8287), - y: uint256(0x274ff9766cb2ebb15e8971dd046080d167743a825438eb577c1ac5a3cc9c54d6) + qDeltaRange: Honk.G1Point({ + x: uint256(0x2c9fffb3a9f0da1f3f8f732cb0873b437cc1dc97a5d9730d19c31df4a1c1f540), + y: uint256(0x1118a1349f966cd8bb7b9557c059c3b936a5b189e8d56f75fffc6511adac2a09) }), - qElliptic: Honk.G1Point({ - x: uint256(0x1534a28b15c98473424fe8f04b314269e2ceb84b2ba03d9233e5621e392ec778), - y: uint256(0x21383bb1156fec27094fbe8b470bb9bd38f09050b54000b9e8210d495c303c50) + qElliptic: Honk.G1Point({ + x: uint256(0x2d05352c103814f8855acfda27603975ae3dcdb9b08592d4c999769d84047e0c), + y: uint256(0x15c7b3939f3108548006275aa6c62b4cc3095add5e1e463f2a3ab57eff4b9b3c) }), - qAux: Honk.G1Point({ - x: uint256(0x12d0e6d9b6385ab7ecd2dca74f9bb94f6242c9182d64ec7b243c364e3ab623b2), - y: uint256(0x1c2ccee3dfb933fd21007ac4fb913c021d4f606373c172cb7f65e7b65c8a19a9) + qAux: Honk.G1Point({ + x: uint256(0x1055198df3ec55ad61ff8c8f824bfc3cf74e459f46dd1c1d2ace45890e9b80fb), + y: uint256(0x07725ad2b53ee322b94db4b28baefdbd7239bf4d9c2e9e0d9565bfda8954a380) }), - qLookup: Honk.G1Point({ - x: uint256(0x0c1d4485ea10a2e7ac60989c6b89adb46cfe368c3aea2e98dd23dda8c0177eeb), - y: uint256(0x2ec88245a56ced2a57fd11e8a75055c828da386b922da330779817f4c389a7ea) + qLookup: Honk.G1Point({ + x: uint256(0x0a15b7287881191263af5654587121b7c5db6c7fe8d390ab0454d0996a0b184b), + y: uint256(0x2b5b0486da55ab0a673f7ca8d0fb5400a5462bef7a98730f34fe266bcf8b63ae) }), - qPoseidon2External: Honk.G1Point({ - x: uint256(0x2c1c2ccda8b91666f7bd30eb4a992c3e4c729adcf73e008348e8c97083d56242), - y: uint256(0x2b418829be00d02f2e01a1fbf110420b328a44416e889990f1e81b735023ff1d) + qPoseidon2External: Honk.G1Point({ + x: uint256(0x2c1c2ccda8b91666f7bd30eb4a992c3e4c729adcf73e008348e8c97083d56242), + y: uint256(0x2b418829be00d02f2e01a1fbf110420b328a44416e889990f1e81b735023ff1d) }), - qPoseidon2Internal: Honk.G1Point({ - x: uint256(0x1f60a709d42d5e2c7b406365072a764300c610a5a8d2be21f9a0242dde7bd485), - y: uint256(0x2c5af44525879b9580e7687e6a93dd55fd6aa9251d90a5c2c4fc0ea971e1448b) + qPoseidon2Internal: Honk.G1Point({ + x: uint256(0x1f60a709d42d5e2c7b406365072a764300c610a5a8d2be21f9a0242dde7bd485), + y: uint256(0x2c5af44525879b9580e7687e6a93dd55fd6aa9251d90a5c2c4fc0ea971e1448b) }), - s1: Honk.G1Point({ - x: uint256(0x282bd3a32dfbf5fcb1123602ee8bb334fcae9fe4d32fcffe565701fea25c84da), - y: uint256(0x26d6de44e383b5cfcb046b54d5b88b4c840f85bf6b355de813cfc82946b01696) + s1: Honk.G1Point({ + x: uint256(0x1d9253a09df46bec5da04d4ef7839fd41bd2e97ae43ccfa143dc0d657fa85553), + y: uint256(0x12eba500137049f38ecfef8f8a8f061abfedbf4f832169375aafd290b8920667) }), - s2: Honk.G1Point({ - x: uint256(0x00def638e4fdad7089dd2cc99e003e101ff5ed89c0f4d3842821a6636abeac0f), - y: uint256(0x216b4b4bdcef902c4aa149e4c5e5ef69b4b2fa7909b03e6c527befddf9aea208) + s2: Honk.G1Point({ + x: uint256(0x108fa66ffac071a9a79c3798a54074139931be05a5b8c88596e354ff0c7977b9), + y: uint256(0x2ee653942fe48118b22616ff96b698dc5232a49ae5aaf33196af01d8cd783895) }), - s3: Honk.G1Point({ - x: uint256(0x0e5217dc5c6f84fcae20d18267fe3aa126f1c78bdc848d5d155e965ee46d57ab), - y: uint256(0x1c9d0fd84b8792f7fc102309d8298d734793efe6f917d6983495f8a327a4d836) + s3: Honk.G1Point({ + x: uint256(0x0e5e0e66b8d82ab97c3a4101da87d1457dfe38d8d781cd54d6a51fc4ed80fb5f), + y: uint256(0x1247d037ee1a73c1772120a83c697906102abd709365442c3057ad2f640e015f) }), - s4: Honk.G1Point({ - x: uint256(0x2aa0999747c3673174ec7eb488e5e18dc9c0cc066677941ba659f8ff8b381db1), - y: uint256(0x29abc69897e1af84be5d94015bd6fd94c6612cb259c7c9f2e2c72f76c900c5bd) + s4: Honk.G1Point({ + x: uint256(0x1cf115e956940f5beeb730452473c79f981e974cc1fd2dd4811f4de693860f24), + y: uint256(0x1a64f5ff7c28626ff23e5ae82e45f30158fc7dfd23487ad97ea9bb8b5b66e18d) }), - t1: Honk.G1Point({ - x: uint256(0x1ca80e2d80c4058457bf2ddce67adec85e9d147eea6b130f11d37d3b80f977a6), - y: uint256(0x2812e987a2950af642c89d778f1d8f0bc5b24e1f30dd454b883d4bb2696fada8) + t1: Honk.G1Point({ + x: uint256(0x2467210c5e67f86104a38488eff67d1252b8dc1de9c1f589ff66bfd5a4de1ed6), + y: uint256(0x2126dbe4e3ee0d2240507870a9d85f0d90490efd7c69070f65a31dbff731889f) }), - t2: Honk.G1Point({ - x: uint256(0x0e3ff1d0e58dbe4c2ad55e0b4ac9d28a78a504e26ed2d1468432d01f52f35003), - y: uint256(0x03d5da7641a7698a0e7c920f0ab4ca4760ee05fdfaa8ea5b2a6fa0c1f7d15a0a) + t2: Honk.G1Point({ + x: uint256(0x0c6e576e4ea74b4a4b2c70c36633e7c2d25222fa692417d283831aa00a578825), + y: uint256(0x061c370923246a520c238c6cc2442ce9c0790350438fc20d0371682e92fda4e7) }), - t3: Honk.G1Point({ - x: uint256(0x14a9f5aba97157d82f64938a827361a91cc94b66f88a9c0ca65be9b56e3f9821), - y: uint256(0x1a6dbba0f10b19e540a198c66e04a35ee95ae33ee43b01852d294f06a4a08d4f) + t3: Honk.G1Point({ + x: uint256(0x10e110ee17259e7746e26e882567409aad3fda44ea148dc6195eadfb80dc3884), + y: uint256(0x23ac2d72dddf2f686d55cacac3d5503003d8a19acaab8d6cf00e3850600bf729) }), - t4: Honk.G1Point({ - x: uint256(0x0934b14b98eab15c73b9ecc3453229fd602408a75d6b8b59242fa0eeeb3a4230), - y: uint256(0x1c7079581fa387fd07d23e144ba9161cb2428e1ed84d1b61547a3688baad41ae) + t4: Honk.G1Point({ + x: uint256(0x299f1dfcb8b0b56691dd560e5ee9f73c4d07fac967de3ecbbd0769128209cb9f), + y: uint256(0x01598d24dc1b7a351ac26c8ca4d1d7539ef9b9252f7e664648f36adc1deed9ca) }), - id1: Honk.G1Point({ - x: uint256(0x17fcf5224da2d584726a7b80972a622c6b982121c33a71fd400da52c8df37924), - y: uint256(0x114b4bce95cd9f2aa6f7c8653e855406c1da5e44a3ef692c4435d888a315f359) + id1: Honk.G1Point({ + x: uint256(0x1a0412e7de1e53ce0c0ccefc666cac1ae83945594a7aaf807e964415a11f00db), + y: uint256(0x2526a8a84a5f7d557379a155d0a8d9dade32a096cd81914029722c685fe420a9) }), - id2: Honk.G1Point({ - x: uint256(0x2fef8b3fd63b5ca8faf76f47f6c73652a47df0b42cdea3abdc06c59aec2f3b21), - y: uint256(0x01b2c58279557c3b4b1019d7700f9c1a69f255df49ca874728d18a6843eb581f) + id2: Honk.G1Point({ + x: uint256(0x2158c8dcf92c304cd203397b9868e636c7bde65e68883364c458f067acb8c2b4), + y: uint256(0x08ba19108eabee284eccb6e86b4a8837fb36841af7da73e7979eea7d4f2dbe0b) }), - id3: Honk.G1Point({ - x: uint256(0x0713316ad4da65b28be231d997fc27558c9663cba7aeaa24dd2a94e5cfecb88b), - y: uint256(0x2ab0460a36b81cf33745d9ac0cc66f46c22a2c0f22b97e78de63b0f94d746453) + id3: Honk.G1Point({ + x: uint256(0x211a0d1167642ab55fa62b879782796fb8cd2809c658b45f62d528b5d5b34311), + y: uint256(0x05dab9a3e4d2f01fb9d44a9aefd0fc4565111bb73d25417bc00e0f7969b5e9a0) }), - id4: Honk.G1Point({ - x: uint256(0x00022bd8bd7328e7449214b7ada33e0991108ad45b30afaef78f30bea2091f38), - y: uint256(0x18a83d47716f4f134e9d29db7acc812e89cb7578a36e05b5043bb21ccc93f81d) + id4: Honk.G1Point({ + x: uint256(0x0a53a26d1390a734dd02a7b004ef88102974600e3baa15ec2e461c79ff9b8ca2), + y: uint256(0x21c24911108ee0462b6033b27d7a6acf2c85cf766eaada84575d92e98c103446) }), - lagrangeFirst: Honk.G1Point({ - x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001), - y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002) + lagrangeFirst: Honk.G1Point({ + x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001), + y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002) }), - lagrangeLast: Honk.G1Point({ - x: uint256(0x27949ee1c2c701a8ee2e8c253ae9e3a429f03da04547f6e17fd7d0d27ae07689), - y: uint256(0x08e6579e77d56473d9b459c4265b407d29913310d4f155fd19348efe52bdd1d2) + lagrangeLast: Honk.G1Point({ + x: uint256(0x27949ee1c2c701a8ee2e8c253ae9e3a429f03da04547f6e17fd7d0d27ae07689), + y: uint256(0x08e6579e77d56473d9b459c4265b407d29913310d4f155fd19348efe52bdd1d2) }) }); return vk; From b13bc93ae3e2d71259adc1a23c8cea462084ec08 Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Wed, 18 Dec 2024 13:42:02 +0200 Subject: [PATCH 17/34] fix: bump devbox image version (#10836) Bump image used by dev container --- .devcontainer/dev/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/dev/devcontainer.json b/.devcontainer/dev/devcontainer.json index e5fb68ec02e..12a7c197f6e 100644 --- a/.devcontainer/dev/devcontainer.json +++ b/.devcontainer/dev/devcontainer.json @@ -1,6 +1,6 @@ { "name": "Development", - "image": "aztecprotocol/devbox:1.0", + "image": "aztecprotocol/devbox:1.1", "features": { // Use custom fork with noble added to list of supported distros. "./docker-in-docker": {} From 970ad77966a17fd5c8071a7c3c3a405f83630c5d Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 18 Dec 2024 09:11:04 -0300 Subject: [PATCH 18/34] fix: toBlock argument in L1 getLogs is inclusive (#10828) As @alexghr identified, we got a spurious reorg on a node in the exp1 network. This was caused by the node getting a current `l1BlockNumber=245`, but then fetching an L2 block mined at 246. This caused the `canPrune` check to fail: ``` const canPrune = localPendingBlockNumber > provenBlockNumber && (await this.rollup.read.canPruneAtTime([time], { blockNumber: currentL1BlockNumber })); ``` The `canPruneAtTime` was evaluated at L1 block number 245, and it correctly returned true, since there had been a reorg shortly before (at 240), and no new L2 block had been mined so the rollup hadn't reset its state by then. However, the `localPendingBlockNumber` was incorrectly increased due to the block mined at 246, which caused the archiver to incorrectly reorg it. This PR fixes the L1 event queries so the `toBlock` is inclusive. A quick test with cast shows that this is the case: ``` $ cast logs -r https://mainnet.infura.io/v3/$INFURA_API_KEY --from-block 0x146eade --to-block 0x146eadf --address 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 --json | jq .[].blockNumber | uniq "0x146eade" "0x146eadf" ``` And just for good measure, we also filter the logs returned by the block range searched. --- .../archiver/src/archiver/data_retrieval.ts | 34 +++++++++++-------- yarn-project/cli/src/cmds/l1/prover_stats.ts | 2 +- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/yarn-project/archiver/src/archiver/data_retrieval.ts b/yarn-project/archiver/src/archiver/data_retrieval.ts index e1f8022bfa5..1b6d2bf02a0 100644 --- a/yarn-project/archiver/src/archiver/data_retrieval.ts +++ b/yarn-project/archiver/src/archiver/data_retrieval.ts @@ -44,13 +44,15 @@ export async function retrieveBlocksFromRollup( if (searchStartBlock > searchEndBlock) { break; } - const l2BlockProposedLogs = await rollup.getEvents.L2BlockProposed( - {}, - { - fromBlock: searchStartBlock, - toBlock: searchEndBlock + 1n, - }, - ); + const l2BlockProposedLogs = ( + await rollup.getEvents.L2BlockProposed( + {}, + { + fromBlock: searchStartBlock, + toBlock: searchEndBlock, + }, + ) + ).filter(log => log.blockNumber! >= searchStartBlock && log.blockNumber! <= searchEndBlock); if (l2BlockProposedLogs.length === 0) { break; @@ -218,13 +220,15 @@ export async function retrieveL1ToL2Messages( break; } - const messageSentLogs = await inbox.getEvents.MessageSent( - {}, - { - fromBlock: searchStartBlock, - toBlock: searchEndBlock + 1n, - }, - ); + const messageSentLogs = ( + await inbox.getEvents.MessageSent( + {}, + { + fromBlock: searchStartBlock, + toBlock: searchEndBlock, + }, + ) + ).filter(log => log.blockNumber! >= searchStartBlock && log.blockNumber! <= searchEndBlock); if (messageSentLogs.length === 0) { break; @@ -251,7 +255,7 @@ export async function retrieveL2ProofVerifiedEvents( const logs = await publicClient.getLogs({ address: rollupAddress.toString(), fromBlock: searchStartBlock, - toBlock: searchEndBlock ? searchEndBlock + 1n : undefined, + toBlock: searchEndBlock ? searchEndBlock : undefined, strict: true, event: getAbiItem({ abi: RollupAbi, name: 'L2ProofVerified' }), }); diff --git a/yarn-project/cli/src/cmds/l1/prover_stats.ts b/yarn-project/cli/src/cmds/l1/prover_stats.ts index 424b37b50bb..f30a3be2710 100644 --- a/yarn-project/cli/src/cmds/l1/prover_stats.ts +++ b/yarn-project/cli/src/cmds/l1/prover_stats.ts @@ -181,7 +181,7 @@ async function getL2BlockEvents( name: 'L2BlockProposed', }), fromBlock: blockNum, - toBlock: end + 1n, // the toBlock argument in getLogs is exclusive + toBlock: end, }); events.push(...newEvents); From 96887b60c3a6a1aaf4fa5b7623e664917e7a68bc Mon Sep 17 00:00:00 2001 From: Ilyas Ridhuan Date: Wed, 18 Dec 2024 12:11:26 +0000 Subject: [PATCH 19/34] fix: small fixes to avm witgen (#10749) - Add tree snapshots to nested call contexts - Handle DA limits properly in witgen - Respect staticcall in tree operations --- .../src/barretenberg/vm/avm/trace/errors.hpp | 1 + .../vm/avm/trace/gadgets/merkle_tree.cpp | 4 ++ .../vm/avm/trace/gadgets/merkle_tree.hpp | 8 +++ .../src/barretenberg/vm/avm/trace/trace.cpp | 61 ++++++++++++++----- .../src/barretenberg/vm/avm/trace/trace.hpp | 5 ++ 5 files changed, 65 insertions(+), 14 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/errors.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/errors.hpp index d1d4550edfa..081ee2fbc5e 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/errors.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/errors.hpp @@ -21,6 +21,7 @@ enum class AvmError : uint32_t { DUPLICATE_NULLIFIER, SIDE_EFFECT_LIMIT_REACHED, OUT_OF_GAS, + STATIC_CALL_ALTERATION }; } // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/merkle_tree.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/merkle_tree.cpp index f3332c79a69..366d403e54e 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/merkle_tree.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/merkle_tree.cpp @@ -146,6 +146,8 @@ FF AvmMerkleTreeTraceBuilder::perform_storage_write([[maybe_unused]] uint32_t cl // Update the low leaf tree_snapshots.public_data_tree.root = unconstrained_update_leaf_index(low_preimage_hash, static_cast(low_index), low_path); + // Update the set of writes to unique slots + public_data_unique_writes.insert(slot); return tree_snapshots.public_data_tree.root; } // Check the low leaf conditions (i.e. the slot is sandwiched by the low nullifier, or the new slot is a max @@ -172,6 +174,8 @@ FF AvmMerkleTreeTraceBuilder::perform_storage_write([[maybe_unused]] uint32_t cl // Insert the new leaf into the tree tree_snapshots.public_data_tree.root = unconstrained_update_leaf_index(leaf_preimage_hash, index, insertion_path); tree_snapshots.public_data_tree.size++; + // Update the set of writes to unique slots + public_data_unique_writes.insert(slot); return tree_snapshots.public_data_tree.root; } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/merkle_tree.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/merkle_tree.hpp index 0b9c66b9aa1..0a77411bdc9 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/merkle_tree.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/merkle_tree.hpp @@ -6,6 +6,7 @@ #include "barretenberg/vm/avm/trace/gadgets/poseidon2.hpp" #include "barretenberg/vm/avm/trace/public_inputs.hpp" +#include #include namespace bb::avm_trace { @@ -42,6 +43,12 @@ class AvmMerkleTreeTraceBuilder { FF compute_public_tree_leaf_slot(uint32_t clk, FF contract_address, FF leaf_index); TreeSnapshots& get_tree_snapshots() { return tree_snapshots; } + void restore_tree_state(TreeSnapshots& tree_snapshots, std::unordered_set& public_data_unique_writes) + { + this->tree_snapshots = tree_snapshots; + this->public_data_unique_writes = public_data_unique_writes; + } + std::unordered_set get_public_data_unique_writes() { return public_data_unique_writes; } // Public Data Tree bool perform_storage_read(uint32_t clk, @@ -120,6 +127,7 @@ class AvmMerkleTreeTraceBuilder { std::vector merkle_check_trace; TreeSnapshots non_revertible_tree_snapshots; TreeSnapshots tree_snapshots; + std::unordered_set public_data_unique_writes; MerkleEntry compute_root_from_path(uint32_t clk, const FF& leaf_value, const uint64_t leaf_index, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp index 991f14b1b1f..8002787ebcd 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp @@ -100,7 +100,9 @@ uint32_t finalize_rng_chks_for_testing(std::vector& main_trace, auto old_size = main_trace.size(); for (auto const& clk : custom_clk) { if (clk >= old_size) { - main_trace.push_back(Row{ .main_clk = FF(clk) }); + Row row{}; + row.main_clk = clk; + main_trace.push_back(row); } } @@ -219,6 +221,19 @@ uint32_t AvmTraceBuilder::get_inserted_note_hashes_count() public_inputs.start_tree_snapshots.note_hash_tree.size; } +uint32_t AvmTraceBuilder::get_inserted_nullifiers_count() +{ + return merkle_tree_trace_builder.get_tree_snapshots().nullifier_tree.size - + public_inputs.start_tree_snapshots.nullifier_tree.size; +} + +// Keeping track of the public data writes isn't as simple as comparing sizes +// because of updates to leaves that were already in the tree and state squashing +uint32_t AvmTraceBuilder::get_public_data_writes_count() +{ + return static_cast(merkle_tree_trace_builder.get_public_data_unique_writes().size()); +} + void AvmTraceBuilder::insert_private_state(const std::vector& siloed_nullifiers, const std::vector& unique_note_hashes) { @@ -305,6 +320,7 @@ void AvmTraceBuilder::pay_fee() throw std::runtime_error("Not enough balance for fee payer to pay for transaction"); } + // TS equivalent: // writeStorage(FEE_JUICE_ADDRESS, balance_slot, updated_balance); PublicDataWriteTreeHint write_hint = execution_hints.storage_write_hints.at(storage_write_counter++); ASSERT(write_hint.new_leaf_preimage.value == updated_balance); @@ -2818,15 +2834,17 @@ AvmError AvmTraceBuilder::op_sload(uint8_t indirect, uint32_t slot_offset, uint3 AvmError AvmTraceBuilder::op_sstore(uint8_t indirect, uint32_t src_offset, uint32_t slot_offset) { - // We keep the first encountered error - AvmError error = AvmError::NO_ERROR; auto clk = static_cast(main_trace.size()) + 1; + uint32_t unique_public_data_slot_writes = get_public_data_writes_count(); + AvmError error = current_ext_call_ctx.is_static_call ? AvmError::STATIC_CALL_ALTERATION + : unique_public_data_slot_writes >= MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + ? AvmError::SIDE_EFFECT_LIMIT_REACHED + : AvmError::NO_ERROR; - if (storage_write_counter >= MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX) { + if (!is_ok(error)) { // NOTE: the circuit constraint for this limit should only be applied // for the storage writes performed by this opcode. An exception should before // made for the fee juice storage write made after teardown. - error = AvmError::SIDE_EFFECT_LIMIT_REACHED; auto row = Row{ .main_clk = clk, .main_internal_return_ptr = internal_return_ptr, @@ -3005,8 +3023,11 @@ AvmError AvmTraceBuilder::op_emit_note_hash(uint8_t indirect, uint32_t note_hash { auto const clk = static_cast(main_trace.size()) + 1; uint32_t inserted_note_hashes_count = get_inserted_note_hashes_count(); - if (inserted_note_hashes_count >= MAX_NOTE_HASHES_PER_TX) { - AvmError error = AvmError::SIDE_EFFECT_LIMIT_REACHED; + AvmError error = current_ext_call_ctx.is_static_call ? AvmError::STATIC_CALL_ALTERATION + : inserted_note_hashes_count >= MAX_NOTE_HASHES_PER_TX ? AvmError::SIDE_EFFECT_LIMIT_REACHED + : AvmError::NO_ERROR; + + if (!is_ok(error)) { auto row = Row{ .main_clk = clk, .main_internal_return_ptr = internal_return_ptr, @@ -3019,8 +3040,12 @@ AvmError AvmTraceBuilder::op_emit_note_hash(uint8_t indirect, uint32_t note_hash return error; } - auto [row, error] = create_kernel_output_opcode(indirect, clk, note_hash_offset); + auto [row, output_error] = create_kernel_output_opcode(indirect, clk, note_hash_offset); row.main_sel_op_emit_note_hash = FF(1); + if (is_ok(error)) { + error = output_error; + } + row.main_op_err = FF(static_cast(!is_ok(error))); AppendTreeHint note_hash_write_hint = execution_hints.note_hash_write_hints.at(note_hash_write_counter++); @@ -3157,12 +3182,14 @@ AvmError AvmTraceBuilder::op_nullifier_exists(uint8_t indirect, AvmError AvmTraceBuilder::op_emit_nullifier(uint8_t indirect, uint32_t nullifier_offset) { - // We keep the first encountered error - AvmError error = AvmError::NO_ERROR; auto const clk = static_cast(main_trace.size()) + 1; - if (nullifier_write_counter >= MAX_NULLIFIERS_PER_TX) { - error = AvmError::SIDE_EFFECT_LIMIT_REACHED; + uint32_t inserted_nullifier_count = get_inserted_nullifiers_count(); + AvmError error = current_ext_call_ctx.is_static_call ? AvmError::STATIC_CALL_ALTERATION + : inserted_nullifier_count >= MAX_NULLIFIERS_PER_TX ? AvmError::SIDE_EFFECT_LIMIT_REACHED + : AvmError::NO_ERROR; + + if (!is_ok(error)) { auto row = Row{ .main_clk = clk, .main_internal_return_ptr = internal_return_ptr, @@ -3754,7 +3781,9 @@ AvmError AvmTraceBuilder::constrain_external_call(OpCode opcode, // We push the current ext call ctx onto the stack and initialize a new one current_ext_call_ctx.last_pc = pc; - current_ext_call_ctx.success_offset = resolved_success_offset, + current_ext_call_ctx.success_offset = resolved_success_offset; + current_ext_call_ctx.tree_snapshot = merkle_tree_trace_builder.get_tree_snapshots(); + current_ext_call_ctx.public_data_unique_writes = merkle_tree_trace_builder.get_public_data_unique_writes(); external_call_ctx_stack.emplace(current_ext_call_ctx); // Ext Ctx setup @@ -3771,6 +3800,7 @@ AvmError AvmTraceBuilder::constrain_external_call(OpCode opcode, current_ext_call_ctx = ExtCallCtx{ .context_id = static_cast(clk), .parent_id = current_ext_call_ctx.context_id, + .is_static_call = opcode == OpCode::STATICCALL, .contract_address = read_addr.val, .calldata = calldata, .nested_returndata = {}, @@ -3781,6 +3811,7 @@ AvmError AvmTraceBuilder::constrain_external_call(OpCode opcode, .l2_gas_left = l2_gas_allocated_to_nested_call, .da_gas_left = da_gas_allocated_to_nested_call, .internal_return_ptr_stack = {}, + .tree_snapshot = {}, }; allocate_gas_for_call(l2_gas_allocated_to_nested_call, da_gas_allocated_to_nested_call); @@ -4079,6 +4110,8 @@ ReturnDataError AvmTraceBuilder::op_revert(uint8_t indirect, uint32_t ret_offset set_call_ptr(static_cast(current_ext_call_ctx.context_id)); write_to_memory( current_ext_call_ctx.success_offset, /*success=*/FF::one(), AvmMemoryTag::U1, /*fix_pc=*/false); + merkle_tree_trace_builder.restore_tree_state(current_ext_call_ctx.tree_snapshot, + current_ext_call_ctx.public_data_unique_writes); } } @@ -4091,7 +4124,7 @@ ReturnDataError AvmTraceBuilder::op_revert(uint8_t indirect, uint32_t ret_offset .main_internal_return_ptr = FF(internal_return_ptr), .main_op_err = FF(static_cast(!is_ok(error))), .main_pc = pc, - .main_sel_op_external_return = 1, + .main_sel_op_external_revert = 1, }); pc = is_top_level ? UINT32_MAX : current_ext_call_ctx.last_pc; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp index 3f5c9297acd..b988892dc50 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp @@ -266,6 +266,7 @@ class AvmTraceBuilder { struct ExtCallCtx { uint32_t context_id; // This is the unique id of the ctx, we'll use the clk uint32_t parent_id; + bool is_static_call = false; FF contract_address{}; std::vector calldata; std::vector nested_returndata; @@ -276,6 +277,8 @@ class AvmTraceBuilder { uint32_t l2_gas_left; // as of start of latest nested call uint32_t da_gas_left; // as of start of latest nested call std::stack internal_return_ptr_stack; + TreeSnapshots tree_snapshot; // This is the tree state at the time of the call + std::unordered_set public_data_unique_writes; }; ExtCallCtx current_ext_call_ctx{}; @@ -367,6 +370,8 @@ class AvmTraceBuilder { IntermRegister reg, AvmMemTraceBuilder::MemOpOwner mem_op_owner = AvmMemTraceBuilder::MAIN); uint32_t get_inserted_note_hashes_count(); + uint32_t get_inserted_nullifiers_count(); + uint32_t get_public_data_writes_count(); FF get_tx_hash() const { return public_inputs.previous_non_revertible_accumulated_data.nullifiers[0]; } // TODO: remove these once everything is constrained. From c9e2f823d1e8715f748ad9b683506d8ac2c3cf40 Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Wed, 18 Dec 2024 15:38:49 +0200 Subject: [PATCH 20/34] fix: add log severity (#10835) Get log levels recognized by Google's Log Explorer service --- .../foundation/src/log/pino-logger.ts | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/yarn-project/foundation/src/log/pino-logger.ts b/yarn-project/foundation/src/log/pino-logger.ts index 1cc354b03bc..4178c4ff664 100644 --- a/yarn-project/foundation/src/log/pino-logger.ts +++ b/yarn-project/foundation/src/log/pino-logger.ts @@ -69,7 +69,46 @@ const [logLevel, logFilters] = parseEnv(process.env.LOG_LEVEL, defaultLogLevel); // Define custom logging levels for pino. const customLevels = { verbose: 25 }; -const pinoOpts = { customLevels, useOnlyCustomLevels: false, level: logLevel }; + +// inspired by https://github.com/pinojs/pino/issues/726#issuecomment-605814879 +const levelToSeverityFormatter = (label: string, level: number): object => { + // Severity labels https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity + let severity: string; + + switch (label as pino.Level | keyof typeof customLevels) { + case 'trace': + case 'debug': + severity = 'DEBUG'; + break; + case 'verbose': + case 'info': + severity = 'INFO'; + break; + case 'warn': + severity = 'WARNING'; + break; + case 'error': + severity = 'ERROR'; + break; + case 'fatal': + severity = 'CRITICAL'; + break; + default: + severity = 'DEFAULT'; + break; + } + + return { severity, level }; +}; + +const pinoOpts: pino.LoggerOptions = { + customLevels, + useOnlyCustomLevels: false, + level: logLevel, + formatters: { + level: levelToSeverityFormatter, + }, +}; export const levels = { labels: { ...pino.levels.labels, ...Object.fromEntries(Object.entries(customLevels).map(e => e.reverse())) }, From 5062803b3bb314e1e8080da6531f5799f8edfd39 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 18 Dec 2024 11:47:03 -0300 Subject: [PATCH 21/34] chore: Remove sequencer min/max seconds between blocks (#10845) No longer used since we added L2 slots long ago. --- .../circuit-types/src/interfaces/configs.ts | 6 -- yarn-project/foundation/src/config/env_var.ts | 2 - yarn-project/sequencer-client/src/config.ts | 11 ---- .../src/sequencer/sequencer.ts | 63 ++++--------------- 4 files changed, 11 insertions(+), 71 deletions(-) diff --git a/yarn-project/circuit-types/src/interfaces/configs.ts b/yarn-project/circuit-types/src/interfaces/configs.ts index 98c77996484..661e893a450 100644 --- a/yarn-project/circuit-types/src/interfaces/configs.ts +++ b/yarn-project/circuit-types/src/interfaces/configs.ts @@ -20,10 +20,6 @@ export interface SequencerConfig { maxTxsPerBlock?: number; /** The minimum number of txs to include in a block. */ minTxsPerBlock?: number; - /** The minimum number of seconds in-between consecutive blocks. */ - minSecondsBetweenBlocks?: number; - /** The maximum number of seconds in-between consecutive blocks. Sequencer will produce a block with less than minTxsPerBlock once this threshold is reached. */ - maxSecondsBetweenBlocks?: number; /** Recipient of block reward. */ coinbase?: EthAddress; /** Address to receive fees. */ @@ -55,8 +51,6 @@ export const SequencerConfigSchema = z.object({ transactionPollingIntervalMS: z.number().optional(), maxTxsPerBlock: z.number().optional(), minTxsPerBlock: z.number().optional(), - minSecondsBetweenBlocks: z.number().optional(), - maxSecondsBetweenBlocks: z.number().optional(), coinbase: schemas.EthAddress.optional(), feeRecipient: schemas.AztecAddress.optional(), acvmWorkingDirectory: z.string().optional(), diff --git a/yarn-project/foundation/src/config/env_var.ts b/yarn-project/foundation/src/config/env_var.ts index 76c58270b1f..4828878d721 100644 --- a/yarn-project/foundation/src/config/env_var.ts +++ b/yarn-project/foundation/src/config/env_var.ts @@ -137,9 +137,7 @@ export type EnvVar = | 'ROLLUP_CONTRACT_ADDRESS' | 'SEQ_ALLOWED_SETUP_FN' | 'SEQ_MAX_BLOCK_SIZE_IN_BYTES' - | 'SEQ_MAX_SECONDS_BETWEEN_BLOCKS' | 'SEQ_MAX_TX_PER_BLOCK' - | 'SEQ_MIN_SECONDS_BETWEEN_BLOCKS' | 'SEQ_MIN_TX_PER_BLOCK' | 'SEQ_PUBLISH_RETRY_INTERVAL_MS' | 'SEQ_PUBLISHER_PRIVATE_KEY' diff --git a/yarn-project/sequencer-client/src/config.ts b/yarn-project/sequencer-client/src/config.ts index 47f06247b53..795b8f4b564 100644 --- a/yarn-project/sequencer-client/src/config.ts +++ b/yarn-project/sequencer-client/src/config.ts @@ -59,17 +59,6 @@ export const sequencerConfigMappings: ConfigMappingsType = { description: 'The minimum number of txs to include in a block.', ...numberConfigHelper(1), }, - minSecondsBetweenBlocks: { - env: 'SEQ_MIN_SECONDS_BETWEEN_BLOCKS', - description: 'The minimum number of seconds in-between consecutive blocks.', - ...numberConfigHelper(0), - }, - maxSecondsBetweenBlocks: { - env: 'SEQ_MAX_SECONDS_BETWEEN_BLOCKS', - description: - 'The maximum number of seconds in-between consecutive blocks. Sequencer will produce a block with less than minTxsPerBlock once this threshold is reached.', - ...numberConfigHelper(0), - }, coinbase: { env: 'COINBASE', parseEnv: (val: string) => EthAddress.fromString(val), diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index adc3bda49e2..6116485c849 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -77,8 +77,6 @@ export class Sequencer { private pollingIntervalMs: number = 1000; private maxTxsPerBlock = 32; private minTxsPerBLock = 1; - private minSecondsBetweenBlocks = 0; - private maxSecondsBetweenBlocks = 0; // TODO: zero values should not be allowed for the following 2 values in PROD private _coinbase = EthAddress.ZERO; private _feeRecipient = AztecAddress.ZERO; @@ -139,12 +137,6 @@ export class Sequencer { if (config.minTxsPerBlock !== undefined) { this.minTxsPerBLock = config.minTxsPerBlock; } - if (config.minSecondsBetweenBlocks !== undefined) { - this.minSecondsBetweenBlocks = config.minSecondsBetweenBlocks; - } - if (config.maxSecondsBetweenBlocks !== undefined) { - this.maxSecondsBetweenBlocks = config.maxSecondsBetweenBlocks; - } if (config.coinbase) { this._coinbase = config.coinbase; } @@ -353,15 +345,6 @@ export class Sequencer { } } - /** Whether to skip the check of min txs per block if more than maxSecondsBetweenBlocks has passed since the previous block. */ - private skipMinTxsPerBlockCheck(historicalHeader: BlockHeader | undefined): boolean { - const lastBlockTime = historicalHeader?.globalVariables.timestamp.toNumber() || 0; - const currentTime = Math.floor(Date.now() / 1000); - const elapsed = currentTime - lastBlockTime; - - return this.maxSecondsBetweenBlocks > 0 && elapsed >= this.maxSecondsBetweenBlocks; - } - async mayProposeBlock(tipArchive: Buffer, proposalBlockNumber: bigint): Promise { // This checks that we can propose, and gives us the slot that we are to propose for try { @@ -444,53 +427,29 @@ export class Sequencer { `Last block mined at ${lastBlockTime} current time is ${currentTime} (elapsed ${elapsedSinceLastBlock})`, ); - // If we haven't hit the maxSecondsBetweenBlocks, we need to have at least minTxsPerBLock txs. - // Do not go forward with new block if not enough time has passed since last block - if (this.minSecondsBetweenBlocks > 0 && elapsedSinceLastBlock < this.minSecondsBetweenBlocks) { + // We need to have at least minTxsPerBLock txs. + if (args.pendingTxsCount != undefined && args.pendingTxsCount < this.minTxsPerBLock) { this.log.verbose( - `Not creating block because not enough time ${this.minSecondsBetweenBlocks} has passed since last block`, + `Not creating block because not enough txs in the pool (got ${args.pendingTxsCount} min ${this.minTxsPerBLock})`, ); return false; } - const skipCheck = this.skipMinTxsPerBlockCheck(historicalHeader); - - // If we haven't hit the maxSecondsBetweenBlocks, we need to have at least minTxsPerBLock txs. - if (args.pendingTxsCount != undefined) { - if (args.pendingTxsCount < this.minTxsPerBLock) { - if (skipCheck) { - this.log.debug( - `Creating block with only ${args.pendingTxsCount} txs as more than ${this.maxSecondsBetweenBlocks}s have passed since last block`, - ); - } else { - this.log.verbose( - `Not creating block because not enough txs in the pool (got ${args.pendingTxsCount} min ${this.minTxsPerBLock})`, - ); - return false; - } - } - } - // Bail if we don't have enough valid txs - if (args.validTxsCount != undefined) { - // Bail if we don't have enough valid txs - if (!skipCheck && args.validTxsCount < this.minTxsPerBLock) { - this.log.verbose( - `Not creating block because not enough valid txs loaded from the pool (got ${args.validTxsCount} min ${this.minTxsPerBLock})`, - ); - return false; - } + if (args.validTxsCount != undefined && args.validTxsCount < this.minTxsPerBLock) { + this.log.verbose( + `Not creating block because not enough valid txs loaded from the pool (got ${args.validTxsCount} min ${this.minTxsPerBLock})`, + ); + return false; } // TODO: This check should be processedTxs.length < this.minTxsPerBLock, so we don't publish a block with // less txs than the minimum. But that'd cause the entire block to be aborted and retried. Instead, we should // go back to the p2p pool and load more txs until we hit our minTxsPerBLock target. Only if there are no txs // we should bail. - if (args.processedTxsCount != undefined) { - if (args.processedTxsCount === 0 && !skipCheck && this.minTxsPerBLock > 0) { - this.log.verbose('No txs processed correctly to build block.'); - return false; - } + if (args.processedTxsCount === 0 && this.minTxsPerBLock > 0) { + this.log.verbose('No txs processed correctly to build block.'); + return false; } return true; From 9981078470af8d63f3e6a2cf601f5a2f862c376e Mon Sep 17 00:00:00 2001 From: Gregorio Juliana Date: Wed, 18 Dec 2024 15:59:29 +0100 Subject: [PATCH 22/34] fix: aztec js e2e (#10837) Webpack wasn't being run, so `main.js` was never found Also attempted to make startup faster by reducing the amount of stuff that the test imports --- yarn-project/Earthfile | 13 ++++++++-- yarn-project/archiver/package.json | 2 +- yarn-project/aztec-faucet/package.json | 2 +- yarn-project/aztec-node/package.json | 2 +- yarn-project/aztec.js/package.json | 8 ++++--- .../api/{aztec_address.ts => addresses.ts} | 1 + yarn-project/aztec.js/src/contract/index.ts | 16 ++++++++----- yarn-project/aztec.js/src/index.ts | 24 ++++--------------- yarn-project/bb-prover/package.json | 2 +- yarn-project/bot/package.json | 2 +- yarn-project/circuit-types/package.json | 2 +- yarn-project/cli/package.json | 2 +- yarn-project/cli/src/utils/commands.ts | 2 +- .../src/composed/e2e_aztec_js_browser.test.ts | 7 +++--- yarn-project/end-to-end/src/web/main.ts | 18 ++++++++++---- yarn-project/l1-artifacts/package.json | 2 +- yarn-project/p2p/package.json | 2 +- yarn-project/proof-verifier/package.json | 2 +- yarn-project/protocol-contracts/package.json | 2 +- yarn-project/prover-client/package.json | 2 +- yarn-project/prover-node/package.json | 2 +- yarn-project/sequencer-client/package.json | 2 +- yarn-project/validator-client/package.json | 2 +- yarn-project/world-state/package.json | 2 +- 24 files changed, 65 insertions(+), 56 deletions(-) rename yarn-project/aztec.js/src/api/{aztec_address.ts => addresses.ts} (54%) diff --git a/yarn-project/Earthfile b/yarn-project/Earthfile index adf74380994..50e81f006cc 100644 --- a/yarn-project/Earthfile +++ b/yarn-project/Earthfile @@ -55,7 +55,6 @@ build: ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true RUN ./bootstrap.sh - build-dev: FROM +build SAVE ARTIFACT /usr/src /usr/src @@ -195,7 +194,17 @@ export-aztec-faucet: # We care about creating a slimmed down e2e image because we have to serialize it from earthly to docker for running. end-to-end-prod: BUILD ../spartan/+charts - FROM +cli-base + FROM +build + # A fast build is not enough for the end-to-end tests, we still need to run webpack + RUN cd end-to-end && yarn build:web + # Now that the web is compiled, we can trim down the image further + RUN rm -rf \ + ../noir-projects \ + ../l1-contracts \ + ../barretenberg/ts/src \ + ../barretenberg/ts/dest/node-cjs \ + ../barretenberg/ts/dest/browser + RUN yarn workspaces focus @aztec/end-to-end @aztec/cli-wallet --production && yarn cache clean COPY --dir +rollup-verifier-contract/usr/src/bb /usr/src COPY --dir +build-dev/usr/src/noir-projects/noir-contracts /usr/src/noir-projects/noir-contracts diff --git a/yarn-project/archiver/package.json b/yarn-project/archiver/package.json index c802f7aaf33..c773e74ca99 100644 --- a/yarn-project/archiver/package.json +++ b/yarn-project/archiver/package.json @@ -110,4 +110,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/aztec-faucet/package.json b/yarn-project/aztec-faucet/package.json index 64290005c93..5c0c9a01b91 100644 --- a/yarn-project/aztec-faucet/package.json +++ b/yarn-project/aztec-faucet/package.json @@ -94,4 +94,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/aztec-node/package.json b/yarn-project/aztec-node/package.json index ad55b09fe21..6ace5e54c53 100644 --- a/yarn-project/aztec-node/package.json +++ b/yarn-project/aztec-node/package.json @@ -106,4 +106,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/aztec.js/package.json b/yarn-project/aztec.js/package.json index 830f8f697d5..5ebdafd8895 100644 --- a/yarn-project/aztec.js/package.json +++ b/yarn-project/aztec.js/package.json @@ -8,7 +8,8 @@ "./interfaces/pxe": "./dest/api/interfaces/pxe.js", "./abi": "./dest/api/abi.js", "./account": "./dest/api/account.js", - "./aztec_address": "./dest/api/aztec_address.js", + "./addresses": "./dest/api/addresses.js", + "./contracts": "./dest/contract/index.js", "./deployment": "./dest/api/deployment.js", "./entrypoint": "./dest/api/entrypoint.js", "./eth_address": "./dest/api/eth_address.js", @@ -19,7 +20,8 @@ "./log_id": "./dest/api/log_id.js", "./rpc": "./dest/rpc_clients/index.js", "./tx_hash": "./dest/api/tx_hash.js", - "./wallet": "./dest/api/wallet.js" + "./wallet": "./dest/api/wallet.js", + "./utils": "./dest/utils/index.js" }, "typedocOptions": { "entryPoints": [ @@ -119,4 +121,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/aztec.js/src/api/aztec_address.ts b/yarn-project/aztec.js/src/api/addresses.ts similarity index 54% rename from yarn-project/aztec.js/src/api/aztec_address.ts rename to yarn-project/aztec.js/src/api/addresses.ts index c6cece77dae..5b7111416c9 100644 --- a/yarn-project/aztec.js/src/api/aztec_address.ts +++ b/yarn-project/aztec.js/src/api/addresses.ts @@ -1 +1,2 @@ export { AztecAddress } from '@aztec/foundation/aztec-address'; +export { CompleteAddress } from '@aztec/circuits.js'; diff --git a/yarn-project/aztec.js/src/contract/index.ts b/yarn-project/aztec.js/src/contract/index.ts index dcf7b9a2dd5..b69395de86e 100644 --- a/yarn-project/aztec.js/src/contract/index.ts +++ b/yarn-project/aztec.js/src/contract/index.ts @@ -35,10 +35,14 @@ * * @packageDocumentation */ -export * from './contract.js'; -export * from './contract_function_interaction.js'; -export * from './sent_tx.js'; -export * from './contract_base.js'; -export * from './batch_call.js'; +export { Contract } from './contract.js'; +export { + ContractFunctionInteraction, + type ProfileResult, + type SendMethodOptions, +} from './contract_function_interaction.js'; +export { DefaultWaitOpts, SentTx, type WaitOpts } from './sent_tx.js'; +export { ContractBase, type ContractMethod, type ContractNotes, type ContractStorageLayout } from './contract_base.js'; +export { BatchCall } from './batch_call.js'; export { type DeployOptions, DeployMethod } from './deploy_method.js'; -export * from './deploy_sent_tx.js'; +export { DeploySentTx } from './deploy_sent_tx.js'; diff --git a/yarn-project/aztec.js/src/index.ts b/yarn-project/aztec.js/src/index.ts index c4a15950273..4164b5000a8 100644 --- a/yarn-project/aztec.js/src/index.ts +++ b/yarn-project/aztec.js/src/index.ts @@ -13,29 +13,12 @@ * ```typescript * import { TxHash } from '@aztec.js/tx_hash' * import { type ContractArtifact, type FunctionArtifact, FunctionSelector } from '@aztec/aztec.js/abi'; - * import { AztecAddress } from '@aztec/aztec.js/aztec_address'; + * import { AztecAddress } from '@aztec/aztec.js/addresses'; * import { EthAddress } from '@aztec/aztec.js/eth_address'; * ``` * * TODO: Ultimately reimplement this mega exporter by mega exporting a granular api (then deprecate it). */ -export { - BatchCall, - Contract, - ContractBase, - ContractFunctionInteraction, - DefaultWaitOpts, - DeployMethod, - DeploySentTx, - SentTx, - type ContractMethod, - type ContractNotes, - type ContractStorageLayout, - type DeployOptions, - type ProfileResult, - type SendMethodOptions, - type WaitOpts, -} from './contract/index.js'; export { ContractDeployer } from './deployment/index.js'; @@ -79,7 +62,6 @@ export { AccountWallet, AccountWalletWithSecretKey, SignerlessWallet, type Walle // // TODO https://github.com/AztecProtocol/aztec-packages/issues/2632 --> FunctionSelector might not need to be exposed // // here once the issue is resolved. export { - AztecAddress, ContractClassWithId, ContractInstanceWithAddress, EthAddress, @@ -110,7 +92,6 @@ export { AuthWitness, Body, Comparator, - CompleteAddress, ContractClass2BlockL2Logs, EncryptedLogPayload, EpochProofQuote, @@ -174,3 +155,6 @@ export { EthCheatCodes, deployL1Contract, deployL1Contracts, type DeployL1Contra export * from './api/abi.js'; export * from './api/fee.js'; export * from './api/init.js'; +// Granular export, even if not in the api folder +export * from './contract/index.js'; +export * from './api/addresses.js'; diff --git a/yarn-project/bb-prover/package.json b/yarn-project/bb-prover/package.json index d32a9343fb1..1c109743f2c 100644 --- a/yarn-project/bb-prover/package.json +++ b/yarn-project/bb-prover/package.json @@ -111,4 +111,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/bot/package.json b/yarn-project/bot/package.json index fcd38c0be00..e44cad7a4a2 100644 --- a/yarn-project/bot/package.json +++ b/yarn-project/bot/package.json @@ -91,4 +91,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/circuit-types/package.json b/yarn-project/circuit-types/package.json index 94e6136a449..ea574a81948 100644 --- a/yarn-project/circuit-types/package.json +++ b/yarn-project/circuit-types/package.json @@ -106,4 +106,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/cli/package.json b/yarn-project/cli/package.json index 31dcf1da552..7a9d39d31f8 100644 --- a/yarn-project/cli/package.json +++ b/yarn-project/cli/package.json @@ -127,4 +127,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/cli/src/utils/commands.ts b/yarn-project/cli/src/utils/commands.ts index 4065c8fa84a..af672916438 100644 --- a/yarn-project/cli/src/utils/commands.ts +++ b/yarn-project/cli/src/utils/commands.ts @@ -1,5 +1,5 @@ import { FunctionSelector } from '@aztec/aztec.js/abi'; -import { AztecAddress } from '@aztec/aztec.js/aztec_address'; +import { AztecAddress } from '@aztec/aztec.js/addresses'; import { EthAddress } from '@aztec/aztec.js/eth_address'; import { Fr } from '@aztec/aztec.js/fields'; import { LogId } from '@aztec/aztec.js/log_id'; diff --git a/yarn-project/end-to-end/src/composed/e2e_aztec_js_browser.test.ts b/yarn-project/end-to-end/src/composed/e2e_aztec_js_browser.test.ts index 51c7d8eab45..03ff98223ca 100644 --- a/yarn-project/end-to-end/src/composed/e2e_aztec_js_browser.test.ts +++ b/yarn-project/end-to-end/src/composed/e2e_aztec_js_browser.test.ts @@ -23,11 +23,10 @@ const pageLogger = createLogger('e2e:aztec_browser.js:web:page'); * To run the test, do the following: * 1) Build the whole repository, * 2) go to `yarn-project/end-to-end` and build the web packed package with `yarn build:web`, - * 3) start anvil: `anvil`, - * 4) if you intend to use a remotely running environment then export the URL of your PXE e.g. + * 3) if you intend to use a remotely running environment then export the URL of your PXE e.g. * `export PXE_URL='http://localhost:8080'` - * 5) go to `yarn-project/end-to-end` and run the test: `yarn test aztec_js_browser` - * 6) If you get dependency error run `apt install libnss3 libatk1.0-0t64 libatk-bridge2.0-0t64 libcups2t64 libxdamage1 libxkbcommon0 libpango-1.0-0 libcairo2 libasound2t64`. + * 4) go to `yarn-project/end-to-end` and run the test: `yarn test aztec_js_browser` + * 5) If you get dependency error run `apt install libnss3 libatk1.0-0t64 libatk-bridge2.0-0t64 libcups2t64 libxdamage1 libxkbcommon0 libpango-1.0-0 libcairo2 libasound2t64`. * * NOTE 1: If you see the logs spammed with unexpected logs there is probably a chrome process with a webpage * unexpectedly running in the background. Kill it with `killall chrome` diff --git a/yarn-project/end-to-end/src/web/main.ts b/yarn-project/end-to-end/src/web/main.ts index 3e65f0760e9..bc44adf8fea 100644 --- a/yarn-project/end-to-end/src/web/main.ts +++ b/yarn-project/end-to-end/src/web/main.ts @@ -1,6 +1,16 @@ -export * from '@aztec/aztec.js'; -export * from '@aztec/accounts/testing'; -export * from '@aztec/accounts/single_key'; -export * from '@aztec/accounts/schnorr'; +export { Fr } from '@aztec/aztec.js/fields'; +export { createPXEClient } from '@aztec/aztec.js/rpc'; +export { getSchnorrAccount } from '@aztec/accounts/schnorr'; +export { getUnsafeSchnorrAccount } from '@aztec/accounts/single_key'; +export { + getDeployedTestAccountsWallets, + INITIAL_TEST_SECRET_KEYS, + INITIAL_TEST_SIGNING_KEYS, + INITIAL_TEST_ACCOUNT_SALTS, +} from '@aztec/accounts/testing'; +export { AztecAddress, CompleteAddress } from '@aztec/aztec.js/addresses'; +export { Contract, DeployMethod } from '@aztec/aztec.js/contracts'; +export { contractArtifactFromBuffer } from '@aztec/aztec.js/abi'; +export { generatePublicKey } from '@aztec/aztec.js/utils'; export { Buffer } from 'buffer/'; diff --git a/yarn-project/l1-artifacts/package.json b/yarn-project/l1-artifacts/package.json index f5469172c8e..6963e95d3cd 100644 --- a/yarn-project/l1-artifacts/package.json +++ b/yarn-project/l1-artifacts/package.json @@ -32,4 +32,4 @@ "generated" ], "types": "./dest/index.d.ts" -} \ No newline at end of file +} diff --git a/yarn-project/p2p/package.json b/yarn-project/p2p/package.json index a24e71fbc38..5be467e88f8 100644 --- a/yarn-project/p2p/package.json +++ b/yarn-project/p2p/package.json @@ -123,4 +123,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/proof-verifier/package.json b/yarn-project/proof-verifier/package.json index 1af22444af1..9a1fed2dba8 100644 --- a/yarn-project/proof-verifier/package.json +++ b/yarn-project/proof-verifier/package.json @@ -81,4 +81,4 @@ "../../foundation/src/jest/setup.mjs" ] } -} \ No newline at end of file +} diff --git a/yarn-project/protocol-contracts/package.json b/yarn-project/protocol-contracts/package.json index aab9d4b37e3..b63606a7f63 100644 --- a/yarn-project/protocol-contracts/package.json +++ b/yarn-project/protocol-contracts/package.json @@ -101,4 +101,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/prover-client/package.json b/yarn-project/prover-client/package.json index c395650e41e..9278090708f 100644 --- a/yarn-project/prover-client/package.json +++ b/yarn-project/prover-client/package.json @@ -109,4 +109,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/prover-node/package.json b/yarn-project/prover-node/package.json index 53fa2943cc4..4d0fc44fd24 100644 --- a/yarn-project/prover-node/package.json +++ b/yarn-project/prover-node/package.json @@ -96,4 +96,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/sequencer-client/package.json b/yarn-project/sequencer-client/package.json index 1fcf01f6a85..d373ef337b5 100644 --- a/yarn-project/sequencer-client/package.json +++ b/yarn-project/sequencer-client/package.json @@ -118,4 +118,4 @@ "../../foundation/src/jest/setup.mjs" ] } -} \ No newline at end of file +} diff --git a/yarn-project/validator-client/package.json b/yarn-project/validator-client/package.json index e14fc7e52c3..b760d9aedb6 100644 --- a/yarn-project/validator-client/package.json +++ b/yarn-project/validator-client/package.json @@ -97,4 +97,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} diff --git a/yarn-project/world-state/package.json b/yarn-project/world-state/package.json index b3cc7dadddd..ec920a94cfc 100644 --- a/yarn-project/world-state/package.json +++ b/yarn-project/world-state/package.json @@ -102,4 +102,4 @@ "engines": { "node": ">=18" } -} \ No newline at end of file +} From f576e52f097b51baf01c593694a2bc0550c1dec1 Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Wed, 18 Dec 2024 17:04:58 +0200 Subject: [PATCH 23/34] fix: add inotify-tools (#10841) Add missing package needed for `watch.sh` --- .devcontainer/dev/devcontainer.json | 2 +- build-images/Earthfile | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.devcontainer/dev/devcontainer.json b/.devcontainer/dev/devcontainer.json index 12a7c197f6e..2e5d5ec2d45 100644 --- a/.devcontainer/dev/devcontainer.json +++ b/.devcontainer/dev/devcontainer.json @@ -1,6 +1,6 @@ { "name": "Development", - "image": "aztecprotocol/devbox:1.1", + "image": "aztecprotocol/devbox:1.2", "features": { // Use custom fork with noble added to list of supported distros. "./docker-in-docker": {} diff --git a/build-images/Earthfile b/build-images/Earthfile index 08664afe3f0..c9f8ab865ad 100644 --- a/build-images/Earthfile +++ b/build-images/Earthfile @@ -233,6 +233,7 @@ basebox: tmux \ vim \ zsh \ + inotify-tools \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # Install earthly. @@ -323,9 +324,9 @@ devbox: CMD ["/bin/zsh"] ARG TARGETARCH - SAVE IMAGE --push aztecprotocol/devbox:1.1-$TARGETARCH + SAVE IMAGE --push aztecprotocol/devbox:1.2-$TARGETARCH # Save it without the arch tag as this is what's referenced in devcontainer.json - SAVE IMAGE aztecprotocol/devbox:1.1 + SAVE IMAGE aztecprotocol/devbox:1.2 devbox-manifest: LET VERSION = 1.1 From 677c0f4c1fa5ad6c8eea4d16217e5f3ddef7926d Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 18 Dec 2024 12:07:24 -0300 Subject: [PATCH 24/34] fix: Do not start duplicate proving jobs if existing claim (#10793) If the prover node was restarted while there was a claim submitted by it on L1, the handlers for both the epoch and claims monitor would cause it to trigger a proving job. --- .../prover-node/src/prover-node.test.ts | 27 ++++++++++++++++--- yarn-project/prover-node/src/prover-node.ts | 12 +++++---- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/yarn-project/prover-node/src/prover-node.test.ts b/yarn-project/prover-node/src/prover-node.test.ts index 931396a2676..f3fce627a36 100644 --- a/yarn-project/prover-node/src/prover-node.test.ts +++ b/yarn-project/prover-node/src/prover-node.test.ts @@ -218,17 +218,15 @@ describe('prover-node', () => { }); it('starts proving if there is a claim sent by us', async () => { - publisher.getProofClaim.mockResolvedValue(claim); l2BlockSource.getProvenL2EpochNumber.mockResolvedValue(9); - await proverNode.handleInitialEpochSync(10n); + await proverNode.handleClaim(claim); expect(jobs[0].epochNumber).toEqual(10n); }); it('does not start proving if there is a claim sent by us but proof has already landed', async () => { - publisher.getProofClaim.mockResolvedValue(claim); l2BlockSource.getProvenL2EpochNumber.mockResolvedValue(10); - await proverNode.handleInitialEpochSync(10n); + await proverNode.handleClaim(claim); expect(jobs.length).toEqual(0); }); @@ -261,6 +259,27 @@ describe('prover-node', () => { expect(coordination.addEpochProofQuote).toHaveBeenCalledTimes(1); }); + it('starts proving if there is a claim during initial sync', async () => { + l2BlockSource.getL2EpochNumber.mockResolvedValue(11n); + publisher.getProofClaim.mockResolvedValue(claim); + + await proverNode.start(); + await sleep(100); + + expect(jobs[0].epochNumber).toEqual(10n); + expect(jobs.length).toEqual(1); + }); + + it('does not start proving if there is a claim for proven epoch during initial sync', async () => { + l2BlockSource.getProvenL2EpochNumber.mockResolvedValue(10); + publisher.getProofClaim.mockResolvedValue(claim); + + await proverNode.start(); + await sleep(100); + + expect(jobs.length).toEqual(0); + }); + it('sends another quote when a new epoch is completed', async () => { lastEpochComplete = 10n; l2BlockSource.getL2EpochNumber.mockResolvedValue(11n); diff --git a/yarn-project/prover-node/src/prover-node.ts b/yarn-project/prover-node/src/prover-node.ts index 65b788fc03b..8eec703ffed 100644 --- a/yarn-project/prover-node/src/prover-node.ts +++ b/yarn-project/prover-node/src/prover-node.ts @@ -93,6 +93,12 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr return; } + const provenEpoch = await this.l2BlockSource.getProvenL2EpochNumber(); + if (provenEpoch !== undefined && proofClaim.epochToProve <= provenEpoch) { + this.log.verbose(`Claim for epoch ${proofClaim.epochToProve} is already proven`); + return; + } + try { await this.startProof(proofClaim.epochToProve); this.latestEpochWeAreProving = proofClaim.epochToProve; @@ -117,12 +123,8 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr try { const claim = await this.publisher.getProofClaim(); if (!claim || claim.epochToProve < epochNumber) { + this.log.verbose(`Handling epoch ${epochNumber} completed as initial sync`); await this.handleEpochCompleted(epochNumber); - } else if (claim && claim.bondProvider.equals(this.publisher.getSenderAddress())) { - const lastEpochProven = await this.l2BlockSource.getProvenL2EpochNumber(); - if (lastEpochProven === undefined || lastEpochProven < claim.epochToProve) { - await this.handleClaim(claim); - } } } catch (err) { this.log.error(`Error handling initial epoch sync`, err); From 607dc4b090c81b7fad9f44c3b13f1f45659922ad Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Wed, 18 Dec 2024 17:43:23 +0200 Subject: [PATCH 25/34] feat: expose ENFORCE_FEES in helm chart (#10488) This PR exposes the `ENFORCE_FEES` setting in the sequencer to the helm chart. --- spartan/aztec-network/templates/transaction-bot.yaml | 2 ++ spartan/aztec-network/templates/validator.yaml | 2 ++ spartan/aztec-network/values.yaml | 2 ++ spartan/aztec-network/values/release-devnet.yaml | 3 +++ 4 files changed, 9 insertions(+) diff --git a/spartan/aztec-network/templates/transaction-bot.yaml b/spartan/aztec-network/templates/transaction-bot.yaml index 99b395ca987..7d4837ad40f 100644 --- a/spartan/aztec-network/templates/transaction-bot.yaml +++ b/spartan/aztec-network/templates/transaction-bot.yaml @@ -101,6 +101,8 @@ spec: value: "{{ .Values.bot.followChain }}" - name: BOT_NO_START value: "{{ .Values.bot.botNoStart }}" + - name: BOT_FEE_PAYMENT_METHOD + value: "{{ .Values.bot.feePaymentMethod }}" - name: PXE_PROVER_ENABLED value: "{{ .Values.aztec.realProofs }}" - name: PROVER_REAL_PROOFS diff --git a/spartan/aztec-network/templates/validator.yaml b/spartan/aztec-network/templates/validator.yaml index bc88443986d..7d7c131b176 100644 --- a/spartan/aztec-network/templates/validator.yaml +++ b/spartan/aztec-network/templates/validator.yaml @@ -178,6 +178,8 @@ spec: value: "{{ .Values.validator.sequencer.maxTxsPerBlock }}" - name: SEQ_ENFORCE_TIME_TABLE value: "{{ .Values.validator.sequencer.enforceTimeTable }}" + - name: ENFORCE_FEES + value: "{{ .Values.validator.sequencer.enforceFees }}" - name: L1_CHAIN_ID value: "{{ .Values.ethereum.chainId }}" - name: OTEL_RESOURCE_ATTRIBUTES diff --git a/spartan/aztec-network/values.yaml b/spartan/aztec-network/values.yaml index 26cf80bb5f7..dd218203c29 100644 --- a/spartan/aztec-network/values.yaml +++ b/spartan/aztec-network/values.yaml @@ -97,6 +97,7 @@ validator: minTxsPerBlock: 1 maxTxsPerBlock: 4 enforceTimeTable: true + enforceFees: false validator: disabled: false reexecute: true @@ -168,6 +169,7 @@ bot: # Do not wait for transactions followChain: "NONE" botNoStart: false + feePaymentMethod: "none" maxErrors: 3 stopIfUnhealthy: true service: diff --git a/spartan/aztec-network/values/release-devnet.yaml b/spartan/aztec-network/values/release-devnet.yaml index c4cae860388..a6bf3ce8c53 100644 --- a/spartan/aztec-network/values/release-devnet.yaml +++ b/spartan/aztec-network/values/release-devnet.yaml @@ -4,6 +4,8 @@ telemetry: validator: replicas: 1 + sequencer: + enforceFees: false # disabled until the bot can fund itself validatorKeys: - 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 validatorAddresses: @@ -24,6 +26,7 @@ proverAgent: bot: followChain: "PENDING" + feePaymentMethod: "none" # disabled until the bot can fund itself enabled: true txIntervalSeconds: 200 From 96ebc0cf40daee61644471369161fb7438c72431 Mon Sep 17 00:00:00 2001 From: just-mitch <68168980+just-mitch@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:43:51 -0500 Subject: [PATCH 26/34] fix: matching release branches (#10842) This was causing merges to master to override things published by release branches. --- .github/workflows/publish-aztec-packages.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-aztec-packages.yml b/.github/workflows/publish-aztec-packages.yml index 9da6aad1589..9ef92456560 100644 --- a/.github/workflows/publish-aztec-packages.yml +++ b/.github/workflows/publish-aztec-packages.yml @@ -211,7 +211,7 @@ jobs: - name: Publish aztec manifests if: ${{ env.SHOULD_PUBLISH_DOCKER_IMAGES == 'true' }} run: | - if [ "${{ github.ref_name }}" == "release/*" ]; then + if [[ "${{ github.ref_name }}" =~ ^release/ ]]; then TAG="${{ github.ref_name }}" VERSION="${TAG#release/}" DIST_TAG=devnet @@ -282,7 +282,7 @@ jobs: - name: Set tags and versions id: version_step run: | - if [ "${{ github.ref_name }}" == "release/*" ]; then + if [[ "${{ github.ref_name }}" =~ ^release/ ]]; then DIST_TAG=devnet TAG=${{ env.DEPLOY_TAG }} VERSION=${TAG#aztec-packages-v}-devnet @@ -356,7 +356,7 @@ jobs: - name: Publish aztec-up working-directory: ./aztec-up/terraform run: | - if [ "${{ github.ref_name }}" == "release/*" ]; then + if [[ "${{ github.ref_name }}" =~ ^release/ ]]; then TAG="${{ github.ref_name }}" VERSION="${TAG#release/}" elif [ -n "${{ env.DEPLOY_TAG }}" ]; then From e23fd0dd95f193070e4a646ce5953d22e8a09476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Wed, 18 Dec 2024 09:56:44 -0600 Subject: [PATCH 27/34] refactor: fpc optimization, cleanup + docs (#10555) --- cspell.json | 1 + .../contracts/amm_contract/src/main.nr | 2 +- .../contracts/fpc_contract/src/config.nr | 23 +++ .../contracts/fpc_contract/src/lib.nr | 10 -- .../contracts/fpc_contract/src/main.nr | 158 ++++++++++++++---- .../contracts/fpc_contract/src/settings.nr | 23 --- .../contracts/nft_contract/src/main.nr | 2 +- .../contracts/token_contract/src/main.nr | 90 +++++----- .../token_contract/src/test/refunds.nr | 8 +- .../noir-contracts/scripts/flamegraph.sh | 4 +- .../contract/contract_function_interaction.ts | 21 ++- .../src/fee/fee_juice_payment_method.ts | 2 +- .../aztec.js/src/fee/fee_payment_method.ts | 2 +- .../aztec.js/src/fee/no_fee_payment_method.ts | 2 +- .../src/fee/private_fee_payment_method.ts | 62 +++++-- .../src/fee/public_fee_payment_method.ts | 55 ++++-- .../src/contract/contract_class.ts | 2 +- .../cli-wallet/src/utils/options/fees.ts | 15 +- .../cli/src/cmds/devnet/bootstrap_network.ts | 10 +- .../src/benchmarks/bench_prover.test.ts | 3 +- .../src/benchmarks/bench_tx_size_fees.test.ts | 9 +- .../src/e2e_fees/account_init.test.ts | 17 +- .../src/e2e_fees/dapp_subscription.test.ts | 24 +-- .../end-to-end/src/e2e_fees/failures.test.ts | 52 +++--- .../end-to-end/src/e2e_fees/fees_test.ts | 8 +- .../src/e2e_fees/gas_estimation.test.ts | 2 +- .../src/e2e_fees/private_payments.test.ts | 84 +++------- .../src/e2e_fees/public_payments.test.ts | 2 +- .../pxe/src/pxe_service/error_enriching.ts | 2 +- 29 files changed, 394 insertions(+), 301 deletions(-) create mode 100644 noir-projects/noir-contracts/contracts/fpc_contract/src/config.nr delete mode 100644 noir-projects/noir-contracts/contracts/fpc_contract/src/lib.nr delete mode 100644 noir-projects/noir-contracts/contracts/fpc_contract/src/settings.nr diff --git a/cspell.json b/cspell.json index 0b8d2a27549..3ed9bc44cf4 100644 --- a/cspell.json +++ b/cspell.json @@ -11,6 +11,7 @@ "asyncify", "auditability", "authwit", + "authwits", "Automine", "autonat", "autorun", diff --git a/noir-projects/noir-contracts/contracts/amm_contract/src/main.nr b/noir-projects/noir-contracts/contracts/amm_contract/src/main.nr index fe405512cf4..b14258f9d0f 100644 --- a/noir-projects/noir-contracts/contracts/amm_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/amm_contract/src/main.nr @@ -120,7 +120,7 @@ contract AMM { // We then complete the flow in public. Note that the type of operation and amounts will all be publicly known, // but the identity of the caller is not revealed despite us being able to send tokens to them by completing the - // partial notees. + // partial notes. AMM::at(context.this_address()) ._add_liquidity( config, diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/config.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/config.nr new file mode 100644 index 00000000000..00c1473d34b --- /dev/null +++ b/noir-projects/noir-contracts/contracts/fpc_contract/src/config.nr @@ -0,0 +1,23 @@ +use dep::aztec::protocol_types::{address::AztecAddress, traits::{Deserialize, Serialize}}; + +global CONFIG_LENGTH: u32 = 2; + +pub struct Config { + pub accepted_asset: AztecAddress, // Asset the FPC accepts (denoted as AA below) + pub admin: AztecAddress, // Address to which AA is sent during the private fee payment flow +} + +impl Serialize for Config { + fn serialize(self: Self) -> [Field; CONFIG_LENGTH] { + [self.accepted_asset.to_field(), self.admin.to_field()] + } +} + +impl Deserialize for Config { + fn deserialize(fields: [Field; CONFIG_LENGTH]) -> Self { + Config { + accepted_asset: AztecAddress::from_field(fields[0]), + admin: AztecAddress::from_field(fields[1]), + } + } +} diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/lib.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/lib.nr deleted file mode 100644 index e9aad0aeb73..00000000000 --- a/noir-projects/noir-contracts/contracts/fpc_contract/src/lib.nr +++ /dev/null @@ -1,10 +0,0 @@ -use dep::aztec::context::PublicContext; - -pub fn compute_rebate(context: PublicContext, initial_amount: Field) -> Field { - let actual_fee = context.transaction_fee(); - assert( - !initial_amount.lt(actual_fee), - "Initial amount paid to the paymaster does not cover actual fee", - ); - initial_amount - actual_fee -} diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr index 96ca07817a2..d61d242a1d7 100644 --- a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr @@ -1,12 +1,16 @@ -mod lib; -mod settings; +mod config; use dep::aztec::macros::aztec; +/// Fee Payment Contract (FPC) allows users to pay for the transaction fee with an arbitrary asset. Supports private +/// and public fee payment flows. +/// +/// ***Note:*** +/// Accepted asset funds sent by the users to this contract stay in this contract and later on can +/// be pulled by the admin using the `pull_funds` function. #[aztec] contract FPC { - use crate::lib::compute_rebate; - use crate::settings::Settings; + use crate::config::Config; use dep::aztec::{ macros::{functions::{initializer, internal, private, public}, storage::storage}, protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}, @@ -16,61 +20,153 @@ contract FPC { #[storage] struct Storage { - settings: PublicImmutable, + config: PublicImmutable, } + /// Initializes the contract with an accepted asset (AA) and an admin (address that can pull accumulated AA funds + /// from this contract). #[public] #[initializer] - fn constructor(other_asset: AztecAddress, admin: AztecAddress) { - let settings = Settings { other_asset, admin }; - storage.settings.initialize(settings); + fn constructor(accepted_asset: AztecAddress, admin: AztecAddress) { + let config = Config { accepted_asset, admin }; + storage.config.initialize(config); } + /// Pays for the tx fee with msg_sender's private balance of accepted asset (AA). The maximum fee a user is willing + /// to pay is defined by `max_fee` and is denominated in AA. + /// + /// ## Overview + /// Uses partial notes to implement a refund flow which works as follows: + /// Setup Phase: + /// 1. This `setup_refund` function: + /// - Calls the AA token contract, which: + /// - subtracts the `max_fee` from the user's balance; + /// - prepares a partial note for the user (which will be used to later refund the user any unspent fee); + /// - sets a public teardown function (within the same AA token contract), where at the end of the tx + /// a fee (denominated in AA) will be transferred to the FPC in public, and a partial note will be finalized + /// with the refund amount (also denominated in AA). + /// - Sets itself as the `fee_payer` of the tx; meaning this contract will be responsible for ultimately + /// transferring the `tx_fee` -- denominated in fee juice -- to the protocol, during the later "teardown" + /// phase of this tx. + /// + /// Execution Phase: + /// 2. Then the private and public functions of the tx get executed. + /// + /// Teardown Phase: + /// 3. By this point, the protocol has computed the `tx_fee` (denominated in "fee juice"). So now we can + /// execute the "teardown function" which was lined-up during the earlier "setup phase". + /// Within the teardown function, we: + /// - compute how much of the `max_fee` (denominated in AA) the user needs to pay to the FPC, + /// and how much of it will be refunded back to the user. Since the protocol-calculated `tx_fee` is + /// denominated in fee juice, and not in this FPC's AA, an equivalent value of AA is computed based + /// on an exchange rate between AA and fee juice. + /// - finalize the refund note with a value of `max_fee - tx_fee` for the user; + /// - send the tx fee to the FPC in public. + /// + /// Protocol-enshrined fee-payment phase: + /// 4. The protocol deducts the protocol-calculated `tx_fee` (denominated in fee juice) from the `fee_payer`'s + /// balance (which in this case is this FPC's balance), which is a special storage slot in a protocol-controlled + /// "fee juice" contract. + /// + /// With this scheme a user has privately paid for the tx fee with an arbitrary AA (e.g. could be a stablecoin), + /// by paying this FPC. This FPC has in turn paid the protocol-mandated `tx_fee` (denominated in fee + /// juice). + /// + /// ***Note:*** + /// This flow allows us to pay for the tx with msg_sender's private balance of AA and hence msg_sender's identity + /// is not revealed. We do, however, reveal: + /// - the `max_fee`; + /// - which FPC has been used to make the payment; + /// - the asset which was used to make the payment. #[private] - fn fee_entrypoint_private(amount: Field, asset: AztecAddress, nonce: Field) { + fn fee_entrypoint_private(max_fee: Field, nonce: Field) { // TODO(PR #8022): Once PublicImmutable performs only 1 merkle proof here, we'll save ~4k gates - let settings = storage.settings.read(); + let config = storage.config.read(); - assert(asset == settings.other_asset); - - Token::at(asset).setup_refund(settings.admin, context.msg_sender(), amount, nonce).call( + Token::at(config.accepted_asset).setup_refund(context.msg_sender(), max_fee, nonce).call( &mut context, ); context.set_as_fee_payer(); } + /// Pays for the tx fee with msg_sender's public balance of accepted asset (AA). The maximum fee a user is willing + /// to pay is defined by `max_fee` and is denominated in AA. + /// + /// ## Overview + /// The refund flow works as follows: + /// Setup phase: + /// 1. This `fee_entrypoint_public` function: + /// - Transfers the `max_fee` from the user's balance of the accepted asset to this contract. + /// - Sets itself as the `fee_payer` of the tx. + /// - Sets a public teardown function in which the refund will be paid back to the user in public. + /// + /// Execution phase: + /// 2. Then the private and public functions of the tx get executed. + /// + /// Teardown phase: + /// 3. At this point we know the tx fee so we can compute how much of AA the user needs to pay to FPC and how much + /// of it will be refunded back. We send the refund back to the user in public. + /// + /// Protocol-enshrined fee-payment phase: + /// 4. The protocol deducts the actual fee denominated in fee juice from the FPC's balance. #[private] - fn fee_entrypoint_public(amount: Field, asset: AztecAddress, nonce: Field) { - FPC::at(context.this_address()) - .prepare_fee(context.msg_sender(), amount, asset, nonce) + fn fee_entrypoint_public(max_fee: Field, nonce: Field) { + // TODO(PR #8022): Once PublicImmutable performs only 1 merkle proof here, we'll save ~4k gates + let config = storage.config.read(); + + // We pull the max fee from the user's balance of the accepted asset to this contract. + // docs:start:public_call + Token::at(config.accepted_asset) + .transfer_in_public(context.msg_sender(), context.this_address(), max_fee, nonce) .enqueue(&mut context); + // docs:end:public_call + context.set_as_fee_payer(); // TODO(#6277) for improving interface: - // FPC::at(context.this_address()).pay_refund(context.msg_sender(), amount, asset).set_public_teardown_function(&mut context); + // FPC::at(context.this_address()).pay_refund(...).set_public_teardown_function(&mut context); context.set_public_teardown_function( context.this_address(), comptime { FunctionSelector::from_signature("pay_refund((Field),Field,(Field))") }, - [context.msg_sender().to_field(), amount, asset.to_field()], + [context.msg_sender().to_field(), max_fee, config.accepted_asset.to_field()], ); } + /// Pays the refund to the `refund_recipient`. The refund is the difference between the `max_fee` and + /// the actual fee. `accepted_asset` is the asset in which the refund is paid. It's passed as an argument + /// to avoid the need for another read from public storage. #[public] #[internal] - fn prepare_fee(from: AztecAddress, amount: Field, asset: AztecAddress, nonce: Field) { - // docs:start:public_call - Token::at(asset).transfer_in_public(from, context.this_address(), amount, nonce).call( - &mut context, - ); - // docs:end:public_call + fn pay_refund(refund_recipient: AztecAddress, max_fee: Field, accepted_asset: AztecAddress) { + let actual_fee = context.transaction_fee(); + assert(!max_fee.lt(actual_fee), "Max fee paid to the paymaster does not cover actual fee"); + // TODO(#10805): Introduce a real exchange rate + let refund = max_fee - actual_fee; + + Token::at(accepted_asset) + .transfer_in_public(context.this_address(), refund_recipient, refund, 0) + .call(&mut context); } + /// Pulls all the accepted asset funds from this contract to the `to` address. Only the admin can call + /// this function. #[public] - #[internal] - fn pay_refund(refund_address: AztecAddress, amount: Field, asset: AztecAddress) { - // Just do public refunds for the present - let refund = compute_rebate(context, amount); - Token::at(asset).transfer_in_public(context.this_address(), refund_address, refund, 0).call( - &mut context, - ); + fn pull_funds(to: AztecAddress) { + // TODO(PR #8022): Once PublicImmutable performs only 1 merkle proof here, we'll save ~4k gates + let config = storage.config.read(); + + assert(context.msg_sender() == config.admin, "Only admin can pull funds"); + + let token = Token::at(config.accepted_asset); + + // We send the full balance to `to`. + let balance = token.balance_of_public(context.this_address()).view(&mut context); + token.transfer_in_public(context.this_address(), to, balance, 0).call(&mut context); + } + + /// Note: Not marked as view as we need it to be callable as an entrypoint since in some places we need to obtain + /// this value before we have access to an account contract (kernels do not allow for static entrypoints). + #[private] + fn get_accepted_asset() -> AztecAddress { + storage.config.read().accepted_asset } } diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/settings.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/settings.nr deleted file mode 100644 index c3717ca1a7e..00000000000 --- a/noir-projects/noir-contracts/contracts/fpc_contract/src/settings.nr +++ /dev/null @@ -1,23 +0,0 @@ -use dep::aztec::protocol_types::{address::AztecAddress, traits::{Deserialize, Serialize}}; - -global SETTINGS_LENGTH: u32 = 2; - -pub struct Settings { - other_asset: AztecAddress, - admin: AztecAddress, -} - -impl Serialize for Settings { - fn serialize(self: Self) -> [Field; SETTINGS_LENGTH] { - [self.other_asset.to_field(), self.admin.to_field()] - } -} - -impl Deserialize for Settings { - fn deserialize(fields: [Field; SETTINGS_LENGTH]) -> Self { - Settings { - other_asset: AztecAddress::from_field(fields[0]), - admin: AztecAddress::from_field(fields[1]), - } - } -} diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr index 22d12012c5a..109fe6a57f4 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr @@ -152,7 +152,7 @@ contract NFT { // We prepare the private balance increase. let hiding_point_slot = _prepare_private_balance_increase(to, &mut context, storage); - // At last we finalize the transfer. Usafe of the `unsafe` method here is safe because we set the `from` + // At last we finalize the transfer. Usage of the `unsafe` method here is safe because we set the `from` // function argument to a message sender, guaranteeing that he can transfer only his own NFTs. nft._finalize_transfer_to_private_unsafe(from, token_id, hiding_point_slot).enqueue( &mut context, diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr index 642244cf251..f1ec6266f7e 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr @@ -505,6 +505,9 @@ contract Token { // docs:end:finalize_transfer_to_private // docs:start:finalize_transfer_to_private_unsafe + /// This is a wrapper around `_finalize_transfer_to_private` placed here so that a call + /// to `_finalize_transfer_to_private` can be enqueued. Called unsafe as it does not check `from` (this has to be + /// done in the calling function). #[public] #[internal] fn _finalize_transfer_to_private_unsafe( @@ -541,7 +544,7 @@ contract Token { // docs:start:mint_to_private /// Mints token `amount` to a private balance of `to`. Message sender has to have minter permissions (checked - /// in the enqueud call). + /// in the enqueued call). #[private] fn mint_to_private( from: AztecAddress, // sender of the tag: TODO(#9887): this is not great? @@ -613,64 +616,44 @@ contract Token { finalization_payload.emit(); } - /// We need to use different randomness for the user and for the fee payer notes because if the randomness values - /// were the same we could fingerprint the user by doing the following: - /// 1) randomness_influence = fee_payer_point - G_npk * fee_payer_npk = - /// = (G_npk * fee_payer_npk + G_rnd * randomness + G_slot * fee_payer_slot) - /// - G_npk * fee_payer_npk - G_slot * fee_payer_slot = - /// = G_rnd * randomness - /// 2) user_fingerprint = user_point - randomness_influence = - /// = (G_npk * user_npk + G_rnd * randomness + G_slot * user_slot) - G_rnd * randomness = - /// = G_npk * user_npk + G_slot * user_slot - /// 3) Then the second time the user would use this fee paying contract we would recover the same fingerprint - /// and link that the 2 transactions were made by the same user. Given that it's expected that only - /// a limited set of fee paying contracts will be used and they will be known, searching for fingerprints - /// by trying different fee payers is a feasible attack. - /// - /// Note 1: fee_payer_npk is part of the fee_payer address preimage derivation, and is assumed to be known. So - // if we have a known set of fee payer contract addresses getting fee_payer_npk and fee_payer_slot is - // trivial (slot is derived in a `Map<...>` as a hash of balances map slot and a fee payer address). - /// Note 2: fee_payer_point and user_point above are public information because they are passed as args to - /// the public `complete_refund(...)` function. // docs:start:setup_refund + /// Called by fee payer contract (FPC) to set up a refund for a user during the private fee payment flow. #[private] fn setup_refund( - fee_payer: AztecAddress, // Address of the entity which will receive the fee note. user: AztecAddress, // A user for which we are setting up the fee refund. - funded_amount: Field, // The amount the user funded the fee payer with (represents fee limit). + max_fee: Field, // The maximum fee a user is willing to pay for the tx. nonce: Field, // A nonce to make authwitness unique. ) { - // 1. This function is called by fee paying contract (fee_payer) when setting up a refund so we need to support - // the authwit flow here and check that the user really permitted fee_payer to set up a refund on their behalf. + // 1. This function is called by FPC when setting up a refund so we need to support the authwit flow here + // and check that the user really permitted fee_recipient to set up a refund on their behalf. assert_current_call_valid_authwit(&mut context, user); - // 3. Deduct the funded amount from the user's balance - this is a maximum fee a user is willing to pay - // (called fee limit in aztec spec). The difference between fee limit and the actual tx fee will be refunded - // to the user in the `complete_refund(...)` function. + // 2. Deduct the max fee from user's balance. The difference between max fee and the actual tx fee will + // be refunded to the user in the `complete_refund(...)` function. let change = subtract_balance( &mut context, storage, user, - U128::from_integer(funded_amount), + U128::from_integer(max_fee), INITIAL_TRANSFER_CALL_MAX_NOTES, ); + // Emit the change note. storage.balances.at(user).add(user, change).emit(encode_and_encrypt_note_unconstrained( &mut context, user, user, )); - // 4. We prepare the partial notes - let fee_payer_point_slot = - _prepare_private_balance_increase(user, fee_payer, &mut context, storage); + // 3. Prepare the partial note for the refund. let user_point_slot = _prepare_private_balance_increase(user, user, &mut context, storage); - // 5. Set the public teardown function to `complete_refund(...)`. Public teardown is the only time when a public + // 4. Set the public teardown function to `complete_refund(...)`. Public teardown is the only time when a public // function has access to the final transaction fee, which is needed to compute the actual refund amount. + let fee_recipient = context.msg_sender(); // FPC is the fee recipient. context.set_public_teardown_function( context.this_address(), - comptime { FunctionSelector::from_signature("complete_refund(Field,Field,Field)") }, - [fee_payer_point_slot, user_point_slot, funded_amount], + comptime { FunctionSelector::from_signature("complete_refund((Field),Field,Field)") }, + [fee_recipient.to_field(), user_point_slot, max_fee], ); } // docs:end:setup_refund @@ -691,32 +674,34 @@ contract Token { context.storage_write(slot + aztec::protocol_types::point::POINT_LENGTH as Field, setup_log); } - // TODO(#7728): even though the funded_amount should be a U128, we can't have that type in a contract interface due + // TODO(#7728): even though the max_fee should be a U128, we can't have that type in a contract interface due // to serialization issues. // docs:start:complete_refund + /// Executed as a public teardown function and is responsible for completing the refund in a private fee payment + /// flow. #[public] #[internal] - fn complete_refund(fee_payer_slot: Field, user_slot: Field, funded_amount: Field) { + fn complete_refund(fee_recipient: AztecAddress, user_slot: Field, max_fee: Field) { // TODO(#7728): Remove the next line - let funded_amount = U128::from_integer(funded_amount); + let max_fee = U128::from_integer(max_fee); let tx_fee = U128::from_integer(context.transaction_fee()); // 1. We check that user funded the fee payer contract with at least the transaction fee. // TODO(#7796): we should try to prevent reverts here - assert(funded_amount >= tx_fee, "funded amount not enough to cover tx fee"); + assert(max_fee >= tx_fee, "max fee not enough to cover tx fee"); + + // 2. We compute the refund amount as the difference between funded amount and the tx fee. + // TODO(#10805): Introduce a real exchange rate + let refund_amount = max_fee - tx_fee; - // 2. We compute the refund amount as the difference between funded amount and tx fee. - let refund_amount = funded_amount - tx_fee; + // 3. We send the tx fee to the fee recipient in public. + _increase_public_balance_inner(fee_recipient, tx_fee.to_field(), storage); - // 3. We construct the note finalization payloads with the correct amounts and hiding points to get the note - // hashes and unencrypted logs. - let fee_payer_finalization_payload = - UintNote::finalization_payload().new(&mut context, fee_payer_slot, tx_fee); + // 4. We construct the user note finalization payload with the refund amount. let user_finalization_payload = UintNote::finalization_payload().new(&mut context, user_slot, refund_amount); - // 4. At last we emit the note hashes and the final note logs. - fee_payer_finalization_payload.emit(); + // 5. At last we emit the user finalization note hash and the corresponding note log. user_finalization_payload.emit(); // --> Once the tx is settled user and fee recipient can add the notes to their pixies. } @@ -724,13 +709,24 @@ contract Token { /// Internal /// // docs:start:increase_public_balance + /// TODO(#9180): Consider adding macro support for functions callable both as an entrypoint and as an internal + /// function. #[public] #[internal] fn _increase_public_balance(to: AztecAddress, amount: Field) { + _increase_public_balance_inner(to, amount, storage); + } + // docs:end:increase_public_balance + + #[contract_library_method] + fn _increase_public_balance_inner( + to: AztecAddress, + amount: Field, + storage: Storage<&mut PublicContext>, + ) { let new_balance = storage.public_balances.at(to).read().add(U128::from_integer(amount)); storage.public_balances.at(to).write(new_balance); } - // docs:end:increase_public_balance // docs:start:reduce_total_supply #[public] diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/test/refunds.nr b/noir-projects/noir-contracts/contracts/token_contract/src/test/refunds.nr index d8797b3ac8c..5e01965e8a2 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/test/refunds.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/test/refunds.nr @@ -34,7 +34,7 @@ unconstrained fn setup_refund_success() { let _ = OracleMock::mock("getRandomField").returns(fee_payer_randomness); let setup_refund_from_call_interface = - Token::at(token_contract_address).setup_refund(fee_payer, user, funded_amount, nonce); + Token::at(token_contract_address).setup_refund(user, funded_amount, nonce); authwit_cheatcodes::add_private_authwit_from_call_interface( user, @@ -71,7 +71,7 @@ unconstrained fn setup_refund_success() { // This test should be reworked when final support for partial notes is in // Once that happens, the expected error message is commented out below -//#[test(should_fail_with="funded amount not enough to cover tx fee")] +//#[test(should_fail_with="max fee not enough to cover tx fee")] #[test(should_fail_with = "Balance too low")] unconstrained fn setup_refund_insufficient_funded_amount() { let (env, token_contract_address, owner, recipient, _mint_amount) = @@ -86,7 +86,7 @@ unconstrained fn setup_refund_insufficient_funded_amount() { let nonce = random(); let setup_refund_from_call_interface = - Token::at(token_contract_address).setup_refund(fee_payer, user, funded_amount, nonce); + Token::at(token_contract_address).setup_refund(user, funded_amount, nonce); authwit_cheatcodes::add_private_authwit_from_call_interface( user, @@ -96,6 +96,6 @@ unconstrained fn setup_refund_insufficient_funded_amount() { env.impersonate(fee_payer); - // The following should fail with "funded amount not enough to cover tx fee" because funded amount is 0 + // The following should fail with "max fee not enough to cover tx fee" because funded amount is 0 setup_refund_from_call_interface.call(&mut env.private()) } diff --git a/noir-projects/noir-contracts/scripts/flamegraph.sh b/noir-projects/noir-contracts/scripts/flamegraph.sh index 8db540142e6..ca5ae33c18b 100755 --- a/noir-projects/noir-contracts/scripts/flamegraph.sh +++ b/noir-projects/noir-contracts/scripts/flamegraph.sh @@ -63,10 +63,10 @@ FUNCTION_ARTIFACT="${ARTIFACT_NAME}-${FUNCTION}.json" mkdir -p "$SCRIPT_DIR/../dest" # At last, generate the flamegraph -$PROFILER gates-flamegraph --artifact-path "$SCRIPT_DIR/../target/$FUNCTION_ARTIFACT" --backend-path "$SCRIPT_DIR/../../../barretenberg/cpp/build/bin/bb" --backend-gates-command "gates_mega_honk" --output "$SCRIPT_DIR/../dest" +$PROFILER gates --artifact-path "$SCRIPT_DIR/../target/$FUNCTION_ARTIFACT" --backend-path "$SCRIPT_DIR/../../../barretenberg/cpp/build/bin/bb" --backend-gates-command "gates_mega_honk" --output "$SCRIPT_DIR/../dest" # serve the file over http -echo "Serving flamegraph at http://0.0.0.0:8000/main_gates.svg" +echo "Serving flamegraph at http://0.0.0.0:8000/main::gates.svg" python3 -m http.server --directory "$SCRIPT_DIR/../dest" 8000 # Clean up before exiting 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 71117bdf280..35d2231522d 100644 --- a/yarn-project/aztec.js/src/contract/contract_function_interaction.ts +++ b/yarn-project/aztec.js/src/contract/contract_function_interaction.ts @@ -103,13 +103,20 @@ export class ContractFunctionInteraction extends BaseContractInteraction { const txRequest = await this.create(); const simulatedTx = await this.wallet.simulateTx(txRequest, true, options?.from, options?.skipTxValidation); - // As account entrypoints are private, for private functions we retrieve the return values from the first nested call - // since we're interested in the first set of values AFTER the account entrypoint - // For public functions we retrieve the first values directly from the public output. - const rawReturnValues = - this.functionDao.functionType == FunctionType.PRIVATE - ? simulatedTx.getPrivateReturnValues().nested?.[0].values - : simulatedTx.getPublicReturnValues()?.[0].values; + let rawReturnValues; + if (this.functionDao.functionType == FunctionType.PRIVATE) { + if (simulatedTx.getPrivateReturnValues().nested.length > 0) { + // The function invoked is private and it was called via an account contract + // TODO(#10631): There is a bug here: this branch might be triggered when there is no-account contract as well + rawReturnValues = simulatedTx.getPrivateReturnValues().nested[0].values; + } else { + // The function invoked is private and it was called directly (without account contract) + rawReturnValues = simulatedTx.getPrivateReturnValues().values; + } + } else { + // For public functions we retrieve the first values directly from the public output. + rawReturnValues = simulatedTx.getPublicReturnValues()?.[0].values; + } return rawReturnValues ? decodeFromAbi(this.functionDao.returnTypes, rawReturnValues) : []; } diff --git a/yarn-project/aztec.js/src/fee/fee_juice_payment_method.ts b/yarn-project/aztec.js/src/fee/fee_juice_payment_method.ts index 94a3dc954ba..c5a8edfad28 100644 --- a/yarn-project/aztec.js/src/fee/fee_juice_payment_method.ts +++ b/yarn-project/aztec.js/src/fee/fee_juice_payment_method.ts @@ -11,7 +11,7 @@ export class FeeJuicePaymentMethod implements FeePaymentMethod { constructor(protected sender: AztecAddress) {} getAsset() { - return ProtocolContractAddress.FeeJuice; + return Promise.resolve(ProtocolContractAddress.FeeJuice); } getFunctionCalls(): Promise { diff --git a/yarn-project/aztec.js/src/fee/fee_payment_method.ts b/yarn-project/aztec.js/src/fee/fee_payment_method.ts index c27710efedb..6cdf795cd56 100644 --- a/yarn-project/aztec.js/src/fee/fee_payment_method.ts +++ b/yarn-project/aztec.js/src/fee/fee_payment_method.ts @@ -7,7 +7,7 @@ import { type AztecAddress } from '@aztec/foundation/aztec-address'; */ export interface FeePaymentMethod { /** The asset used to pay the fee. */ - getAsset(): AztecAddress; + getAsset(): Promise; /** * Creates a function call to pay the fee in the given asset. * @param gasSettings - The gas limits and max fees. diff --git a/yarn-project/aztec.js/src/fee/no_fee_payment_method.ts b/yarn-project/aztec.js/src/fee/no_fee_payment_method.ts index e9ed5809bc7..3692e990328 100644 --- a/yarn-project/aztec.js/src/fee/no_fee_payment_method.ts +++ b/yarn-project/aztec.js/src/fee/no_fee_payment_method.ts @@ -10,7 +10,7 @@ export class NoFeePaymentMethod implements FeePaymentMethod { constructor() {} getAsset() { - return AztecAddress.ZERO; + return Promise.resolve(AztecAddress.ZERO); } getFunctionCalls(): Promise { diff --git a/yarn-project/aztec.js/src/fee/private_fee_payment_method.ts b/yarn-project/aztec.js/src/fee/private_fee_payment_method.ts index e505901da36..717f5aec04d 100644 --- a/yarn-project/aztec.js/src/fee/private_fee_payment_method.ts +++ b/yarn-project/aztec.js/src/fee/private_fee_payment_method.ts @@ -5,17 +5,17 @@ import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { type Wallet } from '../account/wallet.js'; +import { ContractFunctionInteraction } from '../contract/contract_function_interaction.js'; +import { SignerlessWallet } from '../wallet/signerless_wallet.js'; import { type FeePaymentMethod } from './fee_payment_method.js'; /** * Holds information about how the fee for a transaction is to be paid. */ export class PrivateFeePaymentMethod implements FeePaymentMethod { + private assetPromise: Promise | null = null; + constructor( - /** - * The asset used to pay the fee. - */ - private asset: AztecAddress, /** * Address which will hold the fee payment. */ @@ -26,11 +26,6 @@ export class PrivateFeePaymentMethod implements FeePaymentMethod { */ private wallet: Wallet, - /** - * Address that the FPC sends notes it receives to. - */ - private feeRecipient: AztecAddress, - /** * If true, the max fee will be set to 1. * TODO(#7694): Remove this param once the lacking feature in TXE is implemented. @@ -42,8 +37,43 @@ export class PrivateFeePaymentMethod implements FeePaymentMethod { * The asset used to pay the fee. * @returns The asset used to pay the fee. */ - getAsset() { - return this.asset; + getAsset(): Promise { + if (!this.assetPromise) { + // We use signer-less wallet because this function could be triggered before the associated account is deployed. + const signerlessWallet = new SignerlessWallet(this.wallet); + + const interaction = new ContractFunctionInteraction( + signerlessWallet, + this.paymentContract, + { + name: 'get_accepted_asset', + functionType: FunctionType.PRIVATE, + isInternal: false, + isStatic: false, + parameters: [], + returnTypes: [ + { + kind: 'struct', + path: 'authwit::aztec::protocol_types::address::aztec_address::AztecAddress', + fields: [ + { + name: 'inner', + type: { + kind: 'field', + }, + }, + ], + }, + ], + errorTypes: {}, + isInitializer: false, + }, + [], + ); + + this.assetPromise = interaction.simulate(); + } + return this.assetPromise!; } getFeePayer(): Promise { @@ -65,11 +95,11 @@ export class PrivateFeePaymentMethod implements FeePaymentMethod { caller: this.paymentContract, action: { name: 'setup_refund', - args: [this.feeRecipient.toField(), this.wallet.getAddress().toField(), maxFee, nonce], - selector: FunctionSelector.fromSignature('setup_refund((Field),(Field),Field,Field)'), + args: [this.wallet.getAddress().toField(), maxFee, nonce], + selector: FunctionSelector.fromSignature('setup_refund((Field),Field,Field)'), type: FunctionType.PRIVATE, isStatic: false, - to: this.asset, + to: await this.getAsset(), returnTypes: [], }, }); @@ -78,10 +108,10 @@ export class PrivateFeePaymentMethod implements FeePaymentMethod { { name: 'fee_entrypoint_private', to: this.paymentContract, - selector: FunctionSelector.fromSignature('fee_entrypoint_private(Field,(Field),Field)'), + selector: FunctionSelector.fromSignature('fee_entrypoint_private(Field,Field)'), type: FunctionType.PRIVATE, isStatic: false, - args: [maxFee, this.asset.toField(), nonce], + args: [maxFee, nonce], returnTypes: [], }, ]; diff --git a/yarn-project/aztec.js/src/fee/public_fee_payment_method.ts b/yarn-project/aztec.js/src/fee/public_fee_payment_method.ts index 144e307d7ea..fddcf5e8daf 100644 --- a/yarn-project/aztec.js/src/fee/public_fee_payment_method.ts +++ b/yarn-project/aztec.js/src/fee/public_fee_payment_method.ts @@ -4,18 +4,18 @@ import { FunctionSelector, FunctionType } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; +import { ContractFunctionInteraction } from '../contract/contract_function_interaction.js'; import { type AccountWallet } from '../wallet/account_wallet.js'; +import { SignerlessWallet } from '../wallet/signerless_wallet.js'; import { type FeePaymentMethod } from './fee_payment_method.js'; /** * Holds information about how the fee for a transaction is to be paid. */ export class PublicFeePaymentMethod implements FeePaymentMethod { + private assetPromise: Promise | null = null; + constructor( - /** - * The asset used to pay the fee. - */ - protected asset: AztecAddress, /** * Address which will hold the fee payment. */ @@ -30,8 +30,43 @@ export class PublicFeePaymentMethod implements FeePaymentMethod { * The asset used to pay the fee. * @returns The asset used to pay the fee. */ - getAsset() { - return this.asset; + getAsset(): Promise { + if (!this.assetPromise) { + // We use signer-less wallet because this function could be triggered before the associated account is deployed. + const signerlessWallet = new SignerlessWallet(this.wallet); + + const interaction = new ContractFunctionInteraction( + signerlessWallet, + this.paymentContract, + { + name: 'get_accepted_asset', + functionType: FunctionType.PRIVATE, + isInternal: false, + isStatic: false, + parameters: [], + returnTypes: [ + { + kind: 'struct', + path: 'authwit::aztec::protocol_types::address::aztec_address::AztecAddress', + fields: [ + { + name: 'inner', + type: { + kind: 'field', + }, + }, + ], + }, + ], + errorTypes: {}, + isInitializer: false, + }, + [], + ); + + this.assetPromise = interaction.simulate(); + } + return this.assetPromise!; } getFeePayer(): Promise { @@ -43,7 +78,7 @@ export class PublicFeePaymentMethod implements FeePaymentMethod { * @param gasSettings - The gas settings. * @returns The function call to pay the fee. */ - getFunctionCalls(gasSettings: GasSettings): Promise { + async getFunctionCalls(gasSettings: GasSettings): Promise { const nonce = Fr.random(); const maxFee = gasSettings.getFeeLimit(); @@ -58,7 +93,7 @@ export class PublicFeePaymentMethod implements FeePaymentMethod { selector: FunctionSelector.fromSignature('transfer_in_public((Field),(Field),Field,Field)'), type: FunctionType.PUBLIC, isStatic: false, - to: this.asset, + to: await this.getAsset(), returnTypes: [], }, }, @@ -68,10 +103,10 @@ export class PublicFeePaymentMethod implements FeePaymentMethod { { name: 'fee_entrypoint_public', to: this.paymentContract, - selector: FunctionSelector.fromSignature('fee_entrypoint_public(Field,(Field),Field)'), + selector: FunctionSelector.fromSignature('fee_entrypoint_public(Field,Field)'), type: FunctionType.PRIVATE, isStatic: false, - args: [maxFee, this.asset.toField(), nonce], + args: [maxFee, nonce], returnTypes: [], }, ]); diff --git a/yarn-project/circuits.js/src/contract/contract_class.ts b/yarn-project/circuits.js/src/contract/contract_class.ts index 8809a2bbe02..78c49020d92 100644 --- a/yarn-project/circuits.js/src/contract/contract_class.ts +++ b/yarn-project/circuits.js/src/contract/contract_class.ts @@ -35,7 +35,7 @@ export function getContractClassFromArtifact( ); if (!dispatchFunction) { throw new Error( - 'A contract with public functions should define a public_dispatch(Field) function as its public entrypoint.', + `A contract with public functions should define a public_dispatch(Field) function as its public entrypoint. Contract: ${artifact.name}`, ); } packedBytecode = dispatchFunction.bytecode; diff --git a/yarn-project/cli-wallet/src/utils/options/fees.ts b/yarn-project/cli-wallet/src/utils/options/fees.ts index 829a2c8c67b..fbb6afb53ad 100644 --- a/yarn-project/cli-wallet/src/utils/options/fees.ts +++ b/yarn-project/cli-wallet/src/utils/options/fees.ts @@ -135,15 +135,10 @@ export function parsePaymentMethod( if (!parsed.asset) { throw new Error('Missing "asset" in payment option'); } - if (!parsed.feeRecipient) { - // Recipient of a fee in the refund flow - throw new Error('Missing "feeRecipient" in payment option'); - } const fpc = aliasedAddressParser('contracts', parsed.fpc, db); - const feeRecipient = AztecAddress.fromString(parsed.feeRecipient); - return [AztecAddress.fromString(parsed.asset), fpc, feeRecipient]; + return [AztecAddress.fromString(parsed.asset), fpc]; }; return async (sender: AccountWallet) => { @@ -182,13 +177,13 @@ export function parsePaymentMethod( const [asset, fpc] = getFpcOpts(parsed, db); log(`Using public fee payment with asset ${asset} via paymaster ${fpc}`); const { PublicFeePaymentMethod } = await import('@aztec/aztec.js/fee'); - return new PublicFeePaymentMethod(asset, fpc, sender); + return new PublicFeePaymentMethod(fpc, sender); } case 'fpc-private': { - const [asset, fpc, feeRecipient] = getFpcOpts(parsed, db); - log(`Using private fee payment with asset ${asset} via paymaster ${fpc} with rebate secret ${feeRecipient}`); + const [asset, fpc] = getFpcOpts(parsed, db); + log(`Using private fee payment with asset ${asset} via paymaster ${fpc}`); const { PrivateFeePaymentMethod } = await import('@aztec/aztec.js/fee'); - return new PrivateFeePaymentMethod(asset, fpc, sender, feeRecipient); + return new PrivateFeePaymentMethod(fpc, sender); } case undefined: throw new Error('Missing "method" in payment option'); diff --git a/yarn-project/cli/src/cmds/devnet/bootstrap_network.ts b/yarn-project/cli/src/cmds/devnet/bootstrap_network.ts index 9ba166fad9d..fe8059e0203 100644 --- a/yarn-project/cli/src/cmds/devnet/bootstrap_network.ts +++ b/yarn-project/cli/src/cmds/devnet/bootstrap_network.ts @@ -61,8 +61,8 @@ export async function bootstrapNetwork( await initPortal(pxe, l1Clients, erc20Address, portalAddress, bridge.address); - const feeRecipient = wallet.getAddress(); - const fpc = await deployFPC(wallet, token.address, feeRecipient); + const fpcAdmin = wallet.getAddress(); + const fpc = await deployFPC(wallet, token.address, fpcAdmin); const counter = await deployCounter(wallet); // NOTE: Disabling for now in order to get devnet running @@ -222,14 +222,12 @@ async function initPortal( async function deployFPC( wallet: Wallet, tokenAddress: AztecAddress, - feeRecipient: AztecAddress, + admin: AztecAddress, ): Promise { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - Importing noir-contracts.js even in devDeps results in a circular dependency error. Need to ignore because this line doesn't cause an error in a dev environment const { FPCContract } = await import('@aztec/noir-contracts.js/FPC'); - const fpc = await FPCContract.deploy(wallet, tokenAddress, feeRecipient) - .send({ universalDeploy: true }) - .deployed(waitOpts); + const fpc = await FPCContract.deploy(wallet, tokenAddress, admin).send({ universalDeploy: true }).deployed(waitOpts); const info: ContractDeploymentInfo = { address: fpc.address, initHash: fpc.instance.initializationHash, diff --git a/yarn-project/end-to-end/src/benchmarks/bench_prover.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_prover.test.ts index 5cfda3ff9d6..b4151bd06fa 100644 --- a/yarn-project/end-to-end/src/benchmarks/bench_prover.test.ts +++ b/yarn-project/end-to-end/src/benchmarks/bench_prover.test.ts @@ -204,13 +204,12 @@ describe('benchmarks/proving', () => { const feeFnCall0 = { gasSettings, - paymentMethod: new PublicFeePaymentMethod(initialTokenContract.address, initialFpContract.address, wallet), + paymentMethod: new PublicFeePaymentMethod(initialFpContract.address, wallet), }; // const feeFnCall1 = { // gasSettings, // paymentMethod: new PrivateFeePaymentMethod( - // initialTokenContract.address, // initialFpContract.address, // await getWalletOnPxe(1), // ), diff --git a/yarn-project/end-to-end/src/benchmarks/bench_tx_size_fees.test.ts b/yarn-project/end-to-end/src/benchmarks/bench_tx_size_fees.test.ts index a998193f7f8..02b8f858f30 100644 --- a/yarn-project/end-to-end/src/benchmarks/bench_tx_size_fees.test.ts +++ b/yarn-project/end-to-end/src/benchmarks/bench_tx_size_fees.test.ts @@ -49,7 +49,10 @@ describe('benchmarks/tx_size_fees', () => { beforeAll(async () => { feeJuice = await FeeJuiceContract.at(ProtocolContractAddress.FeeJuice, aliceWallet); token = await TokenContract.deploy(aliceWallet, aliceWallet.getAddress(), 'test', 'test', 18).send().deployed(); - fpc = await FPCContract.deploy(aliceWallet, token.address, sequencerAddress).send().deployed(); + + // We set Alice as the FPC admin to avoid the need for deployment of another account. + const fpcAdmin = aliceWallet.getAddress(); + fpc = await FPCContract.deploy(aliceWallet, token.address, fpcAdmin).send().deployed(); }); // mint tokens @@ -91,7 +94,7 @@ describe('benchmarks/tx_size_fees', () => { ], [ 'public fee', - () => new PublicFeePaymentMethod(token.address, fpc.address, aliceWallet), + () => new PublicFeePaymentMethod(fpc.address, aliceWallet), // DA: // non-rev: 1 nullifiers, overhead; rev: 2 note hashes, 1 nullifier, 1168 B enc note logs, 0 B enc logs,0 B unenc logs, teardown // L2: @@ -100,7 +103,7 @@ describe('benchmarks/tx_size_fees', () => { ], [ 'private fee', - () => new PrivateFeePaymentMethod(token.address, fpc.address, aliceWallet, sequencerAddress), + () => new PrivateFeePaymentMethod(fpc.address, aliceWallet), // DA: // non-rev: 3 nullifiers, overhead; rev: 2 note hashes, 1168 B enc note logs, 0 B enc logs, 0 B unenc logs, teardown // L2: diff --git a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts index f4464e972c4..e997538a6d1 100644 --- a/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/account_init.test.ts @@ -66,13 +66,11 @@ describe('e2e_fees account_init', () => { // Seeded by initBalances below in a beforeEach hook let fpcsInitialGas: bigint; let fpcsInitialPublicBananas: bigint; - let sequencerInitialPrivateBananas: bigint; async function initBalances() { - [[fpcsInitialGas], [fpcsInitialPublicBananas], [sequencerInitialPrivateBananas]] = await Promise.all([ + [[fpcsInitialGas], [fpcsInitialPublicBananas]] = await Promise.all([ t.getGasBalanceFn(bananaFPC.address), t.getBananaPublicBalanceFn(bananaFPC.address), - t.getBananaPrivateBalanceFn(t.sequencerAddress), ]); } @@ -117,12 +115,7 @@ describe('e2e_fees account_init', () => { await t.mintPrivateBananas(mintedBananas, bobsAddress); // Bob deploys his account through the private FPC - const paymentMethod = new PrivateFeePaymentMethod( - bananaCoin.address, - bananaFPC.address, - await bobsAccountManager.getWallet(), - t.sequencerAddress, // Sequencer is the recipient of the refund fee notes because it's the FPC admin. - ); + const paymentMethod = new PrivateFeePaymentMethod(bananaFPC.address, await bobsAccountManager.getWallet()); const tx = await bobsAccountManager.deploy({ fee: { gasSettings, paymentMethod } }).wait(); const actualFee = tx.transactionFee!; @@ -132,8 +125,8 @@ describe('e2e_fees account_init', () => { await expect(t.getBananaPrivateBalanceFn(bobsAddress)).resolves.toEqual([mintedBananas - actualFee]); // the FPC admin (set to sequencer) got the banana fee note so his private balance should have increased by the actual fee - await expect(t.getBananaPrivateBalanceFn(t.sequencerAddress)).resolves.toEqual([ - sequencerInitialPrivateBananas + actualFee, + await expect(t.getBananaPublicBalanceFn(t.bananaFPC.address)).resolves.toEqual([ + fpcsInitialPublicBananas + actualFee, ]); // the FPC should have been the fee payer @@ -144,7 +137,7 @@ describe('e2e_fees account_init', () => { const mintedBananas = FEE_FUNDING_FOR_TESTER_ACCOUNT; await bananaCoin.methods.mint_to_public(bobsAddress, mintedBananas).send().wait(); - const paymentMethod = new PublicFeePaymentMethod(bananaCoin.address, bananaFPC.address, bobsWallet); + const paymentMethod = new PublicFeePaymentMethod(bananaFPC.address, bobsWallet); const tx = await bobsAccountManager .deploy({ skipPublicDeployment: false, diff --git a/yarn-project/end-to-end/src/e2e_fees/dapp_subscription.test.ts b/yarn-project/end-to-end/src/e2e_fees/dapp_subscription.test.ts index 262272d194c..d3bd333d2e7 100644 --- a/yarn-project/end-to-end/src/e2e_fees/dapp_subscription.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/dapp_subscription.test.ts @@ -26,7 +26,6 @@ describe('e2e_fees dapp_subscription', () => { let aliceAddress: AztecAddress; // Dapp subscriber. let bobAddress: AztecAddress; // Dapp owner. let sequencerAddress: AztecAddress; - let feeRecipient: AztecAddress; // Account that receives the fees from the fee refund flow. let bananaCoin: BananaCoin; let counterContract: CounterContract; @@ -59,9 +58,6 @@ describe('e2e_fees dapp_subscription', () => { counterContract, pxe, } = await t.setup()); - - // We like sequencer so we send him the fees. - feeRecipient = sequencerAddress; }); afterAll(async () => { @@ -112,9 +108,7 @@ describe('e2e_fees dapp_subscription', () => { the FPC finalizes the partial notes for the fee and the refund */ - const { transactionFee } = await subscribe( - new PrivateFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet, feeRecipient), - ); + const { transactionFee } = await subscribe(new PrivateFeePaymentMethod(bananaFPC.address, aliceWallet)); // We let Alice see Bob's notes because the expect uses Alice's wallet to interact with the contracts to "get" state. aliceWallet.setScopes([aliceAddress, bobAddress]); @@ -127,7 +121,7 @@ describe('e2e_fees dapp_subscription', () => { // alice, bob, fpc await expectBananasPrivateDelta(-t.SUBSCRIPTION_AMOUNT - transactionFee!, t.SUBSCRIPTION_AMOUNT, 0n); - await expectBananasPublicDelta(0n, 0n, 0n); + await expectBananasPublicDelta(0n, 0n, transactionFee!); // REFUND_AMOUNT is a transparent note note }); @@ -144,9 +138,7 @@ describe('e2e_fees dapp_subscription', () => { PUBLIC TEARDOWN the FPC finalizes the partial notes for the fee and the refund */ - const { transactionFee } = await subscribe( - new PublicFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet), - ); + const { transactionFee } = await subscribe(new PublicFeePaymentMethod(bananaFPC.address, aliceWallet)); await expectMapping( t.getGasBalanceFn, @@ -165,7 +157,7 @@ describe('e2e_fees dapp_subscription', () => { it('should call dapp subscription entrypoint', async () => { // Subscribe again, so this test does not depend on the previous ones being run. - await subscribe(new PrivateFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet, feeRecipient)); + await subscribe(new PrivateFeePaymentMethod(bananaFPC.address, aliceWallet)); expect(await subscriptionContract.methods.is_initialized(aliceAddress).simulate()).toBe(true); @@ -187,18 +179,14 @@ describe('e2e_fees dapp_subscription', () => { it('should reject after the sub runs out', async () => { // Subscribe again. This will overwrite the previous subscription. - await subscribe(new PrivateFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet, feeRecipient), 0); + await subscribe(new PrivateFeePaymentMethod(bananaFPC.address, aliceWallet), 0); // TODO(#6651): Change back to /(context.block_number()) as u64 < expiry_block_number as u64/ when fixed await expect(dappIncrement()).rejects.toThrow(/Note encrypted logs hash mismatch/); }); it('should reject after the txs run out', async () => { // Subscribe again. This will overwrite the previous subscription. - await subscribe( - new PrivateFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet, feeRecipient), - 5, - 1, - ); + await subscribe(new PrivateFeePaymentMethod(bananaFPC.address, aliceWallet), 5, 1); await expect(dappIncrement()).resolves.toBeDefined(); await expect(dappIncrement()).rejects.toThrow(/note.remaining_txs as u64 > 0/); }); diff --git a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts index 7efc18bc661..ecc938877dc 100644 --- a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts @@ -40,12 +40,11 @@ describe('e2e_fees failures', () => { const outrageousPublicAmountAliceDoesNotHave = t.ALICE_INITIAL_BANANAS * 5n; const privateMintedAlicePrivateBananas = t.ALICE_INITIAL_BANANAS; - const [initialAlicePrivateBananas, initialSequencerPrivateBananas] = await t.getBananaPrivateBalanceFn( - aliceAddress, - sequencerAddress, - ); + const [initialAlicePrivateBananas] = await t.getBananaPrivateBalanceFn(aliceAddress, sequencerAddress); const [initialAliceGas, initialFPCGas] = await t.getGasBalanceFn(aliceAddress, bananaFPC.address); + const [initialFPCPublicBananas] = await t.getBananaPublicBalanceFn(bananaFPC.address); + await t.mintPrivateBananas(privateMintedAlicePrivateBananas, aliceAddress); // if we simulate locally, it throws an error @@ -56,12 +55,7 @@ describe('e2e_fees failures', () => { .send({ fee: { gasSettings, - paymentMethod: new PrivateFeePaymentMethod( - bananaCoin.address, - bananaFPC.address, - aliceWallet, - t.sequencerAddress, - ), + paymentMethod: new PrivateFeePaymentMethod(bananaFPC.address, aliceWallet), }, }) .wait(), @@ -85,12 +79,7 @@ describe('e2e_fees failures', () => { skipPublicSimulation: true, fee: { gasSettings, - paymentMethod: new PrivateFeePaymentMethod( - bananaCoin.address, - bananaFPC.address, - aliceWallet, - t.sequencerAddress, - ), + paymentMethod: new PrivateFeePaymentMethod(bananaFPC.address, aliceWallet), }, }) .wait({ dontThrowOnRevert: true }); @@ -107,16 +96,19 @@ describe('e2e_fees failures', () => { // and thus we paid the fee await expectMapping( t.getBananaPrivateBalanceFn, - [aliceAddress, sequencerAddress], + [aliceAddress], [ // Even with the revert public teardown function got successfully executed so Alice received the refund note // and hence paid the actual fee. initialAlicePrivateBananas + privateMintedAlicePrivateBananas - feeAmount, - // Sequencer is the FPC admin/fee recipient and hence he should have received the fee amount note - initialSequencerPrivateBananas + feeAmount, ], ); + // FPC should have received the fee in public + await expect(t.getBananaPublicBalanceFn(t.bananaFPC.address)).resolves.toEqual([ + initialFPCPublicBananas + feeAmount, + ]); + // Gas balance of Alice should have stayed the same as the FPC paid the gas fee and not her (she paid bananas // to FPC admin). await expectMapping( @@ -152,7 +144,7 @@ describe('e2e_fees failures', () => { .send({ fee: { gasSettings, - paymentMethod: new PublicFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet), + paymentMethod: new PublicFeePaymentMethod(bananaFPC.address, aliceWallet), }, }) .wait(), @@ -182,7 +174,7 @@ describe('e2e_fees failures', () => { skipPublicSimulation: true, fee: { gasSettings, - paymentMethod: new PublicFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet), + paymentMethod: new PublicFeePaymentMethod(bananaFPC.address, aliceWallet), }, }) .wait({ dontThrowOnRevert: true }); @@ -218,7 +210,7 @@ describe('e2e_fees failures', () => { .send({ fee: { gasSettings, - paymentMethod: new BuggedSetupFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet), + paymentMethod: new BuggedSetupFeePaymentMethod(bananaFPC.address, aliceWallet), }, }) .wait(), @@ -232,7 +224,7 @@ describe('e2e_fees failures', () => { skipPublicSimulation: true, fee: { gasSettings, - paymentMethod: new BuggedSetupFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet), + paymentMethod: new BuggedSetupFeePaymentMethod(bananaFPC.address, aliceWallet), }, }) .wait(), @@ -272,7 +264,7 @@ describe('e2e_fees failures', () => { .send({ fee: { gasSettings: badGas, - paymentMethod: new PublicFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet), + paymentMethod: new PublicFeePaymentMethod(bananaFPC.address, aliceWallet), }, }) .wait(), @@ -284,7 +276,7 @@ describe('e2e_fees failures', () => { skipPublicSimulation: true, fee: { gasSettings: badGas, - paymentMethod: new PublicFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet), + paymentMethod: new PublicFeePaymentMethod(bananaFPC.address, aliceWallet), }, }) .wait({ @@ -317,12 +309,14 @@ describe('e2e_fees failures', () => { }); class BuggedSetupFeePaymentMethod extends PublicFeePaymentMethod { - override getFunctionCalls(gasSettings: GasSettings): Promise { + override async getFunctionCalls(gasSettings: GasSettings): Promise { const maxFee = gasSettings.getFeeLimit(); const nonce = Fr.random(); const tooMuchFee = new Fr(maxFee.toBigInt() * 2n); + const asset = await this.getAsset(); + return Promise.resolve([ this.wallet .setPublicAuthWit( @@ -334,7 +328,7 @@ class BuggedSetupFeePaymentMethod extends PublicFeePaymentMethod { selector: FunctionSelector.fromSignature('transfer_in_public((Field),(Field),Field,Field)'), type: FunctionType.PUBLIC, isStatic: false, - to: this.asset, + to: asset, returnTypes: [], }, }, @@ -344,10 +338,10 @@ class BuggedSetupFeePaymentMethod extends PublicFeePaymentMethod { { name: 'fee_entrypoint_public', to: this.paymentContract, - selector: FunctionSelector.fromSignature('fee_entrypoint_public(Field,(Field),Field)'), + selector: FunctionSelector.fromSignature('fee_entrypoint_public(Field,Field)'), type: FunctionType.PRIVATE, isStatic: false, - args: [tooMuchFee, this.asset.toField(), nonce], + args: [tooMuchFee, nonce], returnTypes: [], }, ]); diff --git a/yarn-project/end-to-end/src/e2e_fees/fees_test.ts b/yarn-project/end-to-end/src/e2e_fees/fees_test.ts index 427816c6d9a..518f545c8de 100644 --- a/yarn-project/end-to-end/src/e2e_fees/fees_test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/fees_test.ts @@ -60,7 +60,7 @@ export class FeesTest { public sequencerAddress!: AztecAddress; public coinbase!: EthAddress; - public feeRecipient!: AztecAddress; // Account that receives the fees from the fee refund flow. + public fpcAdmin!: AztecAddress; public gasSettings!: GasSettings; @@ -140,8 +140,8 @@ export class FeesTest { [this.aliceWallet, this.bobWallet] = this.wallets.slice(0, 2); [this.aliceAddress, this.bobAddress, this.sequencerAddress] = this.wallets.map(w => w.getAddress()); - // We like sequencer so we send him the fees. - this.feeRecipient = this.sequencerAddress; + // We set Alice as the FPC admin to avoid the need for deployment of another account. + this.fpcAdmin = this.aliceAddress; this.feeJuiceContract = await FeeJuiceContract.at(getCanonicalFeeJuice().address, this.aliceWallet); const bobInstance = await this.bobWallet.getContractInstance(this.bobAddress); @@ -223,7 +223,7 @@ export class FeesTest { expect(await context.pxe.isContractPubliclyDeployed(feeJuiceContract.address)).toBe(true); const bananaCoin = this.bananaCoin; - const bananaFPC = await FPCContract.deploy(this.aliceWallet, bananaCoin.address, this.feeRecipient) + const bananaFPC = await FPCContract.deploy(this.aliceWallet, bananaCoin.address, this.fpcAdmin) .send() .deployed(); 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 522004039e4..1d2a7427cc1 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 @@ -96,7 +96,7 @@ describe('e2e_fees gas_estimation', () => { 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 paymentMethod = new PublicFeePaymentMethod(bananaFPC.address, aliceWallet); const estimatedGas = await makeTransferRequest().estimateGas({ fee: { gasSettings, paymentMethod, estimatedGasPadding: 0 }, }); diff --git a/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts index e9518e69f08..39420fd44b8 100644 --- a/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts @@ -39,7 +39,6 @@ describe('e2e_fees private_payment', () => { let initialBobPrivateBananas: bigint; let initialFPCPublicBananas: bigint; - let initialSequencerPrivateBananas: bigint; let initialFPCGas: bigint; let initialSequencerGas: bigint; @@ -53,11 +52,11 @@ describe('e2e_fees private_payment', () => { initialSequencerL1Gas = await t.getCoinbaseBalance(); [ - [initialAlicePrivateBananas, initialBobPrivateBananas, initialSequencerPrivateBananas], + [initialAlicePrivateBananas, initialBobPrivateBananas], [initialAlicePublicBananas, initialBobPublicBananas, initialFPCPublicBananas], [initialAliceGas, initialFPCGas, initialSequencerGas], ] = await Promise.all([ - t.getBananaPrivateBalanceFn(aliceAddress, bobAddress, sequencerAddress), + t.getBananaPrivateBalanceFn(aliceAddress, bobAddress), t.getBananaPublicBalanceFn(aliceAddress, bobAddress, bananaFPC.address), t.getGasBalanceFn(aliceAddress, bananaFPC.address, sequencerAddress), ]); @@ -94,12 +93,7 @@ describe('e2e_fees private_payment', () => { const settings = { fee: { gasSettings, - paymentMethod: new PrivateFeePaymentMethod( - bananaCoin.address, - bananaFPC.address, - aliceWallet, - sequencerAddress, - ), + paymentMethod: new PrivateFeePaymentMethod(bananaFPC.address, aliceWallet), }, }; const localTx = await interaction.prove(settings); @@ -140,15 +134,13 @@ describe('e2e_fees private_payment', () => { await expectMapping( t.getBananaPrivateBalanceFn, - [aliceAddress, bobAddress, bananaFPC.address, sequencerAddress], - [ - initialAlicePrivateBananas - feeAmount - transferAmount, - transferAmount, - 0n, - initialSequencerPrivateBananas + feeAmount, - ], + [aliceAddress, bobAddress], + [initialAlicePrivateBananas - feeAmount - transferAmount, transferAmount], ); + // FPC should have received fee amount of bananas + await expectMapping(t.getBananaPublicBalanceFn, [bananaFPC.address], [initialFPCPublicBananas + feeAmount]); + await expectMapping( t.getGasBalanceFn, [aliceAddress, bananaFPC.address, sequencerAddress], @@ -181,12 +173,7 @@ describe('e2e_fees private_payment', () => { .send({ fee: { gasSettings, - paymentMethod: new PrivateFeePaymentMethod( - bananaCoin.address, - bananaFPC.address, - aliceWallet, - sequencerAddress, - ), + paymentMethod: new PrivateFeePaymentMethod(bananaFPC.address, aliceWallet), }, }) .wait(); @@ -195,9 +182,13 @@ describe('e2e_fees private_payment', () => { await expectMapping( t.getBananaPrivateBalanceFn, - [aliceAddress, bananaFPC.address, sequencerAddress], - [initialAlicePrivateBananas - feeAmount + newlyMintedBananas, 0n, initialSequencerPrivateBananas + feeAmount], + [aliceAddress], + [initialAlicePrivateBananas - feeAmount + newlyMintedBananas], ); + + // FPC should have received fee amount of bananas + await expectMapping(t.getBananaPublicBalanceFn, [bananaFPC.address], [initialFPCPublicBananas + feeAmount]); + await expectMapping( t.getGasBalanceFn, [aliceAddress, bananaFPC.address, sequencerAddress], @@ -230,12 +221,7 @@ describe('e2e_fees private_payment', () => { .send({ fee: { gasSettings, - paymentMethod: new PrivateFeePaymentMethod( - bananaCoin.address, - bananaFPC.address, - aliceWallet, - sequencerAddress, - ), + paymentMethod: new PrivateFeePaymentMethod(bananaFPC.address, aliceWallet), }, }) .wait(); @@ -244,17 +230,13 @@ describe('e2e_fees private_payment', () => { await expectMapping( t.getBananaPrivateBalanceFn, - [aliceAddress, bananaFPC.address, sequencerAddress], - [ - initialAlicePrivateBananas - feeAmount + amountTransferredToPrivate, - 0n, - initialSequencerPrivateBananas + feeAmount, - ], + [aliceAddress], + [initialAlicePrivateBananas - feeAmount + amountTransferredToPrivate], ); await expectMapping( t.getBananaPublicBalanceFn, - [aliceAddress, bananaFPC.address, sequencerAddress], - [initialAlicePublicBananas - amountTransferredToPrivate, initialFPCPublicBananas, 0n], + [aliceAddress, bananaFPC.address], + [initialAlicePublicBananas - amountTransferredToPrivate, initialFPCPublicBananas + feeAmount], ); await expectMapping( t.getGasBalanceFn, @@ -293,12 +275,7 @@ describe('e2e_fees private_payment', () => { .send({ fee: { gasSettings, - paymentMethod: new PrivateFeePaymentMethod( - bananaCoin.address, - bananaFPC.address, - aliceWallet, - sequencerAddress, - ), + paymentMethod: new PrivateFeePaymentMethod(bananaFPC.address, aliceWallet), }, }) .wait(); @@ -307,18 +284,16 @@ describe('e2e_fees private_payment', () => { await expectMapping( t.getBananaPrivateBalanceFn, - [aliceAddress, bobAddress, bananaFPC.address, sequencerAddress], + [aliceAddress, bobAddress], [ initialAlicePrivateBananas - feeAmount - amountTransferredInPrivate + amountTransferredToPrivate, initialBobPrivateBananas + amountTransferredInPrivate, - 0n, - initialSequencerPrivateBananas + feeAmount, ], ); await expectMapping( t.getBananaPublicBalanceFn, - [aliceAddress, bananaFPC.address, sequencerAddress], - [initialAlicePublicBananas - amountTransferredToPrivate, initialFPCPublicBananas, 0n], + [aliceAddress, bananaFPC.address], + [initialAlicePublicBananas - amountTransferredToPrivate, initialFPCPublicBananas + feeAmount], ); await expectMapping( t.getGasBalanceFn, @@ -342,12 +317,7 @@ describe('e2e_fees private_payment', () => { skipPublicSimulation: true, fee: { gasSettings, - paymentMethod: new PrivateFeePaymentMethod( - bananaCoin.address, - bankruptFPC.address, - aliceWallet, - aliceAddress, - ), + paymentMethod: new PrivateFeePaymentMethod(bankruptFPC.address, aliceWallet), }, }) .wait(), @@ -362,14 +332,12 @@ describe('e2e_fees private_payment', () => { fee: { gasSettings: t.gasSettings, paymentMethod: new PrivateFeePaymentMethod( - bananaCoin.address, bananaFPC.address, aliceWallet, - sequencerAddress, // Sequencer is the recipient of the refund fee notes because it's the FPC admin. true, // We set max fee/funded amount to 1 to trigger the error. ), }, }), - ).rejects.toThrow('funded amount not enough to cover tx fee'); + ).rejects.toThrow('max fee not enough to cover tx fee'); }); }); diff --git a/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts index 22e4fbcb46a..8f1175fb0b0 100644 --- a/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/public_payments.test.ts @@ -64,7 +64,7 @@ describe('e2e_fees public_payment', () => { .send({ fee: { gasSettings, - paymentMethod: new PublicFeePaymentMethod(bananaCoin.address, bananaFPC.address, aliceWallet), + paymentMethod: new PublicFeePaymentMethod(bananaFPC.address, aliceWallet), }, }) .wait(); diff --git a/yarn-project/pxe/src/pxe_service/error_enriching.ts b/yarn-project/pxe/src/pxe_service/error_enriching.ts index cb71823fe13..2c18f72b1e2 100644 --- a/yarn-project/pxe/src/pxe_service/error_enriching.ts +++ b/yarn-project/pxe/src/pxe_service/error_enriching.ts @@ -39,7 +39,7 @@ export async function enrichSimulationError(err: SimulationError, db: PxeDatabas ); } else { logger.warn( - `Could not function artifact in contract ${contract.name} for function '${fnName}' when enriching error callstack`, + `Could not find function artifact in contract ${contract.name} for function '${fnName}' when enriching error callstack`, ); } }); From 26c87a92521e1b30ac1c480afdcf4fb09ea69570 Mon Sep 17 00:00:00 2001 From: just-mitch <68168980+just-mitch@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:56:58 -0500 Subject: [PATCH 28/34] chore: no release please prs for release branches (#10850) --- .github/workflows/release-please.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 3a0defae122..9bf68adabd9 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -5,7 +5,6 @@ on: push: branches: - master - - "release/*" permissions: contents: write From 921febbbb337144aaf69cc3cfca9b8b5e77e9edc Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Wed, 18 Dec 2024 18:07:35 +0200 Subject: [PATCH 29/34] refactor: read function names from contract classes (#10753) This PR removes contract artifacts from the archiver as they were only used for dubugging purposes. Function names are now (optionally) emitted when registereing contract classes. I have created #10752 to remove function names from the contract class once we don't need this debug information --------- Co-authored-by: Santiago Palladino --- .../archiver/src/archiver/archiver.ts | 16 +++-------- .../archiver/src/archiver/archiver_store.ts | 6 ++-- .../contract_artifacts_store.test.ts | 22 --------------- .../contract_artifacts_store.ts | 22 --------------- .../kv_archiver_store/kv_archiver_store.ts | 23 ++++++--------- .../memory_archiver_store.ts | 28 ++++++------------- yarn-project/archiver/src/factory.ts | 11 +++++++- .../aztec-node/src/aztec-node/server.ts | 7 ++--- .../src/interfaces/archiver.test.ts | 17 ++++------- .../circuit-types/src/interfaces/archiver.ts | 7 +++-- .../src/interfaces/aztec-node.test.ts | 15 +++++----- .../src/interfaces/aztec-node.ts | 8 ++++-- .../interfaces/contract_data_source.ts | 9 ++---- .../pxe/src/pxe_service/pxe_service.ts | 11 ++++++-- .../simulator/src/public/fixtures/index.ts | 5 ++-- yarn-project/txe/src/node/txe_node.ts | 4 +-- .../util/txe_public_contract_data_source.ts | 4 +-- 17 files changed, 76 insertions(+), 139 deletions(-) delete mode 100644 yarn-project/archiver/src/archiver/kv_archiver_store/contract_artifacts_store.test.ts delete mode 100644 yarn-project/archiver/src/archiver/kv_archiver_store/contract_artifacts_store.ts diff --git a/yarn-project/archiver/src/archiver/archiver.ts b/yarn-project/archiver/src/archiver/archiver.ts index c72c03b815f..c116f738515 100644 --- a/yarn-project/archiver/src/archiver/archiver.ts +++ b/yarn-project/archiver/src/archiver/archiver.ts @@ -36,7 +36,6 @@ import { isValidUnconstrainedFunctionMembershipProof, } from '@aztec/circuits.js'; import { createEthereumChain } from '@aztec/ethereum'; -import { type ContractArtifact } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { type EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; @@ -766,12 +765,8 @@ export class Archiver implements ArchiveSource, Traceable { return; } - addContractArtifact(address: AztecAddress, artifact: ContractArtifact): Promise { - return this.store.addContractArtifact(address, artifact); - } - - getContractArtifact(address: AztecAddress): Promise { - return this.store.getContractArtifact(address); + registerContractFunctionNames(address: AztecAddress, names: Record): Promise { + return this.store.registerContractFunctionName(address, names); } getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise { @@ -1078,11 +1073,8 @@ class ArchiverStoreHelper getContractClassIds(): Promise { return this.store.getContractClassIds(); } - addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise { - return this.store.addContractArtifact(address, contract); - } - getContractArtifact(address: AztecAddress): Promise { - return this.store.getContractArtifact(address); + registerContractFunctionName(address: AztecAddress, names: Record): Promise { + return this.store.registerContractFunctionName(address, names); } getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise { return this.store.getContractFunctionName(address, selector); diff --git a/yarn-project/archiver/src/archiver/archiver_store.ts b/yarn-project/archiver/src/archiver/archiver_store.ts index 11d0abd7c35..d2056cba085 100644 --- a/yarn-project/archiver/src/archiver/archiver_store.ts +++ b/yarn-project/archiver/src/archiver/archiver_store.ts @@ -18,7 +18,7 @@ import { type PrivateLog, type UnconstrainedFunctionWithMembershipProof, } from '@aztec/circuits.js'; -import { type ContractArtifact, type FunctionSelector } from '@aztec/foundation/abi'; +import { type FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { type DataRetrieval } from './structs/data_retrieval.js'; @@ -261,12 +261,10 @@ export interface ArchiverDataStore { /** Returns the list of all class ids known by the archiver. */ getContractClassIds(): Promise; - addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise; - getContractArtifact(address: AztecAddress): Promise; - // TODO: These function names are in memory only as they are for development/debugging. They require the full contract // artifact supplied to the node out of band. This should be reviewed and potentially removed as part of // the node api cleanup process. + registerContractFunctionName(address: AztecAddress, names: Record): Promise; getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise; /** diff --git a/yarn-project/archiver/src/archiver/kv_archiver_store/contract_artifacts_store.test.ts b/yarn-project/archiver/src/archiver/kv_archiver_store/contract_artifacts_store.test.ts deleted file mode 100644 index 54fc9c7d69e..00000000000 --- a/yarn-project/archiver/src/archiver/kv_archiver_store/contract_artifacts_store.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AztecAddress } from '@aztec/circuits.js'; -import { openTmpStore } from '@aztec/kv-store/lmdb'; -import { BenchmarkingContractArtifact } from '@aztec/noir-contracts.js/Benchmarking'; - -import { beforeEach } from '@jest/globals'; - -import { KVArchiverDataStore } from './kv_archiver_store.js'; - -describe('Contract Artifact Store', () => { - let archiverStore: KVArchiverDataStore; - - beforeEach(() => { - archiverStore = new KVArchiverDataStore(openTmpStore()); - }); - - it('Should add and return contract artifacts', async () => { - const artifact = BenchmarkingContractArtifact; - const address = AztecAddress.random(); - await archiverStore.addContractArtifact(address, artifact); - await expect(archiverStore.getContractArtifact(address)).resolves.toEqual(artifact); - }); -}); diff --git a/yarn-project/archiver/src/archiver/kv_archiver_store/contract_artifacts_store.ts b/yarn-project/archiver/src/archiver/kv_archiver_store/contract_artifacts_store.ts deleted file mode 100644 index 8e18df413f2..00000000000 --- a/yarn-project/archiver/src/archiver/kv_archiver_store/contract_artifacts_store.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { type AztecAddress } from '@aztec/circuits.js'; -import { type ContractArtifact } from '@aztec/foundation/abi'; -import { type AztecKVStore, type AztecMap } from '@aztec/kv-store'; -import { contractArtifactFromBuffer, contractArtifactToBuffer } from '@aztec/types/abi'; - -export class ContractArtifactsStore { - #contractArtifacts: AztecMap; - - constructor(db: AztecKVStore) { - this.#contractArtifacts = db.openMap('archiver_contract_artifacts'); - } - - addContractArtifact(address: AztecAddress, contractArtifact: ContractArtifact): Promise { - return this.#contractArtifacts.set(address.toString(), contractArtifactToBuffer(contractArtifact)); - } - - getContractArtifact(address: AztecAddress): ContractArtifact | undefined { - const contractArtifact = this.#contractArtifacts.get(address.toString()); - // TODO(@spalladino): AztecMap lies and returns Uint8Arrays instead of Buffers, hence the extra Buffer.from. - return contractArtifact && contractArtifactFromBuffer(Buffer.from(contractArtifact)); - } -} diff --git a/yarn-project/archiver/src/archiver/kv_archiver_store/kv_archiver_store.ts b/yarn-project/archiver/src/archiver/kv_archiver_store/kv_archiver_store.ts index b7dfaa60041..ac12a3ba185 100644 --- a/yarn-project/archiver/src/archiver/kv_archiver_store/kv_archiver_store.ts +++ b/yarn-project/archiver/src/archiver/kv_archiver_store/kv_archiver_store.ts @@ -17,7 +17,7 @@ import { type PrivateLog, type UnconstrainedFunctionWithMembershipProof, } from '@aztec/circuits.js'; -import { type ContractArtifact, FunctionSelector } from '@aztec/foundation/abi'; +import { type FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { createLogger } from '@aztec/foundation/log'; import { type AztecKVStore } from '@aztec/kv-store'; @@ -26,7 +26,6 @@ import { type ArchiverDataStore, type ArchiverL1SynchPoint } from '../archiver_s import { type DataRetrieval } from '../structs/data_retrieval.js'; import { type L1Published } from '../structs/published.js'; import { BlockStore } from './block_store.js'; -import { ContractArtifactsStore } from './contract_artifacts_store.js'; import { ContractClassStore } from './contract_class_store.js'; import { ContractInstanceStore } from './contract_instance_store.js'; import { LogStore } from './log_store.js'; @@ -43,7 +42,6 @@ export class KVArchiverDataStore implements ArchiverDataStore { #messageStore: MessageStore; #contractClassStore: ContractClassStore; #contractInstanceStore: ContractInstanceStore; - #contractArtifactStore: ContractArtifactsStore; private functionNames = new Map(); #log = createLogger('archiver:data-store'); @@ -54,27 +52,22 @@ export class KVArchiverDataStore implements ArchiverDataStore { this.#messageStore = new MessageStore(db); this.#contractClassStore = new ContractClassStore(db); this.#contractInstanceStore = new ContractInstanceStore(db); - this.#contractArtifactStore = new ContractArtifactsStore(db); this.#nullifierStore = new NullifierStore(db); } - getContractArtifact(address: AztecAddress): Promise { - return Promise.resolve(this.#contractArtifactStore.getContractArtifact(address)); - } - // TODO: These function names are in memory only as they are for development/debugging. They require the full contract // artifact supplied to the node out of band. This should be reviewed and potentially removed as part of // the node api cleanup process. - getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise { + getContractFunctionName(_address: AztecAddress, selector: FunctionSelector): Promise { return Promise.resolve(this.functionNames.get(selector.toString())); } - async addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise { - await this.#contractArtifactStore.addContractArtifact(address, contract); - // Building tup this map of selectors to function names save expensive re-hydration of contract artifacts later - contract.functions.forEach(f => { - this.functionNames.set(FunctionSelector.fromNameAndParameters(f.name, f.parameters).toString(), f.name); - }); + registerContractFunctionName(_address: AztecAddress, names: Record): Promise { + for (const [selector, name] of Object.entries(names)) { + this.functionNames.set(selector, name); + } + + return Promise.resolve(); } getContractClass(id: Fr): Promise { diff --git a/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts b/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts index 1a31c8d14ce..fab9073e458 100644 --- a/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts +++ b/yarn-project/archiver/src/archiver/memory_archiver_store/memory_archiver_store.ts @@ -28,7 +28,7 @@ import { type PrivateLog, type UnconstrainedFunctionWithMembershipProof, } from '@aztec/circuits.js'; -import { type ContractArtifact, FunctionSelector } from '@aztec/foundation/abi'; +import { type FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { createLogger } from '@aztec/foundation/log'; @@ -68,8 +68,6 @@ export class MemoryArchiverStore implements ArchiverDataStore { */ private l1ToL2Messages = new L1ToL2MessageStore(); - private contractArtifacts: Map = new Map(); - private contractClasses: Map = new Map(); private bytecodeCommitments: Map = new Map(); @@ -86,6 +84,8 @@ export class MemoryArchiverStore implements ArchiverDataStore { private lastProvenL2BlockNumber: number = 0; private lastProvenL2EpochNumber: number = 0; + private functionNames = new Map(); + #log = createLogger('archiver:data-store'); constructor( @@ -730,26 +730,16 @@ export class MemoryArchiverStore implements ArchiverDataStore { }); } - public addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise { - this.contractArtifacts.set(address.toString(), contract); - return Promise.resolve(); - } - - public getContractArtifact(address: AztecAddress): Promise { - return Promise.resolve(this.contractArtifacts.get(address.toString())); + public getContractFunctionName(_address: AztecAddress, selector: FunctionSelector): Promise { + return Promise.resolve(this.functionNames.get(selector.toString())); } - async getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise { - const artifact = await this.getContractArtifact(address); - - if (!artifact) { - return undefined; + public registerContractFunctionName(_address: AztecAddress, names: Record): Promise { + for (const [selector, name] of Object.entries(names)) { + this.functionNames.set(selector, name); } - const func = artifact.functions.find(f => - FunctionSelector.fromNameAndParameters({ name: f.name, parameters: f.parameters }).equals(selector), - ); - return Promise.resolve(func?.name); + return Promise.resolve(); } public estimateSize(): { mappingSize: number; actualSize: number; numItems: number } { diff --git a/yarn-project/archiver/src/factory.ts b/yarn-project/archiver/src/factory.ts index 817770dcd52..018cbec57f9 100644 --- a/yarn-project/archiver/src/factory.ts +++ b/yarn-project/archiver/src/factory.ts @@ -4,6 +4,7 @@ import { computePublicBytecodeCommitment, getContractClassFromArtifact, } from '@aztec/circuits.js'; +import { FunctionSelector, FunctionType } from '@aztec/foundation/abi'; import { createLogger } from '@aztec/foundation/log'; import { type Maybe } from '@aztec/foundation/types'; import { type DataStoreConfig } from '@aztec/kv-store/config'; @@ -45,7 +46,15 @@ async function registerProtocolContracts(store: KVArchiverDataStore) { privateFunctions: [], unconstrainedFunctions: [], }; - await store.addContractArtifact(contract.address, contract.artifact); + + const functionNames: Record = {}; + for (const fn of contract.artifact.functions) { + if (fn.functionType === FunctionType.PUBLIC) { + functionNames[FunctionSelector.fromNameAndParameters(fn.name, fn.parameters).toString()] = fn.name; + } + } + + await store.registerContractFunctionName(contract.address, functionNames); const bytecodeCommitment = computePublicBytecodeCommitment(contractClassPublic.packedBytecode); await store.addContractClasses([contractClassPublic], [bytecodeCommitment], blockNumber); await store.addContractInstances([contract.instance], blockNumber); diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index 60e2ce1ca22..59ba35913fe 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -55,7 +55,6 @@ import { } from '@aztec/circuits.js'; import { computePublicDataTreeLeafSlot } from '@aztec/circuits.js/hash'; import { type L1ContractAddresses, createEthereumChain } from '@aztec/ethereum'; -import { type ContractArtifact } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { padArrayEnd } from '@aztec/foundation/collection'; import { type Logger, createLogger } from '@aztec/foundation/log'; @@ -901,10 +900,8 @@ export class AztecNodeService implements AztecNode, Traceable { return this.contractDataSource.addContractClass(contractClass); } - public addContractArtifact(address: AztecAddress, artifact: ContractArtifact): Promise { - this.log.info(`Adding contract artifact ${artifact.name} for ${address.toString()} via API`); - // TODO: Node should validate the artifact before accepting it - return this.contractDataSource.addContractArtifact(address, artifact); + public registerContractFunctionNames(_address: AztecAddress, names: Record): Promise { + return this.contractDataSource.registerContractFunctionNames(_address, names); } public flushTxs(): Promise { diff --git a/yarn-project/circuit-types/src/interfaces/archiver.test.ts b/yarn-project/circuit-types/src/interfaces/archiver.test.ts index 04aa0e0341d..4824b95365a 100644 --- a/yarn-project/circuit-types/src/interfaces/archiver.test.ts +++ b/yarn-project/circuit-types/src/interfaces/archiver.test.ts @@ -17,7 +17,6 @@ import { type JsonRpcTestContext, createJsonRpcTestSetup } from '@aztec/foundati import { fileURLToPath } from '@aztec/foundation/url'; import { loadContractArtifact } from '@aztec/types/abi'; -import { deepStrictEqual } from 'assert'; import { readFileSync } from 'fs'; import omit from 'lodash.omit'; import { resolve } from 'path'; @@ -223,15 +222,12 @@ describe('ArchiverApiSchema', () => { expect(result).toBe(1n); }); - it('getContractArtifact', async () => { - const result = await context.client.getContractArtifact(AztecAddress.random()); - deepStrictEqual(result, artifact); + it('registerContractFunctionNames', async () => { + await context.client.registerContractFunctionNames(AztecAddress.random(), { + [FunctionSelector.random().toString()]: 'test_fn', + }); }); - it('addContractArtifact', async () => { - await context.client.addContractArtifact(AztecAddress.random(), artifact); - }, 20_000); - it('getContract', async () => { const address = AztecAddress.random(); const result = await context.client.getContract(address); @@ -378,10 +374,9 @@ class MockArchiver implements ArchiverApi { expect(address).toBeInstanceOf(AztecAddress); return Promise.resolve(this.artifact); } - addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise { + registerContractFunctionNames(address: AztecAddress, names: Record): Promise { expect(address).toBeInstanceOf(AztecAddress); - // We use node's native assertion because jest's is too slow - deepStrictEqual(contract, this.artifact); + expect(names).toEqual(expect.any(Object)); return Promise.resolve(); } getL1ToL2Messages(blockNumber: bigint): Promise { diff --git a/yarn-project/circuit-types/src/interfaces/archiver.ts b/yarn-project/circuit-types/src/interfaces/archiver.ts index bf8ace98b60..302df9b5732 100644 --- a/yarn-project/circuit-types/src/interfaces/archiver.ts +++ b/yarn-project/circuit-types/src/interfaces/archiver.ts @@ -6,7 +6,6 @@ import { PrivateLog, PublicFunctionSchema, } from '@aztec/circuits.js'; -import { ContractArtifactSchema } from '@aztec/foundation/abi'; import { type ApiSchemaFor, optional, schemas } from '@aztec/foundation/schemas'; import { z } from 'zod'; @@ -69,8 +68,10 @@ export const ArchiverApiSchema: ApiSchemaFor = { getBytecodeCommitment: z.function().args(schemas.Fr).returns(schemas.Fr), getContract: z.function().args(schemas.AztecAddress).returns(ContractInstanceWithAddressSchema.optional()), getContractClassIds: z.function().args().returns(z.array(schemas.Fr)), - getContractArtifact: z.function().args(schemas.AztecAddress).returns(ContractArtifactSchema.optional()), - addContractArtifact: z.function().args(schemas.AztecAddress, ContractArtifactSchema).returns(z.void()), + registerContractFunctionNames: z + .function() + .args(schemas.AztecAddress, z.record(z.string(), z.string())) + .returns(z.void()), getL1ToL2Messages: z.function().args(schemas.BigInt).returns(z.array(schemas.Fr)), getL1ToL2MessageIndex: z.function().args(schemas.Fr).returns(schemas.BigInt.optional()), // TODO(#10007): Remove this method diff --git a/yarn-project/circuit-types/src/interfaces/aztec-node.test.ts b/yarn-project/circuit-types/src/interfaces/aztec-node.test.ts index 3bb4ee18185..53fee1105c6 100644 --- a/yarn-project/circuit-types/src/interfaces/aztec-node.test.ts +++ b/yarn-project/circuit-types/src/interfaces/aztec-node.test.ts @@ -19,13 +19,12 @@ import { getContractClassFromArtifact, } from '@aztec/circuits.js'; import { type L1ContractAddresses, L1ContractsNames } from '@aztec/ethereum'; -import { type ContractArtifact } from '@aztec/foundation/abi'; +import { type ContractArtifact, FunctionSelector } from '@aztec/foundation/abi'; import { memoize } from '@aztec/foundation/decorators'; import { type JsonRpcTestContext, createJsonRpcTestSetup } from '@aztec/foundation/json-rpc/test'; import { fileURLToPath } from '@aztec/foundation/url'; import { loadContractArtifact } from '@aztec/types/abi'; -import { deepStrictEqual } from 'assert'; import { readFileSync } from 'fs'; import omit from 'lodash.omit'; import times from 'lodash.times'; @@ -224,9 +223,11 @@ describe('AztecNodeApiSchema', () => { expect(response).toEqual(Object.fromEntries(ProtocolContractsNames.map(name => [name, expect.any(AztecAddress)]))); }); - it('addContractArtifact', async () => { - await context.client.addContractArtifact(AztecAddress.random(), artifact); - }, 20_000); + it('registerContractFunctionNames', async () => { + await context.client.registerContractFunctionNames(AztecAddress.random(), { + [FunctionSelector.random().toString()]: 'test_fn', + }); + }); it('getPrivateLogs', async () => { const response = await context.client.getPrivateLogs(1, 1); @@ -505,9 +506,7 @@ class MockAztecNode implements AztecNode { ) as ProtocolContractAddresses, ); } - addContractArtifact(address: AztecAddress, artifact: ContractArtifact): Promise { - expect(address).toBeInstanceOf(AztecAddress); - deepStrictEqual(artifact, this.artifact); + registerContractFunctionNames(_address: AztecAddress, _names: Record): Promise { return Promise.resolve(); } getPrivateLogs(_from: number, _limit: number): Promise { diff --git a/yarn-project/circuit-types/src/interfaces/aztec-node.ts b/yarn-project/circuit-types/src/interfaces/aztec-node.ts index e1979488813..f4b052b87fd 100644 --- a/yarn-project/circuit-types/src/interfaces/aztec-node.ts +++ b/yarn-project/circuit-types/src/interfaces/aztec-node.ts @@ -17,7 +17,6 @@ import { ProtocolContractAddressesSchema, } from '@aztec/circuits.js'; import { type L1ContractAddresses, L1ContractAddressesSchema } from '@aztec/ethereum'; -import { type ContractArtifact, ContractArtifactSchema } from '@aztec/foundation/abi'; import type { AztecAddress } from '@aztec/foundation/aztec-address'; import type { Fr } from '@aztec/foundation/fields'; import { createSafeJsonRpcClient, defaultFetch } from '@aztec/foundation/json-rpc/client'; @@ -287,7 +286,7 @@ export interface AztecNode * @param aztecAddress * @param artifact */ - addContractArtifact(address: AztecAddress, artifact: ContractArtifact): Promise; + registerContractFunctionNames(address: AztecAddress, names: Record): Promise; /** * Retrieves all private logs from up to `limit` blocks, starting from the block number `from`. @@ -534,7 +533,10 @@ export const AztecNodeApiSchema: ApiSchemaFor = { getProtocolContractAddresses: z.function().returns(ProtocolContractAddressesSchema), - addContractArtifact: z.function().args(schemas.AztecAddress, ContractArtifactSchema).returns(z.void()), + registerContractFunctionNames: z + .function() + .args(schemas.AztecAddress, z.record(z.string(), z.string())) + .returns(z.void()), getPrivateLogs: z.function().args(z.number(), z.number()).returns(z.array(PrivateLog.schema)), diff --git a/yarn-project/circuits.js/src/contract/interfaces/contract_data_source.ts b/yarn-project/circuits.js/src/contract/interfaces/contract_data_source.ts index 84ed5f4afd9..388a828b9cb 100644 --- a/yarn-project/circuits.js/src/contract/interfaces/contract_data_source.ts +++ b/yarn-project/circuits.js/src/contract/interfaces/contract_data_source.ts @@ -1,4 +1,4 @@ -import { type ContractArtifact, type FunctionSelector } from '@aztec/foundation/abi'; +import { type FunctionSelector } from '@aztec/foundation/abi'; import { type AztecAddress } from '@aztec/foundation/aztec-address'; import { type Fr } from '@aztec/foundation/fields'; @@ -45,11 +45,8 @@ export interface ContractDataSource { */ getContractClassIds(): Promise; - /** Returns a contract artifact. */ - getContractArtifact(address: AztecAddress): Promise; - /** Returns a function's name */ getContractFunctionName(address: AztecAddress, selector: FunctionSelector): Promise; - /** Registers a a contract artifact. */ - addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise; + /** Registers a function names. Useful for debugging. */ + registerContractFunctionNames(address: AztecAddress, names: Record): Promise; } diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index f919d5a137b..ec8c0226d61 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -52,6 +52,7 @@ import { type ContractArtifact, EventSelector, FunctionSelector, + FunctionType, encodeArguments, } from '@aztec/foundation/abi'; import { Fr, type Point } from '@aztec/foundation/fields'; @@ -240,8 +241,14 @@ export class PXEService implements PXE { await this.db.addContractArtifact(contractClassId, artifact); - // TODO: PXE may not want to broadcast the artifact to the network - await this.node.addContractArtifact(instance.address, artifact); + const functionNames: Record = {}; + for (const fn of artifact.functions) { + if (fn.functionType === FunctionType.PUBLIC) { + functionNames[FunctionSelector.fromNameAndParameters(fn.name, fn.parameters).toString()] = fn.name; + } + } + + await this.node.registerContractFunctionNames(instance.address, functionNames); // TODO(#10007): Node should get public contract class from the registration event, not from PXE registration await this.node.addContractClass({ ...contractClass, privateFunctions: [], unconstrainedFunctions: [] }); diff --git a/yarn-project/simulator/src/public/fixtures/index.ts b/yarn-project/simulator/src/public/fixtures/index.ts index 6789e8622d3..36c126c0ef3 100644 --- a/yarn-project/simulator/src/public/fixtures/index.ts +++ b/yarn-project/simulator/src/public/fixtures/index.ts @@ -4,6 +4,7 @@ import { BlockHeader, CallContext, type ContractClassPublic, + type ContractDataSource, type ContractInstanceWithAddress, DEFAULT_GAS_LIMIT, DEPLOYER_CONTRACT_ADDRESS, @@ -144,7 +145,7 @@ export function createTxForPublicCall( return tx; } -export class MockedAvmTestContractDataSource { +export class MockedAvmTestContractDataSource implements ContractDataSource { private fnName = 'public_dispatch'; private bytecode: Buffer; public fnSelector: FunctionSelector; @@ -218,7 +219,7 @@ export class MockedAvmTestContractDataSource { return Promise.resolve(this.fnName); } - addContractArtifact(_address: AztecAddress, _contract: ContractArtifact): Promise { + registerContractFunctionNames(_address: AztecAddress, _names: Record): Promise { return Promise.resolve(); } } diff --git a/yarn-project/txe/src/node/txe_node.ts b/yarn-project/txe/src/node/txe_node.ts index 35aa9266548..c798e9a9ae0 100644 --- a/yarn-project/txe/src/node/txe_node.ts +++ b/yarn-project/txe/src/node/txe_node.ts @@ -1,4 +1,4 @@ -import { type ContractArtifact, createLogger } from '@aztec/aztec.js'; +import { createLogger } from '@aztec/aztec.js'; import { type AztecNode, type EpochProofQuote, @@ -450,7 +450,7 @@ export class TXENode implements AztecNode { * @param aztecAddress * @param artifact */ - addContractArtifact(_address: AztecAddress, _artifact: ContractArtifact): Promise { + registerContractFunctionNames(_address: AztecAddress, _names: Record): Promise { throw new Error('TXE Node method addContractArtifact not implemented'); } diff --git a/yarn-project/txe/src/util/txe_public_contract_data_source.ts b/yarn-project/txe/src/util/txe_public_contract_data_source.ts index a56aeb40d8b..7d15b9d8d48 100644 --- a/yarn-project/txe/src/util/txe_public_contract_data_source.ts +++ b/yarn-project/txe/src/util/txe_public_contract_data_source.ts @@ -85,8 +85,8 @@ export class TXEPublicContractDataSource implements ContractDataSource { return Promise.resolve(func?.name); } - addContractArtifact(address: AztecAddress, contract: ContractArtifact): Promise { - return this.txeOracle.addContractArtifact(contract); + registerContractFunctionNames(_address: AztecAddress, _names: Record): Promise { + return Promise.resolve(); } // TODO(#10007): Remove this method. From a4be4a7b113276d45ea9f6279efa41f475700417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Wed, 18 Dec 2024 10:22:15 -0600 Subject: [PATCH 30/34] refactor: optimization of `syncTaggedLogsAsSender` (#10811) --- .../pxe/src/simulator_oracle/index.ts | 80 +++++++++---------- .../simulator_oracle/simulator_oracle.test.ts | 69 ++++++++-------- .../pxe/src/simulator_oracle/tagging_utils.ts | 3 + 3 files changed, 76 insertions(+), 76 deletions(-) diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index acd71477f52..bb3885695a4 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -38,7 +38,7 @@ import { type IncomingNoteDao } from '../database/incoming_note_dao.js'; import { type PxeDatabase } from '../database/index.js'; import { produceNoteDaos } from '../note_decryption_utils/produce_note_daos.js'; import { getAcirSimulator } from '../simulator/index.js'; -import { getIndexedTaggingSecretsForTheWindow, getInitialIndexesMap } from './tagging_utils.js'; +import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndexesMap } from './tagging_utils.js'; /** * A data oracle that provides information needed for simulating a transaction. @@ -353,59 +353,56 @@ export class SimulatorOracle implements DBOracle { recipient: AztecAddress, ): Promise { const appTaggingSecret = await this.#calculateAppTaggingSecret(contractAddress, sender, recipient); - let [currentIndex] = await this.db.getTaggingSecretsIndexesAsSender([appTaggingSecret]); - - const INDEX_OFFSET = 10; - - let previousEmptyBack = 0; - let currentEmptyBack = 0; - let currentEmptyFront: number; - - // The below code is trying to find the index of the start of the first window in which for all elements of window, we do not see logs. - // We take our window size, and fetch the node for these logs. We store both the amount of empty consecutive slots from the front and the back. - // We use our current empty consecutive slots from the front, as well as the previous consecutive empty slots from the back to see if we ever hit a time where there - // is a window in which we see the combination of them to be greater than the window's size. If true, we rewind current index to the start of said window and use it. - // Assuming two windows of 5: - // [0, 1, 0, 1, 0], [0, 0, 0, 0, 0] - // We can see that when processing the second window, the previous amount of empty slots from the back of the window (1), added with the empty elements from the front of the window (5) - // is greater than 5 (6) and therefore we have found a window to use. - // We simply need to take the number of elements (10) - the size of the window (5) - the number of consecutive empty elements from the back of the last window (1) = 4; - // This is the first index of our desired window. - // Note that if we ever see a situation like so: - // [0, 1, 0, 1, 0], [0, 0, 0, 0, 1] - // This also returns the correct index (4), but this is indicative of a problem / desync. i.e. we should never have a window that has a log that exists after the window. + const [oldIndex] = await this.db.getTaggingSecretsIndexesAsSender([appTaggingSecret]); + // This algorithm works such that: + // 1. If we find minimum consecutive empty logs in a window of logs we set the index to the index of the last log + // we found and quit. + // 2. If we don't find minimum consecutive empty logs in a window of logs we slide the window to latest log index + // and repeat the process. + const MIN_CONSECUTIVE_EMPTY_LOGS = 10; + const WINDOW_SIZE = MIN_CONSECUTIVE_EMPTY_LOGS * 2; + + let [numConsecutiveEmptyLogs, currentIndex] = [0, oldIndex]; do { - const currentTags = [...new Array(INDEX_OFFSET)].map((_, i) => { + // We compute the tags for the current window of indexes + const currentTags = [...new Array(WINDOW_SIZE)].map((_, i) => { const indexedAppTaggingSecret = new IndexedTaggingSecret(appTaggingSecret, currentIndex + i); return indexedAppTaggingSecret.computeSiloedTag(recipient, contractAddress); }); - previousEmptyBack = currentEmptyBack; + // We fetch the logs for the tags const possibleLogs = await this.aztecNode.getLogsByTags(currentTags); - const indexOfFirstLog = possibleLogs.findIndex(possibleLog => possibleLog.length !== 0); - currentEmptyFront = indexOfFirstLog === -1 ? INDEX_OFFSET : indexOfFirstLog; - + // We find the index of the last log in the window that is not empty const indexOfLastLog = possibleLogs.findLastIndex(possibleLog => possibleLog.length !== 0); - currentEmptyBack = indexOfLastLog === -1 ? INDEX_OFFSET : INDEX_OFFSET - 1 - indexOfLastLog; - currentIndex += INDEX_OFFSET; - } while (currentEmptyFront + previousEmptyBack < INDEX_OFFSET); + if (indexOfLastLog === -1) { + // We haven't found any logs in the current window so we stop looking + break; + } - // We unwind the entire current window and the amount of consecutive empty slots from the previous window - const newIndex = currentIndex - (INDEX_OFFSET + previousEmptyBack); + // We move the current index to that of the last log we found + currentIndex += indexOfLastLog + 1; - await this.db.setTaggingSecretsIndexesAsSender([new IndexedTaggingSecret(appTaggingSecret, newIndex)]); + // We compute the number of consecutive empty logs we found and repeat the process if we haven't found enough. + numConsecutiveEmptyLogs = WINDOW_SIZE - indexOfLastLog - 1; + } while (numConsecutiveEmptyLogs < MIN_CONSECUTIVE_EMPTY_LOGS); const contractName = await this.contractDataOracle.getDebugContractName(contractAddress); - this.log.debug(`Syncing logs for sender ${sender} at contract ${contractName}(${contractAddress})`, { - sender, - secret: appTaggingSecret, - index: currentIndex, - contractName, - contractAddress, - }); + if (currentIndex !== oldIndex) { + await this.db.setTaggingSecretsIndexesAsSender([new IndexedTaggingSecret(appTaggingSecret, currentIndex)]); + + this.log.debug(`Syncing logs for sender ${sender} at contract ${contractName}(${contractAddress})`, { + sender, + secret: appTaggingSecret, + index: currentIndex, + contractName, + contractAddress, + }); + } else { + this.log.debug(`No new logs found for sender ${sender} at contract ${contractName}(${contractAddress})`); + } } /** @@ -421,9 +418,6 @@ export class SimulatorOracle implements DBOracle { maxBlockNumber: number, scopes?: AztecAddress[], ): Promise> { - // Half the size of the window we slide over the tagging secret indexes. - const WINDOW_HALF_SIZE = 10; - // Ideally this algorithm would be implemented in noir, exposing its building blocks as oracles. // However it is impossible at the moment due to the language not supporting nested slices. // This nesting is necessary because for a given set of tags we don't diff --git a/yarn-project/pxe/src/simulator_oracle/simulator_oracle.test.ts b/yarn-project/pxe/src/simulator_oracle/simulator_oracle.test.ts index 722eaf8e944..0db352f96a6 100644 --- a/yarn-project/pxe/src/simulator_oracle/simulator_oracle.test.ts +++ b/yarn-project/pxe/src/simulator_oracle/simulator_oracle.test.ts @@ -37,6 +37,7 @@ import { type PxeDatabase } from '../database/index.js'; import { KVPxeDatabase } from '../database/kv_pxe_database.js'; import { ContractDataOracle } from '../index.js'; import { SimulatorOracle } from './index.js'; +import { WINDOW_HALF_SIZE } from './tagging_utils.js'; const TXS_PER_BLOCK = 4; const NUM_NOTE_HASHES_PER_BLOCK = TXS_PER_BLOCK * MAX_NOTE_HASHES_PER_TX; @@ -138,16 +139,15 @@ describe('Simulator oracle', () => { describe('sync tagged logs', () => { const NUM_SENDERS = 10; - const SENDER_OFFSET_WINDOW_SIZE = 10; let senders: { completeAddress: CompleteAddress; ivsk: Fq; secretKey: Fr }[]; - function generateMockLogs(senderOffset: number) { + function generateMockLogs(tagIndex: number) { const logs: { [k: string]: TxScopedL2Log[] } = {}; - // Add a random note from every address in the address book for our account with index senderOffset + // Add a random note from every address in the address book for our account with index tagIndex // Compute the tag as sender (knowledge of preaddress and ivsk) for (const sender of senders) { - const tag = computeSiloedTagForIndex(sender, recipient.address, contractAddress, senderOffset); + const tag = computeSiloedTagForIndex(sender, recipient.address, contractAddress, tagIndex); const blockNumber = 1; const randomNote = new MockNoteRequest( getRandomNoteLogPayload(tag, contractAddress), @@ -164,18 +164,18 @@ describe('Simulator oracle', () => { // Add a random note from the first sender in the address book, repeating the tag // Compute the tag as sender (knowledge of preaddress and ivsk) const firstSender = senders[0]; - const tag = computeSiloedTagForIndex(firstSender, recipient.address, contractAddress, senderOffset); + const tag = computeSiloedTagForIndex(firstSender, recipient.address, contractAddress, tagIndex); const payload = getRandomNoteLogPayload(tag, contractAddress); const logData = payload.generatePayload(GrumpkinScalar.random(), recipient.address).toBuffer(); const log = new TxScopedL2Log(TxHash.random(), 1, 0, false, logData); logs[tag.toString()].push(log); // Accumulated logs intended for recipient: NUM_SENDERS + 1 - // Add a random note from half the address book for our account with index senderOffset + 1 + // Add a random note from half the address book for our account with index tagIndex + 1 // Compute the tag as sender (knowledge of preaddress and ivsk) for (let i = NUM_SENDERS / 2; i < NUM_SENDERS; i++) { const sender = senders[i]; - const tag = computeSiloedTagForIndex(sender, recipient.address, contractAddress, senderOffset + 1); + const tag = computeSiloedTagForIndex(sender, recipient.address, contractAddress, tagIndex + 1); const blockNumber = 2; const randomNote = new MockNoteRequest( getRandomNoteLogPayload(tag, contractAddress), @@ -189,13 +189,13 @@ describe('Simulator oracle', () => { } // Accumulated logs intended for recipient: NUM_SENDERS + 1 + NUM_SENDERS / 2 - // Add a random note from every address in the address book for a random recipient with index senderOffset + // Add a random note from every address in the address book for a random recipient with index tagIndex // Compute the tag as sender (knowledge of preaddress and ivsk) for (const sender of senders) { const keys = deriveKeys(Fr.random()); const partialAddress = Fr.random(); const randomRecipient = computeAddress(keys.publicKeys, partialAddress); - const tag = computeSiloedTagForIndex(sender, randomRecipient, contractAddress, senderOffset); + const tag = computeSiloedTagForIndex(sender, randomRecipient, contractAddress, tagIndex); const blockNumber = 3; const randomNote = new MockNoteRequest( getRandomNoteLogPayload(tag, contractAddress), @@ -232,8 +232,8 @@ describe('Simulator oracle', () => { }); it('should sync tagged logs', async () => { - const senderOffset = 0; - generateMockLogs(senderOffset); + const tagIndex = 0; + generateMockLogs(tagIndex); const syncedLogs = await simulatorOracle.syncTaggedLogs(contractAddress, 3); // We expect to have all logs intended for the recipient, one per sender + 1 with a duplicated tag for the first // one + half of the logs for the second index @@ -266,8 +266,8 @@ describe('Simulator oracle', () => { await keyStore.addAccount(sender.secretKey, sender.completeAddress.partialAddress); } - let senderOffset = 0; - generateMockLogs(senderOffset); + let tagIndex = 0; + generateMockLogs(tagIndex); // Recompute the secrets (as recipient) to ensure indexes are updated const ivsk = await keyStore.getMasterIncomingViewingSecretKey(recipient.address); @@ -292,13 +292,14 @@ describe('Simulator oracle', () => { let indexesAsSenderAfterSync = await database.getTaggingSecretsIndexesAsSender(secrets); expect(indexesAsSenderAfterSync).toStrictEqual([1, 1, 1, 1, 1, 2, 2, 2, 2, 2]); - // Two windows are fetch for each sender - expect(aztecNode.getLogsByTags.mock.calls.length).toBe(NUM_SENDERS * 2); + // Only 1 window is obtained for each sender + expect(aztecNode.getLogsByTags.mock.calls.length).toBe(NUM_SENDERS); aztecNode.getLogsByTags.mockReset(); - // We add more logs at the end of the window to make sure we only detect them and bump the indexes if it lies within our window - senderOffset = 10; - generateMockLogs(senderOffset); + // We add more logs to the second half of the window to test that a second iteration in `syncTaggedLogsAsSender` + // is handled correctly. + tagIndex = 11; + generateMockLogs(tagIndex); for (let i = 0; i < senders.length; i++) { await simulatorOracle.syncTaggedLogsAsSender( contractAddress, @@ -308,14 +309,14 @@ describe('Simulator oracle', () => { } indexesAsSenderAfterSync = await database.getTaggingSecretsIndexesAsSender(secrets); - expect(indexesAsSenderAfterSync).toStrictEqual([11, 11, 11, 11, 11, 12, 12, 12, 12, 12]); + expect(indexesAsSenderAfterSync).toStrictEqual([12, 12, 12, 12, 12, 13, 13, 13, 13, 13]); expect(aztecNode.getLogsByTags.mock.calls.length).toBe(NUM_SENDERS * 2); }); it('should sync tagged logs with a sender index offset', async () => { - const senderOffset = 5; - generateMockLogs(senderOffset); + const tagIndex = 5; + generateMockLogs(tagIndex); const syncedLogs = await simulatorOracle.syncTaggedLogs(contractAddress, 3); // We expect to have all logs intended for the recipient, one per sender + 1 with a duplicated tag for the first one + half of the logs for the second index expect(syncedLogs.get(recipient.address.toString())).toHaveLength(NUM_SENDERS + 1 + NUM_SENDERS / 2); @@ -341,8 +342,8 @@ describe('Simulator oracle', () => { }); it("should sync tagged logs for which indexes are not updated if they're inside the window", async () => { - const senderOffset = 1; - generateMockLogs(senderOffset); + const tagIndex = 1; + generateMockLogs(tagIndex); // Recompute the secrets (as recipient) to update indexes const ivsk = await keyStore.getMasterIncomingViewingSecretKey(recipient.address); @@ -361,8 +362,8 @@ describe('Simulator oracle', () => { expect(syncedLogs.get(recipient.address.toString())).toHaveLength(NUM_SENDERS + 1 + NUM_SENDERS / 2); // First sender should have 2 logs, but keep index 2 since they were built using the same tag - // Next 4 senders should also have index 2 = offset + 1 - // Last 5 senders should have index 3 = offset + 2 + // Next 4 senders should also have index 2 = tagIndex + 1 + // Last 5 senders should have index 3 = tagIndex + 2 const indexes = await database.getTaggingSecretsIndexesAsRecipient(secrets); expect(indexes).toHaveLength(NUM_SENDERS); @@ -374,8 +375,8 @@ describe('Simulator oracle', () => { }); it("should not sync tagged logs for which indexes are not updated if they're outside the window", async () => { - const senderOffset = 0; - generateMockLogs(senderOffset); + const tagIndex = 0; + generateMockLogs(tagIndex); // Recompute the secrets (as recipient) to update indexes const ivsk = await keyStore.getMasterIncomingViewingSecretKey(recipient.address); @@ -384,8 +385,10 @@ describe('Simulator oracle', () => { return poseidon2Hash([firstSenderSecretPoint.x, firstSenderSecretPoint.y, contractAddress]); }); + // We set the indexes to WINDOW_HALF_SIZE + 1 so that it's outside the window and for this reason no updates + // should be triggered. await database.setTaggingSecretsIndexesAsRecipient( - secrets.map(secret => new IndexedTaggingSecret(secret, SENDER_OFFSET_WINDOW_SIZE + 1)), + secrets.map(secret => new IndexedTaggingSecret(secret, WINDOW_HALF_SIZE + 1)), ); const syncedLogs = await simulatorOracle.syncTaggedLogs(contractAddress, 3); @@ -404,8 +407,8 @@ describe('Simulator oracle', () => { }); it('should sync tagged logs from scratch after a DB wipe', async () => { - const senderOffset = 0; - generateMockLogs(senderOffset); + const tagIndex = 0; + generateMockLogs(tagIndex); // Recompute the secrets (as recipient) to update indexes const ivsk = await keyStore.getMasterIncomingViewingSecretKey(recipient.address); @@ -415,7 +418,7 @@ describe('Simulator oracle', () => { }); await database.setTaggingSecretsIndexesAsRecipient( - secrets.map(secret => new IndexedTaggingSecret(secret, SENDER_OFFSET_WINDOW_SIZE + 2)), + secrets.map(secret => new IndexedTaggingSecret(secret, WINDOW_HALF_SIZE + 2)), ); let syncedLogs = await simulatorOracle.syncTaggedLogs(contractAddress, 3); @@ -447,8 +450,8 @@ describe('Simulator oracle', () => { }); it('should not sync tagged logs with a blockNumber > maxBlockNumber', async () => { - const senderOffset = 0; - generateMockLogs(senderOffset); + const tagIndex = 0; + generateMockLogs(tagIndex); const syncedLogs = await simulatorOracle.syncTaggedLogs(contractAddress, 1); // Only NUM_SENDERS + 1 logs should be synched, since the rest have blockNumber > 1 diff --git a/yarn-project/pxe/src/simulator_oracle/tagging_utils.ts b/yarn-project/pxe/src/simulator_oracle/tagging_utils.ts index 82759eaf038..6cf121bcd7b 100644 --- a/yarn-project/pxe/src/simulator_oracle/tagging_utils.ts +++ b/yarn-project/pxe/src/simulator_oracle/tagging_utils.ts @@ -1,5 +1,8 @@ import { type Fr, IndexedTaggingSecret } from '@aztec/circuits.js'; +// Half the size of the window we slide over the tagging secret indexes. +export const WINDOW_HALF_SIZE = 10; + export function getIndexedTaggingSecretsForTheWindow( secretsAndWindows: { appTaggingSecret: Fr; leftMostIndex: number; rightMostIndex: number }[], ): IndexedTaggingSecret[] { From 6f1ad792a2a8d5d3d770932fb61eaa8f0d497932 Mon Sep 17 00:00:00 2001 From: Alex Gherghisan Date: Wed, 18 Dec 2024 20:13:47 +0200 Subject: [PATCH 31/34] chore: silence logs to k8s port-forward (#10768) --- yarn-project/end-to-end/src/spartan/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/end-to-end/src/spartan/utils.ts b/yarn-project/end-to-end/src/spartan/utils.ts index 2f5b672b253..cd656791614 100644 --- a/yarn-project/end-to-end/src/spartan/utils.ts +++ b/yarn-project/end-to-end/src/spartan/utils.ts @@ -104,7 +104,7 @@ export async function startPortForward({ // If we don't pipe stderr, then the port forwarding does not work. // Log to silent because this doesn't actually report errors, // just extremely verbose debug logs. - logger.debug(data.toString()); + logger.silent(data.toString()); }); // Wait a moment for the port forward to establish From b721253797e37d2d80c0c5f5bf60e602a304dc44 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 18 Dec 2024 15:37:27 -0300 Subject: [PATCH 32/34] feat: Claim epoch proof rights without a block (#10844) If the sequencer does not have enough txs to build a block, it will still try to submit an epoch proof if there's one available. Fixes #9404 --- .../prover_coordination/epoch_proof_quote.ts | 7 + .../epoch_proof_quote_payload.ts | 10 ++ .../end-to-end/src/e2e_epochs.test.ts | 22 ++- .../src/publisher/l1-publisher-metrics.ts | 10 +- .../src/publisher/l1-publisher.ts | 62 +++++-- .../sequencer-client/src/publisher/utils.ts | 11 +- .../src/sequencer/sequencer.test.ts | 170 +++++------------- .../src/sequencer/sequencer.ts | 38 +++- 8 files changed, 173 insertions(+), 157 deletions(-) diff --git a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.ts b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.ts index 454d01aa585..26ed60e0d35 100644 --- a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.ts +++ b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote.ts @@ -78,6 +78,13 @@ export class EpochProofQuote extends Gossipable { }; } + toInspect() { + return { + signature: this.signature.toString(), + ...this.payload.toInspect(), + }; + } + /** * Get the size of the epoch proof quote in bytes. * @returns The size of the epoch proof quote in bytes. diff --git a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote_payload.ts b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote_payload.ts index 60c06e39501..71d9c7ccc8e 100644 --- a/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote_payload.ts +++ b/yarn-project/circuit-types/src/prover_coordination/epoch_proof_quote_payload.ts @@ -114,6 +114,16 @@ export class EpochProofQuotePayload { }; } + toInspect() { + return { + epochToProve: Number(this.epochToProve), + validUntilSlot: this.validUntilSlot.toString(), + bondAmount: this.bondAmount.toString(), + prover: this.prover.toString(), + basisPointFee: this.basisPointFee, + }; + } + getSize(): number { // We cache size to avoid recalculating it if (this.size) { diff --git a/yarn-project/end-to-end/src/e2e_epochs.test.ts b/yarn-project/end-to-end/src/e2e_epochs.test.ts index 9f71bfdac2b..6a5e89dfe77 100644 --- a/yarn-project/end-to-end/src/e2e_epochs.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs.test.ts @@ -26,9 +26,9 @@ describe('e2e_epochs', () => { const EPOCH_DURATION_IN_L2_SLOTS = 4; const L2_SLOT_DURATION_IN_L1_SLOTS = 2; - const L1_BLOCK_TIME_IN_S = 8; + const L1_BLOCK_TIME_IN_S = process.env.L1_BLOCK_TIME ? parseInt(process.env.L1_BLOCK_TIME) : 8; - beforeAll(async () => { + beforeEach(async () => { // Set up system without any account nor protocol contracts // and with faster block times and shorter epochs. context = await setup(0, { @@ -99,7 +99,7 @@ describe('e2e_epochs', () => { logger.info(`L2 genesis at L1 block ${constants.l1GenesisBlock} (timestamp ${constants.l1GenesisTime})`); }); - afterAll(async () => { + afterEach(async () => { clearInterval(handle); await context.teardown(); }); @@ -117,6 +117,11 @@ describe('e2e_epochs', () => { await retryUntil(() => Promise.resolve(target === l2BlockNumber), `Wait until L2 block ${target}`, 60, 0.1); }; + /** Waits until the given L2 block number is marked as proven. */ + const waitUntilProvenL2BlockNumber = async (target: number) => { + await retryUntil(() => Promise.resolve(target === l2ProvenBlockNumber), `Wait proven L2 block ${target}`, 60, 0.1); + }; + it('does not allow submitting proof after epoch end', async () => { await waitUntilEpochStarts(1); const blockNumberAtEndOfEpoch0 = Number(await rollup.getBlockNumber()); @@ -149,4 +154,15 @@ describe('e2e_epochs', () => { expect(lastL2BlockTxReceipt.blockNumber).toBeGreaterThan(lastProverTxReceipt!.blockNumber); logger.info(`Test succeeded`); }); + + it('submits proof claim alone if there is no txs to build a block', async () => { + context.sequencer?.updateSequencerConfig({ minTxsPerBlock: 1 }); + await waitUntilEpochStarts(1); + const blockNumberAtEndOfEpoch0 = Number(await rollup.getBlockNumber()); + logger.info(`Starting epoch 1 after L2 block ${blockNumberAtEndOfEpoch0}`); + + await waitUntilProvenL2BlockNumber(blockNumberAtEndOfEpoch0); + expect(l2BlockNumber).toEqual(blockNumberAtEndOfEpoch0); + logger.info(`Test succeeded`); + }); }); diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher-metrics.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher-metrics.ts index b33c857a529..f23ac261169 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher-metrics.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher-metrics.ts @@ -1,4 +1,4 @@ -import type { L1PublishBlockStats, L1PublishProofStats } from '@aztec/circuit-types/stats'; +import type { L1PublishBlockStats, L1PublishProofStats, L1PublishStats } from '@aztec/circuit-types/stats'; import { Attributes, type Histogram, @@ -10,7 +10,7 @@ import { import { formatEther } from 'viem/utils'; -export type L1TxType = 'submitProof' | 'process'; +export type L1TxType = 'submitProof' | 'process' | 'claimEpochProofRight'; export class L1PublisherMetrics { private gasPrice: Histogram; @@ -74,7 +74,11 @@ export class L1PublisherMetrics { this.recordTx('process', durationMs, stats); } - private recordTx(txType: L1TxType, durationMs: number, stats: Omit) { + recordClaimEpochProofRightTx(durationMs: number, stats: L1PublishStats) { + this.recordTx('claimEpochProofRight', durationMs, stats); + } + + private recordTx(txType: L1TxType, durationMs: number, stats: L1PublishStats) { const attributes = { [Attributes.L1_TX_TYPE]: txType, [Attributes.L1_SENDER]: stats.sender, diff --git a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts index f2580de6a6f..a89969ede84 100644 --- a/yarn-project/sequencer-client/src/publisher/l1-publisher.ts +++ b/yarn-project/sequencer-client/src/publisher/l1-publisher.ts @@ -7,7 +7,7 @@ import { type TxHash, getHashedSignaturePayload, } from '@aztec/circuit-types'; -import { type L1PublishBlockStats, type L1PublishProofStats } from '@aztec/circuit-types/stats'; +import { type L1PublishBlockStats, type L1PublishProofStats, type L1PublishStats } from '@aztec/circuit-types/stats'; import { AGGREGATION_OBJECT_LENGTH, AZTEC_MAX_EPOCH_DURATION, @@ -38,7 +38,6 @@ import { ExtRollupLibAbi, GovernanceProposerAbi, LeonidasLibAbi, RollupAbi } fro import { type TelemetryClient } from '@aztec/telemetry-client'; import pick from 'lodash.pick'; -import { inspect } from 'util'; import { type BaseError, type Chain, @@ -71,7 +70,7 @@ import { privateKeyToAccount } from 'viem/accounts'; import { type PublisherConfig, type TxSenderConfig } from './config.js'; import { L1PublisherMetrics } from './l1-publisher-metrics.js'; -import { prettyLogViemError, prettyLogViemErrorMsg } from './utils.js'; +import { prettyLogViemErrorMsg } from './utils.js'; /** * Stats for a sent transaction. @@ -615,6 +614,53 @@ export class L1Publisher { return false; } + /** Calls claimEpochProofRight in the Rollup contract to submit a chosen prover quote for the previous epoch. */ + public async claimEpochProofRight(proofQuote: EpochProofQuote) { + const timer = new Timer(); + + let receipt; + try { + this.log.debug(`Submitting claimEpochProofRight transaction`); + receipt = await this.l1TxUtils.sendAndMonitorTransaction({ + to: this.rollupContract.address, + data: encodeFunctionData({ + abi: RollupAbi, + functionName: 'claimEpochProofRight', + args: [proofQuote.toViemArgs()], + }), + }); + } catch (err) { + this.log.error(`Failed to claim epoch proof right: ${prettyLogViemErrorMsg(err)}`, err, { + proofQuote: proofQuote.toInspect(), + }); + return false; + } + + if (receipt.status === 'success') { + const tx = await this.getTransactionStats(receipt.transactionHash); + const stats: L1PublishStats = { + gasPrice: receipt.effectiveGasPrice, + gasUsed: receipt.gasUsed, + transactionHash: receipt.transactionHash, + ...pick(tx!, 'calldataGas', 'calldataSize', 'sender'), + }; + this.log.verbose(`Submitted claim epoch proof right to L1 rollup contract`, { + ...stats, + ...proofQuote.toInspect(), + }); + this.metrics.recordClaimEpochProofRightTx(timer.ms(), stats); + return true; + } else { + this.metrics.recordFailedTx('claimEpochProofRight'); + // TODO: Get the error message from the reverted tx + this.log.error(`Claim epoch proof right tx reverted`, { + txHash: receipt.transactionHash, + ...proofQuote.toInspect(), + }); + return false; + } + } + private async tryGetErrorFromRevertedTx( data: Hex, args: { @@ -958,8 +1004,7 @@ export class L1Publisher { data, }; } catch (err) { - prettyLogViemError(err, this.log); - this.log.error(`Rollup publish failed`, err); + this.log.error(`Rollup publish failed: ${prettyLogViemErrorMsg(err)}`, err); return undefined; } } @@ -972,9 +1017,6 @@ export class L1Publisher { return undefined; } try { - this.log.info(`ProposeAndClaim`); - this.log.info(inspect(quote.payload)); - const kzg = Blob.getViemKzgInstance(); const { args, gas } = await this.prepareProposeTx(encodedData); const data = encodeFunctionData({ @@ -1002,9 +1044,7 @@ export class L1Publisher { data, }; } catch (err) { - prettyLogViemError(err, this.log); - const errorMessage = err instanceof Error ? err.message : String(err); - this.log.error(`Rollup publish failed`, errorMessage); + this.log.error(`Rollup publish failed: ${prettyLogViemErrorMsg(err)}`, err); return undefined; } } diff --git a/yarn-project/sequencer-client/src/publisher/utils.ts b/yarn-project/sequencer-client/src/publisher/utils.ts index 26f68eebdac..c8a570896f4 100644 --- a/yarn-project/sequencer-client/src/publisher/utils.ts +++ b/yarn-project/sequencer-client/src/publisher/utils.ts @@ -1,5 +1,3 @@ -import { type Logger } from '@aztec/foundation/log'; - import { BaseError, ContractFunctionRevertedError } from 'viem'; export function prettyLogViemErrorMsg(err: any) { @@ -12,12 +10,5 @@ export function prettyLogViemErrorMsg(err: any) { return `${errorName}${args}`; } } -} - -// TODO(palla/log): Review this method -export function prettyLogViemError(err: any, logger: Logger) { - const msg = prettyLogViemErrorMsg(err); - if (msg) { - logger.debug(`canProposeAtTime failed with "${msg}"`); - } + return err?.message ?? err; } diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index 72498b7e86c..d65fe420217 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -16,8 +16,8 @@ import { UnencryptedTxL2Logs, WorldStateRunningState, type WorldStateSynchronizer, + mockEpochProofQuote as baseMockEpochProofQuote, makeProcessedTxFromPrivateOnlyTx, - mockEpochProofQuote, mockTxForRollup, } from '@aztec/circuit-types'; import { @@ -588,9 +588,10 @@ describe('sequencer', () => { expect(publisher.proposeL2Block).not.toHaveBeenCalled(); }); - describe('Handling proof quotes', () => { + describe('proof quotes', () => { let txHash: TxHash; let currentEpoch = 0n; + const setupForBlockNumber = (blockNumber: number) => { currentEpoch = BigInt(blockNumber) / BigInt(epochDuration); // Create a new block and header @@ -640,17 +641,20 @@ describe('sequencer', () => { blockBuilder.setBlockCompleted.mockResolvedValue(block); }; + const mockEpochProofQuote = (opts: { epoch?: bigint; validUntilSlot?: bigint; fee?: number } = {}) => + baseMockEpochProofQuote( + opts.epoch ?? currentEpoch - 1n, + opts.validUntilSlot ?? block.header.globalVariables.slotNumber.toBigInt() + 1n, + 10000n, + EthAddress.random(), + opts.fee ?? 1, + ); + it('submits a valid proof quote with a block', async () => { const blockNumber = epochDuration + 1; setupForBlockNumber(blockNumber); - const proofQuote = mockEpochProofQuote( - currentEpoch - 1n, - block.header.globalVariables.slotNumber.toBigInt() + 1n, - 10000n, - EthAddress.random(), - 1, - ); + const proofQuote = mockEpochProofQuote(); p2p.getEpochProofQuotes.mockResolvedValue([proofQuote]); publisher.proposeL2Block.mockResolvedValueOnce(true); @@ -663,17 +667,32 @@ describe('sequencer', () => { expect(publisher.proposeL2Block).toHaveBeenCalledWith(block, getSignatures(), [txHash], proofQuote); }); + it('submits a valid proof quote even without a block', async () => { + const blockNumber = epochDuration + 1; + setupForBlockNumber(blockNumber); + + // There are no txs! + p2p.getPendingTxs.mockResolvedValue([]); + + const proofQuote = mockEpochProofQuote(); + + p2p.getEpochProofQuotes.mockResolvedValue([proofQuote]); + publisher.claimEpochProofRight.mockResolvedValueOnce(true); + publisher.validateProofQuote.mockImplementation((x: EpochProofQuote) => Promise.resolve(x)); + + // The previous epoch can be claimed + publisher.getClaimableEpoch.mockImplementation(() => Promise.resolve(currentEpoch - 1n)); + + await sequencer.doRealWork(); + expect(publisher.claimEpochProofRight).toHaveBeenCalledWith(proofQuote); + expect(publisher.proposeL2Block).not.toHaveBeenCalled(); + }); + it('does not claim the epoch previous to the first', async () => { const blockNumber = 1; setupForBlockNumber(blockNumber); - const proofQuote = mockEpochProofQuote( - 0n, - block.header.globalVariables.slotNumber.toBigInt() + 1n, - 10000n, - EthAddress.random(), - 1, - ); + const proofQuote = mockEpochProofQuote({ epoch: 0n }); p2p.getEpochProofQuotes.mockResolvedValue([proofQuote]); publisher.proposeL2Block.mockResolvedValueOnce(true); @@ -689,14 +708,8 @@ describe('sequencer', () => { const blockNumber = epochDuration + 1; setupForBlockNumber(blockNumber); - const proofQuote = mockEpochProofQuote( - currentEpoch - 1n, - // Slot number expired - block.header.globalVariables.slotNumber.toBigInt() - 1n, - 10000n, - EthAddress.random(), - 1, - ); + const expiredSlotNumber = block.header.globalVariables.slotNumber.toBigInt() - 1n; + const proofQuote = mockEpochProofQuote({ validUntilSlot: expiredSlotNumber }); p2p.getEpochProofQuotes.mockResolvedValue([proofQuote]); publisher.proposeL2Block.mockResolvedValueOnce(true); @@ -713,13 +726,7 @@ describe('sequencer', () => { const blockNumber = epochDuration + 1; setupForBlockNumber(blockNumber); - const proofQuote = mockEpochProofQuote( - currentEpoch - 1n, - block.header.globalVariables.slotNumber.toBigInt() + 1n, - 10000n, - EthAddress.random(), - 1, - ); + const proofQuote = mockEpochProofQuote(); p2p.getEpochProofQuotes.mockResolvedValue([proofQuote]); publisher.proposeL2Block.mockResolvedValueOnce(true); @@ -735,13 +742,7 @@ describe('sequencer', () => { const blockNumber = epochDuration + 1; setupForBlockNumber(blockNumber); - const proofQuote = mockEpochProofQuote( - currentEpoch - 1n, - block.header.globalVariables.slotNumber.toBigInt() + 1n, - 10000n, - EthAddress.random(), - 1, - ); + const proofQuote = mockEpochProofQuote(); p2p.getEpochProofQuotes.mockResolvedValue([proofQuote]); publisher.proposeL2Block.mockResolvedValueOnce(true); @@ -756,61 +757,6 @@ describe('sequencer', () => { expect(publisher.proposeL2Block).toHaveBeenCalledWith(block, getSignatures(), [txHash], undefined); }); - it('only selects valid quotes', async () => { - const blockNumber = epochDuration + 1; - setupForBlockNumber(blockNumber); - - // Create 1 valid quote and 3 that have a higher fee but are invalid - const validProofQuote = mockEpochProofQuote( - currentEpoch - 1n, - block.header.globalVariables.slotNumber.toBigInt() + 1n, - 10000n, - EthAddress.random(), - 1, - ); - - const proofQuoteInvalidSlot = mockEpochProofQuote( - currentEpoch - 1n, - block.header.globalVariables.slotNumber.toBigInt() - 1n, - 10000n, - EthAddress.random(), - 2, - ); - - const proofQuoteInvalidEpoch = mockEpochProofQuote( - currentEpoch, - block.header.globalVariables.slotNumber.toBigInt() - 1n, - 10000n, - EthAddress.random(), - 2, - ); - - // This is deemed invalid by the contract, we identify it by a fee of 2 - const proofQuoteInvalid = mockEpochProofQuote( - currentEpoch - 1n, - block.header.globalVariables.slotNumber.toBigInt() + 1n, - 10000n, - EthAddress.random(), - 2, - ); - - const allQuotes = [validProofQuote, proofQuoteInvalidSlot, proofQuoteInvalidEpoch, proofQuoteInvalid]; - - p2p.getEpochProofQuotes.mockResolvedValue(allQuotes); - publisher.proposeL2Block.mockResolvedValueOnce(true); - - // Quote is reported as invalid - publisher.validateProofQuote.mockImplementation(p => - Promise.resolve(p.payload.basisPointFee === 2 ? undefined : p), - ); - - // The previous epoch can be claimed - publisher.getClaimableEpoch.mockImplementation(() => Promise.resolve(currentEpoch - 1n)); - - await sequencer.doRealWork(); - expect(publisher.proposeL2Block).toHaveBeenCalledWith(block, getSignatures(), [txHash], validProofQuote); - }); - it('selects the lowest cost valid quote', async () => { const blockNumber = epochDuration + 1; setupForBlockNumber(blockNumber); @@ -818,40 +764,14 @@ describe('sequencer', () => { // Create 3 valid quotes with different fees. // And 3 invalid quotes with lower fees // We should select the lowest cost valid quote - const validQuotes = times(3, (i: number) => - mockEpochProofQuote( - currentEpoch - 1n, - block.header.globalVariables.slotNumber.toBigInt() + 1n, - 10000n, - EthAddress.random(), - 10 + i, - ), - ); + const validQuotes = times(3, (i: number) => mockEpochProofQuote({ fee: 10 + i })); - const proofQuoteInvalidSlot = mockEpochProofQuote( - currentEpoch - 1n, - block.header.globalVariables.slotNumber.toBigInt() - 1n, - 10000n, - EthAddress.random(), - 1, - ); + const expiredSlot = block.header.globalVariables.slotNumber.toBigInt() - 1n; + const proofQuoteInvalidSlot = mockEpochProofQuote({ validUntilSlot: expiredSlot, fee: 1 }); + const proofQuoteInvalidEpoch = mockEpochProofQuote({ epoch: currentEpoch, fee: 2 }); - const proofQuoteInvalidEpoch = mockEpochProofQuote( - currentEpoch, - block.header.globalVariables.slotNumber.toBigInt() - 1n, - 10000n, - EthAddress.random(), - 2, - ); - - // This is deemed invalid by the contract, we identify it by it's fee - const proofQuoteInvalid = mockEpochProofQuote( - currentEpoch - 1n, - block.header.globalVariables.slotNumber.toBigInt() + 1n, - 10000n, - EthAddress.random(), - 3, - ); + // This is deemed invalid by the contract, we identify it by its fee + const proofQuoteInvalid = mockEpochProofQuote({ fee: 3 }); const allQuotes = [proofQuoteInvalidSlot, proofQuoteInvalidEpoch, ...validQuotes, proofQuoteInvalid]; diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index 6116485c849..384b5cf2952 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -283,6 +283,7 @@ export class Sequencer { const pendingTxs = await this.p2pClient.getPendingTxs(); if (!this.shouldProposeBlock(historicalHeader, { pendingTxsCount: pendingTxs.length })) { + await this.claimEpochProofRightIfAvailable(slot); return; } @@ -315,6 +316,7 @@ export class Sequencer { // Bail if we don't have enough valid txs if (!this.shouldProposeBlock(historicalHeader, { validTxsCount: validTxs.length })) { + await this.claimEpochProofRightIfAvailable(slot); return; } @@ -428,7 +430,7 @@ export class Sequencer { ); // We need to have at least minTxsPerBLock txs. - if (args.pendingTxsCount != undefined && args.pendingTxsCount < this.minTxsPerBLock) { + if (args.pendingTxsCount !== undefined && args.pendingTxsCount < this.minTxsPerBLock) { this.log.verbose( `Not creating block because not enough txs in the pool (got ${args.pendingTxsCount} min ${this.minTxsPerBLock})`, ); @@ -436,7 +438,7 @@ export class Sequencer { } // Bail if we don't have enough valid txs - if (args.validTxsCount != undefined && args.validTxsCount < this.minTxsPerBLock) { + if (args.validTxsCount !== undefined && args.validTxsCount < this.minTxsPerBLock) { this.log.verbose( `Not creating block because not enough valid txs loaded from the pool (got ${args.validTxsCount} min ${this.minTxsPerBLock})`, ); @@ -701,7 +703,7 @@ export class Sequencer { // Find out which epoch we are currently in const epochToProve = await this.publisher.getClaimableEpoch(); if (epochToProve === undefined) { - this.log.debug(`No epoch to prove`); + this.log.trace(`No epoch to prove at slot ${slotNumber}`); return undefined; } @@ -714,7 +716,10 @@ export class Sequencer { }); // ensure these quotes are still valid for the slot and have the contract validate them const validQuotesPromise = Promise.all( - quotes.filter(x => x.payload.validUntilSlot >= slotNumber).map(x => this.publisher.validateProofQuote(x)), + quotes + .filter(x => x.payload.validUntilSlot >= slotNumber) + .filter(x => x.payload.epochToProve === epochToProve) + .map(x => this.publisher.validateProofQuote(x)), ); const validQuotes = (await validQuotesPromise).filter((q): q is EpochProofQuote => !!q); @@ -727,7 +732,7 @@ export class Sequencer { (a: EpochProofQuote, b: EpochProofQuote) => a.payload.basisPointFee - b.payload.basisPointFee, ); const quote = sortedQuotes[0]; - this.log.info(`Selected proof quote for proof claim`, quote.payload); + this.log.info(`Selected proof quote for proof claim`, { quote: quote.toInspect() }); return quote; } catch (err) { this.log.error(`Failed to create proof claim for previous epoch`, err, { slotNumber }); @@ -787,6 +792,29 @@ export class Sequencer { return toReturn; } + @trackSpan( + 'Sequencer.claimEpochProofRightIfAvailable', + slotNumber => ({ [Attributes.SLOT_NUMBER]: Number(slotNumber) }), + epoch => ({ [Attributes.EPOCH_NUMBER]: Number(epoch) }), + ) + /** Collects an epoch proof quote if there is an epoch to prove, and submits it to the L1 contract. */ + protected async claimEpochProofRightIfAvailable(slotNumber: bigint) { + const proofQuote = await this.createProofClaimForPreviousEpoch(slotNumber); + if (proofQuote === undefined) { + return; + } + + const epoch = proofQuote.payload.epochToProve; + const ctx = { slotNumber, epoch, quote: proofQuote.toInspect() }; + this.log.verbose(`Claiming proof right for epoch ${epoch}`, ctx); + const success = await this.publisher.claimEpochProofRight(proofQuote); + if (!success) { + throw new Error(`Failed to claim proof right for epoch ${epoch}`); + } + this.log.info(`Claimed proof right for epoch ${epoch}`, ctx); + return epoch; + } + /** * Returns whether all dependencies have caught up. * We don't check against the previous block submitted since it may have been reorg'd out. From 51d82aaf62b84885eb388b1565c1a119c60d849e Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 18 Dec 2024 15:37:36 -0300 Subject: [PATCH 33/34] fix: Archiver does not jump the gun on epoch completed (#10801) Archiver's isEpochComplete would return `true` when the first L1 block of the last epoch L2 slot was mined, ignoring the fact that the L2 block could be posted on a later L1 slot. This fixes the check so it reports the epoch as completed only once the last L1 block of the last L2 slot of the epoch is mined. Fixes #10800 --- .../archiver/src/archiver/archiver.test.ts | 112 ++++++++++++++++-- .../archiver/src/archiver/archiver.ts | 19 ++- .../src/epoch-helpers/index.test.ts | 28 +++++ .../circuit-types/src/epoch-helpers/index.ts | 14 ++- .../end-to-end/src/e2e_epochs.test.ts | 1 + 5 files changed, 158 insertions(+), 16 deletions(-) create mode 100644 yarn-project/circuit-types/src/epoch-helpers/index.test.ts diff --git a/yarn-project/archiver/src/archiver/archiver.test.ts b/yarn-project/archiver/src/archiver/archiver.test.ts index 79ca76e7cd3..305a89874f0 100644 --- a/yarn-project/archiver/src/archiver/archiver.test.ts +++ b/yarn-project/archiver/src/archiver/archiver.test.ts @@ -1,9 +1,10 @@ -import { InboxLeaf, L2Block } from '@aztec/circuit-types'; +import { InboxLeaf, type L1RollupConstants, L2Block } from '@aztec/circuit-types'; import { GENESIS_ARCHIVE_ROOT, PrivateLog } from '@aztec/circuits.js'; import { DefaultL1ContractsConfig } from '@aztec/ethereum'; import { Blob } from '@aztec/foundation/blob'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; +import { type Logger, createLogger } from '@aztec/foundation/log'; import { sleep } from '@aztec/foundation/sleep'; import { type InboxAbi, RollupAbi } from '@aztec/l1-artifacts'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; @@ -26,7 +27,9 @@ import { type ArchiverInstrumentation } from './instrumentation.js'; import { MemoryArchiverStore } from './memory_archiver_store/memory_archiver_store.js'; interface MockRollupContractRead { + /** Given an L2 block number, returns the archive. */ archiveAt: (args: readonly [bigint]) => Promise<`0x${string}`>; + /** Given an L2 block number, returns provenBlockNumber, provenArchive, pendingBlockNumber, pendingArchive, archiveForLocalPendingBlockNumber, provenEpochNumber. */ status: (args: readonly [bigint]) => Promise<[bigint, `0x${string}`, bigint, `0x${string}`, `0x${string}`]>; } @@ -52,6 +55,7 @@ describe('Archiver', () => { let instrumentation: MockProxy; let archiverStore: ArchiverDataStore; let now: number; + let l1Constants: L1RollupConstants; let rollupRead: MockProxy; let inboxRead: MockProxy; @@ -61,9 +65,12 @@ describe('Archiver', () => { let l2BlockProposedLogs: Log[]; let l2MessageSentLogs: Log[]; + let logger: Logger; + const GENESIS_ROOT = new Fr(GENESIS_ARCHIVE_ROOT).toString(); beforeEach(() => { + logger = createLogger('archiver:test'); now = +new Date(); publicClient = mock>({ // Return a block with a reasonable timestamp @@ -89,6 +96,13 @@ describe('Archiver', () => { const tracer = new NoopTelemetryClient().getTracer(); instrumentation = mock({ isEnabled: () => true, tracer }); archiverStore = new MemoryArchiverStore(1000); + l1Constants = { + l1GenesisTime: BigInt(now), + l1StartBlock: 0n, + epochDuration: 4, + slotDuration: 24, + ethereumSlotDuration: 12, + }; archiver = new Archiver( publicClient, @@ -96,13 +110,7 @@ describe('Archiver', () => { archiverStore, { pollingIntervalMs: 1000, batchSize: 1000 }, instrumentation, - { - l1GenesisTime: BigInt(now), - l1StartBlock: 0n, - epochDuration: 4, - slotDuration: 24, - ethereumSlotDuration: 12, - }, + l1Constants, ); blocks = blockNumbers.map(x => L2Block.random(x, txsPerBlock, x + 1, 2)); @@ -369,6 +377,94 @@ describe('Archiver', () => { expect((await archiver.getContractClassLogs({ fromBlock: 2, toBlock: 3 })).logs).toEqual([]); }, 10_000); + it('reports an epoch as pending if the current L2 block is not in the last slot of the epoch', async () => { + const { l1StartBlock, slotDuration, ethereumSlotDuration, epochDuration } = l1Constants; + const notLastL2SlotInEpoch = epochDuration - 2; + const l1BlockForL2Block = l1StartBlock + BigInt((notLastL2SlotInEpoch * slotDuration) / ethereumSlotDuration); + expect(notLastL2SlotInEpoch).toEqual(2); + + logger.info(`Syncing L2 block on slot ${notLastL2SlotInEpoch} mined in L1 block ${l1BlockForL2Block}`); + const l2Block = blocks[0]; + l2Block.header.globalVariables.slotNumber = new Fr(notLastL2SlotInEpoch); + blocks = [l2Block]; + + const rollupTxs = blocks.map(makeRollupTx); + publicClient.getBlockNumber.mockResolvedValueOnce(l1BlockForL2Block); + rollupRead.status.mockResolvedValueOnce([0n, GENESIS_ROOT, 1n, l2Block.archive.root.toString(), GENESIS_ROOT]); + makeL2BlockProposedEvent(l1BlockForL2Block, 1n, l2Block.archive.root.toString()); + rollupTxs.forEach(tx => publicClient.getTransaction.mockResolvedValueOnce(tx)); + + await archiver.start(false); + + // Epoch should not yet be complete + expect(await archiver.isEpochComplete(0n)).toBe(false); + + // Wait until block 1 is processed + while ((await archiver.getBlockNumber()) !== 1) { + await sleep(100); + } + + // Epoch should not be complete + expect(await archiver.isEpochComplete(0n)).toBe(false); + }); + + it('reports an epoch as complete if the current L2 block is in the last slot of the epoch', async () => { + const { l1StartBlock, slotDuration, ethereumSlotDuration, epochDuration } = l1Constants; + const lastL2SlotInEpoch = epochDuration - 1; + const l1BlockForL2Block = l1StartBlock + BigInt((lastL2SlotInEpoch * slotDuration) / ethereumSlotDuration); + expect(lastL2SlotInEpoch).toEqual(3); + + logger.info(`Syncing L2 block on slot ${lastL2SlotInEpoch} mined in L1 block ${l1BlockForL2Block}`); + const l2Block = blocks[0]; + l2Block.header.globalVariables.slotNumber = new Fr(lastL2SlotInEpoch); + blocks = [l2Block]; + + const rollupTxs = blocks.map(makeRollupTx); + publicClient.getBlockNumber.mockResolvedValueOnce(l1BlockForL2Block); + rollupRead.status.mockResolvedValueOnce([0n, GENESIS_ROOT, 1n, l2Block.archive.root.toString(), GENESIS_ROOT]); + makeL2BlockProposedEvent(l1BlockForL2Block, 1n, l2Block.archive.root.toString()); + rollupTxs.forEach(tx => publicClient.getTransaction.mockResolvedValueOnce(tx)); + + await archiver.start(false); + + // Epoch should not yet be complete + expect(await archiver.isEpochComplete(0n)).toBe(false); + + // Wait until block 1 is processed + while ((await archiver.getBlockNumber()) !== 1) { + await sleep(100); + } + + // Epoch should be complete once block was synced + expect(await archiver.isEpochComplete(0n)).toBe(true); + }); + + it('reports an epoch as pending if the current L1 block is not the last one on the epoch and no L2 block landed', async () => { + const { l1StartBlock, slotDuration, ethereumSlotDuration, epochDuration } = l1Constants; + const notLastL1BlockForEpoch = l1StartBlock + BigInt((epochDuration * slotDuration) / ethereumSlotDuration) - 2n; + expect(notLastL1BlockForEpoch).toEqual(6n); + + logger.info(`Syncing archiver to L1 block ${notLastL1BlockForEpoch}`); + publicClient.getBlockNumber.mockResolvedValueOnce(notLastL1BlockForEpoch); + rollupRead.status.mockResolvedValueOnce([0n, GENESIS_ROOT, 0n, GENESIS_ROOT, GENESIS_ROOT]); + + await archiver.start(true); + expect(await archiver.isEpochComplete(0n)).toBe(false); + }); + + it('reports an epoch as complete if the current L1 block is the last one on the epoch and no L2 block landed', async () => { + const { l1StartBlock, slotDuration, ethereumSlotDuration, epochDuration } = l1Constants; + const lastL1BlockForEpoch = l1StartBlock + BigInt((epochDuration * slotDuration) / ethereumSlotDuration) - 1n; + expect(lastL1BlockForEpoch).toEqual(7n); + + logger.info(`Syncing archiver to L1 block ${lastL1BlockForEpoch}`); + publicClient.getBlockNumber.mockResolvedValueOnce(lastL1BlockForEpoch); + rollupRead.status.mockResolvedValueOnce([0n, GENESIS_ROOT, 0n, GENESIS_ROOT, GENESIS_ROOT]); + + await archiver.start(true); + expect(await archiver.isEpochComplete(0n)).toBe(true); + }); + // TODO(palla/reorg): Add a unit test for the archiver handleEpochPrune xit('handles an upcoming L2 prune', () => {}); diff --git a/yarn-project/archiver/src/archiver/archiver.ts b/yarn-project/archiver/src/archiver/archiver.ts index c116f738515..ab59cca5420 100644 --- a/yarn-project/archiver/src/archiver/archiver.ts +++ b/yarn-project/archiver/src/archiver/archiver.ts @@ -507,6 +507,10 @@ export class Archiver implements ArchiveSource, Traceable { return Promise.resolve(); } + public getL1Constants(): L1RollupConstants { + return this.l1constants; + } + public getRollupAddress(): Promise { return Promise.resolve(this.l1Addresses.rollupAddress); } @@ -566,17 +570,22 @@ export class Archiver implements ArchiveSource, Traceable { return true; } + // If we haven't run an initial sync, just return false. + const l1Timestamp = this.l1Timestamp; + if (l1Timestamp === undefined) { + return false; + } + // If not, the epoch may also be complete if the L2 slot has passed without a block - // We compute this based on the timestamp for the given epoch and the timestamp of the last L1 block - const l1Timestamp = this.getL1Timestamp(); + // We compute this based on the end timestamp for the given epoch and the timestamp of the last L1 block const [_startTimestamp, endTimestamp] = getTimestampRangeForEpoch(epochNumber, this.l1constants); // For this computation, we throw in a few extra seconds just for good measure, // since we know the next L1 block won't be mined within this range. Remember that - // l1timestamp is the timestamp of the last l1 block we've seen, so this 3s rely on - // the fact that L1 won't mine two blocks within 3s of each other. + // l1timestamp is the timestamp of the last l1 block we've seen, so this relies on + // the fact that L1 won't mine two blocks within this time of each other. // TODO(palla/reorg): Is the above a safe assumption? - const leeway = 3n; + const leeway = 1n; return l1Timestamp + leeway >= endTimestamp; } diff --git a/yarn-project/circuit-types/src/epoch-helpers/index.test.ts b/yarn-project/circuit-types/src/epoch-helpers/index.test.ts new file mode 100644 index 00000000000..4fa879b7f6c --- /dev/null +++ b/yarn-project/circuit-types/src/epoch-helpers/index.test.ts @@ -0,0 +1,28 @@ +import { type EpochConstants, getTimestampRangeForEpoch } from './index.js'; + +describe('EpochHelpers', () => { + let constants: EpochConstants; + const l1GenesisTime = 1734440000n; + + beforeEach(() => { + constants = { + l1GenesisBlock: 10n, + l1GenesisTime: l1GenesisTime, + epochDuration: 4, + slotDuration: 24, + ethereumSlotDuration: 12, + }; + }); + + it('returns timestamp range for initial epoch', () => { + const [start, end] = getTimestampRangeForEpoch(0n, constants); + expect(start).toEqual(l1GenesisTime); + expect(end).toEqual(l1GenesisTime + BigInt(24 * 3 + 12)); + }); + + it('returns timestamp range for second epoch', () => { + const [start, end] = getTimestampRangeForEpoch(1n, constants); + expect(start).toEqual(l1GenesisTime + BigInt(24 * 4)); + expect(end).toEqual(l1GenesisTime + BigInt(24 * 4) + BigInt(24 * 3 + 12)); + }); +}); diff --git a/yarn-project/circuit-types/src/epoch-helpers/index.ts b/yarn-project/circuit-types/src/epoch-helpers/index.ts index 50c698e1160..90a22f1a4b5 100644 --- a/yarn-project/circuit-types/src/epoch-helpers/index.ts +++ b/yarn-project/circuit-types/src/epoch-helpers/index.ts @@ -14,11 +14,13 @@ export const EmptyL1RollupConstants: L1RollupConstants = { ethereumSlotDuration: 1, }; +// REFACTOR: Merge this type with L1RollupConstants export type EpochConstants = { l1GenesisBlock: bigint; l1GenesisTime: bigint; epochDuration: number; slotDuration: number; + ethereumSlotDuration: number; }; /** Returns the slot number for a given timestamp. */ @@ -40,15 +42,21 @@ export function getSlotRangeForEpoch(epochNumber: bigint, constants: Pick, + constants: Pick, ) { const [startSlot, endSlot] = getSlotRangeForEpoch(epochNumber, constants); + const ethereumSlotsPerL2Slot = constants.slotDuration / constants.ethereumSlotDuration; return [ constants.l1GenesisTime + startSlot * BigInt(constants.slotDuration), - constants.l1GenesisTime + endSlot * BigInt(constants.slotDuration), + constants.l1GenesisTime + + endSlot * BigInt(constants.slotDuration) + + BigInt((ethereumSlotsPerL2Slot - 1) * constants.ethereumSlotDuration), ]; } diff --git a/yarn-project/end-to-end/src/e2e_epochs.test.ts b/yarn-project/end-to-end/src/e2e_epochs.test.ts index 6a5e89dfe77..539cd573cc0 100644 --- a/yarn-project/end-to-end/src/e2e_epochs.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs.test.ts @@ -94,6 +94,7 @@ describe('e2e_epochs', () => { slotDuration: L1_BLOCK_TIME_IN_S * L2_SLOT_DURATION_IN_L1_SLOTS, l1GenesisBlock: await rollup.getL1StartBlock(), l1GenesisTime: await rollup.getL1GenesisTime(), + ethereumSlotDuration: L1_BLOCK_TIME_IN_S, }; logger.info(`L2 genesis at L1 block ${constants.l1GenesisBlock} (timestamp ${constants.l1GenesisTime})`); From e867e87e4e5e4b140bf8ec3e5ee75abd24571bb1 Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> Date: Thu, 19 Dec 2024 03:10:59 +0800 Subject: [PATCH 34/34] fix: update run.sh for new devbox version (#10851) follow on from https://github.com/AztecProtocol/aztec-packages/pull/10841/files --- build-images/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-images/run.sh b/build-images/run.sh index 3a9185795ae..f524dacb47f 100755 --- a/build-images/run.sh +++ b/build-images/run.sh @@ -41,5 +41,5 @@ else -vdevbox-var-lib-docker:/var/lib/docker \ -v$HOME/.ssh/id_rsa:/home/aztec-dev/.ssh/id_rsa:ro \ --privileged \ - aztecprotocol/devbox:1.1 + aztecprotocol/devbox:1.2 fi \ No newline at end of file