@aztec/end-to-end 0.0.1-commit.e2b2873ed → 0.0.1-commit.e304674f1
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/README.md +27 -0
- package/dest/bench/client_flows/client_flows_benchmark.d.ts +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +19 -26
- package/dest/bench/utils.d.ts +1 -1
- package/dest/bench/utils.d.ts.map +1 -1
- package/dest/bench/utils.js +6 -3
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +2 -2
- 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 +16 -16
- package/dest/e2e_epochs/epochs_test.d.ts +11 -7
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +60 -38
- package/dest/e2e_fees/fees_test.d.ts +1 -1
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +14 -7
- package/dest/e2e_nested_contract/nested_contract_test.d.ts +1 -1
- package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
- package/dest/e2e_nested_contract/nested_contract_test.js +4 -6
- package/dest/e2e_p2p/inactivity_slash_test.js +3 -3
- package/dest/e2e_p2p/p2p_network.d.ts +8 -9
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +32 -19
- package/dest/e2e_p2p/reqresp/utils.d.ts +3 -3
- package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
- package/dest/e2e_p2p/reqresp/utils.js +46 -9
- package/dest/e2e_p2p/shared.d.ts +25 -7
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +49 -44
- package/dest/e2e_token_contract/token_contract_test.d.ts +2 -2
- package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
- package/dest/e2e_token_contract/token_contract_test.js +13 -13
- package/dest/fixtures/authwit_proxy.d.ts +15 -0
- package/dest/fixtures/authwit_proxy.d.ts.map +1 -0
- package/dest/fixtures/authwit_proxy.js +34 -0
- package/dest/fixtures/e2e_prover_test.d.ts +6 -5
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +37 -49
- package/dest/fixtures/elu_monitor.d.ts +21 -0
- package/dest/fixtures/elu_monitor.d.ts.map +1 -0
- package/dest/fixtures/elu_monitor.js +102 -0
- package/dest/fixtures/fixtures.d.ts +5 -1
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +6 -0
- package/dest/fixtures/get_bb_config.d.ts +1 -1
- package/dest/fixtures/get_bb_config.d.ts.map +1 -1
- package/dest/fixtures/get_bb_config.js +5 -5
- package/dest/fixtures/ha_setup.d.ts +1 -1
- package/dest/fixtures/ha_setup.d.ts.map +1 -1
- package/dest/fixtures/ha_setup.js +3 -1
- package/dest/fixtures/setup.d.ts +33 -11
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +68 -89
- package/dest/fixtures/setup_p2p_test.d.ts +10 -7
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +18 -15
- package/dest/fixtures/token_utils.d.ts +2 -2
- package/dest/fixtures/token_utils.d.ts.map +1 -1
- package/dest/fixtures/token_utils.js +5 -7
- package/dest/legacy-jest-resolver.d.cts +3 -0
- package/dest/legacy-jest-resolver.d.cts.map +1 -0
- package/dest/shared/cross_chain_test_harness.d.ts +1 -1
- package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
- package/dest/shared/cross_chain_test_harness.js +13 -13
- package/dest/shared/gas_portal_test_harness.js +2 -2
- package/dest/shared/index.d.ts +2 -1
- package/dest/shared/index.d.ts.map +1 -1
- package/dest/shared/index.js +1 -0
- package/dest/shared/jest_setup.js +41 -1
- package/dest/shared/mock_state_view.d.ts +86 -0
- package/dest/shared/mock_state_view.d.ts.map +1 -0
- package/dest/shared/mock_state_view.js +186 -0
- package/dest/shared/submit-transactions.js +1 -1
- package/dest/shared/uniswap_l1_l2.d.ts +1 -1
- package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.js +14 -17
- package/dest/simulators/lending_simulator.d.ts +1 -1
- package/dest/simulators/lending_simulator.d.ts.map +1 -1
- package/dest/simulators/lending_simulator.js +4 -4
- package/dest/simulators/token_simulator.d.ts +1 -1
- package/dest/simulators/token_simulator.d.ts.map +1 -1
- package/dest/simulators/token_simulator.js +2 -2
- package/dest/spartan/setup_test_wallets.d.ts +11 -2
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/setup_test_wallets.js +97 -38
- package/dest/spartan/tx_metrics.js +1 -1
- package/dest/spartan/utils/bot.d.ts +3 -2
- package/dest/spartan/utils/bot.d.ts.map +1 -1
- package/dest/spartan/utils/bot.js +2 -1
- package/dest/spartan/utils/config.d.ts +7 -1
- package/dest/spartan/utils/config.d.ts.map +1 -1
- package/dest/spartan/utils/config.js +3 -1
- package/dest/spartan/utils/index.d.ts +4 -2
- package/dest/spartan/utils/index.d.ts.map +1 -1
- package/dest/spartan/utils/index.js +5 -1
- package/dest/spartan/utils/k8s.d.ts +3 -1
- package/dest/spartan/utils/k8s.d.ts.map +1 -1
- package/dest/spartan/utils/k8s.js +6 -0
- package/dest/spartan/utils/nodes.d.ts +4 -5
- package/dest/spartan/utils/nodes.d.ts.map +1 -1
- package/dest/spartan/utils/nodes.js +9 -9
- package/dest/spartan/utils/pod_logs.d.ts +25 -0
- package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
- package/dest/spartan/utils/pod_logs.js +74 -0
- package/dest/test-wallet/test_wallet.d.ts +16 -23
- package/dest/test-wallet/test_wallet.d.ts.map +1 -1
- package/dest/test-wallet/test_wallet.js +73 -65
- package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
- package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
- package/dest/test-wallet/wallet_worker_script.js +48 -0
- package/dest/test-wallet/worker_wallet.d.ts +52 -0
- package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
- package/dest/test-wallet/worker_wallet.js +151 -0
- package/dest/test-wallet/worker_wallet_schema.d.ts +274 -0
- package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
- package/dest/test-wallet/worker_wallet_schema.js +10 -0
- package/package.json +43 -44
- package/src/bench/client_flows/client_flows_benchmark.ts +27 -10
- package/src/bench/utils.ts +7 -2
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +20 -16
- package/src/e2e_epochs/epochs_test.ts +78 -66
- package/src/e2e_fees/fees_test.ts +14 -7
- package/src/e2e_nested_contract/nested_contract_test.ts +6 -4
- package/src/e2e_p2p/inactivity_slash_test.ts +3 -3
- package/src/e2e_p2p/p2p_network.ts +47 -28
- package/src/e2e_p2p/reqresp/utils.ts +58 -9
- package/src/e2e_p2p/shared.ts +71 -59
- package/src/e2e_token_contract/token_contract_test.ts +18 -10
- package/src/fixtures/authwit_proxy.ts +54 -0
- package/src/fixtures/dumps/epoch_proof_result.json +1 -1
- package/src/fixtures/e2e_prover_test.ts +43 -52
- package/src/fixtures/elu_monitor.ts +126 -0
- package/src/fixtures/fixtures.ts +10 -0
- package/src/fixtures/get_bb_config.ts +7 -6
- package/src/fixtures/ha_setup.ts +3 -1
- package/src/fixtures/setup.ts +97 -124
- package/src/fixtures/setup_p2p_test.ts +17 -25
- package/src/fixtures/token_utils.ts +3 -3
- package/src/legacy-jest-resolver.cjs +135 -0
- package/src/shared/cross_chain_test_harness.ts +13 -9
- package/src/shared/gas_portal_test_harness.ts +1 -1
- package/src/shared/index.ts +1 -0
- package/src/shared/jest_setup.ts +51 -1
- package/src/shared/mock_state_view.ts +188 -0
- package/src/shared/submit-transactions.ts +1 -1
- package/src/shared/uniswap_l1_l2.ts +35 -28
- package/src/simulators/lending_simulator.ts +8 -4
- package/src/simulators/token_simulator.ts +6 -2
- package/src/spartan/setup_test_wallets.ts +138 -31
- package/src/spartan/tx_metrics.ts +1 -1
- package/src/spartan/utils/bot.ts +4 -1
- package/src/spartan/utils/config.ts +2 -0
- package/src/spartan/utils/index.ts +7 -0
- package/src/spartan/utils/k8s.ts +8 -0
- package/src/spartan/utils/nodes.ts +15 -10
- package/src/spartan/utils/pod_logs.ts +99 -0
- package/src/test-wallet/test_wallet.ts +101 -80
- package/src/test-wallet/wallet_worker_script.ts +60 -0
- package/src/test-wallet/worker_wallet.ts +213 -0
- package/src/test-wallet/worker_wallet_schema.ts +13 -0
|
@@ -3,16 +3,11 @@ import type { AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
|
|
|
3
3
|
import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses';
|
|
4
4
|
import { Fr } from '@aztec/aztec.js/fields';
|
|
5
5
|
import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config';
|
|
6
|
-
import {
|
|
7
|
-
type EmpireSlashingProposerContract,
|
|
8
|
-
GSEContract,
|
|
9
|
-
RollupContract,
|
|
10
|
-
type TallySlashingProposerContract,
|
|
11
|
-
} from '@aztec/ethereum/contracts';
|
|
6
|
+
import { GSEContract, RollupContract, type SlashingProposerContract } from '@aztec/ethereum/contracts';
|
|
12
7
|
import type { Operator } from '@aztec/ethereum/deploy-aztec-l1-contracts';
|
|
13
8
|
import { deployL1Contract } from '@aztec/ethereum/deploy-l1-contract';
|
|
14
9
|
import { MultiAdderArtifact } from '@aztec/ethereum/l1-artifacts';
|
|
15
|
-
import {
|
|
10
|
+
import { createL1TxUtils } from '@aztec/ethereum/l1-tx-utils';
|
|
16
11
|
import { ChainMonitor } from '@aztec/ethereum/test';
|
|
17
12
|
import type { ExtendedViemWalletClient, ViemClient } from '@aztec/ethereum/types';
|
|
18
13
|
import { EpochNumber } from '@aztec/foundation/branded-types';
|
|
@@ -24,8 +19,8 @@ import { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
|
|
|
24
19
|
import type { BootstrapNode } from '@aztec/p2p/bootstrap';
|
|
25
20
|
import { createBootstrapNodeFromPrivateKey, getBootstrapNodeEnr } from '@aztec/p2p/test-helpers';
|
|
26
21
|
import { tryStop } from '@aztec/stdlib/interfaces/server';
|
|
27
|
-
import {
|
|
28
|
-
import type {
|
|
22
|
+
import { TopicType } from '@aztec/stdlib/p2p';
|
|
23
|
+
import type { GenesisData } from '@aztec/stdlib/world-state';
|
|
29
24
|
import { ZkPassportProofParams } from '@aztec/stdlib/zkpassport';
|
|
30
25
|
import { getGenesisValues } from '@aztec/world-state/testing';
|
|
31
26
|
|
|
@@ -58,7 +53,7 @@ export const WAIT_FOR_TX_TIMEOUT = l1ContractsConfig.aztecSlotDuration * 3;
|
|
|
58
53
|
export const SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES = {
|
|
59
54
|
aztecSlotDuration: 12,
|
|
60
55
|
ethereumSlotDuration: 4,
|
|
61
|
-
|
|
56
|
+
aztecProofSubmissionEpochs: 640,
|
|
62
57
|
};
|
|
63
58
|
|
|
64
59
|
export class P2PNetworkTest {
|
|
@@ -76,7 +71,7 @@ export class P2PNetworkTest {
|
|
|
76
71
|
public validators: Operator[] = [];
|
|
77
72
|
|
|
78
73
|
public deployedAccounts: InitialAccountData[] = [];
|
|
79
|
-
public
|
|
74
|
+
public genesis: GenesisData | undefined;
|
|
80
75
|
|
|
81
76
|
// The re-execution test needs a wallet and a spam contract
|
|
82
77
|
public wallet?: TestWallet;
|
|
@@ -123,7 +118,7 @@ export class P2PNetworkTest {
|
|
|
123
118
|
initialValidatorConfig.aztecProofSubmissionEpochs ?? l1ContractsConfig.aztecProofSubmissionEpochs,
|
|
124
119
|
slashingRoundSizeInEpochs:
|
|
125
120
|
initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
|
|
126
|
-
|
|
121
|
+
slasherEnabled: initialValidatorConfig.slasherEnabled ?? true,
|
|
127
122
|
aztecTargetCommitteeSize: numberOfValidators,
|
|
128
123
|
metricsPort: metricsPort,
|
|
129
124
|
numberOfInitialFundedAccounts: 2,
|
|
@@ -136,7 +131,7 @@ export class P2PNetworkTest {
|
|
|
136
131
|
aztecEpochDuration: initialValidatorConfig.aztecEpochDuration ?? l1ContractsConfig.aztecEpochDuration,
|
|
137
132
|
slashingRoundSizeInEpochs:
|
|
138
133
|
initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
|
|
139
|
-
|
|
134
|
+
slasherEnabled: initialValidatorConfig.slasherEnabled ?? true,
|
|
140
135
|
|
|
141
136
|
ethereumSlotDuration: initialValidatorConfig.ethereumSlotDuration ?? l1ContractsConfig.ethereumSlotDuration,
|
|
142
137
|
aztecSlotDuration: initialValidatorConfig.aztecSlotDuration ?? l1ContractsConfig.aztecSlotDuration,
|
|
@@ -322,8 +317,9 @@ export class P2PNetworkTest {
|
|
|
322
317
|
throw new Error('Call setupAccount before deploying spam contract');
|
|
323
318
|
}
|
|
324
319
|
|
|
325
|
-
|
|
326
|
-
|
|
320
|
+
({ contract: this.spamContract } = await SpamContract.deploy(this.wallet).send({
|
|
321
|
+
from: this.defaultAccountAddress!,
|
|
322
|
+
}));
|
|
327
323
|
}
|
|
328
324
|
|
|
329
325
|
async removeInitialNode() {
|
|
@@ -343,7 +339,7 @@ export class P2PNetworkTest {
|
|
|
343
339
|
}
|
|
344
340
|
|
|
345
341
|
private async _sendDummyTx(l1Client: ExtendedViemWalletClient) {
|
|
346
|
-
const l1TxUtils =
|
|
342
|
+
const l1TxUtils = createL1TxUtils(l1Client);
|
|
347
343
|
return await l1TxUtils.sendAndMonitorTransaction({
|
|
348
344
|
to: l1Client.account!.address,
|
|
349
345
|
value: 1n,
|
|
@@ -358,7 +354,7 @@ export class P2PNetworkTest {
|
|
|
358
354
|
...this.setupOptions,
|
|
359
355
|
fundSponsoredFPC: true,
|
|
360
356
|
skipAccountDeployment: true,
|
|
361
|
-
|
|
357
|
+
slasherEnabled: this.setupOptions.slasherEnabled ?? this.deployL1ContractsArgs.slasherEnabled ?? false,
|
|
362
358
|
aztecTargetCommitteeSize: 0,
|
|
363
359
|
l1ContractsArgs: this.deployL1ContractsArgs,
|
|
364
360
|
},
|
|
@@ -370,8 +366,13 @@ export class P2PNetworkTest {
|
|
|
370
366
|
const sponsoredFPCAddress = await getSponsoredFPCAddress();
|
|
371
367
|
const initialFundedAccounts = [...this.context.initialFundedAccounts.map(a => a.address), sponsoredFPCAddress];
|
|
372
368
|
|
|
373
|
-
const {
|
|
374
|
-
|
|
369
|
+
const { genesis } = await getGenesisValues(
|
|
370
|
+
initialFundedAccounts,
|
|
371
|
+
undefined,
|
|
372
|
+
undefined,
|
|
373
|
+
this.context.genesis!.genesisTimestamp,
|
|
374
|
+
);
|
|
375
|
+
this.genesis = genesis;
|
|
375
376
|
|
|
376
377
|
const rollupContract = RollupContract.getFromL1ContractsValues(this.context.deployL1ContractsValues);
|
|
377
378
|
this.monitor = new ChainMonitor(rollupContract, this.context.dateProvider).start();
|
|
@@ -406,6 +407,7 @@ export class P2PNetworkTest {
|
|
|
406
407
|
expectedNodeCount?: number,
|
|
407
408
|
timeoutSeconds = 30,
|
|
408
409
|
checkIntervalSeconds = 0.1,
|
|
410
|
+
topics: TopicType[] = [TopicType.tx],
|
|
409
411
|
) {
|
|
410
412
|
const nodeCount = expectedNodeCount ?? nodes.length;
|
|
411
413
|
const minPeerCount = nodeCount - 1;
|
|
@@ -431,6 +433,29 @@ export class P2PNetworkTest {
|
|
|
431
433
|
);
|
|
432
434
|
|
|
433
435
|
this.logger.warn('All nodes connected to P2P mesh');
|
|
436
|
+
|
|
437
|
+
// Wait for GossipSub mesh to form for all specified topics.
|
|
438
|
+
// We only require at least 1 mesh peer per node because GossipSub
|
|
439
|
+
// stops grafting once it reaches Dlo peers and won't fill the mesh to all available peers.
|
|
440
|
+
for (const topic of topics) {
|
|
441
|
+
this.logger.warn(`Waiting for GossipSub mesh to form for ${topic} topic...`);
|
|
442
|
+
await Promise.all(
|
|
443
|
+
nodes.map(async (node, index) => {
|
|
444
|
+
const p2p = node.getP2P();
|
|
445
|
+
await retryUntil(
|
|
446
|
+
async () => {
|
|
447
|
+
const meshPeers = await p2p.getGossipMeshPeerCount(topic);
|
|
448
|
+
this.logger.debug(`Node ${index} has ${meshPeers} gossip mesh peers for ${topic} topic`);
|
|
449
|
+
return meshPeers >= 1 ? true : undefined;
|
|
450
|
+
},
|
|
451
|
+
`Node ${index} to have gossip mesh peers for ${topic} topic`,
|
|
452
|
+
timeoutSeconds,
|
|
453
|
+
checkIntervalSeconds,
|
|
454
|
+
);
|
|
455
|
+
}),
|
|
456
|
+
);
|
|
457
|
+
this.logger.warn(`All nodes have gossip mesh peers for ${topic} topic`);
|
|
458
|
+
}
|
|
434
459
|
}
|
|
435
460
|
|
|
436
461
|
async teardown() {
|
|
@@ -442,8 +467,7 @@ export class P2PNetworkTest {
|
|
|
442
467
|
async getContracts(): Promise<{
|
|
443
468
|
rollup: RollupContract;
|
|
444
469
|
slasherContract: GetContractReturnType<typeof SlasherAbi, ViemClient>;
|
|
445
|
-
slashingProposer:
|
|
446
|
-
slashFactory: SlashFactoryContract;
|
|
470
|
+
slashingProposer: SlashingProposerContract | undefined;
|
|
447
471
|
}> {
|
|
448
472
|
if (!this.ctx.deployL1ContractsValues) {
|
|
449
473
|
throw new Error('DeployAztecL1ContractsValues not set');
|
|
@@ -460,14 +484,9 @@ export class P2PNetworkTest {
|
|
|
460
484
|
client: this.ctx.deployL1ContractsValues.l1Client,
|
|
461
485
|
});
|
|
462
486
|
|
|
463
|
-
// Get the actual slashing proposer from rollup
|
|
487
|
+
// Get the actual slashing proposer from rollup
|
|
464
488
|
const slashingProposer = await rollup.getSlashingProposer();
|
|
465
489
|
|
|
466
|
-
|
|
467
|
-
this.ctx.deployL1ContractsValues.l1Client,
|
|
468
|
-
getAddress(this.ctx.deployL1ContractsValues.l1ContractAddresses.slashFactoryAddress!.toString()),
|
|
469
|
-
);
|
|
470
|
-
|
|
471
|
-
return { rollup, slasherContract, slashingProposer, slashFactory };
|
|
490
|
+
return { rollup, slasherContract, slashingProposer };
|
|
472
491
|
}
|
|
473
492
|
}
|
|
@@ -3,24 +3,24 @@ import { createLogger } from '@aztec/aztec.js/log';
|
|
|
3
3
|
import { waitForTx } from '@aztec/aztec.js/node';
|
|
4
4
|
import { Tx } from '@aztec/aztec.js/tx';
|
|
5
5
|
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
6
|
-
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
6
|
+
import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
7
7
|
import { timesAsync } from '@aztec/foundation/collection';
|
|
8
8
|
import { retryUntil } from '@aztec/foundation/retry';
|
|
9
9
|
|
|
10
|
-
import { jest } from '@jest/globals';
|
|
10
|
+
import { expect, jest } from '@jest/globals';
|
|
11
11
|
import fs from 'fs';
|
|
12
12
|
import os from 'os';
|
|
13
13
|
import path from 'path';
|
|
14
14
|
|
|
15
|
-
import { shouldCollectMetrics } from '../../fixtures/fixtures.js';
|
|
15
|
+
import { getBootNodeUdpPort, shouldCollectMetrics } from '../../fixtures/fixtures.js';
|
|
16
16
|
import { createNodes } from '../../fixtures/setup_p2p_test.js';
|
|
17
|
-
import { P2PNetworkTest,
|
|
17
|
+
import { P2PNetworkTest, WAIT_FOR_TX_TIMEOUT } from '../p2p_network.js';
|
|
18
18
|
import { prepareTransactions } from '../shared.js';
|
|
19
19
|
|
|
20
20
|
// Don't set this to a higher value than 9 because each node will use a different L1 publisher account and anvil seeds
|
|
21
21
|
export const NUM_VALIDATORS = 6;
|
|
22
|
-
export const NUM_TXS_PER_NODE =
|
|
23
|
-
export const BOOT_NODE_UDP_PORT =
|
|
22
|
+
export const NUM_TXS_PER_NODE = 4;
|
|
23
|
+
export const BOOT_NODE_UDP_PORT = getBootNodeUdpPort();
|
|
24
24
|
|
|
25
25
|
export const createReqrespDataDir = () => fs.mkdtempSync(path.join(os.tmpdir(), 'reqresp-'));
|
|
26
26
|
|
|
@@ -38,8 +38,14 @@ export async function createReqrespTest(options: ReqrespOptions = {}): Promise<P
|
|
|
38
38
|
// To collect metrics - run in aztec-packages `docker compose --profile metrics up`
|
|
39
39
|
metricsPort: shouldCollectMetrics(),
|
|
40
40
|
initialConfig: {
|
|
41
|
-
|
|
42
|
-
aztecSlotDuration:
|
|
41
|
+
ethereumSlotDuration: 8,
|
|
42
|
+
aztecSlotDuration: 36,
|
|
43
|
+
blockDurationMs: 6000,
|
|
44
|
+
l1PublishingTime: 8,
|
|
45
|
+
minTxsPerBlock: 1,
|
|
46
|
+
maxTxsPerBlock: 2,
|
|
47
|
+
enforceTimeTable: true,
|
|
48
|
+
aztecProofSubmissionEpochs: 1024, // effectively do not reorg
|
|
43
49
|
...(disableStatusHandshake ? { p2pDisableStatusHandshake: true } : {}),
|
|
44
50
|
listenAddress: '127.0.0.1',
|
|
45
51
|
aztecEpochDuration: 64, // stable committee
|
|
@@ -85,7 +91,7 @@ export async function runReqrespTxTest(params: {
|
|
|
85
91
|
t.bootstrapNodeEnr,
|
|
86
92
|
NUM_VALIDATORS,
|
|
87
93
|
BOOT_NODE_UDP_PORT,
|
|
88
|
-
t.
|
|
94
|
+
t.genesis,
|
|
89
95
|
dataDir,
|
|
90
96
|
shouldCollectMetrics(),
|
|
91
97
|
);
|
|
@@ -143,6 +149,13 @@ export async function runReqrespTxTest(params: {
|
|
|
143
149
|
const submittedTxs = await Promise.all(
|
|
144
150
|
txBatches.map(async (batch, batchIndex) => {
|
|
145
151
|
const proposerNode = nodes[proposerIndexes[batchIndex]];
|
|
152
|
+
for (const tx of batch) {
|
|
153
|
+
t.logger.info(`Tx ${tx.getTxHash().toString()} base64: ${tx.toBuffer().toString('base64')}`);
|
|
154
|
+
}
|
|
155
|
+
const txHashes = batch.map(tx => tx.getTxHash().toString());
|
|
156
|
+
t.logger.info(
|
|
157
|
+
`Sending batch ${batchIndex} to proposer ${getNodePort(proposerIndexes[batchIndex])}: ${txHashes.join(', ')}`,
|
|
158
|
+
);
|
|
146
159
|
await Promise.all(
|
|
147
160
|
batch.map(async tx => {
|
|
148
161
|
try {
|
|
@@ -157,6 +170,12 @@ export async function runReqrespTxTest(params: {
|
|
|
157
170
|
}),
|
|
158
171
|
);
|
|
159
172
|
|
|
173
|
+
// Log pool state per node after sending
|
|
174
|
+
for (let i = 0; i < NUM_VALIDATORS; i++) {
|
|
175
|
+
const count = await nodes[i].getPendingTxCount();
|
|
176
|
+
t.logger.info(`Node ${getNodePort(i)} pool has ${count} pending txs`);
|
|
177
|
+
}
|
|
178
|
+
|
|
160
179
|
t.logger.info('Waiting for all transactions to be mined');
|
|
161
180
|
await Promise.all(
|
|
162
181
|
submittedTxs.flatMap((batch, batchIndex) =>
|
|
@@ -170,6 +189,36 @@ export async function runReqrespTxTest(params: {
|
|
|
170
189
|
|
|
171
190
|
t.logger.info('All transactions mined');
|
|
172
191
|
|
|
192
|
+
// Assert that multiple blocks were built for at least one slot
|
|
193
|
+
t.logger.info('Verifying multiple blocks for at least one checkpoint');
|
|
194
|
+
// Wait for L1 checkpoint sync, which may lag behind P2P block propagation.
|
|
195
|
+
const checkpoints = await retryUntil(
|
|
196
|
+
async () => {
|
|
197
|
+
const cps = await nodes[0].getCheckpoints(CheckpointNumber(1), 50);
|
|
198
|
+
return cps.length > 0 && cps.some(cp => cp.checkpoint.blocks.length >= 2) ? cps : undefined;
|
|
199
|
+
},
|
|
200
|
+
'waiting for multi-block checkpoint to sync from L1',
|
|
201
|
+
30,
|
|
202
|
+
1,
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
let mbpsFound = false;
|
|
206
|
+
let expectedBlockNumber = checkpoints[0].checkpoint.blocks[0].number;
|
|
207
|
+
|
|
208
|
+
for (const published of checkpoints) {
|
|
209
|
+
const blockCount = published.checkpoint.blocks.length;
|
|
210
|
+
mbpsFound = mbpsFound || blockCount >= 2;
|
|
211
|
+
|
|
212
|
+
for (let i = 0; i < blockCount; i++) {
|
|
213
|
+
const block = published.checkpoint.blocks[i];
|
|
214
|
+
expect(block.indexWithinCheckpoint).toBe(i);
|
|
215
|
+
expect(block.checkpointNumber).toBe(published.checkpoint.number);
|
|
216
|
+
expect(block.number).toBe(expectedBlockNumber);
|
|
217
|
+
expectedBlockNumber++;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
expect(mbpsFound).toBe(true);
|
|
173
222
|
return nodes;
|
|
174
223
|
}
|
|
175
224
|
|
package/src/e2e_p2p/shared.ts
CHANGED
|
@@ -6,12 +6,9 @@ import { Fr } from '@aztec/aztec.js/fields';
|
|
|
6
6
|
import type { Logger } from '@aztec/aztec.js/log';
|
|
7
7
|
import { TxHash } from '@aztec/aztec.js/tx';
|
|
8
8
|
import type { RollupCheatCodes } from '@aztec/aztec/testing';
|
|
9
|
-
import type {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
TallySlashingProposerContract,
|
|
13
|
-
} from '@aztec/ethereum/contracts';
|
|
14
|
-
import { EpochNumber } from '@aztec/foundation/branded-types';
|
|
9
|
+
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
10
|
+
import type { RollupContract, SlashingProposerContract } from '@aztec/ethereum/contracts';
|
|
11
|
+
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
15
12
|
import { timesAsync, unique } from '@aztec/foundation/collection';
|
|
16
13
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
17
14
|
import { retryUntil } from '@aztec/foundation/retry';
|
|
@@ -21,7 +18,6 @@ import { TestContract, TestContractArtifact } from '@aztec/noir-test-contracts.j
|
|
|
21
18
|
import { getPXEConfig, getPXEConfig as getRpcConfig } from '@aztec/pxe/server';
|
|
22
19
|
import { getRoundForOffense } from '@aztec/slasher';
|
|
23
20
|
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
24
|
-
import type { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
|
|
25
21
|
|
|
26
22
|
import { submitTxsTo } from '../shared/submit-transactions.js';
|
|
27
23
|
import { TestWallet } from '../test-wallet/test_wallet.js';
|
|
@@ -41,7 +37,7 @@ export const submitComplexTxsTo = async (
|
|
|
41
37
|
const spamCount = 15;
|
|
42
38
|
for (let i = 0; i < numTxs; i++) {
|
|
43
39
|
const method = spamContract.methods.spam(seed + BigInt(i * spamCount), spamCount, !!opts.callPublic);
|
|
44
|
-
const txHash = await method.send({ from, wait: NO_WAIT });
|
|
40
|
+
const { txHash } = await method.send({ from, wait: NO_WAIT });
|
|
45
41
|
logger.info(`Tx sent with hash ${txHash.toString()}`);
|
|
46
42
|
txs.push(txHash);
|
|
47
43
|
}
|
|
@@ -98,7 +94,7 @@ export async function prepareTransactions(
|
|
|
98
94
|
}
|
|
99
95
|
|
|
100
96
|
export function awaitProposalExecution(
|
|
101
|
-
slashingProposer:
|
|
97
|
+
slashingProposer: SlashingProposerContract,
|
|
102
98
|
timeoutSeconds: number,
|
|
103
99
|
logger: Logger,
|
|
104
100
|
): Promise<bigint> {
|
|
@@ -108,24 +104,12 @@ export function awaitProposalExecution(
|
|
|
108
104
|
reject(new Error(`Timeout waiting for proposal execution after ${timeoutSeconds}s`));
|
|
109
105
|
}, timeoutSeconds * 1000);
|
|
110
106
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
logger.warn(`Proposal ${args.payload} from round ${args.round} executed`);
|
|
114
|
-
clearTimeout(timeout);
|
|
115
|
-
unwatch();
|
|
116
|
-
resolve(args.round);
|
|
117
|
-
});
|
|
118
|
-
} else if (slashingProposer.type === 'tally') {
|
|
119
|
-
const unwatch = slashingProposer.listenToRoundExecuted(args => {
|
|
120
|
-
logger.warn(`Slash from round ${args.round} executed`);
|
|
121
|
-
clearTimeout(timeout);
|
|
122
|
-
unwatch();
|
|
123
|
-
resolve(args.round);
|
|
124
|
-
});
|
|
125
|
-
} else {
|
|
107
|
+
const unwatch = slashingProposer.listenToRoundExecuted(args => {
|
|
108
|
+
logger.warn(`Slash from round ${args.round} executed`);
|
|
126
109
|
clearTimeout(timeout);
|
|
127
|
-
|
|
128
|
-
|
|
110
|
+
unwatch();
|
|
111
|
+
resolve(args.round);
|
|
112
|
+
});
|
|
129
113
|
});
|
|
130
114
|
}
|
|
131
115
|
|
|
@@ -150,6 +134,58 @@ export async function awaitCommitteeExists({
|
|
|
150
134
|
return committee!.map(c => c.toString() as `0x${string}`);
|
|
151
135
|
}
|
|
152
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Advance epochs until we find one where the target proposer is selected for at least one slot,
|
|
139
|
+
* then stop one epoch before it. This leaves time for the caller to start sequencers before
|
|
140
|
+
* warping to the target epoch, avoiding the race where the target epoch passes before sequencers
|
|
141
|
+
* are ready.
|
|
142
|
+
*
|
|
143
|
+
* Returns the target epoch number so the caller can warp to it after starting sequencers.
|
|
144
|
+
*/
|
|
145
|
+
export async function advanceToEpochBeforeProposer({
|
|
146
|
+
epochCache,
|
|
147
|
+
cheatCodes,
|
|
148
|
+
targetProposer,
|
|
149
|
+
logger,
|
|
150
|
+
maxAttempts = 20,
|
|
151
|
+
}: {
|
|
152
|
+
epochCache: EpochCacheInterface;
|
|
153
|
+
cheatCodes: RollupCheatCodes;
|
|
154
|
+
targetProposer: EthAddress;
|
|
155
|
+
logger: Logger;
|
|
156
|
+
maxAttempts?: number;
|
|
157
|
+
}): Promise<{ targetEpoch: EpochNumber }> {
|
|
158
|
+
const { epochDuration } = await cheatCodes.getConfig();
|
|
159
|
+
|
|
160
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
161
|
+
const currentEpoch = await cheatCodes.getEpoch();
|
|
162
|
+
// Check the NEXT epoch's slots so we stay one epoch before the target,
|
|
163
|
+
// giving the caller time to start sequencers before the target epoch arrives.
|
|
164
|
+
const nextEpoch = Number(currentEpoch) + 1;
|
|
165
|
+
const startSlot = nextEpoch * Number(epochDuration);
|
|
166
|
+
const endSlot = startSlot + Number(epochDuration);
|
|
167
|
+
|
|
168
|
+
logger.info(
|
|
169
|
+
`Checking next epoch ${nextEpoch} (slots ${startSlot}-${endSlot - 1}) for proposer ${targetProposer} (current epoch: ${currentEpoch})`,
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
for (let s = startSlot; s < endSlot; s++) {
|
|
173
|
+
const proposer = await epochCache.getProposerAttesterAddressInSlot(SlotNumber(s));
|
|
174
|
+
if (proposer && proposer.equals(targetProposer)) {
|
|
175
|
+
logger.warn(
|
|
176
|
+
`Found target proposer ${targetProposer} in slot ${s} of epoch ${nextEpoch}. Staying at epoch ${currentEpoch} to allow sequencer startup.`,
|
|
177
|
+
);
|
|
178
|
+
return { targetEpoch: EpochNumber(nextEpoch) };
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
logger.info(`Target proposer not found in epoch ${nextEpoch}, advancing to next epoch`);
|
|
183
|
+
await cheatCodes.advanceToNextEpoch();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
throw new Error(`Target proposer ${targetProposer} not found in any slot after ${maxAttempts} epoch attempts`);
|
|
187
|
+
}
|
|
188
|
+
|
|
153
189
|
export async function awaitOffenseDetected({
|
|
154
190
|
logger,
|
|
155
191
|
nodeAdmin,
|
|
@@ -192,7 +228,6 @@ export async function awaitCommitteeKicked({
|
|
|
192
228
|
rollup,
|
|
193
229
|
cheatCodes,
|
|
194
230
|
committee,
|
|
195
|
-
slashFactory,
|
|
196
231
|
slashingProposer,
|
|
197
232
|
slashingRoundSize,
|
|
198
233
|
aztecSlotDuration,
|
|
@@ -203,8 +238,7 @@ export async function awaitCommitteeKicked({
|
|
|
203
238
|
rollup: RollupContract;
|
|
204
239
|
cheatCodes: RollupCheatCodes;
|
|
205
240
|
committee: readonly `0x${string}`[];
|
|
206
|
-
|
|
207
|
-
slashingProposer: EmpireSlashingProposerContract | TallySlashingProposerContract | undefined;
|
|
241
|
+
slashingProposer: SlashingProposerContract | undefined;
|
|
208
242
|
slashingRoundSize: number;
|
|
209
243
|
aztecSlotDuration: number;
|
|
210
244
|
aztecEpochDuration: number;
|
|
@@ -217,36 +251,14 @@ export async function awaitCommitteeKicked({
|
|
|
217
251
|
|
|
218
252
|
await cheatCodes.debugRollup();
|
|
219
253
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const events = await slashFactory.getSlashPayloadCreatedEvents();
|
|
229
|
-
return events.length > 0 ? events : undefined;
|
|
230
|
-
},
|
|
231
|
-
'slash payload created',
|
|
232
|
-
120,
|
|
233
|
-
1,
|
|
234
|
-
);
|
|
235
|
-
expect(slashPayloadEvents.length).toBe(1);
|
|
236
|
-
// The uniqueness check is needed since a validator may be slashed more than once on the same round (eg because they let two epochs be pruned)
|
|
237
|
-
expect(unique(slashPayloadEvents[0].slashes.map(slash => slash.validator.toString()))).toHaveLength(
|
|
238
|
-
committee.length,
|
|
239
|
-
);
|
|
240
|
-
} else {
|
|
241
|
-
// Use the slash offset to ensure we are in the right epoch for tally
|
|
242
|
-
const slashOffsetInRounds = await slashingProposer.getSlashOffsetInRounds();
|
|
243
|
-
const slashingRoundSizeInEpochs = slashingRoundSize / aztecEpochDuration;
|
|
244
|
-
const slashingOffsetInEpochs = Number(slashOffsetInRounds) * slashingRoundSizeInEpochs;
|
|
245
|
-
const firstEpochInOffenseRound = offenseEpoch - (offenseEpoch % slashingRoundSizeInEpochs);
|
|
246
|
-
const targetEpoch = firstEpochInOffenseRound + slashingOffsetInEpochs;
|
|
247
|
-
logger.info(`Advancing to epoch ${targetEpoch} so we start slashing`);
|
|
248
|
-
await cheatCodes.advanceToEpoch(EpochNumber(targetEpoch), { offset: -aztecSlotDuration / 2 });
|
|
249
|
-
}
|
|
254
|
+
// Use the slash offset to ensure we are in the right epoch for tally
|
|
255
|
+
const slashOffsetInRounds = await slashingProposer.getSlashOffsetInRounds();
|
|
256
|
+
const slashingRoundSizeInEpochs = slashingRoundSize / aztecEpochDuration;
|
|
257
|
+
const slashingOffsetInEpochs = Number(slashOffsetInRounds) * slashingRoundSizeInEpochs;
|
|
258
|
+
const firstEpochInOffenseRound = offenseEpoch - (offenseEpoch % slashingRoundSizeInEpochs);
|
|
259
|
+
const targetEpoch = firstEpochInOffenseRound + slashingOffsetInEpochs;
|
|
260
|
+
logger.info(`Advancing to epoch ${targetEpoch} so we start slashing`);
|
|
261
|
+
await cheatCodes.advanceToEpoch(EpochNumber(targetEpoch), { offset: -aztecSlotDuration / 2 });
|
|
250
262
|
|
|
251
263
|
const attestersPre = await rollup.getAttesters();
|
|
252
264
|
expect(attestersPre.length).toBe(committee.length);
|
|
@@ -26,7 +26,7 @@ export class TokenContractTest {
|
|
|
26
26
|
node!: AztecNode;
|
|
27
27
|
|
|
28
28
|
badAccount!: InvalidAccountContract;
|
|
29
|
-
|
|
29
|
+
authwitProxy!: GenericProxyContract;
|
|
30
30
|
wallet!: TestWallet;
|
|
31
31
|
adminAddress!: AztecAddress;
|
|
32
32
|
account1Address!: AztecAddress;
|
|
@@ -81,32 +81,36 @@ export class TokenContractTest {
|
|
|
81
81
|
await publicDeployAccounts(this.wallet, [this.adminAddress, this.account1Address]);
|
|
82
82
|
|
|
83
83
|
this.logger.verbose(`Deploying TokenContract...`);
|
|
84
|
-
this.asset = await TokenContract.deploy(
|
|
84
|
+
({ contract: this.asset } = await TokenContract.deploy(
|
|
85
85
|
this.wallet,
|
|
86
86
|
this.adminAddress,
|
|
87
87
|
TokenContractTest.TOKEN_NAME,
|
|
88
88
|
TokenContractTest.TOKEN_SYMBOL,
|
|
89
89
|
TokenContractTest.TOKEN_DECIMALS,
|
|
90
|
-
).send({ from: this.adminAddress });
|
|
90
|
+
).send({ from: this.adminAddress }));
|
|
91
91
|
this.logger.verbose(`Token deployed to ${this.asset.address}`);
|
|
92
92
|
|
|
93
93
|
this.logger.verbose(`Deploying bad account...`);
|
|
94
|
-
this.badAccount = await InvalidAccountContract.deploy(this.wallet).send({
|
|
94
|
+
({ contract: this.badAccount } = await InvalidAccountContract.deploy(this.wallet).send({
|
|
95
|
+
from: this.adminAddress,
|
|
96
|
+
}));
|
|
95
97
|
this.logger.verbose(`Deployed to ${this.badAccount.address}.`);
|
|
96
98
|
|
|
97
99
|
// Deploy a proxy contract for "on behalf of other" tests. The note owner must be the tx sender
|
|
98
100
|
// (so their notes are in scope), but msg_sender in the target must differ from the note owner
|
|
99
101
|
// to trigger authwit validation. The proxy forwards calls so that msg_sender != tx sender.
|
|
100
102
|
this.logger.verbose(`Deploying generic proxy...`);
|
|
101
|
-
this.
|
|
102
|
-
|
|
103
|
+
({ contract: this.authwitProxy } = await GenericProxyContract.deploy(this.wallet).send({
|
|
104
|
+
from: this.adminAddress,
|
|
105
|
+
}));
|
|
106
|
+
this.logger.verbose(`Deployed to ${this.authwitProxy.address}.`);
|
|
103
107
|
|
|
104
108
|
this.tokenSim = new TokenSimulator(this.asset, this.wallet, this.adminAddress, this.logger, [
|
|
105
109
|
this.adminAddress,
|
|
106
110
|
this.account1Address,
|
|
107
111
|
]);
|
|
108
112
|
|
|
109
|
-
expect(await this.asset.methods.get_admin().simulate({ from: this.adminAddress })).toBe(
|
|
113
|
+
expect((await this.asset.methods.get_admin().simulate({ from: this.adminAddress })).result).toBe(
|
|
110
114
|
this.adminAddress.toBigInt(),
|
|
111
115
|
);
|
|
112
116
|
}
|
|
@@ -140,7 +144,9 @@ export class TokenContractTest {
|
|
|
140
144
|
await asset.methods.mint_to_public(adminAddress, amount).send({ from: adminAddress });
|
|
141
145
|
tokenSim.mintPublic(adminAddress, amount);
|
|
142
146
|
|
|
143
|
-
const publicBalance = await asset.methods
|
|
147
|
+
const { result: publicBalance } = await asset.methods
|
|
148
|
+
.balance_of_public(adminAddress)
|
|
149
|
+
.simulate({ from: adminAddress });
|
|
144
150
|
this.logger.verbose(`Public balance of wallet 0: ${publicBalance}`);
|
|
145
151
|
expect(publicBalance).toEqual(this.tokenSim.balanceOfPublic(adminAddress));
|
|
146
152
|
|
|
@@ -148,11 +154,13 @@ export class TokenContractTest {
|
|
|
148
154
|
await mintTokensToPrivate(asset, adminAddress, adminAddress, amount);
|
|
149
155
|
tokenSim.mintPrivate(adminAddress, amount);
|
|
150
156
|
|
|
151
|
-
const privateBalance = await asset.methods
|
|
157
|
+
const { result: privateBalance } = await asset.methods
|
|
158
|
+
.balance_of_private(adminAddress)
|
|
159
|
+
.simulate({ from: adminAddress });
|
|
152
160
|
this.logger.verbose(`Private balance of wallet 0: ${privateBalance}`);
|
|
153
161
|
expect(privateBalance).toEqual(tokenSim.balanceOfPrivate(adminAddress));
|
|
154
162
|
|
|
155
|
-
const totalSupply = await asset.methods.total_supply().simulate({ from: adminAddress });
|
|
163
|
+
const { result: totalSupply } = await asset.methods.total_supply().simulate({ from: adminAddress });
|
|
156
164
|
this.logger.verbose(`Total supply: ${totalSupply}`);
|
|
157
165
|
expect(totalSupply).toEqual(tokenSim.totalSupply);
|
|
158
166
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ContractFunctionInteraction,
|
|
3
|
+
SendInteractionOptions,
|
|
4
|
+
SimulateInteractionOptions,
|
|
5
|
+
} from '@aztec/aztec.js/contracts';
|
|
6
|
+
import type { GenericProxyContract } from '@aztec/noir-test-contracts.js/GenericProxy';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Builds a proxy forwarding call from an action, selecting the right forward_private_N method.
|
|
10
|
+
*/
|
|
11
|
+
async function buildProxyCall(proxy: GenericProxyContract, action: ContractFunctionInteraction) {
|
|
12
|
+
const call = await action.getFunctionCall();
|
|
13
|
+
const argCount = call.args.length;
|
|
14
|
+
if (argCount === 2) {
|
|
15
|
+
return proxy.methods.forward_private_2(call.to, call.selector, call.args);
|
|
16
|
+
} else if (argCount === 3) {
|
|
17
|
+
return proxy.methods.forward_private_3(call.to, call.selector, call.args);
|
|
18
|
+
} else if (argCount === 4) {
|
|
19
|
+
return proxy.methods.forward_private_4(call.to, call.selector, call.args);
|
|
20
|
+
} else if (argCount === 5) {
|
|
21
|
+
return proxy.methods.forward_private_5(call.to, call.selector, call.args);
|
|
22
|
+
} else if (argCount === 6) {
|
|
23
|
+
return proxy.methods.forward_private_6(call.to, call.selector, call.args);
|
|
24
|
+
}
|
|
25
|
+
throw new Error(`No forward_private_${argCount} method on proxy`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Sends a contract call through the authwit proxy.
|
|
30
|
+
* The proxy becomes msg_sender in the target (triggering authwit validation),
|
|
31
|
+
* while the actual tx sender retains their keys in scope.
|
|
32
|
+
*/
|
|
33
|
+
export async function sendThroughAuthwitProxy(
|
|
34
|
+
proxy: GenericProxyContract,
|
|
35
|
+
action: ContractFunctionInteraction,
|
|
36
|
+
options: SendInteractionOptions,
|
|
37
|
+
) {
|
|
38
|
+
const proxyCall = await buildProxyCall(proxy, action);
|
|
39
|
+
return proxyCall.send(options);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Simulates a contract call through the authwit proxy.
|
|
44
|
+
* The proxy becomes msg_sender in the target (triggering authwit validation),
|
|
45
|
+
* while the actual tx sender retains their keys in scope.
|
|
46
|
+
*/
|
|
47
|
+
export async function simulateThroughAuthwitProxy(
|
|
48
|
+
proxy: GenericProxyContract,
|
|
49
|
+
action: ContractFunctionInteraction,
|
|
50
|
+
options: SimulateInteractionOptions,
|
|
51
|
+
) {
|
|
52
|
+
const proxyCall = await buildProxyCall(proxy, action);
|
|
53
|
+
return proxyCall.simulate(options);
|
|
54
|
+
}
|