@aztec/end-to-end 0.0.0-test.0 → 0.0.1-commit.21caa21
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/dest/bench/client_flows/benchmark.d.ts +61 -0
- package/dest/bench/client_flows/benchmark.d.ts.map +1 -0
- package/dest/bench/client_flows/benchmark.js +261 -0
- package/dest/bench/client_flows/client_flows_benchmark.d.ts +80 -0
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -0
- package/dest/bench/client_flows/client_flows_benchmark.js +334 -0
- package/dest/bench/client_flows/config.d.ts +14 -0
- package/dest/bench/client_flows/config.d.ts.map +1 -0
- package/dest/bench/client_flows/config.js +106 -0
- package/dest/bench/client_flows/data_extractor.d.ts +2 -0
- package/dest/bench/client_flows/data_extractor.d.ts.map +1 -0
- package/dest/bench/client_flows/data_extractor.js +77 -0
- package/dest/bench/utils.d.ts +12 -38
- package/dest/bench/utils.d.ts.map +1 -1
- package/dest/bench/utils.js +26 -66
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +21 -13
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +85 -57
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +19 -25
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +50 -70
- package/dest/e2e_deploy_contract/deploy_test.d.ts +16 -8
- package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
- package/dest/e2e_deploy_contract/deploy_test.js +13 -19
- package/dest/e2e_epochs/epochs_test.d.ts +59 -18
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +226 -44
- package/dest/e2e_fees/bridging_race.notest.d.ts +2 -0
- package/dest/e2e_fees/bridging_race.notest.d.ts.map +1 -0
- package/dest/e2e_fees/bridging_race.notest.js +63 -0
- package/dest/e2e_fees/fees_test.d.ts +21 -10
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +103 -109
- package/dest/e2e_l1_publisher/write_json.d.ts +10 -0
- package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -0
- package/dest/e2e_l1_publisher/write_json.js +58 -0
- package/dest/e2e_multi_validator/utils.d.ts +12 -0
- package/dest/e2e_multi_validator/utils.d.ts.map +1 -0
- package/dest/e2e_multi_validator/utils.js +214 -0
- package/dest/e2e_nested_contract/nested_contract_test.d.ts +10 -7
- package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
- package/dest/e2e_nested_contract/nested_contract_test.js +24 -20
- package/dest/e2e_p2p/inactivity_slash_test.d.ts +31 -0
- package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -0
- package/dest/e2e_p2p/inactivity_slash_test.js +139 -0
- package/dest/e2e_p2p/p2p_network.d.ts +275 -23
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +184 -131
- package/dest/e2e_p2p/shared.d.ts +43 -7
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +164 -19
- package/dest/e2e_token_contract/token_contract_test.d.ts +12 -6
- package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
- package/dest/e2e_token_contract/token_contract_test.js +50 -26
- package/dest/fixtures/e2e_prover_test.d.ts +63 -0
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -0
- package/dest/{e2e_prover → fixtures}/e2e_prover_test.js +104 -105
- package/dest/fixtures/fixtures.d.ts +6 -7
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +4 -3
- package/dest/fixtures/get_acvm_config.d.ts +2 -2
- package/dest/fixtures/get_acvm_config.d.ts.map +1 -1
- package/dest/fixtures/get_acvm_config.js +2 -14
- package/dest/fixtures/get_bb_config.d.ts +2 -2
- package/dest/fixtures/get_bb_config.d.ts.map +1 -1
- package/dest/fixtures/get_bb_config.js +10 -17
- package/dest/fixtures/index.d.ts +1 -1
- package/dest/fixtures/l1_to_l2_messaging.d.ts +9 -6
- package/dest/fixtures/l1_to_l2_messaging.d.ts.map +1 -1
- package/dest/fixtures/l1_to_l2_messaging.js +44 -18
- package/dest/fixtures/logging.d.ts +1 -1
- package/dest/fixtures/setup_l1_contracts.d.ts +476 -5
- package/dest/fixtures/setup_l1_contracts.d.ts.map +1 -1
- package/dest/fixtures/setup_l1_contracts.js +4 -4
- package/dest/fixtures/setup_p2p_test.d.ts +15 -14
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +81 -21
- package/dest/fixtures/snapshot_manager.d.ts +17 -9
- package/dest/fixtures/snapshot_manager.d.ts.map +1 -1
- package/dest/fixtures/snapshot_manager.js +147 -121
- package/dest/fixtures/token_utils.d.ts +10 -4
- package/dest/fixtures/token_utils.d.ts.map +1 -1
- package/dest/fixtures/token_utils.js +28 -12
- package/dest/fixtures/utils.d.ts +524 -40
- package/dest/fixtures/utils.d.ts.map +1 -1
- package/dest/fixtures/utils.js +464 -369
- package/dest/fixtures/web3signer.d.ts +5 -0
- package/dest/fixtures/web3signer.d.ts.map +1 -0
- package/dest/fixtures/web3signer.js +53 -0
- package/dest/fixtures/with_telemetry_utils.d.ts +1 -1
- package/dest/index.d.ts +1 -1
- package/dest/quality_of_service/alert_checker.d.ts +2 -2
- package/dest/quality_of_service/alert_checker.d.ts.map +1 -1
- package/dest/shared/cross_chain_test_harness.d.ts +39 -34
- package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
- package/dest/shared/cross_chain_test_harness.js +104 -50
- package/dest/shared/gas_portal_test_harness.d.ts +29 -31
- package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
- package/dest/shared/gas_portal_test_harness.js +51 -30
- package/dest/shared/index.d.ts +1 -1
- package/dest/shared/jest_setup.d.ts +1 -1
- package/dest/shared/jest_setup.js +1 -1
- package/dest/shared/submit-transactions.d.ts +6 -4
- package/dest/shared/submit-transactions.d.ts.map +1 -1
- package/dest/shared/submit-transactions.js +8 -7
- package/dest/shared/uniswap_l1_l2.d.ts +14 -12
- package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.js +146 -116
- package/dest/simulators/index.d.ts +1 -1
- package/dest/simulators/lending_simulator.d.ts +7 -11
- package/dest/simulators/lending_simulator.d.ts.map +1 -1
- package/dest/simulators/lending_simulator.js +15 -16
- package/dest/simulators/token_simulator.d.ts +6 -3
- package/dest/simulators/token_simulator.d.ts.map +1 -1
- package/dest/simulators/token_simulator.js +16 -13
- package/dest/spartan/setup_test_wallets.d.ts +26 -11
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/setup_test_wallets.js +201 -58
- package/dest/spartan/utils.d.ts +116 -313
- package/dest/spartan/utils.d.ts.map +1 -1
- package/dest/spartan/utils.js +434 -130
- package/package.json +65 -58
- package/src/bench/client_flows/benchmark.ts +341 -0
- package/src/bench/client_flows/client_flows_benchmark.ts +447 -0
- package/src/bench/client_flows/config.ts +61 -0
- package/src/bench/client_flows/data_extractor.ts +89 -0
- package/src/bench/utils.ts +22 -76
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +80 -77
- package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +65 -106
- package/src/e2e_deploy_contract/deploy_test.ts +24 -39
- package/src/e2e_epochs/epochs_test.ts +276 -55
- package/src/e2e_fees/bridging_race.notest.ts +80 -0
- package/src/e2e_fees/fees_test.ts +142 -138
- package/src/e2e_l1_publisher/write_json.ts +77 -0
- package/src/e2e_multi_validator/utils.ts +258 -0
- package/src/e2e_nested_contract/nested_contract_test.ts +29 -19
- package/src/e2e_p2p/inactivity_slash_test.ts +182 -0
- package/src/e2e_p2p/p2p_network.ts +279 -169
- package/src/e2e_p2p/shared.ts +247 -29
- package/src/e2e_token_contract/token_contract_test.ts +43 -39
- package/src/fixtures/dumps/epoch_proof_result.json +1 -1
- package/src/{e2e_prover → fixtures}/e2e_prover_test.ts +107 -152
- package/src/fixtures/fixtures.ts +4 -3
- package/src/fixtures/get_acvm_config.ts +3 -11
- package/src/fixtures/get_bb_config.ts +18 -13
- package/src/fixtures/l1_to_l2_messaging.ts +53 -23
- package/src/fixtures/setup_l1_contracts.ts +6 -7
- package/src/fixtures/setup_p2p_test.ts +126 -38
- package/src/fixtures/snapshot_manager.ts +187 -139
- package/src/fixtures/token_utils.ts +32 -15
- package/src/fixtures/utils.ts +580 -434
- package/src/fixtures/web3signer.ts +63 -0
- package/src/guides/up_quick_start.sh +7 -15
- package/src/quality_of_service/alert_checker.ts +1 -1
- package/src/shared/cross_chain_test_harness.ts +108 -79
- package/src/shared/gas_portal_test_harness.ts +59 -50
- package/src/shared/jest_setup.ts +1 -1
- package/src/shared/submit-transactions.ts +12 -8
- package/src/shared/uniswap_l1_l2.ts +181 -184
- package/src/simulators/lending_simulator.ts +14 -15
- package/src/simulators/token_simulator.ts +21 -13
- package/src/spartan/DEVELOP.md +121 -0
- package/src/spartan/setup_test_wallets.ts +251 -93
- package/src/spartan/utils.ts +490 -130
- package/dest/e2e_prover/e2e_prover_test.d.ts +0 -56
- package/dest/e2e_prover/e2e_prover_test.d.ts.map +0 -1
- package/dest/sample-dapp/connect.js +0 -12
- package/dest/sample-dapp/contracts.js +0 -10
- package/dest/sample-dapp/deploy.js +0 -35
- package/dest/sample-dapp/index.js +0 -98
- package/src/sample-dapp/connect.mjs +0 -16
- package/src/sample-dapp/contracts.mjs +0 -14
- package/src/sample-dapp/deploy.mjs +0 -40
- package/src/sample-dapp/index.mjs +0 -128
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
|
+
import { FeeJuicePaymentMethodWithClaim } from '@aztec/aztec.js/fee';
|
|
3
|
+
import { type FeePaymentMethod, PrivateFeePaymentMethod, SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee';
|
|
4
|
+
import { type Logger, createLogger } from '@aztec/aztec.js/log';
|
|
5
|
+
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
6
|
+
import type { Wallet } from '@aztec/aztec.js/wallet';
|
|
7
|
+
import { CheatCodes } from '@aztec/aztec/testing';
|
|
8
|
+
import { type DeployL1ContractsArgs, RollupContract, createExtendedL1Client, deployL1Contract } from '@aztec/ethereum';
|
|
9
|
+
import { ChainMonitor } from '@aztec/ethereum/test';
|
|
10
|
+
import { randomBytes } from '@aztec/foundation/crypto';
|
|
11
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
12
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
13
|
+
import { TestERC20Abi } from '@aztec/l1-artifacts/TestERC20Abi';
|
|
14
|
+
import { TestERC20Bytecode } from '@aztec/l1-artifacts/TestERC20Bytecode';
|
|
15
|
+
import { AMMContract } from '@aztec/noir-contracts.js/AMM';
|
|
16
|
+
import { FPCContract } from '@aztec/noir-contracts.js/FPC';
|
|
17
|
+
import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice';
|
|
18
|
+
import { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC';
|
|
19
|
+
import { TokenContract as BananaCoin, TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
20
|
+
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
21
|
+
import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';
|
|
22
|
+
import { type PXEConfig, getPXEConfig } from '@aztec/pxe/server';
|
|
23
|
+
import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
24
|
+
import { GasSettings } from '@aztec/stdlib/gas';
|
|
25
|
+
import { deriveSigningKey } from '@aztec/stdlib/keys';
|
|
26
|
+
import { TestWallet } from '@aztec/test-wallet/server';
|
|
27
|
+
|
|
28
|
+
import { MNEMONIC } from '../../fixtures/fixtures.js';
|
|
29
|
+
import {
|
|
30
|
+
type ISnapshotManager,
|
|
31
|
+
type SubsystemsContext,
|
|
32
|
+
createSnapshotManager,
|
|
33
|
+
deployAccounts,
|
|
34
|
+
} from '../../fixtures/snapshot_manager.js';
|
|
35
|
+
import { mintTokensToPrivate } from '../../fixtures/token_utils.js';
|
|
36
|
+
import { type SetupOptions, setupSponsoredFPC } from '../../fixtures/utils.js';
|
|
37
|
+
import { CrossChainTestHarness } from '../../shared/cross_chain_test_harness.js';
|
|
38
|
+
import {
|
|
39
|
+
FeeJuicePortalTestingHarnessFactory,
|
|
40
|
+
type GasBridgingTestHarness,
|
|
41
|
+
} from '../../shared/gas_portal_test_harness.js';
|
|
42
|
+
import { ProxyLogger } from './benchmark.js';
|
|
43
|
+
import { type ClientFlowsConfig, FULL_FLOWS_CONFIG, KEY_FLOWS_CONFIG } from './config.js';
|
|
44
|
+
|
|
45
|
+
const { E2E_DATA_PATH: dataPath, BENCHMARK_CONFIG } = process.env;
|
|
46
|
+
|
|
47
|
+
export type AccountType = 'ecdsar1' | 'schnorr';
|
|
48
|
+
export type FeePaymentMethodGetter = (wallet: Wallet, sender: AztecAddress) => Promise<FeePaymentMethod | undefined>;
|
|
49
|
+
export type BenchmarkingFeePaymentMethod = 'bridged_fee_juice' | 'private_fpc' | 'sponsored_fpc' | 'fee_juice';
|
|
50
|
+
|
|
51
|
+
export class ClientFlowsBenchmark {
|
|
52
|
+
private snapshotManager: ISnapshotManager;
|
|
53
|
+
|
|
54
|
+
public logger: Logger;
|
|
55
|
+
public aztecNode!: AztecNode;
|
|
56
|
+
public cheatCodes!: CheatCodes;
|
|
57
|
+
public context!: SubsystemsContext;
|
|
58
|
+
public chainMonitor!: ChainMonitor;
|
|
59
|
+
public feeJuiceBridgeTestHarness!: GasBridgingTestHarness;
|
|
60
|
+
public adminWallet!: TestWallet;
|
|
61
|
+
|
|
62
|
+
// The admin that aids in the setup of the test
|
|
63
|
+
public adminAddress!: AztecAddress;
|
|
64
|
+
|
|
65
|
+
// Aztec Node config
|
|
66
|
+
public sequencerAddress!: AztecAddress;
|
|
67
|
+
public coinbase!: EthAddress;
|
|
68
|
+
|
|
69
|
+
// Contracts
|
|
70
|
+
public feeJuiceContract!: FeeJuiceContract;
|
|
71
|
+
// Asset in which fees are paid via FPC
|
|
72
|
+
public bananaCoin!: BananaCoin;
|
|
73
|
+
public bananaCoinInstance!: ContractInstanceWithAddress;
|
|
74
|
+
public bananaFPC!: FPCContract;
|
|
75
|
+
public bananaFPCInstance!: ContractInstanceWithAddress;
|
|
76
|
+
// Random asset we want to trade
|
|
77
|
+
public candyBarCoin!: TokenContract;
|
|
78
|
+
public candyBarCoinInstance!: ContractInstanceWithAddress;
|
|
79
|
+
// AMM contract
|
|
80
|
+
public amm!: AMMContract;
|
|
81
|
+
public ammInstance!: ContractInstanceWithAddress;
|
|
82
|
+
// Liquidity token for AMM
|
|
83
|
+
public liquidityToken!: TokenContract;
|
|
84
|
+
public liquidityTokenInstance!: ContractInstanceWithAddress;
|
|
85
|
+
// Sponsored FPC contract
|
|
86
|
+
public sponsoredFPC!: SponsoredFPCContract;
|
|
87
|
+
public sponsoredFPCInstance!: ContractInstanceWithAddress;
|
|
88
|
+
|
|
89
|
+
// PXE and Wallet used by the benchmarking user. It can be set up with client-side proving enabled
|
|
90
|
+
public userWallet!: TestWallet;
|
|
91
|
+
|
|
92
|
+
public realProofs = ['true', '1'].includes(process.env.REAL_PROOFS ?? '');
|
|
93
|
+
|
|
94
|
+
public paymentMethods: Record<BenchmarkingFeePaymentMethod, { forWallet: FeePaymentMethodGetter; circuits: number }> =
|
|
95
|
+
{
|
|
96
|
+
// eslint-disable-next-line camelcase
|
|
97
|
+
bridged_fee_juice: {
|
|
98
|
+
forWallet: this.getBridgedFeeJuicePaymentMethodForWallet.bind(this),
|
|
99
|
+
circuits: 2, // FeeJuice claim + kernel inner
|
|
100
|
+
},
|
|
101
|
+
// eslint-disable-next-line camelcase
|
|
102
|
+
private_fpc: {
|
|
103
|
+
forWallet: this.getPrivateFPCPaymentMethodForWallet.bind(this),
|
|
104
|
+
circuits:
|
|
105
|
+
2 + // FPC entrypoint + kernel inner
|
|
106
|
+
2 + // BananaCoin transfer_to_public + kernel inner
|
|
107
|
+
2 + // Account verify_private_authwit + kernel inner
|
|
108
|
+
2, // BananaCoin prepare_private_balance_increase + kernel inner
|
|
109
|
+
},
|
|
110
|
+
// eslint-disable-next-line camelcase
|
|
111
|
+
sponsored_fpc: {
|
|
112
|
+
forWallet: this.getSponsoredFPCPaymentMethodForWallet.bind(this),
|
|
113
|
+
circuits: 2, // Sponsored FPC sponsor_unconditionally + kernel inner
|
|
114
|
+
},
|
|
115
|
+
// eslint-disable-next-line camelcase
|
|
116
|
+
fee_juice: {
|
|
117
|
+
forWallet: () => Promise.resolve(undefined),
|
|
118
|
+
circuits: 0,
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
public config: ClientFlowsConfig;
|
|
123
|
+
|
|
124
|
+
private proxyLogger: ProxyLogger;
|
|
125
|
+
|
|
126
|
+
constructor(testName?: string, setupOptions: Partial<SetupOptions & DeployL1ContractsArgs> = {}) {
|
|
127
|
+
this.logger = createLogger(`bench:client_flows${testName ? `:${testName}` : ''}`);
|
|
128
|
+
this.snapshotManager = createSnapshotManager(
|
|
129
|
+
`bench_client_flows${testName ? `/${testName}` : ''}`,
|
|
130
|
+
dataPath,
|
|
131
|
+
{ startProverNode: true, ...setupOptions },
|
|
132
|
+
{ ...setupOptions },
|
|
133
|
+
);
|
|
134
|
+
this.config = BENCHMARK_CONFIG === 'key_flows' ? KEY_FLOWS_CONFIG : FULL_FLOWS_CONFIG;
|
|
135
|
+
ProxyLogger.create();
|
|
136
|
+
this.proxyLogger = ProxyLogger.getInstance();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async setup() {
|
|
140
|
+
const context = await this.snapshotManager.setup();
|
|
141
|
+
await context.aztecNode.setConfig({ feeRecipient: this.sequencerAddress, coinbase: this.coinbase });
|
|
142
|
+
|
|
143
|
+
const rollupContract = RollupContract.getFromConfig(context.aztecNodeConfig);
|
|
144
|
+
this.chainMonitor = new ChainMonitor(rollupContract, context.dateProvider, this.logger, 200).start();
|
|
145
|
+
|
|
146
|
+
return this;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async teardown() {
|
|
150
|
+
await this.chainMonitor.stop();
|
|
151
|
+
await this.snapshotManager.teardown();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async mintAndBridgeFeeJuice(address: AztecAddress) {
|
|
155
|
+
const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(address);
|
|
156
|
+
const { claimSecret: secret, messageLeafIndex: index } = claim;
|
|
157
|
+
await this.feeJuiceContract.methods
|
|
158
|
+
.claim(address, claim.claimAmount, secret, index)
|
|
159
|
+
.send({ from: this.adminAddress })
|
|
160
|
+
.wait();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Admin mints bananaCoin tokens privately to the target address and redeems them. */
|
|
164
|
+
async mintPrivateBananas(amount: bigint, address: AztecAddress) {
|
|
165
|
+
const balanceBefore = await this.bananaCoin.methods
|
|
166
|
+
.balance_of_private(address)
|
|
167
|
+
.simulate({ from: this.adminAddress });
|
|
168
|
+
|
|
169
|
+
await mintTokensToPrivate(this.bananaCoin, this.adminAddress, address, amount);
|
|
170
|
+
|
|
171
|
+
const balanceAfter = await this.bananaCoin.methods
|
|
172
|
+
.balance_of_private(address)
|
|
173
|
+
.simulate({ from: this.adminAddress });
|
|
174
|
+
expect(balanceAfter).toEqual(balanceBefore + amount);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
createBenchmarkingAccountManager(wallet: TestWallet, type: 'ecdsar1' | 'schnorr') {
|
|
178
|
+
const benchysSecret = Fr.random();
|
|
179
|
+
const salt = Fr.random();
|
|
180
|
+
|
|
181
|
+
let benchysPrivateSigningKey;
|
|
182
|
+
if (type === 'schnorr') {
|
|
183
|
+
benchysPrivateSigningKey = deriveSigningKey(benchysSecret);
|
|
184
|
+
return wallet.createSchnorrAccount(benchysSecret, salt, benchysPrivateSigningKey);
|
|
185
|
+
} else if (type === 'ecdsar1') {
|
|
186
|
+
benchysPrivateSigningKey = randomBytes(32);
|
|
187
|
+
return wallet.createECDSARAccount(benchysSecret, salt, benchysPrivateSigningKey);
|
|
188
|
+
} else {
|
|
189
|
+
throw new Error(`Unknown account type: ${type}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
public async applyBaseSnapshots() {
|
|
194
|
+
await this.applyInitialAccountsSnapshot();
|
|
195
|
+
await this.applySetupFeeJuiceSnapshot();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async applyInitialAccountsSnapshot() {
|
|
199
|
+
await this.snapshotManager.snapshot(
|
|
200
|
+
'initial_accounts',
|
|
201
|
+
deployAccounts(2, this.logger),
|
|
202
|
+
async (
|
|
203
|
+
{ deployedAccounts: [{ address: adminAddress }, { address: sequencerAddress }] },
|
|
204
|
+
{ wallet, aztecNode, cheatCodes },
|
|
205
|
+
) => {
|
|
206
|
+
this.adminWallet = wallet;
|
|
207
|
+
this.aztecNode = aztecNode;
|
|
208
|
+
this.cheatCodes = cheatCodes;
|
|
209
|
+
|
|
210
|
+
this.adminAddress = adminAddress;
|
|
211
|
+
this.sequencerAddress = sequencerAddress;
|
|
212
|
+
|
|
213
|
+
const canonicalFeeJuice = await getCanonicalFeeJuice();
|
|
214
|
+
this.feeJuiceContract = FeeJuiceContract.at(canonicalFeeJuice.address, this.adminWallet);
|
|
215
|
+
this.coinbase = EthAddress.random();
|
|
216
|
+
|
|
217
|
+
const userPXEConfig = getPXEConfig();
|
|
218
|
+
const userPXEConfigWithContracts = {
|
|
219
|
+
...userPXEConfig,
|
|
220
|
+
proverEnabled: this.realProofs,
|
|
221
|
+
} as PXEConfig;
|
|
222
|
+
|
|
223
|
+
this.userWallet = await TestWallet.create(this.aztecNode, userPXEConfigWithContracts, {
|
|
224
|
+
loggers: {
|
|
225
|
+
prover: this.proxyLogger.createLogger('pxe:bb:wasm:bundle:proxied'),
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
},
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
async applySetupFeeJuiceSnapshot() {
|
|
233
|
+
await this.snapshotManager.snapshot(
|
|
234
|
+
'setup_fee_juice',
|
|
235
|
+
async () => {},
|
|
236
|
+
async (_data, context) => {
|
|
237
|
+
this.context = context;
|
|
238
|
+
|
|
239
|
+
this.feeJuiceContract = FeeJuiceContract.at(ProtocolContractAddress.FeeJuice, this.adminWallet);
|
|
240
|
+
|
|
241
|
+
this.feeJuiceBridgeTestHarness = await FeeJuicePortalTestingHarnessFactory.create({
|
|
242
|
+
aztecNode: context.aztecNode,
|
|
243
|
+
aztecNodeAdmin: context.aztecNode,
|
|
244
|
+
l1Client: context.deployL1ContractsValues.l1Client,
|
|
245
|
+
wallet: this.adminWallet,
|
|
246
|
+
logger: this.logger,
|
|
247
|
+
});
|
|
248
|
+
},
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async applyDeployBananaTokenSnapshot() {
|
|
253
|
+
await this.snapshotManager.snapshot(
|
|
254
|
+
'deploy_banana_token',
|
|
255
|
+
async () => {
|
|
256
|
+
const { contract: bananaCoin, instance: bananaCoinInstance } = await BananaCoin.deploy(
|
|
257
|
+
this.adminWallet,
|
|
258
|
+
this.adminAddress,
|
|
259
|
+
'BC',
|
|
260
|
+
'BC',
|
|
261
|
+
18n,
|
|
262
|
+
)
|
|
263
|
+
.send({ from: this.adminAddress })
|
|
264
|
+
.wait();
|
|
265
|
+
this.logger.info(`BananaCoin deployed at ${bananaCoin.address}`);
|
|
266
|
+
return { bananaCoinAddress: bananaCoin.address, bananaCoinInstance };
|
|
267
|
+
},
|
|
268
|
+
({ bananaCoinAddress, bananaCoinInstance }) => {
|
|
269
|
+
this.bananaCoin = BananaCoin.at(bananaCoinAddress, this.adminWallet);
|
|
270
|
+
this.bananaCoinInstance = bananaCoinInstance;
|
|
271
|
+
return Promise.resolve();
|
|
272
|
+
},
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async applyDeployCandyBarTokenSnapshot() {
|
|
277
|
+
await this.snapshotManager.snapshot(
|
|
278
|
+
'deploy_candy_bar_token',
|
|
279
|
+
async () => {
|
|
280
|
+
const { contract: candyBarCoin, instance: candyBarCoinInstance } = await TokenContract.deploy(
|
|
281
|
+
this.adminWallet,
|
|
282
|
+
this.adminAddress,
|
|
283
|
+
'CBC',
|
|
284
|
+
'CBC',
|
|
285
|
+
18n,
|
|
286
|
+
)
|
|
287
|
+
.send({ from: this.adminAddress })
|
|
288
|
+
.wait();
|
|
289
|
+
this.logger.info(`CandyBarCoin deployed at ${candyBarCoin.address}`);
|
|
290
|
+
return { candyBarCoinAddress: candyBarCoin.address, candyBarCoinInstance };
|
|
291
|
+
},
|
|
292
|
+
({ candyBarCoinAddress, candyBarCoinInstance }) => {
|
|
293
|
+
this.candyBarCoin = TokenContract.at(candyBarCoinAddress, this.adminWallet);
|
|
294
|
+
this.candyBarCoinInstance = candyBarCoinInstance;
|
|
295
|
+
return Promise.resolve();
|
|
296
|
+
},
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
public async applyFPCSetupSnapshot() {
|
|
301
|
+
await this.snapshotManager.snapshot(
|
|
302
|
+
'fpc_setup',
|
|
303
|
+
async context => {
|
|
304
|
+
const feeJuiceContract = this.feeJuiceBridgeTestHarness.feeJuice;
|
|
305
|
+
expect((await context.wallet.getContractMetadata(feeJuiceContract.address)).isContractPublished).toBe(true);
|
|
306
|
+
|
|
307
|
+
const bananaCoin = this.bananaCoin;
|
|
308
|
+
const { contract: bananaFPC, instance: bananaFPCInstance } = await FPCContract.deploy(
|
|
309
|
+
this.adminWallet,
|
|
310
|
+
bananaCoin.address,
|
|
311
|
+
this.adminAddress,
|
|
312
|
+
)
|
|
313
|
+
.send({ from: this.adminAddress })
|
|
314
|
+
.wait();
|
|
315
|
+
|
|
316
|
+
this.logger.info(`BananaPay deployed at ${bananaFPC.address}`);
|
|
317
|
+
|
|
318
|
+
await this.feeJuiceBridgeTestHarness.bridgeFromL1ToL2(bananaFPC.address, this.adminAddress);
|
|
319
|
+
|
|
320
|
+
return { bananaFPCAddress: bananaFPC.address, bananaFPCInstance };
|
|
321
|
+
},
|
|
322
|
+
data => {
|
|
323
|
+
this.bananaFPC = FPCContract.at(data.bananaFPCAddress, this.adminWallet);
|
|
324
|
+
this.bananaFPCInstance = data.bananaFPCInstance;
|
|
325
|
+
return Promise.resolve();
|
|
326
|
+
},
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
async applyDeploySponsoredFPCSnapshot() {
|
|
331
|
+
await this.snapshotManager.snapshot(
|
|
332
|
+
'deploy_sponsored_fpc',
|
|
333
|
+
async () => {
|
|
334
|
+
const sponsoredFPCInstance = await setupSponsoredFPC(this.adminWallet);
|
|
335
|
+
this.logger.info(`SponsoredFPC at ${sponsoredFPCInstance.address}`);
|
|
336
|
+
return { sponsoredFPCAddress: sponsoredFPCInstance.address, sponsoredFPCInstance };
|
|
337
|
+
},
|
|
338
|
+
({ sponsoredFPCAddress, sponsoredFPCInstance }) => {
|
|
339
|
+
this.sponsoredFPC = SponsoredFPCContract.at(sponsoredFPCAddress, this.adminWallet);
|
|
340
|
+
this.sponsoredFPCInstance = sponsoredFPCInstance;
|
|
341
|
+
return Promise.resolve();
|
|
342
|
+
},
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
public async createCrossChainTestHarness(owner: AztecAddress) {
|
|
347
|
+
const l1Client = createExtendedL1Client(this.context.aztecNodeConfig.l1RpcUrls, MNEMONIC);
|
|
348
|
+
|
|
349
|
+
const underlyingERC20Address = await deployL1Contract(l1Client, TestERC20Abi, TestERC20Bytecode, [
|
|
350
|
+
'Underlying',
|
|
351
|
+
'UND',
|
|
352
|
+
l1Client.account.address,
|
|
353
|
+
]).then(({ address }) => address);
|
|
354
|
+
|
|
355
|
+
this.logger.verbose(`Setting up cross chain harness...`);
|
|
356
|
+
const crossChainTestHarness = await CrossChainTestHarness.new(
|
|
357
|
+
this.aztecNode,
|
|
358
|
+
l1Client,
|
|
359
|
+
this.adminWallet,
|
|
360
|
+
owner,
|
|
361
|
+
this.logger,
|
|
362
|
+
underlyingERC20Address,
|
|
363
|
+
);
|
|
364
|
+
|
|
365
|
+
this.logger.verbose(`L2 token deployed to: ${crossChainTestHarness.l2Token.address}`);
|
|
366
|
+
|
|
367
|
+
return crossChainTestHarness;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
public async createAndFundBenchmarkingAccountOnUserWallet(accountType: AccountType) {
|
|
371
|
+
const benchysAccountManager = await this.createBenchmarkingAccountManager(this.adminWallet, accountType);
|
|
372
|
+
const benchysAccount = await benchysAccountManager.getAccount();
|
|
373
|
+
const benchysAddress = benchysAccountManager.address;
|
|
374
|
+
const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(benchysAddress);
|
|
375
|
+
const behchysDeployMethod = await benchysAccountManager.getDeployMethod();
|
|
376
|
+
await behchysDeployMethod
|
|
377
|
+
.send({
|
|
378
|
+
from: AztecAddress.ZERO,
|
|
379
|
+
fee: { paymentMethod: new FeeJuicePaymentMethodWithClaim(benchysAddress, claim) },
|
|
380
|
+
})
|
|
381
|
+
.wait();
|
|
382
|
+
// Register benchy on the user's Wallet, where we're going to be interacting from
|
|
383
|
+
const accountManager = await this.userWallet.createAccount({
|
|
384
|
+
secret: benchysAccount.getSecretKey(),
|
|
385
|
+
salt: new Fr(benchysAccount.salt),
|
|
386
|
+
contract: benchysAccountManager.getAccountContract(),
|
|
387
|
+
});
|
|
388
|
+
return accountManager.address;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
public async applyDeployAmmSnapshot() {
|
|
392
|
+
await this.snapshotManager.snapshot(
|
|
393
|
+
'deploy_amm',
|
|
394
|
+
async () => {
|
|
395
|
+
const { contract: liquidityToken, instance: liquidityTokenInstance } = await TokenContract.deploy(
|
|
396
|
+
this.adminWallet,
|
|
397
|
+
this.adminAddress,
|
|
398
|
+
'LPT',
|
|
399
|
+
'LPT',
|
|
400
|
+
18n,
|
|
401
|
+
)
|
|
402
|
+
.send({ from: this.adminAddress })
|
|
403
|
+
.wait();
|
|
404
|
+
const { contract: amm, instance: ammInstance } = await AMMContract.deploy(
|
|
405
|
+
this.adminWallet,
|
|
406
|
+
this.bananaCoin.address,
|
|
407
|
+
this.candyBarCoin.address,
|
|
408
|
+
liquidityToken.address,
|
|
409
|
+
)
|
|
410
|
+
.send({ from: this.adminAddress })
|
|
411
|
+
.wait();
|
|
412
|
+
this.logger.info(`AMM deployed at ${amm.address}`);
|
|
413
|
+
await liquidityToken.methods.set_minter(amm.address, true).send({ from: this.adminAddress }).wait();
|
|
414
|
+
return {
|
|
415
|
+
ammAddress: amm.address,
|
|
416
|
+
ammInstance,
|
|
417
|
+
liquidityTokenAddress: liquidityToken.address,
|
|
418
|
+
liquidityTokenInstance,
|
|
419
|
+
};
|
|
420
|
+
},
|
|
421
|
+
({ ammAddress, ammInstance, liquidityTokenAddress, liquidityTokenInstance }) => {
|
|
422
|
+
this.liquidityToken = TokenContract.at(liquidityTokenAddress, this.adminWallet);
|
|
423
|
+
this.liquidityTokenInstance = liquidityTokenInstance;
|
|
424
|
+
this.amm = AMMContract.at(ammAddress, this.adminWallet);
|
|
425
|
+
this.ammInstance = ammInstance;
|
|
426
|
+
return Promise.resolve();
|
|
427
|
+
},
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
public async getBridgedFeeJuicePaymentMethodForWallet(_wallet: Wallet, sender: AztecAddress) {
|
|
432
|
+
const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(sender);
|
|
433
|
+
return new FeeJuicePaymentMethodWithClaim(sender, claim);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
public async getPrivateFPCPaymentMethodForWallet(wallet: Wallet, sender: AztecAddress) {
|
|
437
|
+
// The private fee paying method assembled on the app side requires knowledge of the maximum
|
|
438
|
+
// fee the user is willing to pay
|
|
439
|
+
const maxFeesPerGas = (await this.aztecNode.getCurrentBaseFees()).mul(1.5);
|
|
440
|
+
const gasSettings = GasSettings.default({ maxFeesPerGas });
|
|
441
|
+
return new PrivateFeePaymentMethod(this.bananaFPC.address, sender, wallet, gasSettings);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
public getSponsoredFPCPaymentMethodForWallet(_wallet: Wallet, _sender: AztecAddress) {
|
|
445
|
+
return Promise.resolve(new SponsoredFeePaymentMethod(this.sponsoredFPC.address));
|
|
446
|
+
}
|
|
447
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { AccountType, BenchmarkingFeePaymentMethod } from './client_flows_benchmark.js';
|
|
2
|
+
|
|
3
|
+
export type ClientFlowConfig = {
|
|
4
|
+
accounts: AccountType[];
|
|
5
|
+
feePaymentMethods: BenchmarkingFeePaymentMethod[];
|
|
6
|
+
recursions?: number[];
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
type ClientFlows = 'accountDeployments' | 'deployments' | 'transfers' | 'bridging' | 'amm';
|
|
10
|
+
|
|
11
|
+
export type ClientFlowsConfig = {
|
|
12
|
+
[key in ClientFlows]: ClientFlowConfig;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const KEY_FLOWS_CONFIG: ClientFlowsConfig = {
|
|
16
|
+
accountDeployments: {
|
|
17
|
+
accounts: ['ecdsar1', 'schnorr'],
|
|
18
|
+
feePaymentMethods: ['sponsored_fpc'],
|
|
19
|
+
},
|
|
20
|
+
deployments: {
|
|
21
|
+
accounts: ['ecdsar1', 'schnorr'],
|
|
22
|
+
feePaymentMethods: ['sponsored_fpc'],
|
|
23
|
+
},
|
|
24
|
+
amm: {
|
|
25
|
+
accounts: ['ecdsar1'],
|
|
26
|
+
feePaymentMethods: ['sponsored_fpc'],
|
|
27
|
+
},
|
|
28
|
+
bridging: {
|
|
29
|
+
accounts: ['ecdsar1'],
|
|
30
|
+
feePaymentMethods: ['sponsored_fpc'],
|
|
31
|
+
},
|
|
32
|
+
transfers: {
|
|
33
|
+
accounts: ['ecdsar1'],
|
|
34
|
+
feePaymentMethods: ['sponsored_fpc', 'private_fpc'],
|
|
35
|
+
recursions: [0, 1],
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const FULL_FLOWS_CONFIG: ClientFlowsConfig = {
|
|
40
|
+
accountDeployments: {
|
|
41
|
+
accounts: ['ecdsar1', 'schnorr'],
|
|
42
|
+
feePaymentMethods: ['bridged_fee_juice', 'sponsored_fpc'],
|
|
43
|
+
},
|
|
44
|
+
deployments: {
|
|
45
|
+
accounts: ['ecdsar1', 'schnorr'],
|
|
46
|
+
feePaymentMethods: ['bridged_fee_juice', 'sponsored_fpc'],
|
|
47
|
+
},
|
|
48
|
+
amm: {
|
|
49
|
+
accounts: ['ecdsar1', 'schnorr'],
|
|
50
|
+
feePaymentMethods: ['sponsored_fpc', 'private_fpc'],
|
|
51
|
+
},
|
|
52
|
+
bridging: {
|
|
53
|
+
accounts: ['ecdsar1', 'schnorr'],
|
|
54
|
+
feePaymentMethods: ['sponsored_fpc', 'private_fpc'],
|
|
55
|
+
},
|
|
56
|
+
transfers: {
|
|
57
|
+
accounts: ['ecdsar1', 'schnorr'],
|
|
58
|
+
feePaymentMethods: ['sponsored_fpc', 'private_fpc'],
|
|
59
|
+
recursions: [0, 1, 2],
|
|
60
|
+
},
|
|
61
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { BBBundlePrivateKernelProver } from '@aztec/bb-prover/client/bundle';
|
|
2
|
+
import { createLogger, logger } from '@aztec/foundation/log';
|
|
3
|
+
import { Timer } from '@aztec/foundation/timer';
|
|
4
|
+
import { WASMSimulator } from '@aztec/simulator/client';
|
|
5
|
+
import type { PrivateExecutionStep } from '@aztec/stdlib/kernel';
|
|
6
|
+
import type { ProvingStats, ProvingTimings, SimulationStats } from '@aztec/stdlib/tx';
|
|
7
|
+
|
|
8
|
+
import { Decoder } from 'msgpackr';
|
|
9
|
+
import { readFile, readdir, writeFile } from 'node:fs/promises';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
|
|
12
|
+
import { type Log, ProxyLogger, generateBenchmark } from './benchmark.js';
|
|
13
|
+
|
|
14
|
+
async function main() {
|
|
15
|
+
ProxyLogger.create();
|
|
16
|
+
const proxyLogger = ProxyLogger.getInstance();
|
|
17
|
+
const ivcFolder = process.env.CAPTURE_IVC_FOLDER;
|
|
18
|
+
if (!ivcFolder) {
|
|
19
|
+
throw new Error('CAPTURE_IVC_FOLDER is not set');
|
|
20
|
+
}
|
|
21
|
+
const flows = await readdir(ivcFolder);
|
|
22
|
+
logger.info(`Flows in ${ivcFolder}: \n${flows.map(flowName => `\t- ${flowName}`).join('\n')}`);
|
|
23
|
+
const simulator = new WASMSimulator();
|
|
24
|
+
const log = proxyLogger.createLogger('bb:prover');
|
|
25
|
+
const prover = new BBBundlePrivateKernelProver(simulator, log);
|
|
26
|
+
|
|
27
|
+
const userLog = createLogger('chonk_flows:data_processor');
|
|
28
|
+
|
|
29
|
+
for (const flow of flows) {
|
|
30
|
+
userLog.info(`Processing flow ${flow}`);
|
|
31
|
+
const ivcInputs = await readFile(join(ivcFolder, flow, 'ivc-inputs.msgpack'));
|
|
32
|
+
const stepsFromFile: PrivateExecutionStep[] = new Decoder({ useRecords: false }).unpack(ivcInputs);
|
|
33
|
+
const witnesses = await readFile(join(ivcFolder, flow, 'witnesses.json'));
|
|
34
|
+
|
|
35
|
+
const witnessStack = JSON.parse(witnesses.toString()).map((witnessMap: Record<string, string>) => {
|
|
36
|
+
return new Map<number, string>(Object.entries(witnessMap).map(([k, v]) => [Number(k), v]));
|
|
37
|
+
});
|
|
38
|
+
const profileFile = await readFile(join(ivcFolder, flow, 'profile.json'));
|
|
39
|
+
const profile = JSON.parse(profileFile.toString()) as {
|
|
40
|
+
stats: ProvingStats | SimulationStats;
|
|
41
|
+
steps: {
|
|
42
|
+
functionName: string;
|
|
43
|
+
gateCount: number;
|
|
44
|
+
timings: { witgen: number; gateCount: number };
|
|
45
|
+
}[];
|
|
46
|
+
};
|
|
47
|
+
const privateExecutionSteps: PrivateExecutionStep[] = profile.steps.map((step, i) => ({
|
|
48
|
+
functionName: step.functionName,
|
|
49
|
+
gateCount: step.gateCount,
|
|
50
|
+
bytecode: stepsFromFile[i].bytecode,
|
|
51
|
+
// TODO(AD) do we still want to take this from witness.json?
|
|
52
|
+
witness: witnessStack[i],
|
|
53
|
+
vk: stepsFromFile[i].vk,
|
|
54
|
+
timings: {
|
|
55
|
+
witgen: step.timings.witgen,
|
|
56
|
+
gateCount: step.timings.gateCount,
|
|
57
|
+
},
|
|
58
|
+
}));
|
|
59
|
+
|
|
60
|
+
let error: any;
|
|
61
|
+
let currentLogs: Log[] = [];
|
|
62
|
+
let provingTime;
|
|
63
|
+
try {
|
|
64
|
+
const provingTimer = new Timer();
|
|
65
|
+
await prover.createChonkProof(privateExecutionSteps);
|
|
66
|
+
provingTime = provingTimer.ms();
|
|
67
|
+
} catch (e) {
|
|
68
|
+
userLog.error(`Failed to generate chonk proof for ${flow}`, e);
|
|
69
|
+
error = (e as Error).message;
|
|
70
|
+
}
|
|
71
|
+
// Extract logs from this run from the proxy and write them to disk unconditionally
|
|
72
|
+
currentLogs = proxyLogger.getLogs();
|
|
73
|
+
await writeFile(join(ivcFolder, flow, 'logs.json'), JSON.stringify(currentLogs, null, 2));
|
|
74
|
+
if (!(profile.stats.timings as ProvingTimings).proving) {
|
|
75
|
+
(profile.stats.timings as ProvingTimings).proving = provingTime;
|
|
76
|
+
}
|
|
77
|
+
const benchmark = generateBenchmark(flow, currentLogs, profile.stats, privateExecutionSteps, 'native', error);
|
|
78
|
+
await writeFile(join(ivcFolder, flow, 'benchmark.json'), JSON.stringify(benchmark, null, 2));
|
|
79
|
+
proxyLogger.flushLogs();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
await main();
|
|
85
|
+
} catch (e) {
|
|
86
|
+
// eslint-disable-next-line no-console
|
|
87
|
+
console.error(e);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|