Commit 64c9b2e5 authored by Ethen Pociask's avatar Ethen Pociask

Merge branch 'develop' of https://github.com/epociask/optimism into...

Merge branch 'develop' of https://github.com/epociask/optimism into indexer.withdrawal_type_supplies
parents f0425638 a9650b9c
This diff is collapsed.
1a2e2e071ef0a1b6f41fdcba773b04c30498752f 3e962e2efe17396886fcb1fd141ccf4204cd3a21
...@@ -30,6 +30,8 @@ We recommend using the [Conventional Commits](https://www.conventionalcommits.or ...@@ -30,6 +30,8 @@ We recommend using the [Conventional Commits](https://www.conventionalcommits.or
Unless your PR is ready for immediate review and merging, please mark it as 'draft' (or simply do not open a PR yet). Unless your PR is ready for immediate review and merging, please mark it as 'draft' (or simply do not open a PR yet).
Once ready for review, make sure to include a thorough PR description to help reviewers. You can read more about the guidelines for opening PRs in the [PR Guidelines](./handbook/pr-guidelines.md) file.
**Bonus:** Add comments to the diff under the "Files Changed" tab on the PR page to clarify any sections where you think we might have questions about the approach taken. **Bonus:** Add comments to the diff under the "Files Changed" tab on the PR page to clarify any sections where you think we might have questions about the approach taken.
### Response time: ### Response time:
......
...@@ -39,6 +39,15 @@ golang-docker: ...@@ -39,6 +39,15 @@ golang-docker:
op-node op-batcher op-proposer op-challenger op-node op-batcher op-proposer op-challenger
.PHONY: golang-docker .PHONY: golang-docker
contracts-bedrock-docker:
IMAGE_TAGS=$$(git rev-parse HEAD),latest \
docker buildx bake \
--progress plain \
--load \
-f docker-bake.hcl \
contracts-bedrock
.PHONY: contracts-bedrock-docker
submodules: submodules:
git submodule update --init --recursive git submodule update --init --recursive
.PHONY: submodules .PHONY: submodules
......
...@@ -6,7 +6,6 @@ import ( ...@@ -6,7 +6,6 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"path"
"github.com/ethereum-optimism/optimism/op-service/ioutil" "github.com/ethereum-optimism/optimism/op-service/ioutil"
) )
...@@ -35,18 +34,16 @@ func writeJSON[X any](outputPath string, value X) error { ...@@ -35,18 +34,16 @@ func writeJSON[X any](outputPath string, value X) error {
var out io.Writer var out io.Writer
finish := func() error { return nil } finish := func() error { return nil }
if outputPath != "-" { if outputPath != "-" {
// Write to a tmp file but reserve the file extension if present f, err := ioutil.NewAtomicWriterCompressed(outputPath, 0755)
tmpPath := outputPath + "-tmp" + path.Ext(outputPath)
f, err := ioutil.OpenCompressed(tmpPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
if err != nil { if err != nil {
return fmt.Errorf("failed to open output file: %w", err) return fmt.Errorf("failed to open output file: %w", err)
} }
// Ensure we close the stream even if failures occur.
defer f.Close() defer f.Close()
out = f out = f
finish = func() error { // Closing the file causes it to be renamed to the final destination
// Rename the file into place as atomically as the OS will allow // so make sure we handle any errors it returns
return os.Rename(tmpPath, outputPath) finish = f.Close
}
} else { } else {
out = os.Stdout out = os.Stdout
} }
......
...@@ -80,13 +80,13 @@ func (m *MIPSEVM) Step(t *testing.T, stepWitness *StepWitness) []byte { ...@@ -80,13 +80,13 @@ func (m *MIPSEVM) Step(t *testing.T, stepWitness *StepWitness) []byte {
if stepWitness.HasPreimage() { if stepWitness.HasPreimage() {
t.Logf("reading preimage key %x at offset %d", stepWitness.PreimageKey, stepWitness.PreimageOffset) t.Logf("reading preimage key %x at offset %d", stepWitness.PreimageKey, stepWitness.PreimageOffset)
poInput, err := encodePreimageOracleInput(t, stepWitness, 0) poInput, err := encodePreimageOracleInput(t, stepWitness, LocalContext{})
require.NoError(t, err, "encode preimage oracle input") require.NoError(t, err, "encode preimage oracle input")
_, leftOverGas, err := m.env.Call(vm.AccountRef(sender), m.addrs.Oracle, poInput, startingGas, big.NewInt(0)) _, leftOverGas, err := m.env.Call(vm.AccountRef(sender), m.addrs.Oracle, poInput, startingGas, big.NewInt(0))
require.NoErrorf(t, err, "evm should not fail, took %d gas", startingGas-leftOverGas) require.NoErrorf(t, err, "evm should not fail, took %d gas", startingGas-leftOverGas)
} }
input := encodeStepInput(t, stepWitness, 0) input := encodeStepInput(t, stepWitness, LocalContext{})
ret, leftOverGas, err := m.env.Call(vm.AccountRef(sender), m.addrs.MIPS, input, startingGas, big.NewInt(0)) ret, leftOverGas, err := m.env.Call(vm.AccountRef(sender), m.addrs.MIPS, input, startingGas, big.NewInt(0))
require.NoError(t, err, "evm should not fail") require.NoError(t, err, "evm should not fail")
require.Len(t, ret, 32, "expecting 32-byte state hash") require.Len(t, ret, 32, "expecting 32-byte state hash")
...@@ -109,7 +109,7 @@ func encodeStepInput(t *testing.T, wit *StepWitness, localContext LocalContext) ...@@ -109,7 +109,7 @@ func encodeStepInput(t *testing.T, wit *StepWitness, localContext LocalContext)
mipsAbi, err := bindings.MIPSMetaData.GetAbi() mipsAbi, err := bindings.MIPSMetaData.GetAbi()
require.NoError(t, err) require.NoError(t, err)
input, err := mipsAbi.Pack("step", wit.State, wit.MemProof, new(big.Int).SetUint64(uint64(localContext))) input, err := mipsAbi.Pack("step", wit.State, wit.MemProof, localContext)
require.NoError(t, err) require.NoError(t, err)
return input return input
} }
...@@ -132,7 +132,7 @@ func encodePreimageOracleInput(t *testing.T, wit *StepWitness, localContext Loca ...@@ -132,7 +132,7 @@ func encodePreimageOracleInput(t *testing.T, wit *StepWitness, localContext Loca
copy(tmp[:], preimagePart) copy(tmp[:], preimagePart)
input, err := preimageAbi.Pack("loadLocalData", input, err := preimageAbi.Pack("loadLocalData",
new(big.Int).SetBytes(wit.PreimageKey[1:]), new(big.Int).SetBytes(wit.PreimageKey[1:]),
new(big.Int).SetUint64(uint64(localContext)), localContext,
tmp, tmp,
new(big.Int).SetUint64(uint64(len(preimagePart))), new(big.Int).SetUint64(uint64(len(preimagePart))),
new(big.Int).SetUint64(uint64(wit.PreimageOffset)), new(big.Int).SetUint64(uint64(wit.PreimageOffset)),
...@@ -292,7 +292,7 @@ func TestEVMFault(t *testing.T) { ...@@ -292,7 +292,7 @@ func TestEVMFault(t *testing.T) {
State: initialState.EncodeWitness(), State: initialState.EncodeWitness(),
MemProof: insnProof[:], MemProof: insnProof[:],
} }
input := encodeStepInput(t, stepWitness, 0) input := encodeStepInput(t, stepWitness, LocalContext{})
startingGas := uint64(30_000_000) startingGas := uint64(30_000_000)
_, _, err := env.Call(vm.AccountRef(sender), addrs.MIPS, input, startingGas, big.NewInt(0)) _, _, err := env.Call(vm.AccountRef(sender), addrs.MIPS, input, startingGas, big.NewInt(0))
......
package mipsevm package mipsevm
type LocalContext uint64 import "github.com/ethereum/go-ethereum/common"
type LocalContext common.Hash
type StepWitness struct { type StepWitness struct {
// encoded state witness // encoded state witness
......
...@@ -14,8 +14,10 @@ variable "GIT_DATE" { ...@@ -14,8 +14,10 @@ variable "GIT_DATE" {
default = "0" default = "0"
} }
// The default version to embed in the built images.
// During CI release builds this is set to <<pipeline.git.tag>>
variable "GIT_VERSION" { variable "GIT_VERSION" {
default = "docker" // original default as set in proxyd file, not used by full go stack, yet default = "v0.0.0"
} }
variable "IMAGE_TAGS" { variable "IMAGE_TAGS" {
...@@ -27,98 +29,129 @@ variable "PLATFORMS" { ...@@ -27,98 +29,129 @@ variable "PLATFORMS" {
// Only a specify a single platform when `--load` ing into docker. // Only a specify a single platform when `--load` ing into docker.
// Multi-platform is supported when outputting to disk or pushing to a registry. // Multi-platform is supported when outputting to disk or pushing to a registry.
// Multi-platform builds can be tested locally with: --set="*.output=type=image,push=false" // Multi-platform builds can be tested locally with: --set="*.output=type=image,push=false"
default = "linux/amd64" default = ""
} }
target "op-stack-go" { // Each of the services can have a customized version, but defaults to the global specified version.
variable "OP_NODE_VERSION" {
default = "${GIT_VERSION}"
}
variable "OP_BATCHER_VERSION" {
default = "${GIT_VERSION}"
}
variable "OP_PROPOSER_VERSION" {
default = "${GIT_VERSION}"
}
variable "OP_CHALLENGER_VERSION" {
default = "${GIT_VERSION}"
}
variable OP_HEARTBEAT_VERSION {
default = "${GIT_VERSION}"
}
variable OP_PROGRAM_VERSION {
default = "${GIT_VERSION}"
}
variable CANNON_VERSION {
default = "${GIT_VERSION}"
}
target "op-node" {
dockerfile = "ops/docker/op-stack-go/Dockerfile" dockerfile = "ops/docker/op-stack-go/Dockerfile"
context = "." context = "."
args = { args = {
GIT_COMMIT = "${GIT_COMMIT}" GIT_COMMIT = "${GIT_COMMIT}"
GIT_DATE = "${GIT_DATE}" GIT_DATE = "${GIT_DATE}"
OP_NODE_VERSION = "${OP_NODE_VERSION}"
} }
platforms = split(",", PLATFORMS) target = "op-node-target"
tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-stack-go:${tag}"]
}
target "op-node" {
dockerfile = "Dockerfile"
context = "./op-node"
args = {
OP_STACK_GO_BUILDER = "op-stack-go"
}
contexts = {
op-stack-go: "target:op-stack-go"
}
platforms = split(",", PLATFORMS) platforms = split(",", PLATFORMS)
tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-node:${tag}"] tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-node:${tag}"]
} }
target "op-batcher" { target "op-batcher" {
dockerfile = "Dockerfile" dockerfile = "ops/docker/op-stack-go/Dockerfile"
context = "./op-batcher" context = "."
args = { args = {
OP_STACK_GO_BUILDER = "op-stack-go" GIT_COMMIT = "${GIT_COMMIT}"
} GIT_DATE = "${GIT_DATE}"
contexts = { OP_BATCHER_VERSION = "${OP_BATCHER_VERSION}"
op-stack-go: "target:op-stack-go"
} }
target = "op-batcher-target"
platforms = split(",", PLATFORMS) platforms = split(",", PLATFORMS)
tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-batcher:${tag}"] tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-batcher:${tag}"]
} }
target "op-proposer" { target "op-proposer" {
dockerfile = "Dockerfile" dockerfile = "ops/docker/op-stack-go/Dockerfile"
context = "./op-proposer" context = "."
args = { args = {
OP_STACK_GO_BUILDER = "op-stack-go" GIT_COMMIT = "${GIT_COMMIT}"
} GIT_DATE = "${GIT_DATE}"
contexts = { OP_PROPOSER_VERSION = "${OP_PROPOSER_VERSION}"
op-stack-go: "target:op-stack-go"
} }
target = "op-proposer-target"
platforms = split(",", PLATFORMS) platforms = split(",", PLATFORMS)
tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-proposer:${tag}"] tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-proposer:${tag}"]
} }
target "op-challenger" { target "op-challenger" {
dockerfile = "Dockerfile" dockerfile = "ops/docker/op-stack-go/Dockerfile"
context = "./op-challenger" context = "."
args = { args = {
OP_STACK_GO_BUILDER = "op-stack-go" GIT_COMMIT = "${GIT_COMMIT}"
} GIT_DATE = "${GIT_DATE}"
contexts = { OP_CHALLENGER_VERSION = "${OP_CHALLENGER_VERSION}"
op-stack-go: "target:op-stack-go"
} }
target = "op-challenger-target"
platforms = split(",", PLATFORMS) platforms = split(",", PLATFORMS)
tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-challenger:${tag}"] tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-challenger:${tag}"]
} }
target "op-heartbeat" { target "op-heartbeat" {
dockerfile = "Dockerfile" dockerfile = "ops/docker/op-stack-go/Dockerfile"
context = "./op-heartbeat" context = "."
args = { args = {
OP_STACK_GO_BUILDER = "op-stack-go" GIT_COMMIT = "${GIT_COMMIT}"
} GIT_DATE = "${GIT_DATE}"
contexts = { OP_HEARTBEAT_VERSION = "${OP_HEARTBEAT_VERSION}"
op-stack-go: "target:op-stack-go"
} }
target = "op-heartbeat-target"
platforms = split(",", PLATFORMS) platforms = split(",", PLATFORMS)
tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-heartbeat:${tag}"] tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-heartbeat:${tag}"]
} }
target "op-program" { target "op-program" {
dockerfile = "Dockerfile" dockerfile = "ops/docker/op-stack-go/Dockerfile"
context = "./op-program" context = "."
args = { args = {
OP_STACK_GO_BUILDER = "op-stack-go" GIT_COMMIT = "${GIT_COMMIT}"
} GIT_DATE = "${GIT_DATE}"
contexts = { OP_PROGRAM_VERSION = "${OP_PROGRAM_VERSION}"
op-stack-go: "target:op-stack-go"
} }
target = "op-program-target"
platforms = split(",", PLATFORMS) platforms = split(",", PLATFORMS)
tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-program:${tag}"] tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/op-program:${tag}"]
} }
target "cannon" {
dockerfile = "ops/docker/op-stack-go/Dockerfile"
context = "."
args = {
GIT_COMMIT = "${GIT_COMMIT}"
GIT_DATE = "${GIT_DATE}"
CANNON_VERSION = "${CANNON_VERSION}"
}
target = "cannon-target"
platforms = split(",", PLATFORMS)
tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/cannon:${tag}"]
}
target "proxyd" { target "proxyd" {
dockerfile = "Dockerfile" dockerfile = "Dockerfile"
context = "./proxyd" context = "./proxyd"
...@@ -180,4 +213,10 @@ target "ci-builder" { ...@@ -180,4 +213,10 @@ target "ci-builder" {
tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/ci-builder:${tag}"] tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/ci-builder:${tag}"]
} }
target "contracts-bedrock" {
dockerfile = "./ops/docker/Dockerfile.packages"
context = "."
target = "contracts-bedrock"
platforms = split(",", PLATFORMS)
tags = [for tag in split(",", IMAGE_TAGS) : "${REGISTRY}/${REPOSITORY}/contracts-bedrock:${tag}"]
}
# Pull Request Guidelines and Best Practices
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Overview](#overview)
- [PR Lifecycle Best Practices](#pr-lifecycle-best-practices)
- [Before Starting PRs](#before-starting-prs)
- [Opening PRs](#opening-prs)
- [Reviewing PRs](#reviewing-prs)
- [Merging PRs](#merging-prs)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Overview
This document contains guidelines best practices for PRs that should be enforced as much as possible. The motivations and goals behind these best practices are:
- **Ensure thorough reviews**: By the time the PR is merged, at least one other person—because there is always at least one reviewer—should understand the PR’s changes just as well as the PR author. This helps improve security by reducing bugs and single points of failure (i.e. there should never be only one person who understands certain code).
- **Reduce PR churn**: PRs should be quickly reviewable and mergeable without much churn (both in terms of code rewrites and comment cycles). This saves time by reducing the number of rebases due to conflicts. Similarly, too many review cycles is a burden for both PR authors and reviewers, and results in “review fatigue” where reviews become less careful and thorough, increasing the likelihood of bugs.
- **Traceability**: We should be able to look back at issues and PRs to understand why a certain decision was made or why a given approach was taken.
## PR Lifecycle Best Practices
This is organized by current state of PR, so it can be easily be referenced frequently to help internalize the guidelines.
### Before Starting PRs
- **Keep PRs Focused**: Each PR should be a single, narrow, well-defined scope.
### Opening PRs
- **Review Your Own Code**: Reviewing the diff yourself *in a different context*, can be very useful for discovering issues, typos, and bugs before opening the PR. For example, write code in your IDE, then review it in the GitHub diff view. The perspective change forces you to slow down and helps reveal issues you may have missed.
- **Explain Decisions/Tradeoffs**: Explain rationale for any design/architecture decisions and implementation details in the PR description. If it closes an issue, remember to mention the issue it closes, e.g. `Closes <issueUrl>`. Otherwise, just link to the issue. If there is no issue, whatever details would have been in the issue should be in the PR description.
- **Guide PR reviewers:** Let them know about areas of concern, under-tested areas, or vague requirements that should be ironed out.
### Reviewing PRs
- **Verify Requirements are Met**: If the PR claims to fix or close an issue, check that all the requirements in the issue are actually met. Otherwise the issue may be in a good place to merge, but just shouldn’t close the issue.
- **Focus on Tests**: The tests are the spec and therefore should be the focus of reviews. If tests are thorough and passing, the rest is an implementation detail (to an extent—don’t skip source code reviews) that can be fixed in a future optimization/cleanup PR. Make sure edge case behaviors are defined and handled.
- **Think like an Auditor:** What edge cases were ignored? How can the code break? When might it behave incorrectly and unexpectedly? What code should have been changed that isn’t in the diff? What implicit assumptions are made that might be invalid?
- **Ensure Comment Significance is Clear**: Indicate which comments are nits/optionals that the PR author can resolve, compared to which you want to follow up on.
- Prefix non-blocking comments with `[nit]` or `[non-blocking]`.
- **Consider Reviewing in Your IDE**: For example, GitHub has [this VSCode extension](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github) to review PRs. This provides more code context and enables review to benefit from your standard lints and IDE features, whereas GitHub’s diff shows none of that.
### Merging PRs
- **Resolve all Comments**: Comments can be resolved by (1) the PR author for nits/optionals, (2) the author or reviewer after discussions, or (3) extracting the comment into an issue to address in a future PR. For (3), ensure the new issue links to the specific comment thread. This is currently enforced by GitHub's merge requirements.
- **Other Standard Merge Requirements**: The PR must be approved by the appropriate reviewers, CI must passing, and other standard merge requirements apply.
...@@ -9,7 +9,7 @@ require ( ...@@ -9,7 +9,7 @@ require (
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231030223232-e16eae11e492 github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231030223232-e16eae11e492
github.com/ethereum/go-ethereum v1.13.1 github.com/ethereum/go-ethereum v1.13.5
github.com/fsnotify/fsnotify v1.7.0 github.com/fsnotify/fsnotify v1.7.0
github.com/go-chi/chi/v5 v5.0.10 github.com/go-chi/chi/v5 v5.0.10
github.com/go-chi/docgen v1.2.0 github.com/go-chi/docgen v1.2.0
...@@ -71,7 +71,7 @@ require ( ...@@ -71,7 +71,7 @@ require (
github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/crate-crypto/go-ipa v0.0.0-20230601170251-1830d0757c80 // indirect github.com/crate-crypto/go-ipa v0.0.0-20230601170251-1830d0757c80 // indirect
github.com/crate-crypto/go-kzg-4844 v0.3.0 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
github.com/deckarep/golang-set/v2 v2.1.0 // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect
...@@ -81,7 +81,7 @@ require ( ...@@ -81,7 +81,7 @@ require (
github.com/docker/go-units v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect
github.com/elastic/gosigar v0.14.2 // indirect github.com/elastic/gosigar v0.14.2 // indirect
github.com/ethereum/c-kzg-4844 v0.3.1 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect
github.com/fatih/color v1.13.0 // indirect github.com/fatih/color v1.13.0 // indirect
github.com/felixge/fgprof v0.9.3 // indirect github.com/felixge/fgprof v0.9.3 // indirect
github.com/fjl/memsize v0.0.1 // indirect github.com/fjl/memsize v0.0.1 // indirect
...@@ -210,7 +210,7 @@ require ( ...@@ -210,7 +210,7 @@ require (
rsc.io/tmplfunc v0.0.3 // indirect rsc.io/tmplfunc v0.0.3 // indirect
) )
replace github.com/ethereum/go-ethereum v1.13.1 => github.com/ethereum-optimism/op-geth v1.101304.0-rc.2.0.20231030225546-cd491fa3b588 replace github.com/ethereum/go-ethereum v1.13.5 => github.com/ethereum-optimism/op-geth v1.101304.2-0.20231123204650-32ddd8bd7cfe
//replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain //replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain
//replace github.com/ethereum/go-ethereum v1.13.1 => ../go-ethereum //replace github.com/ethereum/go-ethereum v1.13.5 => ../go-ethereum
...@@ -103,8 +103,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHH ...@@ -103,8 +103,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHH
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/crate-crypto/go-ipa v0.0.0-20230601170251-1830d0757c80 h1:DuBDHVjgGMPki7bAyh91+3cF1Vh34sAEdH8JQgbc2R0= github.com/crate-crypto/go-ipa v0.0.0-20230601170251-1830d0757c80 h1:DuBDHVjgGMPki7bAyh91+3cF1Vh34sAEdH8JQgbc2R0=
github.com/crate-crypto/go-ipa v0.0.0-20230601170251-1830d0757c80/go.mod h1:gzbVz57IDJgQ9rLQwfSk696JGWof8ftznEL9GoAv3NI= github.com/crate-crypto/go-ipa v0.0.0-20230601170251-1830d0757c80/go.mod h1:gzbVz57IDJgQ9rLQwfSk696JGWof8ftznEL9GoAv3NI=
github.com/crate-crypto/go-kzg-4844 v0.3.0 h1:UBlWE0CgyFqqzTI+IFyCzA7A3Zw4iip6uzRv5NIXG0A= github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA=
github.com/crate-crypto/go-kzg-4844 v0.3.0/go.mod h1:SBP7ikXEgDnUPONgm33HtuDZEDtWa3L4QtN1ocJSEQ4= github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
...@@ -134,8 +134,6 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm ...@@ -134,8 +134,6 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY=
github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
...@@ -151,12 +149,12 @@ github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/ ...@@ -151,12 +149,12 @@ github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/
github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs=
github.com/ethereum-optimism/op-geth v1.101304.0-rc.2.0.20231030225546-cd491fa3b588 h1:jrvFoV3aSGJcTT8Pyo8R2Sp7CZ0v3hqrdhfSmyZbJVw= github.com/ethereum-optimism/op-geth v1.101304.2-0.20231123204650-32ddd8bd7cfe h1:fh0BJoqdlp2CY9gPNrc/xM6nrwb84j82dFzIyq42cBM=
github.com/ethereum-optimism/op-geth v1.101304.0-rc.2.0.20231030225546-cd491fa3b588/go.mod h1:12W+vBetjYbDj5D2+V8hizke5yWuLrUDf7UmVkXTnCQ= github.com/ethereum-optimism/op-geth v1.101304.2-0.20231123204650-32ddd8bd7cfe/go.mod h1:KyXcYdAJTSm8tvOmd+KPeOygiA+FEE5VX3vs2WwjwQ4=
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231030223232-e16eae11e492 h1:FyzLzMLKMc9zcDYcSxbrLDglIRrGQJE9juFzIO35RmE= github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231030223232-e16eae11e492 h1:FyzLzMLKMc9zcDYcSxbrLDglIRrGQJE9juFzIO35RmE=
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231030223232-e16eae11e492/go.mod h1:/70H/KqrtKcvWvNGVj6S3rAcLC+kUPr3t2aDmYIS+Xk= github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231030223232-e16eae11e492/go.mod h1:/70H/KqrtKcvWvNGVj6S3rAcLC+kUPr3t2aDmYIS+Xk=
github.com/ethereum/c-kzg-4844 v0.3.1 h1:sR65+68+WdnMKxseNWxSJuAv2tsUrihTpVBTfM/U5Zg= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY=
github.com/ethereum/c-kzg-4844 v0.3.1/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
......
...@@ -14,6 +14,7 @@ COPY ./indexer /app/indexer ...@@ -14,6 +14,7 @@ COPY ./indexer /app/indexer
COPY ./op-bindings /app/op-bindings COPY ./op-bindings /app/op-bindings
COPY ./op-service /app/op-service COPY ./op-service /app/op-service
COPY ./op-node /app/op-node COPY ./op-node /app/op-node
COPY ./op-chain-ops /app/op-chain-ops
WORKDIR /app/indexer WORKDIR /app/indexer
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
"url": "https://github.com/ethereum-optimism/optimism.git" "url": "https://github.com/ethereum-optimism/optimism.git"
}, },
"devDependencies": { "devDependencies": {
"tsup": "^7.2.0", "tsup": "^8.0.1",
"vitest": "^0.34.4" "vitest": "^0.34.4"
} }
} }
...@@ -39,6 +39,11 @@ type L2BridgeMessage struct { ...@@ -39,6 +39,11 @@ type L2BridgeMessage struct {
TransactionWithdrawalHash common.Hash `gorm:"serializer:bytes"` TransactionWithdrawalHash common.Hash `gorm:"serializer:bytes"`
} }
type L2BridgeMessageVersionedMessageHash struct {
MessageHash common.Hash `gorm:"primaryKey;serializer:bytes"`
V1MessageHash common.Hash `gorm:"serializer:bytes"`
}
type BridgeMessagesView interface { type BridgeMessagesView interface {
L1BridgeMessage(common.Hash) (*L1BridgeMessage, error) L1BridgeMessage(common.Hash) (*L1BridgeMessage, error)
L1BridgeMessageWithFilter(BridgeMessage) (*L1BridgeMessage, error) L1BridgeMessageWithFilter(BridgeMessage) (*L1BridgeMessage, error)
...@@ -55,6 +60,8 @@ type BridgeMessagesDB interface { ...@@ -55,6 +60,8 @@ type BridgeMessagesDB interface {
StoreL2BridgeMessages([]L2BridgeMessage) error StoreL2BridgeMessages([]L2BridgeMessage) error
MarkRelayedL2BridgeMessage(common.Hash, uuid.UUID) error MarkRelayedL2BridgeMessage(common.Hash, uuid.UUID) error
StoreL2BridgeMessageV1MessageHashes([]L2BridgeMessageVersionedMessageHash) error
} }
/** /**
...@@ -134,8 +141,33 @@ func (db bridgeMessagesDB) StoreL2BridgeMessages(messages []L2BridgeMessage) err ...@@ -134,8 +141,33 @@ func (db bridgeMessagesDB) StoreL2BridgeMessages(messages []L2BridgeMessage) err
return result.Error return result.Error
} }
func (db bridgeMessagesDB) StoreL2BridgeMessageV1MessageHashes(versionedHashes []L2BridgeMessageVersionedMessageHash) error {
deduped := db.gorm.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "message_hash"}}, DoNothing: true})
result := deduped.Create(&versionedHashes)
if result.Error == nil && int(result.RowsAffected) < len(versionedHashes) {
db.log.Warn("ignored L2 bridge v1 message hash duplicates", "duplicates", len(versionedHashes)-int(result.RowsAffected))
}
return result.Error
}
func (db bridgeMessagesDB) L2BridgeMessage(msgHash common.Hash) (*L2BridgeMessage, error) { func (db bridgeMessagesDB) L2BridgeMessage(msgHash common.Hash) (*L2BridgeMessage, error) {
return db.L2BridgeMessageWithFilter(BridgeMessage{MessageHash: msgHash}) message, err := db.L2BridgeMessageWithFilter(BridgeMessage{MessageHash: msgHash})
if message != nil || err != nil {
return message, err
}
// check if this is a v1 hash of an older message
versioned := L2BridgeMessageVersionedMessageHash{V1MessageHash: msgHash}
result := db.gorm.Where(&versioned).Take(&versioned)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, result.Error
}
return db.L2BridgeMessageWithFilter(BridgeMessage{MessageHash: versioned.MessageHash})
} }
func (db bridgeMessagesDB) L2BridgeMessageWithFilter(filter BridgeMessage) (*L2BridgeMessage, error) { func (db bridgeMessagesDB) L2BridgeMessageWithFilter(filter BridgeMessage) (*L2BridgeMessage, error) {
......
...@@ -13,8 +13,10 @@ import ( ...@@ -13,8 +13,10 @@ import (
"github.com/ethereum-optimism/optimism/indexer/client" "github.com/ethereum-optimism/optimism/indexer/client"
"github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/config"
"github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/database"
"github.com/prometheus/client_golang/prometheus"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e" op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-service/metrics"
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
...@@ -30,7 +32,8 @@ import ( ...@@ -30,7 +32,8 @@ import (
*/ */
type E2ETestSuite struct { type E2ETestSuite struct {
t *testing.T t *testing.T
MetricsRegistry *prometheus.Registry
// API // API
Client *client.Client Client *client.Client
...@@ -152,14 +155,15 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite { ...@@ -152,14 +155,15 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
require.NoError(t, err, "must open indexer API client") require.NoError(t, err, "must open indexer API client")
return E2ETestSuite{ return E2ETestSuite{
t: t, t: t,
Client: client, MetricsRegistry: metrics.NewRegistry(),
DB: ix.DB, Client: client,
Indexer: ix, DB: ix.DB,
OpCfg: &opCfg, Indexer: ix,
OpSys: opSys, OpCfg: &opCfg,
L1Client: opSys.Clients["l1"], OpSys: opSys,
L2Client: opSys.Clients["sequencer"], L1Client: opSys.Clients["l1"],
L2Client: opSys.Clients["sequencer"],
} }
} }
......
...@@ -4,12 +4,11 @@ import ( ...@@ -4,12 +4,11 @@ import (
"errors" "errors"
"math/big" "math/big"
"github.com/ethereum-optimism/optimism/indexer/processors/contracts"
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
) )
type CrossDomainMessengerSentMessage struct { type CrossDomainMessengerSentMessage struct {
...@@ -40,7 +39,17 @@ func ParseCrossDomainMessage(sentMessageReceipt *types.Receipt) (CrossDomainMess ...@@ -40,7 +39,17 @@ func ParseCrossDomainMessage(sentMessageReceipt *types.Receipt) (CrossDomainMess
if err != nil { if err != nil {
return CrossDomainMessengerSentMessage{}, err return CrossDomainMessengerSentMessage{}, err
} }
msgHash, err := CrossDomainMessengerSentMessageHash(sentMessage, sentMessageExtension.Value)
msg := crossdomain.NewCrossDomainMessage(
sentMessage.MessageNonce,
sentMessage.Sender,
sentMessage.Target,
sentMessageExtension.Value,
sentMessage.GasLimit,
sentMessage.Message,
)
msgHash, err := msg.Hash()
if err != nil { if err != nil {
return CrossDomainMessengerSentMessage{}, err return CrossDomainMessengerSentMessage{}, err
} }
...@@ -51,17 +60,3 @@ func ParseCrossDomainMessage(sentMessageReceipt *types.Receipt) (CrossDomainMess ...@@ -51,17 +60,3 @@ func ParseCrossDomainMessage(sentMessageReceipt *types.Receipt) (CrossDomainMess
return CrossDomainMessengerSentMessage{}, errors.New("missing SentMessage receipts") return CrossDomainMessengerSentMessage{}, errors.New("missing SentMessage receipts")
} }
func CrossDomainMessengerSentMessageHash(sentMessage *bindings.CrossDomainMessengerSentMessage, value *big.Int) (common.Hash, error) {
abi, err := bindings.CrossDomainMessengerMetaData.GetAbi()
if err != nil {
return common.Hash{}, err
}
calldata, err := contracts.CrossDomainMessageCalldata(abi, sentMessage, value)
if err != nil {
return common.Hash{}, err
}
return crypto.Keccak256Hash(calldata), nil
}
...@@ -176,6 +176,22 @@ CREATE INDEX IF NOT EXISTS l2_bridge_messages_timestamp ON l2_bridge_messages(ti ...@@ -176,6 +176,22 @@ CREATE INDEX IF NOT EXISTS l2_bridge_messages_timestamp ON l2_bridge_messages(ti
CREATE INDEX IF NOT EXISTS l2_bridge_messages_transaction_withdrawal_hash ON l2_bridge_messages(transaction_withdrawal_hash); CREATE INDEX IF NOT EXISTS l2_bridge_messages_transaction_withdrawal_hash ON l2_bridge_messages(transaction_withdrawal_hash);
CREATE INDEX IF NOT EXISTS l2_bridge_messages_from_address ON l2_bridge_messages(from_address); CREATE INDEX IF NOT EXISTS l2_bridge_messages_from_address ON l2_bridge_messages(from_address);
/**
* Since the CDM uses the latest versioned message hash when emitting the `RelayedMessage` event, we need
* to keep track of all of the future versions of message hashes such that legacy messages can be queried
* queried for when relayed on L1
*
* As new the CDM is updated with new versions, we need to ensure that there's a better way to correlate message between
* chains (adding the message nonce to the RelayedMessage event) or continue to add columns to this table and migrate
* unrelayed messages such that finalization logic can handle switching between the varying versioned message hashes
*/
CREATE TABLE IF NOT EXISTS l2_bridge_message_versioned_message_hashes(
message_hash VARCHAR PRIMARY KEY NOT NULL UNIQUE REFERENCES l2_bridge_messages(message_hash),
-- only filled in if `message_hash` is for a v0 message
v1_message_hash VARCHAR UNIQUE
);
-- StandardBridge -- StandardBridge
CREATE TABLE IF NOT EXISTS l1_bridge_deposits ( CREATE TABLE IF NOT EXISTS l1_bridge_deposits (
transaction_source_hash VARCHAR PRIMARY KEY REFERENCES l1_transaction_deposits(source_hash) ON DELETE CASCADE, transaction_source_hash VARCHAR PRIMARY KEY REFERENCES l1_transaction_deposits(source_hash) ON DELETE CASCADE,
......
...@@ -256,7 +256,7 @@ func (b *BridgeProcessor) processInitiatedL2Events() error { ...@@ -256,7 +256,7 @@ func (b *BridgeProcessor) processInitiatedL2Events() error {
legacyBridgeLog := l2BridgeLog.New("mode", "legacy", "from_block_number", legacyFromL2Height, "to_block_number", legacyToL2Height) legacyBridgeLog := l2BridgeLog.New("mode", "legacy", "from_block_number", legacyFromL2Height, "to_block_number", legacyToL2Height)
legacyBridgeLog.Info("scanning for initiated bridge events") legacyBridgeLog.Info("scanning for initiated bridge events")
if err := bridge.LegacyL2ProcessInitiatedBridgeEvents(legacyBridgeLog, tx, b.metrics, b.chainConfig.L2Contracts, legacyFromL2Height, legacyToL2Height); err != nil { if err := bridge.LegacyL2ProcessInitiatedBridgeEvents(legacyBridgeLog, tx, b.metrics, b.chainConfig.Preset, b.chainConfig.L2Contracts, legacyFromL2Height, legacyToL2Height); err != nil {
return err return err
} else if legacyToL2Height.Cmp(toL2Height) == 0 { } else if legacyToL2Height.Cmp(toL2Height) == 0 {
return nil // a-ok! Entire range was legacy blocks return nil // a-ok! Entire range was legacy blocks
...@@ -312,7 +312,7 @@ func (b *BridgeProcessor) processFinalizedL1Events() error { ...@@ -312,7 +312,7 @@ func (b *BridgeProcessor) processFinalizedL1Events() error {
legacyBridgeLog := l1BridgeLog.New("mode", "legacy", "from_block_number", legacyFromL1Height, "to_block_number", legacyToL1Height) legacyBridgeLog := l1BridgeLog.New("mode", "legacy", "from_block_number", legacyFromL1Height, "to_block_number", legacyToL1Height)
legacyBridgeLog.Info("scanning for finalized bridge events") legacyBridgeLog.Info("scanning for finalized bridge events")
if err := bridge.LegacyL1ProcessFinalizedBridgeEvents(legacyBridgeLog, tx, b.metrics, b.l1Etl.EthClient, b.chainConfig.L1Contracts, legacyFromL1Height, legacyToL1Height); err != nil { if err := bridge.LegacyL1ProcessFinalizedBridgeEvents(legacyBridgeLog, tx, b.metrics, b.chainConfig.L1Contracts, legacyFromL1Height, legacyToL1Height); err != nil {
return err return err
} else if legacyToL1Height.Cmp(toL1Height) == 0 { } else if legacyToL1Height.Cmp(toL1Height) == 0 {
return nil // a-ok! Entire range was legacy blocks return nil // a-ok! Entire range was legacy blocks
......
...@@ -7,6 +7,7 @@ import ( ...@@ -7,6 +7,7 @@ import (
"github.com/ethereum-optimism/optimism/indexer/bigint" "github.com/ethereum-optimism/optimism/indexer/bigint"
"github.com/ethereum-optimism/optimism/indexer/config" "github.com/ethereum-optimism/optimism/indexer/config"
"github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/indexer/processors/bridge/ovm1"
"github.com/ethereum-optimism/optimism/indexer/processors/contracts" "github.com/ethereum-optimism/optimism/indexer/processors/contracts"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -155,21 +156,30 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M ...@@ -155,21 +156,30 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M
log.Info("detected proven withdrawals", "size", len(provenWithdrawals)) log.Info("detected proven withdrawals", "size", len(provenWithdrawals))
} }
skippedOVM1ProvenWithdrawals := 0
for i := range provenWithdrawals { for i := range provenWithdrawals {
proven := provenWithdrawals[i] provenWithdrawal := provenWithdrawals[i]
withdrawal, err := db.BridgeTransactions.L2TransactionWithdrawal(proven.WithdrawalHash) withdrawal, err := db.BridgeTransactions.L2TransactionWithdrawal(provenWithdrawal.WithdrawalHash)
if err != nil { if err != nil {
return err return err
} else if withdrawal == nil { } else if withdrawal == nil {
return fmt.Errorf("missing indexed withdrawal! tx_hash = %s", proven.Event.TransactionHash) if _, ok := ovm1.PortalWithdrawalTransactions[provenWithdrawal.WithdrawalHash]; ok {
skippedOVM1ProvenWithdrawals++
continue
}
return fmt.Errorf("missing indexed withdrawal! tx_hash = %s", provenWithdrawal.Event.TransactionHash)
} }
if err := db.BridgeTransactions.MarkL2TransactionWithdrawalProvenEvent(proven.WithdrawalHash, provenWithdrawals[i].Event.GUID); err != nil { if err := db.BridgeTransactions.MarkL2TransactionWithdrawalProvenEvent(provenWithdrawal.WithdrawalHash, provenWithdrawals[i].Event.GUID); err != nil {
return fmt.Errorf("failed to mark withdrawal as proven. tx_hash = %s: %w", proven.Event.TransactionHash, err) return fmt.Errorf("failed to mark withdrawal as proven. tx_hash = %s: %w", provenWithdrawal.Event.TransactionHash, err)
} }
} }
if len(provenWithdrawals) > 0 { if len(provenWithdrawals) > 0 {
metrics.RecordL1ProvenWithdrawals(len(provenWithdrawals)) metrics.RecordL1ProvenWithdrawals(len(provenWithdrawals))
if skippedOVM1ProvenWithdrawals > 0 {
metrics.RecordL1SkippedOVM1ProvenWithdrawals(skippedOVM1ProvenWithdrawals)
log.Info("skipped OVM 1.0 proven withdrawals", "size", skippedOVM1ProvenWithdrawals)
}
} }
// (2) OptimismPortal (finalized withdrawals) // (2) OptimismPortal (finalized withdrawals)
...@@ -181,12 +191,17 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M ...@@ -181,12 +191,17 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M
log.Info("detected finalized withdrawals", "size", len(finalizedWithdrawals)) log.Info("detected finalized withdrawals", "size", len(finalizedWithdrawals))
} }
skippedOVM1FinalizedWithdrawals := 0
for i := range finalizedWithdrawals { for i := range finalizedWithdrawals {
finalizedWithdrawal := finalizedWithdrawals[i] finalizedWithdrawal := finalizedWithdrawals[i]
withdrawal, err := db.BridgeTransactions.L2TransactionWithdrawal(finalizedWithdrawal.WithdrawalHash) withdrawal, err := db.BridgeTransactions.L2TransactionWithdrawal(finalizedWithdrawal.WithdrawalHash)
if err != nil { if err != nil {
return err return err
} else if withdrawal == nil { } else if withdrawal == nil {
if _, ok := ovm1.PortalWithdrawalTransactions[finalizedWithdrawal.WithdrawalHash]; ok {
skippedOVM1FinalizedWithdrawals++
continue
}
return fmt.Errorf("missing indexed withdrawal on finalization! tx_hash = %s", finalizedWithdrawal.Event.TransactionHash.String()) return fmt.Errorf("missing indexed withdrawal on finalization! tx_hash = %s", finalizedWithdrawal.Event.TransactionHash.String())
} }
...@@ -196,6 +211,10 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M ...@@ -196,6 +211,10 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M
} }
if len(finalizedWithdrawals) > 0 { if len(finalizedWithdrawals) > 0 {
metrics.RecordL1FinalizedWithdrawals(len(finalizedWithdrawals)) metrics.RecordL1FinalizedWithdrawals(len(finalizedWithdrawals))
if skippedOVM1ProvenWithdrawals > 0 {
metrics.RecordL1SkippedOVM1FinalizedWithdrawals(skippedOVM1FinalizedWithdrawals)
log.Info("skipped OVM 1.0 finalized withdrawals", "size", skippedOVM1FinalizedWithdrawals)
}
} }
// (3) L1CrossDomainMessenger // (3) L1CrossDomainMessenger
...@@ -207,21 +226,30 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M ...@@ -207,21 +226,30 @@ func L1ProcessFinalizedBridgeEvents(log log.Logger, db *database.DB, metrics L1M
log.Info("detected relayed messages", "size", len(crossDomainRelayedMessages)) log.Info("detected relayed messages", "size", len(crossDomainRelayedMessages))
} }
skippedOVM1Messages := 0
for i := range crossDomainRelayedMessages { for i := range crossDomainRelayedMessages {
relayed := crossDomainRelayedMessages[i] relayedMessage := crossDomainRelayedMessages[i]
message, err := db.BridgeMessages.L2BridgeMessage(relayed.MessageHash) message, err := db.BridgeMessages.L2BridgeMessage(relayedMessage.MessageHash)
if err != nil { if err != nil {
return err return err
} else if message == nil { } else if message == nil {
return fmt.Errorf("missing indexed L2CrossDomainMessager message! tx_hash = %s", relayed.Event.TransactionHash.String()) if _, ok := ovm1.L1RelayedMessages[relayedMessage.MessageHash]; ok {
skippedOVM1Messages++
continue
}
return fmt.Errorf("missing indexed L2CrossDomainMessager message! tx_hash = %s", relayedMessage.Event.TransactionHash.String())
} }
if err := db.BridgeMessages.MarkRelayedL2BridgeMessage(relayed.MessageHash, relayed.Event.GUID); err != nil { if err := db.BridgeMessages.MarkRelayedL2BridgeMessage(relayedMessage.MessageHash, relayedMessage.Event.GUID); err != nil {
return fmt.Errorf("failed to relay cross domain message. tx_hash = %s: %w", relayed.Event.TransactionHash, err) return fmt.Errorf("failed to relay cross domain message. tx_hash = %s: %w", relayedMessage.Event.TransactionHash, err)
} }
} }
if len(crossDomainRelayedMessages) > 0 { if len(crossDomainRelayedMessages) > 0 {
metrics.RecordL1CrossDomainRelayedMessages(len(crossDomainRelayedMessages)) metrics.RecordL1CrossDomainRelayedMessages(len(crossDomainRelayedMessages))
if skippedOVM1Messages > 0 { // Logged as a warning just for visibility
metrics.RecordL1SkippedOVM1CrossDomainRelayedMessages(skippedOVM1Messages)
log.Info("skipped OVM 1.0 relayed L2CrossDomainMessenger withdrawals", "size", skippedOVM1Messages)
}
} }
// (4) L1StandardBridge // (4) L1StandardBridge
......
package bridge
import (
"testing"
"github.com/ethereum-optimism/optimism/indexer/bigint"
"github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/indexer/processors/contracts"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/require"
)
func TestLegacyWithdrawalAndMessageHash(t *testing.T) {
// Pre-Bedrock OP-Goerli withdrawal that was proven post-bedrock
// - L1 proven withdrawal tx: 0xa8853a3532f40052385602c66512e438bc1e3736d3cb7abde359f5b9377441c7
value := bigint.Zero
expectedWithdrawalHash := common.HexToHash("0xae99d25df3e38730f6ee6588733417e20a131923b84870be6aedb4f863b6302d")
// Ensure the L2 Tx which correlates with the above proven withdrawal results in the same computed withdrawal hash
// - L2 withdrawal tx: 0x254d9c28add020404142f840ed794cea51f86c0f0a737e3e7bdd7e1e4550962e
abi, err := bindings.CrossDomainMessengerMetaData.GetAbi()
require.NoError(t, err)
var sentMessage bindings.CrossDomainMessengerSentMessage
sentMessageEvent := abi.Events["SentMessage"]
logData := common.FromHex("0x0000000000000000000000004200000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e4a9f9e67500000000000000000000000007865c6e87b9f70255377e024ace6630c1eaa37f0000000000000000000000003b8e53b3ab8e01fb57d0c9e893bc4d655aa67d84000000000000000000000000b91882244f7f82540f2941a759724523c7b9a166000000000000000000000000b91882244f7f82540f2941a759724523c7b9a166000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
require.NoError(t, contracts.UnpackLog(&sentMessage, &types.Log{Data: logData, Topics: []common.Hash{sentMessageEvent.ID, common.HexToHash("0x000000000000000000000000636af16bf2f682dd3109e60102b8e1a089fedaa8")}}, sentMessageEvent.Name, abi))
// timestamp and message hash are filled in fields. not core to the event
msg := database.BridgeMessage{
Nonce: sentMessage.MessageNonce,
GasLimit: sentMessage.GasLimit,
Tx: database.Transaction{FromAddress: sentMessage.Sender, ToAddress: sentMessage.Target, Amount: value, Data: sentMessage.Message},
}
hash, err := legacyBridgeMessageWithdrawalHash(420, &msg)
require.NoError(t, err)
require.Equal(t, expectedWithdrawalHash, hash)
// Ensure the relayed message hash (v1) matches
expectedMessageHash := common.HexToHash("0xcb16ecc1967f5d7aed909349a4351d28fbb396429ef7faf1c9d2a670e3ca906f")
v1MessageHash, err := legacyBridgeMessageV1MessageHash(&msg)
require.NoError(t, err)
require.Equal(t, expectedMessageHash, v1MessageHash)
}
...@@ -25,6 +25,10 @@ type L1Metricer interface { ...@@ -25,6 +25,10 @@ type L1Metricer interface {
RecordL1CrossDomainSentMessages(size int) RecordL1CrossDomainSentMessages(size int)
RecordL1CrossDomainRelayedMessages(size int) RecordL1CrossDomainRelayedMessages(size int)
RecordL1SkippedOVM1ProvenWithdrawals(size int)
RecordL1SkippedOVM1FinalizedWithdrawals(size int)
RecordL1SkippedOVM1CrossDomainRelayedMessages(size int)
RecordL1InitiatedBridgeTransfers(token common.Address, size int) RecordL1InitiatedBridgeTransfers(token common.Address, size int)
RecordL1FinalizedBridgeTransfers(token common.Address, size int) RecordL1FinalizedBridgeTransfers(token common.Address, size int)
} }
...@@ -56,15 +60,19 @@ type bridgeMetrics struct { ...@@ -56,15 +60,19 @@ type bridgeMetrics struct {
intervalFailures *prometheus.CounterVec intervalFailures *prometheus.CounterVec
txDeposits prometheus.Counter txDeposits prometheus.Counter
txMintedETH prometheus.Counter
txWithdrawals prometheus.Counter txWithdrawals prometheus.Counter
txWithdrawnETH prometheus.Counter
provenWithdrawals prometheus.Counter provenWithdrawals prometheus.Counter
finalizedWithdrawals prometheus.Counter finalizedWithdrawals prometheus.Counter
txMintedETH prometheus.Counter
txWithdrawnETH prometheus.Counter
sentMessages *prometheus.CounterVec sentMessages *prometheus.CounterVec
relayedMessages *prometheus.CounterVec relayedMessages *prometheus.CounterVec
skippedOVM1Withdrawals *prometheus.CounterVec
skippedOVM1RelayedMessages prometheus.Counter
initiatedBridgeTransfers *prometheus.CounterVec initiatedBridgeTransfers *prometheus.CounterVec
finalizedBridgeTransfers *prometheus.CounterVec finalizedBridgeTransfers *prometheus.CounterVec
} }
...@@ -114,7 +122,7 @@ func NewMetrics(registry *prometheus.Registry) Metricer { ...@@ -114,7 +122,7 @@ func NewMetrics(registry *prometheus.Registry) Metricer {
txWithdrawals: factory.NewCounter(prometheus.CounterOpts{ txWithdrawals: factory.NewCounter(prometheus.CounterOpts{
Namespace: MetricsNamespace, Namespace: MetricsNamespace,
Name: "tx_withdrawals", Name: "tx_withdrawals",
Help: "number of processed transactions withdrawn from l2", Help: "number of initiated transaction withdrawals from l2",
}), }),
txWithdrawnETH: factory.NewCounter(prometheus.CounterOpts{ txWithdrawnETH: factory.NewCounter(prometheus.CounterOpts{
Namespace: MetricsNamespace, Namespace: MetricsNamespace,
...@@ -145,6 +153,18 @@ func NewMetrics(registry *prometheus.Registry) Metricer { ...@@ -145,6 +153,18 @@ func NewMetrics(registry *prometheus.Registry) Metricer {
}, []string{ }, []string{
"chain", "chain",
}), }),
skippedOVM1Withdrawals: factory.NewCounterVec(prometheus.CounterOpts{
Namespace: MetricsNamespace,
Name: "skipped_ovm1_withdrawals",
Help: "number of skipped ovm 1.0 withdrawals on l1 (proven|finalized)",
}, []string{
"stage",
}),
skippedOVM1RelayedMessages: factory.NewCounter(prometheus.CounterOpts{
Namespace: MetricsNamespace,
Name: "skipped_ovm1_relayed_messages",
Help: "number of skipped ovm 1.0 relayed messages on l1",
}),
initiatedBridgeTransfers: factory.NewCounterVec(prometheus.CounterOpts{ initiatedBridgeTransfers: factory.NewCounterVec(prometheus.CounterOpts{
Namespace: MetricsNamespace, Namespace: MetricsNamespace,
Name: "initiated_token_transfers", Name: "initiated_token_transfers",
...@@ -206,6 +226,18 @@ func (m *bridgeMetrics) RecordL1CrossDomainRelayedMessages(size int) { ...@@ -206,6 +226,18 @@ func (m *bridgeMetrics) RecordL1CrossDomainRelayedMessages(size int) {
m.relayedMessages.WithLabelValues("l1").Add(float64(size)) m.relayedMessages.WithLabelValues("l1").Add(float64(size))
} }
func (m *bridgeMetrics) RecordL1SkippedOVM1ProvenWithdrawals(size int) {
m.skippedOVM1Withdrawals.WithLabelValues("stage", "proven").Add(float64(size))
}
func (m *bridgeMetrics) RecordL1SkippedOVM1FinalizedWithdrawals(size int) {
m.skippedOVM1Withdrawals.WithLabelValues("stage", "finalized").Add(float64(size))
}
func (m *bridgeMetrics) RecordL1SkippedOVM1CrossDomainRelayedMessages(size int) {
m.skippedOVM1RelayedMessages.Add(float64(size))
}
func (m *bridgeMetrics) RecordL1InitiatedBridgeTransfers(tokenAddr common.Address, size int) { func (m *bridgeMetrics) RecordL1InitiatedBridgeTransfers(tokenAddr common.Address, size int) {
m.initiatedBridgeTransfers.WithLabelValues("l1", tokenAddr.String()).Add(float64(size)) m.initiatedBridgeTransfers.WithLabelValues("l1", tokenAddr.String()).Add(float64(size))
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -4,43 +4,18 @@ import ( ...@@ -4,43 +4,18 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum-optimism/optimism/indexer/bigint"
"github.com/ethereum-optimism/optimism/indexer/database" "github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
) "github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
var (
// Standard ABI types copied from golang ABI tests
uint256Type, _ = abi.NewType("uint256", "", nil)
bytesType, _ = abi.NewType("bytes", "", nil)
addressType, _ = abi.NewType("address", "", nil)
CrossDomainMessengerLegacyRelayMessageEncoding = abi.NewMethod(
"relayMessage",
"relayMessage",
abi.Function,
"external", // mutability
false, // isConst
true, // payable
abi.Arguments{ // inputs
{Name: "target", Type: addressType},
{Name: "sender", Type: addressType},
{Name: "data", Type: bytesType},
{Name: "nonce", Type: uint256Type},
// The actual transaction on the legacy L1CrossDomainMessenger has a trailing
// proof argument but is ignored for the `XDomainCallData` encoding
},
abi.Arguments{}, // outputs
)
) )
type CrossDomainMessengerSentMessageEvent struct { type CrossDomainMessengerSentMessageEvent struct {
Event *database.ContractEvent Event *database.ContractEvent
MessageCalldata []byte BridgeMessage database.BridgeMessage
BridgeMessage database.BridgeMessage Version uint16
} }
type CrossDomainMessengerRelayedMessageEvent struct { type CrossDomainMessengerRelayedMessageEvent struct {
...@@ -85,32 +60,47 @@ func CrossDomainMessengerSentMessageEvents(chainSelector string, contractAddress ...@@ -85,32 +60,47 @@ func CrossDomainMessengerSentMessageEvents(chainSelector string, contractAddress
return nil, err return nil, err
} }
version, _ := DecodeVersionedNonce(sentMessage.MessageNonce) _, versionBig := crossdomain.DecodeVersionedNonce(sentMessage.MessageNonce)
version := uint16(versionBig.Uint64())
if i < numVersionZeroMessages && version != 0 { if i < numVersionZeroMessages && version != 0 {
return nil, fmt.Errorf("expected version zero nonce. nonce %d tx_hash %s", sentMessage.MessageNonce, sentMessage.Raw.TxHash) return nil, fmt.Errorf("expected version zero nonce: nonce %d, tx_hash %s", sentMessage.MessageNonce, sentMessage.Raw.TxHash)
} }
// In version zero, to value is bridged through the cross domain messenger. value := bigint.Zero
value := big.NewInt(0) var messageHash common.Hash
if version > 0 { switch version {
case 0:
messageHash, err = crossdomain.HashCrossDomainMessageV0(sentMessage.Target, sentMessage.Sender, sentMessage.Message, sentMessage.MessageNonce)
if err != nil {
return nil, err
}
case 1:
sentMessageExtension := bindings.CrossDomainMessengerSentMessageExtension1{Raw: *sentMessageExtensionEvents[i].RLPLog} sentMessageExtension := bindings.CrossDomainMessengerSentMessageExtension1{Raw: *sentMessageExtensionEvents[i].RLPLog}
err = UnpackLog(&sentMessageExtension, sentMessageExtensionEvents[i].RLPLog, sentMessageExtensionEventAbi.Name, crossDomainMessengerAbi) err = UnpackLog(&sentMessageExtension, sentMessageExtensionEvents[i].RLPLog, sentMessageExtensionEventAbi.Name, crossDomainMessengerAbi)
if err != nil { if err != nil {
return nil, err return nil, err
} }
value = sentMessageExtension.Value value = sentMessageExtension.Value
} messageHash, err = crossdomain.HashCrossDomainMessageV1(sentMessage.MessageNonce, sentMessage.Sender, sentMessage.Target, value, sentMessage.GasLimit, sentMessage.Message)
if err != nil {
return nil, err
}
messageCalldata, err := CrossDomainMessageCalldata(crossDomainMessengerAbi, &sentMessage, value) default:
if err != nil { // NOTE: We explicitly fail here since the presence of a new version means finalization
return nil, err // logic needs to be updated to ensure L1 finalization can run from genesis and handle
// the changing version formats. Any unrelayed OVM1 messages that have been harcoded with
// the v1 hash format also need to be updated. This failure is a serving indicator
return nil, fmt.Errorf("expected cross domain version 0 or version 1: %d", version)
} }
crossDomainSentMessages[i] = CrossDomainMessengerSentMessageEvent{ crossDomainSentMessages[i] = CrossDomainMessengerSentMessageEvent{
Event: &sentMessageEvents[i], Event: &sentMessageEvents[i],
MessageCalldata: messageCalldata, Version: version,
BridgeMessage: database.BridgeMessage{ BridgeMessage: database.BridgeMessage{
MessageHash: crypto.Keccak256Hash(messageCalldata), MessageHash: messageHash,
Nonce: sentMessage.MessageNonce, Nonce: sentMessage.MessageNonce,
SentMessageEventGUID: sentMessageEvents[i].GUID, SentMessageEventGUID: sentMessageEvents[i].GUID,
GasLimit: sentMessage.GasLimit, GasLimit: sentMessage.GasLimit,
...@@ -157,26 +147,3 @@ func CrossDomainMessengerRelayedMessageEvents(chainSelector string, contractAddr ...@@ -157,26 +147,3 @@ func CrossDomainMessengerRelayedMessageEvents(chainSelector string, contractAddr
return crossDomainRelayedMessages, nil return crossDomainRelayedMessages, nil
} }
// Replica of `Encoding.sol#encodeCrossDomainMessage` solidity implementation
func CrossDomainMessageCalldata(abi *abi.ABI, sentMsg *bindings.CrossDomainMessengerSentMessage, value *big.Int) ([]byte, error) {
version, _ := DecodeVersionedNonce(sentMsg.MessageNonce)
switch version {
case 0:
// Legacy Message
inputBytes, err := CrossDomainMessengerLegacyRelayMessageEncoding.Inputs.Pack(sentMsg.Target, sentMsg.Sender, sentMsg.Message, sentMsg.MessageNonce)
if err != nil {
return nil, err
}
return append(CrossDomainMessengerLegacyRelayMessageEncoding.ID, inputBytes...), nil
case 1:
// Current Message
msgBytes, err := abi.Pack("relayMessage", sentMsg.MessageNonce, sentMsg.Sender, sentMsg.Target, value, sentMsg.GasLimit, sentMsg.Message)
if err != nil {
return nil, err
}
return msgBytes, nil
}
return nil, fmt.Errorf("unsupported cross domain messenger version: %d", version)
}
...@@ -30,12 +30,6 @@ type OptimismPortalWithdrawalFinalizedEvent struct { ...@@ -30,12 +30,6 @@ type OptimismPortalWithdrawalFinalizedEvent struct {
Event *database.ContractEvent Event *database.ContractEvent
} }
type OptimismPortalProvenWithdrawal struct {
OutputRoot [32]byte
Timestamp *big.Int
L2OutputIndex *big.Int
}
func OptimismPortalTransactionDepositEvents(contractAddress common.Address, db *database.DB, fromHeight, toHeight *big.Int) ([]OptimismPortalTransactionDepositEvent, error) { func OptimismPortalTransactionDepositEvents(contractAddress common.Address, db *database.DB, fromHeight, toHeight *big.Int) ([]OptimismPortalTransactionDepositEvent, error) {
optimismPortalAbi, err := bindings.OptimismPortalMetaData.GetAbi() optimismPortalAbi, err := bindings.OptimismPortalMetaData.GetAbi()
if err != nil { if err != nil {
......
package contracts package contracts
import ( import (
"encoding/binary"
"errors" "errors"
"fmt" "fmt"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
) )
// DecodeVersionNonce is an re-implementation of Encoding.sol#decodeVersionedNonce.
// If the nonce is greater than 32 bytes (solidity uint256), bytes [32:] are ignored
func DecodeVersionedNonce(nonce *big.Int) (uint16, *big.Int) {
nonceBytes := nonce.Bytes()
nonceByteLen := len(nonceBytes)
if nonceByteLen < 30 {
// version is 0x0000
return 0, nonce
} else if nonceByteLen == 31 {
// version is 0x00[01..ff]
return uint16(nonceBytes[0]), new(big.Int).SetBytes(nonceBytes[1:])
} else {
// fully specified
version := binary.BigEndian.Uint16(nonceBytes[:2])
return version, new(big.Int).SetBytes(nonceBytes[2:])
}
}
func UnpackLog(out interface{}, log *types.Log, name string, contractAbi *abi.ABI) error { func UnpackLog(out interface{}, log *types.Log, name string, contractAbi *abi.ABI) error {
eventAbi, ok := contractAbi.Events[name] eventAbi, ok := contractAbi.Events[name]
if !ok { if !ok {
......
ARG OP_STACK_GO_BUILDER=us-docker.pkg.dev/oplabs-tools-artifacts/images/op-stack-go:latest
FROM $OP_STACK_GO_BUILDER as builder
# See "make golang-docker" and /ops/docker/op-stack-go
FROM alpine:3.18
COPY --from=builder /usr/local/bin/op-batcher /usr/local/bin/op-batcher
CMD ["op-batcher"]
# ignore everything but the dockerfile, the op-stack-go base image performs the build
*
...@@ -312,6 +312,10 @@ func (bs *BatcherService) Stop(ctx context.Context) error { ...@@ -312,6 +312,10 @@ func (bs *BatcherService) Stop(ctx context.Context) error {
result = errors.Join(result, fmt.Errorf("failed to close balance metricer: %w", err)) result = errors.Join(result, fmt.Errorf("failed to close balance metricer: %w", err))
} }
} }
if bs.TxManager != nil {
bs.TxManager.Close()
}
if bs.metricsSrv != nil { if bs.metricsSrv != nil {
if err := bs.metricsSrv.Stop(ctx); err != nil { if err := bs.metricsSrv.Stop(ctx); err != nil {
result = errors.Join(result, fmt.Errorf("failed to stop metrics server: %w", err)) result = errors.Join(result, fmt.Errorf("failed to stop metrics server: %w", err))
......
This diff is collapsed.
...@@ -13,7 +13,7 @@ const AlphabetVMStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\": ...@@ -13,7 +13,7 @@ const AlphabetVMStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":
var AlphabetVMStorageLayout = new(solc.StorageLayout) var AlphabetVMStorageLayout = new(solc.StorageLayout)
var AlphabetVMDeployedBin = "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80637dc0d1d01461003b578063836e7b3214610085575b600080fd5b60005461005b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610098610093366004610213565b6100a6565b60405190815260200161007c565b600080600060087f0000000000000000000000000000000000000000000000000000000000000000901b600889896040516100e2929190610287565b6040518091039020901b03610108576000915061010187890189610297565b9050610127565b610114878901896102b0565b90925090508161012381610301565b9250505b81610133826001610339565b604080516020810193909352820152606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001798975050505050505050565b60008083601f8401126101dc57600080fd5b50813567ffffffffffffffff8111156101f457600080fd5b60208301915083602082850101111561020c57600080fd5b9250929050565b60008060008060006060868803121561022b57600080fd5b853567ffffffffffffffff8082111561024357600080fd5b61024f89838a016101ca565b9097509550602088013591508082111561026857600080fd5b50610275888289016101ca565b96999598509660400135949350505050565b8183823760009101908152919050565b6000602082840312156102a957600080fd5b5035919050565b600080604083850312156102c357600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610332576103326102d2565b5060010190565b6000821982111561034c5761034c6102d2565b50019056fea164736f6c634300080f000a" var AlphabetVMDeployedBin = "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80637dc0d1d01461003b578063e14ced3214610085575b600080fd5b60005461005b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b610098610093366004610213565b6100a6565b60405190815260200161007c565b600080600060087f0000000000000000000000000000000000000000000000000000000000000000901b600889896040516100e2929190610287565b6040518091039020901b03610108576000915061010187890189610297565b9050610127565b610114878901896102b0565b90925090508161012381610301565b9250505b81610133826001610339565b604080516020810193909352820152606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001798975050505050505050565b60008083601f8401126101dc57600080fd5b50813567ffffffffffffffff8111156101f457600080fd5b60208301915083602082850101111561020c57600080fd5b9250929050565b60008060008060006060868803121561022b57600080fd5b853567ffffffffffffffff8082111561024357600080fd5b61024f89838a016101ca565b9097509550602088013591508082111561026857600080fd5b50610275888289016101ca565b96999598509660400135949350505050565b8183823760009101908152919050565b6000602082840312156102a957600080fd5b5035919050565b600080604083850312156102c357600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610332576103326102d2565b5060010190565b6000821982111561034c5761034c6102d2565b50019056fea164736f6c634300080f000a"
func init() { func init() {
if err := json.Unmarshal([]byte(AlphabetVMStorageLayoutJSON), AlphabetVMStorageLayout); err != nil { if err := json.Unmarshal([]byte(AlphabetVMStorageLayoutJSON), AlphabetVMStorageLayout); err != nil {
......
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.
package predeploys
import (
"github.com/ethereum/go-ethereum/common"
)
type DeployConfig interface {
GovernanceEnabled() bool
CanyonTime(genesisTime uint64) *uint64
}
type Predeploy struct {
Address common.Address
ProxyDisabled bool
Enabled func(config DeployConfig) bool
}
This diff is collapsed.
...@@ -32,6 +32,11 @@ type Constructor struct { ...@@ -32,6 +32,11 @@ type Constructor struct {
Args []interface{} Args []interface{}
} }
type SuperchainPredeploy struct {
Name string
CodeHash common.Hash
}
type Deployment struct { type Deployment struct {
Name string Name string
Bytecode hexutil.Bytes Bytecode hexutil.Bytes
...@@ -70,6 +75,8 @@ func NewBackendWithGenesisTimestamp(ts uint64, shanghai bool) *backends.Simulate ...@@ -70,6 +75,8 @@ func NewBackendWithGenesisTimestamp(ts uint64, shanghai bool) *backends.Simulate
LondonBlock: big.NewInt(0), LondonBlock: big.NewInt(0),
ArrowGlacierBlock: big.NewInt(0), ArrowGlacierBlock: big.NewInt(0),
GrayGlacierBlock: big.NewInt(0), GrayGlacierBlock: big.NewInt(0),
ShanghaiTime: nil,
CancunTime: nil,
// Activated proof of stake. We manually build/commit blocks in the simulator anyway, // Activated proof of stake. We manually build/commit blocks in the simulator anyway,
// and the timestamp verification of PoS is not against the wallclock, // and the timestamp verification of PoS is not against the wallclock,
// preventing blocks from getting stuck temporarily in the future-blocks queue, decreasing setup time a lot. // preventing blocks from getting stuck temporarily in the future-blocks queue, decreasing setup time a lot.
......
This diff is collapsed.
...@@ -64,6 +64,7 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro ...@@ -64,6 +64,7 @@ func NewL2Genesis(config *DeployConfig, block *types.Block) (*core.Genesis, erro
RegolithTime: config.RegolithTime(block.Time()), RegolithTime: config.RegolithTime(block.Time()),
CanyonTime: config.CanyonTime(block.Time()), CanyonTime: config.CanyonTime(block.Time()),
ShanghaiTime: config.CanyonTime(block.Time()), ShanghaiTime: config.CanyonTime(block.Time()),
CancunTime: nil, // no Dencun on L2 yet.
Optimism: &params.OptimismConfig{ Optimism: &params.OptimismConfig{
EIP1559Denominator: eip1559Denom, EIP1559Denominator: eip1559Denom,
EIP1559Elasticity: eip1559Elasticity, EIP1559Elasticity: eip1559Elasticity,
...@@ -134,6 +135,8 @@ func NewL1Genesis(config *DeployConfig) (*core.Genesis, error) { ...@@ -134,6 +135,8 @@ func NewL1Genesis(config *DeployConfig) (*core.Genesis, error) {
LondonBlock: big.NewInt(0), LondonBlock: big.NewInt(0),
ArrowGlacierBlock: big.NewInt(0), ArrowGlacierBlock: big.NewInt(0),
GrayGlacierBlock: big.NewInt(0), GrayGlacierBlock: big.NewInt(0),
ShanghaiTime: nil,
CancunTime: nil,
} }
extraData := make([]byte, 0) extraData := make([]byte, 0)
...@@ -168,6 +171,10 @@ func NewL1Genesis(config *DeployConfig) (*core.Genesis, error) { ...@@ -168,6 +171,10 @@ func NewL1Genesis(config *DeployConfig) (*core.Genesis, error) {
if timestamp == 0 { if timestamp == 0 {
timestamp = hexutil.Uint64(time.Now().Unix()) timestamp = hexutil.Uint64(time.Now().Unix())
} }
if !config.L1UseClique && config.L1CancunTimeOffset != nil {
cancunTime := uint64(timestamp) + *config.L1CancunTimeOffset
chainConfig.CancunTime = &cancunTime
}
return &core.Genesis{ return &core.Genesis{
Config: &chainConfig, Config: &chainConfig,
......
...@@ -18,13 +18,13 @@ var ( ...@@ -18,13 +18,13 @@ var (
codeNamespace = common.HexToAddress("0xc0D3C0d3C0d3C0D3c0d3C0d3c0D3C0d3c0d30000") codeNamespace = common.HexToAddress("0xc0D3C0d3C0d3C0D3c0d3C0d3c0D3C0d3c0d30000")
// l2PredeployNamespace represents the namespace of L2 predeploys // l2PredeployNamespace represents the namespace of L2 predeploys
l2PredeployNamespace = common.HexToAddress("0x4200000000000000000000000000000000000000") l2PredeployNamespace = common.HexToAddress("0x4200000000000000000000000000000000000000")
// bigL2PredeployNamespace represents the predeploy namespace as a big.Int // BigL2PredeployNamespace represents the predeploy namespace as a big.Int
BigL2PredeployNamespace = new(big.Int).SetBytes(l2PredeployNamespace.Bytes()) BigL2PredeployNamespace = new(big.Int).SetBytes(l2PredeployNamespace.Bytes())
// bigCodeNamespace represents the predeploy namespace as a big.Int // bigCodeNamespace represents the predeploy namespace as a big.Int
bigCodeNameSpace = new(big.Int).SetBytes(codeNamespace.Bytes()) bigCodeNamespace = new(big.Int).SetBytes(codeNamespace.Bytes())
// implementationSlot represents the EIP 1967 implementation storage slot // ImplementationSlot represents the EIP 1967 implementation storage slot
ImplementationSlot = common.HexToHash("0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc") ImplementationSlot = common.HexToHash("0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc")
// implementationSlot represents the EIP 1967 admin storage slot // AdminSlot represents the EIP 1967 admin storage slot
AdminSlot = common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103") AdminSlot = common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103")
) )
...@@ -69,7 +69,7 @@ func AddressToCodeNamespace(addr common.Address) (common.Address, error) { ...@@ -69,7 +69,7 @@ func AddressToCodeNamespace(addr common.Address) (common.Address, error) {
return common.Address{}, fmt.Errorf("cannot handle non predeploy: %s", addr) return common.Address{}, fmt.Errorf("cannot handle non predeploy: %s", addr)
} }
bigAddress := new(big.Int).SetBytes(addr[18:]) bigAddress := new(big.Int).SetBytes(addr[18:])
num := new(big.Int).Or(bigCodeNameSpace, bigAddress) num := new(big.Int).Or(bigCodeNamespace, bigAddress)
return common.BigToAddress(num), nil return common.BigToAddress(num), nil
} }
......
This diff is collapsed.
...@@ -18,6 +18,7 @@ import ( ...@@ -18,6 +18,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys" "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/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/immutables"
"github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/eth"
) )
...@@ -48,14 +49,14 @@ func testBuildL2Genesis(t *testing.T, config *genesis.DeployConfig) *core.Genesi ...@@ -48,14 +49,14 @@ func testBuildL2Genesis(t *testing.T, config *genesis.DeployConfig) *core.Genesi
require.NoError(t, err) require.NoError(t, err)
for name, predeploy := range predeploys.Predeploys { for name, predeploy := range predeploys.Predeploys {
addr := *predeploy addr := predeploy.Address
account, ok := gen.Alloc[addr] account, ok := gen.Alloc[addr]
require.Equal(t, true, ok, name) require.Equal(t, true, ok, name)
require.Greater(t, len(account.Code), 0) require.Greater(t, len(account.Code), 0)
adminSlot, ok := account.Storage[genesis.AdminSlot] adminSlot, ok := account.Storage[genesis.AdminSlot]
isProxy := predeploys.IsProxied(addr) || isProxy := !predeploy.ProxyDisabled ||
(!config.EnableGovernance && addr == predeploys.GovernanceTokenAddr) (!config.EnableGovernance && addr == predeploys.GovernanceTokenAddr)
if isProxy { if isProxy {
require.Equal(t, true, ok, name) require.Equal(t, true, ok, name)
...@@ -73,6 +74,10 @@ func testBuildL2Genesis(t *testing.T, config *genesis.DeployConfig) *core.Genesi ...@@ -73,6 +74,10 @@ func testBuildL2Genesis(t *testing.T, config *genesis.DeployConfig) *core.Genesi
require.Equal(t, common.Big1, gen.Alloc[addr].Balance) require.Equal(t, common.Big1, gen.Alloc[addr].Balance)
} }
create2Deployer := gen.Alloc[predeploys.Create2DeployerAddr]
codeHash := crypto.Keccak256Hash(create2Deployer.Code)
require.Equal(t, codeHash, immutables.Create2DeployerCodeHash)
if writeFile { if writeFile {
file, _ := json.MarshalIndent(gen, "", " ") file, _ := json.MarshalIndent(gen, "", " ")
_ = os.WriteFile("genesis.json", file, 0644) _ = os.WriteFile("genesis.json", file, 0644)
...@@ -86,7 +91,7 @@ func TestBuildL2MainnetGenesis(t *testing.T) { ...@@ -86,7 +91,7 @@ func TestBuildL2MainnetGenesis(t *testing.T) {
config.EnableGovernance = true config.EnableGovernance = true
config.FundDevAccounts = false config.FundDevAccounts = false
gen := testBuildL2Genesis(t, config) gen := testBuildL2Genesis(t, config)
require.Equal(t, 2322, len(gen.Alloc)) require.Equal(t, 2323, len(gen.Alloc))
} }
func TestBuildL2MainnetNoGovernanceGenesis(t *testing.T) { func TestBuildL2MainnetNoGovernanceGenesis(t *testing.T) {
...@@ -95,5 +100,5 @@ func TestBuildL2MainnetNoGovernanceGenesis(t *testing.T) { ...@@ -95,5 +100,5 @@ func TestBuildL2MainnetNoGovernanceGenesis(t *testing.T) {
config.EnableGovernance = false config.EnableGovernance = false
config.FundDevAccounts = false config.FundDevAccounts = false
gen := testBuildL2Genesis(t, config) gen := testBuildL2Genesis(t, config)
require.Equal(t, 2322, len(gen.Alloc)) require.Equal(t, 2323, len(gen.Alloc))
} }
This diff is collapsed.
This diff is collapsed.
...@@ -65,6 +65,7 @@ func TestBuildOptimism(t *testing.T) { ...@@ -65,6 +65,7 @@ func TestBuildOptimism(t *testing.T) {
"LegacyERC20ETH": true, "LegacyERC20ETH": true,
"EAS": true, "EAS": true,
"SchemaRegistry": true, "SchemaRegistry": true,
"Create2Deployer": true,
} }
// Only the exact contracts that we care about are being // Only the exact contracts that we care about are being
......
...@@ -61,6 +61,10 @@ func (db *MemoryStateDB) CreateAccount(addr common.Address) { ...@@ -61,6 +61,10 @@ func (db *MemoryStateDB) CreateAccount(addr common.Address) {
db.rw.Lock() db.rw.Lock()
defer db.rw.Unlock() defer db.rw.Unlock()
db.createAccount(addr)
}
func (db *MemoryStateDB) createAccount(addr common.Address) {
if _, ok := db.genesis.Alloc[addr]; !ok { if _, ok := db.genesis.Alloc[addr]; !ok {
db.genesis.Alloc[addr] = core.GenesisAccount{ db.genesis.Alloc[addr] = core.GenesisAccount{
Code: []byte{}, Code: []byte{},
...@@ -69,7 +73,6 @@ func (db *MemoryStateDB) CreateAccount(addr common.Address) { ...@@ -69,7 +73,6 @@ func (db *MemoryStateDB) CreateAccount(addr common.Address) {
Nonce: 0, Nonce: 0,
} }
} }
} }
func (db *MemoryStateDB) SubBalance(addr common.Address, amount *big.Int) { func (db *MemoryStateDB) SubBalance(addr common.Address, amount *big.Int) {
...@@ -165,6 +168,8 @@ func (db *MemoryStateDB) SetCode(addr common.Address, code []byte) { ...@@ -165,6 +168,8 @@ func (db *MemoryStateDB) SetCode(addr common.Address, code []byte) {
db.rw.Lock() db.rw.Lock()
defer db.rw.Unlock() defer db.rw.Unlock()
db.createAccount(addr)
account, ok := db.genesis.Alloc[addr] account, ok := db.genesis.Alloc[addr]
if !ok { if !ok {
return return
......
This diff is collapsed.
This diff is collapsed.
# ignore everything but the dockerfile, the op-stack-go base image performs the build
*
This diff is collapsed.
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
func TestMainShouldReturnErrorWhenConfigInvalid(t *testing.T) { func TestMainShouldReturnErrorWhenConfigInvalid(t *testing.T) {
cfg := &config.Config{} cfg := &config.Config{}
err := Main(context.Background(), testlog.Logger(t, log.LvlInfo), cfg) app, err := Main(context.Background(), testlog.Logger(t, log.LvlInfo), cfg)
require.ErrorIs(t, err, cfg.Check()) require.ErrorIs(t, err, cfg.Check())
require.Nil(t, app)
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -180,7 +180,7 @@ func TestPerformAction(t *testing.T) { ...@@ -180,7 +180,7 @@ func TestPerformAction(t *testing.T) {
ProofData: []byte{4, 5, 6}, ProofData: []byte{4, 5, 6},
OracleData: &types.PreimageOracleData{ OracleData: &types.PreimageOracleData{
IsLocal: true, IsLocal: true,
LocalContext: 6, LocalContext: common.Hash{0x06},
}, },
} }
err := responder.PerformAction(context.Background(), action) err := responder.PerformAction(context.Background(), action)
...@@ -232,6 +232,9 @@ func (m *mockTxManager) From() common.Address { ...@@ -232,6 +232,9 @@ func (m *mockTxManager) From() common.Address {
return m.from return m.from
} }
func (m *mockTxManager) Close() {
}
type mockContract struct { type mockContract struct {
calls int calls int
callFails bool callFails bool
......
...@@ -33,6 +33,6 @@ func (a *alphabetWithProofProvider) GetStepData(ctx context.Context, i types.Pos ...@@ -33,6 +33,6 @@ func (a *alphabetWithProofProvider) GetStepData(ctx context.Context, i types.Pos
return nil, nil, nil, err return nil, nil, nil, err
} }
traceIndex := i.TraceIndex(int(a.depth)).Uint64() traceIndex := i.TraceIndex(int(a.depth)).Uint64()
data := types.NewPreimageOracleData(0, []byte{byte(traceIndex)}, []byte{byte(traceIndex - 1)}, uint32(traceIndex-1)) data := types.NewPreimageOracleData(types.NoLocalContext, []byte{byte(traceIndex)}, []byte{byte(traceIndex - 1)}, uint32(traceIndex-1))
return preimage, []byte{byte(traceIndex - 1)}, data, nil return preimage, []byte{byte(traceIndex - 1)}, data, nil
} }
...@@ -11,11 +11,15 @@ func NewSimpleTraceAccessor(trace types.TraceProvider) *Accessor { ...@@ -11,11 +11,15 @@ func NewSimpleTraceAccessor(trace types.TraceProvider) *Accessor {
selector := func(_ context.Context, _ types.Game, _ types.Claim, _ types.Position) (types.TraceProvider, error) { selector := func(_ context.Context, _ types.Game, _ types.Claim, _ types.Position) (types.TraceProvider, error) {
return trace, nil return trace, nil
} }
return &Accessor{selector} return NewAccessor(selector)
} }
type ProviderSelector func(ctx context.Context, game types.Game, ref types.Claim, pos types.Position) (types.TraceProvider, error) type ProviderSelector func(ctx context.Context, game types.Game, ref types.Claim, pos types.Position) (types.TraceProvider, error)
func NewAccessor(selector ProviderSelector) *Accessor {
return &Accessor{selector}
}
type Accessor struct { type Accessor struct {
selector ProviderSelector selector ProviderSelector
} }
......
...@@ -124,7 +124,7 @@ func TestGetStepData(t *testing.T) { ...@@ -124,7 +124,7 @@ func TestGetStepData(t *testing.T) {
require.EqualValues(t, generator.proof.StateData, preimage) require.EqualValues(t, generator.proof.StateData, preimage)
require.EqualValues(t, generator.proof.ProofData, proof) require.EqualValues(t, generator.proof.ProofData, proof)
expectedData := types.NewPreimageOracleData(0, generator.proof.OracleKey, generator.proof.OracleValue, generator.proof.OracleOffset) expectedData := types.NewPreimageOracleData(common.Hash{}, generator.proof.OracleKey, generator.proof.OracleValue, generator.proof.OracleOffset)
require.EqualValues(t, expectedData, data) require.EqualValues(t, expectedData, data)
}) })
......
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.
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