Skip to content

Commit d1b3160

Browse files
authored
AA-40: Gaschecks with geth (eth-infinitism#102)
* A-32-enforce-checkin-gas-reports * use geth for local gas checks * changed "big" to 10 (avoid getting close to 128k tx limit)
1 parent 925528b commit d1b3160

File tree

13 files changed

+125
-32
lines changed

13 files changed

+125
-32
lines changed

.github/workflows/build.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ jobs:
1515

1616
test:
1717
runs-on: ubuntu-latest
18+
1819
steps:
1920
- uses: actions/setup-node@v1
2021
with:
@@ -29,6 +30,25 @@ jobs:
2930

3031
- run: yarn run ci
3132

33+
gas-checks:
34+
runs-on: ubuntu-latest
35+
services:
36+
localgeth:
37+
image: dtr22/geth-dev
38+
39+
steps:
40+
- uses: actions/setup-node@v1
41+
with:
42+
node-version: '14'
43+
- uses: actions/checkout@v1
44+
- uses: actions/cache@v2
45+
with:
46+
path: node_modules
47+
key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }}
48+
- run: yarn install
49+
- run: yarn compile
50+
- run: yarn ci-gas-calc
51+
3252
lint:
3353
runs-on: ubuntu-latest
3454
steps:

contracts/test/TestPaymasterAcceptAll.sol

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,13 @@ import "../BasePaymaster.sol";
88
*/
99
contract TestPaymasterAcceptAll is BasePaymaster {
1010

11-
// solhint-disable-next-line no-empty-blocks
12-
constructor(EntryPoint _entryPoint) BasePaymaster(_entryPoint) {}
11+
constructor(EntryPoint _entryPoint) BasePaymaster(_entryPoint) {
12+
// to support "deterministic address" deployer
13+
// solhint-disable avoid-tx-origin
14+
if (tx.origin != msg.sender) {
15+
_transferOwnership(tx.origin);
16+
}
17+
}
1318

1419
function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 requestId, uint maxCost) external virtual override view returns (bytes memory context) {
1520
(userOp, requestId, maxCost);

gascalc/1-simple-wallet.gas.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ context('simple wallet', function () {
99
await g.addTestRow({ title: 'simple - diff from previous', count: 2, diffLastGas: true })
1010
})
1111

12-
it('simple 20', async function () {
12+
it('simple 10', async function () {
1313
if (g.skipLong()) this.skip()
14-
await g.addTestRow({ title: 'simple', count: 20, diffLastGas: false })
15-
await g.addTestRow({ title: 'simple - diff from previous', count: 21, diffLastGas: true })
14+
await g.addTestRow({ title: 'simple', count: 10, diffLastGas: false })
15+
await g.addTestRow({ title: 'simple - diff from previous', count: 11, diffLastGas: true })
1616
})
1717
})

gascalc/2-paymaster.gas.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { parseEther } from 'ethers/lib/utils'
22
import { TestPaymasterAcceptAll__factory } from '../typechain'
33
import { ethers } from 'hardhat'
44
import { GasChecker } from './GasChecker'
5+
import { Create2Factory } from '../src/Create2Factory'
6+
import { hexValue } from '@ethersproject/bytes'
57

68
const ethersSigner = ethers.provider.getSigner()
79

@@ -11,8 +13,9 @@ context('Minimal Paymaster', function () {
1113

1214
let paymasterAddress: string
1315
before(async () => {
14-
const paymaster = await new TestPaymasterAcceptAll__factory(ethersSigner).deploy(g.entryPoint().address)
15-
paymasterAddress = paymaster.address
16+
const paymasterInit = hexValue(new TestPaymasterAcceptAll__factory(ethersSigner).getDeployTransaction(g.entryPoint().address).data!)
17+
const paymasterAddress = await new Create2Factory(ethers.provider, ethersSigner).deploy(paymasterInit, 0)
18+
const paymaster = TestPaymasterAcceptAll__factory.connect(paymasterAddress, ethersSigner)
1619
await paymaster.addStake(0, { value: 1 })
1720
await g.entryPoint().depositTo(paymaster.address, { value: parseEther('10') })
1821
})
@@ -26,13 +29,13 @@ context('Minimal Paymaster', function () {
2629
})
2730
})
2831

29-
it('simple paymaster 20', async function () {
32+
it('simple paymaster 10', async function () {
3033
if (g.skipLong()) this.skip()
3134

32-
await g.addTestRow({ title: 'simple paymaster', count: 20, paymaster: paymasterAddress, diffLastGas: false })
35+
await g.addTestRow({ title: 'simple paymaster', count: 10, paymaster: paymasterAddress, diffLastGas: false })
3336
await g.addTestRow({
3437
title: 'simple paymaster with diff',
35-
count: 21,
38+
count: 11,
3639
paymaster: paymasterAddress,
3740
diffLastGas: true
3841
})

gascalc/3-huge-tx-gas.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import { DefaultGasTestInfo, GasChecker } from './GasChecker'
22

3-
context('huge tx', function () {
3+
context('huge tx - 5k', function () {
44
this.timeout(60000)
5-
const huge = DefaultGasTestInfo.destCallData!.padEnd(20480, 'f')
5+
const huge = DefaultGasTestInfo.destCallData!.padEnd(10240, 'f')
66
const g = new GasChecker()
77

8-
it('big tx', async () => {
9-
await g.addTestRow({ title: 'big tx 10k', count: 1, destCallData: huge, diffLastGas: false })
8+
it('big tx 5k', async () => {
9+
await g.addTestRow({ title: 'big tx 5k', count: 1, destCallData: huge, diffLastGas: false })
1010
await g.addTestRow({ title: 'big tx - diff from previous', count: 2, destCallData: huge, diffLastGas: true })
1111
})
12-
it('big tx 20', async function () {
12+
it('big tx 10', async function () {
1313
if (g.skipLong()) this.skip()
14-
await g.addTestRow({ title: 'big tx', count: 20, destCallData: huge, diffLastGas: false })
15-
await g.addTestRow({ title: 'big tx - diff from previous', count: 21, destCallData: huge, diffLastGas: true })
14+
await g.addTestRow({ title: 'big tx 5k', count: 10, destCallData: huge, diffLastGas: false })
15+
await g.addTestRow({ title: 'big tx - diff from previous', count: 11, destCallData: huge, diffLastGas: true })
1616
})
1717
})

gascalc/GasChecker.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ export class GasChecker {
199199
return op
200200
}))
201201

202+
const txdata = GasCheckCollector.inst.entryPoint.interface.encodeFunctionData('handleOps', [userOps, info.beneficiary])
203+
console.log('=== encoded data=', txdata.length)
202204
const gasEst = await GasCheckCollector.inst.entryPoint.estimateGas.handleOps(
203205
userOps, info.beneficiary, {}
204206
)

hardhat.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ const config: HardhatUserConfig = {
3636
},
3737
networks: {
3838
dev: { url: 'http://localhost:8545' },
39+
// github action starts localgeth service, for gas calculations
40+
localgeth: { url: 'http://localgeth:8545' },
3941
goerli: getNetwork('goerli'),
4042
proxy: getNetwork1('http://localhost:8545'),
4143
kovan: getNetwork('kovan')

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,16 @@
1010
"lint:js": "eslint -f unix .",
1111
"lint-fix": "eslint -f unix . --fix",
1212
"lint:sol": "solhint -f unix \"contracts/**/*.sol\" --max-warnings 0",
13-
"gas-calc": "npx ts-mocha gascalc/*",
13+
"gas-calc": "./scripts/gascalc",
14+
"mocha-gascalc": "TS_NODE_TRANSPILE_ONLY=1 npx ts-mocha gascalc/*",
1415
"test": "./scripts/hh-wrapper test",
1516
"coverage": "COVERAGE=1 hardhat coverage",
1617
"deploy": "./scripts/hh-wrapper deploy",
1718
"test-dev": "hardhat test --network dev",
18-
"ci": "yarn compile && hardhat test && yarn gas-calc && yarn run runop",
19+
"ci": "yarn compile && hardhat test && yarn run runop",
20+
"ci-gas-calc": "yarn gas-calc && yarn check-gas-reports",
21+
"check-gas-reports": "./scripts/check-gas-reports",
22+
1923
"runop": "hardhat run src/runop.ts ",
2024
"runop-goerli": "AA_URL=https://account-abstraction-goerli.nethermind.io yarn runop --network goerli",
2125
"runop3": "hardhat run src/runop3.ts "

reports/gas-checker.txt

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,34 @@
22
the destination is "wallet.nonce()", which is known to be "hot" address used by this wallet
33
it little higher than EOA call: its an exec from entrypoint (or wallet owner) into wallet contract, verifying msg.sender and exec to target)
44
- gas estimate "simple" - 27751
5-
- gas estimate "big tx 10k" - 218388
5+
- gas estimate "big tx 5k" - 122740
66
╔════════════════════════════════╤═══════╤═══════════════╤════════════════╤═════════════════════╗
77
║ handleOps description │ count │ total gasUsed │ per UserOp gas │ per UserOp overhead ║
88
║ │ │ │ (delta for │ (compared to ║
99
║ │ │ │ one UserOp) │ wallet.exec()) ║
1010
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
11-
║ simple │ 1 │ 74114 │ │ ║
11+
║ simple │ 1 │ 74094 │ │ ║
1212
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
13-
║ simple - diff from previous │ 2 │ │ 4207514324
13+
║ simple - diff from previous │ 2 │ │ 4213514384
1414
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
15-
║ simple │ 20874669 │ │ ║
15+
║ simple │ 10453128 │ │ ║
1616
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
17-
║ simple - diff from previous │ 21 │ │ 4242814677
17+
║ simple - diff from previous │ 11 │ │ 4213214381
1818
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
19-
║ simple paymaster │ 1 │ 80231 │ │ ║
19+
║ simple paymaster │ 1 │ 74094 │ │ ║
2020
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
21-
║ simple paymaster with diff │ 2 │ │ 4097213221
21+
║ simple paymaster with diff │ 2 │ │ 4211514364
2222
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
23-
║ simple paymaster │ 20858952 │ │ ║
23+
║ simple paymaster │ 10453124 │ │ ║
2424
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
25-
║ simple paymaster with diff │ 21 │ │ 4126113510
25+
║ simple paymaster with diff │ 11 │ │ 4224414493
2626
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
27-
║ big tx 10k │ 1 │ 274578 │ │ ║
27+
║ big tx 5k │ 1 │ 173728 │ │ ║
2828
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
29-
║ big tx - diff from previous │ 2 │ │ 24182623438
29+
║ big tx - diff from previous │ 2 │ │ 14137018630
3030
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
31-
║ big tx 204955417 │ │ ║
31+
║ big tx 5k101451288 │ │ ║
3232
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
33-
║ big tx - diff from previous │ 21 │ │ 25173933351
33+
║ big tx - diff from previous │ 11 │ │ 14283220092
3434
╚════════════════════════════════╧═══════╧═══════════════╧════════════════╧═════════════════════╝
3535

scripts/check-gas-reports

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/bash
2+
# make sure gas reports are checked in with this commit
3+
# dump report diff
4+
# exit with "1" if there is a diff, zero if no diff
5+
6+
folder=${1:-reports}
7+
git diff --color=always $folder
8+
git diff ${folder} | grep -q .
9+
10+
if [ "$?" == 1 ]; then
11+
#diff with no error - ok
12+
exit
13+
else
14+
echo ERROR: found above unchecked reports.
15+
exit 1
16+
fi
17+

0 commit comments

Comments
 (0)