@aztec/sequencer-client 0.6.7 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +21 -0
- package/package.json +10 -10
- package/src/block_builder/solo_block_builder.test.ts +8 -8
- package/src/block_builder/solo_block_builder.ts +114 -44
- package/src/block_builder/types.ts +1 -1
- package/src/publisher/viem-tx-sender.ts +4 -1
- package/src/sequencer/sequencer.ts +18 -6
- package/src/simulator/public_executor.ts +2 -16
- package/src/simulator/rollup.ts +25 -6
- package/.tsbuildinfo +0 -1
- package/dest/block_builder/index.d.ts +0 -19
- package/dest/block_builder/index.d.ts.map +0 -1
- package/dest/block_builder/index.js +0 -2
- package/dest/block_builder/solo_block_builder.d.ts +0 -76
- package/dest/block_builder/solo_block_builder.d.ts.map +0 -1
- package/dest/block_builder/solo_block_builder.js +0 -452
- package/dest/block_builder/solo_block_builder.test.d.ts +0 -3
- package/dest/block_builder/solo_block_builder.test.d.ts.map +0 -1
- package/dest/block_builder/solo_block_builder.test.js +0 -277
- package/dest/block_builder/types.d.ts +0 -12
- package/dest/block_builder/types.d.ts.map +0 -1
- package/dest/block_builder/types.js +0 -2
- package/dest/client/index.d.ts +0 -2
- package/dest/client/index.d.ts.map +0 -1
- package/dest/client/index.js +0 -2
- package/dest/client/sequencer-client.d.ts +0 -32
- package/dest/client/sequencer-client.d.ts.map +0 -1
- package/dest/client/sequencer-client.js +0 -47
- package/dest/config.d.ts +0 -12
- package/dest/config.d.ts.map +0 -1
- package/dest/config.js +0 -28
- package/dest/global_variable_builder/config.d.ts +0 -19
- package/dest/global_variable_builder/config.d.ts.map +0 -1
- package/dest/global_variable_builder/config.js +0 -2
- package/dest/global_variable_builder/global_builder.d.ts +0 -58
- package/dest/global_variable_builder/global_builder.d.ts.map +0 -1
- package/dest/global_variable_builder/global_builder.js +0 -36
- package/dest/global_variable_builder/index.d.ts +0 -12
- package/dest/global_variable_builder/index.d.ts.map +0 -1
- package/dest/global_variable_builder/index.js +0 -12
- package/dest/global_variable_builder/viem-reader.d.ts +0 -16
- package/dest/global_variable_builder/viem-reader.d.ts.map +0 -1
- package/dest/global_variable_builder/viem-reader.js +0 -37
- package/dest/index.d.ts +0 -12
- package/dest/index.d.ts.map +0 -1
- package/dest/index.js +0 -14
- package/dest/mocks/verification_keys.d.ts +0 -28
- package/dest/mocks/verification_keys.d.ts.map +0 -1
- package/dest/mocks/verification_keys.js +0 -14
- package/dest/prover/empty.d.ts +0 -41
- package/dest/prover/empty.d.ts.map +0 -1
- package/dest/prover/empty.js +0 -57
- package/dest/prover/index.d.ts +0 -40
- package/dest/prover/index.d.ts.map +0 -1
- package/dest/prover/index.js +0 -2
- package/dest/publisher/config.d.ts +0 -32
- package/dest/publisher/config.d.ts.map +0 -1
- package/dest/publisher/config.js +0 -2
- package/dest/publisher/index.d.ts +0 -10
- package/dest/publisher/index.d.ts.map +0 -1
- package/dest/publisher/index.js +0 -11
- package/dest/publisher/l1-publisher.d.ts +0 -105
- package/dest/publisher/l1-publisher.d.ts.map +0 -1
- package/dest/publisher/l1-publisher.js +0 -156
- package/dest/publisher/l1-publisher.test.d.ts +0 -2
- package/dest/publisher/l1-publisher.test.d.ts.map +0 -1
- package/dest/publisher/l1-publisher.test.js +0 -58
- package/dest/publisher/viem-tx-sender.d.ts +0 -42
- package/dest/publisher/viem-tx-sender.d.ts.map +0 -1
- package/dest/publisher/viem-tx-sender.js +0 -118
- package/dest/receiver.d.ts +0 -13
- package/dest/receiver.d.ts.map +0 -1
- package/dest/receiver.js +0 -2
- package/dest/sequencer/config.d.ts +0 -26
- package/dest/sequencer/config.d.ts.map +0 -1
- package/dest/sequencer/config.js +0 -2
- package/dest/sequencer/index.d.ts +0 -4
- package/dest/sequencer/index.d.ts.map +0 -1
- package/dest/sequencer/index.js +0 -4
- package/dest/sequencer/processed_tx.d.ts +0 -51
- package/dest/sequencer/processed_tx.d.ts.map +0 -1
- package/dest/sequencer/processed_tx.js +0 -40
- package/dest/sequencer/public_processor.d.ts +0 -75
- package/dest/sequencer/public_processor.d.ts.map +0 -1
- package/dest/sequencer/public_processor.js +0 -269
- package/dest/sequencer/public_processor.test.d.ts +0 -2
- package/dest/sequencer/public_processor.test.d.ts.map +0 -1
- package/dest/sequencer/public_processor.test.js +0 -164
- package/dest/sequencer/sequencer.d.ts +0 -133
- package/dest/sequencer/sequencer.d.ts.map +0 -1
- package/dest/sequencer/sequencer.js +0 -297
- package/dest/sequencer/sequencer.test.d.ts +0 -2
- package/dest/sequencer/sequencer.test.d.ts.map +0 -1
- package/dest/sequencer/sequencer.test.js +0 -99
- package/dest/sequencer/utils.d.ts +0 -7
- package/dest/sequencer/utils.d.ts.map +0 -1
- package/dest/sequencer/utils.js +0 -12
- package/dest/simulator/index.d.ts +0 -43
- package/dest/simulator/index.d.ts.map +0 -1
- package/dest/simulator/index.js +0 -2
- package/dest/simulator/public_executor.d.ts +0 -22
- package/dest/simulator/public_executor.d.ts.map +0 -1
- package/dest/simulator/public_executor.js +0 -99
- package/dest/simulator/public_kernel.d.ts +0 -20
- package/dest/simulator/public_kernel.d.ts.map +0 -1
- package/dest/simulator/public_kernel.js +0 -27
- package/dest/simulator/rollup.d.ts +0 -33
- package/dest/simulator/rollup.d.ts.map +0 -1
- package/dest/simulator/rollup.js +0 -41
- package/dest/utils.d.ts +0 -12
- package/dest/utils.d.ts.map +0 -1
- package/dest/utils.js +0 -16
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { AppendOnlyTreeSnapshot, BaseOrMergeRollupPublicInputs, BaseRollupInputs, ConstantBaseRollupData, GlobalVariables, MembershipWitness, NullifierLeafPreimage, PreviousKernelData, PreviousRollupData, Proof, RollupTypes, RootRollupInputs, RootRollupPublicInputs, VerificationKey } from '@aztec/circuits.js';
|
|
2
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
-
import { L2Block, MerkleTreeId } from '@aztec/types';
|
|
4
|
-
import { MerkleTreeOperations } from '@aztec/world-state';
|
|
5
|
-
import { VerificationKeys } from '../mocks/verification_keys.js';
|
|
6
|
-
import { RollupProver } from '../prover/index.js';
|
|
7
|
-
import { ProcessedTx } from '../sequencer/processed_tx.js';
|
|
8
|
-
import { RollupSimulator } from '../simulator/index.js';
|
|
9
|
-
import { BlockBuilder } from './index.js';
|
|
10
|
-
import { AllowedTreeNames } from './types.js';
|
|
11
|
-
/**
|
|
12
|
-
* Builds an L2 block out of a set of ProcessedTx's,
|
|
13
|
-
* using the base, merge, and root rollup circuits.
|
|
14
|
-
*/
|
|
15
|
-
export declare class SoloBlockBuilder implements BlockBuilder {
|
|
16
|
-
protected db: MerkleTreeOperations;
|
|
17
|
-
protected vks: VerificationKeys;
|
|
18
|
-
protected simulator: RollupSimulator;
|
|
19
|
-
protected prover: RollupProver;
|
|
20
|
-
protected debug: import("@aztec/foundation/log").DebugLogger;
|
|
21
|
-
constructor(db: MerkleTreeOperations, vks: VerificationKeys, simulator: RollupSimulator, prover: RollupProver, debug?: import("@aztec/foundation/log").DebugLogger);
|
|
22
|
-
/**
|
|
23
|
-
* Builds an L2 block with the given number containing the given txs, updating state trees.
|
|
24
|
-
* @param globalVariables - Global variables to be used in the block.
|
|
25
|
-
* @param txs - Processed transactions to include in the block.
|
|
26
|
-
* @param newL1ToL2Messages - L1 to L2 messages to be part of the block.
|
|
27
|
-
* @param timestamp - Timestamp of the block.
|
|
28
|
-
* @returns The new L2 block and a correctness proof as returned by the root rollup circuit.
|
|
29
|
-
*/
|
|
30
|
-
buildL2Block(globalVariables: GlobalVariables, txs: ProcessedTx[], newL1ToL2Messages: Fr[]): Promise<[L2Block, Proof]>;
|
|
31
|
-
protected validateTxs(txs: ProcessedTx[]): void;
|
|
32
|
-
protected getTreeSnapshot(id: MerkleTreeId): Promise<AppendOnlyTreeSnapshot>;
|
|
33
|
-
protected runCircuits(globalVariables: GlobalVariables, txs: ProcessedTx[], newL1ToL2Messages: Fr[]): Promise<[RootRollupPublicInputs, Proof]>;
|
|
34
|
-
protected baseRollupCircuit(tx1: ProcessedTx, tx2: ProcessedTx, globalVariables: GlobalVariables): Promise<[BaseOrMergeRollupPublicInputs, Proof]>;
|
|
35
|
-
protected mergeRollupCircuit(left: [BaseOrMergeRollupPublicInputs, Proof], right: [BaseOrMergeRollupPublicInputs, Proof]): Promise<[BaseOrMergeRollupPublicInputs, Proof]>;
|
|
36
|
-
protected getVerificationKey(type: RollupTypes): VerificationKey;
|
|
37
|
-
protected rootRollupCircuit(left: [BaseOrMergeRollupPublicInputs, Proof], right: [BaseOrMergeRollupPublicInputs, Proof], newL1ToL2Messages: Fr[]): Promise<[RootRollupPublicInputs, Proof]>;
|
|
38
|
-
updateHistoricBlocksTree(globalVariables: GlobalVariables): Promise<void>;
|
|
39
|
-
protected calculateBlockHash(globals: GlobalVariables): Promise<Fr>;
|
|
40
|
-
protected validateTrees(rollupOutput: BaseOrMergeRollupPublicInputs | RootRollupPublicInputs): Promise<void>;
|
|
41
|
-
protected validateRootOutput(rootOutput: RootRollupPublicInputs): Promise<void>;
|
|
42
|
-
protected validateRootTree(rootOutput: RootRollupPublicInputs, treeId: MerkleTreeId, name: 'Contract' | 'PrivateData' | 'L1ToL2Message'): Promise<void>;
|
|
43
|
-
/**
|
|
44
|
-
* Validates that the root of the public data tree matches the output of the circuit simulation.
|
|
45
|
-
* @param output - The output of the circuit simulation.
|
|
46
|
-
* Note: Public data tree is sparse, so the "next available leaf index" doesn't make sense there.
|
|
47
|
-
* For this reason we only validate root.
|
|
48
|
-
*/
|
|
49
|
-
protected validatePublicDataTreeRoot(output: BaseOrMergeRollupPublicInputs | RootRollupPublicInputs): Promise<void>;
|
|
50
|
-
protected validateTree<T extends BaseOrMergeRollupPublicInputs | RootRollupPublicInputs>(output: T, treeId: MerkleTreeId, name: AllowedTreeNames<T>): Promise<void>;
|
|
51
|
-
protected validateSimulatedTree(localTree: AppendOnlyTreeSnapshot, simulatedTree: AppendOnlyTreeSnapshot, name: 'PrivateData' | 'Contract' | 'Nullifier' | 'L1ToL2Message' | 'HistoricBlocks', label?: string): void;
|
|
52
|
-
protected getRootRollupInput(rollupOutputLeft: BaseOrMergeRollupPublicInputs, rollupProofLeft: Proof, rollupOutputRight: BaseOrMergeRollupPublicInputs, rollupProofRight: Proof, newL1ToL2Messages: Fr[]): Promise<RootRollupInputs>;
|
|
53
|
-
protected getPreviousRollupDataFromPublicInputs(rollupOutput: BaseOrMergeRollupPublicInputs, rollupProof: Proof, vk: VerificationKey): PreviousRollupData;
|
|
54
|
-
protected getKernelDataFor(tx: ProcessedTx): PreviousKernelData;
|
|
55
|
-
protected getMembershipWitnessFor<N extends number>(value: Fr, treeId: MerkleTreeId, height: N): Promise<MembershipWitness<N>>;
|
|
56
|
-
protected getHistoricTreesMembershipWitnessFor(tx: ProcessedTx): Promise<MembershipWitness<16>>;
|
|
57
|
-
protected getConstantBaseRollupData(globalVariables: GlobalVariables): Promise<ConstantBaseRollupData>;
|
|
58
|
-
protected getLowNullifierInfo(nullifier: Fr): Promise<{
|
|
59
|
-
index: number;
|
|
60
|
-
leafPreimage: NullifierLeafPreimage;
|
|
61
|
-
witness: MembershipWitness<16>;
|
|
62
|
-
} | {
|
|
63
|
-
index: {
|
|
64
|
-
index: number;
|
|
65
|
-
alreadyPresent: boolean;
|
|
66
|
-
};
|
|
67
|
-
leafPreimage: NullifierLeafPreimage;
|
|
68
|
-
witness: MembershipWitness<16>;
|
|
69
|
-
}>;
|
|
70
|
-
protected getSubtreeSiblingPath(treeId: MerkleTreeId, subtreeHeight: number): Promise<Fr[]>;
|
|
71
|
-
protected processPublicDataUpdateRequests(tx: ProcessedTx): Promise<Fr[][]>;
|
|
72
|
-
protected getPublicDataReadsSiblingPaths(tx: ProcessedTx): Promise<Fr[][]>;
|
|
73
|
-
protected buildBaseRollupInput(left: ProcessedTx, right: ProcessedTx, globalVariables: GlobalVariables): Promise<BaseRollupInputs>;
|
|
74
|
-
protected makeEmptyMembershipWitness<N extends number>(height: N): MembershipWitness<N>;
|
|
75
|
-
}
|
|
76
|
-
//# sourceMappingURL=solo_block_builder.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"solo_block_builder.d.ts","sourceRoot":"","sources":["../../src/block_builder/solo_block_builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,452 +0,0 @@
|
|
|
1
|
-
import { AppendOnlyTreeSnapshot, BaseRollupInputs, CircuitsWasm, ConstantBaseRollupData, HISTORIC_BLOCKS_TREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_HEIGHT, MembershipWitness, MergeRollupInputs, NULLIFIER_TREE_HEIGHT, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NullifierLeafPreimage, PreviousKernelData, PreviousRollupData, ROLLUP_VK_TREE_HEIGHT, RollupTypes, RootRollupInputs, RootRollupPublicInputs, VK_TREE_HEIGHT, makeTuple, } from '@aztec/circuits.js';
|
|
2
|
-
import { computeBlockHash, computeBlockHashWithGlobals, computeContractLeaf } from '@aztec/circuits.js/abis';
|
|
3
|
-
import { toFriendlyJSON } from '@aztec/circuits.js/utils';
|
|
4
|
-
import { toBigIntBE } from '@aztec/foundation/bigint-buffer';
|
|
5
|
-
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
6
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
7
|
-
import { createDebugLogger } from '@aztec/foundation/log';
|
|
8
|
-
import { assertLength } from '@aztec/foundation/serialize';
|
|
9
|
-
import { ContractData, L2Block, L2BlockL2Logs, MerkleTreeId, PublicDataWrite, TxL2Logs } from '@aztec/types';
|
|
10
|
-
import { computeGlobalVariablesHash } from '@aztec/world-state';
|
|
11
|
-
import chunk from 'lodash.chunk';
|
|
12
|
-
import flatMap from 'lodash.flatmap';
|
|
13
|
-
const frToBigInt = (fr) => toBigIntBE(fr.toBuffer());
|
|
14
|
-
const bigintToFr = (num) => new Fr(num);
|
|
15
|
-
const bigintToNum = (num) => Number(num);
|
|
16
|
-
// Denotes fields that are not used now, but will be in the future
|
|
17
|
-
const FUTURE_FR = new Fr(0n);
|
|
18
|
-
const FUTURE_NUM = 0;
|
|
19
|
-
// Denotes fields that should be deleted
|
|
20
|
-
const DELETE_FR = new Fr(0n);
|
|
21
|
-
/**
|
|
22
|
-
* Builds an L2 block out of a set of ProcessedTx's,
|
|
23
|
-
* using the base, merge, and root rollup circuits.
|
|
24
|
-
*/
|
|
25
|
-
export class SoloBlockBuilder {
|
|
26
|
-
constructor(db, vks, simulator, prover, debug = createDebugLogger('aztec:sequencer:solo-block-builder')) {
|
|
27
|
-
this.db = db;
|
|
28
|
-
this.vks = vks;
|
|
29
|
-
this.simulator = simulator;
|
|
30
|
-
this.prover = prover;
|
|
31
|
-
this.debug = debug;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Builds an L2 block with the given number containing the given txs, updating state trees.
|
|
35
|
-
* @param globalVariables - Global variables to be used in the block.
|
|
36
|
-
* @param txs - Processed transactions to include in the block.
|
|
37
|
-
* @param newL1ToL2Messages - L1 to L2 messages to be part of the block.
|
|
38
|
-
* @param timestamp - Timestamp of the block.
|
|
39
|
-
* @returns The new L2 block and a correctness proof as returned by the root rollup circuit.
|
|
40
|
-
*/
|
|
41
|
-
async buildL2Block(globalVariables, txs, newL1ToL2Messages) {
|
|
42
|
-
const [startPrivateDataTreeSnapshot, startNullifierTreeSnapshot, startContractTreeSnapshot, startPublicDataTreeSnapshot, startL1ToL2MessageTreeSnapshot, startHistoricBlocksTreeSnapshot,] = await Promise.all([
|
|
43
|
-
MerkleTreeId.PRIVATE_DATA_TREE,
|
|
44
|
-
MerkleTreeId.NULLIFIER_TREE,
|
|
45
|
-
MerkleTreeId.CONTRACT_TREE,
|
|
46
|
-
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
47
|
-
MerkleTreeId.L1_TO_L2_MESSAGES_TREE,
|
|
48
|
-
MerkleTreeId.BLOCKS_TREE,
|
|
49
|
-
].map(tree => this.getTreeSnapshot(tree)));
|
|
50
|
-
// Check txs are good for processing
|
|
51
|
-
this.validateTxs(txs);
|
|
52
|
-
// We fill the tx batch with empty txs, we process only one tx at a time for now
|
|
53
|
-
const [circuitsOutput, proof] = await this.runCircuits(globalVariables, txs, newL1ToL2Messages);
|
|
54
|
-
const { endPrivateDataTreeSnapshot, endNullifierTreeSnapshot, endContractTreeSnapshot, endPublicDataTreeRoot, endL1ToL2MessageTreeSnapshot, endHistoricBlocksTreeSnapshot, } = circuitsOutput;
|
|
55
|
-
// Collect all new nullifiers, commitments, and contracts from all txs in this block
|
|
56
|
-
const wasm = await CircuitsWasm.get();
|
|
57
|
-
const newNullifiers = flatMap(txs, tx => tx.data.end.newNullifiers);
|
|
58
|
-
const newCommitments = flatMap(txs, tx => tx.data.end.newCommitments);
|
|
59
|
-
const newContracts = flatMap(txs, tx => tx.data.end.newContracts).map(cd => computeContractLeaf(wasm, cd));
|
|
60
|
-
const newContractData = flatMap(txs, tx => tx.data.end.newContracts).map(n => new ContractData(n.contractAddress, n.portalContractAddress));
|
|
61
|
-
const newPublicDataWrites = flatMap(txs, tx => tx.data.end.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafIndex, t.newValue)));
|
|
62
|
-
const newL2ToL1Msgs = flatMap(txs, tx => tx.data.end.newL2ToL1Msgs);
|
|
63
|
-
// Consolidate logs data from all txs
|
|
64
|
-
const encryptedLogsArr = [];
|
|
65
|
-
const unencryptedLogsArr = [];
|
|
66
|
-
for (const tx of txs) {
|
|
67
|
-
const encryptedLogs = tx.encryptedLogs || new TxL2Logs([]);
|
|
68
|
-
encryptedLogsArr.push(encryptedLogs);
|
|
69
|
-
const unencryptedLogs = tx.unencryptedLogs || new TxL2Logs([]);
|
|
70
|
-
unencryptedLogsArr.push(unencryptedLogs);
|
|
71
|
-
}
|
|
72
|
-
const newEncryptedLogs = new L2BlockL2Logs(encryptedLogsArr);
|
|
73
|
-
const newUnencryptedLogs = new L2BlockL2Logs(unencryptedLogsArr);
|
|
74
|
-
const l2Block = L2Block.fromFields({
|
|
75
|
-
number: Number(globalVariables.blockNumber.value),
|
|
76
|
-
globalVariables,
|
|
77
|
-
startPrivateDataTreeSnapshot,
|
|
78
|
-
endPrivateDataTreeSnapshot,
|
|
79
|
-
startNullifierTreeSnapshot,
|
|
80
|
-
endNullifierTreeSnapshot,
|
|
81
|
-
startContractTreeSnapshot,
|
|
82
|
-
endContractTreeSnapshot,
|
|
83
|
-
startPublicDataTreeRoot: startPublicDataTreeSnapshot.root,
|
|
84
|
-
endPublicDataTreeRoot,
|
|
85
|
-
startL1ToL2MessageTreeSnapshot,
|
|
86
|
-
endL1ToL2MessageTreeSnapshot,
|
|
87
|
-
startHistoricBlocksTreeSnapshot,
|
|
88
|
-
endHistoricBlocksTreeSnapshot,
|
|
89
|
-
newCommitments,
|
|
90
|
-
newNullifiers,
|
|
91
|
-
newL2ToL1Msgs,
|
|
92
|
-
newContracts,
|
|
93
|
-
newContractData,
|
|
94
|
-
newPublicDataWrites,
|
|
95
|
-
newL1ToL2Messages,
|
|
96
|
-
newEncryptedLogs,
|
|
97
|
-
newUnencryptedLogs,
|
|
98
|
-
});
|
|
99
|
-
if (!l2Block.getCalldataHash().equals(circuitsOutput.sha256CalldataHash())) {
|
|
100
|
-
throw new Error(`Calldata hash mismatch, ${l2Block.getCalldataHash().toString('hex')} == ${circuitsOutput
|
|
101
|
-
.sha256CalldataHash()
|
|
102
|
-
.toString('hex')} `);
|
|
103
|
-
}
|
|
104
|
-
return [l2Block, proof];
|
|
105
|
-
}
|
|
106
|
-
validateTxs(txs) {
|
|
107
|
-
for (const tx of txs) {
|
|
108
|
-
for (const historicTreeRoot of [
|
|
109
|
-
'privateDataTreeRoot',
|
|
110
|
-
'contractTreeRoot',
|
|
111
|
-
'nullifierTreeRoot',
|
|
112
|
-
'l1ToL2MessagesTreeRoot',
|
|
113
|
-
]) {
|
|
114
|
-
if (tx.data.constants.blockData[historicTreeRoot].isZero()) {
|
|
115
|
-
throw new Error(`Empty ${historicTreeRoot} for tx: ${toFriendlyJSON(tx)}`);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
async getTreeSnapshot(id) {
|
|
121
|
-
const treeInfo = await this.db.getTreeInfo(id);
|
|
122
|
-
return new AppendOnlyTreeSnapshot(Fr.fromBuffer(treeInfo.root), Number(treeInfo.size));
|
|
123
|
-
}
|
|
124
|
-
async runCircuits(globalVariables, txs, newL1ToL2Messages) {
|
|
125
|
-
// Check that the length of the array of txs is a power of two
|
|
126
|
-
// See https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2
|
|
127
|
-
if (txs.length < 4 || (txs.length & (txs.length - 1)) !== 0) {
|
|
128
|
-
throw new Error(`Length of txs for the block should be a power of two and at least four (got ${txs.length})`);
|
|
129
|
-
}
|
|
130
|
-
// padArrayEnd throws if the array is already full. Otherwise it pads till we reach the required size
|
|
131
|
-
newL1ToL2Messages = padArrayEnd(newL1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
132
|
-
// Run the base rollup circuits for the txs
|
|
133
|
-
const baseRollupOutputs = [];
|
|
134
|
-
for (const pair of chunk(txs, 2)) {
|
|
135
|
-
const [tx1, tx2] = pair;
|
|
136
|
-
baseRollupOutputs.push(await this.baseRollupCircuit(tx1, tx2, globalVariables));
|
|
137
|
-
}
|
|
138
|
-
// Run merge rollups in layers until we have only two outputs
|
|
139
|
-
let mergeRollupInputs = baseRollupOutputs;
|
|
140
|
-
let mergeRollupOutputs = [];
|
|
141
|
-
while (mergeRollupInputs.length > 2) {
|
|
142
|
-
for (const pair of chunk(mergeRollupInputs, 2)) {
|
|
143
|
-
const [r1, r2] = pair;
|
|
144
|
-
mergeRollupOutputs.push(await this.mergeRollupCircuit(r1, r2));
|
|
145
|
-
}
|
|
146
|
-
mergeRollupInputs = mergeRollupOutputs;
|
|
147
|
-
mergeRollupOutputs = [];
|
|
148
|
-
}
|
|
149
|
-
// Run the root rollup with the last two merge rollups (or base, if no merge layers)
|
|
150
|
-
const [mergeOutputLeft, mergeOutputRight] = mergeRollupInputs;
|
|
151
|
-
return this.rootRollupCircuit(mergeOutputLeft, mergeOutputRight, newL1ToL2Messages);
|
|
152
|
-
}
|
|
153
|
-
async baseRollupCircuit(tx1, tx2, globalVariables) {
|
|
154
|
-
this.debug(`Running base rollup for ${tx1.hash} ${tx2.hash}`);
|
|
155
|
-
const rollupInput = await this.buildBaseRollupInput(tx1, tx2, globalVariables);
|
|
156
|
-
const rollupOutput = await this.simulator.baseRollupCircuit(rollupInput);
|
|
157
|
-
await this.validateTrees(rollupOutput);
|
|
158
|
-
const proof = await this.prover.getBaseRollupProof(rollupInput, rollupOutput);
|
|
159
|
-
return [rollupOutput, proof];
|
|
160
|
-
}
|
|
161
|
-
async mergeRollupCircuit(left, right) {
|
|
162
|
-
const vk = this.getVerificationKey(left[0].rollupType);
|
|
163
|
-
const mergeInputs = new MergeRollupInputs([
|
|
164
|
-
this.getPreviousRollupDataFromPublicInputs(left[0], left[1], vk),
|
|
165
|
-
this.getPreviousRollupDataFromPublicInputs(right[0], right[1], vk),
|
|
166
|
-
]);
|
|
167
|
-
this.debug(`Running merge rollup circuit`);
|
|
168
|
-
const output = await this.simulator.mergeRollupCircuit(mergeInputs);
|
|
169
|
-
const proof = await this.prover.getMergeRollupProof(mergeInputs, output);
|
|
170
|
-
return [output, proof];
|
|
171
|
-
}
|
|
172
|
-
getVerificationKey(type) {
|
|
173
|
-
switch (type) {
|
|
174
|
-
case RollupTypes.Base:
|
|
175
|
-
return this.vks.baseRollupCircuit;
|
|
176
|
-
case RollupTypes.Merge:
|
|
177
|
-
return this.vks.mergeRollupCircuit;
|
|
178
|
-
default:
|
|
179
|
-
throw new Error(`No verification key available for ${type}`);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
async rootRollupCircuit(left, right, newL1ToL2Messages) {
|
|
183
|
-
this.debug(`Running root rollup circuit`);
|
|
184
|
-
const rootInput = await this.getRootRollupInput(...left, ...right, newL1ToL2Messages);
|
|
185
|
-
// Update the local trees to include the new l1 to l2 messages
|
|
186
|
-
await this.db.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGES_TREE, newL1ToL2Messages.map(m => m.toBuffer()));
|
|
187
|
-
// Simulate and get proof for the root circuit
|
|
188
|
-
const rootOutput = await this.simulator.rootRollupCircuit(rootInput);
|
|
189
|
-
const rootProof = await this.prover.getRootRollupProof(rootInput, rootOutput);
|
|
190
|
-
// Update the root trees with the latest data and contract tree roots,
|
|
191
|
-
// and validate them against the output of the root circuit simulation
|
|
192
|
-
this.debug(`Updating and validating root trees`);
|
|
193
|
-
const globalVariablesHash = await computeGlobalVariablesHash(left[0].constants.globalVariables);
|
|
194
|
-
await this.db.updateLatestGlobalVariablesHash(globalVariablesHash);
|
|
195
|
-
await this.db.updateHistoricBlocksTree(globalVariablesHash);
|
|
196
|
-
await this.validateRootOutput(rootOutput);
|
|
197
|
-
return [rootOutput, rootProof];
|
|
198
|
-
}
|
|
199
|
-
async updateHistoricBlocksTree(globalVariables) {
|
|
200
|
-
// Calculate the block hash and add it to the historic block hashes tree
|
|
201
|
-
const blockHash = await this.calculateBlockHash(globalVariables);
|
|
202
|
-
await this.db.appendLeaves(MerkleTreeId.BLOCKS_TREE, [blockHash.toBuffer()]);
|
|
203
|
-
}
|
|
204
|
-
async calculateBlockHash(globals) {
|
|
205
|
-
const [privateDataTreeRoot, nullifierTreeRoot, contractTreeRoot, publicDataTreeRoot, l1ToL2MessageTreeRoot] = (await Promise.all([
|
|
206
|
-
MerkleTreeId.PRIVATE_DATA_TREE,
|
|
207
|
-
MerkleTreeId.NULLIFIER_TREE,
|
|
208
|
-
MerkleTreeId.CONTRACT_TREE,
|
|
209
|
-
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
210
|
-
MerkleTreeId.L1_TO_L2_MESSAGES_TREE,
|
|
211
|
-
].map(tree => this.getTreeSnapshot(tree)))).map(r => r.root);
|
|
212
|
-
const wasm = await CircuitsWasm.get();
|
|
213
|
-
const blockHash = computeBlockHashWithGlobals(wasm, globals, privateDataTreeRoot, nullifierTreeRoot, contractTreeRoot, l1ToL2MessageTreeRoot, publicDataTreeRoot);
|
|
214
|
-
return blockHash;
|
|
215
|
-
}
|
|
216
|
-
// Validate that the new roots we calculated from manual insertions match the outputs of the simulation
|
|
217
|
-
async validateTrees(rollupOutput) {
|
|
218
|
-
await Promise.all([
|
|
219
|
-
this.validateTree(rollupOutput, MerkleTreeId.CONTRACT_TREE, 'Contract'),
|
|
220
|
-
this.validateTree(rollupOutput, MerkleTreeId.PRIVATE_DATA_TREE, 'PrivateData'),
|
|
221
|
-
this.validateTree(rollupOutput, MerkleTreeId.NULLIFIER_TREE, 'Nullifier'),
|
|
222
|
-
this.validatePublicDataTreeRoot(rollupOutput),
|
|
223
|
-
]);
|
|
224
|
-
}
|
|
225
|
-
// Validate that the roots of all local trees match the output of the root circuit simulation
|
|
226
|
-
async validateRootOutput(rootOutput) {
|
|
227
|
-
await Promise.all([
|
|
228
|
-
this.validateTrees(rootOutput),
|
|
229
|
-
this.validateTree(rootOutput, MerkleTreeId.BLOCKS_TREE, 'HistoricBlocks'),
|
|
230
|
-
this.validateTree(rootOutput, MerkleTreeId.L1_TO_L2_MESSAGES_TREE, 'L1ToL2Message'),
|
|
231
|
-
]);
|
|
232
|
-
}
|
|
233
|
-
// Helper for validating a roots tree against a circuit simulation output
|
|
234
|
-
async validateRootTree(rootOutput, treeId, name) {
|
|
235
|
-
const localTree = await this.getTreeSnapshot(treeId);
|
|
236
|
-
const simulatedTree = rootOutput[`endTreeOfHistoric${name}TreeRootsSnapshot`];
|
|
237
|
-
this.validateSimulatedTree(localTree, simulatedTree, name, `Roots ${name}`);
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Validates that the root of the public data tree matches the output of the circuit simulation.
|
|
241
|
-
* @param output - The output of the circuit simulation.
|
|
242
|
-
* Note: Public data tree is sparse, so the "next available leaf index" doesn't make sense there.
|
|
243
|
-
* For this reason we only validate root.
|
|
244
|
-
*/
|
|
245
|
-
async validatePublicDataTreeRoot(output) {
|
|
246
|
-
const localTree = await this.getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE);
|
|
247
|
-
const simulatedTreeRoot = output[`endPublicDataTreeRoot`];
|
|
248
|
-
if (!simulatedTreeRoot.toBuffer().equals(localTree.root.toBuffer())) {
|
|
249
|
-
throw new Error(`PublicData tree root mismatch (local ${localTree.root}, simulated ${simulatedTreeRoot})`);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
// Helper for validating a non-roots tree against a circuit simulation output
|
|
253
|
-
async validateTree(output, treeId, name) {
|
|
254
|
-
if ('endL1ToL2MessageTreeSnapshot' in output && !(output instanceof RootRollupPublicInputs)) {
|
|
255
|
-
throw new Error(`The name 'L1ToL2Message' can only be used when output is of type RootRollupPublicInputs`);
|
|
256
|
-
}
|
|
257
|
-
const localTree = await this.getTreeSnapshot(treeId);
|
|
258
|
-
const simulatedTree = output[`end${name}TreeSnapshot`];
|
|
259
|
-
this.validateSimulatedTree(localTree, simulatedTree, name);
|
|
260
|
-
}
|
|
261
|
-
// Helper for comparing two trees snapshots
|
|
262
|
-
validateSimulatedTree(localTree, simulatedTree, name, label) {
|
|
263
|
-
if (!simulatedTree.root.toBuffer().equals(localTree.root.toBuffer())) {
|
|
264
|
-
throw new Error(`${label ?? name} tree root mismatch (local ${localTree.root}, simulated ${simulatedTree.root})`);
|
|
265
|
-
}
|
|
266
|
-
if (simulatedTree.nextAvailableLeafIndex !== localTree.nextAvailableLeafIndex) {
|
|
267
|
-
throw new Error(`${label ?? name} tree next available leaf index mismatch (local ${localTree.nextAvailableLeafIndex}, simulated ${simulatedTree.nextAvailableLeafIndex})`);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
// Builds the inputs for the root rollup circuit, without making any changes to trees
|
|
271
|
-
async getRootRollupInput(rollupOutputLeft, rollupProofLeft, rollupOutputRight, rollupProofRight, newL1ToL2Messages) {
|
|
272
|
-
const vk = this.getVerificationKey(rollupOutputLeft.rollupType);
|
|
273
|
-
const previousRollupData = [
|
|
274
|
-
this.getPreviousRollupDataFromPublicInputs(rollupOutputLeft, rollupProofLeft, vk),
|
|
275
|
-
this.getPreviousRollupDataFromPublicInputs(rollupOutputRight, rollupProofRight, vk),
|
|
276
|
-
];
|
|
277
|
-
const getRootTreeSiblingPath = async (treeId) => {
|
|
278
|
-
// TODO: Synchronize these operations into the tree db to avoid race conditions
|
|
279
|
-
const { size } = await this.db.getTreeInfo(treeId);
|
|
280
|
-
// TODO: Check for off-by-one errors
|
|
281
|
-
const path = await this.db.getSiblingPath(treeId, size);
|
|
282
|
-
return path.toFieldArray();
|
|
283
|
-
};
|
|
284
|
-
const newL1ToL2MessageTreeRootSiblingPath = await this.getSubtreeSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGES_TREE, L1_TO_L2_MSG_SUBTREE_HEIGHT);
|
|
285
|
-
// Get tree snapshots
|
|
286
|
-
const startL1ToL2MessageTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_TREE);
|
|
287
|
-
// Get historic block tree roots
|
|
288
|
-
const startHistoricBlocksTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.BLOCKS_TREE);
|
|
289
|
-
const newHistoricBlocksTreeSiblingPath = await getRootTreeSiblingPath(MerkleTreeId.BLOCKS_TREE);
|
|
290
|
-
return RootRollupInputs.from({
|
|
291
|
-
previousRollupData,
|
|
292
|
-
newL1ToL2Messages,
|
|
293
|
-
newL1ToL2MessageTreeRootSiblingPath,
|
|
294
|
-
startL1ToL2MessageTreeSnapshot,
|
|
295
|
-
startHistoricBlocksTreeSnapshot,
|
|
296
|
-
newHistoricBlocksTreeSiblingPath,
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
getPreviousRollupDataFromPublicInputs(rollupOutput, rollupProof, vk) {
|
|
300
|
-
return new PreviousRollupData(rollupOutput, rollupProof, vk,
|
|
301
|
-
// MembershipWitness for a VK tree to be implemented in the future
|
|
302
|
-
FUTURE_NUM, new MembershipWitness(ROLLUP_VK_TREE_HEIGHT, BigInt(FUTURE_NUM), makeTuple(ROLLUP_VK_TREE_HEIGHT, () => FUTURE_FR)));
|
|
303
|
-
}
|
|
304
|
-
getKernelDataFor(tx) {
|
|
305
|
-
return new PreviousKernelData(tx.data, tx.proof,
|
|
306
|
-
// VK for the kernel circuit
|
|
307
|
-
this.vks.privateKernelCircuit,
|
|
308
|
-
// MembershipWitness for a VK tree to be implemented in the future
|
|
309
|
-
FUTURE_NUM, assertLength(Array(VK_TREE_HEIGHT).fill(FUTURE_FR), VK_TREE_HEIGHT));
|
|
310
|
-
}
|
|
311
|
-
// Scan a tree searching for a specific value and return a membership witness proof for it
|
|
312
|
-
async getMembershipWitnessFor(value, treeId, height) {
|
|
313
|
-
// If this is an empty tx, then just return zeroes
|
|
314
|
-
if (value.isZero())
|
|
315
|
-
return this.makeEmptyMembershipWitness(height);
|
|
316
|
-
const index = await this.db.findLeafIndex(treeId, value.toBuffer());
|
|
317
|
-
if (index === undefined) {
|
|
318
|
-
throw new Error(`Leaf with value ${value} not found in tree ${MerkleTreeId[treeId]}`);
|
|
319
|
-
}
|
|
320
|
-
const path = await this.db.getSiblingPath(treeId, index);
|
|
321
|
-
return new MembershipWitness(height, index, assertLength(path.toFieldArray(), height));
|
|
322
|
-
}
|
|
323
|
-
async getHistoricTreesMembershipWitnessFor(tx) {
|
|
324
|
-
const wasm = await CircuitsWasm.get();
|
|
325
|
-
const blockData = tx.data.constants.blockData;
|
|
326
|
-
const { privateDataTreeRoot, nullifierTreeRoot, contractTreeRoot, l1ToL2MessagesTreeRoot, publicDataTreeRoot } = blockData;
|
|
327
|
-
const blockHash = computeBlockHash(wasm, blockData.globalVariablesHash, privateDataTreeRoot, nullifierTreeRoot, contractTreeRoot, l1ToL2MessagesTreeRoot, publicDataTreeRoot);
|
|
328
|
-
return this.getMembershipWitnessFor(blockHash, MerkleTreeId.BLOCKS_TREE, HISTORIC_BLOCKS_TREE_HEIGHT);
|
|
329
|
-
}
|
|
330
|
-
async getConstantBaseRollupData(globalVariables) {
|
|
331
|
-
return ConstantBaseRollupData.from({
|
|
332
|
-
baseRollupVkHash: DELETE_FR,
|
|
333
|
-
mergeRollupVkHash: DELETE_FR,
|
|
334
|
-
privateKernelVkTreeRoot: FUTURE_FR,
|
|
335
|
-
publicKernelVkTreeRoot: FUTURE_FR,
|
|
336
|
-
startHistoricBlocksTreeRootsSnapshot: await this.getTreeSnapshot(MerkleTreeId.BLOCKS_TREE),
|
|
337
|
-
globalVariables,
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
async getLowNullifierInfo(nullifier) {
|
|
341
|
-
// Return empty nullifier info for an empty tx
|
|
342
|
-
if (nullifier.value === 0n) {
|
|
343
|
-
return {
|
|
344
|
-
index: 0,
|
|
345
|
-
leafPreimage: NullifierLeafPreimage.empty(),
|
|
346
|
-
witness: this.makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT),
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
const tree = MerkleTreeId.NULLIFIER_TREE;
|
|
350
|
-
const prevValueIndex = await this.db.getPreviousValueIndex(tree, frToBigInt(nullifier));
|
|
351
|
-
const prevValueInfo = await this.db.getLeafData(tree, prevValueIndex.index);
|
|
352
|
-
if (!prevValueInfo)
|
|
353
|
-
throw new Error(`Nullifier tree should have one initial leaf`);
|
|
354
|
-
const prevValueSiblingPath = await this.db.getSiblingPath(tree, BigInt(prevValueIndex.index));
|
|
355
|
-
return {
|
|
356
|
-
index: prevValueIndex,
|
|
357
|
-
leafPreimage: new NullifierLeafPreimage(bigintToFr(prevValueInfo.value), bigintToFr(prevValueInfo.nextValue), bigintToNum(prevValueInfo.nextIndex)),
|
|
358
|
-
witness: new MembershipWitness(NULLIFIER_TREE_HEIGHT, BigInt(prevValueIndex.index), assertLength(prevValueSiblingPath.toFieldArray(), NULLIFIER_TREE_HEIGHT)),
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
async getSubtreeSiblingPath(treeId, subtreeHeight) {
|
|
362
|
-
const nextAvailableLeafIndex = await this.db.getTreeInfo(treeId).then(t => t.size);
|
|
363
|
-
const fullSiblingPath = await this.db.getSiblingPath(treeId, nextAvailableLeafIndex);
|
|
364
|
-
// Drop the first subtreeHeight items since we only care about the path to the subtree root
|
|
365
|
-
return fullSiblingPath.getSubtreeSiblingPath(subtreeHeight).toFieldArray();
|
|
366
|
-
}
|
|
367
|
-
async processPublicDataUpdateRequests(tx) {
|
|
368
|
-
const newPublicDataUpdateRequestsSiblingPaths = [];
|
|
369
|
-
for (const publicDataUpdateRequest of tx.data.end.publicDataUpdateRequests) {
|
|
370
|
-
const index = publicDataUpdateRequest.leafIndex.value;
|
|
371
|
-
const path = await this.db.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, index);
|
|
372
|
-
await this.db.updateLeaf(MerkleTreeId.PUBLIC_DATA_TREE, publicDataUpdateRequest.newValue.toBuffer(), index);
|
|
373
|
-
newPublicDataUpdateRequestsSiblingPaths.push(path.toFieldArray());
|
|
374
|
-
}
|
|
375
|
-
return newPublicDataUpdateRequestsSiblingPaths;
|
|
376
|
-
}
|
|
377
|
-
async getPublicDataReadsSiblingPaths(tx) {
|
|
378
|
-
const newPublicDataReadsSiblingPaths = [];
|
|
379
|
-
for (const publicDataRead of tx.data.end.publicDataReads) {
|
|
380
|
-
const index = publicDataRead.leafIndex.value;
|
|
381
|
-
const path = await this.db.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, index);
|
|
382
|
-
newPublicDataReadsSiblingPaths.push(path.toFieldArray());
|
|
383
|
-
}
|
|
384
|
-
return newPublicDataReadsSiblingPaths;
|
|
385
|
-
}
|
|
386
|
-
// Builds the base rollup inputs, updating the contract, nullifier, and data trees in the process
|
|
387
|
-
async buildBaseRollupInput(left, right, globalVariables) {
|
|
388
|
-
const wasm = await CircuitsWasm.get();
|
|
389
|
-
// Get trees info before any changes hit
|
|
390
|
-
const constants = await this.getConstantBaseRollupData(globalVariables);
|
|
391
|
-
const startNullifierTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE);
|
|
392
|
-
const startContractTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.CONTRACT_TREE);
|
|
393
|
-
const startPrivateDataTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE);
|
|
394
|
-
const startPublicDataTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE);
|
|
395
|
-
const startHistoricBlocksTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.BLOCKS_TREE);
|
|
396
|
-
// Get the subtree sibling paths for the circuit
|
|
397
|
-
const newCommitmentsSubtreeSiblingPath = await this.getSubtreeSiblingPath(MerkleTreeId.PRIVATE_DATA_TREE, BaseRollupInputs.PRIVATE_DATA_SUBTREE_HEIGHT);
|
|
398
|
-
const newContractsSubtreeSiblingPath = await this.getSubtreeSiblingPath(MerkleTreeId.CONTRACT_TREE, BaseRollupInputs.CONTRACT_SUBTREE_HEIGHT);
|
|
399
|
-
// Update the contract and private data trees with the new items being inserted to get the new roots
|
|
400
|
-
// that will be used by the next iteration of the base rollup circuit, skipping the empty ones
|
|
401
|
-
const newContracts = flatMap([left, right], tx => tx.data.end.newContracts.map(cd => computeContractLeaf(wasm, cd)));
|
|
402
|
-
const newCommitments = flatMap([left, right], tx => tx.data.end.newCommitments.map(x => x.toBuffer()));
|
|
403
|
-
await this.db.appendLeaves(MerkleTreeId.CONTRACT_TREE, newContracts.map(x => x.toBuffer()));
|
|
404
|
-
await this.db.appendLeaves(MerkleTreeId.PRIVATE_DATA_TREE, newCommitments);
|
|
405
|
-
// Update the public data tree and get membership witnesses.
|
|
406
|
-
// All public data reads are checked against the unmodified data root when the corresponding tx started,
|
|
407
|
-
// so it's the unmodified tree for tx1, and the one after applying tx1 update request for tx2.
|
|
408
|
-
// Update requests are checked against the tree as it is iteratively updated.
|
|
409
|
-
// See https://github.com/AztecProtocol/aztec3-packages/issues/270#issuecomment-1522258200
|
|
410
|
-
const leftPublicDataReadSiblingPaths = await this.getPublicDataReadsSiblingPaths(left);
|
|
411
|
-
const leftPublicDataUpdateRequestsSiblingPaths = await this.processPublicDataUpdateRequests(left);
|
|
412
|
-
const rightPublicDataReadSiblingPaths = await this.getPublicDataReadsSiblingPaths(right);
|
|
413
|
-
const rightPublicDataUpdateRequestsSiblingPaths = await this.processPublicDataUpdateRequests(right);
|
|
414
|
-
const newPublicDataReadsSiblingPaths = [...leftPublicDataReadSiblingPaths, ...rightPublicDataReadSiblingPaths];
|
|
415
|
-
const newPublicDataUpdateRequestsSiblingPaths = [
|
|
416
|
-
...leftPublicDataUpdateRequestsSiblingPaths,
|
|
417
|
-
...rightPublicDataUpdateRequestsSiblingPaths,
|
|
418
|
-
];
|
|
419
|
-
// Update the nullifier tree, capturing the low nullifier info for each individual operation
|
|
420
|
-
const newNullifiers = [...left.data.end.newNullifiers, ...right.data.end.newNullifiers];
|
|
421
|
-
const [nullifierWitnessLeaves, newNullifiersSubtreeSiblingPath] = await this.db.batchInsert(MerkleTreeId.NULLIFIER_TREE, newNullifiers.map(fr => fr.toBuffer()), BaseRollupInputs.NULLIFIER_SUBTREE_HEIGHT);
|
|
422
|
-
if (nullifierWitnessLeaves === undefined) {
|
|
423
|
-
throw new Error(`Could not craft nullifier batch insertion proofs`);
|
|
424
|
-
}
|
|
425
|
-
// Extract witness objects from returned data
|
|
426
|
-
const lowNullifierMembershipWitnesses = nullifierWitnessLeaves.map(l => MembershipWitness.fromBufferArray(l.index, assertLength(l.siblingPath.toBufferArray(), NULLIFIER_TREE_HEIGHT)));
|
|
427
|
-
return BaseRollupInputs.from({
|
|
428
|
-
constants,
|
|
429
|
-
startNullifierTreeSnapshot,
|
|
430
|
-
startContractTreeSnapshot,
|
|
431
|
-
startPrivateDataTreeSnapshot,
|
|
432
|
-
startPublicDataTreeRoot: startPublicDataTreeSnapshot.root,
|
|
433
|
-
startHistoricBlocksTreeSnapshot,
|
|
434
|
-
newCommitmentsSubtreeSiblingPath,
|
|
435
|
-
newContractsSubtreeSiblingPath,
|
|
436
|
-
newNullifiersSubtreeSiblingPath: newNullifiersSubtreeSiblingPath.toFieldArray(),
|
|
437
|
-
newPublicDataUpdateRequestsSiblingPaths,
|
|
438
|
-
newPublicDataReadsSiblingPaths,
|
|
439
|
-
lowNullifierLeafPreimages: nullifierWitnessLeaves.map(({ leafData }) => new NullifierLeafPreimage(new Fr(leafData.value), new Fr(leafData.nextValue), Number(leafData.nextIndex))),
|
|
440
|
-
lowNullifierMembershipWitness: lowNullifierMembershipWitnesses,
|
|
441
|
-
kernelData: [this.getKernelDataFor(left), this.getKernelDataFor(right)],
|
|
442
|
-
historicBlocksTreeRootMembershipWitnesses: [
|
|
443
|
-
await this.getHistoricTreesMembershipWitnessFor(left),
|
|
444
|
-
await this.getHistoricTreesMembershipWitnessFor(right),
|
|
445
|
-
],
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
makeEmptyMembershipWitness(height) {
|
|
449
|
-
return new MembershipWitness(height, 0n, makeTuple(height, () => Fr.ZERO));
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29sb19ibG9ja19idWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Jsb2NrX2J1aWxkZXIvc29sb19ibG9ja19idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxzQkFBc0IsRUFFdEIsZ0JBQWdCLEVBQ2hCLFlBQVksRUFDWixzQkFBc0IsRUFFdEIsMkJBQTJCLEVBQzNCLDJCQUEyQixFQUMzQixpQkFBaUIsRUFDakIsaUJBQWlCLEVBQ2pCLHFCQUFxQixFQUNyQixtQ0FBbUMsRUFDbkMscUJBQXFCLEVBQ3JCLGtCQUFrQixFQUNsQixrQkFBa0IsRUFFbEIscUJBQXFCLEVBQ3JCLFdBQVcsRUFDWCxnQkFBZ0IsRUFDaEIsc0JBQXNCLEVBQ3RCLGNBQWMsRUFFZCxTQUFTLEdBQ1YsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsMkJBQTJCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM3RyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzdELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDOUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzNELE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUM3RyxPQUFPLEVBQXdCLDBCQUEwQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFdEYsT0FBTyxLQUFLLE1BQU0sY0FBYyxDQUFDO0FBQ2pDLE9BQU8sT0FBTyxNQUFNLGdCQUFnQixDQUFDO0FBU3JDLE1BQU0sVUFBVSxHQUFHLENBQUMsRUFBTSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7QUFDekQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxHQUFXLEVBQUUsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2hELE1BQU0sV0FBVyxHQUFHLENBQUMsR0FBVyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7QUFFakQsa0VBQWtFO0FBQ2xFLE1BQU0sU0FBUyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzdCLE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQztBQUVyQix3Q0FBd0M7QUFDeEMsTUFBTSxTQUFTLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFFN0I7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLGdCQUFnQjtJQUMzQixZQUNZLEVBQXdCLEVBQ3hCLEdBQXFCLEVBQ3JCLFNBQTBCLEVBQzFCLE1BQW9CLEVBQ3BCLFFBQVEsaUJBQWlCLENBQUMsb0NBQW9DLENBQUM7UUFKL0QsT0FBRSxHQUFGLEVBQUUsQ0FBc0I7UUFDeEIsUUFBRyxHQUFILEdBQUcsQ0FBa0I7UUFDckIsY0FBUyxHQUFULFNBQVMsQ0FBaUI7UUFDMUIsV0FBTSxHQUFOLE1BQU0sQ0FBYztRQUNwQixVQUFLLEdBQUwsS0FBSyxDQUEwRDtJQUN4RSxDQUFDO0lBRUo7Ozs7Ozs7T0FPRztJQUNJLEtBQUssQ0FBQyxZQUFZLENBQ3ZCLGVBQWdDLEVBQ2hDLEdBQWtCLEVBQ2xCLGlCQUF1QjtRQUV2QixNQUFNLENBQ0osNEJBQTRCLEVBQzVCLDBCQUEwQixFQUMxQix5QkFBeUIsRUFDekIsMkJBQTJCLEVBQzNCLDhCQUE4QixFQUM5QiwrQkFBK0IsRUFDaEMsR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQ25CO1lBQ0UsWUFBWSxDQUFDLGlCQUFpQjtZQUM5QixZQUFZLENBQUMsY0FBYztZQUMzQixZQUFZLENBQUMsYUFBYTtZQUMxQixZQUFZLENBQUMsZ0JBQWdCO1lBQzdCLFlBQVksQ0FBQyxzQkFBc0I7WUFDbkMsWUFBWSxDQUFDLFdBQVc7U0FDekIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQzFDLENBQUM7UUFFRixvQ0FBb0M7UUFDcEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUV0QixnRkFBZ0Y7UUFDaEYsTUFBTSxDQUFDLGNBQWMsRUFBRSxLQUFLLENBQUMsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxFQUFFLEdBQUcsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBRWhHLE1BQU0sRUFDSiwwQkFBMEIsRUFDMUIsd0JBQXdCLEVBQ3hCLHVCQUF1QixFQUN2QixxQkFBcUIsRUFDckIsNEJBQTRCLEVBQzVCLDZCQUE2QixHQUM5QixHQUFHLGNBQWMsQ0FBQztRQUVuQixvRkFBb0Y7UUFDcEYsTUFBTSxJQUFJLEdBQUcsTUFBTSxZQUFZLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdEMsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3BFLE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN0RSxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDM0csTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDLEdBQUcsQ0FDdEUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLFlBQVksQ0FBQyxDQUFDLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUNsRSxDQUFDO1FBQ0YsTUFBTSxtQkFBbUIsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQzVDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksZUFBZSxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQzVGLENBQUM7UUFDRixNQUFNLGFBQWEsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFcEUscUNBQXFDO1FBQ3JDLE1BQU0sZ0JBQWdCLEdBQWUsRUFBRSxDQUFDO1FBQ3hDLE1BQU0sa0JBQWtCLEdBQWUsRUFBRSxDQUFDO1FBQzFDLEtBQUssTUFBTSxFQUFFLElBQUksR0FBRyxFQUFFO1lBQ3BCLE1BQU0sYUFBYSxHQUFHLEVBQUUsQ0FBQyxhQUFhLElBQUksSUFBSSxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDM0QsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sZUFBZSxHQUFHLEVBQUUsQ0FBQyxlQUFlLElBQUksSUFBSSxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDL0Qsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1NBQzFDO1FBQ0QsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzdELE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxhQUFhLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUVqRSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDO1lBQ2pDLE1BQU0sRUFBRSxNQUFNLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUM7WUFDakQsZUFBZTtZQUNmLDRCQUE0QjtZQUM1QiwwQkFBMEI7WUFDMUIsMEJBQTBCO1lBQzFCLHdCQUF3QjtZQUN4Qix5QkFBeUI7WUFDekIsdUJBQXVCO1lBQ3ZCLHVCQUF1QixFQUFFLDJCQUEyQixDQUFDLElBQUk7WUFDekQscUJBQXFCO1lBQ3JCLDhCQUE4QjtZQUM5Qiw0QkFBNEI7WUFDNUIsK0JBQStCO1lBQy9CLDZCQUE2QjtZQUM3QixjQUFjO1lBQ2QsYUFBYTtZQUNiLGFBQWE7WUFDYixZQUFZO1lBQ1osZUFBZTtZQUNmLG1CQUFtQjtZQUNuQixpQkFBaUI7WUFDakIsZ0JBQWdCO1lBQ2hCLGtCQUFrQjtTQUNuQixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxFQUFFO1lBQzFFLE1BQU0sSUFBSSxLQUFLLENBQ2IsMkJBQTJCLE9BQU8sQ0FBQyxlQUFlLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sY0FBYztpQkFDdEYsa0JBQWtCLEVBQUU7aUJBQ3BCLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUN0QixDQUFDO1NBQ0g7UUFFRCxPQUFPLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzFCLENBQUM7SUFFUyxXQUFXLENBQUMsR0FBa0I7UUFDdEMsS0FBSyxNQUFNLEVBQUUsSUFBSSxHQUFHLEVBQUU7WUFDcEIsS0FBSyxNQUFNLGdCQUFnQixJQUFJO2dCQUM3QixxQkFBcUI7Z0JBQ3JCLGtCQUFrQjtnQkFDbEIsbUJBQW1CO2dCQUNuQix3QkFBd0I7YUFDaEIsRUFBRTtnQkFDVixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO29CQUMxRCxNQUFNLElBQUksS0FBSyxDQUFDLFNBQVMsZ0JBQWdCLFlBQVksY0FBYyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztpQkFDNUU7YUFDRjtTQUNGO0lBQ0gsQ0FBQztJQUVTLEtBQUssQ0FBQyxlQUFlLENBQUMsRUFBZ0I7UUFDOUMsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUMvQyxPQUFPLElBQUksc0JBQXNCLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3pGLENBQUM7SUFFUyxLQUFLLENBQUMsV0FBVyxDQUN6QixlQUFnQyxFQUNoQyxHQUFrQixFQUNsQixpQkFBdUI7UUFFdkIsOERBQThEO1FBQzlELCtFQUErRTtRQUMvRSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDM0QsTUFBTSxJQUFJLEtBQUssQ0FBQywrRUFBK0UsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7U0FDL0c7UUFFRCxxR0FBcUc7UUFDckcsaUJBQWlCLEdBQUcsV0FBVyxDQUFDLGlCQUFpQixFQUFFLEVBQUUsQ0FBQyxJQUFJLEVBQUUsbUNBQW1DLENBQUMsQ0FBQztRQUVqRywyQ0FBMkM7UUFDM0MsTUFBTSxpQkFBaUIsR0FBNkMsRUFBRSxDQUFDO1FBQ3ZFLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtZQUNoQyxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztZQUN4QixpQkFBaUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDO1NBQ2pGO1FBRUQsNkRBQTZEO1FBQzdELElBQUksaUJBQWlCLEdBQTZDLGlCQUFpQixDQUFDO1FBQ3BGLElBQUksa0JBQWtCLEdBQTZDLEVBQUUsQ0FBQztRQUN0RSxPQUFPLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDbkMsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLEVBQUU7Z0JBQzlDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO2dCQUN0QixrQkFBa0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDaEU7WUFDRCxpQkFBaUIsR0FBRyxrQkFBa0IsQ0FBQztZQUN2QyxrQkFBa0IsR0FBRyxFQUFFLENBQUM7U0FDekI7UUFFRCxvRkFBb0Y7UUFDcEYsTUFBTSxDQUFDLGVBQWUsRUFBRSxnQkFBZ0IsQ0FBQyxHQUFHLGlCQUFpQixDQUFDO1FBQzlELE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3RGLENBQUM7SUFFUyxLQUFLLENBQUMsaUJBQWlCLENBQy9CLEdBQWdCLEVBQ2hCLEdBQWdCLEVBQ2hCLGVBQWdDO1FBRWhDLElBQUksQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDOUQsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUMvRSxNQUFNLFlBQVksR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDekUsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDOUUsT0FBTyxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRVMsS0FBSyxDQUFDLGtCQUFrQixDQUNoQyxJQUE0QyxFQUM1QyxLQUE2QztRQUU3QyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3ZELE1BQU0sV0FBVyxHQUFHLElBQUksaUJBQWlCLENBQUM7WUFDeEMsSUFBSSxDQUFDLHFDQUFxQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ2hFLElBQUksQ0FBQyxxQ0FBcUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztTQUNuRSxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7UUFDM0MsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3BFLE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDekUsT0FBTyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBRVMsa0JBQWtCLENBQUMsSUFBaUI7UUFDNUMsUUFBUSxJQUFJLEVBQUU7WUFDWixLQUFLLFdBQVcsQ0FBQyxJQUFJO2dCQUNuQixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUM7WUFDcEMsS0FBSyxXQUFXLENBQUMsS0FBSztnQkFDcEIsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDO1lBQ3JDO2dCQUNFLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLElBQUksRUFBRSxDQUFDLENBQUM7U0FDaEU7SUFDSCxDQUFDO0lBRVMsS0FBSyxDQUFDLGlCQUFpQixDQUMvQixJQUE0QyxFQUM1QyxLQUE2QyxFQUM3QyxpQkFBdUI7UUFFdkIsSUFBSSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1FBQzFDLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsSUFBSSxFQUFFLEdBQUcsS0FBSyxFQUFFLGlCQUFpQixDQUFDLENBQUM7UUFFdEYsOERBQThEO1FBQzlELE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQ3hCLFlBQVksQ0FBQyxzQkFBc0IsRUFDbkMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQ3pDLENBQUM7UUFFRiw4Q0FBOEM7UUFDOUMsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXJFLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFFOUUsc0VBQXNFO1FBQ3RFLHNFQUFzRTtRQUN0RSxJQUFJLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUM7UUFDakQsTUFBTSxtQkFBbUIsR0FBRyxNQUFNLDBCQUEwQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDaEcsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDLCtCQUErQixDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDbkUsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDLHdCQUF3QixDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFFNUQsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFMUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQsS0FBSyxDQUFDLHdCQUF3QixDQUFDLGVBQWdDO1FBQzdELHdFQUF3RTtRQUN4RSxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNqRSxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQy9FLENBQUM7SUFFUyxLQUFLLENBQUMsa0JBQWtCLENBQUMsT0FBd0I7UUFDekQsTUFBTSxDQUFDLG1CQUFtQixFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLHFCQUFxQixDQUFDLEdBQUcsQ0FDNUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUNmO1lBQ0UsWUFBWSxDQUFDLGlCQUFpQjtZQUM5QixZQUFZLENBQUMsY0FBYztZQUMzQixZQUFZLENBQUMsYUFBYTtZQUMxQixZQUFZLENBQUMsZ0JBQWdCO1lBQzdCLFlBQVksQ0FBQyxzQkFBc0I7U0FDcEMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQzFDLENBQ0YsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFbkIsTUFBTSxJQUFJLEdBQUcsTUFBTSxZQUFZLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdEMsTUFBTSxTQUFTLEdBQUcsMkJBQTJCLENBQzNDLElBQUksRUFDSixPQUFPLEVBQ1AsbUJBQW1CLEVBQ25CLGlCQUFpQixFQUNqQixnQkFBZ0IsRUFDaEIscUJBQXFCLEVBQ3JCLGtCQUFrQixDQUNuQixDQUFDO1FBQ0YsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVELHVHQUF1RztJQUM3RixLQUFLLENBQUMsYUFBYSxDQUFDLFlBQW9FO1FBQ2hHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztZQUNoQixJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQztZQUN2RSxJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsaUJBQWlCLEVBQUUsYUFBYSxDQUFDO1lBQzlFLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxFQUFFLFlBQVksQ0FBQyxjQUFjLEVBQUUsV0FBVyxDQUFDO1lBQ3pFLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxZQUFZLENBQUM7U0FDOUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELDZGQUE2RjtJQUNuRixLQUFLLENBQUMsa0JBQWtCLENBQUMsVUFBa0M7UUFDbkUsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDO1lBQ2hCLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDO1lBQzlCLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQyxXQUFXLEVBQUUsZ0JBQWdCLENBQUM7WUFDekUsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDLHNCQUFzQixFQUFFLGVBQWUsQ0FBQztTQUNwRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQseUVBQXlFO0lBQy9ELEtBQUssQ0FBQyxnQkFBZ0IsQ0FDOUIsVUFBa0MsRUFDbEMsTUFBb0IsRUFDcEIsSUFBa0Q7UUFFbEQsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JELE1BQU0sYUFBYSxHQUFHLFVBQVUsQ0FBQyxvQkFBb0IsSUFBSSxtQkFBbUIsQ0FBQyxDQUFDO1FBQzlFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxTQUFTLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxTQUFTLElBQUksRUFBRSxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ08sS0FBSyxDQUFDLDBCQUEwQixDQUFDLE1BQThEO1FBQ3ZHLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUM1RSxNQUFNLGlCQUFpQixHQUFHLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBRTFELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFO1lBQ25FLE1BQU0sSUFBSSxLQUFLLENBQUMsd0NBQXdDLFNBQVMsQ0FBQyxJQUFJLGVBQWUsaUJBQWlCLEdBQUcsQ0FBQyxDQUFDO1NBQzVHO0lBQ0gsQ0FBQztJQUVELDZFQUE2RTtJQUNuRSxLQUFLLENBQUMsWUFBWSxDQUMxQixNQUFTLEVBQ1QsTUFBb0IsRUFDcEIsSUFBeUI7UUFFekIsSUFBSSw4QkFBOEIsSUFBSSxNQUFNLElBQUksQ0FBQyxDQUFDLE1BQU0sWUFBWSxzQkFBc0IsQ0FBQyxFQUFFO1lBQzNGLE1BQU0sSUFBSSxLQUFLLENBQUMseUZBQXlGLENBQUMsQ0FBQztTQUM1RztRQUVELE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNyRCxNQUFNLGFBQWEsR0FBSSxNQUFvQyxDQUFDLE1BQU0sSUFBSSxjQUFjLENBQUMsQ0FBQztRQUN0RixJQUFJLENBQUMscUJBQXFCLENBQUMsU0FBUyxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRUQsMkNBQTJDO0lBQ2pDLHFCQUFxQixDQUM3QixTQUFpQyxFQUNqQyxhQUFxQyxFQUNyQyxJQUFtRixFQUNuRixLQUFjO1FBRWQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRTtZQUNwRSxNQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxJQUFJLElBQUksOEJBQThCLFNBQVMsQ0FBQyxJQUFJLGVBQWUsYUFBYSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7U0FDbkg7UUFDRCxJQUFJLGFBQWEsQ0FBQyxzQkFBc0IsS0FBSyxTQUFTLENBQUMsc0JBQXNCLEVBQUU7WUFDN0UsTUFBTSxJQUFJLEtBQUssQ0FDYixHQUFHLEtBQUssSUFBSSxJQUFJLG1EQUNkLFNBQVMsQ0FBQyxzQkFDWixlQUFlLGFBQWEsQ0FBQyxzQkFBc0IsR0FBRyxDQUN2RCxDQUFDO1NBQ0g7SUFDSCxDQUFDO0lBRUQscUZBQXFGO0lBQzNFLEtBQUssQ0FBQyxrQkFBa0IsQ0FDaEMsZ0JBQStDLEVBQy9DLGVBQXNCLEVBQ3RCLGlCQUFnRCxFQUNoRCxnQkFBdUIsRUFDdkIsaUJBQXVCO1FBRXZCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNoRSxNQUFNLGtCQUFrQixHQUEyQztZQUNqRSxJQUFJLENBQUMscUNBQXFDLENBQUMsZ0JBQWdCLEVBQUUsZUFBZSxFQUFFLEVBQUUsQ0FBQztZQUNqRixJQUFJLENBQUMscUNBQXFDLENBQUMsaUJBQWlCLEVBQUUsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDO1NBQ3BGLENBQUM7UUFFRixNQUFNLHNCQUFzQixHQUFHLEtBQUssRUFBRSxNQUFvQixFQUFFLEVBQUU7WUFDNUQsK0VBQStFO1lBQy9FLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ25ELG9DQUFvQztZQUNwQyxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUN4RCxPQUFPLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUM3QixDQUFDLENBQUM7UUFFRixNQUFNLG1DQUFtQyxHQUFHLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUMxRSxZQUFZLENBQUMsc0JBQXNCLEVBQ25DLDJCQUEyQixDQUM1QixDQUFDO1FBRUYscUJBQXFCO1FBQ3JCLE1BQU0sOEJBQThCLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBRXZHLGdDQUFnQztRQUNoQyxNQUFNLCtCQUErQixHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDN0YsTUFBTSxnQ0FBZ0MsR0FBRyxNQUFNLHNCQUFzQixDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUVoRyxPQUFPLGdCQUFnQixDQUFDLElBQUksQ0FBQztZQUMzQixrQkFBa0I7WUFDbEIsaUJBQWlCO1lBQ2pCLG1DQUFtQztZQUNuQyw4QkFBOEI7WUFDOUIsK0JBQStCO1lBQy9CLGdDQUFnQztTQUNqQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRVMscUNBQXFDLENBQzdDLFlBQTJDLEVBQzNDLFdBQWtCLEVBQ2xCLEVBQW1CO1FBRW5CLE9BQU8sSUFBSSxrQkFBa0IsQ0FDM0IsWUFBWSxFQUNaLFdBQVcsRUFDWCxFQUFFO1FBRUYsa0VBQWtFO1FBQ2xFLFVBQVUsRUFDVixJQUFJLGlCQUFpQixDQUNuQixxQkFBcUIsRUFDckIsTUFBTSxDQUFDLFVBQVUsQ0FBQyxFQUNsQixTQUFTLENBQUMscUJBQXFCLEVBQUUsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQ2xELENBQ0YsQ0FBQztJQUNKLENBQUM7SUFFUyxnQkFBZ0IsQ0FBQyxFQUFlO1FBQ3hDLE9BQU8sSUFBSSxrQkFBa0IsQ0FDM0IsRUFBRSxDQUFDLElBQUksRUFDUCxFQUFFLENBQUMsS0FBSztRQUVSLDRCQUE0QjtRQUM1QixJQUFJLENBQUMsR0FBRyxDQUFDLG9CQUFvQjtRQUU3QixrRUFBa0U7UUFDbEUsVUFBVSxFQUNWLFlBQVksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUNwRSxDQUFDO0lBQ0osQ0FBQztJQUVELDBGQUEwRjtJQUNoRixLQUFLLENBQUMsdUJBQXVCLENBQ3JDLEtBQVMsRUFDVCxNQUFvQixFQUNwQixNQUFTO1FBRVQsa0RBQWtEO1FBQ2xELElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtZQUFFLE9BQU8sSUFBSSxDQUFDLDBCQUEwQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRW5FLE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ3BFLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRTtZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixLQUFLLHNCQUFzQixZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQ3ZGO1FBQ0QsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDekQsT0FBTyxJQUFJLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsWUFBWSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3pGLENBQUM7SUFFUyxLQUFLLENBQUMsb0NBQW9DLENBQUMsRUFBZTtRQUNsRSxNQUFNLElBQUksR0FBRyxNQUFNLFlBQVksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUV0QyxNQUFNLFNBQVMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUM7UUFDOUMsTUFBTSxFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLHNCQUFzQixFQUFFLGtCQUFrQixFQUFFLEdBQzVHLFNBQVMsQ0FBQztRQUNaLE1BQU0sU0FBUyxHQUFHLGdCQUFnQixDQUNoQyxJQUFJLEVBQ0osU0FBUyxDQUFDLG1CQUFtQixFQUM3QixtQkFBbUIsRUFDbkIsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixzQkFBc0IsRUFDdEIsa0JBQWtCLENBQ25CLENBQUM7UUFDRixPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLFdBQVcsRUFBRSwyQkFBMkIsQ0FBQyxDQUFDO0lBQ3hHLENBQUM7SUFFUyxLQUFLLENBQUMseUJBQXlCLENBQUMsZUFBZ0M7UUFDeEUsT0FBTyxzQkFBc0IsQ0FBQyxJQUFJLENBQUM7WUFDakMsZ0JBQWdCLEVBQUUsU0FBUztZQUMzQixpQkFBaUIsRUFBRSxTQUFTO1lBQzVCLHVCQUF1QixFQUFFLFNBQVM7WUFDbEMsc0JBQXNCLEVBQUUsU0FBUztZQUNqQyxvQ0FBb0MsRUFBRSxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQztZQUMxRixlQUFlO1NBQ2hCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFUyxLQUFLLENBQUMsbUJBQW1CLENBQUMsU0FBYTtRQUMvQyw4Q0FBOEM7UUFDOUMsSUFBSSxTQUFTLENBQUMsS0FBSyxLQUFLLEVBQUUsRUFBRTtZQUMxQixPQUFPO2dCQUNMLEtBQUssRUFBRSxDQUFDO2dCQUNSLFlBQVksRUFBRSxxQkFBcUIsQ0FBQyxLQUFLLEVBQUU7Z0JBQzNDLE9BQU8sRUFBRSxJQUFJLENBQUMsMEJBQTBCLENBQUMscUJBQXFCLENBQUM7YUFDaEUsQ0FBQztTQUNIO1FBRUQsTUFBTSxJQUFJLEdBQUcsWUFBWSxDQUFDLGNBQWMsQ0FBQztRQUN6QyxNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMscUJBQXFCLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ3hGLE1BQU0sYUFBYSxHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1RSxJQUFJLENBQUMsYUFBYTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztRQUNuRixNQUFNLG9CQUFvQixHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUU5RixPQUFPO1lBQ0wsS0FBSyxFQUFFLGNBQWM7WUFDckIsWUFBWSxFQUFFLElBQUkscUJBQXFCLENBQ3JDLFVBQVUsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLEVBQy9CLFVBQVUsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLEVBQ25DLFdBQVcsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQ3JDO1lBQ0QsT0FBTyxFQUFFLElBQUksaUJBQWlCLENBQzVCLHFCQUFxQixFQUNyQixNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxFQUM1QixZQUFZLENBQUMsb0JBQW9CLENBQUMsWUFBWSxFQUFFLEVBQUUscUJBQXFCLENBQUMsQ0FDekU7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVTLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxNQUFvQixFQUFFLGFBQXFCO1FBQy9FLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbkYsTUFBTSxlQUFlLEdBQUcsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsc0JBQXNCLENBQUMsQ0FBQztRQUVyRiwyRkFBMkY7UUFDM0YsT0FBTyxlQUFlLENBQUMscUJBQXFCLENBQUMsYUFBYSxDQUFDLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDN0UsQ0FBQztJQUVTLEtBQUssQ0FBQywrQkFBK0IsQ0FBQyxFQUFlO1FBQzdELE1BQU0sdUNBQXVDLEdBQVcsRUFBRSxDQUFDO1FBQzNELEtBQUssTUFBTSx1QkFBdUIsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsRUFBRTtZQUMxRSxNQUFNLEtBQUssR0FBRyx1QkFBdUIsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDO1lBQ3RELE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ2hGLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLGdCQUFnQixFQUFFLHVCQUF1QixDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUM1Ryx1Q0FBdUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7U0FDbkU7UUFDRCxPQUFPLHVDQUF1QyxDQUFDO0lBQ2pELENBQUM7SUFFUyxLQUFLLENBQUMsOEJBQThCLENBQUMsRUFBZTtRQUM1RCxNQUFNLDhCQUE4QixHQUFXLEVBQUUsQ0FBQztRQUNsRCxLQUFLLE1BQU0sY0FBYyxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRTtZQUN4RCxNQUFNLEtBQUssR0FBRyxjQUFjLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztZQUM3QyxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNoRiw4QkFBOEIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7U0FDMUQ7UUFDRCxPQUFPLDhCQUE4QixDQUFDO0lBQ3hDLENBQUM7SUFFRCxpR0FBaUc7SUFDdkYsS0FBSyxDQUFDLG9CQUFvQixDQUFDLElBQWlCLEVBQUUsS0FBa0IsRUFBRSxlQUFnQztRQUMxRyxNQUFNLElBQUksR0FBRyxNQUFNLFlBQVksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUV0Qyx3Q0FBd0M7UUFDeEMsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMseUJBQXlCLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDeEUsTUFBTSwwQkFBMEIsR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzNGLE1BQU0seUJBQXlCLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN6RixNQUFNLDRCQUE0QixHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNoRyxNQUFNLDJCQUEyQixHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUM5RixNQUFNLCtCQUErQixHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFN0YsZ0RBQWdEO1FBQ2hELE1BQU0sZ0NBQWdDLEdBQUcsTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQ3ZFLFlBQVksQ0FBQyxpQkFBaUIsRUFDOUIsZ0JBQWdCLENBQUMsMkJBQTJCLENBQzdDLENBQUM7UUFDRixNQUFNLDhCQUE4QixHQUFHLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUNyRSxZQUFZLENBQUMsYUFBYSxFQUMxQixnQkFBZ0IsQ0FBQyx1QkFBdUIsQ0FDekMsQ0FBQztRQUVGLG9HQUFvRztRQUNwRyw4RkFBOEY7UUFDOUYsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQy9DLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FDbEUsQ0FBQztRQUNGLE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3ZHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQ3hCLFlBQVksQ0FBQyxhQUFhLEVBQzFCLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FDcEMsQ0FBQztRQUVGLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLGlCQUFpQixFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBRTNFLDREQUE0RDtRQUM1RCx3R0FBd0c7UUFDeEcsOEZBQThGO1FBQzlGLDZFQUE2RTtRQUM3RSwwRkFBMEY7UUFDMUYsTUFBTSw4QkFBOEIsR0FBRyxNQUFNLElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2RixNQUFNLHdDQUF3QyxHQUFHLE1BQU0sSUFBSSxDQUFDLCtCQUErQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xHLE1BQU0sK0JBQStCLEdBQUcsTUFBTSxJQUFJLENBQUMsOEJBQThCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekYsTUFBTSx5Q0FBeUMsR0FBRyxNQUFNLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUVwRyxNQUFNLDhCQUE4QixHQUFHLENBQUMsR0FBRyw4QkFBOEIsRUFBRSxHQUFHLCtCQUErQixDQUFDLENBQUM7UUFDL0csTUFBTSx1Q0FBdUMsR0FBRztZQUM5QyxHQUFHLHdDQUF3QztZQUMzQyxHQUFHLHlDQUF5QztTQUM3QyxDQUFDO1FBRUYsNEZBQTRGO1FBQzVGLE1BQU0sYUFBYSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUV4RixNQUFNLENBQUMsc0JBQXNCLEVBQUUsK0JBQStCLENBQUMsR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUN6RixZQUFZLENBQUMsY0FBYyxFQUMzQixhQUFhLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQ3RDLGdCQUFnQixDQUFDLHdCQUF3QixDQUMxQyxDQUFDO1FBQ0YsSUFBSSxzQkFBc0IsS0FBSyxTQUFTLEVBQUU7WUFDeEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO1NBQ3JFO1FBRUQsNkNBQTZDO1FBQzdDLE1BQU0sK0JBQStCLEdBQ25DLHNCQUFzQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUM3QixpQkFBaUIsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDLENBQy9HLENBQUM7UUFFSixPQUFPLGdCQUFnQixDQUFDLElBQUksQ0FBQztZQUMzQixTQUFTO1lBQ1QsMEJBQTBCO1lBQzFCLHlCQUF5QjtZQUN6Qiw0QkFBNEI7WUFDNUIsdUJBQXVCLEVBQUUsMkJBQTJCLENBQUMsSUFBSTtZQUN6RCwrQkFBK0I7WUFDL0IsZ0NBQWdDO1lBQ2hDLDhCQUE4QjtZQUM5QiwrQkFBK0IsRUFBRSwrQkFBK0IsQ0FBQyxZQUFZLEVBQUU7WUFDL0UsdUNBQXVDO1lBQ3ZDLDhCQUE4QjtZQUM5Qix5QkFBeUIsRUFBRSxzQkFBc0IsQ0FBQyxHQUFHLENBQ25ELENBQUMsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLENBQ2YsSUFBSSxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FDNUc7WUFDRCw2QkFBNkIsRUFBRSwrQkFBK0I7WUFDOUQsVUFBVSxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN2RSx5Q0FBeUMsRUFBRTtnQkFDekMsTUFBTSxJQUFJLENBQUMsb0NBQW9DLENBQUMsSUFBSSxDQUFDO2dCQUNyRCxNQUFNLElBQUksQ0FBQyxvQ0FBb0MsQ0FBQyxLQUFLLENBQUM7YUFDdkQ7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRVMsMEJBQTBCLENBQW1CLE1BQVM7UUFDOUQsT0FBTyxJQUFJLGlCQUFpQixDQUMxQixNQUFNLEVBQ04sRUFBRSxFQUNGLFNBQVMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUNqQyxDQUFDO0lBQ0osQ0FBQztDQUNGIn0=
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"solo_block_builder.test.d.ts","sourceRoot":"","sources":["../../src/block_builder/solo_block_builder.test.ts"],"names":[],"mappings":"AAkDA,OAAO,EAAE,KAAK,OAAO,EAAsB,MAAM,SAAS,CAAC;AAe3D,eAAO,MAAM,aAAa,yBAAgD,CAAC"}
|