Skip to content
This repository has been archived by the owner on Nov 5, 2023. It is now read-only.

Commit

Permalink
Merge pull request #584 from web3well/bw-406-aggregator-compression
Browse files Browse the repository at this point in the history
Use compression in aggregator
  • Loading branch information
blakecduncan authored May 2, 2023
2 parents daa51bc + e42ccf2 commit ffd7037
Show file tree
Hide file tree
Showing 15 changed files with 219 additions and 96 deletions.
11 changes: 8 additions & 3 deletions aggregator/deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 };

Expand Down
10 changes: 10 additions & 0 deletions aggregator/manualTests/helpers/receiptOf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ethers } from "../../deps.ts";

export default async function receiptOf(
responsePromise: Promise<ethers.providers.TransactionResponse>,
): Promise<ethers.providers.TransactionReceipt> {
const response = await responsePromise;
const receipt = await response.wait();

return receipt;
}
2 changes: 0 additions & 2 deletions aggregator/manualTests/mint1ViaEthereumService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ const ethereumService = await EthereumService.create(
(evt) => {
console.log(evt);
},
addresses.verificationGateway,
addresses.utilities,
env.PRIVATE_KEY_AGG,
);

Expand Down
34 changes: 34 additions & 0 deletions aggregator/manualTests/registerWallet.ts
Original file line number Diff line number Diff line change
@@ -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",
],
),
);
2 changes: 0 additions & 2 deletions aggregator/manualTests/zeroAddressError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
// );

Expand Down
69 changes: 53 additions & 16 deletions aggregator/src/app/AggregationStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export type AggregationStrategyResult = {
aggregateBundle: Bundle | nil;
includedRows: BundleRow[];
bundleOverheadCost: BigNumber;
bundleOverheadLen: number;
expectedFee: BigNumber;
expectedMaxCost: BigNumber;
failedRows: BundleRow[];
Expand Down Expand Up @@ -105,7 +106,8 @@ export default class AggregationStrategy {
async run(eligibleRows: BundleRow[]): Promise<AggregationStrategyResult> {
eligibleRows = await this.#filterRows(eligibleRows);

const bundleOverheadGas = await this.measureBundleOverheadGas();
const { bundleOverheadGas, bundleOverheadLen } = await this
.measureBundleOverhead();

let aggregateBundle = this.blsWalletSigner.aggregate([]);
let aggregateGas = bundleOverheadGas;
Expand Down Expand Up @@ -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,
Expand All @@ -164,6 +167,7 @@ export default class AggregationStrategy {
bundleOverheadCost: bundleOverheadGas.mul(
(await this.ethereumService.GasConfig()).maxFeePerGas,
),
bundleOverheadLen,
expectedFee,
expectedMaxCost: aggregateBundleCheck.expectedMaxCost,
failedRows,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -459,14 +465,16 @@ export default class AggregationStrategy {
.callStaticSequenceWithMeasure(
feeToken
? es.Call(feeToken, "balanceOf", [es.wallet.address])
: es.Call(es.utilities, "ethBalanceOf", [es.wallet.address]),
bundles.map((bundle) =>
: es.Call(es.aggregatorUtilities, "ethBalanceOf", [
es.wallet.address,
]),
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) => {
Expand Down Expand Up @@ -533,10 +541,12 @@ export default class AggregationStrategy {
return nil;
}

bundleOverheadGas ??= await this.measureBundleOverheadGas();
bundleOverheadGas ??=
(await this.measureBundleOverhead()).bundleOverheadGas;

const gasEstimate = await this.ethereumService.verificationGateway
.estimateGas.processBundle(bundle);
const gasEstimate = await this.ethereumService.estimateCompressedGas(
bundle,
);

const marginalGasEstimate = gasEstimate.sub(bundleOverheadGas);

Expand Down Expand Up @@ -625,8 +635,7 @@ export default class AggregationStrategy {
}

const gasEstimate = feeInfo?.gasEstimate ??
await this.ethereumService.verificationGateway
.estimateGas.processBundle(bundle);
await this.ethereumService.estimateCompressedGas(bundle);

return {
success,
Expand All @@ -639,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
Expand All @@ -664,15 +673,43 @@ 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]),
),
]);

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<number> {
Expand Down
9 changes: 7 additions & 2 deletions aggregator/src/app/AppEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type AppEvent =
data: {
includedRows: number;
bundleOverheadCost: string;
bundleOverheadLen: number;
expectedFee: string;
expectedMaxCost: string;
};
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -97,5 +103,4 @@ type AppEvent =
};
};


export default AppEvent;
2 changes: 2 additions & 0 deletions aggregator/src/app/BundleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ export default class BundleService {
aggregateBundle,
includedRows,
bundleOverheadCost,
bundleOverheadLen,
expectedFee,
expectedMaxCost,
failedRows,
Expand All @@ -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),
},
Expand Down
Loading

0 comments on commit ffd7037

Please sign in to comment.