Skip to content

Commit

Permalink
Merge pull request #104 from defi-wonderland/fix/merge-develop-to-sup…
Browse files Browse the repository at this point in the history
…erchain-beacon

fix: merge develop
  • Loading branch information
agusduha authored Oct 17, 2024
2 parents 58533e4 + 90e4f71 commit 60168f9
Show file tree
Hide file tree
Showing 111 changed files with 18,320 additions and 942 deletions.
56 changes: 48 additions & 8 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -796,9 +796,22 @@ jobs:
description: Test directory
type: string
default: "./..."
machine: true
resource_class: ethereum-optimism/latitude-1
machine:
image: <<pipeline.parameters.base_image>>
resource_class: xlarge
steps:
- run:
name: Install components
command: |
go version
go install gotest.tools/[email protected]
- run:
name: Install Kurtosis
command: |
echo "deb [trusted=yes] https://apt.fury.io/kurtosis-tech/ /" | sudo tee /etc/apt/sources.list.d/kurtosis.list
sudo apt update
sudo apt install kurtosis-cli=1.3.0
kurtosis engine start
- checkout
- when:
condition: <<parameters.uses_artifacts>>
Expand Down Expand Up @@ -850,6 +863,7 @@ jobs:
op-program
op-service
op-supervisor
op-deployer
packages/contracts-bedrock/scripts/checks/semver-natspec
)
formatted_packages=""
Expand Down Expand Up @@ -1274,6 +1288,24 @@ jobs:
command: bash scripts/ops/publish-artifacts.sh
working_directory: packages/contracts-bedrock

go-release:
parameters:
module:
description: Go Module Name
type: string
filename:
description: Goreleaser config file
default: .goreleaser.yaml
type: string
machine: true
resource_class: ethereum-optimism/latitude-1
steps:
- checkout
- run:
name: Run goreleaser
command: |
./bin/goreleaser release --clean -f ./<<parameters.module>>/<<parameters.filename>>
workflows:
main:
when:
Expand Down Expand Up @@ -1351,9 +1383,9 @@ workflows:
requires:
- contracts-bedrock-build
- go-test-kurtosis:
name: op-chain-ops-integration
module: op-chain-ops
test_directory: ./deployer/integration_test
name: op-deployer-integration
module: op-deployer
test_directory: ./pkg/deployer/integration_test
uses_artifacts: true
requires: ["contracts-bedrock-build"]
- go-e2e-test:
Expand Down Expand Up @@ -1385,7 +1417,7 @@ workflows:
- check-generated-mocks-op-node
- check-generated-mocks-op-service
- go-mod-download
- op-chain-ops-integration
- op-deployer-integration
- op-program-compat
- op-e2e-HTTP-tests
- op-e2e-fault-proof-tests
Expand Down Expand Up @@ -1414,7 +1446,6 @@ workflows:
- op-conductor
- da-server
- op-supervisor
- op-deployer
- cannon
- cannon-prestate
- check-generated-mocks-op-node
Expand All @@ -1435,6 +1466,16 @@ workflows:
ignore-dirs:
./packages/contracts-bedrock/lib

go-release-deployer:
jobs:
- go-release:
filters:
tags:
only: /^op-deployer.*/
branches:
ignore: /.*/
module: op-deployer

release:
when:
not:
Expand Down Expand Up @@ -1505,7 +1546,6 @@ workflows:
- da-server-docker-release
- op-ufm-docker-release
- op-supervisor-docker-release
- op-deployer-docker-release
- cannon-docker-release
# Standard (xlarge) AMD-only docker images go here
- docker-build:
Expand Down
44 changes: 44 additions & 0 deletions cannon/mipsevm/exec/mips_instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,3 +569,47 @@ func HandleRd(cpu *mipsevm.CpuScalars, registers *[32]Word, storeReg Word, val W
cpu.NextPC = cpu.NextPC + 4
return nil
}

func LoadSubWord(memory *memory.Memory, addr Word, byteLength Word, signExtend bool, memoryTracker MemTracker) Word {
// Pull data from memory
effAddr := (addr) & arch.AddressMask
memoryTracker.TrackMemAccess(effAddr)
mem := memory.GetWord(effAddr)

// Extract a sub-word based on the low-order bits in addr
dataMask, bitOffset, bitLength := calculateSubWordMaskAndOffset(addr, byteLength)
retVal := (mem >> bitOffset) & dataMask
if signExtend {
retVal = SignExtend(retVal, bitLength)
}

return retVal
}

