@aztec/end-to-end 0.0.0-test.1 → 0.0.1-commit.b655e406
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 +73 -0
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -0
- package/dest/bench/client_flows/client_flows_benchmark.js +311 -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 +99 -0
- package/dest/bench/utils.d.ts +10 -36
- 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 +20 -12
- 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 +18 -24
- 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 +48 -69
- package/dest/e2e_deploy_contract/deploy_test.d.ts +14 -6
- 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 +58 -17
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +224 -43
- 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 +20 -9
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +98 -107
- 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 +57 -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 +9 -6
- package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
- package/dest/e2e_nested_contract/nested_contract_test.js +22 -19
- 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 +135 -0
- package/dest/e2e_p2p/p2p_network.d.ts +69 -22
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +180 -129
- package/dest/e2e_p2p/shared.d.ts +41 -5
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +163 -19
- package/dest/e2e_token_contract/token_contract_test.d.ts +11 -5
- 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/{e2e_prover → fixtures}/e2e_prover_test.d.ts +14 -9
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -0
- package/dest/{e2e_prover → fixtures}/e2e_prover_test.js +95 -100
- package/dest/fixtures/fixtures.d.ts +5 -6
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +4 -3
- package/dest/fixtures/get_acvm_config.d.ts +1 -1
- 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 +1 -1
- package/dest/fixtures/get_bb_config.d.ts.map +1 -1
- package/dest/fixtures/get_bb_config.js +10 -17
- package/dest/fixtures/l1_to_l2_messaging.d.ts +8 -5
- 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/setup_l1_contracts.d.ts +3 -3
- 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 +14 -13
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +73 -21
- package/dest/fixtures/snapshot_manager.d.ts +15 -7
- 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 +6 -3
- package/dest/fixtures/token_utils.d.ts.map +1 -1
- package/dest/fixtures/token_utils.js +23 -10
- package/dest/fixtures/utils.d.ts +76 -37
- package/dest/fixtures/utils.d.ts.map +1 -1
- package/dest/fixtures/utils.js +464 -368
- 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/quality_of_service/alert_checker.d.ts +1 -1
- package/dest/quality_of_service/alert_checker.d.ts.map +1 -1
- package/dest/shared/cross_chain_test_harness.d.ts +41 -25
- 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 +32 -24
- package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
- package/dest/shared/gas_portal_test_harness.js +50 -29
- package/dest/shared/jest_setup.js +1 -1
- package/dest/shared/submit-transactions.d.ts +5 -3
- 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 +13 -11
- package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.js +138 -108
- package/dest/simulators/lending_simulator.d.ts +6 -6
- package/dest/simulators/lending_simulator.d.ts.map +1 -1
- package/dest/simulators/lending_simulator.js +13 -16
- package/dest/simulators/token_simulator.d.ts +5 -2
- 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 +23 -10
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/setup_test_wallets.js +167 -58
- package/dest/spartan/utils.d.ts +106 -303
- package/dest/spartan/utils.d.ts.map +1 -1
- package/dest/spartan/utils.js +434 -130
- package/package.json +61 -56
- package/src/bench/client_flows/benchmark.ts +341 -0
- package/src/bench/client_flows/client_flows_benchmark.ts +402 -0
- package/src/bench/client_flows/config.ts +61 -0
- package/src/bench/client_flows/data_extractor.ts +111 -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 +63 -105
- package/src/e2e_deploy_contract/deploy_test.ts +23 -38
- package/src/e2e_epochs/epochs_test.ts +274 -54
- package/src/e2e_fees/bridging_race.notest.ts +80 -0
- package/src/e2e_fees/fees_test.ts +137 -136
- package/src/e2e_l1_publisher/write_json.ts +76 -0
- package/src/e2e_multi_validator/utils.ts +258 -0
- package/src/e2e_nested_contract/nested_contract_test.ts +27 -18
- package/src/e2e_p2p/inactivity_slash_test.ts +178 -0
- package/src/e2e_p2p/p2p_network.ts +272 -166
- package/src/e2e_p2p/shared.ts +244 -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 +101 -145
- 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 +112 -38
- package/src/fixtures/snapshot_manager.ts +187 -139
- package/src/fixtures/token_utils.ts +29 -12
- package/src/fixtures/utils.ts +552 -425
- package/src/fixtures/web3signer.ts +63 -0
- package/src/guides/up_quick_start.sh +6 -14
- 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 +58 -49
- package/src/shared/jest_setup.ts +1 -1
- package/src/shared/submit-transactions.ts +12 -8
- package/src/shared/uniswap_l1_l2.ts +173 -176
- package/src/simulators/lending_simulator.ts +12 -15
- package/src/simulators/token_simulator.ts +21 -13
- package/src/spartan/DEVELOP.md +121 -0
- package/src/spartan/setup_test_wallets.ts +215 -93
- package/src/spartan/utils.ts +490 -130
- 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
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { RollupContract, createL1Clients } from '@aztec/ethereum';
|
|
1
|
+
import { createLogger } from '@aztec/aztec.js/log';
|
|
2
|
+
import { RollupContract, createExtendedL1Client } from '@aztec/ethereum';
|
|
3
|
+
import { ChainMonitor } from '@aztec/ethereum/test';
|
|
5
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { CounterContract } from '@aztec/noir-contracts.js/Counter';
|
|
5
|
+
import { sleep } from '@aztec/foundation/sleep';
|
|
6
|
+
import { TestERC20Abi } from '@aztec/l1-artifacts';
|
|
9
7
|
import { FPCContract } from '@aztec/noir-contracts.js/FPC';
|
|
10
8
|
import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice';
|
|
9
|
+
import { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC';
|
|
11
10
|
import { TokenContract as BananaCoin } from '@aztec/noir-contracts.js/Token';
|
|
12
11
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
13
12
|
import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';
|
|
14
|
-
import { computePartialAddress } from '@aztec/stdlib/contract';
|
|
15
13
|
import { GasSettings } from '@aztec/stdlib/gas';
|
|
16
14
|
import { getContract } from 'viem';
|
|
17
15
|
import { MNEMONIC } from '../fixtures/fixtures.js';
|
|
18
16
|
import { createSnapshotManager, deployAccounts } from '../fixtures/snapshot_manager.js';
|
|
19
17
|
import { mintTokensToPrivate } from '../fixtures/token_utils.js';
|
|
20
|
-
import {
|
|
18
|
+
import { ensureAccountContractsPublished, getBalancesFn, setupSponsoredFPC } from '../fixtures/utils.js';
|
|
21
19
|
import { FeeJuicePortalTestingHarnessFactory } from '../shared/gas_portal_test_harness.js';
|
|
22
20
|
const { E2E_DATA_PATH: dataPath } = process.env;
|
|
23
21
|
/**
|
|
@@ -26,27 +24,28 @@ const { E2E_DATA_PATH: dataPath } = process.env;
|
|
|
26
24
|
* PublicDeployAccounts: Deploys the accounts publicly.
|
|
27
25
|
* DeployFeeJuice: Deploys the Fee Juice contract.
|
|
28
26
|
* FPCSetup: Deploys BananaCoin and FPC contracts, and bridges gas from L1.
|
|
27
|
+
* SponsoredFPCSetup: Deploys Sponsored FPC contract, and bridges gas from L1.
|
|
29
28
|
* FundAlice: Mints private and public bananas to Alice.
|
|
30
29
|
* SetupSubscription: Deploys a counter contract and a subscription contract, and mints Fee Juice to the subscription contract.
|
|
31
30
|
*/ export class FeesTest {
|
|
32
31
|
numberOfAccounts;
|
|
33
32
|
snapshotManager;
|
|
34
|
-
|
|
33
|
+
accounts;
|
|
35
34
|
logger;
|
|
36
|
-
pxe;
|
|
37
35
|
aztecNode;
|
|
38
36
|
cheatCodes;
|
|
39
|
-
|
|
37
|
+
wallet;
|
|
40
38
|
aliceAddress;
|
|
41
|
-
bobWallet;
|
|
42
39
|
bobAddress;
|
|
43
40
|
sequencerAddress;
|
|
44
41
|
coinbase;
|
|
45
42
|
fpcAdmin;
|
|
46
43
|
gasSettings;
|
|
44
|
+
rollupContract;
|
|
47
45
|
feeJuiceContract;
|
|
48
46
|
bananaCoin;
|
|
49
47
|
bananaFPC;
|
|
48
|
+
sponsoredFPC;
|
|
50
49
|
counterContract;
|
|
51
50
|
subscriptionContract;
|
|
52
51
|
feeJuiceBridgeTestHarness;
|
|
@@ -63,13 +62,15 @@ const { E2E_DATA_PATH: dataPath } = process.env;
|
|
|
63
62
|
APP_SPONSORED_TX_GAS_LIMIT;
|
|
64
63
|
constructor(testName, numberOfAccounts = 3, setupOptions = {}){
|
|
65
64
|
this.numberOfAccounts = numberOfAccounts;
|
|
66
|
-
this.
|
|
65
|
+
this.accounts = [];
|
|
67
66
|
this.ALICE_INITIAL_BANANAS = BigInt(1e22);
|
|
68
67
|
this.SUBSCRIPTION_AMOUNT = BigInt(1e19);
|
|
69
68
|
this.APP_SPONSORED_TX_GAS_LIMIT = BigInt(10e9);
|
|
70
69
|
if (!numberOfAccounts) {
|
|
71
70
|
throw new Error('There must be at least 1 initial account.');
|
|
72
71
|
}
|
|
72
|
+
setupOptions.coinbase ??= EthAddress.random();
|
|
73
|
+
this.coinbase = setupOptions.coinbase;
|
|
73
74
|
this.logger = createLogger(`e2e:e2e_fees:${testName}`);
|
|
74
75
|
this.snapshotManager = createSnapshotManager(`e2e_fees/${testName}-${numberOfAccounts}`, dataPath, {
|
|
75
76
|
startProverNode: true,
|
|
@@ -80,16 +81,12 @@ const { E2E_DATA_PATH: dataPath } = process.env;
|
|
|
80
81
|
}
|
|
81
82
|
async setup() {
|
|
82
83
|
const context = await this.snapshotManager.setup();
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
coinbase: this.coinbase
|
|
86
|
-
});
|
|
87
|
-
const rollupContract = RollupContract.getFromConfig(context.aztecNodeConfig);
|
|
88
|
-
this.chainMonitor = new ChainMonitor(rollupContract, this.logger, 200).start();
|
|
84
|
+
this.rollupContract = RollupContract.getFromConfig(context.aztecNodeConfig);
|
|
85
|
+
this.chainMonitor = new ChainMonitor(this.rollupContract, context.dateProvider, this.logger, 200).start();
|
|
89
86
|
return this;
|
|
90
87
|
}
|
|
91
88
|
async teardown() {
|
|
92
|
-
this.chainMonitor.stop();
|
|
89
|
+
await this.chainMonitor.stop();
|
|
93
90
|
await this.snapshotManager.teardown();
|
|
94
91
|
}
|
|
95
92
|
setIsMarkingAsProven(b) {
|
|
@@ -101,15 +98,33 @@ const { E2E_DATA_PATH: dataPath } = process.env;
|
|
|
101
98
|
await sleep(1000);
|
|
102
99
|
}
|
|
103
100
|
}
|
|
104
|
-
async
|
|
105
|
-
const
|
|
101
|
+
async getBlockRewards() {
|
|
102
|
+
const blockReward = await this.rollupContract.getBlockReward();
|
|
103
|
+
const rewardConfig = await this.rollupContract.getRewardConfig();
|
|
104
|
+
const balance = await this.feeJuiceBridgeTestHarness.getL1FeeJuiceBalance(EthAddress.fromString(rewardConfig.rewardDistributor));
|
|
105
|
+
const toDistribute = balance > blockReward ? blockReward : balance;
|
|
106
|
+
const sequencerBlockRewards = toDistribute * BigInt(rewardConfig.sequencerBps) / 10000n;
|
|
107
|
+
const proverBlockRewards = toDistribute - sequencerBlockRewards;
|
|
108
|
+
return {
|
|
109
|
+
sequencerBlockRewards,
|
|
110
|
+
proverBlockRewards
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
async mintAndBridgeFeeJuice(minter, recipient) {
|
|
114
|
+
const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(recipient);
|
|
106
115
|
const { claimSecret: secret, messageLeafIndex: index } = claim;
|
|
107
|
-
await this.feeJuiceContract.methods.claim(
|
|
116
|
+
await this.feeJuiceContract.methods.claim(recipient, claim.claimAmount, secret, index).send({
|
|
117
|
+
from: minter
|
|
118
|
+
}).wait();
|
|
108
119
|
}
|
|
109
120
|
/** Alice mints bananaCoin tokens privately to the target address and redeems them. */ async mintPrivateBananas(amount, address) {
|
|
110
|
-
const balanceBefore = await this.bananaCoin.methods.balance_of_private(address).simulate(
|
|
111
|
-
|
|
112
|
-
|
|
121
|
+
const balanceBefore = await this.bananaCoin.methods.balance_of_private(address).simulate({
|
|
122
|
+
from: this.aliceAddress
|
|
123
|
+
});
|
|
124
|
+
await mintTokensToPrivate(this.bananaCoin, this.aliceAddress, address, amount);
|
|
125
|
+
const balanceAfter = await this.bananaCoin.methods.balance_of_private(address).simulate({
|
|
126
|
+
from: this.aliceAddress
|
|
127
|
+
});
|
|
113
128
|
expect(balanceAfter).toEqual(balanceBefore + amount);
|
|
114
129
|
}
|
|
115
130
|
async applyBaseSnapshots() {
|
|
@@ -119,77 +134,65 @@ const { E2E_DATA_PATH: dataPath } = process.env;
|
|
|
119
134
|
await this.applyDeployBananaTokenSnapshot();
|
|
120
135
|
}
|
|
121
136
|
async applyInitialAccountsSnapshot() {
|
|
122
|
-
await this.snapshotManager.snapshot('initial_accounts', deployAccounts(this.numberOfAccounts, this.logger), async ({ deployedAccounts }, {
|
|
123
|
-
this.
|
|
137
|
+
await this.snapshotManager.snapshot('initial_accounts', deployAccounts(this.numberOfAccounts, this.logger), async ({ deployedAccounts }, { wallet, aztecNode, cheatCodes })=>{
|
|
138
|
+
this.wallet = wallet;
|
|
124
139
|
this.aztecNode = aztecNode;
|
|
125
140
|
this.gasSettings = GasSettings.default({
|
|
126
141
|
maxFeesPerGas: (await this.aztecNode.getCurrentBaseFees()).mul(2)
|
|
127
142
|
});
|
|
128
|
-
this.cheatCodes =
|
|
129
|
-
this.
|
|
130
|
-
this.
|
|
131
|
-
[this.
|
|
132
|
-
[this.aliceAddress, this.bobAddress, this.sequencerAddress] = this.wallets.map((w)=>w.getAddress());
|
|
143
|
+
this.cheatCodes = cheatCodes;
|
|
144
|
+
this.accounts = deployedAccounts.map((a)=>a.address);
|
|
145
|
+
this.accounts.forEach((a, i)=>this.logger.verbose(`Account ${i} address: ${a}`));
|
|
146
|
+
[this.aliceAddress, this.bobAddress, this.sequencerAddress] = this.accounts.slice(0, 3);
|
|
133
147
|
// We set Alice as the FPC admin to avoid the need for deployment of another account.
|
|
134
148
|
this.fpcAdmin = this.aliceAddress;
|
|
135
149
|
const canonicalFeeJuice = await getCanonicalFeeJuice();
|
|
136
|
-
this.feeJuiceContract = await FeeJuiceContract.at(canonicalFeeJuice.address, this.
|
|
137
|
-
if (this.numberOfAccounts > 1) {
|
|
138
|
-
const bobInstance = (await this.bobWallet.getContractMetadata(this.bobAddress)).contractInstance;
|
|
139
|
-
await this.aliceWallet.registerAccount(deployedAccounts[1].secret, await computePartialAddress(bobInstance));
|
|
140
|
-
}
|
|
141
|
-
this.coinbase = EthAddress.random();
|
|
142
|
-
const { publicClient, walletClient } = createL1Clients(aztecNodeConfig.l1RpcUrls, MNEMONIC);
|
|
143
|
-
this.feeJuiceBridgeTestHarness = await FeeJuicePortalTestingHarnessFactory.create({
|
|
144
|
-
aztecNode: aztecNode,
|
|
145
|
-
pxeService: pxe,
|
|
146
|
-
publicClient: publicClient,
|
|
147
|
-
walletClient: walletClient,
|
|
148
|
-
wallet: this.aliceWallet,
|
|
149
|
-
logger: this.logger
|
|
150
|
-
});
|
|
150
|
+
this.feeJuiceContract = await FeeJuiceContract.at(canonicalFeeJuice.address, this.wallet);
|
|
151
151
|
});
|
|
152
152
|
}
|
|
153
153
|
async applyPublicDeployAccountsSnapshot() {
|
|
154
|
-
await this.snapshotManager.snapshot('public_deploy_accounts', ()=>
|
|
154
|
+
await this.snapshotManager.snapshot('public_deploy_accounts', ()=>ensureAccountContractsPublished(this.wallet, this.accounts));
|
|
155
155
|
}
|
|
156
156
|
async applySetupFeeJuiceSnapshot() {
|
|
157
|
-
await this.snapshotManager.snapshot('setup_fee_juice', async (context)=>{
|
|
158
|
-
await setupCanonicalFeeJuice(context.pxe);
|
|
159
|
-
}, async (_data, context)=>{
|
|
157
|
+
await this.snapshotManager.snapshot('setup_fee_juice', async ()=>{}, async (_data, context)=>{
|
|
160
158
|
this.context = context;
|
|
161
|
-
this.feeJuiceContract = await FeeJuiceContract.at(ProtocolContractAddress.FeeJuice, this.
|
|
162
|
-
this.getGasBalanceFn = getBalancesFn('⛽', this.feeJuiceContract.methods.balance_of_public, this.logger);
|
|
163
|
-
const { publicClient, walletClient } = createL1Clients(context.aztecNodeConfig.l1RpcUrls, MNEMONIC);
|
|
159
|
+
this.feeJuiceContract = await FeeJuiceContract.at(ProtocolContractAddress.FeeJuice, this.wallet);
|
|
160
|
+
this.getGasBalanceFn = getBalancesFn('⛽', this.feeJuiceContract.methods.balance_of_public, this.aliceAddress, this.logger);
|
|
164
161
|
this.feeJuiceBridgeTestHarness = await FeeJuicePortalTestingHarnessFactory.create({
|
|
165
162
|
aztecNode: context.aztecNode,
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
wallet: this.aliceWallet,
|
|
163
|
+
aztecNodeAdmin: context.aztecNode,
|
|
164
|
+
l1Client: context.deployL1ContractsValues.l1Client,
|
|
165
|
+
wallet: this.wallet,
|
|
170
166
|
logger: this.logger
|
|
171
167
|
});
|
|
172
168
|
});
|
|
173
169
|
}
|
|
174
170
|
async applyDeployBananaTokenSnapshot() {
|
|
175
171
|
await this.snapshotManager.snapshot('deploy_banana_token', async ()=>{
|
|
176
|
-
const bananaCoin = await BananaCoin.deploy(this.
|
|
172
|
+
const bananaCoin = await BananaCoin.deploy(this.wallet, this.aliceAddress, 'BC', 'BC', 18n).send({
|
|
173
|
+
from: this.aliceAddress
|
|
174
|
+
}).deployed();
|
|
177
175
|
this.logger.info(`BananaCoin deployed at ${bananaCoin.address}`);
|
|
178
176
|
return {
|
|
179
177
|
bananaCoinAddress: bananaCoin.address
|
|
180
178
|
};
|
|
181
179
|
}, async ({ bananaCoinAddress })=>{
|
|
182
|
-
this.bananaCoin = await BananaCoin.at(bananaCoinAddress, this.
|
|
180
|
+
this.bananaCoin = await BananaCoin.at(bananaCoinAddress, this.wallet);
|
|
181
|
+
const logger = this.logger;
|
|
182
|
+
this.getBananaPublicBalanceFn = getBalancesFn('🍌.public', this.bananaCoin.methods.balance_of_public, this.aliceAddress, logger);
|
|
183
|
+
this.getBananaPrivateBalanceFn = getBalancesFn('🍌.private', this.bananaCoin.methods.balance_of_private, this.aliceAddress, logger);
|
|
183
184
|
});
|
|
184
185
|
}
|
|
185
186
|
async applyFPCSetupSnapshot() {
|
|
186
187
|
await this.snapshotManager.snapshot('fpc_setup', async (context)=>{
|
|
187
188
|
const feeJuiceContract = this.feeJuiceBridgeTestHarness.feeJuice;
|
|
188
|
-
expect((await context.
|
|
189
|
+
expect((await context.wallet.getContractMetadata(feeJuiceContract.address)).isContractPublished).toBe(true);
|
|
189
190
|
const bananaCoin = this.bananaCoin;
|
|
190
|
-
const bananaFPC = await FPCContract.deploy(this.
|
|
191
|
+
const bananaFPC = await FPCContract.deploy(this.wallet, bananaCoin.address, this.fpcAdmin).send({
|
|
192
|
+
from: this.aliceAddress
|
|
193
|
+
}).deployed();
|
|
191
194
|
this.logger.info(`BananaPay deployed at ${bananaFPC.address}`);
|
|
192
|
-
await this.feeJuiceBridgeTestHarness.bridgeFromL1ToL2(
|
|
195
|
+
await this.feeJuiceBridgeTestHarness.bridgeFromL1ToL2(bananaFPC.address, this.aliceAddress);
|
|
193
196
|
return {
|
|
194
197
|
bananaFPCAddress: bananaFPC.address,
|
|
195
198
|
feeJuiceAddress: feeJuiceContract.address,
|
|
@@ -197,51 +200,56 @@ const { E2E_DATA_PATH: dataPath } = process.env;
|
|
|
197
200
|
rollupAddress: context.deployL1ContractsValues.l1ContractAddresses.rollupAddress
|
|
198
201
|
};
|
|
199
202
|
}, async (data, context)=>{
|
|
200
|
-
const bananaFPC = await FPCContract.at(data.bananaFPCAddress, this.
|
|
203
|
+
const bananaFPC = await FPCContract.at(data.bananaFPCAddress, this.wallet);
|
|
201
204
|
this.bananaFPC = bananaFPC;
|
|
202
|
-
const logger = this.logger;
|
|
203
|
-
this.getBananaPublicBalanceFn = getBalancesFn('🍌.public', this.bananaCoin.methods.balance_of_public, logger);
|
|
204
|
-
this.getBananaPrivateBalanceFn = getBalancesFn('🍌.private', this.bananaCoin.methods.balance_of_private, logger);
|
|
205
205
|
this.getCoinbaseBalance = async ()=>{
|
|
206
|
-
const
|
|
206
|
+
const l1Client = createExtendedL1Client(context.aztecNodeConfig.l1RpcUrls, MNEMONIC);
|
|
207
207
|
const gasL1 = getContract({
|
|
208
208
|
address: data.l1FeeJuiceAddress.toString(),
|
|
209
209
|
abi: TestERC20Abi,
|
|
210
|
-
client:
|
|
210
|
+
client: l1Client
|
|
211
211
|
});
|
|
212
212
|
return await gasL1.read.balanceOf([
|
|
213
213
|
this.coinbase.toString()
|
|
214
214
|
]);
|
|
215
215
|
};
|
|
216
216
|
this.getCoinbaseSequencerRewards = async ()=>{
|
|
217
|
-
|
|
218
|
-
const rollup = getContract({
|
|
219
|
-
address: data.rollupAddress.toString(),
|
|
220
|
-
abi: RollupAbi,
|
|
221
|
-
client: walletClient
|
|
222
|
-
});
|
|
223
|
-
return await rollup.read.getSequencerRewards([
|
|
224
|
-
this.coinbase.toString()
|
|
225
|
-
]);
|
|
217
|
+
return await this.rollupContract.getSequencerRewards(this.coinbase);
|
|
226
218
|
};
|
|
227
219
|
this.getProverFee = async (blockNumber)=>{
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
const
|
|
235
|
-
const
|
|
220
|
+
const block = await this.aztecNode.getBlock(blockNumber);
|
|
221
|
+
// @todo @lherskind As we deal with #13601
|
|
222
|
+
// Right now the value is from `FeeLib.sol`
|
|
223
|
+
const L1_GAS_PER_EPOCH_VERIFIED = 1000000n;
|
|
224
|
+
// We round up
|
|
225
|
+
const mulDiv = (a, b, c)=>a * b / c + (a * b % c > 0n ? 1n : 0n);
|
|
226
|
+
const { baseFee } = await this.rollupContract.getL1FeesAt(block.header.globalVariables.timestamp);
|
|
227
|
+
const proverCost = mulDiv(mulDiv(L1_GAS_PER_EPOCH_VERIFIED, baseFee, await this.rollupContract.getEpochDuration()), 1n, await this.rollupContract.getManaTarget()) + await this.rollupContract.getProvingCostPerMana();
|
|
228
|
+
const price = await this.rollupContract.getFeeAssetPerEth();
|
|
236
229
|
const mana = block.header.totalManaUsed.toBigInt();
|
|
237
|
-
return mana *
|
|
230
|
+
return mulDiv(mana * proverCost, price, 10n ** 9n);
|
|
238
231
|
};
|
|
239
232
|
});
|
|
240
233
|
}
|
|
234
|
+
async applySponsoredFPCSetupSnapshot() {
|
|
235
|
+
await this.snapshotManager.snapshot('sponsored_fpc_setup', async (context)=>{
|
|
236
|
+
const feeJuiceContract = this.feeJuiceBridgeTestHarness.feeJuice;
|
|
237
|
+
expect((await context.wallet.getContractMetadata(feeJuiceContract.address)).isContractPublished).toBe(true);
|
|
238
|
+
const sponsoredFPC = await setupSponsoredFPC(this.wallet);
|
|
239
|
+
this.logger.info(`SponsoredFPC at ${sponsoredFPC.address}`);
|
|
240
|
+
return {
|
|
241
|
+
sponsoredFPCAddress: sponsoredFPC.address
|
|
242
|
+
};
|
|
243
|
+
}, async (data)=>{
|
|
244
|
+
this.sponsoredFPC = await SponsoredFPCContract.at(data.sponsoredFPCAddress, this.wallet);
|
|
245
|
+
});
|
|
246
|
+
}
|
|
241
247
|
async applyFundAliceWithBananas() {
|
|
242
248
|
await this.snapshotManager.snapshot('fund_alice', async ()=>{
|
|
243
249
|
await this.mintPrivateBananas(this.ALICE_INITIAL_BANANAS, this.aliceAddress);
|
|
244
|
-
await this.bananaCoin.methods.mint_to_public(this.aliceAddress, this.ALICE_INITIAL_BANANAS).send(
|
|
250
|
+
await this.bananaCoin.methods.mint_to_public(this.aliceAddress, this.ALICE_INITIAL_BANANAS).send({
|
|
251
|
+
from: this.aliceAddress
|
|
252
|
+
}).wait();
|
|
245
253
|
}, ()=>Promise.resolve());
|
|
246
254
|
}
|
|
247
255
|
async applyFundAliceWithPrivateBananas() {
|
|
@@ -249,21 +257,4 @@ const { E2E_DATA_PATH: dataPath } = process.env;
|
|
|
249
257
|
await this.mintPrivateBananas(this.ALICE_INITIAL_BANANAS, this.aliceAddress);
|
|
250
258
|
}, ()=>Promise.resolve());
|
|
251
259
|
}
|
|
252
|
-
async applySetupSubscription() {
|
|
253
|
-
await this.snapshotManager.snapshot('setup_subscription', async ()=>{
|
|
254
|
-
const counterContract = await CounterContract.deploy(this.bobWallet, 0, this.bobAddress).send().deployed();
|
|
255
|
-
// Deploy subscription contract, that allows subscriptions for SUBSCRIPTION_AMOUNT of bananas
|
|
256
|
-
const subscriptionContract = await AppSubscriptionContract.deploy(this.bobWallet, counterContract.address, this.bobAddress, this.bananaCoin.address, this.SUBSCRIPTION_AMOUNT, this.APP_SPONSORED_TX_GAS_LIMIT).send().deployed();
|
|
257
|
-
// Mint some Fee Juice to the subscription contract
|
|
258
|
-
// Could also use bridgeFromL1ToL2 from the harness, but this is more direct
|
|
259
|
-
await this.mintAndBridgeFeeJuice(subscriptionContract.address, FEE_FUNDING_FOR_TESTER_ACCOUNT);
|
|
260
|
-
return {
|
|
261
|
-
counterContractAddress: counterContract.address,
|
|
262
|
-
subscriptionContractAddress: subscriptionContract.address
|
|
263
|
-
};
|
|
264
|
-
}, async ({ counterContractAddress, subscriptionContractAddress })=>{
|
|
265
|
-
this.counterContract = await CounterContract.at(counterContractAddress, this.bobWallet);
|
|
266
|
-
this.subscriptionContract = await AppSubscriptionContract.at(subscriptionContractAddress, this.bobWallet);
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
260
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
|
+
import type { L2Block } from '@aztec/aztec.js/block';
|
|
3
|
+
import { Fr } from '@aztec/aztec.js/fields';
|
|
4
|
+
import { BatchedBlob, Blob } from '@aztec/blob-lib';
|
|
5
|
+
/**
|
|
6
|
+
* Creates a json object that can be used to test the solidity contract.
|
|
7
|
+
* The json object must be put into
|
|
8
|
+
*/
|
|
9
|
+
export declare function writeJson(fileName: string, block: L2Block, l1ToL2Content: Fr[], blobs: Blob[], batchedBlob: BatchedBlob, recipientAddress: AztecAddress, deployerAddress: `0x${string}`): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=write_json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write_json.d.ts","sourceRoot":"","sources":["../../src/e2e_l1_publisher/write_json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,IAAI,EAAiC,MAAM,iBAAiB,CAAC;AAOnF;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,aAAa,EAAE,EAAE,EAAE,EACnB,KAAK,EAAE,IAAI,EAAE,EACb,WAAW,EAAE,WAAW,EACxB,gBAAgB,EAAE,YAAY,EAC9B,eAAe,EAAE,KAAK,MAAM,EAAE,GAC7B,OAAO,CAAC,IAAI,CAAC,CAqDf"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { getPrefixedEthBlobCommitments } from '@aztec/blob-lib';
|
|
2
|
+
import { writeFile } from 'fs/promises';
|
|
3
|
+
const AZTEC_GENERATE_TEST_DATA = !!process.env.AZTEC_GENERATE_TEST_DATA;
|
|
4
|
+
/**
|
|
5
|
+
* Creates a json object that can be used to test the solidity contract.
|
|
6
|
+
* The json object must be put into
|
|
7
|
+
*/ export async function writeJson(fileName, block, l1ToL2Content, blobs, batchedBlob, recipientAddress, deployerAddress) {
|
|
8
|
+
if (!AZTEC_GENERATE_TEST_DATA) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
// Path relative to the package.json in the end-to-end folder
|
|
12
|
+
const path = `../../l1-contracts/test/fixtures/${fileName}.json`;
|
|
13
|
+
const asHex = (value, size = 64)=>{
|
|
14
|
+
const buffer = Buffer.isBuffer(value) ? value : value.toBuffer();
|
|
15
|
+
return `0x${buffer.toString('hex').padStart(size, '0')}`;
|
|
16
|
+
};
|
|
17
|
+
const jsonObject = {
|
|
18
|
+
populate: {
|
|
19
|
+
l1ToL2Content: l1ToL2Content.map((value)=>asHex(value)),
|
|
20
|
+
recipient: asHex(recipientAddress.toField()),
|
|
21
|
+
sender: deployerAddress
|
|
22
|
+
},
|
|
23
|
+
messages: {
|
|
24
|
+
l2ToL1Messages: block.body.txEffects.flatMap((txEffect)=>txEffect.l2ToL1Msgs).map((value)=>asHex(value))
|
|
25
|
+
},
|
|
26
|
+
block: {
|
|
27
|
+
// The json formatting in forge is a bit brittle, so we convert Fr to a number in the few values below.
|
|
28
|
+
// This should not be a problem for testing as long as the values are not larger than u32.
|
|
29
|
+
archive: asHex(block.archive.root),
|
|
30
|
+
blobCommitments: getPrefixedEthBlobCommitments(blobs),
|
|
31
|
+
batchedBlobInputs: batchedBlob.getEthBlobEvaluationInputs(),
|
|
32
|
+
blockNumber: block.number,
|
|
33
|
+
body: `0x${block.body.toBuffer().toString('hex')}`,
|
|
34
|
+
header: {
|
|
35
|
+
lastArchiveRoot: asHex(block.header.lastArchive.root),
|
|
36
|
+
contentCommitment: {
|
|
37
|
+
blobsHash: asHex(block.header.contentCommitment.blobsHash),
|
|
38
|
+
inHash: asHex(block.header.contentCommitment.inHash),
|
|
39
|
+
outHash: asHex(block.header.contentCommitment.outHash)
|
|
40
|
+
},
|
|
41
|
+
slotNumber: Number(block.header.globalVariables.slotNumber),
|
|
42
|
+
timestamp: Number(block.header.globalVariables.timestamp),
|
|
43
|
+
coinbase: asHex(block.header.globalVariables.coinbase, 40),
|
|
44
|
+
feeRecipient: asHex(block.header.globalVariables.feeRecipient),
|
|
45
|
+
gasFees: {
|
|
46
|
+
feePerDaGas: Number(block.header.globalVariables.gasFees.feePerDaGas),
|
|
47
|
+
feePerL2Gas: Number(block.header.globalVariables.gasFees.feePerL2Gas)
|
|
48
|
+
},
|
|
49
|
+
totalManaUsed: block.header.totalManaUsed.toNumber()
|
|
50
|
+
},
|
|
51
|
+
headerHash: asHex(block.getCheckpointHeader().hash()),
|
|
52
|
+
numTxs: block.body.txEffects.length
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const output = JSON.stringify(jsonObject, null, 2);
|
|
56
|
+
await writeFile(path, output, 'utf8');
|
|
57
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
+
import type { EthPrivateKey } from '@aztec/node-keystore';
|
|
4
|
+
export declare function createJSONRPCSigner(keyLookup: Map<string, EthPrivateKey>, stats: Map<string, number>): import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>;
|
|
5
|
+
export declare function createKeyFile1(fileName: string, mnemonic: string, validatorIndex: number, publisher1Key: EthPrivateKey, publisher2Key: EthPrivateKey, coinbase: EthAddress, feeRecipient: AztecAddress): Promise<void>;
|
|
6
|
+
export declare function createKeyFile2(fileName: string, validatorKey: EthPrivateKey, publisherMnemonic: string, publisher1Index: number, coinbase: EthAddress, feeRecipient: AztecAddress): Promise<void>;
|
|
7
|
+
export declare function createKeyFile3(fileName: string, validatorAddress: EthAddress, publisher1Key: EthPrivateKey, publisher2Key: EthPrivateKey, coinbase: EthAddress, remoteSignerUrl: string, feeRecipient: AztecAddress): Promise<void>;
|
|
8
|
+
export declare function createKeyFile4(fileName: string, validator1Address: EthAddress, validator2Address: EthAddress, publisher1Index: number, publisher2Key: EthPrivateKey, mnemonic: string, publisher3Key: EthPrivateKey, coinbase1: EthAddress, coinbase2: EthAddress, remoteSignerUrl: string, feeRecipient1: AztecAddress, feeRecipient2: AztecAddress): Promise<void>;
|
|
9
|
+
export declare function createKeyFile5(fileName: string, proverAddress: EthAddress, remoteSignerUrl: string): Promise<void>;
|
|
10
|
+
export declare function createKeyFile6(fileName: string, mnemonic: string, validator1Index: number, coinbase: EthAddress, feeRecipient: AztecAddress): Promise<void>;
|
|
11
|
+
export declare function addressForPrivateKey(privateKey: EthPrivateKey): EthAddress;
|
|
12
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/e2e_multi_validator/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAW1D,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,sGA0EpG;AAGD,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,UAAU,EACpB,YAAY,EAAE,YAAY,iBAmB3B;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,aAAa,EAC3B,iBAAiB,EAAE,MAAM,EACzB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,UAAU,EACpB,YAAY,EAAE,YAAY,iBAmB3B;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,UAAU,EAC5B,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,UAAU,EACpB,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,YAAY,iBAiB3B;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,UAAU,EAC7B,iBAAiB,EAAE,UAAU,EAC7B,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,UAAU,EACrB,SAAS,EAAE,UAAU,EACrB,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,YAAY,EAC3B,aAAa,EAAE,YAAY,iBA4B5B;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAcxG;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,UAAU,EACpB,YAAY,EAAE,YAAY,iBAkB3B;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,aAAa,GAAG,UAAU,CAE1E"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { getAddressFromPrivateKey } from '@aztec/ethereum';
|
|
2
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
+
import { writeFile } from 'fs/promises';
|
|
4
|
+
import { createServer } from 'http';
|
|
5
|
+
import { signMessage, signTypedData } from 'viem/accounts';
|
|
6
|
+
// Create a mock JSON RPC signer
|
|
7
|
+
// Only supports signing messages and type data
|
|
8
|
+
const SUPPORTED_METHODS = [
|
|
9
|
+
'eth_sign',
|
|
10
|
+
'eth_signTypedData_v4'
|
|
11
|
+
];
|
|
12
|
+
export function createJSONRPCSigner(keyLookup, stats) {
|
|
13
|
+
return createServer((req, res)=>{
|
|
14
|
+
if (req.method === 'POST') {
|
|
15
|
+
let body = '';
|
|
16
|
+
req.on('data', (chunk)=>{
|
|
17
|
+
body += chunk.toString();
|
|
18
|
+
});
|
|
19
|
+
req.on('end', ()=>{
|
|
20
|
+
try {
|
|
21
|
+
const jsonRequest = JSON.parse(body);
|
|
22
|
+
res.writeHead(200, {
|
|
23
|
+
'Content-Type': 'application/json'
|
|
24
|
+
});
|
|
25
|
+
if (!SUPPORTED_METHODS.includes(jsonRequest.method)) {
|
|
26
|
+
res.end(JSON.stringify({
|
|
27
|
+
jsonrpc: '2.0',
|
|
28
|
+
id: jsonRequest.id,
|
|
29
|
+
error: {
|
|
30
|
+
code: -32601,
|
|
31
|
+
message: 'Method not supported'
|
|
32
|
+
}
|
|
33
|
+
}));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// Get the address sending the transaction
|
|
37
|
+
const [address, data] = jsonRequest.params;
|
|
38
|
+
const lowerCaseAddress = address.toLowerCase();
|
|
39
|
+
stats.set(lowerCaseAddress, (stats.get(lowerCaseAddress) ?? 0) + 1);
|
|
40
|
+
// Find the private key for the address
|
|
41
|
+
const privateKey = keyLookup.get(address.toLowerCase());
|
|
42
|
+
if (!privateKey) {
|
|
43
|
+
res.end(JSON.stringify({
|
|
44
|
+
jsonrpc: '2.0',
|
|
45
|
+
id: jsonRequest.id,
|
|
46
|
+
error: {
|
|
47
|
+
code: -32602,
|
|
48
|
+
message: `No private key found for address ${address}`
|
|
49
|
+
}
|
|
50
|
+
}));
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const promise = jsonRequest.method === 'eth_sign' ? signMessage({
|
|
54
|
+
message: {
|
|
55
|
+
raw: data
|
|
56
|
+
},
|
|
57
|
+
privateKey
|
|
58
|
+
}) : signTypedData({
|
|
59
|
+
privateKey,
|
|
60
|
+
...data
|
|
61
|
+
});
|
|
62
|
+
void promise.then((signature)=>{
|
|
63
|
+
res.end(JSON.stringify({
|
|
64
|
+
jsonrpc: '2.0',
|
|
65
|
+
id: jsonRequest.id,
|
|
66
|
+
result: signature
|
|
67
|
+
}));
|
|
68
|
+
});
|
|
69
|
+
} catch (err) {
|
|
70
|
+
res.end(JSON.stringify({
|
|
71
|
+
jsonrpc: '2.0',
|
|
72
|
+
id: 1,
|
|
73
|
+
error: {
|
|
74
|
+
code: -32603,
|
|
75
|
+
message: `${err}`
|
|
76
|
+
}
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
} else {
|
|
81
|
+
res.writeHead(405);
|
|
82
|
+
res.end('Method not allowed');
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// Functions for creating file based key stores for the e2e_multi_validator_node_key_store test
|
|
87
|
+
export async function createKeyFile1(fileName, mnemonic, validatorIndex, publisher1Key, publisher2Key, coinbase, feeRecipient) {
|
|
88
|
+
const obj = {
|
|
89
|
+
schemaVersion: 1,
|
|
90
|
+
validators: [
|
|
91
|
+
{
|
|
92
|
+
attester: {
|
|
93
|
+
mnemonic: mnemonic,
|
|
94
|
+
accountIndex: 0,
|
|
95
|
+
addressIndex: validatorIndex,
|
|
96
|
+
addressCount: 1
|
|
97
|
+
},
|
|
98
|
+
coinbase: coinbase.toChecksumString(),
|
|
99
|
+
publisher: [
|
|
100
|
+
publisher1Key,
|
|
101
|
+
publisher2Key
|
|
102
|
+
],
|
|
103
|
+
feeRecipient: feeRecipient.toString()
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
};
|
|
107
|
+
await writeFile(fileName, JSON.stringify(obj, null, 2));
|
|
108
|
+
}
|
|
109
|
+
export async function createKeyFile2(fileName, validatorKey, publisherMnemonic, publisher1Index, coinbase, feeRecipient) {
|
|
110
|
+
const obj = {
|
|
111
|
+
schemaVersion: 1,
|
|
112
|
+
validators: [
|
|
113
|
+
{
|
|
114
|
+
attester: validatorKey,
|
|
115
|
+
coinbase: coinbase.toChecksumString(),
|
|
116
|
+
publisher: {
|
|
117
|
+
mnemonic: publisherMnemonic,
|
|
118
|
+
accountIndex: 0,
|
|
119
|
+
addressIndex: publisher1Index,
|
|
120
|
+
addressCount: 2
|
|
121
|
+
},
|
|
122
|
+
feeRecipient: feeRecipient.toString()
|
|
123
|
+
}
|
|
124
|
+
]
|
|
125
|
+
};
|
|
126
|
+
await writeFile(fileName, JSON.stringify(obj, null, 2));
|
|
127
|
+
}
|
|
128
|
+
export async function createKeyFile3(fileName, validatorAddress, publisher1Key, publisher2Key, coinbase, remoteSignerUrl, feeRecipient) {
|
|
129
|
+
const obj = {
|
|
130
|
+
schemaVersion: 1,
|
|
131
|
+
validators: [
|
|
132
|
+
{
|
|
133
|
+
attester: validatorAddress.toChecksumString(),
|
|
134
|
+
coinbase: coinbase.toChecksumString(),
|
|
135
|
+
publisher: [
|
|
136
|
+
publisher1Key,
|
|
137
|
+
publisher2Key
|
|
138
|
+
],
|
|
139
|
+
feeRecipient: feeRecipient.toString(),
|
|
140
|
+
remoteSigner: {
|
|
141
|
+
remoteSignerUrl: remoteSignerUrl
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
};
|
|
146
|
+
await writeFile(fileName, JSON.stringify(obj, null, 2));
|
|
147
|
+
}
|
|
148
|
+
export async function createKeyFile4(fileName, validator1Address, validator2Address, publisher1Index, publisher2Key, mnemonic, publisher3Key, coinbase1, coinbase2, remoteSignerUrl, feeRecipient1, feeRecipient2) {
|
|
149
|
+
const obj = {
|
|
150
|
+
schemaVersion: 1,
|
|
151
|
+
remoteSigner: {
|
|
152
|
+
remoteSignerUrl: remoteSignerUrl
|
|
153
|
+
},
|
|
154
|
+
validators: [
|
|
155
|
+
{
|
|
156
|
+
attester: validator1Address.toChecksumString(),
|
|
157
|
+
coinbase: coinbase1.toChecksumString(),
|
|
158
|
+
publisher: {
|
|
159
|
+
mnemonic: mnemonic,
|
|
160
|
+
accountIndex: 0,
|
|
161
|
+
addressIndex: publisher1Index,
|
|
162
|
+
addressCount: 2
|
|
163
|
+
},
|
|
164
|
+
feeRecipient: feeRecipient1.toString()
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
attester: validator2Address.toChecksumString(),
|
|
168
|
+
coinbase: coinbase2.toChecksumString(),
|
|
169
|
+
publisher: [
|
|
170
|
+
publisher2Key,
|
|
171
|
+
publisher3Key
|
|
172
|
+
],
|
|
173
|
+
feeRecipient: feeRecipient2.toString()
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
};
|
|
177
|
+
await writeFile(fileName, JSON.stringify(obj, null, 2));
|
|
178
|
+
}
|
|
179
|
+
export async function createKeyFile5(fileName, proverAddress, remoteSignerUrl) {
|
|
180
|
+
const obj = {
|
|
181
|
+
schemaVersion: 1,
|
|
182
|
+
prover: {
|
|
183
|
+
id: '0x1234567890123456789012345678901234567890',
|
|
184
|
+
publisher: [
|
|
185
|
+
{
|
|
186
|
+
address: proverAddress.toChecksumString(),
|
|
187
|
+
remoteSignerUrl: remoteSignerUrl
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
await writeFile(fileName, JSON.stringify(obj, null, 2));
|
|
193
|
+
}
|
|
194
|
+
export async function createKeyFile6(fileName, mnemonic, validator1Index, coinbase, feeRecipient) {
|
|
195
|
+
const obj = {
|
|
196
|
+
schemaVersion: 1,
|
|
197
|
+
validators: [
|
|
198
|
+
{
|
|
199
|
+
attester: {
|
|
200
|
+
mnemonic: mnemonic,
|
|
201
|
+
accountIndex: 0,
|
|
202
|
+
addressIndex: validator1Index,
|
|
203
|
+
addressCount: 2
|
|
204
|
+
},
|
|
205
|
+
coinbase: coinbase.toChecksumString(),
|
|
206
|
+
feeRecipient: feeRecipient.toString()
|
|
207
|
+
}
|
|
208
|
+
]
|
|
209
|
+
};
|
|
210
|
+
await writeFile(fileName, JSON.stringify(obj, null, 2));
|
|
211
|
+
}
|
|
212
|
+
export function addressForPrivateKey(privateKey) {
|
|
213
|
+
return EthAddress.fromString(getAddressFromPrivateKey(privateKey));
|
|
214
|
+
}
|