Skip to content

Commit

Permalink
Merge branch 'ethereum-optimism:develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
qizhou authored May 10, 2024
2 parents b8fd70d + 4dc6aa8 commit 4a79a72
Show file tree
Hide file tree
Showing 301 changed files with 38,743 additions and 4,077 deletions.
213 changes: 150 additions & 63 deletions .circleci/config.yml

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions .github/workflows/slither.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
slither-analyze:
runs-on: ubuntu-latest
container:
image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:v0.43.0
image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:v0.49.0
steps:
- uses: actions/checkout@v4

Expand All @@ -23,7 +23,7 @@ jobs:
run: rm packages/contracts-bedrock/package.json

- name: Run Slither
uses: crytic/slither-action@v0.3.2
uses: crytic/slither-action@v0.4.0
id: slither
with:
target: packages/contracts-bedrock
Expand Down
36 changes: 36 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,42 @@ golang-docker:
op-node op-batcher op-proposer op-challenger op-dispute-mon
.PHONY: golang-docker

docker-builder-clean:
docker buildx rm buildx-build
.PHONY: docker-builder-clean

docker-builder:
docker buildx create \
--driver=docker-container --name=buildx-build --bootstrap --use
.PHONY: docker-builder

# add --print to dry-run
cross-op-node:
# We don't use a buildx builder here, and just load directly into regular docker, for convenience.
GIT_COMMIT=$$(git rev-parse HEAD) \
GIT_DATE=$$(git show -s --format='%ct') \
IMAGE_TAGS=$$(git rev-parse HEAD),latest \
PLATFORMS="linux/arm64" \
GIT_VERSION=$(shell tags=$$(git tag --points-at $(GITCOMMIT) | grep '^op-node/' | sed 's/op-node\///' | sort -V); \
preferred_tag=$$(echo "$$tags" | grep -v -- '-rc' | tail -n 1); \
if [ -z "$$preferred_tag" ]; then \
if [ -z "$$tags" ]; then \
echo "untagged"; \
else \
echo "$$tags" | tail -n 1; \
fi \
else \
echo $$preferred_tag; \
fi) \
docker buildx bake \
--progress plain \
--builder=buildx-build \
--load \
--no-cache \
-f docker-bake.hcl \
op-node
.PHONY: golang-docker

chain-mon-docker:
# We don't use a buildx builder here, and just load directly into regular docker, for convenience.
GIT_COMMIT=$$(git rev-parse HEAD) \
Expand Down
20 changes: 11 additions & 9 deletions bedrock-devnet/devnet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,17 @@ def devnet_l1_allocs(paths):
init_devnet_l1_deploy_config(paths)

fqn = 'scripts/Deploy.s.sol:Deploy'
# Use foundry pre-funded account #1 for the deployer
run_command([
'forge', 'script', '--chain-id', '900', fqn, "--sig", "runWithStateDump()", "--private-key", "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
], env={}, cwd=paths.contracts_bedrock_dir)
# We need to set the sender here to an account we know the private key of,
# because the sender ends up being the owner of the ProxyAdmin SAFE
# (which we need to enable the Custom Gas Token feature).
'forge', 'script', fqn, "--sig", "runWithStateDump()", "--sender", "0x90F79bf6EB2c4f870365E785982E1f101E93b906"
], env={
'DEPLOYMENT_OUTFILE': paths.l1_deployments_path,
'DEPLOY_CONFIG_PATH': paths.devnet_config_path,
}, cwd=paths.contracts_bedrock_dir)

forge_dump = read_json(paths.forge_l1_dump_path)
write_json(paths.allocs_l1_path, { "accounts": forge_dump })
os.remove(paths.forge_l1_dump_path)
shutil.move(src=paths.forge_l1_dump_path, dst=paths.allocs_l1_path)

shutil.copy(paths.l1_deployments_path, paths.addresses_json_path)

Expand All @@ -162,16 +165,15 @@ def devnet_l2_allocs(paths):
'forge', 'script', fqn, "--sig", "runWithAllUpgrades()"
], env={
'CONTRACT_ADDRESSES_PATH': paths.l1_deployments_path,
'DEPLOY_CONFIG_PATH': paths.devnet_config_path,
}, cwd=paths.contracts_bedrock_dir)

# For the previous forks, and the latest fork (default, thus empty prefix),
# move the forge-dumps into place as .devnet allocs.
for suffix in ["-delta", ""]:
input_path = pjoin(paths.contracts_bedrock_dir, f"state-dump-901{suffix}.json")
forge_dump = read_json(input_path)
output_path = pjoin(paths.devnet_dir, f'allocs-l2{suffix}.json')
write_json(output_path, { "accounts": forge_dump })
os.remove(input_path)
shutil.move(src=input_path, dst=output_path)
log.info("Generated L2 allocs: "+output_path)


Expand Down
2 changes: 1 addition & 1 deletion cannon/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
GITCOMMIT ?= $(shell git rev-parse HEAD)
GITDATE ?= $(shell git show -s --format='%ct')
VERSION := v0.0.0
VERSION ?= v0.0.0

LDFLAGSSTRING +=-X main.GitCommit=$(GITCOMMIT)
LDFLAGSSTRING +=-X main.GitDate=$(GITDATE)
Expand Down
4 changes: 2 additions & 2 deletions cannon/example/claim/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ toolchain go1.21.1
require github.com/ethereum-optimism/optimism v0.0.0

require (
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/sys v0.20.0 // indirect
)

replace github.com/ethereum-optimism/optimism v0.0.0 => ../../..
8 changes: 4 additions & 4 deletions cannon/example/claim/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
50 changes: 13 additions & 37 deletions cannon/mipsevm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package mipsevm

import (
"encoding/binary"
"encoding/json"
"fmt"
"math/big"
"os"

"github.com/ethereum-optimism/optimism/op-chain-ops/foundry"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
Expand All @@ -19,51 +19,27 @@ import (
"github.com/ethereum/go-ethereum/params"
)

// LoadContracts loads the Cannon contracts, from the contracts package.
func LoadContracts() (*Contracts, error) {
mips, err := loadContract("../../packages/contracts-bedrock/forge-artifacts/MIPS.sol/MIPS.json")
// LoadArtifacts loads the Cannon contracts, from the contracts package.
func LoadArtifacts() (*Artifacts, error) {
mips, err := foundry.ReadArtifact("../../packages/contracts-bedrock/forge-artifacts/MIPS.sol/MIPS.json")
if err != nil {
return nil, fmt.Errorf("failed to load MIPS contract: %w", err)
}

oracle, err := loadContract("../../packages/contracts-bedrock/forge-artifacts/PreimageOracle.sol/PreimageOracle.json")
oracle, err := foundry.ReadArtifact("../../packages/contracts-bedrock/forge-artifacts/PreimageOracle.sol/PreimageOracle.json")
if err != nil {
return nil, fmt.Errorf("failed to load Oracle contract: %w", err)
}

return &Contracts{
return &Artifacts{
MIPS: mips,
Oracle: oracle,
}, nil
}

func loadContract(path string) (*Contract, error) {
file, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("artifact at %s not found: %w", path, err)
}

contract := Contract{}
if err := json.Unmarshal(file, &contract); err != nil {
return nil, err
}
return &contract, nil
}

type Contract struct {
DeployedBytecode struct {
Object hexutil.Bytes `json:"object"`
SourceMap string `json:"sourceMap"`
} `json:"deployedBytecode"`
Bytecode struct {
Object hexutil.Bytes `json:"object"`
} `json:"bytecode"`
// ignore abi,etc.
}

type Contracts struct {
MIPS *Contract
Oracle *Contract
type Artifacts struct {
MIPS *foundry.Artifact
Oracle *foundry.Artifact
}

type Addresses struct {
Expand All @@ -73,7 +49,7 @@ type Addresses struct {
FeeRecipient common.Address
}

func NewEVMEnv(contracts *Contracts, addrs *Addresses) (*vm.EVM, *state.StateDB) {
func NewEVMEnv(artifacts *Artifacts, addrs *Addresses) (*vm.EVM, *state.StateDB) {
// Temporary hack until Cancun is activated on mainnet
cpy := *params.MainnetChainConfig
chainCfg := &cpy // don't modify the global chain config
Expand All @@ -94,11 +70,11 @@ func NewEVMEnv(contracts *Contracts, addrs *Addresses) (*vm.EVM, *state.StateDB)

env := vm.NewEVM(blockContext, vm.TxContext{}, state, chainCfg, vmCfg)
// pre-deploy the contracts
env.StateDB.SetCode(addrs.Oracle, contracts.Oracle.DeployedBytecode.Object)
env.StateDB.SetCode(addrs.Oracle, artifacts.Oracle.DeployedBytecode.Object)

var mipsCtorArgs [32]byte
copy(mipsCtorArgs[12:], addrs.Oracle[:])
mipsDeploy := append(hexutil.MustDecode(contracts.MIPS.Bytecode.Object.String()), mipsCtorArgs[:]...)
mipsDeploy := append(hexutil.MustDecode(artifacts.MIPS.Bytecode.Object.String()), mipsCtorArgs[:]...)
startingGas := uint64(30_000_000)
_, deployedMipsAddr, leftOverGas, err := env.Create(vm.AccountRef(addrs.Sender), mipsDeploy, startingGas, common.U2560)
if err != nil {
Expand Down
39 changes: 17 additions & 22 deletions cannon/mipsevm/evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"testing"
"time"

"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-chain-ops/foundry"
preimage "github.com/ethereum-optimism/optimism/op-preimage"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
Expand All @@ -22,8 +22,8 @@ import (
"github.com/stretchr/testify/require"
)

func testContractsSetup(t require.TestingT) (*Contracts, *Addresses) {
contracts, err := LoadContracts()
func testContractsSetup(t require.TestingT) (*Artifacts, *Addresses) {
artifacts, err := LoadArtifacts()
require.NoError(t, err)

addrs := &Addresses{
Expand All @@ -33,7 +33,7 @@ func testContractsSetup(t require.TestingT) (*Contracts, *Addresses) {
FeeRecipient: common.Address{0xaa},
}

return contracts, addrs
return artifacts, addrs
}

func MarkdownTracer() vm.EVMLogger {
Expand All @@ -45,11 +45,12 @@ type MIPSEVM struct {
evmState *state.StateDB
addrs *Addresses
localOracle PreimageOracle
artifacts *Artifacts
}

func NewMIPSEVM(contracts *Contracts, addrs *Addresses) *MIPSEVM {
env, evmState := NewEVMEnv(contracts, addrs)
return &MIPSEVM{env, evmState, addrs, nil}
func NewMIPSEVM(artifacts *Artifacts, addrs *Addresses) *MIPSEVM {
env, evmState := NewEVMEnv(artifacts, addrs)
return &MIPSEVM{env, evmState, addrs, nil, artifacts}
}

func (m *MIPSEVM) SetTracer(tracer vm.EVMLogger) {
Expand All @@ -70,13 +71,13 @@ func (m *MIPSEVM) Step(t *testing.T, stepWitness *StepWitness) []byte {

if stepWitness.HasPreimage() {
t.Logf("reading preimage key %x at offset %d", stepWitness.PreimageKey, stepWitness.PreimageOffset)
poInput, err := encodePreimageOracleInput(t, stepWitness, LocalContext{}, m.localOracle)
poInput, err := encodePreimageOracleInput(t, stepWitness, LocalContext{}, m.localOracle, m.artifacts.Oracle)
require.NoError(t, err, "encode preimage oracle input")
_, leftOverGas, err := m.env.Call(vm.AccountRef(sender), m.addrs.Oracle, poInput, startingGas, common.U2560)
require.NoErrorf(t, err, "evm should not fail, took %d gas", startingGas-leftOverGas)
}

input := encodeStepInput(t, stepWitness, LocalContext{})
input := encodeStepInput(t, stepWitness, LocalContext{}, m.artifacts.MIPS)
ret, leftOverGas, err := m.env.Call(vm.AccountRef(sender), m.addrs.MIPS, input, startingGas, common.U2560)
require.NoError(t, err, "evm should not fail")
require.Len(t, ret, 32, "expecting 32-byte state hash")
Expand All @@ -95,23 +96,17 @@ func (m *MIPSEVM) Step(t *testing.T, stepWitness *StepWitness) []byte {
return evmPost
}

func encodeStepInput(t *testing.T, wit *StepWitness, localContext LocalContext) []byte {
mipsAbi, err := bindings.MIPSMetaData.GetAbi()
require.NoError(t, err)

input, err := mipsAbi.Pack("step", wit.State, wit.MemProof, localContext)
func encodeStepInput(t *testing.T, wit *StepWitness, localContext LocalContext, mips *foundry.Artifact) []byte {
input, err := mips.ABI.Pack("step", wit.State, wit.MemProof, localContext)
require.NoError(t, err)
return input
}

func encodePreimageOracleInput(t *testing.T, wit *StepWitness, localContext LocalContext, localOracle PreimageOracle) ([]byte, error) {
func encodePreimageOracleInput(t *testing.T, wit *StepWitness, localContext LocalContext, localOracle PreimageOracle, oracle *foundry.Artifact) ([]byte, error) {
if wit.PreimageKey == ([32]byte{}) {
return nil, errors.New("cannot encode pre-image oracle input, witness has no pre-image to proof")
}

preimageAbi, err := bindings.PreimageOracleMetaData.GetAbi()
require.NoError(t, err, "failed to load pre-image oracle ABI")

switch preimage.KeyType(wit.PreimageKey[0]) {
case preimage.LocalKeyType:
if len(wit.PreimageValue) > 32+8 {
Expand All @@ -120,7 +115,7 @@ func encodePreimageOracleInput(t *testing.T, wit *StepWitness, localContext Loca
preimagePart := wit.PreimageValue[8:]
var tmp [32]byte
copy(tmp[:], preimagePart)
input, err := preimageAbi.Pack("loadLocalData",
input, err := oracle.ABI.Pack("loadLocalData",
new(big.Int).SetBytes(wit.PreimageKey[1:]),
localContext,
tmp,
Expand All @@ -130,7 +125,7 @@ func encodePreimageOracleInput(t *testing.T, wit *StepWitness, localContext Loca
require.NoError(t, err)
return input, nil
case preimage.Keccak256KeyType:
input, err := preimageAbi.Pack(
input, err := oracle.ABI.Pack(
"loadKeccak256PreimagePart",
new(big.Int).SetUint64(uint64(wit.PreimageOffset)),
wit.PreimageValue[8:])
Expand All @@ -143,7 +138,7 @@ func encodePreimageOracleInput(t *testing.T, wit *StepWitness, localContext Loca
preimage := localOracle.GetPreimage(preimage.Keccak256Key(wit.PreimageKey).PreimageKey())
precompile := common.BytesToAddress(preimage[:20])
callInput := preimage[20:]
input, err := preimageAbi.Pack(
input, err := oracle.ABI.Pack(
"loadPrecompilePreimagePart",
new(big.Int).SetUint64(uint64(wit.PreimageOffset)),
precompile,
Expand Down Expand Up @@ -290,7 +285,7 @@ func TestEVMFault(t *testing.T) {
State: initialState.EncodeWitness(),
MemProof: insnProof[:],
}
input := encodeStepInput(t, stepWitness, LocalContext{})
input := encodeStepInput(t, stepWitness, LocalContext{}, contracts.MIPS)
startingGas := uint64(30_000_000)

_, _, err := env.Call(vm.AccountRef(sender), addrs.MIPS, input, startingGas, common.U2560)
Expand Down
7 changes: 6 additions & 1 deletion cannon/mipsevm/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import (
"io"
)

const HEAP_START = 0x05000000

func LoadELF(f *elf.File) (*State, error) {
s := &State{
PC: uint32(f.Entry),
NextPC: uint32(f.Entry + 4),
HI: 0,
LO: 0,
Heap: 0x20000000,
Heap: HEAP_START,
Registers: [32]uint32{},
Memory: NewMemory(),
ExitCode: 0,
Expand Down Expand Up @@ -43,6 +45,9 @@ func LoadELF(f *elf.File) (*State, error) {
if prog.Vaddr+prog.Memsz >= uint64(1<<32) {
return nil, fmt.Errorf("program %d out of 32-bit mem range: %x - %x (size: %x)", i, prog.Vaddr, prog.Vaddr+prog.Memsz, prog.Memsz)
}
if prog.Vaddr+prog.Memsz >= HEAP_START {
return nil, fmt.Errorf("program %d overlaps with heap: %x - %x (size: %x). The heap start offset must be reconfigured", i, prog.Vaddr, prog.Vaddr+prog.Memsz, prog.Memsz)
}
if err := s.Memory.SetMemoryRange(uint32(prog.Vaddr), r); err != nil {
return nil, fmt.Errorf("failed to read program segment %d: %w", i, err)
}
Expand Down
Loading

0 comments on commit 4a79a72

Please sign in to comment.