Commit 0ebce9dc authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

ci: Use faucet in actor tests (#3193)

To improve the concurrency of the Bedrock actor tests, I hooked up an ETH faucet. Now, the actors can use the faucet to fund themselves before each run.
parent 46bfb3c3
import { Wallet, utils } from 'ethers' import { Wallet } from 'ethers'
import { expect } from 'chai' import { expect } from 'chai'
import { actor, setupActor, run, setupRun } from '../lib/convenience' import { actor, setupActor, run, setupRun } from '../lib/convenience'
import { devWalletsL2 } from './utils' import { devWalletsL2, l2Provider } from './utils'
import { Faucet } from '../lib/faucet'
interface Context { interface Context {
wallet: Wallet wallet: Wallet
} }
actor('Sender', () => { actor('Sender', () => {
let sourceWallet: Wallet
let destWallet: Wallet let destWallet: Wallet
setupActor(async () => { setupActor(async () => {
const devWallets = devWalletsL2() const devWallets = devWalletsL2()
sourceWallet = devWallets[0] destWallet = devWallets[0]
destWallet = devWallets[1]
}) })
setupRun(async () => { setupRun(async () => {
const newWallet = Wallet.createRandom().connect(sourceWallet.provider) const faucet = new Faucet(process.env.FAUCET_URL, l2Provider)
const tx = await sourceWallet.sendTransaction({ const wallet = Wallet.createRandom().connect(l2Provider)
to: newWallet.address, await faucet.drip(wallet.address)
value: utils.parseEther('0.1'),
})
await tx.wait()
return { return {
wallet: newWallet, wallet,
} }
}) })
......
import { utils, Wallet, providers, constants } from 'ethers' import { utils, Wallet, constants } from 'ethers'
import { import {
CrossChainMessenger, CrossChainMessenger,
ETHBridgeAdapter, ETHBridgeAdapter,
...@@ -7,65 +7,68 @@ import { ...@@ -7,65 +7,68 @@ import {
import { predeploys } from '@eth-optimism/contracts-bedrock' import { predeploys } from '@eth-optimism/contracts-bedrock'
import { sleep } from '@eth-optimism/core-utils' import { sleep } from '@eth-optimism/core-utils'
import { actor, setupActor, run } from '../lib/convenience' import { actor, setupActor, run, setupRun } from '../lib/convenience'
import { l1Provider, l2Provider } from './utils'
import { Faucet } from '../lib/faucet'
interface Context { interface Context {
wallet: Wallet wallet: Wallet
messenger: CrossChainMessenger
} }
actor('Dev account sender', () => { actor('Depositor', () => {
let l1Provider: providers.JsonRpcProvider
let l2Provider: providers.JsonRpcProvider
let wallet: Wallet
let messenger: CrossChainMessenger
let contracts: any let contracts: any
setupActor(async () => { setupActor(async () => {
l1Provider = new providers.JsonRpcProvider(process.env.L1_RPC)
l2Provider = new providers.JsonRpcProvider(process.env.L2_RPC)
wallet = new Wallet(process.env.PRIVATE_KEY)
contracts = require(process.env.CONTRACTS_JSON_PATH) contracts = require(process.env.CONTRACTS_JSON_PATH)
messenger = new CrossChainMessenger({ })
l1SignerOrProvider: wallet.connect(l1Provider),
l2SignerOrProvider: wallet.connect(l2Provider), setupRun(async () => {
l1ChainId: (await l1Provider.getNetwork()).chainId, const wallet = Wallet.createRandom().connect(l1Provider)
l2ChainId: (await l2Provider.getNetwork()).chainId, const faucet = new Faucet(process.env.FAUCET_URL, l1Provider)
bridges: { await faucet.drip(wallet.address)
Standard: {
Adapter: StandardBridgeAdapter, return {
l1Bridge: contracts.L1StandardBridgeProxy, wallet,
l2Bridge: predeploys.L2StandardBridge, messenger: new CrossChainMessenger({
}, l1SignerOrProvider: wallet.connect(l1Provider),
ETH: { l2SignerOrProvider: wallet.connect(l2Provider),
Adapter: ETHBridgeAdapter, l1ChainId: (await l1Provider.getNetwork()).chainId,
l1Bridge: contracts.L1StandardBridgeProxy, l2ChainId: (await l2Provider.getNetwork()).chainId,
l2Bridge: predeploys.L2StandardBridge, bridges: {
Standard: {
Adapter: StandardBridgeAdapter,
l1Bridge: contracts.L1StandardBridgeProxy,
l2Bridge: predeploys.L2StandardBridge,
},
ETH: {
Adapter: ETHBridgeAdapter,
l1Bridge: contracts.L1StandardBridgeProxy,
l2Bridge: predeploys.L2StandardBridge,
},
}, },
}, contracts: {
contracts: { l1: {
l1: { AddressManager: constants.AddressZero,
AddressManager: constants.AddressZero, StateCommitmentChain: constants.AddressZero,
StateCommitmentChain: constants.AddressZero, CanonicalTransactionChain: constants.AddressZero,
CanonicalTransactionChain: constants.AddressZero, BondManager: constants.AddressZero,
BondManager: constants.AddressZero, L1StandardBridge: contracts.L1StandardBridgeProxy,
L1StandardBridge: contracts.L1StandardBridgeProxy, L1CrossDomainMessenger: contracts.L1CrossDomainMessengerProxy,
L1CrossDomainMessenger: contracts.L1CrossDomainMessengerProxy, L2OutputOracle: contracts.L2OutputOracleProxy,
L2OutputOracle: contracts.L2OutputOracleProxy, OptimismPortal: contracts.OptimismPortalProxy,
OptimismPortal: contracts.OptimismPortalProxy, },
}, },
}, bedrock: true,
bedrock: true, }),
}) }
}) })
run(async (b, ctx: Context, logger) => { run(async (b, ctx: Context, logger) => {
const { messenger } = ctx
const recipient = Wallet.createRandom().connect(l2Provider) const recipient = Wallet.createRandom().connect(l2Provider)
logger.log(`Depositing funds to ${recipient.address}.`) logger.log(`Depositing funds to ${recipient.address}.`)
const depositTx = await messenger.depositETH(utils.parseEther('0.0001'), { const depositTx = await messenger.depositETH(utils.parseEther('0.000001'), {
recipient: recipient.address, recipient: recipient.address,
}) })
logger.log(`Awaiting receipt for deposit tx ${depositTx.hash}.`) logger.log(`Awaiting receipt for deposit tx ${depositTx.hash}.`)
...@@ -74,7 +77,7 @@ actor('Dev account sender', () => { ...@@ -74,7 +77,7 @@ actor('Dev account sender', () => {
for (let i = 0; i < 60; i++) { for (let i = 0; i < 60; i++) {
const recipBal = await recipient.getBalance() const recipBal = await recipient.getBalance()
logger.log(`Polling L2 for deposit completion.`) logger.log(`Polling L2 for deposit completion.`)
if (recipBal.eq(utils.parseEther('0.0001'))) { if (recipBal.eq(utils.parseEther('0.000001'))) {
logger.log('Deposit successful.') logger.log('Deposit successful.')
return return
} }
......
...@@ -3,12 +3,16 @@ import { providers, Wallet } from 'ethers' ...@@ -3,12 +3,16 @@ import { providers, Wallet } from 'ethers'
const DEV_MNEMONIC = const DEV_MNEMONIC =
'test test test test test test test test test test test junk' 'test test test test test test test test test test test junk'
export const l1Provider = new providers.JsonRpcProvider(process.env.L1_RPC)
export const l2Provider = new providers.JsonRpcProvider(process.env.L2_RPC)
export const devWalletsL2 = () => { export const devWalletsL2 = () => {
const provider = new providers.JsonRpcProvider(process.env.L2_RPC)
const wallets = [] const wallets = []
for (let i = 0; i < 20; i++) { for (let i = 0; i < 20; i++) {
wallets.push( wallets.push(
Wallet.fromMnemonic(DEV_MNEMONIC, `m/44'/60'/0'/0/${i}`).connect(provider) Wallet.fromMnemonic(DEV_MNEMONIC, `m/44'/60'/0'/0/${i}`).connect(
l2Provider
)
) )
} }
return wallets return wallets
......
import { ethers, providers } from 'ethers'
import { fetchJson, getAddress } from 'ethers/lib/utils'
export class Faucet {
private url: string
private provider: providers.Provider
constructor(url: string, provider: providers.Provider) {
this.url = url
this.provider = provider
}
public async drip(
recipient: string
): Promise<ethers.providers.TransactionReceipt> {
const res = await fetchJson(
`${this.url}/api/claim`,
JSON.stringify({
address: getAddress(recipient),
})
)
const txHash = res.tx_hash
return this.provider.waitForTransaction(txHash, 0, 30000)
}
}
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
"test:coverage": "yarn test" "test:coverage": "yarn test"
}, },
"dependencies": { "dependencies": {
"@eth-optimism/contracts-bedrock": "0.5.2", "@eth-optimism/contracts-bedrock": "0.5.3",
"@eth-optimism/core-utils": "^0.9.2", "@eth-optimism/core-utils": "^0.9.2",
"@eth-optimism/sdk": "^1.3.1", "@eth-optimism/sdk": "^1.3.1",
"@types/chai": "^4.2.18", "@types/chai": "^4.2.18",
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"resolveJsonModule": true "resolveJsonModule": true
}, },
"include": [ "include": [
"./lib", "./lib/**/*.ts",
"./bedrock/**/*.(ts|json)", "./bedrock/**/*.(ts|json)",
"./package.json" "./package.json"
] ]
......
...@@ -652,27 +652,6 @@ ...@@ -652,27 +652,6 @@
minimatch "^3.1.2" minimatch "^3.1.2"
strip-json-comments "^3.1.1" strip-json-comments "^3.1.1"
"@eth-optimism/contracts-bedrock@0.5.2":
version "0.5.2"
resolved "https://registry.yarnpkg.com/@eth-optimism/contracts-bedrock/-/contracts-bedrock-0.5.2.tgz#9e7c364afe0791e54f311d3a2135623448881936"
integrity sha512-5QFEmudbU9Q6rOxZibPRTqW6q/gKQ7H6toC9v645pYJ4Aw2mB+FIQDbeJ4hDLwV/GRjaHXOuU9uGEqLMk+y8Cw==
dependencies:
"@eth-optimism/core-utils" "^0.9.2"
"@ethereumjs/trie" "^5.0.0-beta.1"
"@ethereumjs/util" "^8.0.0-beta.1"
"@openzeppelin/contracts" "^4.5.0"
"@openzeppelin/contracts-upgradeable" "^4.5.2"
"@rari-capital/solmate" "https://github.com/rari-capital/solmate.git#8f9b23f8838670afda0fd8983f2c41e8037ae6bc"
bip39 "^3.0.4"
ds-test "https://github.com/dapphub/ds-test.git#9310e879db8ba3ea6d5c6489a579118fd264a3f5"
ethereumjs-wallet "^1.0.2"
ethers "^5.6.8"
excessively-safe-call "https://github.com/nomad-xyz/ExcessivelySafeCall.git#4fcdfd3593d21381f696c790fa6180b8ef559c1e"
forge-std "https://github.com/foundry-rs/forge-std.git#f18682b2874fc57d7c80a511fed0b35ec4201ffa"
hardhat "^2.9.6"
merkle-patricia-tree "^4.2.4"
rlp "^2.2.7"
"@ethereum-waffle/chai@^3.4.0": "@ethereum-waffle/chai@^3.4.0":
version "3.4.0" version "3.4.0"
resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.4.0.tgz#2477877410a96bf370edd64df905b04fb9aba9d5" resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.4.0.tgz#2477877410a96bf370edd64df905b04fb9aba9d5"
...@@ -2864,11 +2843,6 @@ ...@@ -2864,11 +2843,6 @@
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.1.tgz#f63fc384255d6ac139e0a2561aa207fd7c14183c" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.1.tgz#f63fc384255d6ac139e0a2561aa207fd7c14183c"
integrity sha512-5EFiZld3DYFd8aTL8eeMnhnaWh1/oXLXFNuFMrgF3b1DNPshF3LCyO7VR6lc+gac2URJ0BlVcZoCfkk/3MoEfg== integrity sha512-5EFiZld3DYFd8aTL8eeMnhnaWh1/oXLXFNuFMrgF3b1DNPshF3LCyO7VR6lc+gac2URJ0BlVcZoCfkk/3MoEfg==
"@openzeppelin/contracts-upgradeable@^4.5.2":
version "4.7.2"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.2.tgz#414096e21f048200cbb7ad4fe4c6de2e822513bf"
integrity sha512-3dgc6qVmFch/uOmlmKnw5/v3JxwXcZD4T10/9CI1OUbX8AqjoZrBGKfxN1z3QxnIXRU/X31/BItJezJSDDTe7Q==
"@openzeppelin/contracts@3.4.1-solc-0.7-2": "@openzeppelin/contracts@3.4.1-solc-0.7-2":
version "3.4.1-solc-0.7-2" version "3.4.1-solc-0.7-2"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz#371c67ebffe50f551c3146a9eec5fe6ffe862e92" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz#371c67ebffe50f551c3146a9eec5fe6ffe862e92"
...@@ -2899,11 +2873,6 @@ ...@@ -2899,11 +2873,6 @@
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.4.0.tgz#4a1df71f736c31230bbbd634dfb006a756b51e6b" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.4.0.tgz#4a1df71f736c31230bbbd634dfb006a756b51e6b"
integrity sha512-dlKiZmDvJnGRLHojrDoFZJmsQVeltVeoiRN7RK+cf2FmkhASDEblE0RiaYdxPNsUZa6mRG8393b9bfyp+V5IAw== integrity sha512-dlKiZmDvJnGRLHojrDoFZJmsQVeltVeoiRN7RK+cf2FmkhASDEblE0RiaYdxPNsUZa6mRG8393b9bfyp+V5IAw==
"@openzeppelin/contracts@^4.5.0":
version "4.7.2"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.7.2.tgz#7587416fe2d35abf574193515b8971bfe9f64bc7"
integrity sha512-4n/JL9izql8303mPqPdubuna/DWEMbmOzWYUWyCPhjhiEr2w3nQrjE7vZz1fBF+wzzP6dZbIcsgqACk53c9FGA==
"@primitivefi/hardhat-dodoc@^0.1.3": "@primitivefi/hardhat-dodoc@^0.1.3":
version "0.1.3" version "0.1.3"
resolved "https://registry.yarnpkg.com/@primitivefi/hardhat-dodoc/-/hardhat-dodoc-0.1.3.tgz#338ecff24b93d3b43fa35a98909f6840af86c27c" resolved "https://registry.yarnpkg.com/@primitivefi/hardhat-dodoc/-/hardhat-dodoc-0.1.3.tgz#338ecff24b93d3b43fa35a98909f6840af86c27c"
...@@ -8629,10 +8598,6 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: ...@@ -8629,10 +8598,6 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
md5.js "^1.3.4" md5.js "^1.3.4"
safe-buffer "^5.1.1" safe-buffer "^5.1.1"
"excessively-safe-call@https://github.com/nomad-xyz/ExcessivelySafeCall.git#4fcdfd3593d21381f696c790fa6180b8ef559c1e":
version "0.0.1-rc.1"
resolved "https://github.com/nomad-xyz/ExcessivelySafeCall.git#4fcdfd3593d21381f696c790fa6180b8ef559c1e"
"excessively-safe-call@https://github.com/nomad-xyz/ExcessivelySafeCall.git#81cd99ce3e69117d665d7601c330ea03b97acce0": "excessively-safe-call@https://github.com/nomad-xyz/ExcessivelySafeCall.git#81cd99ce3e69117d665d7601c330ea03b97acce0":
version "0.0.1-rc.1" version "0.0.1-rc.1"
resolved "https://github.com/nomad-xyz/ExcessivelySafeCall.git#81cd99ce3e69117d665d7601c330ea03b97acce0" resolved "https://github.com/nomad-xyz/ExcessivelySafeCall.git#81cd99ce3e69117d665d7601c330ea03b97acce0"
......
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