Commit 456ba22b authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #1429 from ethereum-optimism/develop

Develop to Master PR
parents 09dcc3c6 ea2efbde
---
'@eth-optimism/contracts': patch
---
Add etherscan verification support
---
'@eth-optimism/core-utils': patch
---
increased coverage of core-utils
---
'@eth-optimism/batch-submitter': patch
'@eth-optimism/core-utils': patch
'@eth-optimism/data-transport-layer': patch
'@eth-optimism/message-relayer': patch
---
Added coverage for packages
---
'@eth-optimism/core-utils': patch
'@eth-optimism/l2geth': patch
---
Lower per tx fee overhead to more accurately represent L1 costs
---
'@eth-optimism/batch-submitter': patch
---
Add loglines for eip1559 related fields before sending a transaction
...@@ -60,45 +60,8 @@ jobs: ...@@ -60,45 +60,8 @@ jobs:
env: env:
CC_SECRET: ${{ secrets.CC_SECRET }} CC_SECRET: ${{ secrets.CC_SECRET }}
# A hack that allows running a job only if a specific directory changed.
# Ref: https://github.community/t/run-job-only-if-folder-changed/118292
is-contracts-package:
name: Check files for changes to the contracts package
# This job will break on a push event, so we just skip it,
# which in turn skips the test-coverage job.
if: ${{ github.event_name != 'push' }}
outputs:
run_coverage: ${{ steps.check_files.outputs.run_coverage }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- run: git fetch origin $GITHUB_BASE_REF
- name: check modified files
id: check_files
run: |
echo "=============== list modified files ==============="
git diff --name-only origin/$GITHUB_BASE_REF HEAD -- .
echo "========== check paths of modified files =========="
git diff --name-only origin/$GITHUB_BASE_REF HEAD -- . > files.txt
while IFS= read -r file
do
echo $file
if [[ $file != packages/contracts/* ]]; then
echo "This modified files are not in the contracts package."
echo "::set-output name=run_coverage::false"
break
else
echo "::set-output name=run_coverage::true"
fi
done < files.txt
test-coverage: test-coverage:
name: Generate test coverage name: Generate test coverage
needs: is-contracts-package
if: needs.is-contracts-package.outputs.run_coverage == 'true'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
...@@ -142,6 +105,31 @@ jobs: ...@@ -142,6 +105,31 @@ jobs:
files: ./packages/contracts/coverage.json files: ./packages/contracts/coverage.json
fail_ci_if_error: false fail_ci_if_error: false
verbose: true verbose: true
flags: contracts
- uses: codecov/codecov-action@v1
with:
files: ./packages/core-utils/coverage.json
fail_ci_if_error: false
verbose: true
flags: core-utils
- uses: codecov/codecov-action@v1
with:
files: ./packages/batch-submitter/coverage.json
fail_ci_if_error: false
verbose: true
flags: batch-submitter
- uses: codecov/codecov-action@v1
with:
files: ./packages/data-transport-layer/coverage.json
fail_ci_if_error: false
verbose: true
flags: data-transport-layer
- uses: codecov/codecov-action@v1
with:
files: ./packages/message-relayer/coverage.json
fail_ci_if_error: false
verbose: true
flags: message-relayer
lint: lint:
name: Linting name: Linting
runs-on: ubuntu-latest runs-on: ubuntu-latest
......
...@@ -3,6 +3,7 @@ node_modules ...@@ -3,6 +3,7 @@ node_modules
results results
temp temp
.nyc_output .nyc_output
coverage.json
*.tsbuildinfo *.tsbuildinfo
dist dist
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
// overhead represents the fixed cost of batch submission of a single // overhead represents the fixed cost of batch submission of a single
// transaction in gas. // transaction in gas.
const overhead uint64 = 4200 + 200*params.TxDataNonZeroGasEIP2028 const overhead uint64 = 2750
// feeScalar is used to scale the calculations in EncodeL2GasLimit // feeScalar is used to scale the calculations in EncodeL2GasLimit
// to prevent them from being too large // to prevent them from being too large
......
...@@ -420,9 +420,7 @@ describe('Basic RPC tests', () => { ...@@ -420,9 +420,7 @@ describe('Basic RPC tests', () => {
expect(decoded).to.deep.eq(BigNumber.from(l2Gaslimit)) expect(decoded).to.deep.eq(BigNumber.from(l2Gaslimit))
expect(estimate.toString().endsWith(l2Gaslimit.toString())) expect(estimate.toString().endsWith(l2Gaslimit.toString()))
const l2GasPrice = BigNumber.from(0) const l2GasPrice = await env.gasPriceOracle.gasPrice()
// The L2GasPrice should be fetched from the L2GasPrice oracle contract,
// but it does not yet exist. Use the default value for now
const expected = TxGasLimit.encode({ const expected = TxGasLimit.encode({
data: tx.data, data: tx.data,
l1GasPrice, l1GasPrice,
......
...@@ -25,7 +25,7 @@ var ( ...@@ -25,7 +25,7 @@ var (
// overhead represents the fixed cost of batch submission of a single // overhead represents the fixed cost of batch submission of a single
// transaction in gas. // transaction in gas.
const overhead uint64 = 4200 + 200*params.TxDataNonZeroGasEIP2028 const overhead uint64 = 2750
// feeScalar is used to scale the calculations in EncodeL2GasLimit // feeScalar is used to scale the calculations in EncodeL2GasLimit
// to prevent them from being too large // to prevent them from being too large
......
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/master/graph/badge.svg?token=0VTG7PG7YR&flag=batch-submitter)](https://codecov.io/gh/ethereum-optimism/optimism)
# Batch Submitter # Batch Submitter
Contains an executable batch submitter service which watches L1 and a local L2 node and submits batches to the Contains an executable batch submitter service which watches L1 and a local L2 node and submits batches to the
...@@ -31,9 +32,9 @@ Examples: ...@@ -31,9 +32,9 @@ Examples:
### Submission ### Submission
You may test a submission locally against a local Hardhat fork. You may test a submission locally against a local Hardhat fork.
1. Follow the instructions [here](https://github.com/ethereum-optimism/hardhat) to run a Hardhat node. 1. Follow the instructions [here](https://github.com/ethereum-optimism/hardhat) to run a Hardhat node.
2. Change the Batch Submitter `.env` field `L1_NODE_WEB3_URL` to the local Hardhat url. Depending on which network you are using, update `ADDRESS_MANAGER_ADDRESS` according to the [Regenesis repo](https://github.com/ethereum-optimism/regenesis). 2. Change the Batch Submitter `.env` field `L1_NODE_WEB3_URL` to the local Hardhat url. Depending on which network you are using, update `ADDRESS_MANAGER_ADDRESS` according to the [Regenesis repo](https://github.com/ethereum-optimism/regenesis).
3. Also check `L2_NODE_WEB3_URL` is correctly set and has transactions to submit. 3. Also check `L2_NODE_WEB3_URL` is correctly set and has transactions to submit.
3. Run `yarn build` to build your changes. 3. Run `yarn build` to build your changes.
......
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
"pre-commit": "lint-staged", "pre-commit": "lint-staged",
"lint:fix": "yarn lint:check --fix", "lint:fix": "yarn lint:check --fix",
"lint:check": "eslint .", "lint:check": "eslint .",
"test": "hardhat test --show-stack-traces" "test": "hardhat test --show-stack-traces",
"test:coverage": "nyc hardhat test && nyc merge .nyc_output coverage.json"
}, },
"keywords": [ "keywords": [
"optimism", "optimism",
......
...@@ -195,6 +195,9 @@ export abstract class BatchSubmitter { ...@@ -195,6 +195,9 @@ export abstract class BatchSubmitter {
beforeSendTransaction: (tx: PopulatedTransaction) => { beforeSendTransaction: (tx: PopulatedTransaction) => {
this.logger.info(`Submitting ${txName} transaction`, { this.logger.info(`Submitting ${txName} transaction`, {
gasPrice: tx.gasPrice, gasPrice: tx.gasPrice,
maxFeePerGas: tx.maxFeePerGas,
maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
gasLimit: tx.gasLimit,
nonce: tx.nonce, nonce: tx.nonce,
contractAddr: this.chainContract.address, contractAddr: this.chainContract.address,
}) })
......
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/master/graph/badge.svg?token=0VTG7PG7YR)](https://codecov.io/gh/ethereum-optimism/optimism) [![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/master/graph/badge.svg?token=0VTG7PG7YR&flag=contracts)](https://codecov.io/gh/ethereum-optimism/optimism)
# Optimistic Ethereum Smart Contracts # Optimistic Ethereum Smart Contracts
......
...@@ -10,6 +10,7 @@ import { ...@@ -10,6 +10,7 @@ import {
// Hardhat plugins // Hardhat plugins
import '@nomiclabs/hardhat-ethers' import '@nomiclabs/hardhat-ethers'
import '@nomiclabs/hardhat-waffle' import '@nomiclabs/hardhat-waffle'
import '@nomiclabs/hardhat-etherscan'
import 'hardhat-deploy' import 'hardhat-deploy'
import '@typechain/hardhat' import '@typechain/hardhat'
import '@eth-optimism/hardhat-ovm' import '@eth-optimism/hardhat-ovm'
...@@ -24,6 +25,8 @@ import 'hardhat-gas-reporter' ...@@ -24,6 +25,8 @@ import 'hardhat-gas-reporter'
dotenv.config() dotenv.config()
const enableGasReport = !!process.env.ENABLE_GAS_REPORT const enableGasReport = !!process.env.ENABLE_GAS_REPORT
const privateKey = process.env.PRIVATE_KEY ||
"0x0000000000000000000000000000000000000000000000000000000000000000"; // this is to avoid hardhat error
const config: HardhatUserConfig = { const config: HardhatUserConfig = {
networks: { networks: {
...@@ -41,6 +44,20 @@ const config: HardhatUserConfig = { ...@@ -41,6 +44,20 @@ const config: HardhatUserConfig = {
ovm: true, ovm: true,
saveDeployments: false, saveDeployments: false,
}, },
'optimism-kovan': {
chainId: 69,
url: 'https://kovan.optimism.io',
accounts: [privateKey],
gasPrice: 15000000,
ovm: true,
},
'optimism-mainnet': {
chainId: 10,
url: 'https://mainnet.optimism.io',
accounts: [privateKey],
gasPrice: 15000000,
ovm: true,
},
}, },
mocha: { mocha: {
timeout: 50000, timeout: 50000,
...@@ -81,6 +98,9 @@ const config: HardhatUserConfig = { ...@@ -81,6 +98,9 @@ const config: HardhatUserConfig = {
gasPrice: 100, gasPrice: 100,
outputFile: process.env.CI ? 'gas-report.txt' : undefined, outputFile: process.env.CI ? 'gas-report.txt' : undefined,
}, },
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY,
},
} }
if ( if (
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
"@ethersproject/abstract-signer": "^5.4.1", "@ethersproject/abstract-signer": "^5.4.1",
"@ethersproject/contracts": "^5.4.1", "@ethersproject/contracts": "^5.4.1",
"@ethersproject/hardware-wallets": "^5.4.0", "@ethersproject/hardware-wallets": "^5.4.0",
"@nomiclabs/hardhat-etherscan": "^2.1.5",
"glob": "^7.1.6" "glob": "^7.1.6"
}, },
"devDependencies": { "devDependencies": {
......
node_modules/ node_modules/
build/ build/
\ No newline at end of file
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/master/graph/badge.svg?token=0VTG7PG7YR&flag=core-utils)](https://codecov.io/gh/ethereum-optimism/optimism)
# @eth-optimism/core-utils # @eth-optimism/core-utils
## What is this? ## What is this?
......
...@@ -17,7 +17,8 @@ ...@@ -17,7 +17,8 @@
"lint:check": "eslint .", "lint:check": "eslint .",
"lint:fix": "yarn lint:check --fix", "lint:fix": "yarn lint:check --fix",
"pre-commit": "lint-staged", "pre-commit": "lint-staged",
"test": "ts-mocha test/**/*.spec.ts" "test": "ts-mocha test/**/*.spec.ts",
"test:coverage": "nyc ts-mocha test/**/*.spec.ts && nyc merge .nyc_output coverage.json"
}, },
"devDependencies": { "devDependencies": {
"@types/chai": "^4.2.17", "@types/chai": "^4.2.17",
...@@ -26,20 +27,21 @@ ...@@ -26,20 +27,21 @@
"@types/prettier": "^2.2.3", "@types/prettier": "^2.2.3",
"@typescript-eslint/eslint-plugin": "^4.26.0", "@typescript-eslint/eslint-plugin": "^4.26.0",
"@typescript-eslint/parser": "^4.26.0", "@typescript-eslint/parser": "^4.26.0",
"chai": "^4.3.0",
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"chai": "^4.3.0",
"eslint": "^7.27.0", "eslint": "^7.27.0",
"eslint-plugin-prettier": "^3.4.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-ban": "^1.5.2", "eslint-plugin-ban": "^1.5.2",
"eslint-plugin-import": "^2.23.4", "eslint-plugin-import": "^2.23.4",
"eslint-plugin-jsdoc": "^35.1.2", "eslint-plugin-jsdoc": "^35.1.2",
"eslint-plugin-prefer-arrow": "^1.2.3", "eslint-plugin-prefer-arrow": "^1.2.3",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-react": "^7.24.0", "eslint-plugin-react": "^7.24.0",
"eslint-plugin-unicorn": "^32.0.1", "eslint-plugin-unicorn": "^32.0.1",
"lint-staged": "11.0.0",
"mocha": "^8.3.0", "mocha": "^8.3.0",
"nyc": "^15.1.0",
"prettier": "^2.2.1", "prettier": "^2.2.1",
"lint-staged": "11.0.0",
"ts-mocha": "^8.0.0", "ts-mocha": "^8.0.0",
"typescript": "^4.2.3" "typescript": "^4.2.3"
}, },
......
...@@ -8,7 +8,7 @@ import { remove0x } from './common' ...@@ -8,7 +8,7 @@ import { remove0x } from './common'
const feeScalar = 10_000_000 const feeScalar = 10_000_000
const txDataZeroGas = 4 const txDataZeroGas = 4
const txDataNonZeroGasEIP2028 = 16 const txDataNonZeroGasEIP2028 = 16
const overhead = 4200 + 200 * txDataNonZeroGasEIP2028 const overhead = 2750
const tenThousand = BigNumber.from(10_000) const tenThousand = BigNumber.from(10_000)
export const TxGasPrice = BigNumber.from(feeScalar + feeScalar / 2) export const TxGasPrice = BigNumber.from(feeScalar + feeScalar / 2)
export interface EncodableL2GasLimit { export interface EncodableL2GasLimit {
......
...@@ -50,5 +50,28 @@ describe('BatchEncoder', () => { ...@@ -50,5 +50,28 @@ describe('BatchEncoder', () => {
expect(encoded).to.equal(calldata) expect(encoded).to.equal(calldata)
} }
}) })
it('should throw an error', () => {
const batch = {
shouldStartAtElement: 10,
totalElementsToAppend: 1,
contexts: [
{
numSequencedTransactions: 2,
numSubsequentQueueTransactions: 1,
timestamp: 100,
blockNumber: 200,
},
],
transactions: ['0x454234000000112', '0x45423400000012'],
}
expect(() => encodeAppendSequencerBatch(batch)).to.throw(
'Unexpected uneven hex string value!'
)
expect(() => sequencerBatch.decode('0x')).to.throw(
'Incorrect function signature'
)
})
}) })
}) })
...@@ -2,7 +2,105 @@ import { expect } from '../setup' ...@@ -2,7 +2,105 @@ import { expect } from '../setup'
import { BigNumber } from 'ethers' import { BigNumber } from 'ethers'
/* Imports: Internal */ /* Imports: Internal */
import { toRpcHexString } from '../../src' import {
toRpcHexString,
remove0x,
add0x,
fromHexString,
toHexString,
padHexString,
} from '../../src'
describe('remove0x', () => {
it('should return undefined', () => {
expect(remove0x(undefined)).to.deep.equal(undefined)
})
it('should return without a 0x', () => {
const cases = [
{ input: '0x', output: '' },
{
input: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
output: '1f9840a85d5af5bf1d1762f925bdaddc4201f984',
},
{ input: 'a', output: 'a' },
]
for (const test of cases) {
expect(remove0x(test.input)).to.deep.equal(test.output)
}
})
})
describe('add0x', () => {
it('should return undefined', () => {
expect(add0x(undefined)).to.deep.equal(undefined)
})
it('should return with a 0x', () => {
const cases = [
{ input: '0x', output: '0x' },
{
input: '1f9840a85d5af5bf1d1762f925bdaddc4201f984',
output: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
},
{ input: '', output: '0x' },
]
for (const test of cases) {
expect(add0x(test.input)).to.deep.equal(test.output)
}
})
})
describe('toHexString', () => {
it('should return undefined', () => {
expect(add0x(undefined)).to.deep.equal(undefined)
})
it('should return with a hex string', () => {
const cases = [
{ input: 0, output: '0x00' },
{
input: '0',
output: '0x30',
},
{ input: '', output: '0x' },
]
for (const test of cases) {
expect(toHexString(test.input)).to.deep.equal(test.output)
}
})
})
describe('fromHexString', () => {
it('should return a buffer from a hex string', () => {
const cases = [
{ input: '0x', output: Buffer.from('', 'hex') },
{
input: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
output: Buffer.from('1f9840a85d5af5bf1d1762f925bdaddc4201f984', 'hex'),
},
{ input: '', output: Buffer.from('', 'hex') },
{
input: Buffer.from('1f9840a85d5af5bf1d1762f925bdaddc4201f984'),
output: Buffer.from('1f9840a85d5af5bf1d1762f925bdaddc4201f984'),
},
]
for (const test of cases) {
expect(fromHexString(test.input)).to.deep.equal(test.output)
}
})
})
describe('padHexString', () => {
it('should return return input string if length is 2 + length * 2', () => {
expect(padHexString('abcd', 1)).to.deep.equal('abcd')
expect(padHexString('abcdefgh', 3).length).to.deep.equal(8)
})
it('should return a string padded with 0x and zeros', () => {
expect(padHexString('0xabcd', 3)).to.deep.equal('0x00abcd')
})
})
describe('toRpcHexString', () => { describe('toRpcHexString', () => {
it('should parse 0', () => { it('should parse 0', () => {
......
import { expect } from '../setup'
/* Imports: Internal */
import { sleep } from '../../src'
describe('sleep', async () => {
it('should return wait input amount of ms', async () => {
const startTime = Date.now()
await sleep(1000)
const endTime = Date.now()
expect(startTime + 1000 <= endTime).to.deep.equal(true)
})
})
import { expect } from '../setup' import { expect } from '../setup'
import * as fees from '../../src/fees' import * as fees from '../../src/fees'
import { utils } from 'ethers' import { BigNumber, utils } from 'ethers'
const hundredBillion = 10 ** 11 const hundredBillion = 10 ** 11
const tenThousand = 10 ** 4
describe('Fees', () => { describe('Fees', () => {
it('should count zeros and ones', () => { it('should count zeros and ones', () => {
...@@ -116,5 +117,12 @@ describe('Fees', () => { ...@@ -116,5 +117,12 @@ describe('Fees', () => {
expect(decoded).to.deep.eq(roundedL2GasLimit) expect(decoded).to.deep.eq(roundedL2GasLimit)
}) })
} }
it('should decode numbers', () => {
const x = 1
expect(fees.TxGasLimit.decode(x)).to.deep.equal(
BigNumber.from(x * tenThousand)
)
})
}) })
}) })
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/master/graph/badge.svg?token=0VTG7PG7YR&flag=data-transport-layer)](https://codecov.io/gh/ethereum-optimism/optimism)
# @eth-optimism/data-transport-layer # @eth-optimism/data-transport-layer
## What is this? ## What is this?
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
"start": "ts-node ./src/services/run.ts", "start": "ts-node ./src/services/run.ts",
"start:local": "ts-node ./src/services/run.ts | pino-pretty", "start:local": "ts-node ./src/services/run.ts | pino-pretty",
"test": "hardhat --config test/config/hardhat.config.ts test", "test": "hardhat --config test/config/hardhat.config.ts test",
"test:coverage": "nyc hardhat --config test/config/hardhat.config.ts test && nyc merge .nyc_output coverage.json",
"build": "tsc -p tsconfig.build.json", "build": "tsc -p tsconfig.build.json",
"pre-commit": "lint-staged" "pre-commit": "lint-staged"
}, },
......
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/master/graph/badge.svg?token=0VTG7PG7YR&flag=message-relayer)](https://codecov.io/gh/ethereum-optimism/optimism)
# @eth-optimism/message-relayer # @eth-optimism/message-relayer
This package contains: This package contains:
...@@ -63,7 +64,7 @@ const main = async () => { ...@@ -63,7 +64,7 @@ const main = async () => {
// proof // proof
// ) // )
// } // }
} }
main() main()
``` ```
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
"pre-commit": "lint-staged", "pre-commit": "lint-staged",
"lint:fix": "yarn lint:check --fix", "lint:fix": "yarn lint:check --fix",
"lint:check": "eslint .", "lint:check": "eslint .",
"test": "hardhat test --show-stack-traces" "test": "hardhat test --show-stack-traces",
"test:coverage": "nyc hardhat test && nyc merge .nyc_output coverage.json"
}, },
"keywords": [ "keywords": [
"optimism", "optimism",
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment