Commit ec682122 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

Merge pull request #3389 from ethereum-optimism/develop

Develop -> Master
parents 2c80ff28 6c0235a6
---
'@eth-optimism/l2geth': patch
---
Add the gas estimation block tag to `eth_estimateGas` to be RPC compliant
---
'@eth-optimism/contracts-periphery': patch
---
Fixes import paths in the contracts-periphery package
---
'@eth-optimism/foundry': patch
'@eth-optimism/ci-builder': patch
---
Upgrade foundry to support consistent storage layouts
---
'@eth-optimism/core-utils': minor
---
Removes ethers as a dependency in favor of individual ethers sub-packages
---
'@eth-optimism/contracts': patch
---
Significantly reduces contracts package bundle size
---
'@eth-optimism/hardhat-node': patch
---
Fixes CI to properly release the hardhat-node
......@@ -221,7 +221,7 @@ jobs:
name: Check if we should run
command: |
shopt -s inherit_errexit
CHANGED=$(check-changed "op-(batcher|bindings|e2e|node|proposer)")
CHANGED=$(check-changed "op-(batcher|bindings|e2e|node|proposer|chain-ops)")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
......@@ -255,6 +255,11 @@ jobs:
command: |
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell ./...
working_directory: op-service
- run:
name: lint op-chain-ops
command: |
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell ./...
working_directory: op-chain-ops
- run:
name: prep results dir
command: mkdir -p /test-results
......@@ -283,6 +288,11 @@ jobs:
command: |
gotestsum --junitfile /test-results/op-service.xml -- -coverpkg=github.com/ethereum-optimism/optimism/... -coverprofile=coverage.out -covermode=atomic ./...
working_directory: op-service
- run:
name: test op-chain-ops
command: |
gotestsum --junitfile /test-results/op-chain-ops.xml -- -coverpkg=github.com/ethereum-optimism/optimism/... -coverprofile=coverage.out -covermode=atomic ./...
working_directory: op-chain-ops
- store_test_results:
path: /test-results
- run:
......@@ -400,7 +410,7 @@ jobs:
fi
- run:
name: Lint
command: golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell ./...
command: golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint -e "errors.As" -e "errors.Is" ./...
working_directory: <<parameters.working_directory>>
- store_test_results:
path: /test-results
......@@ -497,19 +507,6 @@ jobs:
name: Bring up the stack
command: |
make devnet-up
- run:
name: Check L2 Config
command: npx hardhat check-l2-config --network devnetL1
working_directory: packages/contracts-bedrock
- run:
name: Do a deposit
command: |
timeout 5m npx hardhat deposit \
--to 0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244 \
--amount-eth 1 \
--private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
--network devnetL1
working_directory: packages/contracts-bedrock
- run:
name: Deposit ERC20 through the bridge
command: timeout 5m npx hardhat deposit-erc20 --network devnetL1
......@@ -631,7 +628,7 @@ jobs:
-sim=<<parameters.sim>> \
-sim.loglevel=5 \
-docker.pull=true \
-client=go-ethereum,op-geth_optimism-history,op-proposer_<<parameters.version>>,op-batcher_<<parameters.version>>,op-node_<<parameters.version>>,op-contracts_<<parameters.version>> |& tee /tmp/hive.log
-client=go-ethereum,op-geth_optimism-history,op-proposer_<<parameters.version>>,op-batcher_<<parameters.version>>,op-node_<<parameters.version>> |& tee /tmp/hive.log
- run:
command: |
tar -cvf /tmp/workspace.tgz -C /home/circleci/project /home/circleci/project/workspace
......@@ -809,6 +806,17 @@ workflows:
- gcr
requires:
- contracts-bedrock-tests
- docker-publish:
name: contract-artifacts-bedrock-publish-dev
docker_file: ops/docker/Dockerfile.packages
docker_tags: us-central1-docker.pkg.dev/bedrock-goerli-development/images/contract-artifacts-bedrock:<<pipeline.git.revision>>
target: contract-artifacts-bedrock
docker_context: .
repo: us-central1-docker.pkg.dev
context:
- gcr
requires:
- contracts-bedrock-tests
- hive-test:
name: hive-test-rpc
version: <<pipeline.git.revision>>
......@@ -836,126 +844,3 @@ workflows:
- op-batcher-publish-dev
- op-proposer-publish-dev
- deployer-bedrock-publish-dev
nightly:
triggers:
- schedule:
cron: "0 10 * * *"
filters:
branches:
only:
- develop
jobs:
- yarn-monorepo
- docker-publish:
name: l2geth-release
docker_file: l2geth/Dockerfile
docker_tags: ethereumoptimism/l2geth:nightly
docker_context: .
context:
- optimism
- docker-publish:
name: gas-oracle-release
docker_file: gas-oracle/Dockerfile
docker_tags: ethereumoptimism/gas-oracle:nightly
docker_context: .
context:
- optimism
- docker-publish:
name: hardhat-node-release
docker_file: ops/docker/hardhat/Dockerfile
docker_tags: ethereumoptimism/hardhat-node:nightly
docker_context: ops/docker/hardhat
context:
- optimism
- docker-publish:
name: proxyd-release
docker_file: proxyd/Dockerfile
docker_tags: ethereumoptimism/proxyd:nightly
docker_context: .
context:
- optimism
- docker-publish:
name: l2geth-exporter-release
docker_file: l2geth-exporter/Dockerfile
docker_tags: ethereumoptimism/l2geth-exporter:nightly
docker_context: .
context:
- optimism
- docker-publish:
name: op-exporter-release
docker_file: op-exporter/Dockerfile
docker_tags: ethereumoptimism/op-exporter:nightly
docker_context: .
context:
- optimism
- docker-publish:
name: fault-detector-release
docker_file: ops/docker/Dockerfile.packages
docker_tags: ethereumoptimism/fault-detector:nightly
docker_context: .
target: fault-detector
context:
- optimism
- docker-publish:
name: drippie-mon-release
docker_file: ops/docker/Dockerfile.packages
docker_tags: ethereumoptimism/drippie-mon:nightly
docker_context: .
target: drippie-mon
context:
- optimism
- docker-publish:
name: message-relayer-release
docker_file: ops/docker/Dockerfile.packages
docker_tags: ethereumoptimism/message-relayer:nightly
docker_context: .
target: message-relayer
context:
- optimism
- docker-publish:
name: data-transport-layer-release
docker_file: ops/docker/Dockerfile.packages
docker_tags: ethereumoptimism/data-transport-layer:nightly
docker_context: .
target: data-transport-layer
context:
- optimism
- docker-publish:
name: integration-tests-release
docker_file: ops/docker/Dockerfile.packages
docker_tags: ethereumoptimism/integration-tests:nightly
docker_context: .
target: integration-tests
context:
- optimism
- docker-publish:
name: replica-healthcheck-release
docker_file: ops/docker/Dockerfile.packages
docker_tags: ethereumoptimism/replica-healthcheck:nightly
docker_context: .
target: replica-healthcheck
context:
- optimism
- docker-publish:
name: batch-submitter-service-release
docker_file: batch-submitter/Dockerfile
docker_tags: ethereumoptimism/batch-submitter-service:nightly
docker_context: .
context:
- optimism
- docker-publish:
name: indexer-release
docker_file: indexer/Dockerfile
docker_tags: ethereumoptimism/indexer:nightly
docker_context: .
context:
- optimism
- docker-publish:
name: teleportr-release
docker_file: teleportr/Dockerfile
docker_tags: ethereumoptimism/teleportr:nightly
docker_context: .
context:
- optimism
......@@ -134,7 +134,7 @@ jobs:
hardhat-node:
name: Publish Hardhat Node ${{ needs.release.outputs.hardhat-node }}
needs: release
if: needs.release.hardhat-node != ''
if: needs.release.outputs.hardhat-node != ''
runs-on: ubuntu-latest
steps:
- name: Checkout
......
......@@ -61,7 +61,7 @@ jobs:
if: failure()
uses: jwalton/gh-docker-logs@v1
with:
images: 'ethereumoptimism/hardhat,ethereumoptimism/deployer,ethereumoptimism/data-transport-layer,ethereumoptimism/l2geth,ethereumoptimism/message-relayer,ethereumoptimism/batch-submitter,ethereumoptimism/l2geth'
images: 'ethereumoptimism/hardhat-node,ethereumoptimism/deployer,ethereumoptimism/data-transport-layer,ethereumoptimism/l2geth,ethereumoptimism/message-relayer,ethereumoptimism/batch-submitter,ethereumoptimism/l2geth'
dest: './logs'
- name: Tar logs
......
......@@ -7,7 +7,7 @@ There are plenty of ways to contribute, in particular we appreciate support in t
- Reporting issues. For security issues see [Security policy](https://github.com/ethereum-optimism/.github/blob/master/SECURITY.md).
- Fixing and responding to existing issues. You can start off with those tagged ["good first issue"](https://github.com/ethereum-optimism/optimism/contribute) which are meant as introductory issues for external contributors.
- Improving the [community site](https://community.optimism.io/)[documentation](https://github.com/ethereum-optimism/community-hub) and [tutorials](https://github.com/ethereum-optimism/optimism-tutorial).
- Become an "Optimizer" and answer questions in the [Optimism Discord](https://discord.com/invite/jrnFEvq).
- Become an "Optimizer" and answer questions in the [Optimism Discord](https://discord.optimism.io).
- Get involved in the protocol design process by proposing changes or new features or write parts of the spec yourself in the [optimistic-specs repo](https://github.com/ethereum-optimism/optimistic-specs).
Note that we have a [Code of Conduct](https://github.com/ethereum-optimism/.github/blob/master/CODE_OF_CONDUCT.md), please follow it in all your interactions with the project.
......
......@@ -52,6 +52,7 @@ mod-tidy:
cd ./op-proposer && go mod tidy && cd .. && \
cd ./op-batcher && go mod tidy && cd .. && \
cd ./op-bindings && go mod tidy && cd .. && \
cd ./op-chain-ops && go mod tidy && cd .. && \
cd ./op-e2e && go mod tidy && cd ..
.PHONY: mod-tidy
......@@ -108,27 +109,5 @@ clean-node-modules:
tag-bedrock-go-modules:
@if [ -z "$(VERSION)" ]; then \
echo "You must specify a version."; \
exit 0; \
fi
@FIRST_CHAR=$(shell printf '%s' "$(VERSION)" | cut -c1); \
if [ "$$FIRST_CHAR" != "v" ]; then \
echo "Tag must start with v."; \
exit 0; \
fi
git tag "op-proposer/$(VERSION)"
git tag "op-node/$(VERSION)"
git tag "op-e2e/$(VERSION)"
git tag "op-bindings/$(VERSION)"
git tag "op-batcher/$(VERSION)"
git tag "op-service/$(VERSION)"
git push $(BEDROCK_TAGS_REMOTE) "op-proposer/$(VERSION)"
git push $(BEDROCK_TAGS_REMOTE) "op-node/$(VERSION)"
git push $(BEDROCK_TAGS_REMOTE) "op-e2e/$(VERSION)"
git push $(BEDROCK_TAGS_REMOTE) "op-bindings/$(VERSION)"
git push $(BEDROCK_TAGS_REMOTE) "op-batcher/$(VERSION)"
git push $(BEDROCK_TAGS_REMOTE) "op-service/$(VERSION)"
./ops/scripts/tag-bedrock-go-modules.sh $(BEDROCK_TAGS_REMOTE) $(VERSION)
.PHONY: tag-bedrock-go-modules
\ No newline at end of file
......@@ -209,9 +209,9 @@ func TestParsePrivateKeyStr(t *testing.T) {
}
// TestGetConfiguredPrivateKey asserts that GetConfiguredPrivateKey either:
// 1) Derives the correct private key assuming the BIP39 mnemonic and BIP32
// 1. Derives the correct private key assuming the BIP39 mnemonic and BIP32
// derivation path are both present and the private key string is omitted.
// 2) Parses the correct private key assuming only the private key string is
// 2. Parses the correct private key assuming only the private key string is
// present, but the BIP39 mnemonic and BIP32 derivation path are omitted.
func TestGetConfiguredPrivateKey(t *testing.T) {
tests := []struct {
......
......@@ -28,7 +28,7 @@ func L1EthClientWithTimeout(ctx context.Context, url string, disableHTTP2 bool)
TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
}
}
//nolint:staticcheck // Geth v1.10.23 uses rpc.DialOptions and rpc.WithClient, but we need to update geth first. Lint is flagged because of global go workspace usage.
rpcClient, err := rpc.DialHTTPWithClient(url, httpClient)
if err != nil {
return nil, err
......
......@@ -330,6 +330,7 @@ func waitMined(
// CalcGasFeeCap deterministically computes the recommended gas fee cap given
// the base fee and gasTipCap. The resulting gasFeeCap is equal to:
//
// gasTipCap + 2*baseFee.
func CalcGasFeeCap(baseFee, gasTipCap *big.Int) *big.Int {
return new(big.Int).Add(
......
......@@ -19,7 +19,7 @@ use (
./teleportr
)
replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/op-geth v0.0.0-20220819161933-acfde114de61
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220909213840-e6575c0168f1
// For local debugging:
//replace github.com/ethereum/go-ethereum v1.10.21 => ../go-ethereum
//replace github.com/ethereum/go-ethereum v1.10.23 => ../go-ethereum
......@@ -25,6 +25,8 @@ github.com/docker/docker v1.6.2/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsvi
github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/ethereum-optimism/op-geth v0.0.0-20220904174542-4311f9d2cead/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
github.com/ethereum-optimism/op-geth v0.0.0-20220906163738-712cb0a1c140/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8=
......
......@@ -193,10 +193,20 @@ func (d *Database) AddIndexedL1Block(block *IndexedL1Block) error {
const insertDepositStatement = `
INSERT INTO deposits
(guid, from_address, to_address, l1_token, l2_token, amount, tx_hash, log_index, block_hash, data)
(guid, from_address, to_address, l1_token, l2_token, amount, tx_hash, log_index, l1_block_hash, data)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
`
const insertWithdrawalStatement = `
INSERT INTO withdrawals
(guid, from_address, to_address, l1_token, l2_token, amount, tx_hash, log_index, l1_block_hash, data)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
ON CONFLICT (tx_hash)
DO UPDATE SET l1_block_hash = $9;
`
return txn(d.db, func(tx *sql.Tx) error {
_, err := tx.Exec(
insertBlockStatement,
......@@ -232,6 +242,29 @@ func (d *Database) AddIndexedL1Block(block *IndexedL1Block) error {
}
}
if len(block.Withdrawals) == 0 {
return nil
}
for _, withdrawal := range block.Withdrawals {
_, err = tx.Exec(
insertWithdrawalStatement,
NewGUID(),
withdrawal.FromAddress.String(),
withdrawal.ToAddress.String(),
withdrawal.L1Token.String(),
withdrawal.L2Token.String(),
withdrawal.Amount.String(),
withdrawal.TxHash.String(),
withdrawal.LogIndex,
block.Hash.String(),
withdrawal.Data,
)
if err != nil {
return err
}
}
return nil
})
}
......@@ -249,7 +282,7 @@ func (d *Database) AddIndexedL2Block(block *IndexedL2Block) error {
const insertWithdrawalStatement = `
INSERT INTO withdrawals
(guid, from_address, to_address, l1_token, l2_token, amount, tx_hash, log_index, block_hash, data)
(guid, from_address, to_address, l1_token, l2_token, amount, tx_hash, log_index, l2_block_hash, data)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
`
......@@ -292,36 +325,6 @@ func (d *Database) AddIndexedL2Block(block *IndexedL2Block) error {
})
}
// AddStateBatch inserts the state batches into the known state batches
// database.
func (d *Database) AddStateBatch(batches []StateBatch) error {
const insertStateBatchStatement = `
INSERT INTO state_batches
(index, root, size, prev_total, extra_data, block_hash)
VALUES
($1, $2, $3, $4, $5, $6)
`
return txn(d.db, func(tx *sql.Tx) error {
for _, sb := range batches {
_, err := tx.Exec(
insertStateBatchStatement,
sb.Index.Uint64(),
sb.Root.String(),
sb.Size.Uint64(),
sb.PrevTotal.Uint64(),
sb.ExtraData,
sb.BlockHash.String(),
)
if err != nil {
return err
}
}
return nil
})
}
// GetDepositsByAddress returns the list of Deposits indexed for the given
// address paginated by the given params.
func (d *Database) GetDepositsByAddress(address common.Address, page PaginationParam) (*PaginatedDeposits, error) {
......@@ -333,7 +336,7 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP
l1_tokens.name, l1_tokens.symbol, l1_tokens.decimals,
l1_blocks.number, l1_blocks.timestamp
FROM deposits
INNER JOIN l1_blocks ON deposits.block_hash=l1_blocks.hash
INNER JOIN l1_blocks ON deposits.l1_block_hash=l1_blocks.hash
INNER JOIN l1_tokens ON deposits.l1_token=l1_tokens.address
WHERE deposits.from_address = $1 ORDER BY l1_blocks.timestamp LIMIT $2 OFFSET $3;
`
......@@ -372,7 +375,7 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP
SELECT
count(*)
FROM deposits
INNER JOIN l1_blocks ON deposits.block_hash=l1_blocks.hash
INNER JOIN l1_blocks ON deposits.l1_block_hash=l1_blocks.hash
INNER JOIN l1_tokens ON deposits.l1_token=l1_tokens.address
WHERE deposits.from_address = $1;
`
......@@ -398,54 +401,43 @@ func (d *Database) GetDepositsByAddress(address common.Address, page PaginationP
}, nil
}
// GetWithdrawalBatch returns the StateBatch corresponding to the given
// withdrawal transaction hash.
func (d *Database) GetWithdrawalBatch(hash common.Hash) (*StateBatchJSON, error) {
const selectWithdrawalBatchStatement = `
SELECT
state_batches.index, state_batches.root, state_batches.size, state_batches.prev_total, state_batches.extra_data, state_batches.block_hash,
l1_blocks.number, l1_blocks.timestamp
FROM state_batches
INNER JOIN l1_blocks ON state_batches.block_hash = l1_blocks.hash
WHERE size + prev_total >= (
// GetWithdrawalStatus returns the finalization status corresponding to the
// given withdrawal transaction hash.
func (d *Database) GetWithdrawalStatus(hash common.Hash) (*WithdrawalJSON, error) {
const selectWithdrawalStatement = `
SELECT
number
FROM
withdrawals
INNER JOIN l2_blocks ON withdrawals.block_hash = l2_blocks.hash where tx_hash=$1
) ORDER BY "index" LIMIT 1;
withdrawals.guid, withdrawals.from_address, withdrawals.to_address,
withdrawals.amount, withdrawals.tx_hash, withdrawals.data,
withdrawals.l1_token, withdrawals.l2_token,
l2_tokens.name, l2_tokens.symbol, l2_tokens.decimals,
l1_blocks.number, l1_blocks.timestamp,
l2_blocks.number, l2_blocks.timestamp
FROM withdrawals
INNER JOIN l1_blocks ON withdrawals.l1_block_hash=l1_blocks.hash
INNER JOIN l2_blocks ON withdrawals.l2_block_hash=l2_blocks.hash
INNER JOIN l2_tokens ON withdrawals.l2_token=l2_tokens.address
WHERE withdrawals.tx_hash = $1;
`
var batch *StateBatchJSON
var withdrawal *WithdrawalJSON
err := txn(d.db, func(tx *sql.Tx) error {
row := tx.QueryRow(selectWithdrawalBatchStatement, hash.String())
row := tx.QueryRow(selectWithdrawalStatement, hash.String())
if row.Err() != nil {
return row.Err()
}
var index, size, prevTotal, blockNumber, blockTimestamp uint64
var root, blockHash string
var extraData []byte
err := row.Scan(&index, &root, &size, &prevTotal, &extraData, &blockHash,
&blockNumber, &blockTimestamp)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
batch = nil
return nil
}
var l2Token Token
if err := row.Scan(
&withdrawal.GUID, &withdrawal.FromAddress, &withdrawal.ToAddress,
&withdrawal.Amount, &withdrawal.TxHash, &withdrawal.Data,
&withdrawal.L1Token, &l2Token.Address,
&l2Token.Name, &l2Token.Symbol, &l2Token.Decimals,
&withdrawal.L1BlockNumber, &withdrawal.L1BlockTimestamp,
&withdrawal.L2BlockNumber, &withdrawal.L2BlockTimestamp,
); err != nil {
return err
}
batch = &StateBatchJSON{
Index: index,
Root: root,
Size: size,
PrevTotal: prevTotal,
ExtraData: extraData,
BlockHash: blockHash,
BlockNumber: blockNumber,
BlockTimestamp: blockTimestamp,
}
withdrawal.L2Token = &l2Token
return nil
})
......@@ -453,7 +445,7 @@ func (d *Database) GetWithdrawalBatch(hash common.Hash) (*StateBatchJSON, error)
return nil, err
}
return batch, nil
return withdrawal, nil
}
// GetWithdrawalsByAddress returns the list of Withdrawals indexed for the given
......@@ -467,7 +459,7 @@ func (d *Database) GetWithdrawalsByAddress(address common.Address, page Paginati
l2_tokens.name, l2_tokens.symbol, l2_tokens.decimals,
l2_blocks.number, l2_blocks.timestamp
FROM withdrawals
INNER JOIN l2_blocks ON withdrawals.block_hash=l2_blocks.hash
INNER JOIN l2_blocks ON withdrawals.l2_block_hash=l2_blocks.hash
INNER JOIN l2_tokens ON withdrawals.l2_token=l2_tokens.address
WHERE withdrawals.from_address = $1 ORDER BY l2_blocks.timestamp LIMIT $2 OFFSET $3;
`
......@@ -488,7 +480,7 @@ func (d *Database) GetWithdrawalsByAddress(address common.Address, page Paginati
&withdrawal.Amount, &withdrawal.TxHash, &withdrawal.Data,
&withdrawal.L1Token, &l2Token.Address,
&l2Token.Name, &l2Token.Symbol, &l2Token.Decimals,
&withdrawal.BlockNumber, &withdrawal.BlockTimestamp,
&withdrawal.L2BlockNumber, &withdrawal.L2BlockTimestamp,
); err != nil {
return err
}
......@@ -503,16 +495,11 @@ func (d *Database) GetWithdrawalsByAddress(address common.Address, page Paginati
return nil, err
}
for i := range withdrawals {
batch, _ := d.GetWithdrawalBatch(common.HexToHash(withdrawals[i].TxHash))
withdrawals[i].Batch = batch
}
const selectWithdrawalCountStatement = `
SELECT
count(*)
FROM withdrawals
INNER JOIN l2_blocks ON withdrawals.block_hash=l2_blocks.hash
INNER JOIN l2_blocks ON withdrawals.l2_block_hash=l2_blocks.hash
INNER JOIN l2_tokens ON withdrawals.l2_token=l2_tokens.address
WHERE withdrawals.from_address = $1;
`
......@@ -671,7 +658,7 @@ WHERE address = $1
func (d *Database) GetAirdrop(address common.Address) (*Airdrop, error) {
row := d.db.QueryRow(getAirdropQuery, strings.ToLower(address.String()))
if row.Err() != nil {
return nil, fmt.Errorf("error getting airdrop: %v", row.Err())
return nil, fmt.Errorf("error getting airdrop: %w", row.Err())
}
airdrop := new(Airdrop)
......@@ -690,7 +677,7 @@ func (d *Database) GetAirdrop(address common.Address) (*Airdrop, error) {
return nil, nil
}
if err != nil {
return nil, fmt.Errorf("error scanning airdrop: %v", err)
return nil, fmt.Errorf("error scanning airdrop: %w", err)
}
return airdrop, nil
}
......@@ -11,6 +11,7 @@ type IndexedL1Block struct {
Number uint64
Timestamp uint64
Deposits []Deposit
Withdrawals []Withdrawal
}
// String returns the block hash for the indexed l1 block.
......@@ -24,6 +25,7 @@ type IndexedL2Block struct {
ParentHash common.Hash
Number uint64
Timestamp uint64
Deposits []Deposit
Withdrawals []Withdrawal
}
......
......@@ -28,8 +28,10 @@ CREATE TABLE IF NOT EXISTS deposits (
amount VARCHAR NOT NULL,
data BYTEA NOT NULL,
log_index INTEGER NOT NULL,
block_hash VARCHAR NOT NULL REFERENCES l1_blocks(hash),
tx_hash VARCHAR NOT NULL
l1_block_hash VARCHAR NOT NULL REFERENCES l1_blocks(hash),
l2_block_hash VARCHAR REFERENCES l2_blocks(hash),
tx_hash VARCHAR NOT NULL,
failed BOOLEAN NOT NULL DEFAULT false
)
`
......@@ -51,20 +53,6 @@ CREATE TABLE IF NOT EXISTS l2_tokens (
)
`
const createStateBatchesTable = `
CREATE TABLE IF NOT EXISTS state_batches (
index INTEGER NOT NULL PRIMARY KEY,
root VARCHAR NOT NULL,
size INTEGER NOT NULL,
prev_total INTEGER NOT NULL,
extra_data BYTEA NOT NULL,
block_hash VARCHAR NOT NULL REFERENCES l1_blocks(hash)
);
CREATE INDEX IF NOT EXISTS state_batches_block_hash ON state_batches(block_hash);
CREATE INDEX IF NOT EXISTS state_batches_size ON state_batches(size);
CREATE INDEX IF NOT EXISTS state_batches_prev_total ON state_batches(prev_total);
`
const createWithdrawalsTable = `
CREATE TABLE IF NOT EXISTS withdrawals (
guid VARCHAR PRIMARY KEY NOT NULL,
......@@ -75,9 +63,9 @@ CREATE TABLE IF NOT EXISTS withdrawals (
amount VARCHAR NOT NULL,
data BYTEA NOT NULL,
log_index INTEGER NOT NULL,
block_hash VARCHAR NOT NULL REFERENCES l2_blocks(hash),
l1_block_hash VARCHAR REFERENCES l1_blocks(hash),
l2_block_hash VARCHAR NOT NULL REFERENCES l2_blocks(hash),
tx_hash VARCHAR NOT NULL,
state_batch INTEGER REFERENCES state_batches(index)
)
`
......@@ -127,7 +115,6 @@ var schema = []string{
createL2BlocksTable,
createL1TokensTable,
createL2TokensTable,
createStateBatchesTable,
insertETHL1Token,
insertETHL2Token,
createDepositsTable,
......
package db
import (
"math/big"
"github.com/ethereum/go-ethereum/common"
)
// StateBatch is the state batch containing merkle root of the withdrawals
// periodically written to L1.
type StateBatch struct {
Index *big.Int
Root common.Hash
Size *big.Int
PrevTotal *big.Int
ExtraData []byte
BlockHash common.Hash
}
// StateBatchJSON contains StateBatch data suitable for JSON serialization.
type StateBatchJSON struct {
Index uint64 `json:"index"`
Root string `json:"root"`
Size uint64 `json:"size"`
PrevTotal uint64 `json:"prevTotal"`
ExtraData []byte `json:"extraData"`
BlockHash string `json:"blockHash"`
BlockNumber uint64 `json:"blockNumber"`
BlockTimestamp uint64 `json:"blockTimestamp"`
}
......@@ -34,8 +34,9 @@ type WithdrawalJSON struct {
Amount string `json:"amount"`
Data []byte `json:"data"`
LogIndex uint64 `json:"logIndex"`
BlockNumber uint64 `json:"blockNumber"`
BlockTimestamp string `json:"blockTimestamp"`
L1BlockNumber uint64 `json:"l1BlockNumber"`
L1BlockTimestamp string `json:"l1BlockTimestamp"`
L2BlockNumber uint64 `json:"l2BlockNumber"`
L2BlockTimestamp string `json:"l2BlockTimestamp"`
TxHash string `json:"transactionHash"`
Batch *StateBatchJSON `json:"batch"`
}
......@@ -212,7 +212,7 @@ func (b *Indexer) Serve() error {
b.router.HandleFunc("/v1/l1/status", b.l1IndexingService.GetIndexerStatus).Methods("GET")
b.router.HandleFunc("/v1/l2/status", b.l2IndexingService.GetIndexerStatus).Methods("GET")
b.router.HandleFunc("/v1/deposits/0x{address:[a-fA-F0-9]{40}}", b.l1IndexingService.GetDeposits).Methods("GET")
b.router.HandleFunc("/v1/withdrawal/0x{hash:[a-fA-F0-9]{64}}", b.l2IndexingService.GetWithdrawalBatch).Methods("GET")
b.router.HandleFunc("/v1/withdrawal/0x{hash:[a-fA-F0-9]{64}}", b.l2IndexingService.GetWithdrawalStatus).Methods("GET")
b.router.HandleFunc("/v1/withdrawals/0x{address:[a-fA-F0-9]{40}}", b.l2IndexingService.GetWithdrawals).Methods("GET")
b.router.HandleFunc("/v1/airdrops/0x{address:[a-fA-F0-9]{40}}", b.airdropService.GetAirdrop)
b.router.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
......
......@@ -21,8 +21,6 @@ type Metrics struct {
WithdrawalsCount *prometheus.CounterVec
StateBatchesCount prometheus.Counter
L1CatchingUp prometheus.Gauge
L2CatchingUp prometheus.Gauge
......@@ -74,12 +72,6 @@ func NewMetrics(monitoredTokens map[string]string) *Metrics {
"symbol",
}),
StateBatchesCount: promauto.NewCounter(prometheus.CounterOpts{
Name: "state_batches_count",
Help: "The number of state batches indexed.",
Namespace: metricsNamespace,
}),
L1CatchingUp: promauto.NewGauge(prometheus.GaugeOpts{
Name: "l1_catching_up",
Help: "Whether or not L1 is far behind the chain tip.",
......@@ -168,10 +160,6 @@ func (m *Metrics) RecordWithdrawal(addr common.Address) {
m.WithdrawalsCount.WithLabelValues(sym).Inc()
}
func (m *Metrics) RecordStateBatches(count int) {
m.StateBatchesCount.Add(float64(count))
}
func (m *Metrics) SetL1CatchingUp(state bool) {
var catchingUp float64
if state {
......
......@@ -13,10 +13,12 @@ import (
)
type DepositsMap map[common.Hash][]db.Deposit
type WithdrawalsMap map[common.Hash][]db.Withdrawal // Finalizations
type Bridge interface {
Address() common.Address
GetDepositsByBlockRange(uint64, uint64) (DepositsMap, error)
GetWithdrawalsByBlockRange(uint64, uint64) (WithdrawalsMap, error)
String() string
}
......
......@@ -50,6 +50,36 @@ func (e *EthBridge) GetDepositsByBlockRange(start, end uint64) (DepositsMap, err
return depositsByBlockhash, nil
}
func (s *EthBridge) GetWithdrawalsByBlockRange(start, end uint64) (WithdrawalsMap, error) {
withdrawalsByBlockHash := make(WithdrawalsMap)
iter, err := FilterETHWithdrawalFinalizedWithRetry(s.ctx, s.filterer, &bind.FilterOpts{
Start: start,
End: &end,
})
if err != nil {
logger.Error("Error fetching filter", "err", err)
}
for iter.Next() {
withdrawalsByBlockHash[iter.Event.Raw.BlockHash] = append(
withdrawalsByBlockHash[iter.Event.Raw.BlockHash], db.Withdrawal{
TxHash: iter.Event.Raw.TxHash,
FromAddress: iter.Event.From,
ToAddress: iter.Event.To,
Amount: iter.Event.Amount,
Data: iter.Event.ExtraData,
LogIndex: iter.Event.Raw.Index,
})
}
if err := iter.Error(); err != nil {
return nil, err
}
return withdrawalsByBlockHash, nil
}
func (e *EthBridge) String() string {
return e.name
}
......@@ -43,3 +43,35 @@ func FilterERC20DepositInitiatedWithRetry(ctx context.Context, filterer *binding
time.Sleep(clientRetryInterval)
}
}
// FilterETHWithdrawalFinalizedWithRetry retries the given func until it succeeds,
// waiting for clientRetryInterval duration after every call.
func FilterETHWithdrawalFinalizedWithRetry(ctx context.Context, filterer *bindings.L1StandardBridgeFilterer, opts *bind.FilterOpts) (*bindings.L1StandardBridgeETHWithdrawalFinalizedIterator, error) {
for {
ctxt, cancel := context.WithTimeout(ctx, DefaultConnectionTimeout)
opts.Context = ctxt
res, err := filterer.FilterETHWithdrawalFinalized(opts, nil, nil)
cancel()
if err == nil {
return res, nil
}
logger.Error("Error fetching filter", "err", err)
time.Sleep(clientRetryInterval)
}
}
// FilterERC20WithdrawalFinalizedWithRetry retries the given func until it succeeds,
// waiting for clientRetryInterval duration after every call.
func FilterERC20WithdrawalFinalizedWithRetry(ctx context.Context, filterer *bindings.L1StandardBridgeFilterer, opts *bind.FilterOpts) (*bindings.L1StandardBridgeERC20WithdrawalFinalizedIterator, error) {
for {
ctxt, cancel := context.WithTimeout(ctx, DefaultConnectionTimeout)
opts.Context = ctxt
res, err := filterer.FilterERC20WithdrawalFinalized(opts, nil, nil, nil)
cancel()
if err == nil {
return res, nil
}
logger.Error("Error fetching filter", "err", err)
time.Sleep(clientRetryInterval)
}
}
......@@ -52,6 +52,38 @@ func (s *StandardBridge) GetDepositsByBlockRange(start, end uint64) (DepositsMap
return depositsByBlockhash, nil
}
func (s *StandardBridge) GetWithdrawalsByBlockRange(start, end uint64) (WithdrawalsMap, error) {
withdrawalsByBlockHash := make(WithdrawalsMap)
iter, err := FilterERC20WithdrawalFinalizedWithRetry(s.ctx, s.filterer, &bind.FilterOpts{
Start: start,
End: &end,
})
if err != nil {
logger.Error("Error fetching filter", "err", err)
}
for iter.Next() {
withdrawalsByBlockHash[iter.Event.Raw.BlockHash] = append(
withdrawalsByBlockHash[iter.Event.Raw.BlockHash], db.Withdrawal{
TxHash: iter.Event.Raw.TxHash,
L1Token: iter.Event.L1Token,
L2Token: iter.Event.L2Token,
FromAddress: iter.Event.From,
ToAddress: iter.Event.To,
Amount: iter.Event.Amount,
Data: iter.Event.ExtraData,
LogIndex: iter.Event.Raw.Index,
})
}
if err := iter.Error(); err != nil {
return nil, err
}
return withdrawalsByBlockHash, nil
}
func (s *StandardBridge) String() string {
return s.name
}
......@@ -219,6 +219,7 @@ func (s *Service) Update(newHeader *types.Header) error {
startHeight := headers[0].Number.Uint64()
endHeight := headers[len(headers)-1].Number.Uint64()
depositsByBlockHash := make(map[common.Hash][]db.Deposit)
withdrawalsByBlockHash := make(map[common.Hash][]db.Withdrawal)
start := prometheus.NewTimer(s.metrics.UpdateDuration.WithLabelValues("l1"))
defer func() {
......@@ -227,6 +228,7 @@ func (s *Service) Update(newHeader *types.Header) error {
}()
bridgeDepositsCh := make(chan bridge.DepositsMap, len(s.bridges))
bridgeWdsCh := make(chan bridge.WithdrawalsMap, len(s.bridges))
errCh := make(chan error, len(s.bridges))
for _, bridgeImpl := range s.bridges {
......@@ -238,6 +240,14 @@ func (s *Service) Update(newHeader *types.Header) error {
}
bridgeDepositsCh <- deposits
}(bridgeImpl)
go func(b bridge.Bridge) {
withdrawals, err := b.GetWithdrawalsByBlockRange(startHeight, endHeight)
if err != nil {
errCh <- err
return
}
bridgeWdsCh <- withdrawals
}(bridgeImpl)
}
var receives int
......@@ -246,13 +256,23 @@ func (s *Service) Update(newHeader *types.Header) error {
case bridgeDeposits := <-bridgeDepositsCh:
for blockHash, deposits := range bridgeDeposits {
for _, deposit := range deposits {
if err := s.cacheToken(deposit); err != nil {
if err := s.cacheToken(deposit.L1Token); err != nil {
logger.Warn("error caching token", "err", err)
}
}
depositsByBlockHash[blockHash] = append(depositsByBlockHash[blockHash], deposits...)
}
case bridgeWithdrawals := <-bridgeWdsCh:
for blockHash, withdrawals := range bridgeWithdrawals {
for _, withdrawal := range withdrawals {
if err := s.cacheToken(withdrawal.L1Token); err != nil {
logger.Warn("error caching token", "err", err)
}
}
withdrawalsByBlockHash[blockHash] = append(withdrawalsByBlockHash[blockHash], withdrawals...)
}
case err := <-errCh:
return err
}
......@@ -263,6 +283,51 @@ func (s *Service) Update(newHeader *types.Header) error {
}
}
for i, header := range headers {
blockHash := header.Hash
number := header.Number.Uint64()
deposits := depositsByBlockHash[blockHash]
withdrawals := withdrawalsByBlockHash[blockHash]
if len(deposits) == 0 && len(withdrawals) == 0 && i != len(headers)-1 {
continue
}
block := &db.IndexedL1Block{
Hash: blockHash,
ParentHash: header.ParentHash,
Number: number,
Timestamp: header.Time,
Deposits: deposits,
Withdrawals: withdrawals,
}
err := s.cfg.DB.AddIndexedL1Block(block)
if err != nil {
logger.Error(
"Unable to import ",
"block", number,
"hash", blockHash,
"err", err,
"block", block,
)
return err
}
logger.Debug("Imported ",
"block", number, "hash", blockHash, "deposits", len(block.Deposits))
for _, deposit := range block.Deposits {
token := s.tokenCache[deposit.L2Token]
logger.Info(
"indexed deposit ",
"tx_hash", deposit.TxHash,
"symbol", token.Symbol,
"amount", deposit.Amount,
)
s.metrics.RecordDeposit(deposit.L2Token)
}
}
newHeaderNumber := newHeader.Number.Uint64()
s.metrics.SetL1SyncHeight(endHeight)
s.metrics.SetL1SyncPercent(endHeight, newHeaderNumber)
......@@ -388,33 +453,33 @@ func (s *Service) catchUp(ctx context.Context) error {
return nil
}
func (s *Service) cacheToken(deposit db.Deposit) error {
if s.tokenCache[deposit.L1Token] != nil {
func (s *Service) cacheToken(address common.Address) error {
if s.tokenCache[address] != nil {
return nil
}
token, err := s.cfg.DB.GetL1TokenByAddress(deposit.L1Token.String())
token, err := s.cfg.DB.GetL1TokenByAddress(address.String())
if err != nil {
return err
}
if token != nil {
s.metrics.IncL1CachedTokensCount()
s.tokenCache[deposit.L1Token] = token
s.tokenCache[address] = token
return nil
}
token, err = QueryERC20(deposit.L1Token, s.cfg.L1Client)
token, err = QueryERC20(address, s.cfg.L1Client)
if err != nil {
logger.Error("Error querying ERC20 token details",
"l1_token", deposit.L1Token.String(), "err", err)
"l1_token", address.String(), "err", err)
token = &db.Token{
Address: deposit.L1Token.String(),
Address: address.String(),
}
}
if err := s.cfg.DB.AddL1Token(deposit.L1Token.String(), token); err != nil {
if err := s.cfg.DB.AddL1Token(address.String(), token); err != nil {
return err
}
s.tokenCache[deposit.L1Token] = token
s.tokenCache[address] = token
s.metrics.IncL1CachedTokensCount()
return nil
}
......
......@@ -12,10 +12,12 @@ import (
"github.com/ethereum/go-ethereum/common"
)
type DepositsMap map[common.Hash][]db.Deposit // Finalizations
type WithdrawalsMap map[common.Hash][]db.Withdrawal
type Bridge interface {
Address() common.Address
GetDepositsByBlockRange(uint64, uint64) (DepositsMap, error)
GetWithdrawalsByBlockRange(uint64, uint64) (WithdrawalsMap, error)
String() string
}
......
......@@ -27,3 +27,35 @@ func FilterWithdrawalInitiatedWithRetry(ctx context.Context, filterer *bindings.
time.Sleep(clientRetryInterval)
}
}
// FilterDepositFinalizedWithRetry retries the given func until it succeeds,
// waiting for clientRetryInterval duration after every call.
func FilterDepositFinalizedWithRetry(ctx context.Context, filterer *bindings.L2StandardBridgeFilterer, opts *bind.FilterOpts) (*bindings.L2StandardBridgeDepositFinalizedIterator, error) {
for {
ctxt, cancel := context.WithTimeout(ctx, DefaultConnectionTimeout)
opts.Context = ctxt
res, err := filterer.FilterDepositFinalized(opts, nil, nil, nil)
cancel()
if err == nil {
return res, nil
}
logger.Error("Error fetching filter", "err", err)
time.Sleep(clientRetryInterval)
}
}
// FilterDepositFailedWithRetry retries the given func until it succeeds,
// waiting for clientRetryInterval duration after every call.
func FilterDepositFailedWithRetry(ctx context.Context, filterer *bindings.L2StandardBridgeFilterer, opts *bind.FilterOpts) (*bindings.L2StandardBridgeDepositFailedIterator, error) {
for {
ctxt, cancel := context.WithTimeout(ctx, DefaultConnectionTimeout)
opts.Context = ctxt
res, err := filterer.FilterDepositFailed(opts, nil, nil, nil)
cancel()
if err == nil {
return res, nil
}
logger.Error("Error fetching filter", "err", err)
time.Sleep(clientRetryInterval)
}
}
......@@ -22,6 +22,37 @@ func (s *StandardBridge) Address() common.Address {
return s.address
}
func (s *StandardBridge) GetDepositsByBlockRange(start, end uint64) (DepositsMap, error) {
depositsByBlockhash := make(DepositsMap)
iter, err := FilterDepositFinalizedWithRetry(s.ctx, s.filterer, &bind.FilterOpts{
Start: start,
End: &end,
})
if err != nil {
logger.Error("Error fetching filter", "err", err)
}
for iter.Next() {
depositsByBlockhash[iter.Event.Raw.BlockHash] = append(
depositsByBlockhash[iter.Event.Raw.BlockHash], db.Deposit{
TxHash: iter.Event.Raw.TxHash,
L1Token: iter.Event.L1Token,
L2Token: iter.Event.L2Token,
FromAddress: iter.Event.From,
ToAddress: iter.Event.To,
Amount: iter.Event.Amount,
Data: iter.Event.ExtraData,
LogIndex: iter.Event.Raw.Index,
})
}
if err := iter.Error(); err != nil {
return nil, err
}
return depositsByBlockhash, nil
}
func (s *StandardBridge) GetWithdrawalsByBlockRange(start, end uint64) (WithdrawalsMap, error) {
withdrawalsByBlockhash := make(map[common.Hash][]db.Withdrawal)
......
......@@ -218,6 +218,7 @@ func (s *Service) Update(newHeader *types.Header) error {
startHeight := headers[0].Number.Uint64()
endHeight := headers[len(headers)-1].Number.Uint64()
depositsByBlockHash := make(map[common.Hash][]db.Deposit)
withdrawalsByBlockHash := make(map[common.Hash][]db.Withdrawal)
start := prometheus.NewTimer(s.metrics.UpdateDuration.WithLabelValues("l2"))
......@@ -226,10 +227,19 @@ func (s *Service) Update(newHeader *types.Header) error {
logger.Info("updated index", "start_height", startHeight, "end_height", endHeight, "duration", dur)
}()
bridgeDepositsCh := make(chan bridge.DepositsMap, len(s.bridges))
bridgeWdsCh := make(chan bridge.WithdrawalsMap)
errCh := make(chan error, len(s.bridges))
for _, bridgeImpl := range s.bridges {
go func(b bridge.Bridge) {
deposits, err := b.GetDepositsByBlockRange(startHeight, endHeight)
if err != nil {
errCh <- err
return
}
bridgeDepositsCh <- deposits
}(bridgeImpl)
go func(b bridge.Bridge) {
wds, err := b.GetWithdrawalsByBlockRange(startHeight, endHeight)
if err != nil {
......@@ -246,13 +256,23 @@ func (s *Service) Update(newHeader *types.Header) error {
case bridgeWds := <-bridgeWdsCh:
for blockHash, withdrawals := range bridgeWds {
for _, wd := range withdrawals {
if err := s.cacheToken(wd); err != nil {
if err := s.cacheToken(wd.L2Token); err != nil {
logger.Warn("error caching token", "err", err)
}
}
withdrawalsByBlockHash[blockHash] = append(withdrawalsByBlockHash[blockHash], withdrawals...)
}
case bridgeDeposits := <-bridgeDepositsCh:
for blockHash, deposits := range bridgeDeposits {
for _, deposit := range deposits {
if err := s.cacheToken(deposit.L2Token); err != nil {
logger.Warn("error caching token", "err", err)
}
}
depositsByBlockHash[blockHash] = append(depositsByBlockHash[blockHash], deposits...)
}
case err := <-errCh:
return err
}
......@@ -266,6 +286,7 @@ func (s *Service) Update(newHeader *types.Header) error {
for i, header := range headers {
blockHash := header.Hash()
number := header.Number.Uint64()
deposits := depositsByBlockHash[blockHash]
withdrawals := withdrawalsByBlockHash[blockHash]
if len(withdrawals) == 0 && i != len(headers)-1 {
......@@ -277,6 +298,7 @@ func (s *Service) Update(newHeader *types.Header) error {
ParentHash: header.ParentHash,
Number: number,
Timestamp: header.Time,
Deposits: deposits,
Withdrawals: withdrawals,
}
......@@ -336,16 +358,16 @@ func (s *Service) GetIndexerStatus(w http.ResponseWriter, r *http.Request) {
server.RespondWithJSON(w, http.StatusOK, status)
}
func (s *Service) GetWithdrawalBatch(w http.ResponseWriter, r *http.Request) {
func (s *Service) GetWithdrawalStatus(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
batch, err := s.cfg.DB.GetWithdrawalBatch(common.HexToHash(vars["hash"]))
withdrawal, err := s.cfg.DB.GetWithdrawalStatus(common.HexToHash(vars["hash"]))
if err != nil {
server.RespondWithError(w, http.StatusInternalServerError, err.Error())
return
}
server.RespondWithJSON(w, http.StatusOK, batch)
server.RespondWithJSON(w, http.StatusOK, withdrawal)
}
func (s *Service) GetWithdrawals(w http.ResponseWriter, r *http.Request) {
......@@ -443,32 +465,32 @@ func (s *Service) catchUp(ctx context.Context) error {
return nil
}
func (s *Service) cacheToken(withdrawal db.Withdrawal) error {
if s.tokenCache[withdrawal.L2Token] != nil {
func (s *Service) cacheToken(address common.Address) error {
if s.tokenCache[address] != nil {
return nil
}
token, err := s.cfg.DB.GetL2TokenByAddress(withdrawal.L2Token.String())
token, err := s.cfg.DB.GetL2TokenByAddress(address.String())
if err != nil {
return err
}
if token != nil {
s.metrics.IncL2CachedTokensCount()
s.tokenCache[withdrawal.L2Token] = token
s.tokenCache[address] = token
return nil
}
token, err = QueryERC20(withdrawal.L2Token, s.cfg.L2Client)
token, err = QueryERC20(address, s.cfg.L2Client)
if err != nil {
logger.Error("Error querying ERC20 token details",
"l2_token", withdrawal.L2Token.String(), "err", err)
"l2_token", address.String(), "err", err)
token = &db.Token{
Address: withdrawal.L2Token.String(),
Address: address.String(),
}
}
if err := s.cfg.DB.AddL2Token(withdrawal.L2Token.String(), token); err != nil {
if err := s.cfg.DB.AddL2Token(address.String(), token); err != nil {
return err
}
s.tokenCache[withdrawal.L2Token] = token
s.tokenCache[address] = token
s.metrics.IncL2CachedTokensCount()
return nil
}
......
......@@ -1062,9 +1062,12 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
// EstimateGas returns an estimate of the amount of gas needed to execute the
// given transaction against the current pending block. This is modified to
// encode the fee in wei as gas price is always 1
func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (hexutil.Uint64, error) {
blockNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
return DoEstimateGas(ctx, s.b, args, blockNrOrHash, s.b.RPCGasCap())
func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) {
bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
if blockNrOrHash != nil {
bNrOrHash = *blockNrOrHash
}
return DoEstimateGas(ctx, s.b, args, bNrOrHash, s.b.RPCGasCap())
}
// ExecutionResult groups all structured logs emitted by the EVM
......
......@@ -17,7 +17,7 @@ test:
go test -v ./...
lint:
golangci-lint run -E asciicheck,goimports,misspell ./...
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint -e "errors.As" -e "errors.Is"
.PHONY: \
op-batcher \
......
......@@ -284,7 +284,11 @@ mainLoop:
l.log.Warn("issue fetching L2 head", "err", err)
continue
}
l.log.Info("Got new L2 sync status", "safe_head", syncStatus.SafeL2, "unsafe_head", syncStatus.UnsafeL2, "last_submitted", l.lastSubmittedBlock)
if syncStatus.HeadL1 == (eth.L1BlockRef{}) {
l.log.Info("Rollup node has no L1 head info yet")
continue
}
l.log.Info("Got new L2 sync status", "safe_head", syncStatus.SafeL2, "unsafe_head", syncStatus.UnsafeL2, "last_submitted", l.lastSubmittedBlock, "l1_head", syncStatus.HeadL1)
if syncStatus.SafeL2.Number >= syncStatus.UnsafeL2.Number {
l.log.Trace("No unsubmitted blocks from sequencer")
continue
......@@ -299,7 +303,7 @@ mainLoop:
l.log.Warn("last submitted block lagged behind L2 safe head: batch submission will continue from the safe head now", "last", l.lastSubmittedBlock, "safe", syncStatus.SafeL2)
l.lastSubmittedBlock = syncStatus.SafeL2.ID()
}
if ch, err := derive.NewChannelOut(syncStatus.HeadL1.Time); err != nil {
if ch, err := derive.NewChannelOut(); err != nil {
l.log.Error("Error creating channel", "err", err)
continue
} else {
......
......@@ -3,10 +3,10 @@ module github.com/ethereum-optimism/optimism/op-batcher
go 1.18
require (
github.com/ethereum-optimism/optimism/op-node v0.5.0
github.com/ethereum-optimism/optimism/op-proposer v0.5.0
github.com/ethereum-optimism/optimism/op-service v0.5.0
github.com/ethereum/go-ethereum v1.10.21
github.com/ethereum-optimism/optimism/op-node v0.8.6
github.com/ethereum-optimism/optimism/op-proposer v0.8.6
github.com/ethereum-optimism/optimism/op-service v0.8.6
github.com/ethereum/go-ethereum v1.10.23
github.com/miguelmota/go-ethereum-hdwallet v0.1.1
github.com/urfave/cli v1.22.9
)
......@@ -22,7 +22,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/ethereum-optimism/optimism/op-bindings v0.5.0 // indirect
github.com/ethereum-optimism/optimism/op-bindings v0.8.6 // indirect
github.com/fjl/memsize v0.0.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-stack/stack v1.8.1 // indirect
......@@ -70,4 +70,4 @@ require (
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
)
replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/op-geth v0.0.0-20220819161933-acfde114de61
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220909213840-e6575c0168f1
......@@ -147,16 +147,16 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum-optimism/op-geth v0.0.0-20220819161933-acfde114de61 h1:+WfrwiRELp3hoeb1bnPws3FtUUoYCDDYsCkwvKek5FY=
github.com/ethereum-optimism/op-geth v0.0.0-20220819161933-acfde114de61/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
github.com/ethereum-optimism/optimism/op-bindings v0.5.0 h1:bJT8KmDu5YAVOqPQHxHkntGlRrtRdTIsH+X28LOIcqU=
github.com/ethereum-optimism/optimism/op-bindings v0.5.0/go.mod h1:Ft+sL57mlBysH6nuXZA11GLMMajfBa8SjpEBtitl1Vw=
github.com/ethereum-optimism/optimism/op-node v0.5.0 h1:MwNvYDBFS4quSWkEzfJBGJkzI1yveqQ/GuVK6aTJJ0A=
github.com/ethereum-optimism/optimism/op-node v0.5.0/go.mod h1:jzsaU998O9OISO7ybwpKKm01pQZFpydRPSXP9+U8MYA=
github.com/ethereum-optimism/optimism/op-proposer v0.5.0 h1:GHU2ldpH22/Nv8ZwLmoR5tQChm1yYzoMuExKlb4EazM=
github.com/ethereum-optimism/optimism/op-proposer v0.5.0/go.mod h1:WgjPZHTHuiFoA0rATQJ2vCr7sbM/NgdvJMeCfkh2YIY=
github.com/ethereum-optimism/optimism/op-service v0.5.0 h1:D0OyBbRGttT3geECT935W4DPhbVAibPWZAayWpEd+e4=
github.com/ethereum-optimism/optimism/op-service v0.5.0/go.mod h1:otr/BXzgcZmJKUl18v+WLJjtWoIwqoJ/L0/cNvIIkUs=
github.com/ethereum-optimism/op-geth v0.0.0-20220909213840-e6575c0168f1 h1:W/ZU6BZH7ilTrpdoJOF9N4OReqXbpeRtUB6klIpEdMA=
github.com/ethereum-optimism/op-geth v0.0.0-20220909213840-e6575c0168f1/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/ethereum-optimism/optimism/op-bindings v0.8.6 h1:jJYhmygt7hqGzYa+8sme9SdnKt1c3Y6EbWgIrRONoxw=
github.com/ethereum-optimism/optimism/op-bindings v0.8.6/go.mod h1:gUX5317IAvRMjB4GftayM87JVln3DTqukfirwJpEWnE=
github.com/ethereum-optimism/optimism/op-node v0.8.6 h1:xNwN+Q/Rt17vSKawhBeG9qTcqcyh8JU8PGjK1iuGkF4=
github.com/ethereum-optimism/optimism/op-node v0.8.6/go.mod h1:gkyzgVHV3+tIhLZ8GhT+bL9GrrmouQCW4mKYukS0SHg=
github.com/ethereum-optimism/optimism/op-proposer v0.8.6 h1:iy8XAtkvrURBy3TT2Lf540cbWztxit7K4+BghZ4IsMI=
github.com/ethereum-optimism/optimism/op-proposer v0.8.6/go.mod h1:tuCLnXcO4MrtVyis1Yfo7wtL8EQta1u6zFdzHHj+RAc=
github.com/ethereum-optimism/optimism/op-service v0.8.6 h1:ruZp/BxL8TGn1y9EJmygypPTeVAFlAA0A/h8LsCoV+M=
github.com/ethereum-optimism/optimism/op-service v0.8.6/go.mod h1:gm8YNzERrL/CHBPWx3+01mR/NOVpLLw4GEUSnnTdyFU=
github.com/ethereum/go-ethereum v1.10.4/go.mod h1:nEE0TP5MtxGzOMd7egIrbPJMQBnhVU3ELNxhBglIzhg=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
......
......@@ -2,9 +2,10 @@ SHELL := /bin/bash
pkg := bindings
all: mkdir bindings deployed
all: mkdir bindings more
bindings: l1block-bindings \
l1-cross-domain-messenger-bindings \
l1-standard-bridge-bindings \
l2-to-l1-message-passer-bindings \
optimism-portal-bindings \
......@@ -16,70 +17,78 @@ bindings: l1block-bindings \
sequencer-fee-vault-bindings \
optimism-mintable-erc20-factory-bindings \
optimism-mintable-erc20-bindings \
proxy-bindings \
proxy-admin-bindings \
erc20-bindings \
weth9-bindings
deployed: l1-block-deployed \
optimism-portal-deployed \
l2-to-l1-message-passer-deployed \
gas-price-oracle-deployed
compile:
cd ../packages/contracts-bedrock/ && \
forge build -o ./tmp-artifacts
l1-block-deployed: l1block-bindings
./gen_deployed_bytecode.sh L1Block $(pkg)
l1-cross-domain-messenger-bindings: compile
./gen_bindings.sh contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger $(pkg)
l1-standard-bridge-bindings:
l1-standard-bridge-bindings: compile
./gen_bindings.sh contracts/L1/L1StandardBridge.sol:L1StandardBridge $(pkg)
optimism-portal-deployed: optimism-portal-bindings
./gen_deployed_bytecode.sh OptimismPortal $(pkg)
l2-to-l1-message-passer-deployed: l2-to-l1-message-passer-bindings
./gen_deployed_bytecode.sh L2ToL1MessagePasser $(pkg)
gas-price-oracle-deployed: gas-price-oracle-bindings
./gen_deployed_bytecode.sh GasPriceOracle $(pkg)
optimism-portal-bindings:
optimism-portal-bindings: compile
./gen_bindings.sh contracts/L1/OptimismPortal.sol:OptimismPortal $(pkg)
l2-output-oracle-bindings:
l2-output-oracle-bindings: compile
./gen_bindings.sh contracts/L1/L2OutputOracle.sol:L2OutputOracle $(pkg)
address-manager-bindings:
address-manager-bindings: compile
./gen_bindings.sh contracts/legacy/AddressManager.sol:AddressManager $(pkg)
l1block-bindings:
l1block-bindings: compile
./gen_bindings.sh contracts/L2/L1Block.sol:L1Block $(pkg)
l2-to-l1-message-passer-bindings:
l2-to-l1-message-passer-bindings: compile
./gen_bindings.sh contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser $(pkg)
gas-price-oracle-bindings:
gas-price-oracle-bindings: compile
./gen_bindings.sh contracts/L2/GasPriceOracle.sol:GasPriceOracle $(pkg)
l2-cross-domain-messenger-bindings:
l2-cross-domain-messenger-bindings: compile
./gen_bindings.sh contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger $(pkg)
l2-standard-bridge-bindings:
l2-standard-bridge-bindings: compile
./gen_bindings.sh contracts/L2/L2StandardBridge.sol:L2StandardBridge $(pkg)
sequencer-fee-vault-bindings:
sequencer-fee-vault-bindings: compile
./gen_bindings.sh contracts/L2/SequencerFeeVault.sol:SequencerFeeVault $(pkg)
optimism-mintable-erc20-factory-bindings:
optimism-mintable-erc20-factory-bindings: compile
./gen_bindings.sh contracts/universal/OptimismMintableERC20Factory.sol:OptimismMintableERC20Factory $(pkg)
optimism-mintable-erc20-bindings:
optimism-mintable-erc20-bindings: compile
./gen_bindings.sh contracts/universal/OptimismMintableERC20.sol:OptimismMintableERC20 $(pkg)
erc20-bindings:
proxy-bindings: compile
./gen_bindings.sh contracts/universal/Proxy.sol:Proxy $(pkg)
proxy-admin-bindings: compile
./gen_bindings.sh contracts/universal/ProxyAdmin.sol:ProxyAdmin $(pkg)
erc20-bindings: compile
./gen_bindings.sh ERC20 $(pkg)
weth9-bindings:
weth9-bindings: compile
./gen_bindings.sh contracts/vendor/WETH9.sol:WETH9 $(pkg)
more:
go run ./gen/main.go \
-artifacts ../packages/contracts-bedrock/artifacts,../packages/contracts-governance/artifacts \
-out ./bindings \
-contracts OptimismMintableERC20Factory,L2StandardBridge,L1BlockNumber,DeployerWhitelist,Proxy,OptimismPortal,L2ToL1MessagePasser,L2CrossDomainMessenger,GasPriceOracle,SequencerFeeVault,L1Block,LegacyERC20ETH,WETH9,GovernanceToken \
-package bindings
mkdir:
mkdir -p bin $(pkg)
clean:
rm -rf bin $(pkg)
test:
go test ./...
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const DeployerWhitelistStorageLayoutJSON = "{\"storage\":[{\"astId\":2700,\"contract\":\"contracts/legacy/DeployerWhitelist.sol:DeployerWhitelist\",\"label\":\"owner\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":2705,\"contract\":\"contracts/legacy/DeployerWhitelist.sol:DeployerWhitelist\",\"label\":\"whitelist\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_bool)\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_mapping(t_address,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_bool\"}}}"
var DeployerWhitelistStorageLayout = new(solc.StorageLayout)
var DeployerWhitelistDeployedBin = "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80638da5cb5b1161005b5780638da5cb5b146100c85780639b19251a1461010d578063b1540a0114610140578063bdc7b54f1461015357600080fd5b806308fd63221461008257806313af40351461009757806354fd4d50146100aa575b600080fd5b61009561009036600461088a565b61015b565b005b6100956100a53660046108c6565b6102bb565b6100b26104ec565b6040516100bf9190610918565b60405180910390f35b6000546100e89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100bf565b61013061011b3660046108c6565b60016020526000908152604090205460ff1681565b60405190151581526020016100bf565b61013061014e3660046108c6565b61058f565b6100956105e0565b60005473ffffffffffffffffffffffffffffffffffffffff16331461022d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f4465706c6f79657257686974656c6973743a2066756e6374696f6e2063616e2060448201527f6f6e6c792062652063616c6c656420627920746865206f776e6572206f66207460648201527f68697320636f6e74726163740000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526001602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515159081179091558251938452908301527f8daaf060c3306c38e068a75c054bf96ecd85a3db1252712c4d93632744c42e0d910160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610388576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f4465706c6f79657257686974656c6973743a2066756e6374696f6e2063616e2060448201527f6f6e6c792062652063616c6c656420627920746865206f776e6572206f66207460648201527f68697320636f6e74726163740000000000000000000000000000000000000000608482015260a401610224565b73ffffffffffffffffffffffffffffffffffffffff8116610451576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f4465706c6f79657257686974656c6973743a2063616e206f6e6c79206265206460448201527f697361626c65642076696120656e61626c65417262697472617279436f6e747260648201527f6163744465706c6f796d656e7400000000000000000000000000000000000000608482015260a401610224565b6000546040805173ffffffffffffffffffffffffffffffffffffffff928316815291831660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60606105177f0000000000000000000000000000000000000000000000000000000000000000610724565b6105407f0000000000000000000000000000000000000000000000000000000000000000610724565b6105697f0000000000000000000000000000000000000000000000000000000000000000610724565b60405160200161057b93929190610969565b604051602081830303815290604052905090565b6000805473ffffffffffffffffffffffffffffffffffffffff1615806105da575073ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090205460ff165b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f4465706c6f79657257686974656c6973743a2066756e6374696f6e2063616e2060448201527f6f6e6c792062652063616c6c656420627920746865206f776e6572206f66207460648201527f68697320636f6e74726163740000000000000000000000000000000000000000608482015260a401610224565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681527fc0e106cf568e50698fdbde1eff56f5a5c966cc7958e37e276918e9e4ccdf8cd49060200160405180910390a1600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b60608160000361076757505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610791578061077b81610a0e565b915061078a9050600a83610a75565b915061076b565b60008167ffffffffffffffff8111156107ac576107ac610a89565b6040519080825280601f01601f1916602001820160405280156107d6576020820181803683370190505b5090505b8415610859576107eb600183610ab8565b91506107f8600a86610acf565b610803906030610ae3565b60f81b81838151811061081857610818610afb565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610852600a86610a75565b94506107da565b949350505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461088557600080fd5b919050565b6000806040838503121561089d57600080fd5b6108a683610861565b9150602083013580151581146108bb57600080fd5b809150509250929050565b6000602082840312156108d857600080fd5b6108e182610861565b9392505050565b60005b838110156109035781810151838201526020016108eb565b83811115610912576000848401525b50505050565b60208152600082518060208401526109378160408501602087016108e8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000845161097b8184602089016108e8565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516109b7816001850160208a016108e8565b600192019182015283516109d28160028401602088016108e8565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a3f57610a3f6109df565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610a8457610a84610a46565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082821015610aca57610aca6109df565b500390565b600082610ade57610ade610a46565b500690565b60008219821115610af657610af66109df565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(DeployerWhitelistStorageLayoutJSON), DeployerWhitelistStorageLayout); err != nil {
panic(err)
}
layouts["DeployerWhitelist"] = DeployerWhitelistStorageLayout
deployedBytecodes["DeployerWhitelist"] = DeployerWhitelistDeployedBin
}
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const GasPriceOracleStorageLayoutJSON = "{\"storage\":[{\"astId\":26690,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1663,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"spacer0\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":1666,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"spacer1\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":1669,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"overhead\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_uint256\"},{\"astId\":1672,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"scalar\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_uint256\"},{\"astId\":1675,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"decimals\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_uint256\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var GasPriceOracleStorageLayout = new(solc.StorageLayout)
var GasPriceOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80637046559711610097578063de26c4a111610066578063de26c4a1146101c0578063f2fde38b146101d3578063f45e65d8146101e6578063fe173b971461016457600080fd5b8063704655971461016a578063715018a61461017d5780638c8885c8146101855780638da5cb5b1461019857600080fd5b806349948e0e116100d357806349948e0e14610134578063519b4bd31461014757806354fd4d501461014f5780636ef25c3a1461016457600080fd5b80630c18c162146100fa578063313ce567146101165780633577afc51461011f575b600080fd5b61010360035481565b6040519081526020015b60405180910390f35b61010360055481565b61013261012d3660046107e8565b6101ef565b005b610103610142366004610830565b610233565b610103610293565b61015761031d565b60405161010d919061092f565b48610103565b6101326101783660046107e8565b6103c0565b6101326103fd565b6101326101933660046107e8565b610411565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010d565b6101036101ce366004610830565b61044e565b6101326101e1366004610980565b6104f9565b61010360045481565b6101f76105b5565b60038190556040518181527f32740b35c0ea213650f60d44366b4fb211c9033b50714e4a1d34e65d5beb9bb4906020015b60405180910390a150565b60008061023f8361044e565b9050600061024b610293565b61025590836109ec565b90506000600554600a6102689190610b4b565b905060006004548361027a91906109ec565b905060006102888383610b86565b979650505050505050565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16635cf249696040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103189190610b9a565b905090565b60606103487f0000000000000000000000000000000000000000000000000000000000000000610636565b6103717f0000000000000000000000000000000000000000000000000000000000000000610636565b61039a7f0000000000000000000000000000000000000000000000000000000000000000610636565b6040516020016103ac93929190610bb3565b604051602081830303815290604052905090565b6103c86105b5565b60048190556040518181527f3336cd9708eaf2769a0f0dc0679f30e80f15dcd88d1921b5a16858e8b85c591a90602001610228565b6104056105b5565b61040f6000610773565b565b6104196105b5565b60058190556040518181527fd68112a8707e326d08be3656b528c1bcc5bbbfc47f4177e2179b14d8640838c190602001610228565b80516000908190815b818110156104d15784818151811061047157610471610c29565b01602001517fff00000000000000000000000000000000000000000000000000000000000000166000036104b1576104aa600484610c58565b92506104bf565b6104bc601084610c58565b92505b806104c981610c70565b915050610457565b506000600354836104e29190610c58565b90506104f081610440610c58565b95945050505050565b6105016105b5565b73ffffffffffffffffffffffffffffffffffffffff81166105a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6105b281610773565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461040f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105a0565b60608160000361067957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156106a3578061068d81610c70565b915061069c9050600a83610b86565b915061067d565b60008167ffffffffffffffff8111156106be576106be610801565b6040519080825280601f01601f1916602001820160405280156106e8576020820181803683370190505b5090505b841561076b576106fd600183610ca8565b915061070a600a86610cbf565b610715906030610c58565b60f81b81838151811061072a5761072a610c29565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610764600a86610b86565b94506106ec565b949350505050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156107fa57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561084257600080fd5b813567ffffffffffffffff8082111561085a57600080fd5b818401915084601f83011261086e57600080fd5b81358181111561088057610880610801565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156108c6576108c6610801565b816040528281528760208487010111156108df57600080fd5b826020860160208301376000928101602001929092525095945050505050565b60005b8381101561091a578181015183820152602001610902565b83811115610929576000848401525b50505050565b602081526000825180602084015261094e8160408501602087016108ff565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60006020828403121561099257600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146109b657600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610a2457610a246109bd565b500290565b600181815b80851115610a8257817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610a6857610a686109bd565b80851615610a7557918102915b93841c9390800290610a2e565b509250929050565b600082610a9957506001610b45565b81610aa657506000610b45565b8160018114610abc5760028114610ac657610ae2565b6001915050610b45565b60ff841115610ad757610ad76109bd565b50506001821b610b45565b5060208310610133831016604e8410600b8410161715610b05575081810a610b45565b610b0f8383610a29565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610b4157610b416109bd565b0290505b92915050565b60006109b68383610a8a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082610b9557610b95610b57565b500490565b600060208284031215610bac57600080fd5b5051919050565b60008451610bc58184602089016108ff565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610c01816001850160208a016108ff565b60019201918201528351610c1c8160028401602088016108ff565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008219821115610c6b57610c6b6109bd565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610ca157610ca16109bd565b5060010190565b600082821015610cba57610cba6109bd565b500390565b600082610cce57610cce610b57565b50069056fea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(GasPriceOracleStorageLayoutJSON), GasPriceOracleStorageLayout); err != nil {
panic(err)
}
layouts["GasPriceOracle"] = GasPriceOracleStorageLayout
deployedBytecodes["GasPriceOracle"] = GasPriceOracleDeployedBin
}
This diff is collapsed.
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const L1BlockStorageLayoutJSON = "{\"storage\":[{\"astId\":1909,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"number\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint64\"},{\"astId\":1912,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"timestamp\",\"offset\":8,\"slot\":\"0\",\"type\":\"t_uint64\"},{\"astId\":1915,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"basefee\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":1918,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"hash\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_bytes32\"},{\"astId\":1921,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"sequenceNumber\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_uint64\"}],\"types\":{\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint64\":{\"encoding\":\"inplace\",\"label\":\"uint64\",\"numberOfBytes\":\"8\"}}}"
var L1BlockStorageLayout = new(solc.StorageLayout)
var L1BlockDeployedBin = "0x608060405234801561001057600080fd5b50600436106100885760003560e01c806364ca23ef1161005b57806364ca23ef146100dc5780638381f58a14610109578063b80777ea1461011d578063e591b2821461013d57600080fd5b8063042c2f571461008d57806309bd5a60146100a257806354fd4d50146100be5780635cf24969146100d3575b600080fd5b6100a061009b3660046104a6565b61017d565b005b6100ab60025481565b6040519081526020015b60405180910390f35b6100c66102a9565b6040516100b5919061052d565b6100ab60015481565b6003546100f09067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100b5565b6000546100f09067ffffffffffffffff1681565b6000546100f09068010000000000000000900467ffffffffffffffff1681565b61015873deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610224576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff9687167fffffffffffffffffffffffffffffffff0000000000000000000000000000000090911617680100000000000000009587169590950294909417909355600191909155600255600380547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001691909216179055565b60606102d47f000000000000000000000000000000000000000000000000000000000000000061034c565b6102fd7f000000000000000000000000000000000000000000000000000000000000000061034c565b6103267f000000000000000000000000000000000000000000000000000000000000000061034c565b6040516020016103389392919061057e565b604051602081830303815290604052905090565b60608160000361038f57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156103b957806103a381610623565b91506103b29050600a8361068a565b9150610393565b60008167ffffffffffffffff8111156103d4576103d461069e565b6040519080825280601f01601f1916602001820160405280156103fe576020820181803683370190505b5090505b8415610481576104136001836106cd565b9150610420600a866106e4565b61042b9060306106f8565b60f81b81838151811061044057610440610710565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061047a600a8661068a565b9450610402565b949350505050565b803567ffffffffffffffff811681146104a157600080fd5b919050565b600080600080600060a086880312156104be57600080fd5b6104c786610489565b94506104d560208701610489565b935060408601359250606086013591506104f160808701610489565b90509295509295909350565b60005b83811015610518578181015183820152602001610500565b83811115610527576000848401525b50505050565b602081526000825180602084015261054c8160408501602087016104fd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600084516105908184602089016104fd565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516105cc816001850160208a016104fd565b600192019182015283516105e78160028401602088016104fd565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610654576106546105f4565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826106995761069961065b565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156106df576106df6105f4565b500390565b6000826106f3576106f361065b565b500690565b6000821982111561070b5761070b6105f4565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(L1BlockStorageLayoutJSON), L1BlockStorageLayout); err != nil {
panic(err)
}
layouts["L1Block"] = L1BlockStorageLayout
deployedBytecodes["L1Block"] = L1BlockDeployedBin
}
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const L1BlockNumberStorageLayoutJSON = "{\"storage\":null,\"types\":null}"
var L1BlockNumberStorageLayout = new(solc.StorageLayout)
var L1BlockNumberDeployedBin = "0x60806040526004361061002d5760003560e01c806354fd4d5014610052578063b9b3efe91461007d57610048565b3661004857600061003c6100a0565b90508060005260206000f35b600061003c6100a0565b34801561005e57600080fd5b50610067610134565b6040516100749190610344565b60405180910390f35b34801561008957600080fd5b506100926100a0565b604051908152602001610074565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638381f58a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610101573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101259190610395565b67ffffffffffffffff16905090565b606061015f7f00000000000000000000000000000000000000000000000000000000000000006101d7565b6101887f00000000000000000000000000000000000000000000000000000000000000006101d7565b6101b17f00000000000000000000000000000000000000000000000000000000000000006101d7565b6040516020016101c3939291906103c6565b604051602081830303815290604052905090565b60608160000361021a57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610244578061022e8161046b565b915061023d9050600a836104d2565b915061021e565b60008167ffffffffffffffff81111561025f5761025f6104e6565b6040519080825280601f01601f191660200182016040528015610289576020820181803683370190505b5090505b841561030c5761029e600183610515565b91506102ab600a8661052c565b6102b6906030610540565b60f81b8183815181106102cb576102cb610558565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610305600a866104d2565b945061028d565b949350505050565b60005b8381101561032f578181015183820152602001610317565b8381111561033e576000848401525b50505050565b6020815260008251806020840152610363816040850160208701610314565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000602082840312156103a757600080fd5b815167ffffffffffffffff811681146103bf57600080fd5b9392505050565b600084516103d8818460208901610314565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610414816001850160208a01610314565b6001920191820152835161042f816002840160208801610314565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361049c5761049c61043c565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826104e1576104e16104a3565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156105275761052761043c565b500390565b60008261053b5761053b6104a3565b500690565b600082198211156105535761055361043c565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(L1BlockNumberStorageLayoutJSON), L1BlockNumberStorageLayout); err != nil {
panic(err)
}
layouts["L1BlockNumber"] = L1BlockNumberStorageLayout
deployedBytecodes["L1BlockNumber"] = L1BlockNumberDeployedBin
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const L2ToL1MessagePasserStorageLayoutJSON = "{\"storage\":[{\"astId\":2393,\"contract\":\"contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser\",\"label\":\"sentMessages\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":2396,\"contract\":\"contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser\",\"label\":\"nonce\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var L2ToL1MessagePasserStorageLayout = new(solc.StorageLayout)
var L2ToL1MessagePasserDeployedBin = "0x60806040526004361061005e5760003560e01c806382e3702d1161004357806382e3702d146100c7578063affed0e014610107578063c2b3e5ac1461012b57600080fd5b806344df8e701461008757806354fd4d501461009c57600080fd5b366100825761008033620186a060405180602001604052806000815250610139565b005b600080fd5b34801561009357600080fd5b5061008061026d565b3480156100a857600080fd5b506100b16102a5565b6040516100be9190610587565b60405180910390f35b3480156100d357600080fd5b506100f76100e23660046105a1565b60006020819052908152604090205460ff1681565b60405190151581526020016100be565b34801561011357600080fd5b5061011d60015481565b6040519081526020016100be565b6100806101393660046105e9565b600061019e6040518060c0016040528060015481526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200134815260200185815260200184815250610348565b6000818152602081905260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915554905191925073ffffffffffffffffffffffffffffffffffffffff8616913391907f87bf7b546c8de873abb0db5b579ec131f8d0cf5b14f39933551cf9ced23a61369061022c903490899089906106ed565b60405180910390a460405181907f2ef6ceb1668fdd882b1f89ddd53a666b0c1113d14cf90c0fbf97c7b1ad880fbb90600090a2505060018054810190555050565b4761027781610395565b60405181907f7967de617a5ac1cc7eba2d6f37570a0135afa950d8bb77cdd35f0d0b4e85a16f90600090a250565b60606102d07f00000000000000000000000000000000000000000000000000000000000000006103c4565b6102f97f00000000000000000000000000000000000000000000000000000000000000006103c4565b6103227f00000000000000000000000000000000000000000000000000000000000000006103c4565b60405160200161033493929190610715565b604051602081830303815290604052905090565b80516020808301516040808501516060860151608087015160a0880151935160009761037897909695910161078b565b604051602081830303815290604052805190602001209050919050565b806040516103a290610501565b6040518091039082f09050801580156103bf573d6000803e3d6000fd5b505050565b60608160000361040757505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115610431578061041b81610811565b915061042a9050600a83610878565b915061040b565b60008167ffffffffffffffff81111561044c5761044c6105ba565b6040519080825280601f01601f191660200182016040528015610476576020820181803683370190505b5090505b84156104f95761048b60018361088c565b9150610498600a866108a3565b6104a39060306108b7565b60f81b8183815181106104b8576104b86108cf565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506104f2600a86610878565b945061047a565b949350505050565b6008806108ff83390190565b60005b83811015610528578181015183820152602001610510565b83811115610537576000848401525b50505050565b6000815180845261055581602086016020860161050d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061059a602083018461053d565b9392505050565b6000602082840312156105b357600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156105fe57600080fd5b833573ffffffffffffffffffffffffffffffffffffffff8116811461062257600080fd5b925060208401359150604084013567ffffffffffffffff8082111561064657600080fd5b818601915086601f83011261065a57600080fd5b81358181111561066c5761066c6105ba565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156106b2576106b26105ba565b816040528281528960208487010111156106cb57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b83815282602082015260606040820152600061070c606083018461053d565b95945050505050565b6000845161072781846020890161050d565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551610763816001850160208a0161050d565b6001920191820152835161077e81600284016020880161050d565b0160020195945050505050565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a08301526107d660c083018461053d565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610842576108426107e2565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261088757610887610849565b500490565b60008282101561089e5761089e6107e2565b500390565b6000826108b2576108b2610849565b500690565b600082198211156108ca576108ca6107e2565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfe608060405230fffea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(L2ToL1MessagePasserStorageLayoutJSON), L2ToL1MessagePasserStorageLayout); err != nil {
panic(err)
}
layouts["L2ToL1MessagePasser"] = L2ToL1MessagePasserStorageLayout
deployedBytecodes["L2ToL1MessagePasser"] = L2ToL1MessagePasserDeployedBin
}
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const LegacyERC20ETHStorageLayoutJSON = "{\"storage\":[{\"astId\":26811,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_balances\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":26817,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_allowances\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":26819,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_totalSupply\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":26821,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_name\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_string_storage\"},{\"astId\":26823,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_symbol\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_string_storage\"},{\"astId\":24078,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"remoteToken\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_address\"},{\"astId\":24081,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"bridge\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_string_storage\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var LegacyERC20ETHStorageLayout = new(solc.StorageLayout)
var LegacyERC20ETHDeployedBin = "0x608060405234801561001057600080fd5b50600436106101365760003560e01c806395d89b41116100b2578063ae1f6aaf11610081578063d6c0b2c411610066578063d6c0b2c4146102bb578063dd62ed3e146102db578063e78cea921461032157600080fd5b8063ae1f6aaf1461025e578063c01e1bd61461029d57600080fd5b806395d89b411461021d5780639dc29fac14610225578063a457c2d714610238578063a9059cbb1461024b57600080fd5b806323b872dd1161010957806339509351116100ee57806339509351146101bf57806340c10f19146101d257806370a08231146101e757600080fd5b806323b872dd1461019d578063313ce567146101b057600080fd5b806301ffc9a71461013b57806306fdde0314610163578063095ea7b31461017857806318160ddd1461018b575b600080fd5b61014e610149366004610852565b610341565b60405190151581526020015b60405180910390f35b61016b610432565b60405161015a919061089b565b61014e610186366004610937565b6104c4565b6002545b60405190815260200161015a565b61014e6101ab366004610961565b610554565b6040516012815260200161015a565b61014e6101cd366004610937565b6105df565b6101e56101e0366004610937565b61066a565b005b61018f6101f536600461099d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61016b6106cc565b6101e5610233366004610937565b6106db565b61014e610246366004610937565b61073d565b61014e610259366004610937565b6107c8565b60065473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161015a565b60055473ffffffffffffffffffffffffffffffffffffffff16610278565b6005546102789073ffffffffffffffffffffffffffffffffffffffff1681565b61018f6102e93660046109b8565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6006546102789073ffffffffffffffffffffffffffffffffffffffff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f1d1d8b63000000000000000000000000000000000000000000000000000000007f0bc32271000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000085168314806103fa57507fffffffff00000000000000000000000000000000000000000000000000000000858116908316145b8061042957507fffffffff00000000000000000000000000000000000000000000000000000000858116908216145b95945050505050565b606060038054610441906109eb565b80601f016020809104026020016040519081016040528092919081815260200182805461046d906109eb565b80156104ba5780601f1061048f576101008083540402835291602001916104ba565b820191906000526020600020905b81548152906001019060200180831161049d57829003601f168201915b5050505050905090565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4c656761637945524332304554483a20617070726f766520697320646973616260448201527f6c6564000000000000000000000000000000000000000000000000000000000060648201526000906084015b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4c656761637945524332304554483a207472616e7366657246726f6d2069732060448201527f64697361626c6564000000000000000000000000000000000000000000000000606482015260009060840161054b565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a20696e637265617365416c6c6f77616e6360448201527f652069732064697361626c656400000000000000000000000000000000000000606482015260009060840161054b565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206d696e742069732064697361626c6564604482015260640161054b565b606060048054610441906109eb565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4c656761637945524332304554483a206275726e2069732064697361626c6564604482015260640161054b565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4c656761637945524332304554483a206465637265617365416c6c6f77616e6360448201527f652069732064697361626c656400000000000000000000000000000000000000606482015260009060840161054b565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4c656761637945524332304554483a207472616e73666572206973206469736160448201527f626c656400000000000000000000000000000000000000000000000000000000606482015260009060840161054b565b60006020828403121561086457600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461089457600080fd5b9392505050565b600060208083528351808285015260005b818110156108c8578581018301518582016040015282016108ac565b818111156108da576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461093257600080fd5b919050565b6000806040838503121561094a57600080fd5b6109538361090e565b946020939093013593505050565b60008060006060848603121561097657600080fd5b61097f8461090e565b925061098d6020850161090e565b9150604084013590509250925092565b6000602082840312156109af57600080fd5b6108948261090e565b600080604083850312156109cb57600080fd5b6109d48361090e565b91506109e26020840161090e565b90509250929050565b600181811c908216806109ff57607f821691505b602082108103610a38577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b5091905056fea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(LegacyERC20ETHStorageLayoutJSON), LegacyERC20ETHStorageLayout); err != nil {
panic(err)
}
layouts["LegacyERC20ETH"] = LegacyERC20ETHStorageLayout
deployedBytecodes["LegacyERC20ETH"] = LegacyERC20ETHDeployedBin
}
This diff is collapsed.
This diff is collapsed.
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const ProxyStorageLayoutJSON = "{\"storage\":null,\"types\":null}"
var ProxyStorageLayout = new(solc.StorageLayout)
var ProxyDeployedBin = "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(ProxyStorageLayoutJSON), ProxyStorageLayout); err != nil {
panic(err)
}
layouts["Proxy"] = ProxyStorageLayout
deployedBytecodes["Proxy"] = ProxyDeployedBin
}
This diff is collapsed.
package bindings
import (
"errors"
"fmt"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
"github.com/ethereum/go-ethereum/common"
)
var layouts = make(map[string]*solc.StorageLayout)
var deployedBytecodes = make(map[string]string)
func GetStorageLayout(name string) (*solc.StorageLayout, error) {
layout := layouts[name]
if layout == nil {
return nil, errors.New("storage layout not found")
}
return layout, nil
}
func GetDeployedBytecode(name string) ([]byte, error) {
bc := deployedBytecodes[name]
if bc == "" {
return nil, fmt.Errorf("deployed bytecode %s not found", name)
}
return common.FromHex(bc), nil
}
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const SequencerFeeVaultStorageLayoutJSON = "{\"storage\":[{\"astId\":2541,\"contract\":\"contracts/L2/SequencerFeeVault.sol:SequencerFeeVault\",\"label\":\"l1FeeWallet\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"}}}"
var SequencerFeeVaultStorageLayout = new(solc.StorageLayout)
var SequencerFeeVaultDeployedBin = "0x6080604052600436106100435760003560e01c80633ccfd60b1461004f57806354fd4d5014610066578063d3e5792b14610091578063d4ff9218146100bb57600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b5061006461010d565b005b34801561007257600080fd5b5061007b610296565b60405161008891906104f0565b60405180910390f35b34801561009d57600080fd5b506100ad67d02ab486cedc000081565b604051908152602001610088565b3480156100c757600080fd5b506000546100e89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610088565b67d02ab486cedc00004710156101cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605360248201527f53657175656e6365724665655661756c743a207769746864726177616c20616d60448201527f6f756e74206d7573742062652067726561746572207468616e206d696e696d7560648201527f6d207769746864726177616c20616d6f756e7400000000000000000000000000608482015260a40160405180910390fd5b600080546040805160208101825283815290517fa3a795480000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109363a3a795489347936102629373deaddeaddeaddeaddeaddeaddeaddeaddead00009373ffffffffffffffffffffffffffffffffffffffff909316924792909160040161050a565b6000604051808303818588803b15801561027b57600080fd5b505af115801561028f573d6000803e3d6000fd5b5050505050565b60606102c17f0000000000000000000000000000000000000000000000000000000000000000610339565b6102ea7f0000000000000000000000000000000000000000000000000000000000000000610339565b6103137f0000000000000000000000000000000000000000000000000000000000000000610339565b60405160200161032593929190610560565b604051602081830303815290604052905090565b60608160000361037c57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156103a6578061039081610605565b915061039f9050600a8361066c565b9150610380565b60008167ffffffffffffffff8111156103c1576103c1610680565b6040519080825280601f01601f1916602001820160405280156103eb576020820181803683370190505b5090505b841561046e576104006001836106af565b915061040d600a866106c6565b6104189060306106da565b60f81b81838151811061042d5761042d6106f2565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350610467600a8661066c565b94506103ef565b949350505050565b60005b83811015610491578181015183820152602001610479565b838111156104a0576000848401525b50505050565b600081518084526104be816020860160208601610476565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061050360208301846104a6565b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015263ffffffff8416606083015260a0608083015261055560a08301846104a6565b979650505050505050565b60008451610572818460208901610476565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516105ae816001850160208a01610476565b600192019182015283516105c9816002840160208801610476565b0160020195945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610636576106366105d6565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261067b5761067b61063d565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000828210156106c1576106c16105d6565b500390565b6000826106d5576106d561063d565b500690565b600082198211156106ed576106ed6105d6565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(SequencerFeeVaultStorageLayoutJSON), SequencerFeeVaultStorageLayout); err != nil {
panic(err)
}
layouts["SequencerFeeVault"] = SequencerFeeVaultStorageLayout
deployedBytecodes["SequencerFeeVault"] = SequencerFeeVaultDeployedBin
}
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const WETH9StorageLayoutJSON = "{\"storage\":[{\"astId\":4,\"contract\":\"contracts/vendor/WETH9.sol:WETH9\",\"label\":\"name\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_string_storage\"},{\"astId\":7,\"contract\":\"contracts/vendor/WETH9.sol:WETH9\",\"label\":\"symbol\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_string_storage\"},{\"astId\":10,\"contract\":\"contracts/vendor/WETH9.sol:WETH9\",\"label\":\"decimals\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint8\"},{\"astId\":42,\"contract\":\"contracts/vendor/WETH9.sol:WETH9\",\"label\":\"balanceOf\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":48,\"contract\":\"contracts/vendor/WETH9.sol:WETH9\",\"label\":\"allowance\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_string_storage\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}"
var WETH9StorageLayout = new(solc.StorageLayout)
var WETH9DeployedBin = "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a72315820b2282f823392ab6b42c17b31235784e88e108cd8d10e77cd732aa3e1e7a88a7d64736f6c63430005110032"
func init() {
if err := json.Unmarshal([]byte(WETH9StorageLayoutJSON), WETH9StorageLayout); err != nil {
panic(err)
}
layouts["WETH9"] = WETH9StorageLayout
deployedBytecodes["WETH9"] = WETH9DeployedBin
}
package main
import (
"encoding/json"
"flag"
"log"
"os"
"path/filepath"
"strings"
"text/template"
"github.com/ethereum-optimism/optimism/op-bindings/hardhat"
)
type flags struct {
ArtifactsDir string
Contracts string
OutDir string
Package string
}
type data struct {
Name string
StorageLayout string
DeployedBin string
Package string
}
func main() {
var f flags
flag.StringVar(&f.ArtifactsDir, "artifacts", "", "Comma-separated list of directories containing artifacts and build info")
flag.StringVar(&f.OutDir, "out", "", "Output directory to put code in")
flag.StringVar(&f.Contracts, "contracts", "", "Comma-separated list of contracts to generate code for")
flag.StringVar(&f.Package, "package", "artifacts", "Go package name")
flag.Parse()
artifacts := strings.Split(f.ArtifactsDir, ",")
contracts := strings.Split(f.Contracts, ",")
if len(artifacts) == 0 {
log.Fatalf("must define a list of artifacts")
}
if len(contracts) == 0 {
log.Fatalf("must define a list of contracts")
}
hh, err := hardhat.New("dummy", artifacts, nil)
if err != nil {
log.Fatalln("error reading artifacts:", err)
}
t := template.Must(template.New("artifact").Parse(tmpl))
for _, name := range contracts {
art, err := hh.GetArtifact(name)
if err != nil {
log.Fatalf("error reading artifact %s: %v\n", name, err)
}
storage, err := hh.GetStorageLayout(name)
if err != nil {
log.Fatalf("error reading storage layout %s: %v\n", name, err)
}
ser, err := json.Marshal(storage)
if err != nil {
log.Fatalf("error marshaling storage: %v\n", err)
}
serStr := strings.Replace(string(ser), "\"", "\\\"", -1)
d := data{
Name: name,
StorageLayout: serStr,
DeployedBin: art.DeployedBytecode.String(),
Package: f.Package,
}
fname := filepath.Join(f.OutDir, strings.ToLower(name)+"_more.go")
outfile, err := os.OpenFile(
fname,
os.O_RDWR|os.O_CREATE|os.O_TRUNC,
0o600,
)
if err != nil {
log.Fatalf("error opening %s: %v\n", fname, err)
}
if err := t.Execute(outfile, d); err != nil {
log.Fatalf("error writing template %s: %v", outfile.Name(), err)
}
outfile.Close()
log.Printf("wrote file %s\n", outfile.Name())
}
}
var tmpl = `// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package {{.Package}}
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const {{.Name}}StorageLayoutJSON = "{{.StorageLayout}}"
var {{.Name}}StorageLayout = new(solc.StorageLayout)
var {{.Name}}DeployedBin = "{{.DeployedBin}}"
func init() {
if err := json.Unmarshal([]byte({{.Name}}StorageLayoutJSON), {{.Name}}StorageLayout); err != nil {
panic(err)
}
layouts["{{.Name}}"] = {{.Name}}StorageLayout
deployedBytecodes["{{.Name}}"] = {{.Name}}DeployedBin
}
`
......@@ -37,10 +37,9 @@ TEMP=$(mktemp -d)
CWD=$(pwd)
# Build contracts
cd ${CONTRACTS_PATH}
forge build
forge inspect ${NAME} abi > ${TEMP}/${TYPE}.abi
forge inspect ${NAME} bytecode > ${TEMP}/${TYPE}.bin
forge inspect ${NAME} deployedBytecode > ${CWD}/bin/${TYPE_LOWER}_deployed.hex
forge inspect -o ./tmp-artifacts ${NAME} abi > ${TEMP}/${TYPE}.abi
forge inspect -o ./tmp-artifacts ${NAME} bytecode > ${TEMP}/${TYPE}.bin
forge inspect -o ./tmp-artifacts ${NAME} deployedBytecode > ${CWD}/bin/${TYPE_LOWER}_deployed.hex
# Run ABIGEN
cd ${CWD}
......
#/bin/bash
set -eu
if [ "$#" -ne 2 ]; then
echo "This script takes 2 arguments - CONTRACT_NAME PACKAGE"
exit 1
fi
need_cmd() {
if ! command -v "$1" > /dev/null 2>&1; then
echo "need '$1' (command not found)"
exit 1
fi
}
need_cmd gofmt
TYPE=$1
PACKAGE=$2
# Convert to lower case to respect golang package naming conventions
TYPE_LOWER=$(echo ${TYPE} | tr '[:upper:]' '[:lower:]')
FILENAME="${TYPE_LOWER}_deployed.go"
FILE="${PACKAGE}/${FILENAME}"
DEPLOYED_BYTECODE=$(cat "bin/${TYPE_LOWER}_deployed.hex")
echo "// Code generated - DO NOT EDIT." > ${FILE}
echo "// This file is a generated binding and any manual changes will be lost." >> ${FILE}
echo "package ${PACKAGE}" >> ${FILE}
echo "var ${TYPE}DeployedBin = \"${DEPLOYED_BYTECODE}\"" >> ${FILE}
gofmt -s -w ${FILE}
......@@ -3,7 +3,7 @@ module github.com/ethereum-optimism/optimism/op-bindings
go 1.18
require (
github.com/ethereum/go-ethereum v1.10.21
github.com/ethereum/go-ethereum v1.10.23
github.com/stretchr/testify v1.7.2
)
......@@ -16,7 +16,6 @@ require (
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/golang-jwt/jwt/v4 v4.3.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
......@@ -41,4 +40,6 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/op-geth v0.0.0-20220819161933-acfde114de61
replace github.com/ethereum/go-ethereum v1.10.23 => github.com/ethereum-optimism/op-geth v0.0.0-20220909213840-e6575c0168f1
// github.com/ethereum-optimism/op-geth v0.0.0-20220909213840-e6575c0168f1
......@@ -28,16 +28,16 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
github.com/ethereum-optimism/op-geth v0.0.0-20220819161933-acfde114de61 h1:+WfrwiRELp3hoeb1bnPws3FtUUoYCDDYsCkwvKek5FY=
github.com/ethereum-optimism/op-geth v0.0.0-20220819161933-acfde114de61/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg=
github.com/ethereum-optimism/op-geth v0.0.0-20220909213840-e6575c0168f1 h1:W/ZU6BZH7ilTrpdoJOF9N4OReqXbpeRtUB6klIpEdMA=
github.com/ethereum-optimism/op-geth v0.0.0-20220909213840-e6575c0168f1/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
......@@ -45,8 +45,6 @@ github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog=
github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
......
......@@ -9,7 +9,7 @@ import (
"strings"
"sync"
"github.com/ethereum-optimism/optimism/op-chain-ops/solc"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
// `Hardhat` encapsulates all of the functionality required to interact
......@@ -26,7 +26,7 @@ type Hardhat struct {
artifacts []*Artifact
deployments []*Deployment
buildInfos []*BuildInfo
buildInfos []*BuildInfo //nolint:unused
}
// New creates a new `Hardhat` struct and reads all of the files from
......@@ -202,7 +202,7 @@ func (h *Hardhat) GetBuildInfo(name string) (*BuildInfo, error) {
for _, artifactPath := range h.ArtifactPaths {
fileSystem := os.DirFS(artifactPath)
fs.WalkDir(fileSystem, ".", func(path string, d fs.DirEntry, err error) error {
err := fs.WalkDir(fileSystem, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
......@@ -249,6 +249,9 @@ func (h *Hardhat) GetBuildInfo(name string) (*BuildInfo, error) {
return nil
})
if err != nil {
return nil, err
}
}
// TODO(tynes): handle multiple contracts with same name when required
......
......@@ -3,7 +3,7 @@ package hardhat_test
import (
"testing"
"github.com/ethereum-optimism/optimism/op-chain-ops/hardhat"
"github.com/ethereum-optimism/optimism/op-bindings/hardhat"
"github.com/stretchr/testify/require"
)
......
......@@ -3,7 +3,7 @@ package hardhat
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-chain-ops/solc"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
......@@ -57,7 +57,7 @@ type Log struct {
}
// Artifact represents a hardhat compilation artifact
// The Bytecode and DeployedBytecode are not guranteed
// The Bytecode and DeployedBytecode are not guaranteed
// to be hexutil.Bytes when there are link references.
// In the future, custom json marshalling can be used
// to place the link reference values in the correct location.
......
package predeploys
import "github.com/ethereum/go-ethereum/common"
const (
DevL2OutputOracle = "0x6900000000000000000000000000000000000000"
DevOptimismPortal = "0x6900000000000000000000000000000000000001"
DevL1CrossDomainMessenger = "0x6900000000000000000000000000000000000002"
DevL1StandardBridge = "0x6900000000000000000000000000000000000003"
DevOptimismMintableERC20Factory = "0x6900000000000000000000000000000000000004"
DevAddressManager = "0x6900000000000000000000000000000000000005"
DevProxyAdmin = "0x6900000000000000000000000000000000000006"
)
var (
DevL2OutputOracleAddr = common.HexToAddress(DevL2OutputOracle)
DevOptimismPortalAddr = common.HexToAddress(DevOptimismPortal)
DevL1CrossDomainMessengerAddr = common.HexToAddress(DevL1CrossDomainMessenger)
DevL1StandardBridgeAddr = common.HexToAddress(DevL1StandardBridge)
DevOptimismMintableERC20FactoryAddr = common.HexToAddress(DevOptimismMintableERC20Factory)
DevAddressManagerAddr = common.HexToAddress(DevAddressManager)
DevProxyAdminAddr = common.HexToAddress(DevProxyAdmin)
DevPredeploys = make(map[string]*common.Address)
)
func init() {
DevPredeploys["L2OutputOracle"] = &DevL2OutputOracleAddr
DevPredeploys["OptimismPortal"] = &DevOptimismPortalAddr
DevPredeploys["L1CrossDomainMessenger"] = &DevL1CrossDomainMessengerAddr
DevPredeploys["L1StandardBridge"] = &DevL1StandardBridgeAddr
DevPredeploys["OptimismMintableERC20Factory"] = &DevOptimismMintableERC20FactoryAddr
DevPredeploys["AddressManager"] = &DevAddressManagerAddr
DevPredeploys["Admin"] = &DevProxyAdminAddr
}
......@@ -55,7 +55,7 @@ type StorageLayoutEntry struct {
Label string `json:"label"`
Offset uint `json:"offset"`
Slot uint `json:"slot,string"`
Type string `json"type"`
Type string `json:"type"`
}
type StorageLayoutType struct {
......@@ -73,7 +73,7 @@ type CompilerOutputEvm struct {
MethodIdentifiers map[string]string `json:"methodIdentifiers"`
}
// Object must be a string because its not guranteed to be
// Object must be a string because its not guaranteed to be
// a hex string
type CompilerOutputBytecode struct {
Object string `json:"object"`
......
......@@ -243,6 +243,9 @@ func Migrate(dataDir, outDir string, genesis *core.Genesis, addrLists, allowance
log.Info("trie dumping started", "root", root)
tr, err := backingStateDB.OpenTrie(root)
if err != nil {
return err
}
it := trie.NewIterator(tr.NodeIterator(nil))
totalMigrated := new(big.Int)
logAccountProgress := ProgressLogger(1000, "imported accounts")
......@@ -353,13 +356,11 @@ func Migrate(dataDir, outDir string, genesis *core.Genesis, addrLists, allowance
}
log.Info("committed trie DB")
// Now that the state is dumped, insert the genesis block. We pass in a nil
// database here because we don't want to update the state again with the
// pre-allocs.
// Now that the state is dumped, insert the genesis block.
//
// Unlike regular Geth (which panics if you try to import a genesis state with a nonzero
// block number), the block number can be anything.
block := genesis.ToBlock(nil)
block := genesis.ToBlock()
// Geth block headers are immutable, so swap the root and make a new block with the
// updated root.
......@@ -373,7 +374,7 @@ func Migrate(dataDir, outDir string, genesis *core.Genesis, addrLists, allowance
// Write the genesis state to the database. This is taken verbatim from Geth's
// core.Genesis struct.
rawdb.WriteGenesisState(outDB, block.Hash(), blob)
rawdb.WriteGenesisStateSpec(outDB, block.Hash(), blob)
rawdb.WriteTd(outDB, block.Hash(), block.NumberU64(), block.Difficulty())
rawdb.WriteBlock(outDB, block)
rawdb.WriteReceipts(outDB, block.Hash(), block.NumberU64(), nil)
......
package deployer
import (
"context"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
)
// TestKey is the same test key that geth uses
var TestKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
// ChainID is the chain id used for simulated backends
var ChainID = big.NewInt(1337)
var TestAddress = crypto.PubkeyToAddress(TestKey.PublicKey)
var thousandETH = new(big.Int).Mul(big.NewInt(params.Ether), big.NewInt(1000))
type Constructor struct {
Name string
Args []interface{}
}
type Deployment struct {
Name string
Bytecode hexutil.Bytes
Address common.Address
}
type Deployer func(*backends.SimulatedBackend, *bind.TransactOpts, Constructor) (common.Address, error)
func NewBackend() *backends.SimulatedBackend {
return backends.NewSimulatedBackendWithCacheConfig(
&core.CacheConfig{
Preimages: true,
},
core.GenesisAlloc{
crypto.PubkeyToAddress(TestKey.PublicKey): {Balance: thousandETH},
},
15000000,
)
}
func Deploy(backend *backends.SimulatedBackend, constructors []Constructor, cb Deployer) ([]Deployment, error) {
results := make([]Deployment, len(constructors))
opts, err := bind.NewKeyedTransactorWithChainID(TestKey, ChainID)
if err != nil {
return nil, err
}
opts.GasLimit = 15_000_000
for i, deployment := range constructors {
addr, err := cb(backend, opts, deployment)
if err != nil {
return nil, err
}
backend.Commit()
if addr == (common.Address{}) {
return nil, fmt.Errorf("no address for %s", deployment.Name)
}
code, err := backend.CodeAt(context.Background(), addr, nil)
if len(code) == 0 {
return nil, fmt.Errorf("no code found for %s", deployment.Name)
}
if err != nil {
return nil, fmt.Errorf("cannot fetch code for %s", deployment.Name)
}
results[i] = Deployment{
Name: deployment.Name,
Bytecode: code,
Address: addr,
}
}
return results, nil
}
......@@ -2,66 +2,78 @@ package genesis
import (
"encoding/json"
"math/big"
"os"
"path/filepath"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/hardhat"
"github.com/ethereum-optimism/optimism/op-chain-ops/state"
"github.com/ethereum/go-ethereum/common"
)
// DeployConfig represents the deployment configuration for Optimism
type DeployConfig struct {
L1StartingBlockTag rpc.BlockNumberOrHash `json:"l1StartingBlockTag"`
L1ChainID *big.Int `json:"l1ChainID"`
L2ChainID *big.Int `json:"l2ChainID"`
L2BlockTime uint `json:"l2BlockTime"`
MaxSequencerDrift uint `json:"maxSequencerDrift"`
SequencerWindowSize uint `json:"sequencerWindowSize"`
ChannelTimeout uint `json:"channelTimeout"`
L1StartingBlockTag *rpc.BlockNumberOrHash `json:"l1StartingBlockTag"`
L1ChainID uint64 `json:"l1ChainID"`
L2ChainID uint64 `json:"l2ChainID"`
L2BlockTime uint64 `json:"l2BlockTime"`
FinalizationPeriodSeconds uint64 `json:"finalizationPeriodSeconds"`
MaxSequencerDrift uint64 `json:"maxSequencerDrift"`
SequencerWindowSize uint64 `json:"sequencerWindowSize"`
ChannelTimeout uint64 `json:"channelTimeout"`
P2PSequencerAddress common.Address `json:"p2pSequencerAddress"`
OptimismL2FeeRecipient common.Address `json:"optimismL2FeeRecipient"`
BatchInboxAddress common.Address `json:"batchInboxAddress"`
BatchSenderAddress common.Address `json:"batchSenderAddress"`
L2OutputOracleSubmissionInterval uint `json:"l2OutputOracleSubmissionInterval"`
L2OutputOracleSubmissionInterval uint64 `json:"l2OutputOracleSubmissionInterval"`
L2OutputOracleStartingTimestamp int `json:"l2OutputOracleStartingTimestamp"`
L2OutputOracleProposer common.Address `json:"l2OutputOracleProposer"`
L2OutputOracleOwner common.Address `json:"l2OutputOracleOwner"`
L2OutputOracleGenesisL2Output common.Hash `json:"l2OutputOracleGenesisL2Output"`
L1BlockTime uint64 `json:"l1BlockTime"`
L1GenesisBlockTimestamp hexutil.Uint64 `json:"l1GenesisBlockTimestamp"`
L1GenesisBlockNonce hexutil.Uint64 `json:"l1GenesisBlockNonce"`
CliqueSignerAddress common.Address `json:"cliqueSignerAddress"`
L1GenesisBlockGasLimit hexutil.Uint64 `json:"l1GenesisBlockGasLimit"`
L1GenesisBlockDifficulty *hexutil.Big `json:"l1GenesisBlockDifficulty"`
L1GenesisBlockMixHash common.Hash `json:"l1GenesisBlockMixHash"`
L1GenesisBlockCoinbase common.Address `json:"l1GenesisBlockCoinbase"`
L1GenesisBlockNumber hexutil.Uint64 `json:"l1GenesisBlockNumber"`
L1GenesisBlockGasUsed hexutil.Uint64 `json:"l1GenesisBlockGasUsed"`
L1GenesisBlockParentHash common.Hash `json:"l1GenesisBlockParentHash"`
L1GenesisBlockBaseFeePerGas *hexutil.Big `json:"l1GenesisBlockBaseFeePerGas"`
L2GenesisBlockNonce hexutil.Uint64 `json:"l2GenesisBlockNonce"`
L2GenesisBlockExtraData hexutil.Bytes `json:"l2GenesisBlockExtraData"`
L2GenesisBlockGasLimit hexutil.Uint64 `json:"l2GenesisBlockGasLimit"`
L2GenesisBlockDifficulty *hexutil.Big `json:"l2GenesisBlockDifficulty"`
L2GenesisBlockMixHash common.Hash `json:"l2GenesisBlockMixHash"`
L2GenesisBlockCoinbase common.Address `json:"l2GenesisBlockCoinbase"`
L2GenesisBlockNumber hexutil.Uint64 `json:"l2GenesisBlockNumber"`
L2GenesisBlockGasUsed hexutil.Uint64 `json:"l2GenesisBlockGasUsed"`
L2GenesisBlockParentHash common.Hash `json:"l2GenesisBlockParentHash"`
L2GenesisBlockBaseFeePerGas *hexutil.Big `json:"l2GenesisBlockBaseFeePerGas"`
L2CrossDomainMessengerOwner common.Address `json:"l2CrossDomainMessengerOwner"`
OptimismBaseFeeRecipient common.Address `json:"optimismBaseFeeRecipient"`
OptimismL1FeeRecipient common.Address `json:"optimismL1FeeRecipient"`
GasPriceOracleOwner common.Address `json:"gasPriceOracleOwner"`
GasPriceOracleOverhead uint `json:"gasPriceOracleOverhead"`
GasPriceOracleScalar uint `json:"gasPriceOracleScalar"`
GasPriceOracleDecimals uint `json:"gasPriceOracleDecimals"`
L2CrossDomainMessengerOwner common.Address `json:"l2CrossDomainMessengerOwner"`
L2GenesisBlockNonce uint64 `json:"l2GenesisBlockNonce"`
L2GenesisBlockExtraData hexutil.Bytes `json:"l2GenesisBlockExtraData"`
L2GenesisBlockGasLimit uint64 `json:"l2GenesisBlockGasLimit"`
L2GenesisBlockDifficulty *big.Int `json:"l2GenesisBlockDifficulty"`
L2GenesisBlockMixHash common.Hash `json:"l2GenesisBlockMixHash"`
L2GenesisBlockCoinbase common.Address `json:"l2GenesisBlockCoinbase"`
L2GenesisBlockNumber uint64 `json:"l2GenesisBlockNumber"`
L2GenesisBlockGasUsed uint64 `json:"l2GenesisBlockGasUsed"`
L2GenesisBlockParentHash common.Hash `json:"l2GenesisBlockParentHash"`
L2GenesisBlockBaseFeePerGas *big.Int `json:"l2GenesisBlockBaseFeePerGas"`
L1GenesisBlockTimestamp uint64 `json:"l1GenesisBlockTimestamp"`
L1GenesisBlockNonce uint64 `json:"l1GenesisBlockNonce"`
L1GenesisBlockGasLimit uint64 `json:"l1GenesisBlockGasLimit"`
L1GenesisBlockDifficulty *big.Int `json:"l1GenesisBlockDifficulty"`
L1GenesisBlockMixHash common.Hash `json:"l1GenesisBlockMixHash"`
L1GenesisBlockCoinbase common.Address `json:"l1GenesisBlockCoinbase"`
L1GenesisBlockNumber uint64 `json:"l1GenesisBlockNumber"`
L1GenesisBlockGasUsed uint64 `json:"l1GenesisBlockGasUsed"`
L1GenesisBlockParentHash common.Hash `json:"l1GenesisBlockParentHash"`
L1GenesisBlockBaseFeePerGas *big.Int `json:"l1GenesisBlockBaseFeePerGas"`
DeploymentWaitConfirmations int `json:"deploymentWaitConfirmations"`
EIP1559Elasticity uint64 `json:"eip1559Elasticity"`
EIP1559Denominator uint64 `json:"eip1559Denominator"`
FundDevAccounts bool `json:"fundDevAccounts"`
}
// NewDeployConfig reads a config file given a path on the filesystem.
......@@ -91,25 +103,11 @@ func NewDeployConfigWithNetwork(network, path string) (*DeployConfig, error) {
// contracts.
type StorageConfig map[string]state.StorageValues
// NewStorageConfig will create a StorageConfig given an instance of a
// NewL2StorageConfig will create a StorageConfig given an instance of a
// Hardhat and a DeployConfig.
func NewStorageConfig(hh *hardhat.Hardhat, config *DeployConfig, chain ethereum.ChainReader) (StorageConfig, error) {
func NewL2StorageConfig(config *DeployConfig, block *types.Block, proxyL1StandardBridge common.Address, proxyL1CrossDomainMessenger common.Address) (StorageConfig, error) {
storage := make(StorageConfig)
proxyL1StandardBridge, err := hh.GetDeployment("L1StandardBridgeProxy")
if err != nil {
return storage, err
}
proxyL1CrossDomainMessenger, err := hh.GetDeployment("L1CrossDomainMessengerProxy")
if err != nil {
return storage, err
}
block, err := getBlockFromTag(chain, config.L1StartingBlockTag)
if err != nil {
return storage, err
}
storage["L2ToL1MessagePasser"] = state.StorageValues{
"nonce": 0,
}
......@@ -122,7 +120,7 @@ func NewStorageConfig(hh *hardhat.Hardhat, config *DeployConfig, chain ethereum.
"_paused": false,
"xDomainMsgSender": "0x000000000000000000000000000000000000dEaD",
"msgNonce": 0,
"otherMessenger": proxyL1CrossDomainMessenger.Address,
"otherMessenger": proxyL1CrossDomainMessenger,
"blockedSystemAddresses": map[any]any{
predeploys.L2CrossDomainMessenger: true,
predeploys.L2ToL1MessagePasser: true,
......@@ -138,7 +136,7 @@ func NewStorageConfig(hh *hardhat.Hardhat, config *DeployConfig, chain ethereum.
"_initialized": true,
"_initializing": false,
"messenger": predeploys.L2CrossDomainMessenger,
"otherBridge": proxyL1StandardBridge.Address,
"otherBridge": proxyL1StandardBridge,
}
storage["SequencerFeeVault"] = state.StorageValues{
"l1FeeWallet": config.OptimismL1FeeRecipient,
......
package genesis
import (
"bytes"
"encoding/json"
"fmt"
"os"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rpc"
"github.com/stretchr/testify/require"
)
func TestConfigMarshalUnmarshal(t *testing.T) {
// NOTE: the l1 starting block tag is set to null
// in the test since the type is not JSON serializable.
// Rather than bloat the code by introducing a marshalable
// block tag type that's only used in test, I created a separate
// test to validate that the starting block tag unmarshals
// correctly.
b, err := os.ReadFile("testdata/test-deploy-config-full.json")
require.NoError(t, err)
dec := json.NewDecoder(bytes.NewReader(b))
decoded := new(DeployConfig)
require.NoError(t, dec.Decode(decoded))
encoded, err := json.MarshalIndent(decoded, "", " ")
require.NoError(t, err)
require.JSONEq(t, string(b), string(encoded))
}
func TestUnmarshalL1StartingBlockTag(t *testing.T) {
decoded := new(DeployConfig)
require.NoError(t, json.Unmarshal([]byte(`{"l1StartingBlockTag": "earliest"}`), decoded))
require.EqualValues(t, rpc.EarliestBlockNumber, *decoded.L1StartingBlockTag.BlockNumber)
h := "0x86c7263d87140ca7cd9bf1bc9e95a435a7a0efc0ae2afaf64920c5b59a6393d4"
require.NoError(t, json.Unmarshal([]byte(fmt.Sprintf(`{"l1StartingBlockTag": "%s"}`, h)), decoded))
require.EqualValues(t, common.HexToHash(h), *decoded.L1StartingBlockTag.BlockHash)
}
......@@ -5,7 +5,9 @@ import (
"math/big"
"time"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
......@@ -13,13 +15,22 @@ import (
)
// NewL2Genesis will create a new L2 genesis
func NewL2Genesis(config *DeployConfig, chain ethereum.ChainReader) (*core.Genesis, error) {
if config.L2ChainID == nil {
func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, error) {
if config.L2ChainID == 0 {
return nil, errors.New("must define L2 ChainID")
}
eip1559Denom := config.EIP1559Denominator
if eip1559Denom == 0 {
eip1559Denom = 50
}
eip1559Elasticity := config.EIP1559Elasticity
if eip1559Elasticity == 0 {
eip1559Elasticity = 10
}
optimismChainConfig := params.ChainConfig{
ChainID: config.L2ChainID,
ChainID: new(big.Int).SetUint64(config.L2ChainID),
HomesteadBlock: big.NewInt(0),
DAOForkBlock: nil,
DAOForkSupport: false,
......@@ -44,6 +55,8 @@ func NewL2Genesis(config *DeployConfig, chain ethereum.ChainReader) (*core.Genes
Optimism: &params.OptimismConfig{
BaseFeeRecipient: config.OptimismBaseFeeRecipient,
L1FeeRecipient: config.OptimismL2FeeRecipient,
EIP1559Denominator: eip1559Denom,
EIP1559Elasticity: eip1559Elasticity,
},
}
......@@ -53,42 +66,37 @@ func NewL2Genesis(config *DeployConfig, chain ethereum.ChainReader) (*core.Genes
}
gasLimit := config.L2GenesisBlockGasLimit
if gasLimit == 0 {
gasLimit = uint64(15_000_000)
gasLimit = 15_000_000
}
baseFee := config.L2GenesisBlockBaseFeePerGas
if baseFee == nil {
baseFee = big.NewInt(params.InitialBaseFee)
baseFee = newHexBig(params.InitialBaseFee)
}
difficulty := config.L2GenesisBlockDifficulty
if difficulty == nil {
difficulty = big.NewInt(1)
}
block, err := getBlockFromTag(chain, config.L1StartingBlockTag)
if err != nil {
return nil, err
difficulty = newHexBig(0)
}
return &core.Genesis{
Config: &optimismChainConfig,
Nonce: config.L2GenesisBlockNonce,
Nonce: uint64(config.L2GenesisBlockNonce),
Timestamp: block.Time(),
ExtraData: extraData,
GasLimit: gasLimit,
Difficulty: difficulty,
GasLimit: uint64(gasLimit),
Difficulty: difficulty.ToInt(),
Mixhash: config.L2GenesisBlockMixHash,
Coinbase: config.L2GenesisBlockCoinbase,
Number: config.L2GenesisBlockNumber,
GasUsed: config.L2GenesisBlockGasUsed,
Number: uint64(config.L2GenesisBlockNumber),
GasUsed: uint64(config.L2GenesisBlockGasUsed),
ParentHash: config.L2GenesisBlockParentHash,
BaseFee: baseFee,
BaseFee: baseFee.ToInt(),
Alloc: map[common.Address]core.GenesisAccount{},
}, nil
}
// NewL1Genesis will create a new L1 genesis config
func NewL1Genesis(config *DeployConfig) (*core.Genesis, error) {
if config.L1ChainID == nil {
if config.L1ChainID == 0 {
return nil, errors.New("must define L1 ChainID")
}
......@@ -97,40 +105,40 @@ func NewL1Genesis(config *DeployConfig) (*core.Genesis, error) {
Period: config.L1BlockTime,
Epoch: 30000,
}
chainConfig.ChainID = config.L1ChainID
chainConfig.ChainID = uint642Big(config.L1ChainID)
gasLimit := config.L1GenesisBlockGasLimit
if gasLimit == 0 {
gasLimit = uint64(15_000_000)
gasLimit = 15_000_000
}
baseFee := config.L1GenesisBlockBaseFeePerGas
if baseFee == nil {
baseFee = big.NewInt(params.InitialBaseFee)
baseFee = newHexBig(params.InitialBaseFee)
}
difficulty := config.L1GenesisBlockDifficulty
if difficulty == nil {
difficulty = big.NewInt(1)
difficulty = newHexBig(1)
}
timestamp := config.L1GenesisBlockTimestamp
if timestamp == 0 {
timestamp = uint64(time.Now().Unix())
timestamp = hexutil.Uint64(time.Now().Unix())
}
extraData := append(append(make([]byte, 32), config.CliqueSignerAddress[:]...), make([]byte, crypto.SignatureLength)...)
return &core.Genesis{
Config: &chainConfig,
Nonce: config.L1GenesisBlockNonce,
Timestamp: timestamp,
Nonce: uint64(config.L1GenesisBlockNonce),
Timestamp: uint64(timestamp),
ExtraData: extraData,
GasLimit: gasLimit,
Difficulty: difficulty,
GasLimit: uint64(gasLimit),
Difficulty: difficulty.ToInt(),
Mixhash: config.L1GenesisBlockMixHash,
Coinbase: config.L1GenesisBlockCoinbase,
Number: config.L1GenesisBlockNumber,
GasUsed: config.L1GenesisBlockGasUsed,
Number: uint64(config.L1GenesisBlockNumber),
GasUsed: uint64(config.L1GenesisBlockGasUsed),
ParentHash: config.L1GenesisBlockParentHash,
BaseFee: baseFee,
BaseFee: baseFee.ToInt(),
Alloc: map[common.Address]core.GenesisAccount{},
}, nil
}
......@@ -16,10 +16,14 @@ import (
var (
// codeNamespace represents the namespace of implementations of predeploys
codeNamespace = common.HexToAddress("0xc0D3C0d3C0d3C0D3c0d3C0d3c0D3C0d3c0d30000")
// predeployNamespace represents the namespace of predeploys
predeployNamespace = common.HexToAddress("0x4200000000000000000000000000000000000000")
// bigPredeployNamespace represents the predeploy namespace as a big.Int
bigPredeployNamespace = new(big.Int).SetBytes(predeployNamespace.Bytes())
// l2PredeployNamespace represents the namespace of L2 predeploys
l2PredeployNamespace = common.HexToAddress("0x4200000000000000000000000000000000000000")
// l1PredeployNamespace represents the namespace of L1 predeploys
l1PredeployNamespace = common.HexToAddress("0x6900000000000000000000000000000000000000")
// bigL2PredeployNamespace represents the predeploy namespace as a big.Int
bigL2PredeployNamespace = new(big.Int).SetBytes(l2PredeployNamespace.Bytes())
// bigL1PredeployNamespace represents the predeploy namespace as a big.Int
bigL1PredeployNamespace = new(big.Int).SetBytes(l1PredeployNamespace.Bytes())
// bigCodeNamespace represents the predeploy namespace as a big.Int
bigCodeNameSpace = new(big.Int).SetBytes(codeNamespace.Bytes())
// implementationSlot represents the EIP 1967 implementation storage slot
......@@ -59,19 +63,26 @@ var DevAccounts = []common.Address{
var devBalance = hexutil.MustDecodeBig("0x200000000000000000000000000000000000000000000000000000000000000")
// AddressToCodeNamespace takes a predeploy address and computes
// the implmentation address that the implementation should be deployed at
// the implementation address that the implementation should be deployed at
func AddressToCodeNamespace(addr common.Address) (common.Address, error) {
bytesAddr := addr.Bytes()
if !bytes.Equal(bytesAddr[0:2], []byte{0x42, 0x00}) {
if !IsL1DevPredeploy(addr) && !IsL2DevPredeploy(addr) {
return common.Address{}, fmt.Errorf("cannot handle non predeploy: %s", addr)
}
bigAddress := new(big.Int).SetBytes(bytesAddr[18:])
bigAddress := new(big.Int).SetBytes(addr[18:])
num := new(big.Int).Or(bigCodeNameSpace, bigAddress)
return common.BigToAddress(num), nil
}
// getBlockFromTag will resolve a Block given an rpc block tag
func getBlockFromTag(chain ethereum.ChainReader, tag rpc.BlockNumberOrHash) (*types.Block, error) {
func IsL1DevPredeploy(addr common.Address) bool {
return bytes.Equal(addr[0:2], []byte{0x69, 0x00})
}
func IsL2DevPredeploy(addr common.Address) bool {
return bytes.Equal(addr[0:2], []byte{0x42, 0x00})
}
// GetBlockFromTag will resolve a Block given an rpc block tag
func GetBlockFromTag(chain ethereum.ChainReader, tag *rpc.BlockNumberOrHash) (*types.Block, error) {
if hash, ok := tag.Hash(); ok {
block, err := chain.BlockByHash(context.Background(), hash)
if err != nil {
......@@ -89,3 +100,14 @@ func getBlockFromTag(chain ethereum.ChainReader, tag rpc.BlockNumberOrHash) (*ty
return nil, fmt.Errorf("invalid block tag: %v", tag)
}
}
// uint642Big creates a new *big.Int from a uint64.
func uint642Big(in uint64) *big.Int {
return new(big.Int).SetUint64(in)
}
func newHexBig(in uint64) *hexutil.Big {
b := new(big.Int).SetUint64(in)
hb := hexutil.Big(*b)
return &hb
}
package genesis
import (
"errors"
"fmt"
"math/big"
"strings"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/deployer"
"github.com/ethereum-optimism/optimism/op-chain-ops/state"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/trie"
)
// TODO(tynes): need bindings for all of the L1 contracts to be able
// to create a genesis file with the L1 contracts predeployed.
// This would speed up testing as deployments take time when
// running tests.
var proxies = []string{
"L2OutputOracleProxy",
"L1CrossDomainMessengerProxy",
"L1StandardBridgeProxy",
"OptimismPortalProxy",
"OptimismMintableERC20FactoryProxy",
}
var portalMeteringSlot = common.Hash{31: 0x01}
var zeroHash common.Hash
func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) {
if config.L2OutputOracleStartingTimestamp != -1 {
return nil, errors.New("l2oo starting timestamp must be -1")
}
if config.L1GenesisBlockTimestamp == 0 {
return nil, errors.New("must specify l1 genesis block timestamp")
}
genesis, err := NewL1Genesis(config)
if err != nil {
return nil, err
}
db := state.NewMemoryStateDB(genesis)
backend := deployer.NewBackend()
deployments, err := deployL1Contracts(config, backend)
if err != nil {
return nil, err
}
depsByName := make(map[string]deployer.Deployment)
depsByAddr := make(map[common.Address]deployer.Deployment)
for _, dep := range deployments {
depsByName[dep.Name] = dep
depsByAddr[dep.Address] = dep
}
opts, err := bind.NewKeyedTransactorWithChainID(deployer.TestKey, deployer.ChainID)
if err != nil {
return nil, err
}
l2ooABI, err := bindings.L2OutputOracleMetaData.GetAbi()
if err != nil {
return nil, err
}
data, err := l2ooABI.Pack(
"initialize",
config.L2OutputOracleGenesisL2Output,
big.NewInt(0),
config.L2OutputOracleProposer,
config.L2OutputOracleOwner,
)
if err != nil {
return nil, err
}
if err := upgradeProxy(
backend,
opts,
depsByName["L2OutputOracleProxy"].Address,
depsByName["L2OutputOracle"].Address,
data,
); err != nil {
return nil, err
}
portalABI, err := bindings.OptimismPortalMetaData.GetAbi()
if err != nil {
return nil, err
}
data, err = portalABI.Pack("initialize")
if err != nil {
return nil, err
}
if err := upgradeProxy(
backend,
opts,
depsByName["OptimismPortalProxy"].Address,
depsByName["OptimismPortal"].Address,
data,
); err != nil {
return nil, err
}
l1XDMABI, err := bindings.L1CrossDomainMessengerMetaData.GetAbi()
if err != nil {
return nil, err
}
data, err = l1XDMABI.Pack("initialize")
if err != nil {
return nil, err
}
if err := upgradeProxy(
backend,
opts,
depsByName["L1CrossDomainMessengerProxy"].Address,
depsByName["L1CrossDomainMessenger"].Address,
data,
); err != nil {
return nil, err
}
l1SBrABI, err := bindings.L1StandardBridgeMetaData.GetAbi()
if err != nil {
return nil, err
}
data, err = l1SBrABI.Pack("initialize", predeploys.DevL1CrossDomainMessengerAddr)
if err != nil {
return nil, err
}
if err := upgradeProxy(
backend,
opts,
depsByName["L1StandardBridgeProxy"].Address,
depsByName["L1StandardBridge"].Address,
data,
); err != nil {
return nil, err
}
if err := upgradeProxy(
backend,
opts,
depsByName["OptimismMintableERC20FactoryProxy"].Address,
depsByName["OptimismMintableERC20Factory"].Address,
nil,
); err != nil {
return nil, err
}
backend.Commit()
memDB := state.NewMemoryStateDB(genesis)
if err := SetL1Proxies(memDB, predeploys.DevProxyAdminAddr); err != nil {
return nil, err
}
FundDevAccounts(memDB)
SetPrecompileBalances(memDB)
for name, proxyAddr := range predeploys.DevPredeploys {
memDB.SetState(*proxyAddr, ImplementationSlot, depsByName[name].Address.Hash())
}
stateDB, err := backend.Blockchain().State()
if err != nil {
return nil, err
}
for _, dep := range deployments {
st := stateDB.StorageTrie(dep.Address)
iter := trie.NewIterator(st.NodeIterator(nil))
FundDevAccounts(db)
SetPrecompileBalances(db)
depAddr := dep.Address
if strings.HasSuffix(dep.Name, "Proxy") {
depAddr = *predeploys.DevPredeploys[strings.TrimSuffix(dep.Name, "Proxy")]
}
return db.Genesis(), nil
memDB.CreateAccount(depAddr)
memDB.SetCode(depAddr, dep.Bytecode)
for iter.Next() {
_, data, _, err := rlp.Split(iter.Value)
if err != nil {
return nil, err
}
key := common.BytesToHash(st.GetKey(iter.Key))
value := common.BytesToHash(data)
if depAddr == predeploys.DevOptimismPortalAddr && key == portalMeteringSlot {
// We need to manually set the block number in the resource
// metering storage slot to zero. Otherwise, deposits will
// revert.
copy(value[:24], zeroHash[:])
}
memDB.SetState(depAddr, key, value)
}
}
return memDB.Genesis(), nil
}
func deployL1Contracts(config *DeployConfig, backend *backends.SimulatedBackend) ([]deployer.Deployment, error) {
constructors := make([]deployer.Constructor, 0)
for _, proxy := range proxies {
constructors = append(constructors, deployer.Constructor{
Name: proxy,
})
}
constructors = append(constructors, []deployer.Constructor{
{
Name: "L2OutputOracle",
Args: []interface{}{
uint642Big(config.L2OutputOracleSubmissionInterval),
[32]byte(config.L2OutputOracleGenesisL2Output),
big.NewInt(0),
big.NewInt(0),
uint642Big(uint64(config.L1GenesisBlockTimestamp)),
uint642Big(config.L2BlockTime),
config.L2OutputOracleProposer,
config.L2OutputOracleOwner,
},
},
{
Name: "OptimismPortal",
Args: []interface{}{
uint642Big(config.FinalizationPeriodSeconds),
},
},
{
Name: "L1CrossDomainMessenger",
},
{
Name: "L1StandardBridge",
},
{
Name: "OptimismMintableERC20Factory",
},
{
Name: "AddressManager",
},
{
Name: "ProxyAdmin",
Args: []interface{}{
common.Address{19: 0x01},
},
},
}...)
return deployer.Deploy(backend, constructors, l1Deployer)
}
func l1Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, deployment deployer.Constructor) (common.Address, error) {
var addr common.Address
var err error
switch deployment.Name {
case "L2OutputOracle":
addr, _, _, err = bindings.DeployL2OutputOracle(
opts,
backend,
deployment.Args[0].(*big.Int),
deployment.Args[1].([32]byte),
deployment.Args[2].(*big.Int),
deployment.Args[3].(*big.Int),
deployment.Args[4].(*big.Int),
deployment.Args[5].(*big.Int),
deployment.Args[6].(common.Address),
deployment.Args[7].(common.Address),
)
case "OptimismPortal":
addr, _, _, err = bindings.DeployOptimismPortal(
opts,
backend,
predeploys.DevL2OutputOracleAddr,
deployment.Args[0].(*big.Int),
)
case "L1CrossDomainMessenger":
addr, _, _, err = bindings.DeployL1CrossDomainMessenger(
opts,
backend,
predeploys.DevOptimismPortalAddr,
)
case "L1StandardBridge":
addr, _, _, err = bindings.DeployL1StandardBridge(
opts,
backend,
predeploys.DevL1CrossDomainMessengerAddr,
)
case "OptimismMintableERC20Factory":
addr, _, _, err = bindings.DeployOptimismMintableERC20Factory(
opts,
backend,
predeploys.DevL1StandardBridgeAddr,
)
case "AddressManager":
addr, _, _, err = bindings.DeployAddressManager(
opts,
backend,
)
case "ProxyAdmin":
addr, _, _, err = bindings.DeployProxyAdmin(
opts,
backend,
common.Address{},
)
default:
if strings.HasSuffix(deployment.Name, "Proxy") {
addr, _, _, err = bindings.DeployProxy(opts, backend, deployer.TestAddress)
} else {
err = fmt.Errorf("unknown contract %s", deployment.Name)
}
}
return addr, err
}
func upgradeProxy(backend *backends.SimulatedBackend, opts *bind.TransactOpts, proxyAddr common.Address, implAddr common.Address, callData []byte) error {
proxy, err := bindings.NewProxy(proxyAddr, backend)
if err != nil {
return err
}
if callData == nil {
_, err = proxy.UpgradeTo(opts, implAddr)
} else {
_, err = proxy.UpgradeToAndCall(
opts,
implAddr,
callData,
)
}
if err == nil {
backend.Commit()
}
return err
}
package genesis
import (
"bytes"
"encoding/json"
"math/big"
"os"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-chain-ops/deployer"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/stretchr/testify/require"
)
func TestBuildL1DeveloperGenesis(t *testing.T) {
b, err := os.ReadFile("testdata/test-deploy-config-full.json")
require.NoError(t, err)
dec := json.NewDecoder(bytes.NewReader(b))
config := new(DeployConfig)
require.NoError(t, dec.Decode(config))
config.L1GenesisBlockTimestamp = hexutil.Uint64(time.Now().Unix())
genesis, err := BuildL1DeveloperGenesis(config)
require.NoError(t, err)
sim := backends.NewSimulatedBackend(
genesis.Alloc,
15000000,
)
callOpts := &bind.CallOpts{}
oracle, err := bindings.NewL2OutputOracle(predeploys.DevL2OutputOracleAddr, sim)
require.NoError(t, err)
portal, err := bindings.NewOptimismPortal(predeploys.DevOptimismPortalAddr, sim)
require.NoError(t, err)
proposer, err := oracle.Proposer(callOpts)
require.NoError(t, err)
require.Equal(t, config.L2OutputOracleProposer, proposer)
owner, err := oracle.Owner(callOpts)
require.NoError(t, err)
require.Equal(t, config.L2OutputOracleOwner, owner)
// Same set of tests as exist in the deployment scripts
interval, err := oracle.SUBMISSIONINTERVAL(callOpts)
require.NoError(t, err)
require.EqualValues(t, config.L2OutputOracleSubmissionInterval, interval.Uint64())
histBlocks, err := oracle.HISTORICALTOTALBLOCKS(callOpts)
require.NoError(t, err)
require.EqualValues(t, 0, histBlocks.Uint64())
startBlock, err := oracle.STARTINGBLOCKNUMBER(callOpts)
require.NoError(t, err)
require.EqualValues(t, 0, startBlock.Uint64())
l2BlockTime, err := oracle.L2BLOCKTIME(callOpts)
require.NoError(t, err)
require.EqualValues(t, 2, l2BlockTime.Uint64())
oracleAddr, err := portal.L2ORACLE(callOpts)
require.NoError(t, err)
require.EqualValues(t, predeploys.DevL2OutputOracleAddr, oracleAddr)
msgr, err := bindings.NewL1CrossDomainMessenger(predeploys.DevL1CrossDomainMessengerAddr, sim)
require.NoError(t, err)
portalAddr, err := msgr.Portal(callOpts)
require.NoError(t, err)
require.Equal(t, predeploys.DevOptimismPortalAddr, portalAddr)
bridge, err := bindings.NewL1StandardBridge(predeploys.DevL1StandardBridgeAddr, sim)
require.NoError(t, err)
msgrAddr, err := bridge.Messenger(callOpts)
require.NoError(t, err)
require.Equal(t, predeploys.DevL1CrossDomainMessengerAddr, msgrAddr)
otherBridge, err := bridge.OtherBridge(callOpts)
require.NoError(t, err)
require.Equal(t, predeploys.L2StandardBridgeAddr, otherBridge)
factory, err := bindings.NewOptimismMintableERC20(predeploys.DevOptimismMintableERC20FactoryAddr, sim)
require.NoError(t, err)
bridgeAddr, err := factory.Bridge(callOpts)
require.NoError(t, err)
require.Equal(t, predeploys.DevL1StandardBridgeAddr, bridgeAddr)
// test that we can do deposits, etc.
priv, err := crypto.HexToECDSA("ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
require.NoError(t, err)
tOpts, err := bind.NewKeyedTransactorWithChainID(priv, deployer.ChainID)
require.NoError(t, err)
tOpts.Value = big.NewInt(0.001 * params.Ether)
tOpts.GasLimit = 1_000_000
_, err = bridge.DepositETH(tOpts, 200000, nil)
require.NoError(t, err)
}
package genesis
import (
"github.com/ethereum-optimism/optimism/op-chain-ops/hardhat"
"github.com/ethereum-optimism/optimism/op-chain-ops/state"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/core"
)
// BuildOptimismDeveloperGenesis will build the developer Optimism Genesis
type L2Addresses struct {
ProxyAdmin common.Address
L1StandardBridgeProxy common.Address
L1CrossDomainMessengerProxy common.Address
}
// BuildL2DeveloperGenesis will build the developer Optimism Genesis
// Block. Suitable for devnets.
func BuildOptimismDeveloperGenesis(hh *hardhat.Hardhat, config *DeployConfig, chain ethereum.ChainReader) (*core.Genesis, error) {
genspec, err := NewL2Genesis(config, chain)
func BuildL2DeveloperGenesis(config *DeployConfig, l1StartBlock *types.Block, l2Addrs *L2Addresses) (*core.Genesis, error) {
genspec, err := NewL2Genesis(config, l1StartBlock)
if err != nil {
return nil, err
}
db := state.NewMemoryStateDB(genspec)
if config.FundDevAccounts {
FundDevAccounts(db)
}
SetPrecompileBalances(db)
return BuildOptimismGenesis(db, hh, config, chain)
return BuildL2Genesis(db, config, l1StartBlock, l2Addrs)
}
// BuildOptimismGenesis will build the L2 Optimism Genesis Block
func BuildOptimismGenesis(db *state.MemoryStateDB, hh *hardhat.Hardhat, config *DeployConfig, chain ethereum.ChainReader) (*core.Genesis, error) {
// BuildL2Genesis will build the L2 Optimism Genesis Block
func BuildL2Genesis(db *state.MemoryStateDB, config *DeployConfig, l1Block *types.Block, l2Addrs *L2Addresses) (*core.Genesis, error) {
// TODO(tynes): need a function for clearing old, unused storage slots.
// Each deployed contract on L2 needs to have its existing storage
// inspected and then cleared if they are no longer used.
if err := SetProxies(hh, db); err != nil {
if err := SetL2Proxies(db, l2Addrs.ProxyAdmin); err != nil {
return nil, err
}
storage, err := NewStorageConfig(hh, config, chain)
storage, err := NewL2StorageConfig(
config,
l1Block,
l2Addrs.L1StandardBridgeProxy,
l2Addrs.L1CrossDomainMessengerProxy,
)
if err != nil {
return nil, err
}
if err := SetImplementations(hh, db, storage); err != nil {
if err := SetImplementations(db, storage); err != nil {
return nil, err
}
if err := MigrateDepositHashes(hh, db); err != nil {
if err := MigrateDepositHashes(db); err != nil {
return nil, err
}
......
package genesis_test
import (
"context"
"encoding/json"
"flag"
"io/ioutil"
"math/big"
"os"
"testing"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum-optimism/optimism/op-bindings/hardhat"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/hardhat"
"github.com/stretchr/testify/require"
)
......@@ -25,18 +30,18 @@ func init() {
var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
func TestBuildOptimismGenesis(t *testing.T) {
func TestBuildL2DeveloperGenesis(t *testing.T) {
hh, err := hardhat.New(
"goerli",
[]string{
"../../packages/contracts-bedrock/artifacts",
"../../packages/contracts-governance/artifacts",
},
nil,
[]string{"../../packages/contracts-bedrock/deployments"},
)
require.Nil(t, err)
config, err := genesis.NewDeployConfig("../../packages/contracts-bedrock/deploy-config/devnetL1.json")
config, err := genesis.NewDeployConfig("./testdata/test-deploy-config-devnet-l1.json")
require.Nil(t, err)
proxyAdmin, err := hh.GetDeployment("ProxyAdmin")
require.Nil(t, err)
backend := backends.NewSimulatedBackend(
......@@ -45,15 +50,16 @@ func TestBuildOptimismGenesis(t *testing.T) {
},
15000000,
)
gen, err := genesis.BuildOptimismDeveloperGenesis(hh, config, backend)
block, err := backend.BlockByNumber(context.Background(), common.Big0)
require.NoError(t, err)
gen, err := genesis.BuildL2DeveloperGenesis(config, block, &genesis.L2Addresses{
ProxyAdmin: proxyAdmin.Address,
})
require.Nil(t, err)
require.NotNil(t, gen)
proxyAdmin, err := hh.GetDeployment("ProxyAdmin")
require.Nil(t, err)
proxy, err := hh.GetArtifact("Proxy")
require.Nil(t, err)
depB, err := bindings.GetDeployedBytecode("Proxy")
require.NoError(t, err)
for name, address := range predeploys.Predeploys {
addr := *address
......@@ -69,11 +75,32 @@ func TestBuildOptimismGenesis(t *testing.T) {
adminSlot, ok := account.Storage[genesis.AdminSlot]
require.Equal(t, ok, true)
require.Equal(t, adminSlot, proxyAdmin.Address.Hash())
require.Equal(t, account.Code, []byte(proxy.DeployedBytecode))
require.Equal(t, account.Code, depB)
}
require.Equal(t, 2337, len(gen.Alloc))
if writeFile {
file, _ := json.MarshalIndent(gen, "", " ")
_ = ioutil.WriteFile("genesis.json", file, 0644)
_ = os.WriteFile("genesis.json", file, 0644)
}
}
func TestBuildL2DeveloperGenesisDevAccountsFunding(t *testing.T) {
config, err := genesis.NewDeployConfig("./testdata/test-deploy-config-devnet-l1.json")
require.Nil(t, err)
config.FundDevAccounts = false
backend := backends.NewSimulatedBackend(
core.GenesisAlloc{
crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000000000)},
},
15000000,
)
block, err := backend.BlockByNumber(context.Background(), common.Big0)
require.NoError(t, err)
gen, err := genesis.BuildL2DeveloperGenesis(config, block, &genesis.L2Addresses{
ProxyAdmin: common.Address{},
})
require.NoError(t, err)
require.Equal(t, 2316, len(gen.Alloc))
}
......@@ -4,8 +4,9 @@ import (
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/hardhat"
"github.com/ethereum-optimism/optimism/op-chain-ops/immutables"
"github.com/ethereum-optimism/optimism/op-chain-ops/state"
"github.com/ethereum/go-ethereum/common"
......@@ -20,22 +21,30 @@ func FundDevAccounts(db vm.StateDB) {
}
}
// SetProxies will set each of the proxies in the state. It requires
// SetL2Proxies will set each of the proxies in the state. It requires
// a Proxy and ProxyAdmin deployment present so that the Proxy bytecode
// can be set in state and the ProxyAdmin can be set as the admin of the
// Proxy.
func SetProxies(hh *hardhat.Hardhat, db vm.StateDB) error {
proxy, err := hh.GetArtifact("Proxy")
if err != nil {
return err
}
proxyAdmin, err := hh.GetDeployment("ProxyAdmin")
func SetL2Proxies(db vm.StateDB, proxyAdminAddr common.Address) error {
return setProxies(db, proxyAdminAddr, bigL2PredeployNamespace, 2048)
}
// SetL1Proxies will set each of the proxies in the state. It requires
// a Proxy and ProxyAdmin deployment present so that the Proxy bytecode
// can be set in state and the ProxyAdmin can be set as the admin of the
// Proxy.
func SetL1Proxies(db vm.StateDB, proxyAdminAddr common.Address) error {
return setProxies(db, proxyAdminAddr, bigL1PredeployNamespace, 2048)
}
func setProxies(db vm.StateDB, proxyAdminAddr common.Address, namespace *big.Int, count uint64) error {
depBytecode, err := bindings.GetDeployedBytecode("Proxy")
if err != nil {
return err
}
for i := uint64(0); i <= 2048; i++ {
bigAddr := new(big.Int).Or(bigPredeployNamespace, new(big.Int).SetUint64(i))
for i := uint64(0); i <= count; i++ {
bigAddr := new(big.Int).Or(namespace, new(big.Int).SetUint64(i))
addr := common.BigToAddress(bigAddr)
// There is no proxy at the governance token address
......@@ -44,8 +53,8 @@ func SetProxies(hh *hardhat.Hardhat, db vm.StateDB) error {
}
db.CreateAccount(addr)
db.SetCode(addr, proxy.DeployedBytecode)
db.SetState(addr, AdminSlot, proxyAdmin.Address.Hash())
db.SetCode(addr, depBytecode)
db.SetState(addr, AdminSlot, proxyAdminAddr.Hash())
}
return nil
}
......@@ -53,19 +62,13 @@ func SetProxies(hh *hardhat.Hardhat, db vm.StateDB) error {
// SetImplementations will set the implmentations of the contracts in the state
// and configure the proxies to point to the implementations. It also sets
// the appropriate storage values for each contract at the proxy address.
func SetImplementations(hh *hardhat.Hardhat, db vm.StateDB, storage StorageConfig) error {
func SetImplementations(db vm.StateDB, storage StorageConfig) error {
deployResults, err := immutables.BuildOptimism()
if err != nil {
return err
}
for name, address := range predeploys.Predeploys {
// Get the hardhat artifact to access the deployed bytecode
artifact, err := hh.GetArtifact(name)
if err != nil {
return err
}
// Convert the address to the code address
var addr common.Address
switch *address {
......@@ -78,7 +81,7 @@ func SetImplementations(hh *hardhat.Hardhat, db vm.StateDB, storage StorageConfi
if err != nil {
return err
}
// Set the implmentation slot in the predeploy proxy
// Set the implementation slot in the predeploy proxy
db.SetState(*address, ImplementationSlot, addr.Hash())
}
......@@ -90,12 +93,16 @@ func SetImplementations(hh *hardhat.Hardhat, db vm.StateDB, storage StorageConfi
if bytecode, ok := deployResults[name]; ok {
db.SetCode(addr, bytecode)
} else {
db.SetCode(addr, artifact.DeployedBytecode)
depBytecode, err := bindings.GetDeployedBytecode(name)
if err != nil {
return err
}
db.SetCode(addr, depBytecode)
}
// Set the storage values
if storageConfig, ok := storage[name]; ok {
layout, err := hh.GetStorageLayout(name)
layout, err := bindings.GetStorageLayout(name)
if err != nil {
return err
}
......@@ -120,8 +127,8 @@ func SetImplementations(hh *hardhat.Hardhat, db vm.StateDB, storage StorageConfi
// Get the storage layout of the L2ToL1MessagePasser
// Iterate over the storage layout to know which storage slots to ignore
// Iterate over each storage slot, compute the migration
func MigrateDepositHashes(hh *hardhat.Hardhat, db vm.StateDB) error {
layout, err := hh.GetStorageLayout("L2ToL1MessagePasser")
func MigrateDepositHashes(db vm.StateDB) error {
layout, err := bindings.GetStorageLayout("L2ToL1MessagePasser")
if err != nil {
return err
}
......@@ -138,14 +145,13 @@ func MigrateDepositHashes(hh *hardhat.Hardhat, db vm.StateDB) error {
ignore[encoded] = true
}
db.ForEachStorage(predeploys.L2ToL1MessagePasserAddr, func(key, value common.Hash) bool {
return db.ForEachStorage(predeploys.L2ToL1MessagePasserAddr, func(key, value common.Hash) bool {
if _, ok := ignore[key]; ok {
return true
}
// TODO(tynes): Do the value migration here
return true
})
return nil
}
// SetPrecompileBalances will set a single wei at each precompile address.
......
package genesis
import (
"archive/tar"
"compress/gzip"
"io"
"os"
"path/filepath"
)
func Untar(tarball, target string) error {
f, err := os.Open(tarball)
if err != nil {
return err
}
defer f.Close()
r, err := gzip.NewReader(f)
if err != nil {
return err
}
tarReader := tar.NewReader(r)
for {
header, err := tarReader.Next()
if err == io.EOF {
break
} else if err != nil {
return err
}
path := filepath.Join(target, header.Name)
info := header.FileInfo()
if info.IsDir() {
if err = os.MkdirAll(path, info.Mode()); err != nil {
return err
}
continue
}
file, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode())
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(file, tarReader)
if err != nil {
return err
}
}
return nil
}
{
"l1StartingBlockTag": "earliest",
"l1ChainID": 900,
"l2ChainID": 901,
"l2BlockTime": 2,
"maxSequencerDrift": 100,
"sequencerWindowSize": 4,
"channelTimeout": 40,
"p2pSequencerAddress": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
"optimismL2FeeRecipient": "0xd9c09e21b57c98e58a80552c170989b426766aa7",
"batchInboxAddress": "0xff00000000000000000000000000000000000000",
"batchSenderAddress": "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
"l2OutputOracleSubmissionInterval": 20,
"l2OutputOracleStartingTimestamp": -1,
"l2OutputOracleProposer": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
"l2OutputOracleOwner": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
"l1BlockTime": 15,
"cliqueSignerAddress": "0xca062b0fd91172d89bcd4bb084ac4e21972cc467",
"optimismBaseFeeRecipient": "0xBcd4042DE499D14e55001CcbB24a551F3b954096",
"optimismL1FeeRecipient": "0x71bE63f3384f5fb98995898A86B02Fb2426c5788",
"deploymentWaitConfirmations": 1,
"fundDevAccounts": true
}
{
"l1StartingBlockTag": null,
"l1ChainID": 901,
"l2ChainID": 902,
"l2BlockTime": 2,
"maxSequencerDrift": 20,
"sequencerWindowSize": 100,
"channelTimeout": 30,
"p2pSequencerAddress": "0x0000000000000000000000000000000000000000",
"optimismL2FeeRecipient": "0x42000000000000000000000000000000000000f0",
"batchInboxAddress": "0x42000000000000000000000000000000000000ff",
"batchSenderAddress": "0x0000000000000000000000000000000000000000",
"l2OutputOracleSubmissionInterval": 6,
"l2OutputOracleStartingTimestamp": -1,
"l2OutputOracleProposer": "0x7770000000000000000000000000000000000001",
"l2OutputOracleOwner": "0x7770000000000000000000000000000000000002",
"l1BlockTime": 15,
"l1GenesisBlockNonce": "0x0",
"cliqueSignerAddress": "0x0000000000000000000000000000000000000000",
"l1GenesisBlockGasLimit": "0xe4e1c0",
"l1GenesisBlockDifficulty": "0x1",
"finalizationPeriodSeconds": 2,
"l1GenesisBlockMixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"l1GenesisBlockCoinbase": "0x0000000000000000000000000000000000000000",
"l1GenesisBlockNumber": "0x0",
"l1GenesisBlockGasUsed": "0x0",
"l1GenesisBlockParentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"l1GenesisBlockTimestamp": "0x0",
"l1GenesisBlockBaseFeePerGas": "0x3b9aca00",
"l2GenesisBlockNonce": "0x0",
"l2GenesisBlockExtraData": "0x",
"l2GenesisBlockGasLimit": "0xe4e1c0",
"l2GenesisBlockDifficulty": "0x1",
"l2GenesisBlockMixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"l2GenesisBlockCoinbase": "0x42000000000000000000000000000000000000f0",
"l2OutputOracleGenesisL2Output": "0x0000000000000000000000000000000000000000000000000000000000000000",
"l2GenesisBlockNumber": "0x0",
"l2GenesisBlockGasUsed": "0x0",
"l2GenesisBlockParentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"l2GenesisBlockBaseFeePerGas": "0x3b9aca00",
"optimismBaseFeeRecipient": "0x42000000000000000000000000000000000000f1",
"optimismL1FeeRecipient": "0x0000000000000000000000000000000000000000",
"l2CrossDomainMessengerOwner": "0x42000000000000000000000000000000000000f2",
"gasPriceOracleOwner": "0x42000000000000000000000000000000000000f3",
"gasPriceOracleOverhead": 2100,
"gasPriceOracleScalar": 1000000,
"gasPriceOracleDecimals": 6,
"deploymentWaitConfirmations": 1,
"eip1559Denominator": 8,
"eip1559Elasticity": 2,
"fundDevAccounts": true
}
\ No newline at end of file
......@@ -4,12 +4,12 @@ go 1.18
require (
github.com/ethereum-optimism/optimism/l2geth v0.0.0-20220820030939-de38b6f6f77e
github.com/ethereum-optimism/optimism/op-bindings v0.4.0
github.com/ethereum/go-ethereum v1.10.21
github.com/ethereum-optimism/optimism/op-bindings v0.8.6
github.com/ethereum/go-ethereum v1.10.23
github.com/mattn/go-isatty v0.0.14
github.com/stretchr/testify v1.7.2
github.com/stretchr/testify v1.8.0
github.com/urfave/cli/v2 v2.10.2
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
)
require (
......@@ -29,16 +29,20 @@ require (
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/go-bexpr v0.1.11 // indirect
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/holiman/uint256 v1.2.0 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/tsdb v0.10.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rjeczalik/notify v0.9.2 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 // indirect
......@@ -48,7 +52,10 @@ require (
github.com/tklauser/numcpus v0.4.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
golang.org/x/sys v0.0.0-20220701225701-179beb0bd1a1 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/ethereum/go-ethereum v1.10.21 => github.com/ethereum-optimism/op-geth v0.0.0-20220904174542-4311f9d2cead
This diff is collapsed.
This diff is collapsed.
......@@ -8,7 +8,7 @@ import (
"regexp"
"strings"
"github.com/ethereum-optimism/optimism/op-chain-ops/solc"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
......
This diff is collapsed.
This diff is collapsed.
......@@ -624,4 +624,3 @@ func (_Testdata *TestdataSession) SetStorage(key [32]byte, value [32]byte) (*typ
func (_Testdata *TestdataTransactorSession) SetStorage(key [32]byte, value [32]byte) (*types.Transaction, error) {
return _Testdata.Contract.SetStorage(&_Testdata.TransactOpts, key, value)
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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