func StoreSubWord(memory *memory.Memory, addr Word, byteLength Word, value Word, memoryTracker MemTracker) {
// Pull data from memory
effAddr := (addr) & arch.AddressMask
memoryTracker.TrackMemAccess(effAddr)
mem := memory.GetWord(effAddr)

// Modify isolated sub-word within mem
dataMask, bitOffset, _ := calculateSubWordMaskAndOffset(addr, byteLength)
subWordValue := dataMask & value
memUpdateMask := dataMask << bitOffset
newMemVal := subWordValue<<bitOffset | (^memUpdateMask)&mem

memory.SetWord(effAddr, newMemVal)
}

func calculateSubWordMaskAndOffset(addr Word, byteLength Word) (dataMask, bitOffset, bitLength Word) {
bitLength = byteLength << 3
dataMask = ^Word(0) >> (arch.WordSize - bitLength)

// Figure out sub-word index based on the low-order bits in addr
byteIndexMask := addr & arch.ExtMask & ^(byteLength - 1)
maxByteShift := arch.WordSizeBytes - byteLength
byteIndex := addr & byteIndexMask
bitOffset = (maxByteShift - byteIndex) << 3

return dataMask, bitOffset, bitLength
}
110 changes: 110 additions & 0 deletions cannon/mipsevm/exec/mips_instructions32_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// These tests target architectures that are 32-bit or larger
package exec

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/ethereum-optimism/optimism/cannon/mipsevm/arch"
"github.com/ethereum-optimism/optimism/cannon/mipsevm/memory"
)

// TestLoadSubWord_32bits validates LoadSubWord with 32-bit offsets (up to 3 bytes)
func TestLoadSubWord_32bits(t *testing.T) {
cases := []struct {
name string
byteLength Word
addr uint32
memVal uint32
signExtend bool
shouldSignExtend bool
expectedValue uint32
}{
{name: "32-bit", byteLength: 4, addr: 0xFF00_0000, memVal: 0x1234_5678, expectedValue: 0x1234_5678},
{name: "32-bit, extra bits", byteLength: 4, addr: 0xFF00_0001, memVal: 0x1234_5678, expectedValue: 0x1234_5678},
{name: "32-bit, extra bits", byteLength: 4, addr: 0xFF00_0002, memVal: 0x1234_5678, expectedValue: 0x1234_5678},
{name: "32-bit, extra bits", byteLength: 4, addr: 0xFF00_0003, memVal: 0x1234_5678, expectedValue: 0x1234_5678},
{name: "16-bit, offset=0", byteLength: 2, addr: 0x00, memVal: 0x1234_5678, expectedValue: 0x1234},
{name: "16-bit, offset=0, extra bit set", byteLength: 2, addr: 0x01, memVal: 0x1234_5678, expectedValue: 0x1234},
{name: "16-bit, offset=2", byteLength: 2, addr: 0x02, memVal: 0x1234_5678, expectedValue: 0x5678},
{name: "16-bit, offset=2, extra bit set", byteLength: 2, addr: 0x03, memVal: 0x1234_5678, expectedValue: 0x5678},
{name: "16-bit, sign extend positive val", byteLength: 2, addr: 0x02, memVal: 0x1234_5678, expectedValue: 0x5678, signExtend: true, shouldSignExtend: false},
{name: "16-bit, sign extend negative val", byteLength: 2, addr: 0x02, memVal: 0x1234_F678, expectedValue: 0xFFFF_F678, signExtend: true, shouldSignExtend: true},
{name: "16-bit, do not sign extend negative val", byteLength: 2, addr: 0x02, memVal: 0x1234_F678, expectedValue: 0xF678, signExtend: false},
{name: "8-bit, offset=0", byteLength: 1, addr: 0x1230, memVal: 0x1234_5678, expectedValue: 0x12},
{name: "8-bit, offset=1", byteLength: 1, addr: 0x1231, memVal: 0x1234_5678, expectedValue: 0x34},
{name: "8-bit, offset=2", byteLength: 1, addr: 0x1232, memVal: 0x1234_5678, expectedValue: 0x56},
{name: "8-bit, offset=3", byteLength: 1, addr: 0x1233, memVal: 0x1234_5678, expectedValue: 0x78},
{name: "8-bit, sign extend positive", byteLength: 1, addr: 0x1233, memVal: 0x1234_5678, expectedValue: 0x78, signExtend: true, shouldSignExtend: false},
{name: "8-bit, sign extend negative", byteLength: 1, addr: 0x1233, memVal: 0x1234_5688, expectedValue: 0xFFFF_FF88, signExtend: true, shouldSignExtend: true},
{name: "8-bit, do not sign extend neg value", byteLength: 1, addr: 0x1233, memVal: 0x1234_5688, expectedValue: 0x88, signExtend: false},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
mem := memory.NewMemory()
memTracker := NewMemoryTracker(mem)

effAddr := Word(c.addr) & arch.AddressMask
// Shift memval for consistency across architectures
memVal := Word(c.memVal) << (arch.WordSize - 32)
mem.SetWord(effAddr, memVal)

retVal := LoadSubWord(mem, Word(c.addr), c.byteLength, c.signExtend, memTracker)

// If sign extending, make sure retVal is consistent across architectures
expected := Word(c.expectedValue)
if c.shouldSignExtend {
signedBits := ^Word(0xFFFF_FFFF)
expected = expected | signedBits
}
require.Equal(t, expected, retVal)
})
}
}

