Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
c1e923f9
Commit
c1e923f9
authored
Jan 17, 2022
by
Matthew Slipper
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
integration-tests: Changes to make it work with live networks again
parent
a9da94ef
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
520 additions
and
475 deletions
+520
-475
early-hairs-smash.md
.changeset/early-hairs-smash.md
+5
-0
config.yml
.circleci/config.yml
+38
-0
.env.example
integration-tests/.env.example
+11
-0
hardhat.config.ts
integration-tests/hardhat.config.ts
+3
-2
package.json
integration-tests/package.json
+0
-3
basic-l1-l2-communication.spec.ts
integration-tests/test/basic-l1-l2-communication.spec.ts
+75
-37
bridged-tokens.spec.ts
integration-tests/test/bridged-tokens.spec.ts
+40
-44
fee-payment.spec.ts
integration-tests/test/fee-payment.spec.ts
+40
-43
native-eth-ovm-calls.spec.ts
integration-tests/test/native-eth-ovm-calls.spec.ts
+3
-3
native-eth.spec.ts
integration-tests/test/native-eth.spec.ts
+71
-81
ovmcontext.spec.ts
integration-tests/test/ovmcontext.spec.ts
+12
-8
queue-ingestion.spec.ts
integration-tests/test/queue-ingestion.spec.ts
+7
-4
replica.spec.ts
integration-tests/test/replica.spec.ts
+10
-10
rpc.spec.ts
integration-tests/test/rpc.spec.ts
+51
-47
setup-docker-compose-network.ts
integration-tests/test/setup-docker-compose-network.ts
+0
-7
docker-compose.ts
integration-tests/test/shared/docker-compose.ts
+0
-62
env.ts
integration-tests/test/shared/env.ts
+11
-3
stress-test-helpers.ts
integration-tests/test/shared/stress-test-helpers.ts
+4
-4
utils.ts
integration-tests/test/shared/utils.ts
+131
-95
stress-tests.spec.ts
integration-tests/test/stress-tests.spec.ts
+6
-5
yarn.lock
yarn.lock
+2
-17
No files found.
.changeset/early-hairs-smash.md
0 → 100644
View file @
c1e923f9
---
'
@eth-optimism/integration-tests'
:
minor
---
Updates to work with a live network
.circleci/config.yml
View file @
c1e923f9
...
@@ -141,6 +141,32 @@ jobs:
...
@@ -141,6 +141,32 @@ jobs:
kubectl rollout restart statefulset nightly-dtl --namespace nightly
kubectl rollout restart statefulset nightly-dtl --namespace nightly
kubectl rollout restart deployment nightly-gas-oracle --namespace nightly
kubectl rollout restart deployment nightly-gas-oracle --namespace nightly
kubectl rollout restart deployment edge-proxyd --namespace nightly
kubectl rollout restart deployment edge-proxyd --namespace nightly
run-itests-nightly
:
docker
:
-
image
:
cimg/base:2021.04
steps
:
-
setup_remote_docker
:
version
:
19.03.13
-
run
:
name
:
Run integration tests
command
:
|
docker run \
--env PRIVATE_KEY=$NIGHTLY_ITESTS_PRIVKEY \
--env L1_URL=https://nightly-l1.optimism-stacks.net \
--env L2_URL=https://nightly-l2.optimism-stacks.net \
--env ADDRESS_MANAGER=0x22D4E211ef8704f2ca2d6dfdB32125E2530ACE3e \
--env L2_CHAINID=69 \
--env MOCHA_BAIL=true \
--env MOCHA_TIMEOUT=300000 \
--env L1_GAS_PRICE=onchain \
--env L2_GAS_PRICE=onchain \
--env RUN_DEBUG_TRACE_TESTS=false \
--env RUN_REPLICA_TESTS=false \
--env RUN_STRESS_TESTS=false \
--env OVMCONTEXT_SPEC_NUM_TXS=1 \
--env DTL_ENQUEUE_CONFIRMATIONS=12 \
"$STACKMAN_REPO/integration-tests:nightly" \
yarn test:integration:live
notify
:
notify
:
docker
:
docker
:
-
image
:
cimg/base:2021.04
-
image
:
cimg/base:2021.04
...
@@ -152,6 +178,18 @@ jobs:
...
@@ -152,6 +178,18 @@ jobs:
workflows
:
workflows
:
nightly-itests
:
triggers
:
-
schedule
:
cron
:
"
0
1
*
*
*
"
filters
:
branches
:
only
:
-
develop
jobs
:
-
run-itests-nightly
:
context
:
-
optimism
nightly
:
nightly
:
triggers
:
triggers
:
-
schedule
:
-
schedule
:
...
...
integration-tests/.env.example
View file @
c1e923f9
...
@@ -4,3 +4,14 @@ L1_URL=
...
@@ -4,3 +4,14 @@ L1_URL=
L2_URL=
L2_URL=
ADDRESS_MANAGER=
ADDRESS_MANAGER=
L2_CHAINID=
L2_CHAINID=
DTL_ENQUEUE_CONFIRMATIONS=
OVMCONTEXT_SPEC_NUM_TXS=1
# Can be set to true below if the withdrawal window is short enough
RUN_WITHDRAWAL_TESTS=false
RUN_DEBUG_TRACE_TESTS=false
RUN_REPLICA_TESTS=false
RUN_STRESS_TESTS=false
# Can be configured up or down as necessary
MOCHA_TIMEOUT=300000
# Set to true to make Mocha stop after the first failed test.
MOCHA_BAIL=false
\ No newline at end of file
integration-tests/hardhat.config.ts
View file @
c1e923f9
...
@@ -4,7 +4,7 @@ import { HardhatUserConfig } from 'hardhat/types'
...
@@ -4,7 +4,7 @@ import { HardhatUserConfig } from 'hardhat/types'
import
'
@nomiclabs/hardhat-ethers
'
import
'
@nomiclabs/hardhat-ethers
'
import
'
@nomiclabs/hardhat-waffle
'
import
'
@nomiclabs/hardhat-waffle
'
import
'
hardhat-gas-reporter
'
import
'
hardhat-gas-reporter
'
import
{
isLiveNetwork
}
from
'
./test/shared/utils
'
import
{
envConfig
}
from
'
./test/shared/utils
'
const
enableGasReport
=
!!
process
.
env
.
ENABLE_GAS_REPORT
const
enableGasReport
=
!!
process
.
env
.
ENABLE_GAS_REPORT
...
@@ -15,7 +15,8 @@ const config: HardhatUserConfig = {
...
@@ -15,7 +15,8 @@ const config: HardhatUserConfig = {
},
},
},
},
mocha
:
{
mocha
:
{
timeout
:
isLiveNetwork
()
?
300
_000
:
75
_000
,
timeout
:
envConfig
.
MOCHA_TIMEOUT
,
bail
:
envConfig
.
MOCHA_BAIL
,
},
},
solidity
:
{
solidity
:
{
compilers
:
[
compilers
:
[
...
...
integration-tests/package.json
View file @
c1e923f9
...
@@ -41,7 +41,6 @@
...
@@ -41,7 +41,6 @@
"@types/chai-as-promised"
:
"^7.1.4"
,
"@types/chai-as-promised"
:
"^7.1.4"
,
"@types/mocha"
:
"^8.2.2"
,
"@types/mocha"
:
"^8.2.2"
,
"@types/rimraf"
:
"^3.0.0"
,
"@types/rimraf"
:
"^3.0.0"
,
"@types/shelljs"
:
"^0.8.8"
,
"@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"
,
"@uniswap/v3-core"
:
"1.0.0"
,
"@uniswap/v3-core"
:
"1.0.0"
,
...
@@ -52,7 +51,6 @@
...
@@ -52,7 +51,6 @@
"chai"
:
"^4.3.4"
,
"chai"
:
"^4.3.4"
,
"chai-as-promised"
:
"^7.1.1"
,
"chai-as-promised"
:
"^7.1.1"
,
"commander"
:
"^8.3.0"
,
"commander"
:
"^8.3.0"
,
"docker-compose"
:
"^0.23.8"
,
"dotenv"
:
"^10.0.0"
,
"dotenv"
:
"^10.0.0"
,
"envalid"
:
"^7.1.0"
,
"envalid"
:
"^7.1.0"
,
"eslint"
:
"^7.27.0"
,
"eslint"
:
"^7.27.0"
,
...
@@ -71,7 +69,6 @@
...
@@ -71,7 +69,6 @@
"mocha"
:
"^8.4.0"
,
"mocha"
:
"^8.4.0"
,
"prom-client"
:
"^14.0.1"
,
"prom-client"
:
"^14.0.1"
,
"rimraf"
:
"^3.0.2"
,
"rimraf"
:
"^3.0.2"
,
"shelljs"
:
"^0.8.4"
,
"typescript"
:
"^4.3.5"
,
"typescript"
:
"^4.3.5"
,
"uniswap-v3-deploy-plugin"
:
"^0.1.0"
"uniswap-v3-deploy-plugin"
:
"^0.1.0"
}
}
...
...
integration-tests/test/basic-l1-l2-communication.spec.ts
View file @
c1e923f9
...
@@ -8,7 +8,13 @@ import { applyL1ToL2Alias, awaitCondition } from '@eth-optimism/core-utils'
...
@@ -8,7 +8,13 @@ import { applyL1ToL2Alias, awaitCondition } from '@eth-optimism/core-utils'
/* Imports: Internal */
/* Imports: Internal */
import
{
Direction
}
from
'
./shared/watcher-utils
'
import
{
Direction
}
from
'
./shared/watcher-utils
'
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
isMainnet
}
from
'
./shared/utils
'
import
{
DEFAULT_TEST_GAS_L1
,
DEFAULT_TEST_GAS_L2
,
envConfig
,
sleep
,
withdrawalTest
,
}
from
'
./shared/utils
'
describe
(
'
Basic L1<>L2 Communication
'
,
async
()
=>
{
describe
(
'
Basic L1<>L2 Communication
'
,
async
()
=>
{
let
Factory__L1SimpleStorage
:
ContractFactory
let
Factory__L1SimpleStorage
:
ContractFactory
...
@@ -37,42 +43,42 @@ describe('Basic L1<>L2 Communication', async () => {
...
@@ -37,42 +43,42 @@ describe('Basic L1<>L2 Communication', async () => {
beforeEach
(
async
()
=>
{
beforeEach
(
async
()
=>
{
L1SimpleStorage
=
await
Factory__L1SimpleStorage
.
deploy
()
L1SimpleStorage
=
await
Factory__L1SimpleStorage
.
deploy
()
await
L1SimpleStorage
.
deploy
Transaction
.
wait
()
await
L1SimpleStorage
.
deploy
ed
()
L2SimpleStorage
=
await
Factory__L2SimpleStorage
.
deploy
()
L2SimpleStorage
=
await
Factory__L2SimpleStorage
.
deploy
()
await
L2SimpleStorage
.
deploy
Transaction
.
wait
()
await
L2SimpleStorage
.
deploy
ed
()
L2Reverter
=
await
Factory__L2Reverter
.
deploy
()
L2Reverter
=
await
Factory__L2Reverter
.
deploy
()
await
L2Reverter
.
deploy
Transaction
.
wait
()
await
L2Reverter
.
deploy
ed
()
})
})
describe
(
'
L2 => L1
'
,
()
=>
{
describe
(
'
L2 => L1
'
,
()
=>
{
it
(
'
should be able to perform a withdrawal from L2 -> L1
'
,
async
function
()
{
withdrawalTest
(
if
(
await
isMainnet
(
env
))
{
'
should be able to perform a withdrawal from L2 -> L1
'
,
console
.
log
(
'
Skipping withdrawals test on mainnet.
'
)
async
()
=>
{
this
.
skip
()
const
value
=
`0x
${
'
77
'
.
repeat
(
32
)}
`
return
}
// Send L2 -> L1 message.
const
transaction
=
await
env
.
l2Messenger
.
sendMessage
(
const
value
=
`0x
${
'
77
'
.
repeat
(
32
)}
`
L1SimpleStorage
.
address
,
L1SimpleStorage
.
interface
.
encodeFunctionData
(
'
setValue
'
,
[
value
]),
// Send L2 -> L1 message.
5000000
,
const
transaction
=
await
env
.
l2Messenger
.
sendMessage
(
{
L1SimpleStorage
.
address
,
gasLimit
:
DEFAULT_TEST_GAS_L2
,
L1SimpleStorage
.
interface
.
encodeFunctionData
(
'
setValue
'
,
[
value
]),
}
5000000
)
)
await
transaction
.
wait
()
await
transaction
.
wait
()
await
env
.
relayXDomainMessages
(
transaction
)
await
env
.
relayXDomainMessages
(
transaction
)
await
env
.
waitForXDomainTransaction
(
transaction
,
Direction
.
L2ToL1
)
await
env
.
waitForXDomainTransaction
(
transaction
,
Direction
.
L2ToL1
)
expect
(
await
L1SimpleStorage
.
msgSender
()).
to
.
equal
(
expect
(
await
L1SimpleStorage
.
msgSender
()).
to
.
equal
(
env
.
l1Messenger
.
address
env
.
l1Messenger
.
address
)
)
expect
(
await
L1SimpleStorage
.
xDomainSender
()).
to
.
equal
(
expect
(
await
L1SimpleStorage
.
xDomainSender
()).
to
.
equal
(
env
.
l2Wallet
.
address
env
.
l2Wallet
.
address
)
)
expect
(
await
L1SimpleStorage
.
value
()).
to
.
equal
(
value
)
expect
(
await
L1SimpleStorage
.
value
()).
to
.
equal
(
value
)
expect
((
await
L1SimpleStorage
.
totalCount
()).
toNumber
()).
to
.
equal
(
1
)
expect
((
await
L1SimpleStorage
.
totalCount
()).
toNumber
()).
to
.
equal
(
1
)
})
}
)
})
})
describe
(
'
L1 => L2
'
,
()
=>
{
describe
(
'
L1 => L2
'
,
()
=>
{
...
@@ -83,7 +89,10 @@ describe('Basic L1<>L2 Communication', async () => {
...
@@ -83,7 +89,10 @@ describe('Basic L1<>L2 Communication', async () => {
const
transaction
=
await
env
.
l1Messenger
.
sendMessage
(
const
transaction
=
await
env
.
l1Messenger
.
sendMessage
(
L2SimpleStorage
.
address
,
L2SimpleStorage
.
address
,
L2SimpleStorage
.
interface
.
encodeFunctionData
(
'
setValue
'
,
[
value
]),
L2SimpleStorage
.
interface
.
encodeFunctionData
(
'
setValue
'
,
[
value
]),
5000000
5000000
,
{
gasLimit
:
DEFAULT_TEST_GAS_L1
,
}
)
)
await
env
.
waitForXDomainTransaction
(
transaction
,
Direction
.
L1ToL2
)
await
env
.
waitForXDomainTransaction
(
transaction
,
Direction
.
L1ToL2
)
...
@@ -101,19 +110,41 @@ describe('Basic L1<>L2 Communication', async () => {
...
@@ -101,19 +110,41 @@ describe('Basic L1<>L2 Communication', async () => {
expect
((
await
L2SimpleStorage
.
totalCount
()).
toNumber
()).
to
.
equal
(
1
)
expect
((
await
L2SimpleStorage
.
totalCount
()).
toNumber
()).
to
.
equal
(
1
)
})
})
it
(
'
should deposit from L1 -> L2 directly via enqueue
'
,
async
()
=>
{
it
(
'
should deposit from L1 -> L2 directly via enqueue
'
,
async
function
()
{
this
.
timeout
(
envConfig
.
MOCHA_TIMEOUT
*
2
+
envConfig
.
DTL_ENQUEUE_CONFIRMATIONS
*
15000
)
const
value
=
`0x
${
'
42
'
.
repeat
(
32
)}
`
const
value
=
`0x
${
'
42
'
.
repeat
(
32
)}
`
// Send L1 -> L2 message.
// Send L1 -> L2 message.
await
env
.
ctc
const
tx
=
await
env
.
ctc
.
connect
(
env
.
l1Wallet
)
.
connect
(
env
.
l1Wallet
)
.
enqueue
(
.
enqueue
(
L2SimpleStorage
.
address
,
L2SimpleStorage
.
address
,
5000000
,
5000000
,
L2SimpleStorage
.
interface
.
encodeFunctionData
(
'
setValueNotXDomain
'
,
[
L2SimpleStorage
.
interface
.
encodeFunctionData
(
'
setValueNotXDomain
'
,
[
value
,
value
,
])
]),
{
gasLimit
:
DEFAULT_TEST_GAS_L1
,
}
)
const
receipt
=
await
tx
.
wait
()
const
waitUntilBlock
=
receipt
.
blockNumber
+
envConfig
.
DTL_ENQUEUE_CONFIRMATIONS
let
currBlock
=
await
env
.
l1Provider
.
getBlockNumber
()
while
(
currBlock
<=
waitUntilBlock
)
{
const
progress
=
envConfig
.
DTL_ENQUEUE_CONFIRMATIONS
-
(
waitUntilBlock
-
currBlock
)
console
.
log
(
`Waiting for
${
progress
}
/
${
envConfig
.
DTL_ENQUEUE_CONFIRMATIONS
}
confirmations.`
)
)
await
sleep
(
5000
)
currBlock
=
await
env
.
l1Provider
.
getBlockNumber
()
}
console
.
log
(
'
Enqueue should be confirmed.
'
)
await
awaitCondition
(
await
awaitCondition
(
async
()
=>
{
async
()
=>
{
...
@@ -138,8 +169,12 @@ describe('Basic L1<>L2 Communication', async () => {
...
@@ -138,8 +169,12 @@ describe('Basic L1<>L2 Communication', async () => {
const
transaction
=
await
env
.
l1Messenger
.
sendMessage
(
const
transaction
=
await
env
.
l1Messenger
.
sendMessage
(
L2SimpleStorage
.
address
,
L2SimpleStorage
.
address
,
L2SimpleStorage
.
interface
.
encodeFunctionData
(
'
setValue
'
,
[
value
]),
L2SimpleStorage
.
interface
.
encodeFunctionData
(
'
setValue
'
,
[
value
]),
5000000
5000000
,
{
gasLimit
:
DEFAULT_TEST_GAS_L1
,
}
)
)
await
transaction
.
wait
()
const
{
remoteReceipt
}
=
await
env
.
waitForXDomainTransaction
(
const
{
remoteReceipt
}
=
await
env
.
waitForXDomainTransaction
(
transaction
,
transaction
,
...
@@ -155,7 +190,10 @@ describe('Basic L1<>L2 Communication', async () => {
...
@@ -155,7 +190,10 @@ describe('Basic L1<>L2 Communication', async () => {
const
transaction
=
await
env
.
l1Messenger
.
sendMessage
(
const
transaction
=
await
env
.
l1Messenger
.
sendMessage
(
L2Reverter
.
address
,
L2Reverter
.
address
,
L2Reverter
.
interface
.
encodeFunctionData
(
'
doRevert
'
,
[]),
L2Reverter
.
interface
.
encodeFunctionData
(
'
doRevert
'
,
[]),
5000000
5000000
,
{
gasLimit
:
DEFAULT_TEST_GAS_L1
,
}
)
)
const
{
remoteReceipt
}
=
await
env
.
waitForXDomainTransaction
(
const
{
remoteReceipt
}
=
await
env
.
waitForXDomainTransaction
(
...
...
integration-tests/test/bridged-tokens.spec.ts
View file @
c1e923f9
...
@@ -5,7 +5,7 @@ import { ethers } from 'hardhat'
...
@@ -5,7 +5,7 @@ import { ethers } from 'hardhat'
import
*
as
L2Artifact
from
'
@eth-optimism/contracts/artifacts/contracts/standards/L2StandardERC20.sol/L2StandardERC20.json
'
import
*
as
L2Artifact
from
'
@eth-optimism/contracts/artifacts/contracts/standards/L2StandardERC20.sol/L2StandardERC20.json
'
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
isLiveNetwork
,
isMainne
t
}
from
'
./shared/utils
'
import
{
withdrawalTes
t
}
from
'
./shared/utils
'
import
{
Direction
}
from
'
./shared/watcher-utils
'
import
{
Direction
}
from
'
./shared/watcher-utils
'
describe
(
'
Bridged tokens
'
,
()
=>
{
describe
(
'
Bridged tokens
'
,
()
=>
{
...
@@ -25,14 +25,16 @@ describe('Bridged tokens', () => {
...
@@ -25,14 +25,16 @@ describe('Bridged tokens', () => {
const
other
=
Wallet
.
createRandom
()
const
other
=
Wallet
.
createRandom
()
otherWalletL1
=
other
.
connect
(
env
.
l1Wallet
.
provider
)
otherWalletL1
=
other
.
connect
(
env
.
l1Wallet
.
provider
)
otherWalletL2
=
other
.
connect
(
env
.
l2Wallet
.
provider
)
otherWalletL2
=
other
.
connect
(
env
.
l2Wallet
.
provider
)
await
env
.
l1Wallet
.
sendTransaction
({
let
tx
=
await
env
.
l1Wallet
.
sendTransaction
({
to
:
otherWalletL1
.
address
,
to
:
otherWalletL1
.
address
,
value
:
utils
.
parseEther
(
'
0.01
'
),
value
:
utils
.
parseEther
(
'
0.01
'
),
})
})
await
env
.
l2Wallet
.
sendTransaction
({
await
tx
.
wait
()
tx
=
await
env
.
l2Wallet
.
sendTransaction
({
to
:
otherWalletL2
.
address
,
to
:
otherWalletL2
.
address
,
value
:
utils
.
parseEther
(
'
0.01
'
),
value
:
utils
.
parseEther
(
'
0.01
'
),
})
})
await
tx
.
wait
()
L1Factory__ERC20
=
await
ethers
.
getContractFactory
(
'
ERC20
'
,
env
.
l1Wallet
)
L1Factory__ERC20
=
await
ethers
.
getContractFactory
(
'
ERC20
'
,
env
.
l1Wallet
)
L2Factory__ERC20
=
new
ethers
.
ContractFactory
(
L2Factory__ERC20
=
new
ethers
.
ContractFactory
(
...
@@ -77,7 +79,7 @@ describe('Bridged tokens', () => {
...
@@ -77,7 +79,7 @@ describe('Bridged tokens', () => {
expect
(
await
L2__ERC20
.
balanceOf
(
env
.
l2Wallet
.
address
)).
to
.
deep
.
equal
(
expect
(
await
L2__ERC20
.
balanceOf
(
env
.
l2Wallet
.
address
)).
to
.
deep
.
equal
(
BigNumber
.
from
(
1000
)
BigNumber
.
from
(
1000
)
)
)
})
.
timeout
(
isLiveNetwork
()
?
300
_000
:
120
_000
)
})
it
(
'
should transfer tokens on L2
'
,
async
()
=>
{
it
(
'
should transfer tokens on L2
'
,
async
()
=>
{
const
tx
=
await
L2__ERC20
.
transfer
(
otherWalletL1
.
address
,
500
)
const
tx
=
await
L2__ERC20
.
transfer
(
otherWalletL1
.
address
,
500
)
...
@@ -90,46 +92,40 @@ describe('Bridged tokens', () => {
...
@@ -90,46 +92,40 @@ describe('Bridged tokens', () => {
)
)
})
})
it
(
'
should withdraw tokens from L2 to the depositor
'
,
async
function
()
{
withdrawalTest
(
if
(
await
isMainnet
(
env
))
{
'
should withdraw tokens from L2 to the depositor
'
,
console
.
log
(
'
Skipping withdrawals test on mainnet.
'
)
async
()
=>
{
this
.
skip
()
const
tx
=
await
env
.
l2Bridge
.
withdraw
(
return
L2__ERC20
.
address
,
500
,
2000000
,
'
0x
'
)
await
env
.
relayXDomainMessages
(
tx
)
await
env
.
waitForXDomainTransaction
(
tx
,
Direction
.
L2ToL1
)
expect
(
await
L1__ERC20
.
balanceOf
(
env
.
l1Wallet
.
address
)).
to
.
deep
.
equal
(
BigNumber
.
from
(
999500
)
)
expect
(
await
L2__ERC20
.
balanceOf
(
env
.
l2Wallet
.
address
)).
to
.
deep
.
equal
(
BigNumber
.
from
(
0
)
)
}
}
)
const
tx
=
await
env
.
l2Bridge
.
withdraw
(
L2__ERC20
.
address
,
withdrawalTest
(
500
,
'
should withdraw tokens from L2 to the transfer recipient
'
,
2000000
,
async
()
=>
{
'
0x
'
const
tx
=
await
env
.
l2Bridge
)
.
connect
(
otherWalletL2
)
await
env
.
relayXDomainMessages
(
tx
)
.
withdraw
(
L2__ERC20
.
address
,
500
,
2000000
,
'
0x
'
)
await
env
.
waitForXDomainTransaction
(
tx
,
Direction
.
L2ToL1
)
await
env
.
relayXDomainMessages
(
tx
)
expect
(
await
L1__ERC20
.
balanceOf
(
env
.
l1Wallet
.
address
)).
to
.
deep
.
equal
(
await
env
.
waitForXDomainTransaction
(
tx
,
Direction
.
L2ToL1
)
BigNumber
.
from
(
999500
)
expect
(
await
L1__ERC20
.
balanceOf
(
otherWalletL1
.
address
)).
to
.
deep
.
equal
(
)
BigNumber
.
from
(
500
)
expect
(
await
L2__ERC20
.
balanceOf
(
env
.
l2Wallet
.
address
)).
to
.
deep
.
equal
(
)
BigNumber
.
from
(
0
)
expect
(
await
L2__ERC20
.
balanceOf
(
otherWalletL2
.
address
)).
to
.
deep
.
equal
(
)
BigNumber
.
from
(
0
)
}).
timeout
(
isLiveNetwork
()
?
300
_000
:
120
_000
)
)
it
(
'
should withdraw tokens from L2 to the transfer recipient
'
,
async
function
()
{
if
(
await
isMainnet
(
env
))
{
console
.
log
(
'
Skipping withdrawals test on mainnet.
'
)
this
.
skip
()
return
}
}
)
const
tx
=
await
env
.
l2Bridge
.
connect
(
otherWalletL2
)
.
withdraw
(
L2__ERC20
.
address
,
500
,
2000000
,
'
0x
'
)
await
env
.
relayXDomainMessages
(
tx
)
await
env
.
waitForXDomainTransaction
(
tx
,
Direction
.
L2ToL1
)
expect
(
await
L1__ERC20
.
balanceOf
(
otherWalletL1
.
address
)).
to
.
deep
.
equal
(
BigNumber
.
from
(
500
)
)
expect
(
await
L2__ERC20
.
balanceOf
(
otherWalletL2
.
address
)).
to
.
deep
.
equal
(
BigNumber
.
from
(
0
)
)
}).
timeout
(
isLiveNetwork
()
?
300
_000
:
120
_000
)
})
})
integration-tests/test/fee-payment.spec.ts
View file @
c1e923f9
...
@@ -6,14 +6,11 @@ import { serialize } from '@ethersproject/transactions'
...
@@ -6,14 +6,11 @@ import { serialize } from '@ethersproject/transactions'
import
{
predeploys
,
getContractFactory
}
from
'
@eth-optimism/contracts
'
import
{
predeploys
,
getContractFactory
}
from
'
@eth-optimism/contracts
'
/* Imports: Internal */
/* Imports: Internal */
import
{
isLiveNetwork
}
from
'
./shared/utils
'
import
{
hardhatTest
}
from
'
./shared/utils
'
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
Direction
}
from
'
./shared/watcher-utils
'
import
{
Direction
}
from
'
./shared/watcher-utils
'
const
setPrices
=
async
(
env
:
OptimismEnv
,
value
:
number
|
BigNumber
)
=>
{
const
setPrices
=
async
(
env
:
OptimismEnv
,
value
:
number
|
BigNumber
)
=>
{
if
(
isLiveNetwork
())
{
return
}
const
gasPrice
=
await
env
.
gasPriceOracle
.
setGasPrice
(
value
)
const
gasPrice
=
await
env
.
gasPriceOracle
.
setGasPrice
(
value
)
await
gasPrice
.
wait
()
await
gasPrice
.
wait
()
const
baseFee
=
await
env
.
gasPriceOracle
.
setL1BaseFee
(
value
)
const
baseFee
=
await
env
.
gasPriceOracle
.
setL1BaseFee
(
value
)
...
@@ -28,24 +25,25 @@ describe('Fee Payment Integration Tests', async () => {
...
@@ -28,24 +25,25 @@ describe('Fee Payment Integration Tests', async () => {
env
=
await
OptimismEnv
.
new
()
env
=
await
OptimismEnv
.
new
()
})
})
if
(
!
isLiveNetwork
())
{
hardhatTest
(
it
(
`should return eth_gasPrice equal to OVM_GasPriceOracle.gasPrice`
,
async
()
=>
{
`should return eth_gasPrice equal to OVM_GasPriceOracle.gasPrice`
,
async
()
=>
{
const
assertGasPrice
=
async
()
=>
{
const
assertGasPrice
=
async
()
=>
{
const
gasPrice
=
await
env
.
l2Wallet
.
getGasPrice
()
const
gasPrice
=
await
env
.
l2Wallet
.
getGasPrice
()
const
oracleGasPrice
=
await
env
.
gasPriceOracle
.
gasPrice
()
const
oracleGasPrice
=
await
env
.
gasPriceOracle
.
gasPrice
()
expect
(
gasPrice
).
to
.
deep
.
equal
(
oracleGasPrice
)
expect
(
gasPrice
).
to
.
deep
.
equal
(
oracleGasPrice
)
}
}
assertGasPrice
()
a
wait
a
ssertGasPrice
()
// update the gas price
// update the gas price
const
tx
=
await
env
.
gasPriceOracle
.
setGasPrice
(
1000
)
const
tx
=
await
env
.
gasPriceOracle
.
setGasPrice
(
1000
)
await
tx
.
wait
()
await
tx
.
wait
()
assertGasPrice
()
a
wait
a
ssertGasPrice
()
}
)
}
}
)
i
t
(
'
Paying a nonzero but acceptable gasPrice fee
'
,
async
()
=>
{
hardhatTes
t
(
'
Paying a nonzero but acceptable gasPrice fee
'
,
async
()
=>
{
await
setPrices
(
env
,
1000
)
await
setPrices
(
env
,
1000
)
const
amount
=
utils
.
parseEther
(
'
0.0000001
'
)
const
amount
=
utils
.
parseEther
(
'
0.0000001
'
)
...
@@ -97,7 +95,7 @@ describe('Fee Payment Integration Tests', async () => {
...
@@ -97,7 +95,7 @@ describe('Fee Payment Integration Tests', async () => {
await
setPrices
(
env
,
1
)
await
setPrices
(
env
,
1
)
})
})
i
t
(
'
should compute correct fee
'
,
async
()
=>
{
hardhatTes
t
(
'
should compute correct fee
'
,
async
()
=>
{
await
setPrices
(
env
,
1000
)
await
setPrices
(
env
,
1000
)
const
preBalance
=
await
env
.
l2Wallet
.
getBalance
()
const
preBalance
=
await
env
.
l2Wallet
.
getBalance
()
...
@@ -149,39 +147,38 @@ describe('Fee Payment Integration Tests', async () => {
...
@@ -149,39 +147,38 @@ describe('Fee Payment Integration Tests', async () => {
await
expect
(
env
.
sequencerFeeVault
.
withdraw
()).
to
.
be
.
rejected
await
expect
(
env
.
sequencerFeeVault
.
withdraw
()).
to
.
be
.
rejected
})
})
it
(
'
should be able to withdraw fees back to L1 once the minimum is met
'
,
async
function
()
{
hardhatTest
(
if
(
isLiveNetwork
())
{
'
should be able to withdraw fees back to L1 once the minimum is met
'
,
this
.
skip
()
async
()
=>
{
return
const
l1FeeWallet
=
await
env
.
sequencerFeeVault
.
l1FeeWallet
()
}
const
balanceBefore
=
await
env
.
l1Wallet
.
provider
.
getBalance
(
l1FeeWallet
)
const
withdrawalAmount
=
const
l1FeeWallet
=
await
env
.
sequencerFeeVault
.
l1FeeWallet
()
await
env
.
sequencerFeeVault
.
MIN_WITHDRAWAL_AMOUNT
()
const
balanceBefore
=
await
env
.
l1Wallet
.
provider
.
getBalance
(
l1FeeWallet
)
const
withdrawalAmount
=
await
env
.
sequencerFeeVault
.
MIN_WITHDRAWAL_AMOUNT
()
// Transfer the minimum required to withdraw.
const
tx
=
await
env
.
l2Wallet
.
sendTransaction
({
// Transfer the minimum required to withdraw.
to
:
env
.
sequencerFeeVault
.
address
,
const
tx
=
await
env
.
l2Wallet
.
sendTransaction
({
value
:
withdrawalAmount
,
to
:
env
.
sequencerFeeVault
.
address
,
gasLimit
:
500000
,
value
:
withdrawalAmount
,
})
gasLimit
:
500000
,
await
tx
.
wait
()
})
await
tx
.
wait
()
const
vaultBalance
=
await
env
.
ovmEth
.
balanceOf
(
const
vaultBalance
=
await
env
.
ovmEth
.
balanceOf
(
env
.
sequencerFeeVault
.
address
env
.
sequencerFeeVault
.
address
)
)
const
withdrawTx
=
await
env
.
sequencerFeeVault
.
withdraw
()
const
withdrawTx
=
await
env
.
sequencerFeeVault
.
withdraw
()
// Wait for the withdrawal to be relayed to L1.
// Wait for the withdrawal to be relayed to L1.
await
withdrawTx
.
wait
()
await
withdrawTx
.
wait
()
await
env
.
relayXDomainMessages
(
withdrawTx
)
await
env
.
relayXDomainMessages
(
withdrawTx
)
await
env
.
waitForXDomainTransaction
(
withdrawTx
,
Direction
.
L2ToL1
)
await
env
.
waitForXDomainTransaction
(
withdrawTx
,
Direction
.
L2ToL1
)
// Balance difference should be equal to old L2 balance.
// Balance difference should be equal to old L2 balance.
const
balanceAfter
=
await
env
.
l1Wallet
.
provider
.
getBalance
(
l1FeeWallet
)
const
balanceAfter
=
await
env
.
l1Wallet
.
provider
.
getBalance
(
l1FeeWallet
)
expect
(
balanceAfter
.
sub
(
balanceBefore
)).
to
.
deep
.
equal
(
expect
(
balanceAfter
.
sub
(
balanceBefore
)).
to
.
deep
.
equal
(
BigNumber
.
from
(
vaultBalance
)
BigNumber
.
from
(
vaultBalance
)
)
)
})
}
)
})
})
integration-tests/test/native-eth-ovm-calls.spec.ts
View file @
c1e923f9
...
@@ -45,7 +45,7 @@ describe('Native ETH value integration tests', () => {
...
@@ -45,7 +45,7 @@ describe('Native ETH value integration tests', () => {
const
there
=
await
wallet
.
sendTransaction
({
const
there
=
await
wallet
.
sendTransaction
({
to
:
other
.
address
,
to
:
other
.
address
,
value
,
value
,
gasPrice
:
await
gasPriceForL2
(
env
),
gasPrice
:
await
gasPriceForL2
(),
})
})
const
thereReceipt
=
await
there
.
wait
()
const
thereReceipt
=
await
there
.
wait
()
const
thereGas
=
thereReceipt
.
gasUsed
.
mul
(
there
.
gasPrice
)
const
thereGas
=
thereReceipt
.
gasUsed
.
mul
(
there
.
gasPrice
)
...
@@ -63,7 +63,7 @@ describe('Native ETH value integration tests', () => {
...
@@ -63,7 +63,7 @@ describe('Native ETH value integration tests', () => {
const
backAgain
=
await
other
.
sendTransaction
({
const
backAgain
=
await
other
.
sendTransaction
({
to
:
wallet
.
address
,
to
:
wallet
.
address
,
value
:
backVal
,
value
:
backVal
,
gasPrice
:
await
gasPriceForL2
(
env
),
gasPrice
:
await
gasPriceForL2
(),
})
})
const
backReceipt
=
await
backAgain
.
wait
()
const
backReceipt
=
await
backAgain
.
wait
()
const
backGas
=
backReceipt
.
gasUsed
.
mul
(
backAgain
.
gasPrice
)
const
backGas
=
backReceipt
.
gasUsed
.
mul
(
backAgain
.
gasPrice
)
...
@@ -169,7 +169,7 @@ describe('Native ETH value integration tests', () => {
...
@@ -169,7 +169,7 @@ describe('Native ETH value integration tests', () => {
it
(
'
should allow ETH to be sent
'
,
async
()
=>
{
it
(
'
should allow ETH to be sent
'
,
async
()
=>
{
const
sendAmount
=
15
const
sendAmount
=
15
const
tx
=
await
ValueCalls0
.
simpleSend
(
ValueCalls1
.
address
,
sendAmount
,
{
const
tx
=
await
ValueCalls0
.
simpleSend
(
ValueCalls1
.
address
,
sendAmount
,
{
gasPrice
:
await
gasPriceForL2
(
env
),
gasPrice
:
await
gasPriceForL2
(),
})
})
await
tx
.
wait
()
await
tx
.
wait
()
...
...
integration-tests/test/native-eth.spec.ts
View file @
c1e923f9
...
@@ -9,11 +9,15 @@ import { expectApprox } from '@eth-optimism/core-utils'
...
@@ -9,11 +9,15 @@ import { expectApprox } from '@eth-optimism/core-utils'
/* Imports: Internal */
/* Imports: Internal */
import
{
Direction
}
from
'
./shared/watcher-utils
'
import
{
Direction
}
from
'
./shared/watcher-utils
'
import
{
isMainnet
,
PROXY_SEQUENCER_ENTRYPOINT_ADDRESS
}
from
'
./shared/utils
'
import
{
DEFAULT_TEST_GAS_L1
,
DEFAULT_TEST_GAS_L2
,
envConfig
,
PROXY_SEQUENCER_ENTRYPOINT_ADDRESS
,
withdrawalTest
,
}
from
'
./shared/utils
'
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
OptimismEnv
}
from
'
./shared/env
'
const
DEFAULT_TEST_GAS_L1
=
330
_000
const
DEFAULT_TEST_GAS_L2
=
1
_300_000
// TX size enforced by CTC:
// TX size enforced by CTC:
const
MAX_ROLLUP_TX_SIZE
=
50
_000
const
MAX_ROLLUP_TX_SIZE
=
50
_000
...
@@ -183,13 +187,7 @@ describe('Native ETH Integration Tests', async () => {
...
@@ -183,13 +187,7 @@ describe('Native ETH Integration Tests', async () => {
).
to
.
be
.
reverted
).
to
.
be
.
reverted
})
})
it
(
'
withdraw
'
,
async
function
()
{
withdrawalTest
(
'
withdraw
'
,
async
()
=>
{
if
(
await
isMainnet
(
env
))
{
console
.
log
(
'
Skipping withdrawals test on mainnet.
'
)
this
.
skip
()
return
}
const
withdrawAmount
=
BigNumber
.
from
(
3
)
const
withdrawAmount
=
BigNumber
.
from
(
3
)
const
preBalances
=
await
getBalances
(
env
)
const
preBalances
=
await
getBalances
(
env
)
expect
(
expect
(
...
@@ -231,13 +229,7 @@ describe('Native ETH Integration Tests', async () => {
...
@@ -231,13 +229,7 @@ describe('Native ETH Integration Tests', async () => {
)
)
})
})
it
(
'
withdrawTo
'
,
async
function
()
{
withdrawalTest
(
'
withdrawTo
'
,
async
()
=>
{
if
(
await
isMainnet
(
env
))
{
console
.
log
(
'
Skipping withdrawals test on mainnet.
'
)
this
.
skip
()
return
}
const
withdrawAmount
=
BigNumber
.
from
(
3
)
const
withdrawAmount
=
BigNumber
.
from
(
3
)
const
preBalances
=
await
getBalances
(
env
)
const
preBalances
=
await
getBalances
(
env
)
...
@@ -295,73 +287,71 @@ describe('Native ETH Integration Tests', async () => {
...
@@ -295,73 +287,71 @@ describe('Native ETH Integration Tests', async () => {
)
)
})
})
it
(
'
deposit, transfer, withdraw
'
,
async
function
()
{
withdrawalTest
(
if
(
await
isMainnet
(
env
))
{
'
deposit, transfer, withdraw
'
,
console
.
log
(
'
Skipping withdrawals test on mainnet.
'
)
async
()
=>
{
this
.
skip
()
// 1. deposit
return
const
amount
=
utils
.
parseEther
(
'
1
'
)
}
await
env
.
waitForXDomainTransaction
(
env
.
l1Bridge
.
depositETH
(
DEFAULT_TEST_GAS_L2
,
'
0xFFFF
'
,
{
// 1. deposit
value
:
amount
,
const
amount
=
utils
.
parseEther
(
'
1
'
)
gasLimit
:
DEFAULT_TEST_GAS_L1
,
await
env
.
waitForXDomainTransaction
(
}),
env
.
l1Bridge
.
depositETH
(
DEFAULT_TEST_GAS_L2
,
'
0xFFFF
'
,
{
Direction
.
L1ToL2
value
:
amount
,
gasLimit
:
DEFAULT_TEST_GAS_L1
,
}),
Direction
.
L1ToL2
)
// 2. transfer to another address
const
other
=
Wallet
.
createRandom
().
connect
(
env
.
l2Wallet
.
provider
)
const
tx
=
await
env
.
l2Wallet
.
sendTransaction
({
to
:
other
.
address
,
value
:
amount
,
})
await
tx
.
wait
()
const
l1BalanceBefore
=
await
other
.
connect
(
env
.
l1Wallet
.
provider
)
.
getBalance
()
// 3. do withdrawal
const
withdrawnAmount
=
utils
.
parseEther
(
'
0.95
'
)
const
transaction
=
await
env
.
l2Bridge
.
connect
(
other
)
.
withdraw
(
predeploys
.
OVM_ETH
,
withdrawnAmount
,
DEFAULT_TEST_GAS_L1
,
'
0xFFFF
'
)
)
await
transaction
.
wait
()
await
env
.
relayXDomainMessages
(
transaction
)
const
receipts
=
await
env
.
waitForXDomainTransaction
(
transaction
,
Direction
.
L2ToL1
)
// Compute the L1 portion of the fee
// 2. transfer to another address
const
l1Fee
=
await
env
.
gasPriceOracle
.
getL1Fee
(
const
other
=
Wallet
.
createRandom
().
connect
(
env
.
l2Wallet
.
provider
)
serialize
({
const
tx
=
await
env
.
l2Wallet
.
sendTransaction
({
nonce
:
transaction
.
nonce
,
to
:
other
.
address
,
value
:
transaction
.
value
,
value
:
amount
,
gasPrice
:
transaction
.
gasPrice
,
gasLimit
:
transaction
.
gasLimit
,
to
:
transaction
.
to
,
data
:
transaction
.
data
,
})
})
)
await
tx
.
wait
()
const
l1BalanceBefore
=
await
other
.
connect
(
env
.
l1Wallet
.
provider
)
.
getBalance
()
// 3. do withdrawal
const
withdrawnAmount
=
utils
.
parseEther
(
'
0.95
'
)
const
transaction
=
await
env
.
l2Bridge
.
connect
(
other
)
.
withdraw
(
predeploys
.
OVM_ETH
,
withdrawnAmount
,
DEFAULT_TEST_GAS_L1
,
'
0xFFFF
'
)
await
transaction
.
wait
()
await
env
.
relayXDomainMessages
(
transaction
)
const
receipts
=
await
env
.
waitForXDomainTransaction
(
transaction
,
Direction
.
L2ToL1
)
// check that correct amount was withdrawn and that fee was charged
// Compute the L1 portion of the fee
const
l2Fee
=
receipts
.
tx
.
gasPrice
.
mul
(
receipts
.
receipt
.
gasUsed
)
const
l1Fee
=
await
env
.
gasPriceOracle
.
getL1Fee
(
serialize
({
nonce
:
transaction
.
nonce
,
value
:
transaction
.
value
,
gasPrice
:
transaction
.
gasPrice
,
gasLimit
:
transaction
.
gasLimit
,
to
:
transaction
.
to
,
data
:
transaction
.
data
,
})
)
const
fee
=
l1Fee
.
add
(
l2Fee
)
// check that correct amount was withdrawn and that fee was charged
const
l1BalanceAfter
=
await
other
const
l2Fee
=
receipts
.
tx
.
gasPrice
.
mul
(
receipts
.
receipt
.
gasUsed
)
.
connect
(
env
.
l1Wallet
.
provider
)
.
getBalance
()
const
fee
=
l1Fee
.
add
(
l2Fee
)
const
l2BalanceAfter
=
await
other
.
getBalance
()
const
l1BalanceAfter
=
await
other
expect
(
l1BalanceAfter
).
to
.
deep
.
eq
(
l1BalanceBefore
.
add
(
withdrawnAmount
))
.
connect
(
env
.
l1Wallet
.
provider
)
expect
(
l2BalanceAfter
).
to
.
deep
.
eq
(
amount
.
sub
(
withdrawnAmount
).
sub
(
fee
))
.
getBalance
()
})
const
l2BalanceAfter
=
await
other
.
getBalance
()
expect
(
l1BalanceAfter
).
to
.
deep
.
eq
(
l1BalanceBefore
.
add
(
withdrawnAmount
))
expect
(
l2BalanceAfter
).
to
.
deep
.
eq
(
amount
.
sub
(
withdrawnAmount
).
sub
(
fee
))
},
envConfig
.
MOCHA_TIMEOUT
*
3
)
})
})
integration-tests/test/ovmcontext.spec.ts
View file @
c1e923f9
...
@@ -7,7 +7,12 @@ import { predeploys } from '@eth-optimism/contracts'
...
@@ -7,7 +7,12 @@ import { predeploys } from '@eth-optimism/contracts'
import
{
Contract
,
BigNumber
}
from
'
ethers
'
import
{
Contract
,
BigNumber
}
from
'
ethers
'
/* Imports: Internal */
/* Imports: Internal */
import
{
l2Provider
,
l1Provider
,
IS_LIVE_NETWORK
}
from
'
./shared/utils
'
import
{
l2Provider
,
l1Provider
,
envConfig
,
DEFAULT_TEST_GAS_L1
,
}
from
'
./shared/utils
'
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
Direction
}
from
'
./shared/watcher-utils
'
import
{
Direction
}
from
'
./shared/watcher-utils
'
...
@@ -41,11 +46,7 @@ describe('OVM Context: Layer 2 EVM Context', () => {
...
@@ -41,11 +46,7 @@ describe('OVM Context: Layer 2 EVM Context', () => {
await
Multicall
.
deployTransaction
.
wait
()
await
Multicall
.
deployTransaction
.
wait
()
})
})
let
numTxs
=
5
const
numTxs
=
envConfig
.
OVMCONTEXT_SPEC_NUM_TXS
if
(
IS_LIVE_NETWORK
)
{
// Tests take way too long if we don't reduce the number of txs here.
numTxs
=
1
}
it
(
'
enqueue: L1 contextual values are correctly set in L2
'
,
async
()
=>
{
it
(
'
enqueue: L1 contextual values are correctly set in L2
'
,
async
()
=>
{
for
(
let
i
=
0
;
i
<
numTxs
;
i
++
)
{
for
(
let
i
=
0
;
i
<
numTxs
;
i
++
)
{
...
@@ -54,7 +55,10 @@ describe('OVM Context: Layer 2 EVM Context', () => {
...
@@ -54,7 +55,10 @@ describe('OVM Context: Layer 2 EVM Context', () => {
const
tx
=
await
env
.
l1Messenger
.
sendMessage
(
const
tx
=
await
env
.
l1Messenger
.
sendMessage
(
OVMContextStorage
.
address
,
OVMContextStorage
.
address
,
'
0x
'
,
'
0x
'
,
2
_000_000
2
_000_000
,
{
gasLimit
:
DEFAULT_TEST_GAS_L1
,
}
)
)
// Wait for the transaction to be sent over to L2.
// Wait for the transaction to be sent over to L2.
...
@@ -89,7 +93,7 @@ describe('OVM Context: Layer 2 EVM Context', () => {
...
@@ -89,7 +93,7 @@ describe('OVM Context: Layer 2 EVM Context', () => {
const
coinbase
=
await
OVMContextStorage
.
coinbases
(
i
)
const
coinbase
=
await
OVMContextStorage
.
coinbases
(
i
)
expect
(
coinbase
).
to
.
equal
(
predeploys
.
OVM_SequencerFeeVault
)
expect
(
coinbase
).
to
.
equal
(
predeploys
.
OVM_SequencerFeeVault
)
}
}
})
.
timeout
(
150000
)
// this specific test takes a while because it involves L1 to L2 txs
})
it
(
'
should set correct OVM Context for `eth_call`
'
,
async
()
=>
{
it
(
'
should set correct OVM Context for `eth_call`
'
,
async
()
=>
{
for
(
let
i
=
0
;
i
<
numTxs
;
i
++
)
{
for
(
let
i
=
0
;
i
<
numTxs
;
i
++
)
{
...
...
integration-tests/test/queue-ingestion.spec.ts
View file @
c1e923f9
...
@@ -7,7 +7,7 @@ import { injectL2Context, applyL1ToL2Alias } from '@eth-optimism/core-utils'
...
@@ -7,7 +7,7 @@ import { injectL2Context, applyL1ToL2Alias } from '@eth-optimism/core-utils'
/* Imports: External */
/* Imports: External */
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
Direction
}
from
'
./shared/watcher-utils
'
import
{
Direction
}
from
'
./shared/watcher-utils
'
import
{
isLiveNetwork
}
from
'
./shared/utils
'
import
{
DEFAULT_TEST_GAS_L1
,
envConfig
}
from
'
./shared/utils
'
describe
(
'
Queue Ingestion
'
,
()
=>
{
describe
(
'
Queue Ingestion
'
,
()
=>
{
let
env
:
OptimismEnv
let
env
:
OptimismEnv
...
@@ -21,7 +21,7 @@ describe('Queue Ingestion', () => {
...
@@ -21,7 +21,7 @@ describe('Queue Ingestion', () => {
// that are in the queue and submit them. L2 will pick up the
// that are in the queue and submit them. L2 will pick up the
// sequencer batch appended event and play the transactions.
// sequencer batch appended event and play the transactions.
it
(
'
should order transactions correctly
'
,
async
()
=>
{
it
(
'
should order transactions correctly
'
,
async
()
=>
{
const
numTxs
=
5
const
numTxs
=
envConfig
.
OVMCONTEXT_SPEC_NUM_TXS
// Enqueue some transactions by building the calldata and then sending
// Enqueue some transactions by building the calldata and then sending
// the transaction to Layer 1
// the transaction to Layer 1
...
@@ -30,7 +30,10 @@ describe('Queue Ingestion', () => {
...
@@ -30,7 +30,10 @@ describe('Queue Ingestion', () => {
const
tx
=
await
env
.
l1Messenger
.
sendMessage
(
const
tx
=
await
env
.
l1Messenger
.
sendMessage
(
`0x
${
`
${
i
}
`
.
repeat
(
40
)}
`
,
`0x
${
`
${
i
}
`
.
repeat
(
40
)}
`
,
`0x0
${
i
}
`
,
`0x0
${
i
}
`
,
1
_000_000
1
_000_000
,
{
gasLimit
:
DEFAULT_TEST_GAS_L1
,
}
)
)
await
tx
.
wait
()
await
tx
.
wait
()
txs
.
push
(
tx
)
txs
.
push
(
tx
)
...
@@ -62,5 +65,5 @@ describe('Queue Ingestion', () => {
...
@@ -62,5 +65,5 @@ describe('Queue Ingestion', () => {
)
)
expect
(
l2Tx
.
l1BlockNumber
).
to
.
equal
(
l1TxReceipt
.
blockNumber
)
expect
(
l2Tx
.
l1BlockNumber
).
to
.
equal
(
l1TxReceipt
.
blockNumber
)
}
}
})
.
timeout
(
isLiveNetwork
()
?
300
_000
:
100
_000
)
})
})
})
integration-tests/test/replica.spec.ts
View file @
c1e923f9
...
@@ -4,26 +4,26 @@ import {
...
@@ -4,26 +4,26 @@ import {
defaultTransactionFactory
,
defaultTransactionFactory
,
gasPriceForL2
,
gasPriceForL2
,
sleep
,
sleep
,
isLiveNetwork
,
envConfig
,
}
from
'
./shared/utils
'
}
from
'
./shared/utils
'
import
{
TransactionReceipt
}
from
'
@ethersproject/abstract-provider
'
import
{
TransactionReceipt
}
from
'
@ethersproject/abstract-provider
'
describe
(
'
Replica Tests
'
,
()
=>
{
describe
(
'
Replica Tests
'
,
()
=>
{
let
env
:
OptimismEnv
let
env
:
OptimismEnv
before
(
async
()
=>
{
before
(
async
function
()
{
if
(
!
envConfig
.
RUN_REPLICA_TESTS
)
{
this
.
skip
()
return
}
env
=
await
OptimismEnv
.
new
()
env
=
await
OptimismEnv
.
new
()
})
})
describe
(
'
Matching blocks
'
,
()
=>
{
describe
(
'
Matching blocks
'
,
()
=>
{
if
(
isLiveNetwork
())
{
console
.
log
(
'
Skipping replica tests on live network
'
)
return
}
it
(
'
should sync a transaction
'
,
async
()
=>
{
it
(
'
should sync a transaction
'
,
async
()
=>
{
const
tx
=
defaultTransactionFactory
()
const
tx
=
defaultTransactionFactory
()
tx
.
gasPrice
=
await
gasPriceForL2
(
env
)
tx
.
gasPrice
=
await
gasPriceForL2
()
const
result
=
await
env
.
l2Wallet
.
sendTransaction
(
tx
)
const
result
=
await
env
.
l2Wallet
.
sendTransaction
(
tx
)
let
receipt
:
TransactionReceipt
let
receipt
:
TransactionReceipt
...
@@ -48,7 +48,7 @@ describe('Replica Tests', () => {
...
@@ -48,7 +48,7 @@ describe('Replica Tests', () => {
const
tx
=
{
const
tx
=
{
...
defaultTransactionFactory
(),
...
defaultTransactionFactory
(),
nonce
:
await
env
.
l2Wallet
.
getTransactionCount
(),
nonce
:
await
env
.
l2Wallet
.
getTransactionCount
(),
gasPrice
:
await
gasPriceForL2
(
env
),
gasPrice
:
await
gasPriceForL2
(),
chainId
:
null
,
// Disables EIP155 transaction signing.
chainId
:
null
,
// Disables EIP155 transaction signing.
}
}
const
signed
=
await
env
.
l2Wallet
.
signTransaction
(
tx
)
const
signed
=
await
env
.
l2Wallet
.
signTransaction
(
tx
)
...
@@ -76,7 +76,7 @@ describe('Replica Tests', () => {
...
@@ -76,7 +76,7 @@ describe('Replica Tests', () => {
const
tx
=
{
const
tx
=
{
...
defaultTransactionFactory
(),
...
defaultTransactionFactory
(),
nonce
:
await
env
.
l2Wallet
.
getTransactionCount
(),
nonce
:
await
env
.
l2Wallet
.
getTransactionCount
(),
gasPrice
:
await
gasPriceForL2
(
env
),
gasPrice
:
await
gasPriceForL2
(),
}
}
const
signed
=
await
env
.
l2Wallet
.
signTransaction
(
tx
)
const
signed
=
await
env
.
l2Wallet
.
signTransaction
(
tx
)
const
result
=
await
env
.
replicaProvider
.
sendTransaction
(
signed
)
const
result
=
await
env
.
replicaProvider
.
sendTransaction
(
signed
)
...
...
integration-tests/test/rpc.spec.ts
View file @
c1e923f9
...
@@ -10,8 +10,10 @@ import {
...
@@ -10,8 +10,10 @@ import {
defaultTransactionFactory
,
defaultTransactionFactory
,
fundUser
,
fundUser
,
L2_CHAINID
,
L2_CHAINID
,
isLiveNetwork
,
gasPriceForL2
,
gasPriceForL2
,
isHardhat
,
hardhatTest
,
envConfig
,
}
from
'
./shared/utils
'
}
from
'
./shared/utils
'
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
import
{
...
@@ -56,7 +58,7 @@ describe('Basic RPC tests', () => {
...
@@ -56,7 +58,7 @@ describe('Basic RPC tests', () => {
describe
(
'
eth_sendRawTransaction
'
,
()
=>
{
describe
(
'
eth_sendRawTransaction
'
,
()
=>
{
it
(
'
should correctly process a valid transaction
'
,
async
()
=>
{
it
(
'
should correctly process a valid transaction
'
,
async
()
=>
{
const
tx
=
defaultTransactionFactory
()
const
tx
=
defaultTransactionFactory
()
tx
.
gasPrice
=
await
gasPriceForL2
(
env
)
tx
.
gasPrice
=
await
gasPriceForL2
()
const
nonce
=
await
wallet
.
getTransactionCount
()
const
nonce
=
await
wallet
.
getTransactionCount
()
const
result
=
await
wallet
.
sendTransaction
(
tx
)
const
result
=
await
wallet
.
sendTransaction
(
tx
)
...
@@ -70,7 +72,7 @@ describe('Basic RPC tests', () => {
...
@@ -70,7 +72,7 @@ describe('Basic RPC tests', () => {
it
(
'
should not accept a transaction with the wrong chain ID
'
,
async
()
=>
{
it
(
'
should not accept a transaction with the wrong chain ID
'
,
async
()
=>
{
const
tx
=
{
const
tx
=
{
...
defaultTransactionFactory
(),
...
defaultTransactionFactory
(),
gasPrice
:
await
gasPriceForL2
(
env
),
gasPrice
:
await
gasPriceForL2
(),
chainId
:
(
await
wallet
.
getChainId
())
+
1
,
chainId
:
(
await
wallet
.
getChainId
())
+
1
,
}
}
...
@@ -83,7 +85,7 @@ describe('Basic RPC tests', () => {
...
@@ -83,7 +85,7 @@ describe('Basic RPC tests', () => {
const
tx
=
{
const
tx
=
{
...
defaultTransactionFactory
(),
...
defaultTransactionFactory
(),
nonce
:
await
wallet
.
getTransactionCount
(),
nonce
:
await
wallet
.
getTransactionCount
(),
gasPrice
:
await
gasPriceForL2
(
env
),
gasPrice
:
await
gasPriceForL2
(),
chainId
:
null
,
// Disables EIP155 transaction signing.
chainId
:
null
,
// Disables EIP155 transaction signing.
}
}
const
signed
=
await
wallet
.
signTransaction
(
tx
)
const
signed
=
await
wallet
.
signTransaction
(
tx
)
...
@@ -97,7 +99,7 @@ describe('Basic RPC tests', () => {
...
@@ -97,7 +99,7 @@ describe('Basic RPC tests', () => {
it
(
'
should accept a transaction with a value
'
,
async
()
=>
{
it
(
'
should accept a transaction with a value
'
,
async
()
=>
{
const
tx
=
{
const
tx
=
{
...
defaultTransactionFactory
(),
...
defaultTransactionFactory
(),
gasPrice
:
await
gasPriceForL2
(
env
),
gasPrice
:
await
gasPriceForL2
(),
chainId
:
await
env
.
l2Wallet
.
getChainId
(),
chainId
:
await
env
.
l2Wallet
.
getChainId
(),
data
:
'
0x
'
,
data
:
'
0x
'
,
value
:
ethers
.
utils
.
parseEther
(
'
0.1
'
),
value
:
ethers
.
utils
.
parseEther
(
'
0.1
'
),
...
@@ -117,7 +119,7 @@ describe('Basic RPC tests', () => {
...
@@ -117,7 +119,7 @@ describe('Basic RPC tests', () => {
const
balance
=
await
env
.
l2Wallet
.
getBalance
()
const
balance
=
await
env
.
l2Wallet
.
getBalance
()
const
tx
=
{
const
tx
=
{
...
defaultTransactionFactory
(),
...
defaultTransactionFactory
(),
gasPrice
:
await
gasPriceForL2
(
env
),
gasPrice
:
await
gasPriceForL2
(),
chainId
:
await
env
.
l2Wallet
.
getChainId
(),
chainId
:
await
env
.
l2Wallet
.
getChainId
(),
data
:
'
0x
'
,
data
:
'
0x
'
,
value
:
balance
.
add
(
ethers
.
utils
.
parseEther
(
'
1
'
)),
value
:
balance
.
add
(
ethers
.
utils
.
parseEther
(
'
1
'
)),
...
@@ -137,32 +139,29 @@ describe('Basic RPC tests', () => {
...
@@ -137,32 +139,29 @@ describe('Basic RPC tests', () => {
})
})
it
(
'
should reject a transaction with too low of a fee
'
,
async
()
=>
{
it
(
'
should reject a transaction with too low of a fee
'
,
async
()
=>
{
if
(
isLiveNetwork
())
{
const
isHH
=
await
isHardhat
()
console
.
log
(
'
Skipping too low of a fee test on live network
'
)
let
gasPrice
return
if
(
isHH
)
{
gasPrice
=
await
env
.
gasPriceOracle
.
gasPrice
()
await
env
.
gasPriceOracle
.
setGasPrice
(
1000
)
}
}
const
gasPrice
=
await
env
.
gasPriceOracle
.
gasPrice
()
await
env
.
gasPriceOracle
.
setGasPrice
(
1000
)
const
tx
=
{
const
tx
=
{
...
defaultTransactionFactory
(),
...
defaultTransactionFactory
(),
gasPrice
:
1
,
gasPrice
:
1
,
}
}
await
expect
(
env
.
l2Wallet
.
sendTransaction
(
tx
)).
to
.
be
.
rejectedWith
(
await
expect
(
env
.
l2Wallet
.
sendTransaction
(
tx
)).
to
.
be
.
rejectedWith
(
`gas price too low: 1 wei, use at least tx.gasPrice = 1000 wei`
/gas price too low: 1 wei, use at least tx
\.
gasPrice =
\d
+ wei/
)
)
// Reset the gas price to its original price
await
env
.
gasPriceOracle
.
setGasPrice
(
gasPrice
)
})
it
(
'
should reject a transaction with too high of a fee
'
,
async
()
=>
{
if
(
isHH
)
{
if
(
isLiveNetwork
())
{
// Reset the gas price to its original price
console
.
log
(
'
Skpping too high of a fee test on live network
'
)
await
env
.
gasPriceOracle
.
setGasPrice
(
gasPrice
)
return
}
}
})
it
(
'
should reject a transaction with too high of a fee
'
,
async
()
=>
{
const
gasPrice
=
await
env
.
gasPriceOracle
.
gasPrice
()
const
gasPrice
=
await
env
.
gasPriceOracle
.
gasPrice
()
const
largeGasPrice
=
gasPrice
.
mul
(
10
)
const
largeGasPrice
=
gasPrice
.
mul
(
10
)
const
tx
=
{
const
tx
=
{
...
@@ -332,7 +331,7 @@ describe('Basic RPC tests', () => {
...
@@ -332,7 +331,7 @@ describe('Basic RPC tests', () => {
it
(
'
includes L1 gas price and L1 gas used
'
,
async
()
=>
{
it
(
'
includes L1 gas price and L1 gas used
'
,
async
()
=>
{
const
tx
=
await
env
.
l2Wallet
.
populateTransaction
({
const
tx
=
await
env
.
l2Wallet
.
populateTransaction
({
to
:
env
.
l2Wallet
.
address
,
to
:
env
.
l2Wallet
.
address
,
gasPrice
:
isLiveNetwork
()
?
10000
:
1
,
gasPrice
:
await
gasPriceForL2
()
,
})
})
const
raw
=
serialize
({
const
raw
=
serialize
({
...
@@ -367,7 +366,7 @@ describe('Basic RPC tests', () => {
...
@@ -367,7 +366,7 @@ describe('Basic RPC tests', () => {
describe
(
'
eth_getTransactionByHash
'
,
()
=>
{
describe
(
'
eth_getTransactionByHash
'
,
()
=>
{
it
(
'
should be able to get all relevant l1/l2 transaction data
'
,
async
()
=>
{
it
(
'
should be able to get all relevant l1/l2 transaction data
'
,
async
()
=>
{
const
tx
=
defaultTransactionFactory
()
const
tx
=
defaultTransactionFactory
()
tx
.
gasPrice
=
await
gasPriceForL2
(
env
)
tx
.
gasPrice
=
await
gasPriceForL2
()
const
result
=
await
wallet
.
sendTransaction
(
tx
)
const
result
=
await
wallet
.
sendTransaction
(
tx
)
await
result
.
wait
()
await
result
.
wait
()
...
@@ -382,7 +381,7 @@ describe('Basic RPC tests', () => {
...
@@ -382,7 +381,7 @@ describe('Basic RPC tests', () => {
it
(
'
should return the block and all included transactions
'
,
async
()
=>
{
it
(
'
should return the block and all included transactions
'
,
async
()
=>
{
// Send a transaction and wait for it to be mined.
// Send a transaction and wait for it to be mined.
const
tx
=
defaultTransactionFactory
()
const
tx
=
defaultTransactionFactory
()
tx
.
gasPrice
=
await
gasPriceForL2
(
env
)
tx
.
gasPrice
=
await
gasPriceForL2
()
const
result
=
await
wallet
.
sendTransaction
(
tx
)
const
result
=
await
wallet
.
sendTransaction
(
tx
)
const
receipt
=
await
result
.
wait
()
const
receipt
=
await
result
.
wait
()
...
@@ -408,32 +407,31 @@ describe('Basic RPC tests', () => {
...
@@ -408,32 +407,31 @@ describe('Basic RPC tests', () => {
// Needs to be skipped on Prod networks because this test doesn't work when
// Needs to be skipped on Prod networks because this test doesn't work when
// other people are sending transactions to the Sequencer at the same time
// other people are sending transactions to the Sequencer at the same time
// as this test is running.
// as this test is running.
it
(
'
should return the same result when new transactions are not applied
'
,
async
function
()
{
hardhatTest
(
if
(
isLiveNetwork
())
{
'
should return the same result when new transactions are not applied
'
,
this
.
skip
()
async
()
=>
{
}
// Get latest block once to start.
const
prev
=
await
provider
.
getBlockWithTransactions
(
'
latest
'
)
// Get latest block once to start.
// set wait to null to allow a deep object comparison
const
prev
=
await
provider
.
getBlockWithTransactions
(
'
latest
'
)
prev
.
transactions
[
0
].
wait
=
null
// set wait to null to allow a deep object comparison
prev
.
transactions
[
0
].
wait
=
null
// Over ten seconds, repeatedly check the latest block to make sure nothing has changed.
for
(
let
i
=
0
;
i
<
5
;
i
++
)
{
// Over ten seconds, repeatedly check the latest block to make sure nothing has changed.
const
latest
=
await
provider
.
getBlockWithTransactions
(
'
latest
'
)
for
(
let
i
=
0
;
i
<
5
;
i
++
)
{
latest
.
transactions
[
0
].
wait
=
null
const
latest
=
await
provider
.
getBlockWithTransactions
(
'
latest
'
)
// Check each key of the transaction individually
latest
.
transactions
[
0
].
wait
=
null
// for easy debugging if one field changes
// Check each key of the transaction individually
for
(
const
[
key
,
value
]
of
Object
.
entries
(
latest
.
transactions
[
0
]))
{
// for easy debugging if one field changes
expect
(
value
).
to
.
deep
.
equal
(
for
(
const
[
key
,
value
]
of
Object
.
entries
(
latest
.
transactions
[
0
]))
{
prev
.
transactions
[
0
][
key
],
expect
(
value
).
to
.
deep
.
equal
(
`mismatch
${
key
}
`
prev
.
transactions
[
0
][
key
],
)
`mismatch
${
key
}
`
}
)
expect
(
latest
).
to
.
deep
.
equal
(
prev
)
await
sleep
(
2000
)
}
}
expect
(
latest
).
to
.
deep
.
equal
(
prev
)
await
sleep
(
2000
)
}
}
}
)
)
})
})
describe
(
'
eth_getBalance
'
,
()
=>
{
describe
(
'
eth_getBalance
'
,
()
=>
{
...
@@ -489,6 +487,12 @@ describe('Basic RPC tests', () => {
...
@@ -489,6 +487,12 @@ describe('Basic RPC tests', () => {
})
})
describe
(
'
debug_traceTransaction
'
,
()
=>
{
describe
(
'
debug_traceTransaction
'
,
()
=>
{
before
(
async
function
()
{
if
(
!
envConfig
.
RUN_DEBUG_TRACE_TESTS
)
{
this
.
skip
()
}
})
it
(
'
should match debug_traceBlock
'
,
async
()
=>
{
it
(
'
should match debug_traceBlock
'
,
async
()
=>
{
const
storage
=
await
ethers
.
getContractFactory
(
const
storage
=
await
ethers
.
getContractFactory
(
'
SimpleStorage
'
,
'
SimpleStorage
'
,
...
...
integration-tests/test/setup-docker-compose-network.ts
deleted
100644 → 0
View file @
a9da94ef
import
{
DockerComposeNetwork
}
from
'
./shared/docker-compose
'
before
(
async
()
=>
{
if
(
!
process
.
env
.
NO_NETWORK
)
{
await
new
DockerComposeNetwork
().
up
()
}
})
integration-tests/test/shared/docker-compose.ts
deleted
100644 → 0
View file @
a9da94ef
import
*
as
compose
from
'
docker-compose
'
import
*
as
shell
from
'
shelljs
'
import
*
as
path
from
'
path
'
type
ServiceNames
=
|
'
batch_submitter
'
|
'
dtl
'
|
'
l2geth
'
|
'
relayer
'
|
'
verifier
'
|
'
replica
'
const
OPS_DIRECTORY
=
path
.
join
(
process
.
cwd
(),
'
../ops
'
)
const
DEFAULT_SERVICES
:
ServiceNames
[]
=
[
'
batch_submitter
'
,
'
dtl
'
,
'
l2geth
'
,
'
relayer
'
,
]
export
class
DockerComposeNetwork
{
constructor
(
private
readonly
services
:
ServiceNames
[]
=
DEFAULT_SERVICES
)
{}
async
up
(
options
?:
compose
.
IDockerComposeOptions
)
{
const
out
=
await
compose
.
upMany
(
this
.
services
,
{
cwd
:
OPS_DIRECTORY
,
...
options
,
})
const
{
err
,
exitCode
}
=
out
if
(
!
err
||
exitCode
)
{
console
.
error
(
err
)
throw
new
Error
(
'
Unexpected error when starting docker-compose network, dumping output
'
)
}
if
(
err
.
includes
(
'
Creating
'
))
{
console
.
info
(
'
🐳 Tests required starting containers. Waiting for sequencer to ready.
'
)
shell
.
exec
(
`
${
OPS_DIRECTORY
}
/scripts/wait-for-sequencer.sh`
,
{
cwd
:
OPS_DIRECTORY
,
})
}
return
out
}
async
logs
()
{
return
compose
.
logs
(
this
.
services
,
{
cwd
:
OPS_DIRECTORY
})
}
async
stop
(
service
:
ServiceNames
)
{
return
compose
.
stopOne
(
service
,
{
cwd
:
OPS_DIRECTORY
})
}
async
rm
()
{
return
compose
.
rm
({
cwd
:
OPS_DIRECTORY
})
}
}
integration-tests/test/shared/env.ts
View file @
c1e923f9
...
@@ -19,6 +19,8 @@ import {
...
@@ -19,6 +19,8 @@ import {
getL1Bridge
,
getL1Bridge
,
getL2Bridge
,
getL2Bridge
,
sleep
,
sleep
,
envConfig
,
DEFAULT_TEST_GAS_L1
,
}
from
'
./utils
'
}
from
'
./utils
'
import
{
import
{
initWatcher
,
initWatcher
,
...
@@ -83,8 +85,10 @@ export class OptimismEnv {
...
@@ -83,8 +85,10 @@ export class OptimismEnv {
// fund the user if needed
// fund the user if needed
const
balance
=
await
l2Wallet
.
getBalance
()
const
balance
=
await
l2Wallet
.
getBalance
()
if
(
balance
.
lt
(
utils
.
parseEther
(
'
1
'
)))
{
const
min
=
envConfig
.
L2_WALLET_MIN_BALANCE_ETH
.
toString
()
await
fundUser
(
watcher
,
l1Bridge
,
utils
.
parseEther
(
'
1
'
).
sub
(
balance
))
const
topUp
=
envConfig
.
L2_WALLET_TOP_UP_AMOUNT_ETH
.
toString
()
if
(
balance
.
lt
(
utils
.
parseEther
(
min
)))
{
await
fundUser
(
watcher
,
l1Bridge
,
utils
.
parseEther
(
topUp
))
}
}
const
l1Messenger
=
getContractFactory
(
'
L1CrossDomainMessenger
'
)
const
l1Messenger
=
getContractFactory
(
'
L1CrossDomainMessenger
'
)
.
connect
(
l1Wallet
)
.
connect
(
l1Wallet
)
...
@@ -156,6 +160,7 @@ export class OptimismEnv {
...
@@ -156,6 +160,7 @@ export class OptimismEnv {
tx
:
Promise
<
TransactionResponse
>
|
TransactionResponse
tx
:
Promise
<
TransactionResponse
>
|
TransactionResponse
):
Promise
<
void
>
{
):
Promise
<
void
>
{
tx
=
await
tx
tx
=
await
tx
await
tx
.
wait
()
let
messagePairs
=
[]
let
messagePairs
=
[]
while
(
true
)
{
while
(
true
)
{
...
@@ -187,7 +192,10 @@ export class OptimismEnv {
...
@@ -187,7 +192,10 @@ export class OptimismEnv {
message
.
sender
,
message
.
sender
,
message
.
message
,
message
.
message
,
message
.
messageNonce
,
message
.
messageNonce
,
proof
proof
,
{
gasLimit
:
DEFAULT_TEST_GAS_L1
*
10
,
}
)
)
await
result
.
wait
()
await
result
.
wait
()
break
break
...
...
integration-tests/test/shared/stress-test-helpers.ts
View file @
c1e923f9
...
@@ -23,7 +23,7 @@ export const fundRandomWallet = async (
...
@@ -23,7 +23,7 @@ export const fundRandomWallet = async (
const
fundTx
=
await
env
.
l1Wallet
.
sendTransaction
({
const
fundTx
=
await
env
.
l1Wallet
.
sendTransaction
({
gasLimit
:
25
_000
,
gasLimit
:
25
_000
,
to
:
wallet
.
address
,
to
:
wallet
.
address
,
gasPrice
:
await
gasPriceForL1
(
env
),
gasPrice
:
await
gasPriceForL1
(),
value
,
value
,
})
})
await
fundTx
.
wait
()
await
fundTx
.
wait
()
...
@@ -47,7 +47,7 @@ export const executeL1ToL2Transaction = async (
...
@@ -47,7 +47,7 @@ export const executeL1ToL2Transaction = async (
),
),
MESSAGE_GAS
,
MESSAGE_GAS
,
{
{
gasPrice
:
await
gasPriceForL1
(
env
),
gasPrice
:
await
gasPriceForL1
(),
}
}
)
)
)
)
...
@@ -71,7 +71,7 @@ export const executeL2ToL1Transaction = async (
...
@@ -71,7 +71,7 @@ export const executeL2ToL1Transaction = async (
),
),
MESSAGE_GAS
,
MESSAGE_GAS
,
{
{
gasPrice
:
gasPriceForL2
(
env
),
gasPrice
:
gasPriceForL2
(),
}
}
)
)
)
)
...
@@ -90,7 +90,7 @@ export const executeL2Transaction = async (
...
@@ -90,7 +90,7 @@ export const executeL2Transaction = async (
tx
.
contract
tx
.
contract
.
connect
(
signer
)
.
connect
(
signer
)
.
functions
[
tx
.
functionName
](...
tx
.
functionParams
,
{
.
functions
[
tx
.
functionName
](...
tx
.
functionParams
,
{
gasPrice
:
gasPriceForL2
(
env
),
gasPrice
:
gasPriceForL2
(),
})
})
)
)
await
result
.
wait
()
await
result
.
wait
()
...
...
integration-tests/test/shared/utils.ts
View file @
c1e923f9
...
@@ -14,32 +14,54 @@ import {
...
@@ -14,32 +14,54 @@ import {
predeploys
,
predeploys
,
}
from
'
@eth-optimism/contracts
'
}
from
'
@eth-optimism/contracts
'
import
{
injectL2Context
,
remove0x
,
Watcher
}
from
'
@eth-optimism/core-utils
'
import
{
injectL2Context
,
remove0x
,
Watcher
}
from
'
@eth-optimism/core-utils
'
import
{
cleanEnv
,
str
,
num
,
bool
}
from
'
envalid
'
import
{
cleanEnv
,
str
,
num
,
bool
,
makeValidator
}
from
'
envalid
'
import
dotenv
from
'
dotenv
'
import
dotenv
from
'
dotenv
'
dotenv
.
config
()
/* Imports: Internal */
/* Imports: Internal */
import
{
Direction
,
waitForXDomainTransaction
}
from
'
./watcher-utils
'
import
{
Direction
,
waitForXDomainTransaction
}
from
'
./watcher-utils
'
import
{
OptimismEnv
}
from
'
./env
'
import
{
OptimismEnv
}
from
'
./env
'
export
const
GWEI
=
BigNumber
.
from
(
1
e9
)
export
const
isLiveNetwork
=
()
=>
{
export
const
isLiveNetwork
=
()
=>
{
return
process
.
env
.
IS_LIVE_NETWORK
===
'
true
'
return
process
.
env
.
IS_LIVE_NETWORK
===
'
true
'
}
}
if
(
isLiveNetwork
())
{
export
const
HARDHAT_CHAIN_ID
=
31337
dotenv
.
config
()
export
const
DEFAULT_TEST_GAS_L1
=
330
_000
}
export
const
DEFAULT_TEST_GAS_L2
=
1
_300_000
export
const
ON_CHAIN_GAS_PRICE
=
'
onchain
'
const
gasPriceValidator
=
makeValidator
((
gasPrice
)
=>
{
if
(
gasPrice
===
'
onchain
'
)
{
return
gasPrice
}
const
env
=
cleanEnv
(
process
.
env
,
{
return
num
().
_parse
(
gasPrice
).
toString
()
})
const
procEnv
=
cleanEnv
(
process
.
env
,
{
L1_GAS_PRICE
:
gasPriceValidator
({
default
:
'
0
'
,
}),
L1_URL
:
str
({
default
:
'
http://localhost:9545
'
}),
L1_URL
:
str
({
default
:
'
http://localhost:9545
'
}),
L2_URL
:
str
({
default
:
'
http://localhost:8545
'
}),
VERIFIER_URL
:
str
({
default
:
'
http://localhost:8547
'
}),
REPLICA_URL
:
str
({
default
:
'
http://localhost:8549
'
}),
L1_POLLING_INTERVAL
:
num
({
default
:
10
}),
L1_POLLING_INTERVAL
:
num
({
default
:
10
}),
L2_CHAINID
:
num
({
default
:
420
}),
L2_GAS_PRICE
:
gasPriceValidator
({
default
:
'
onchain
'
,
}),
L2_URL
:
str
({
default
:
'
http://localhost:8545
'
}),
L2_POLLING_INTERVAL
:
num
({
default
:
10
}),
L2_POLLING_INTERVAL
:
num
({
default
:
10
}),
VERIFIER_POLLING_INTERVAL
:
num
({
default
:
10
}),
L2_WALLET_MIN_BALANCE_ETH
:
num
({
default
:
2
,
}),
L2_WALLET_TOP_UP_AMOUNT_ETH
:
num
({
default
:
3
,
}),
REPLICA_URL
:
str
({
default
:
'
http://localhost:8549
'
}),
REPLICA_POLLING_INTERVAL
:
num
({
default
:
10
}),
REPLICA_POLLING_INTERVAL
:
num
({
default
:
10
}),
PRIVATE_KEY
:
str
({
PRIVATE_KEY
:
str
({
default
:
default
:
'
0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
'
,
'
0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
'
,
...
@@ -51,31 +73,53 @@ const env = cleanEnv(process.env, {
...
@@ -51,31 +73,53 @@ const env = cleanEnv(process.env, {
default
:
default
:
'
0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba
'
,
'
0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba
'
,
}),
}),
L2_CHAINID
:
num
({
default
:
420
}),
IS_LIVE_NETWORK
:
bool
({
default
:
false
}),
OVMCONTEXT_SPEC_NUM_TXS
:
num
({
default
:
5
,
}),
DTL_ENQUEUE_CONFIRMATIONS
:
num
({
default
:
0
,
}),
RUN_WITHDRAWAL_TESTS
:
bool
({
default
:
true
,
}),
RUN_REPLICA_TESTS
:
bool
({
default
:
true
,
}),
RUN_DEBUG_TRACE_TESTS
:
bool
({
default
:
true
,
}),
RUN_STRESS_TESTS
:
bool
({
default
:
true
,
}),
MOCHA_TIMEOUT
:
num
({
default
:
120
_000
,
}),
MOCHA_BAIL
:
bool
({
default
:
false
,
}),
})
})
export
const
envConfig
=
procEnv
// The hardhat instance
// The hardhat instance
export
const
l1Provider
=
new
providers
.
JsonRpcProvider
(
e
nv
.
L1_URL
)
export
const
l1Provider
=
new
providers
.
JsonRpcProvider
(
procE
nv
.
L1_URL
)
l1Provider
.
pollingInterval
=
e
nv
.
L1_POLLING_INTERVAL
l1Provider
.
pollingInterval
=
procE
nv
.
L1_POLLING_INTERVAL
export
const
l2Provider
=
injectL2Context
(
export
const
l2Provider
=
injectL2Context
(
new
providers
.
JsonRpcProvider
(
e
nv
.
L2_URL
)
new
providers
.
JsonRpcProvider
(
procE
nv
.
L2_URL
)
)
)
l2Provider
.
pollingInterval
=
env
.
L2_POLLING_INTERVAL
l2Provider
.
pollingInterval
=
procEnv
.
L2_POLLING_INTERVAL
export
const
verifierProvider
=
injectL2Context
(
new
providers
.
JsonRpcProvider
(
env
.
VERIFIER_URL
)
)
verifierProvider
.
pollingInterval
=
env
.
VERIFIER_POLLING_INTERVAL
export
const
replicaProvider
=
injectL2Context
(
export
const
replicaProvider
=
injectL2Context
(
new
providers
.
JsonRpcProvider
(
e
nv
.
REPLICA_URL
)
new
providers
.
JsonRpcProvider
(
procE
nv
.
REPLICA_URL
)
)
)
replicaProvider
.
pollingInterval
=
e
nv
.
REPLICA_POLLING_INTERVAL
replicaProvider
.
pollingInterval
=
procE
nv
.
REPLICA_POLLING_INTERVAL
// The sequencer private key which is funded on L1
// The sequencer private key which is funded on L1
export
const
l1Wallet
=
new
Wallet
(
e
nv
.
PRIVATE_KEY
,
l1Provider
)
export
const
l1Wallet
=
new
Wallet
(
procE
nv
.
PRIVATE_KEY
,
l1Provider
)
// A random private key which should always be funded with deposits from L1 -> L2
// A random private key which should always be funded with deposits from L1 -> L2
// if it's using non-0 gas price
// if it's using non-0 gas price
...
@@ -83,7 +127,7 @@ export const l2Wallet = l1Wallet.connect(l2Provider)
...
@@ -83,7 +127,7 @@ export const l2Wallet = l1Wallet.connect(l2Provider)
// The owner of the GasPriceOracle on L2
// The owner of the GasPriceOracle on L2
export
const
gasPriceOracleWallet
=
new
Wallet
(
export
const
gasPriceOracleWallet
=
new
Wallet
(
e
nv
.
GAS_PRICE_ORACLE_PRIVATE_KEY
,
procE
nv
.
GAS_PRICE_ORACLE_PRIVATE_KEY
,
l2Provider
l2Provider
)
)
...
@@ -92,13 +136,12 @@ export const PROXY_SEQUENCER_ENTRYPOINT_ADDRESS =
...
@@ -92,13 +136,12 @@ export const PROXY_SEQUENCER_ENTRYPOINT_ADDRESS =
'
0x4200000000000000000000000000000000000004
'
'
0x4200000000000000000000000000000000000004
'
export
const
OVM_ETH_ADDRESS
=
predeploys
.
OVM_ETH
export
const
OVM_ETH_ADDRESS
=
predeploys
.
OVM_ETH
export
const
L2_CHAINID
=
env
.
L2_CHAINID
export
const
L2_CHAINID
=
procEnv
.
L2_CHAINID
export
const
IS_LIVE_NETWORK
=
env
.
IS_LIVE_NETWORK
export
const
getAddressManager
=
(
provider
:
any
)
=>
{
export
const
getAddressManager
=
(
provider
:
any
)
=>
{
return
getContractFactory
(
'
Lib_AddressManager
'
)
return
getContractFactory
(
'
Lib_AddressManager
'
)
.
connect
(
provider
)
.
connect
(
provider
)
.
attach
(
e
nv
.
ADDRESS_MANAGER
)
.
attach
(
procE
nv
.
ADDRESS_MANAGER
)
}
}
// Gets the bridge contract
// Gets the bridge contract
...
@@ -115,33 +158,17 @@ export const getL1Bridge = async (wallet: Wallet, AddressManager: Contract) => {
...
@@ -115,33 +158,17 @@ export const getL1Bridge = async (wallet: Wallet, AddressManager: Contract) => {
throw
new
Error
(
'
Proxy__OVM_L1StandardBridge not found
'
)
throw
new
Error
(
'
Proxy__OVM_L1StandardBridge not found
'
)
}
}
const
L1StandardBridge
=
new
Contract
(
return
new
Contract
(
ProxyBridgeAddress
,
l1BridgeInterface
,
wallet
)
ProxyBridgeAddress
,
l1BridgeInterface
,
wallet
)
return
L1StandardBridge
}
}
export
const
getL2Bridge
=
async
(
wallet
:
Wallet
)
=>
{
export
const
getL2Bridge
=
async
(
wallet
:
Wallet
)
=>
{
const
L2BridgeInterface
=
getContractInterface
(
'
L2StandardBridge
'
)
const
L2BridgeInterface
=
getContractInterface
(
'
L2StandardBridge
'
)
const
L2StandardBridge
=
new
Contract
(
return
new
Contract
(
predeploys
.
L2StandardBridge
,
L2BridgeInterface
,
wallet
)
predeploys
.
L2StandardBridge
,
L2BridgeInterface
,
wallet
)
return
L2StandardBridge
}
}
export
const
getOvmEth
=
(
wallet
:
Wallet
)
=>
{
export
const
getOvmEth
=
(
wallet
:
Wallet
)
=>
{
const
OVM_ETH
=
new
Contract
(
return
new
Contract
(
OVM_ETH_ADDRESS
,
getContractInterface
(
'
OVM_ETH
'
),
wallet
)
OVM_ETH_ADDRESS
,
getContractInterface
(
'
OVM_ETH
'
),
wallet
)
return
OVM_ETH
}
}
export
const
fundUser
=
async
(
export
const
fundUser
=
async
(
...
@@ -152,12 +179,54 @@ export const fundUser = async (
...
@@ -152,12 +179,54 @@ export const fundUser = async (
)
=>
{
)
=>
{
const
value
=
BigNumber
.
from
(
amount
)
const
value
=
BigNumber
.
from
(
amount
)
const
tx
=
recipient
const
tx
=
recipient
?
bridge
.
depositETHTo
(
recipient
,
1
_300_000
,
'
0x
'
,
{
value
})
?
bridge
.
depositETHTo
(
recipient
,
DEFAULT_TEST_GAS_L2
,
'
0x
'
,
{
:
bridge
.
depositETH
(
1
_300_000
,
'
0x
'
,
{
value
})
value
,
gasLimit
:
DEFAULT_TEST_GAS_L1
,
})
:
bridge
.
depositETH
(
DEFAULT_TEST_GAS_L2
,
'
0x
'
,
{
value
,
gasLimit
:
DEFAULT_TEST_GAS_L1
,
})
await
waitForXDomainTransaction
(
watcher
,
tx
,
Direction
.
L1ToL2
)
await
waitForXDomainTransaction
(
watcher
,
tx
,
Direction
.
L1ToL2
)
}
}
export
const
conditionalTest
=
(
condition
:
(
env
?:
OptimismEnv
)
=>
Promise
<
boolean
>
,
name
,
fn
,
message
?:
string
,
timeout
?:
number
)
=>
{
it
(
name
,
async
function
()
{
const
shouldRun
=
await
condition
()
if
(
!
shouldRun
)
{
console
.
log
(
message
)
this
.
skip
()
return
}
await
fn
()
}).
timeout
(
timeout
||
envConfig
.
MOCHA_TIMEOUT
)
}
export
const
withdrawalTest
=
(
name
,
fn
,
timeout
?:
number
)
=>
conditionalTest
(
()
=>
Promise
.
resolve
(
procEnv
.
RUN_WITHDRAWAL_TESTS
),
name
,
fn
,
`Skipping withdrawal test.`
,
timeout
)
export
const
hardhatTest
=
(
name
,
fn
)
=>
conditionalTest
(
isHardhat
,
name
,
fn
,
'
Skipping test on non-Hardhat environment.
'
)
export
const
sleep
=
(
ms
:
number
)
=>
new
Promise
((
r
)
=>
setTimeout
(
r
,
ms
))
export
const
sleep
=
(
ms
:
number
)
=>
new
Promise
((
r
)
=>
setTimeout
(
r
,
ms
))
const
abiCoder
=
new
utils
.
AbiCoder
()
const
abiCoder
=
new
utils
.
AbiCoder
()
...
@@ -175,56 +244,23 @@ export const defaultTransactionFactory = () => {
...
@@ -175,56 +244,23 @@ export const defaultTransactionFactory = () => {
}
}
}
}
export
const
waitForL2Geth
=
async
(
export
const
gasPriceForL2
=
async
()
=>
{
provider
:
providers
.
JsonRpcProvider
if
(
procEnv
.
L2_GAS_PRICE
===
ON_CHAIN_GAS_PRICE
)
{
):
Promise
<
providers
.
JsonRpcProvider
>
=>
{
return
l2Wallet
.
getGasPrice
()
let
ready
:
boolean
=
false
while
(
!
ready
)
{
try
{
await
provider
.
getNetwork
()
ready
=
true
}
catch
(
error
)
{
await
sleep
(
1000
)
}
}
return
injectL2Context
(
provider
)
}
// eslint-disable-next-line @typescript-eslint/no-shadow
export
const
gasPriceForL2
=
async
(
env
:
OptimismEnv
)
=>
{
// The integration tests enforce fees on L2
// which run against hardhat on L1. Update if
// geth --dev is adopted for L1
const
chainId
=
await
env
.
l1Wallet
.
getChainId
()
if
((
await
isMainnet
(
env
))
||
chainId
===
31337
)
{
return
env
.
l2Wallet
.
getGasPrice
()
}
}
if
(
isLiveNetwork
())
{
return
utils
.
parseUnits
(
procEnv
.
L2_GAS_PRICE
,
'
wei
'
)
return
Promise
.
resolve
(
BigNumber
.
from
(
10000
))
}
return
Promise
.
resolve
(
BigNumber
.
from
(
0
))
}
}
// eslint-disable-next-line @typescript-eslint/no-shadow
export
const
gasPriceForL1
=
async
()
=>
{
export
const
gasPriceForL1
=
async
(
env
:
OptimismEnv
)
=>
{
if
(
procEnv
.
L1_GAS_PRICE
===
ON_CHAIN_GAS_PRICE
)
{
const
chainId
=
await
env
.
l1Wallet
.
getChainId
()
return
l1Wallet
.
getGasPrice
()
switch
(
chainId
)
{
case
1
:
return
env
.
l1Wallet
.
getGasPrice
()
case
3
:
case
42
:
return
utils
.
parseUnits
(
'
10
'
,
'
gwei
'
)
case
5
:
return
utils
.
parseUnits
(
'
2
'
,
'
gwei
'
)
default
:
return
BigNumber
.
from
(
0
)
}
}
return
utils
.
parseUnits
(
procEnv
.
L1_GAS_PRICE
,
'
wei
'
)
}
}
// eslint-disable-next-line @typescript-eslint/no-shadow
export
const
isHardhat
=
async
()
=>
{
export
const
isMainnet
=
async
(
env
:
OptimismEnv
)
=>
{
const
chainId
=
await
l1Wallet
.
getChainId
()
const
chainId
=
await
env
.
l1Wallet
.
getChainId
()
return
chainId
===
HARDHAT_CHAIN_ID
return
chainId
===
1
}
}
integration-tests/test/stress-tests.spec.ts
View file @
c1e923f9
...
@@ -17,12 +17,12 @@ import {
...
@@ -17,12 +17,12 @@ import {
}
from
'
./shared/stress-test-helpers
'
}
from
'
./shared/stress-test-helpers
'
/* Imports: Artifacts */
/* Imports: Artifacts */
import
{
fundUser
,
isLiveNetwork
,
isMainnet
}
from
'
./shared/utils
'
import
{
envConfig
,
fundUser
}
from
'
./shared/utils
'
// Need a big timeout to allow for all transactions to be processed.
// Need a big timeout to allow for all transactions to be processed.
// For some reason I can't figure out how to set the timeout on a per-suite basis
// For some reason I can't figure out how to set the timeout on a per-suite basis
// so I'm instead setting it for every test.
// so I'm instead setting it for every test.
const
STRESS_TEST_TIMEOUT
=
isLiveNetwork
()
?
500
_000
:
1
_200_000
const
STRESS_TEST_TIMEOUT
=
envConfig
.
MOCHA_TIMEOUT
*
5
describe
(
'
stress tests
'
,
()
=>
{
describe
(
'
stress tests
'
,
()
=>
{
const
numTransactions
=
3
const
numTransactions
=
3
...
@@ -32,13 +32,14 @@ describe('stress tests', () => {
...
@@ -32,13 +32,14 @@ describe('stress tests', () => {
const
wallets
:
Wallet
[]
=
[]
const
wallets
:
Wallet
[]
=
[]
before
(
async
function
()
{
before
(
async
function
()
{
env
=
await
OptimismEnv
.
new
()
if
(
!
envConfig
.
RUN_STRESS_TESTS
)
{
if
(
await
isMainnet
(
env
))
{
console
.
log
(
'
Skipping stress tests.
'
)
console
.
log
(
'
Skipping stress tests on mainnet.
'
)
this
.
skip
()
this
.
skip
()
return
return
}
}
env
=
await
OptimismEnv
.
new
()
for
(
let
i
=
0
;
i
<
numTransactions
;
i
++
)
{
for
(
let
i
=
0
;
i
<
numTransactions
;
i
++
)
{
wallets
.
push
(
Wallet
.
createRandom
())
wallets
.
push
(
Wallet
.
createRandom
())
}
}
...
...
yarn.lock
View file @
c1e923f9
...
@@ -3210,14 +3210,6 @@
...
@@ -3210,14 +3210,6 @@
"@types/mime" "^1"
"@types/mime" "^1"
"@types/node" "*"
"@types/node" "*"
"@types/shelljs@^0.8.8":
version "0.8.9"
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.9.tgz#45dd8501aa9882976ca3610517dac3831c2fbbf4"
integrity sha512-flVe1dvlrCyQJN/SGrnBxqHG+RzXrVKsmjD8WS/qYHpq5UPjfq7UWFBENP0ZuOl0g6OpAlL6iBoLSvKYUUmyQw==
dependencies:
"@types/glob" "*"
"@types/node" "*"
"@types/sinon-chai@^3.2.3", "@types/sinon-chai@^3.2.5":
"@types/sinon-chai@^3.2.3", "@types/sinon-chai@^3.2.5":
version "3.2.5"
version "3.2.5"
resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.5.tgz#df21ae57b10757da0b26f512145c065f2ad45c48"
resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.5.tgz#df21ae57b10757da0b26f512145c065f2ad45c48"
...
@@ -6247,13 +6239,6 @@ directory-tree@^2.2.7:
...
@@ -6247,13 +6239,6 @@ directory-tree@^2.2.7:
resolved "https://registry.yarnpkg.com/directory-tree/-/directory-tree-2.3.1.tgz#78b8aa84878eb84dd29a51dcd664ded4cd0247c7"
resolved "https://registry.yarnpkg.com/directory-tree/-/directory-tree-2.3.1.tgz#78b8aa84878eb84dd29a51dcd664ded4cd0247c7"
integrity sha512-hxolIHCtQ/a56CUywaLzGD/V78zPwFihI+UK/4ZjOp7GoV4Mptmtv95yavOn/RlnTi7cCMjszvfcNrwCoWLH+Q==
integrity sha512-hxolIHCtQ/a56CUywaLzGD/V78zPwFihI+UK/4ZjOp7GoV4Mptmtv95yavOn/RlnTi7cCMjszvfcNrwCoWLH+Q==
docker-compose@^0.23.8:
version "0.23.13"
resolved "https://registry.yarnpkg.com/docker-compose/-/docker-compose-0.23.13.tgz#77d37bd05b6a966345f631e6d05e961c79514f06"
integrity sha512-/9fYC4g3AO+qsqxIZhmbVnFvJJPcYEV2yJbAPPXH+6AytU3urIY8lUAXOlvY8sl4u25pdKu1JrOfAmWC7lJDJg==
dependencies:
yaml "^1.10.2"
doctrine@^2.1.0:
doctrine@^2.1.0:
version "2.1.0"
version "2.1.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
...
@@ -13963,7 +13948,7 @@ shebang-regex@^3.0.0:
...
@@ -13963,7 +13948,7 @@ shebang-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
shelljs@^0.8.3
, shelljs@^0.8.4
:
shelljs@^0.8.3:
version "0.8.5"
version "0.8.5"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c"
integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==
integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==
...
@@ -16639,7 +16624,7 @@ yallist@^4.0.0:
...
@@ -16639,7 +16624,7 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yaml@^1.10.0
, yaml@^1.10.2
:
yaml@^1.10.0:
version "1.10.2"
version "1.10.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment