Skip to content

Commit

Permalink
Merge branch 'develop' into aj/tower-defense-e2e
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] committed Aug 15, 2023
2 parents 807b779 + b9238af commit 08aedaa
Show file tree
Hide file tree
Showing 42 changed files with 2,273 additions and 1,554 deletions.
37 changes: 37 additions & 0 deletions cannon/mipsevm/evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,43 @@ func TestEVM(t *testing.T) {
}
}

func TestEVMSingleStep(t *testing.T) {
contracts, addrs := testContractsSetup(t)
var tracer vm.EVMLogger
//tracer = SourceMapTracer(t, contracts, addrs)

type testInput struct {
name string
pc uint32
nextPC uint32
insn uint32
}
cases := []testInput{
{"j MSB set target", 0, 4, 0x0A_00_00_02}, // j 0x02_00_00_02
{"j non-zero PC region", 0x10000000, 0x10000004, 0x08_00_00_02}, // j 0x2
{"jal MSB set target", 0, 4, 0x0E_00_00_02}, // jal 0x02_00_00_02
{"jal non-zero PC region", 0x10000000, 0x10000004, 0x0C_00_00_02}, // jal 0x2
}

for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
state := &State{PC: tt.pc, NextPC: tt.nextPC, Memory: NewMemory()}
state.Memory.SetMemory(tt.pc, tt.insn)

us := NewInstrumentedState(state, nil, os.Stdout, os.Stderr)
stepWitness, err := us.Step(true)
require.NoError(t, err)

evm := NewMIPSEVM(contracts, addrs)
evm.SetTracer(tracer)
evmPost := evm.Step(t, stepWitness)
goPost := us.state.EncodeWitness()
require.Equal(t, hexutil.Bytes(goPost).String(), hexutil.Bytes(evmPost).String(),
"mipsevm produced different state than EVM")
})
}
}

