From bdca7833d3dbb8cb6ef5fddec06ef81c030ba4e4 Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Fri, 21 Apr 2023 15:20:11 +1000 Subject: [PATCH 1/8] Set up bundleCompressor in EthereumService --- aggregator/deps.ts | 11 ++- .../manualTests/mint1ViaEthereumService.ts | 2 - aggregator/manualTests/zeroAddressError.ts | 2 - aggregator/src/app/EthereumService.ts | 81 ++++++++++++------- aggregator/src/app/app.ts | 2 - aggregator/test/helpers/Fixture.ts | 6 +- 6 files changed, 60 insertions(+), 44 deletions(-) diff --git a/aggregator/deps.ts b/aggregator/deps.ts index 6589ce12..ee72c881 100644 --- a/aggregator/deps.ts +++ b/aggregator/deps.ts @@ -54,21 +54,26 @@ export type { PublicKey, Signature, VerificationGateway, -} from "https://esm.sh/bls-wallet-clients@0.8.3-c34db60"; +} from "https://esm.sh/bls-wallet-clients@0.8.3-bee2034"; export { Aggregator as AggregatorClient, AggregatorUtilitiesFactory, + BlsRegistrationCompressor, BlsWalletWrapper, + BundleCompressor, + ContractsConnector, decodeError, + Erc20Compressor, ERC20Factory, + FallbackCompressor, getConfig, MockERC20Factory, VerificationGatewayFactory, -} from "https://esm.sh/bls-wallet-clients@0.8.3-c34db60"; +} from "https://esm.sh/bls-wallet-clients@0.8.3-bee2034"; // Workaround for esbuild's export-star bug -import blsWalletClients from "https://esm.sh/bls-wallet-clients@0.8.3-c34db60"; +import blsWalletClients from "https://esm.sh/bls-wallet-clients@0.8.3-bee2034"; const { bundleFromDto, bundleToDto, initBlsWalletSigner } = blsWalletClients; export { bundleFromDto, bundleToDto, initBlsWalletSigner }; diff --git a/aggregator/manualTests/mint1ViaEthereumService.ts b/aggregator/manualTests/mint1ViaEthereumService.ts index 10a4c565..08d756f1 100755 --- a/aggregator/manualTests/mint1ViaEthereumService.ts +++ b/aggregator/manualTests/mint1ViaEthereumService.ts @@ -14,8 +14,6 @@ const ethereumService = await EthereumService.create( (evt) => { console.log(evt); }, - addresses.verificationGateway, - addresses.utilities, env.PRIVATE_KEY_AGG, ); diff --git a/aggregator/manualTests/zeroAddressError.ts b/aggregator/manualTests/zeroAddressError.ts index d94c9996..fcb93508 100644 --- a/aggregator/manualTests/zeroAddressError.ts +++ b/aggregator/manualTests/zeroAddressError.ts @@ -15,8 +15,6 @@ const provider = new ethers.providers.JsonRpcProvider(env.RPC_URL); // (evt) => { // console.log(evt); // }, -// addresses.verificationGateway, -// addresses.utilities, // env.PRIVATE_KEY_AGG, // ); diff --git a/aggregator/src/app/EthereumService.ts b/aggregator/src/app/EthereumService.ts index 6783dff4..6a85e43c 100644 --- a/aggregator/src/app/EthereumService.ts +++ b/aggregator/src/app/EthereumService.ts @@ -1,17 +1,20 @@ import { AggregatorUtilities, - AggregatorUtilitiesFactory, BaseContract, BigNumber, + BlsRegistrationCompressor, BlsWalletSigner, BlsWalletWrapper, Bundle, + BundleCompressor, BytesLike, + ContractsConnector, delay, + Erc20Compressor, ethers, + FallbackCompressor, initBlsWalletSigner, VerificationGateway, - VerificationGatewayFactory, Wallet, } from "../../deps.ts"; @@ -65,29 +68,17 @@ type DecodeReturnType< > = EnforceArray>; export default class EthereumService { - verificationGateway: VerificationGateway; - utilities: AggregatorUtilities; - constructor( public emit: (evt: AppEvent) => void, public wallet: Wallet, public provider: ethers.providers.Provider, public blsWalletWrapper: BlsWalletWrapper, public blsWalletSigner: BlsWalletSigner, - verificationGatewayAddress: string, - utilitiesAddress: string, + public verificationGateway: VerificationGateway, + public aggregatorUtilities: AggregatorUtilities, + public bundleCompressor: BundleCompressor, public nextNonce: BigNumber, - ) { - this.verificationGateway = VerificationGatewayFactory.connect( - verificationGatewayAddress, - this.wallet, - ); - - this.utilities = AggregatorUtilitiesFactory.connect( - utilitiesAddress, - this.wallet, - ); - } + ) {} NextNonce() { const result = this.nextNonce; @@ -97,17 +88,33 @@ export default class EthereumService { static async create( emit: (evt: AppEvent) => void, - verificationGatewayAddress: string, - utilitiesAddress: string, aggPrivateKey: string, ): Promise { const provider = new ethers.providers.JsonRpcProvider(env.RPC_URL); provider.pollingInterval = env.RPC_POLLING_INTERVAL; const wallet = EthereumService.Wallet(provider, aggPrivateKey); + const contractsConnector = await ContractsConnector.create(wallet); + + const [ + verificationGateway, + aggregatorUtilities, + blsExpanderDelegator, + erc20Expander, + blsRegistration, + fallbackExpander, + ] = await Promise.all([ + contractsConnector.VerificationGateway(), + contractsConnector.AggregatorUtilities(), + contractsConnector.BLSExpanderDelegator(), + contractsConnector.ERC20Expander(), + contractsConnector.BLSRegistration(), + contractsConnector.FallbackExpander(), + ]); + const blsWalletWrapper = await BlsWalletWrapper.connect( aggPrivateKey, - verificationGatewayAddress, + verificationGateway.address, provider, ); @@ -122,10 +129,7 @@ export default class EthereumService { ].join(" ")); } - await (await VerificationGatewayFactory.connect( - verificationGatewayAddress, - wallet, - ).processBundle( + await (await verificationGateway.processBundle( await blsWalletWrapper.signWithGasEstimate({ nonce: 0, actions: [], @@ -138,17 +142,31 @@ export default class EthereumService { const blsWalletSigner = await initBlsWalletSigner({ chainId, privateKey: aggPrivateKey, - verificationGatewayAddress, + verificationGatewayAddress: verificationGateway.address, }); + const bundleCompressor = new BundleCompressor(blsExpanderDelegator); + + const [erc20Compressor, blsRegistrationCompressor, fallbackCompressor] = + await Promise.all([ + Erc20Compressor.wrap(erc20Expander), + BlsRegistrationCompressor.wrap(blsRegistration), + FallbackCompressor.wrap(fallbackExpander), + ]); + + await bundleCompressor.addCompressor(erc20Compressor); + await bundleCompressor.addCompressor(blsRegistrationCompressor); + await bundleCompressor.addCompressor(fallbackCompressor); + return new EthereumService( emit, wallet, provider, blsWalletWrapper, blsWalletSigner, - verificationGatewayAddress, - utilitiesAddress, + verificationGateway, + aggregatorUtilities, + bundleCompressor, nextNonce, ); } @@ -221,9 +239,10 @@ export default class EthereumService { async callStaticSequence[]>( ...calls: Calls ): Promise> { - const rawResults = await this.utilities.callStatic.performSequence( - calls.map((c) => c.value), - ); + const rawResults = await this.aggregatorUtilities.callStatic + .performSequence( + calls.map((c) => c.value), + ); const results: CallResult[] = rawResults.map( ([success, result], i) => { diff --git a/aggregator/src/app/app.ts b/aggregator/src/app/app.ts index d5f2dd54..649c52e8 100644 --- a/aggregator/src/app/app.ts +++ b/aggregator/src/app/app.ts @@ -39,8 +39,6 @@ export default async function app(emit: (evt: AppEvent) => void) { const ethereumService = await EthereumService.create( emit, - addresses.verificationGateway, - addresses.utilities, env.PRIVATE_KEY_AGG, ); diff --git a/aggregator/test/helpers/Fixture.ts b/aggregator/test/helpers/Fixture.ts index 2c08013d..9282c0fd 100644 --- a/aggregator/test/helpers/Fixture.ts +++ b/aggregator/test/helpers/Fixture.ts @@ -79,8 +79,6 @@ export default class Fixture { const ethereumService = await EthereumService.create( emit, - netCfg.addresses.verificationGateway, - netCfg.addresses.utilities, env.PRIVATE_KEY_AGG, ); @@ -296,10 +294,10 @@ export default class Fixture { return wallets; } - + createHealthCheckService() { const healthCheckService = new HealthService(); - + return healthCheckService; } From b84aebfaa921a52b3f288371f9ee03bb66fb4f6a Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Fri, 21 Apr 2023 15:28:44 +1000 Subject: [PATCH 2/8] Remove unused variable --- aggregator/src/app/app.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/aggregator/src/app/app.ts b/aggregator/src/app/app.ts index 649c52e8..fbf209e2 100644 --- a/aggregator/src/app/app.ts +++ b/aggregator/src/app/app.ts @@ -10,7 +10,6 @@ import errorHandler from "./errorHandler.ts"; import notFoundHandler from "./notFoundHandler.ts"; import Mutex from "../helpers/Mutex.ts"; import Clock from "../helpers/Clock.ts"; -import getNetworkConfig from "../helpers/getNetworkConfig.ts"; import AppEvent from "./AppEvent.ts"; import BundleTable from "./BundleTable.ts"; import AggregationStrategy from "./AggregationStrategy.ts"; @@ -19,8 +18,6 @@ import HealthService from "./HealthService.ts"; import HealthRouter from "./HealthRouter.ts"; export default async function app(emit: (evt: AppEvent) => void) { - const { addresses } = await getNetworkConfig(); - const clock = Clock.create(); const bundleTableMutex = new Mutex(); From 52d49e16d888fca9caec2235bfcac16697710923 Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Fri, 21 Apr 2023 15:30:07 +1000 Subject: [PATCH 3/8] .utilities -> .aggregatorUtilities --- aggregator/src/app/AggregationStrategy.ts | 4 +++- aggregator/test/BundleServiceFees.test.ts | 14 +++++++------- aggregator/test/EthereumService.test.ts | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/aggregator/src/app/AggregationStrategy.ts b/aggregator/src/app/AggregationStrategy.ts index 7306ddd3..b1d5a936 100644 --- a/aggregator/src/app/AggregationStrategy.ts +++ b/aggregator/src/app/AggregationStrategy.ts @@ -459,7 +459,9 @@ export default class AggregationStrategy { .callStaticSequenceWithMeasure( feeToken ? es.Call(feeToken, "balanceOf", [es.wallet.address]) - : es.Call(es.utilities, "ethBalanceOf", [es.wallet.address]), + : es.Call(es.aggregatorUtilities, "ethBalanceOf", [ + es.wallet.address, + ]), bundles.map((bundle) => es.Call( es.verificationGateway, diff --git a/aggregator/test/BundleServiceFees.test.ts b/aggregator/test/BundleServiceFees.test.ts index c636f4d4..f446cefd 100644 --- a/aggregator/test/BundleServiceFees.test.ts +++ b/aggregator/test/BundleServiceFees.test.ts @@ -48,13 +48,13 @@ function approveAndSendTokensToOrigin( contractAddress: fx.testErc20.address, encodedFunction: fx.testErc20.interface.encodeFunctionData( "approve", - [es.utilities.address, amount], + [es.aggregatorUtilities.address, amount], ), }, { ethValue: 0, - contractAddress: es.utilities.address, - encodedFunction: es.utilities.interface.encodeFunctionData( + contractAddress: es.aggregatorUtilities.address, + encodedFunction: es.aggregatorUtilities.interface.encodeFunctionData( "sendTokenToTxOrigin", [fx.testErc20.address, amount], ), @@ -164,8 +164,8 @@ Fixture.test("submits bundle with sufficient eth fee", async (fx) => { actions: [ { ethValue: 1, - contractAddress: es.utilities.address, - encodedFunction: es.utilities.interface.encodeFunctionData( + contractAddress: es.aggregatorUtilities.address, + encodedFunction: es.aggregatorUtilities.interface.encodeFunctionData( "sendEthToTxOrigin", ), }, @@ -189,8 +189,8 @@ Fixture.test("submits bundle with sufficient eth fee", async (fx) => { actions: [ { ethValue: fee, - contractAddress: es.utilities.address, - encodedFunction: es.utilities.interface.encodeFunctionData( + contractAddress: es.aggregatorUtilities.address, + encodedFunction: es.aggregatorUtilities.interface.encodeFunctionData( "sendEthToTxOrigin", ), }, diff --git a/aggregator/test/EthereumService.test.ts b/aggregator/test/EthereumService.test.ts index 1a138a9b..c43ed76d 100644 --- a/aggregator/test/EthereumService.test.ts +++ b/aggregator/test/EthereumService.test.ts @@ -260,9 +260,9 @@ Fixture.test("callStaticSequence - correctly measures transfer", async (fx) => { const es = fx.ethereumService; const results = await es.callStaticSequence( - es.Call(es.utilities, "ethBalanceOf", [recvWallet.address]), + es.Call(es.aggregatorUtilities, "ethBalanceOf", [recvWallet.address]), es.Call(es.verificationGateway, "processBundle", [bundle]), - es.Call(es.utilities, "ethBalanceOf", [recvWallet.address]), + es.Call(es.aggregatorUtilities, "ethBalanceOf", [recvWallet.address]), ); const [balanceResultBefore, , balanceResultAfter] = results; From 02c8565e98dd38795632e9b5eca93216654447fd Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Fri, 21 Apr 2023 18:43:54 +1000 Subject: [PATCH 4/8] Use compression --- aggregator/src/app/AggregationStrategy.ts | 22 ++++++++--------- aggregator/src/app/EthereumService.ts | 29 ++++++++++++++++------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/aggregator/src/app/AggregationStrategy.ts b/aggregator/src/app/AggregationStrategy.ts index b1d5a936..017c5bc9 100644 --- a/aggregator/src/app/AggregationStrategy.ts +++ b/aggregator/src/app/AggregationStrategy.ts @@ -462,13 +462,13 @@ export default class AggregationStrategy { : es.Call(es.aggregatorUtilities, "ethBalanceOf", [ es.wallet.address, ]), - bundles.map((bundle) => + await Promise.all(bundles.map(async (bundle) => es.Call( - es.verificationGateway, - "processBundle", - [bundle], + es.bundleCompressor.blsExpanderDelegator, + "run", + [await es.bundleCompressor.compress(bundle)], ) - ), + )), ); return Range(bundles.length).map((i) => { @@ -537,8 +537,9 @@ export default class AggregationStrategy { bundleOverheadGas ??= await this.measureBundleOverheadGas(); - const gasEstimate = await this.ethereumService.verificationGateway - .estimateGas.processBundle(bundle); + const gasEstimate = await this.ethereumService.estimateCompressedGas( + bundle, + ); const marginalGasEstimate = gasEstimate.sub(bundleOverheadGas); @@ -627,8 +628,7 @@ export default class AggregationStrategy { } const gasEstimate = feeInfo?.gasEstimate ?? - await this.ethereumService.verificationGateway - .estimateGas.processBundle(bundle); + await this.ethereumService.estimateCompressedGas(bundle); return { success, @@ -666,8 +666,8 @@ export default class AggregationStrategy { }); const [oneOpGasEstimate, twoOpGasEstimate] = await Promise.all([ - es.verificationGateway.estimateGas.processBundle(bundle1), - es.verificationGateway.estimateGas.processBundle( + es.estimateCompressedGas(bundle1), + es.estimateCompressedGas( this.blsWalletSigner.aggregate([bundle1, bundle2]), ), ]); diff --git a/aggregator/src/app/EthereumService.ts b/aggregator/src/app/EthereumService.ts index 6a85e43c..0bd5ccfe 100644 --- a/aggregator/src/app/EthereumService.ts +++ b/aggregator/src/app/EthereumService.ts @@ -310,20 +310,23 @@ export default class EthereumService { assert(bundle.operations.length > 0, "Cannot process empty bundle"); assert(maxAttempts > 0, "Must have at least one attempt"); - const processBundleArgs: Parameters = - [ - bundle, - { - nonce: this.NextNonce(), - ...await this.GasConfig(), - }, - ]; + const compressedBundle = await this.bundleCompressor.compress(bundle); + + const processBundleArgs: Parameters< + (typeof this.bundleCompressor.blsExpanderDelegator)["run"] + > = [ + compressedBundle, + { + nonce: this.NextNonce(), + ...await this.GasConfig(), + }, + ]; const attempt = async () => { let txResponse: ethers.providers.TransactionResponse; try { - txResponse = await this.verificationGateway.processBundle( + txResponse = await this.bundleCompressor.blsExpanderDelegator.run( ...processBundleArgs, ); } catch (error) { @@ -386,6 +389,14 @@ export default class EthereumService { throw new Error("Expected return or throw from attempt loop"); } + async estimateCompressedGas(bundle: Bundle): Promise { + const compressedBundle = await this.bundleCompressor.compress(bundle); + + return this.bundleCompressor.blsExpanderDelegator.estimateGas.run( + compressedBundle, + ); + } + async GasConfig() { const block = await this.provider.getBlock("latest"); const previousBaseFee = block.baseFeePerGas; From 5cacd017d15f7c238d031ef0a108fa38a1e536cf Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Fri, 21 Apr 2023 19:26:26 +1000 Subject: [PATCH 5/8] Add tx len info to events --- aggregator/src/app/AggregationStrategy.ts | 43 ++++++++++++++++++++--- aggregator/src/app/AppEvent.ts | 9 +++-- aggregator/src/app/BundleService.ts | 2 ++ aggregator/src/app/EthereumService.ts | 13 ++++++- 4 files changed, 60 insertions(+), 7 deletions(-) diff --git a/aggregator/src/app/AggregationStrategy.ts b/aggregator/src/app/AggregationStrategy.ts index 017c5bc9..3e9e0e2c 100644 --- a/aggregator/src/app/AggregationStrategy.ts +++ b/aggregator/src/app/AggregationStrategy.ts @@ -70,6 +70,7 @@ export type AggregationStrategyResult = { aggregateBundle: Bundle | nil; includedRows: BundleRow[]; bundleOverheadCost: BigNumber; + bundleOverheadLen: number; expectedFee: BigNumber; expectedMaxCost: BigNumber; failedRows: BundleRow[]; @@ -105,7 +106,8 @@ export default class AggregationStrategy { async run(eligibleRows: BundleRow[]): Promise { eligibleRows = await this.#filterRows(eligibleRows); - const bundleOverheadGas = await this.measureBundleOverheadGas(); + const { bundleOverheadGas, bundleOverheadLen } = await this + .measureBundleOverhead(); let aggregateBundle = this.blsWalletSigner.aggregate([]); let aggregateGas = bundleOverheadGas; @@ -147,6 +149,7 @@ export default class AggregationStrategy { bundleOverheadCost: bundleOverheadGas.mul( (await this.ethereumService.GasConfig()).maxFeePerGas, ), + bundleOverheadLen, expectedFee: BigNumber.from(0), expectedMaxCost: BigNumber.from(0), failedRows, @@ -164,6 +167,7 @@ export default class AggregationStrategy { bundleOverheadCost: bundleOverheadGas.mul( (await this.ethereumService.GasConfig()).maxFeePerGas, ), + bundleOverheadLen, expectedFee, expectedMaxCost: aggregateBundleCheck.expectedMaxCost, failedRows, @@ -217,6 +221,7 @@ export default class AggregationStrategy { aggregateBundle: nil, includedRows: [], bundleOverheadCost: result.bundleOverheadCost, + bundleOverheadLen: result.bundleOverheadLen, expectedFee: BigNumber.from(0), expectedMaxCost: BigNumber.from(0), failedRows, @@ -256,6 +261,7 @@ export default class AggregationStrategy { aggregateBundle: nil, includedRows: [], bundleOverheadCost: result.bundleOverheadCost, + bundleOverheadLen: result.bundleOverheadLen, expectedFee: BigNumber.from(0), expectedMaxCost: BigNumber.from(0), failedRows, @@ -535,7 +541,8 @@ export default class AggregationStrategy { return nil; } - bundleOverheadGas ??= await this.measureBundleOverheadGas(); + bundleOverheadGas ??= + (await this.measureBundleOverhead()).bundleOverheadGas; const gasEstimate = await this.ethereumService.estimateCompressedGas( bundle, @@ -641,7 +648,7 @@ export default class AggregationStrategy { }); } - async measureBundleOverheadGas() { + async measureBundleOverhead() { // The simple way to do this would be to estimate the gas of an empty // bundle. However, an empty bundle is a bit of a special case, in // particular the on-chain BLS library outright refuses to validate it. So @@ -674,7 +681,35 @@ export default class AggregationStrategy { const opMarginalGasEstimate = twoOpGasEstimate.sub(oneOpGasEstimate); - return oneOpGasEstimate.sub(opMarginalGasEstimate); + const bundleOverheadGas = oneOpGasEstimate.sub(opMarginalGasEstimate); + + const [oneOpTx, twoOpTx] = await Promise.all([ + es.bundleCompressor.blsExpanderDelegator.populateTransaction.run( + await es.bundleCompressor.compress(bundle1), + ), + es.bundleCompressor.blsExpanderDelegator.populateTransaction.run( + await es.bundleCompressor.compress( + this.blsWalletSigner.aggregate([bundle1, bundle2]), + ), + ), + ]); + + const [oneOpLen, twoOpLen] = await Promise.all([ + es.wallet.signTransaction(oneOpTx).then((tx) => + ethers.utils.hexDataLength(tx) + ), + es.wallet.signTransaction(twoOpTx).then((tx) => + ethers.utils.hexDataLength(tx) + ), + ]); + + const opMarginalLen = twoOpLen - oneOpLen; + const bundleOverheadLen = oneOpLen - opMarginalLen; + + return { + bundleOverheadGas, + bundleOverheadLen, + }; } async #TokenDecimals(): Promise { diff --git a/aggregator/src/app/AppEvent.ts b/aggregator/src/app/AppEvent.ts index cfeb9c6a..507702f0 100644 --- a/aggregator/src/app/AppEvent.ts +++ b/aggregator/src/app/AppEvent.ts @@ -15,6 +15,7 @@ type AppEvent = data: { includedRows: number; bundleOverheadCost: string; + bundleOverheadLen: number; expectedFee: string; expectedMaxCost: string; }; @@ -44,7 +45,12 @@ type AppEvent = | { type: "unprofitable-despite-breakeven-operations" } | { type: "submission-attempt"; - data: { publicKeyShorts: string[]; attemptNumber: number }; + data: { + publicKeyShorts: string[]; + attemptNumber: number; + txLen: number; + compressedTxLen: number; + }; } | { type: "submission-attempt-failed"; @@ -97,5 +103,4 @@ type AppEvent = }; }; - export default AppEvent; diff --git a/aggregator/src/app/BundleService.ts b/aggregator/src/app/BundleService.ts index 84e380b4..0e1207c9 100644 --- a/aggregator/src/app/BundleService.ts +++ b/aggregator/src/app/BundleService.ts @@ -257,6 +257,7 @@ export default class BundleService { aggregateBundle, includedRows, bundleOverheadCost, + bundleOverheadLen, expectedFee, expectedMaxCost, failedRows, @@ -268,6 +269,7 @@ export default class BundleService { data: { includedRows: includedRows.length, bundleOverheadCost: ethers.utils.formatEther(bundleOverheadCost), + bundleOverheadLen, expectedFee: ethers.utils.formatEther(expectedFee), expectedMaxCost: ethers.utils.formatEther(expectedMaxCost), }, diff --git a/aggregator/src/app/EthereumService.ts b/aggregator/src/app/EthereumService.ts index 0bd5ccfe..1303332b 100644 --- a/aggregator/src/app/EthereumService.ts +++ b/aggregator/src/app/EthereumService.ts @@ -312,6 +312,17 @@ export default class EthereumService { const compressedBundle = await this.bundleCompressor.compress(bundle); + const [rawTx, rawCompressedTx] = await Promise.all([ + this.verificationGateway.populateTransaction.processBundle(bundle).then( + (tx) => this.wallet.signTransaction(tx), + ), + this.bundleCompressor.blsExpanderDelegator.populateTransaction + .run(compressedBundle).then((tx) => this.wallet.signTransaction(tx)), + ]); + + const txLen = ethers.utils.hexDataLength(rawTx); + const compressedTxLen = ethers.utils.hexDataLength(rawCompressedTx); + const processBundleArgs: Parameters< (typeof this.bundleCompressor.blsExpanderDelegator)["run"] > = [ @@ -355,7 +366,7 @@ export default class EthereumService { for (let i = 0; i < maxAttempts; i++) { this.emit({ type: "submission-attempt", - data: { attemptNumber: i + 1, publicKeyShorts }, + data: { attemptNumber: i + 1, publicKeyShorts, txLen, compressedTxLen }, }); const attemptResult = await attempt(); From 0da9350fd6a55940535e936ec1ba87032ab3a582 Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Mon, 24 Apr 2023 10:25:12 +1000 Subject: [PATCH 6/8] registerWallet --- aggregator/manualTests/helpers/receiptOf.ts | 10 ++++++ aggregator/manualTests/registerWallet.ts | 34 +++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 aggregator/manualTests/helpers/receiptOf.ts create mode 100755 aggregator/manualTests/registerWallet.ts diff --git a/aggregator/manualTests/helpers/receiptOf.ts b/aggregator/manualTests/helpers/receiptOf.ts new file mode 100644 index 00000000..5eba4917 --- /dev/null +++ b/aggregator/manualTests/helpers/receiptOf.ts @@ -0,0 +1,10 @@ +import { ethers } from "../../deps.ts"; + +export default async function receiptOf( + responsePromise: Promise, +): Promise { + const response = await responsePromise; + const receipt = await response.wait(); + + return receipt; +} diff --git a/aggregator/manualTests/registerWallet.ts b/aggregator/manualTests/registerWallet.ts new file mode 100755 index 00000000..bd044080 --- /dev/null +++ b/aggregator/manualTests/registerWallet.ts @@ -0,0 +1,34 @@ +#!/usr/bin/env -S deno run --allow-net --allow-env --allow-read + +import { ContractsConnector, ethers } from "../deps.ts"; +import * as env from "../src/env.ts"; +import AdminWallet from "../src/chain/AdminWallet.ts"; +import receiptOf from "./helpers/receiptOf.ts"; + +const provider = new ethers.providers.JsonRpcProvider(env.RPC_URL); + +const adminWallet = AdminWallet(provider); + +const connector = await ContractsConnector.create(adminWallet); + +const addressRegistry = await connector.AddressRegistry(); +const blsPublicKeyRegistry = await connector.BLSPublicKeyRegistry(); + +await receiptOf( + addressRegistry.register("0xCB1ca1e8DF1055636d7D07c3099c9de3c65CAAB4"), +); + +await receiptOf( + blsPublicKeyRegistry.register( + // You can get this in Quill by running this in the console of the wallet + // page (the page you get by clicking on the extension icon) + // JSON.stringify(debug.wallets[0].blsWalletSigner.getPublicKey()) + + [ + "0x0ad7e63a4bbfdad440beda1fe7fdfb77a59f2a6d991700c6cf4c3654a52389a9", + "0x0adaa93bdfda0f6b259a80c1af7ccf3451c35c1e175483927a8052bdbf59f801", + "0x1f56aa1bb1419c741f0a474e51f33da0ffc81ea870e2e2c440db72539a9efb9e", + "0x2f1f7e5d586d6ca5de3c8c198c3be3b998a2b6df7ee8a367a1e58f8b36fd524d", + ], + ), +); From ef8f2c7a13fa2277934829f6662f8107d7b47c70 Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Mon, 24 Apr 2023 13:12:21 +1000 Subject: [PATCH 7/8] Show address that lacks funds --- contracts/clients/src/SafeSingletonFactory.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/contracts/clients/src/SafeSingletonFactory.ts b/contracts/clients/src/SafeSingletonFactory.ts index 8dd1dc49..93fc208b 100644 --- a/contracts/clients/src/SafeSingletonFactory.ts +++ b/contracts/clients/src/SafeSingletonFactory.ts @@ -224,7 +224,9 @@ export default class SafeSingletonFactory { throw new Error( [ - "Insufficient funds:", + "Account", + await this.signer.getAddress(), + "has insufficient funds:", ethers.utils.formatEther(balance), "ETH, need (approx):", ethers.utils.formatEther(gasEstimate.mul(gasPrice)), From e42ccf2f1fb984a27480785db435fd8e57f34429 Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Mon, 24 Apr 2023 13:50:12 +1000 Subject: [PATCH 8/8] Deploy to arbitrum goerli --- contracts/networks/arbitrum-goerli.json | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/contracts/networks/arbitrum-goerli.json b/contracts/networks/arbitrum-goerli.json index 34510fe7..8275b3cc 100644 --- a/contracts/networks/arbitrum-goerli.json +++ b/contracts/networks/arbitrum-goerli.json @@ -1,20 +1,18 @@ { "parameters": {}, "addresses": { - "create2Deployer": "0x036d996D6855B83cd80142f2933d8C2617dA5617", - "precompileCostEstimator": "0x22E4a5251C1F02de8369Dd6f192033F6CB7531A4", - "blsLibrary": "0xF8a11BA6eceC43e23c9896b857128a4269290e39", - "verificationGateway": "0xae7DF242c589D479A5cF8fEA681736e0E0Bb1FB9", - "blsExpander": "0x4473e39a5F33A83B81387bb5F816354F04E724a3", - "utilities": "0x76cE3c1F2E6d87c355560fCbd28ccAcAe03f95F6", - "testToken": "0x5081a39b8A5f0E35a8D959395a630b68B74Dd30f", - "safeSingletonFactory": "n/a" + "safeSingletonFactory": "0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7", + "precompileCostEstimator": "0x6eb8F8d661eFe36daB11147830A1e690249bB830", + "verificationGateway": "0x84e09390992F481E98eeb100bA4f19910c145Ede", + "blsExpander": "0x3F99eFb259ff4d15F3a07C2449a019ab1bF7CEa5", + "utilities": "0x4bD2E4e99B50A2a9e6b9dABfA3C8dCD1f885F008", + "testToken": "0x783746Fda55512043e0BCB9b06dB620277859E02" }, "auxiliary": { "chainid": 421613, "domain": "0x0054159611832e24cdd64c6a133e71d373c5f8553dde6c762e6bffe707ad83cc", - "genesisBlock": 1206441, - "deployedBy": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "version": "bc3d1463f163b742026f951a2574016966b5c857" + "genesisBlock": 17602348, + "deployedBy": "0x9D5e5038c47da189f8C67A587c66a952a8b45bAb", + "version": "52d22bb114dd2abcc4754a05bca757435a2f33fd" } } \ No newline at end of file