// TestStoreSubWord_32bits validates LoadSubWord with 32-bit offsets (up to 3 bytes)
func TestStoreSubWord_32bits(t *testing.T) {
memVal := 0xFFFF_FFFF
value := 0x1234_5678

cases := []struct {
name string
byteLength Word
addr uint32
expectedValue uint32
}{
{name: "32-bit", byteLength: 4, addr: 0xFF00_0000, expectedValue: 0x1234_5678},
{name: "32-bit, extra bits", byteLength: 4, addr: 0xFF00_0001, expectedValue: 0x1234_5678},
{name: "32-bit, extra bits", byteLength: 4, addr: 0xFF00_0002, expectedValue: 0x1234_5678},
{name: "32-bit, extra bits", byteLength: 4, addr: 0xFF00_0003, expectedValue: 0x1234_5678},
{name: "16-bit, subword offset=0", byteLength: 2, addr: 0x00, expectedValue: 0x5678_FFFF},
{name: "16-bit, subword offset=0, extra bit set", byteLength: 2, addr: 0x01, expectedValue: 0x5678_FFFF},
{name: "16-bit, subword offset=2", byteLength: 2, addr: 0x02, expectedValue: 0xFFFF_5678},
{name: "16-bit, subword offset=2, extra bit set", byteLength: 2, addr: 0x03, expectedValue: 0xFFFF_5678},
{name: "8-bit, offset=0", byteLength: 1, addr: 0x1230, expectedValue: 0x78FF_FFFF},
{name: "8-bit, offset=1", byteLength: 1, addr: 0x1231, expectedValue: 0xFF78_FFFF},
{name: "8-bit, offset=2", byteLength: 1, addr: 0x1232, expectedValue: 0xFFFF_78FF},
{name: "8-bit, offset=3", byteLength: 1, addr: 0x1233, expectedValue: 0xFFFF_FF78},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
mem := memory.NewMemory()
memTracker := NewMemoryTracker(mem)

effAddr := Word(c.addr) & arch.AddressMask
// Shift memval for consistency across architectures
memVal := Word(memVal) << (arch.WordSize - 32)
mem.SetWord(effAddr, memVal)

StoreSubWord(mem, Word(c.addr), c.byteLength, Word(value), memTracker)
newMemVal := mem.GetWord(effAddr)

// Make sure expectation is consistent across architectures
expected := Word(c.expectedValue) << (arch.WordSize - 32)
require.Equal(t, expected, newMemVal)
})
}
}
111 changes: 111 additions & 0 deletions cannon/mipsevm/exec/mips_instructions64_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//go:build cannon64
// +build cannon64