func TestEVMFault(t *testing.T) {
contracts, addrs := testContractsSetup(t)
var tracer vm.EVMLogger // no-tracer by default, but see SourceMapTracer and MarkdownTracer
Expand Down
7 changes: 3 additions & 4 deletions cannon/mipsevm/mips.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,13 @@ func (m *InstrumentedState) mipsStep() error {

// j-type j/jal
if opcode == 2 || opcode == 3 {
// TODO likely bug in original code: MIPS spec says this should be in the "current" region;
// a 256 MB aligned region (i.e. use top 4 bits of branch delay slot (pc+4))
linkReg := uint32(0)
if opcode == 3 {
linkReg = 31
}
return m.handleJump(linkReg, SE(insn&0x03FFFFFF, 26)<<2)
// Take top 4 bits of the next PC (its 256 MB region), and concatenate with the 26-bit offset
target := (m.state.NextPC & 0xF0000000) | ((insn & 0x03FFFFFF) << 2)
return m.handleJump(linkReg, target)
}

// register fetch
Expand Down Expand Up @@ -396,7 +396,6 @@ func (m *InstrumentedState) mipsStep() error {
func execute(insn uint32, rs uint32, rt uint32, mem uint32) uint32 {
opcode := insn >> 26 // 6-bits
fun := insn & 0x3f // 6-bits
// TODO(CLI-4136): deref the immed into a register

if opcode < 0x20 {
// transform ArithLogI
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ require (
golang.org/x/term v0.11.0
golang.org/x/time v0.3.0
gorm.io/driver/postgres v1.5.2
gorm.io/gorm v1.25.2
gorm.io/gorm v1.25.3
)

require (
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1111,8 +1111,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0=
gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8=
gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho=
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.3 h1:zi4rHZj1anhZS2EuEODMhDisGy+Daq9jtPrNGgbQYD8=
gorm.io/gorm v1.25.3/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
95 changes: 14 additions & 81 deletions indexer/api/api.go
Original file line number Diff line number Diff line change
@@ -1,102 +1,35 @@
package api

import (
"encoding/json"
"fmt"
"net/http"

"github.com/ethereum-optimism/optimism/indexer/api/routes"
"github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/go-chi/chi/v5"
)

type PaginationResponse struct {
// TODO type this better
Data interface{} `json:"data"`
Cursor string `json:"cursor"`
HasNextPage bool `json:"hasNextPage"`
}

func (a *Api) L1DepositsHandler(w http.ResponseWriter, r *http.Request) {
bv := a.BridgeTransfersView
address := common.HexToAddress(chi.URLParam(r, "address"))

// limit := getIntFromQuery(r, "limit", 10)
// cursor := r.URL.Query().Get("cursor")
// sortDirection := r.URL.Query().Get("sortDirection")

deposits, err := bv.L1BridgeDepositsByAddress(address)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

// This is not the shape of the response we want!!!
// will add in the individual features in future prs 1 by 1
response := PaginationResponse{
Data: deposits,
// Cursor: nextCursor,
HasNextPage: false,
}

jsonResponse(w, response, http.StatusOK)
}

func (a *Api) L2WithdrawalsHandler(w http.ResponseWriter, r *http.Request) {
bv := a.BridgeTransfersView
address := common.HexToAddress(chi.URLParam(r, "address"))

// limit := getIntFromQuery(r, "limit", 10)
// cursor := r.URL.Query().Get("cursor")
// sortDirection := r.URL.Query().Get("sortDirection")

withdrawals, err := bv.L2BridgeWithdrawalsByAddress(address)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

// This is not the shape of the response we want!!!
// will add in the individual features in future prs 1 by 1
response := PaginationResponse{
Data: withdrawals,
// Cursor: nextCursor,
HasNextPage: false,
}

jsonResponse(w, response, http.StatusOK)
}

func (a *Api) HealthzHandler(w http.ResponseWriter, r *http.Request) {
jsonResponse(w, "ok", http.StatusOK)
}

func jsonResponse(w http.ResponseWriter, data interface{}, statusCode int) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(statusCode)
if err := json.NewEncoder(w).Encode(data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
const ethereumAddressRegex = `^0x[a-fA-F0-9]{40}$`

type Api struct {
Router *chi.Mux
BridgeTransfersView database.BridgeTransfersView
Router *chi.Mux
}

func NewApi(bv database.BridgeTransfersView) *Api {
func NewApi(bv database.BridgeTransfersView, logger log.Logger) *Api {
logger.Info("Initializing API...")

r := chi.NewRouter()

api := &Api{Router: r, BridgeTransfersView: bv}
h := routes.NewRoutes(logger, bv)

// these regex are .+ because I wasn't sure what they should be
// don't want a regex for addresses because would prefer to validate the address
// with go-ethereum and throw a friendly error message
r.Get("/api/v0/deposits/{address:.+}", api.L1DepositsHandler)
r.Get("/api/v0/withdrawals/{address:.+}", api.L2WithdrawalsHandler)
r.Get("/healthz", api.HealthzHandler)
api := &Api{Router: r}

return api
r.Get("/healthz", h.HealthzHandler)
r.Get(fmt.Sprintf("/api/v0/deposits/{address:%s}", ethereumAddressRegex), h.L1DepositsHandler)
r.Get(fmt.Sprintf("/api/v0/withdrawals/{address:%s}", ethereumAddressRegex), h.L2WithdrawalsHandler)

return api
}

func (a *Api) Listen(port string) error {
Expand Down
20 changes: 14 additions & 6 deletions indexer/api/api_test.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package api

import (
"fmt"
"math/big"
"net/http"
"net/http/httptest"
"testing"

"github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/assert"
)

// MockBridgeTransfersView mocks the BridgeTransfersView interface
type MockBridgeTransfersView struct{}

var mockAddress = "0x4204204204204204204204204204204204204204"

var (
deposit = database.L1BridgeDeposit{
TransactionSourceHash: common.HexToHash("abc"),
Expand All @@ -23,7 +28,7 @@ var (
}

withdrawal = database.L2BridgeWithdrawal{
TransactionWithdrawalHash: common.HexToHash("0x456"),
TransactionWithdrawalHash: common.HexToHash("0x420"),
CrossDomainMessengerNonce: &database.U256{Int: big.NewInt(0)},
Tx: database.Transaction{},
TokenPair: database.TokenPair{},
Expand Down Expand Up @@ -65,7 +70,8 @@ func (mbv *MockBridgeTransfersView) L2BridgeWithdrawalsByAddress(address common.
}

func TestHealthz(t *testing.T) {
api := NewApi(&MockBridgeTransfersView{})
logger := testlog.Logger(t, log.LvlInfo)
api := NewApi(&MockBridgeTransfersView{}, logger)
request, err := http.NewRequest("GET", "/healthz", nil)
assert.Nil(t, err)

Expand All @@ -76,8 +82,9 @@ func TestHealthz(t *testing.T) {
}

func TestL1BridgeDepositsHandler(t *testing.T) {
api := NewApi(&MockBridgeTransfersView{})
request, err := http.NewRequest("GET", "/api/v0/deposits/0x123", nil)
logger := testlog.Logger(t, log.LvlInfo)
api := NewApi(&MockBridgeTransfersView{}, logger)
request, err := http.NewRequest("GET", fmt.Sprintf("/api/v0/deposits/%s", mockAddress), nil)
assert.Nil(t, err)

responseRecorder := httptest.NewRecorder()
Expand All @@ -87,8 +94,9 @@ func TestL1BridgeDepositsHandler(t *testing.T) {
}

func TestL2BridgeWithdrawalsByAddressHandler(t *testing.T) {
api := NewApi(&MockBridgeTransfersView{})
request, err := http.NewRequest("GET", "/api/v0/withdrawals/0x123", nil)
logger := testlog.Logger(t, log.LvlInfo)
api := NewApi(&MockBridgeTransfersView{}, logger)
request, err := http.NewRequest("GET", fmt.Sprintf("/api/v0/withdrawals/%s", mockAddress), nil)
assert.Nil(t, err)

responseRecorder := httptest.NewRecorder()
Expand Down
52 changes: 52 additions & 0 deletions indexer/api/routes/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package routes

import (
"encoding/json"
"net/http"

"github.com/ethereum/go-ethereum/log"
)

// lazily typing numbers fixme
type Transaction struct {
Timestamp uint64 `json:"timestamp"`
TransactionHash string `json:"transactionHash"`
}

type Block struct {
BlockNumber int64 `json:"number"`
BlockHash string `json:"hash"`
// ParentBlockHash string `json:"parentHash"`
}

type Extensions struct {
OptimismBridgeAddress string `json:"OptimismBridgeAddress"`
}

type TokenInfo struct {
// TODO lazily typing ints go through them all with fine tooth comb once api is up
ChainId int `json:"chainId"`
Address string `json:"address"`
Name string `json:"name"`
Symbol string `json:"symbol"`
Decimals int `json:"decimals"`
Extensions Extensions `json:"extensions"`
}

func jsonResponse(w http.ResponseWriter, logger log.Logger, data interface{}, statusCode int) {
w.Header().Set("Content-Type", "application/json")
jsonData, err := json.Marshal(data)
if err != nil {
http.Error(w, "Internal server error", http.StatusInternalServerError)
logger.Error("Failed to marshal JSON: %v", err)
return
}

w.WriteHeader(statusCode)
_, err = w.Write(jsonData)
if err != nil {
http.Error(w, "Internal server error", http.StatusInternalServerError)
logger.Error("Failed to write JSON data", err)
return
}
}
Loading

0 comments on commit 08aedaa

Please sign in to comment.