// These tests target architectures that are 64-bit or larger
package exec

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/ethereum-optimism/optimism/cannon/mipsevm/arch"
"github.com/ethereum-optimism/optimism/cannon/mipsevm/memory"
)

// TestLoadSubWord_64bits extends TestLoadSubWord_32bits by testing up to 64-bits (7 byte) offsets
func TestLoadSubWord_64bits(t *testing.T) {
memVal := uint64(0x1234_5678_9876_5432)
cases := []struct {
name string
byteLength Word
addr uint64
memVal uint64
signExtend bool
expectedValue uint64
}{
{name: "64-bit", byteLength: 8, addr: 0xFF00_0000, memVal: 0x8234_5678_9876_5432, expectedValue: 0x8234_5678_9876_5432},
{name: "64-bit w sign extension", byteLength: 8, addr: 0xFF00_0000, memVal: 0x8234_5678_9876_5432, expectedValue: 0x8234_5678_9876_5432, signExtend: true},
{name: "32-bit, offset=0", byteLength: 4, addr: 0xFF00_0000, memVal: memVal, expectedValue: 0x1234_5678},
{name: "32-bit, offset=0, extra bits", byteLength: 4, addr: 0xFF00_0001, memVal: memVal, expectedValue: 0x1234_5678},
{name: "32-bit, offset=0, extra bits", byteLength: 4, addr: 0xFF00_0002, memVal: memVal, expectedValue: 0x1234_5678},
{name: "32-bit, offset=0, extra bits", byteLength: 4, addr: 0xFF00_0003, memVal: memVal, expectedValue: 0x1234_5678},
{name: "32-bit, offset=4", byteLength: 4, addr: 0xFF00_0004, memVal: memVal, expectedValue: 0x9876_5432},
{name: "32-bit, offset=4, extra bits", byteLength: 4, addr: 0xFF00_0005, memVal: memVal, expectedValue: 0x9876_5432},
{name: "32-bit, offset=4, extra bits", byteLength: 4, addr: 0xFF00_0006, memVal: memVal, expectedValue: 0x9876_5432},
{name: "32-bit, offset=4, extra bits", byteLength: 4, addr: 0xFF00_0007, memVal: memVal, expectedValue: 0x9876_5432},
{name: "32-bit, sign extend negative", byteLength: 4, addr: 0xFF00_0006, memVal: 0x1234_5678_F1E2_A1B1, expectedValue: 0xFFFF_FFFF_F1E2_A1B1, signExtend: true},
{name: "32-bit, sign extend positive", byteLength: 4, addr: 0xFF00_0007, memVal: 0x1234_5678_7876_5432, expectedValue: 0x7876_5432, signExtend: true},
{name: "16-bit, subword offset=4", byteLength: 2, addr: 0x04, memVal: memVal, expectedValue: 0x9876},
{name: "16-bit, subword offset=4, extra bit set", byteLength: 2, addr: 0x05, memVal: memVal, expectedValue: 0x9876},
{name: "16-bit, subword offset=6", byteLength: 2, addr: 0x06, memVal: memVal, expectedValue: 0x5432},
{name: "16-bit, subword offset=6, extra bit set", byteLength: 2, addr: 0x07, memVal: memVal, expectedValue: 0x5432},
{name: "16-bit, sign extend negative val", byteLength: 2, addr: 0x04, memVal: 0x1234_5678_8BEE_CCDD, expectedValue: 0xFFFF_FFFF_FFFF_8BEE, signExtend: true},
{name: "16-bit, sign extend positive val", byteLength: 2, addr: 0x04, memVal: 0x1234_5678_7876_5432, expectedValue: 0x7876, signExtend: true},
{name: "8-bit, offset=4", byteLength: 1, addr: 0x1234, memVal: memVal, expectedValue: 0x98},
{name: "8-bit, offset=5", byteLength: 1, addr: 0x1235, memVal: memVal, expectedValue: 0x76},
{name: "8-bit, offset=6", byteLength: 1, addr: 0x1236, memVal: memVal, expectedValue: 0x54},
{name: "8-bit, offset=7", byteLength: 1, addr: 0x1237, memVal: memVal, expectedValue: 0x32},
{name: "8-bit, sign extend positive", byteLength: 1, addr: 0x1237, memVal: memVal, expectedValue: 0x32, signExtend: true},
{name: "8-bit, sign extend negative", byteLength: 1, addr: 0x1237, memVal: 0x1234_5678_8764_4381, expectedValue: 0xFFFF_FFFF_FFFF_FF81, signExtend: true},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
mem := memory.NewMemory()
memTracker := NewMemoryTracker(mem)

effAddr := Word(c.addr) & arch.AddressMask
mem.SetWord(effAddr, c.memVal)

retVal := LoadSubWord(mem, Word(c.addr), c.byteLength, c.signExtend, memTracker)
require.Equal(t, c.expectedValue, retVal)
})
}
}

// TestStoreSubWord_64bits extends TestStoreSubWord_32bits by testing up to 64-bits (7 byte) offsets
func TestStoreSubWord_64bits(t *testing.T) {
memVal := uint64(0xFFFF_FFFF_FFFF_FFFF)
value := uint64(0x1234_5678_9876_5432)

cases := []struct {
name string
byteLength Word
addr uint64
expectedValue uint64
}{
{name: "64-bit", byteLength: 8, addr: 0xFF00_0000, expectedValue: value},
{name: "32-bit, offset 0", byteLength: 4, addr: 0xFF00_0000, expectedValue: 0x9876_5432_FFFF_FFFF},
{name: "32-bit, offset 0, extra addr bits", byteLength: 4, addr: 0xFF00_0001, expectedValue: 0x9876_5432_FFFF_FFFF},
{name: "32-bit, offset 0, extra addr bits", byteLength: 4, addr: 0xFF00_0002, expectedValue: 0x9876_5432_FFFF_FFFF},
{name: "32-bit, offset 0, extra addr bits", byteLength: 4, addr: 0xFF00_0003, expectedValue: 0x9876_5432_FFFF_FFFF},
{name: "32-bit, offset 4", byteLength: 4, addr: 0xFF00_0004, expectedValue: 0xFFFF_FFFF_9876_5432},
{name: "32-bit, offset 4, extra addr bits", byteLength: 4, addr: 0xFF00_0005, expectedValue: 0xFFFF_FFFF_9876_5432},
{name: "32-bit, offset 4, extra addr bits", byteLength: 4, addr: 0xFF00_0006, expectedValue: 0xFFFF_FFFF_9876_5432},
{name: "32-bit, offset 4, extra addr bits", byteLength: 4, addr: 0xFF00_0007, expectedValue: 0xFFFF_FFFF_9876_5432},
{name: "16-bit, offset=4", byteLength: 2, addr: 0x04, expectedValue: 0xFFFF_FFFF_5432_FFFF},
{name: "16-bit, offset=4, extra bit set", byteLength: 2, addr: 0x05, expectedValue: 0xFFFF_FFFF_5432_FFFF},
{name: "16-bit, offset=6", byteLength: 2, addr: 0x06, expectedValue: 0xFFFF_FFFF_FFFF_5432},
{name: "16-bit, offset=6, extra bit set", byteLength: 2, addr: 0x07, expectedValue: 0xFFFF_FFFF_FFFF_5432},
{name: "8-bit, offset=4", byteLength: 1, addr: 0x1234, expectedValue: 0xFFFF_FFFF_32FF_FFFF},
{name: "8-bit, offset=5", byteLength: 1, addr: 0x1235, expectedValue: 0xFFFF_FFFF_FF32_FFFF},
{name: "8-bit, offset=6", byteLength: 1, addr: 0x1236, expectedValue: 0xFFFF_FFFF_FFFF_32FF},
{name: "8-bit, offset=7", byteLength: 1, addr: 0x1237, expectedValue: 0xFFFF_FFFF_FFFF_FF32},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
mem := memory.NewMemory()
memTracker := NewMemoryTracker(mem)

effAddr := Word(c.addr) & arch.AddressMask
mem.SetWord(effAddr, memVal)

StoreSubWord(mem, Word(c.addr), c.byteLength, Word(value), memTracker)
newMemVal := mem.GetWord(effAddr)

require.Equal(t, c.expectedValue, newMemVal)
})
}
}
Loading

0 comments on commit 60168f9

Please sign in to comment.