Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bindings/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ module morph-l2/bindings

go 1.24.0

replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.8-0.20260617072029-29056623cdb0
replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.8-0.20260622082553-4abd48c31b4d

replace github.com/morph-l2/go-ethereum => github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc
replace github.com/morph-l2/go-ethereum => github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68

require github.com/morph-l2/go-ethereum v1.10.14-0.20251219060125-03910bc750a2

Expand Down
2 changes: 2 additions & 0 deletions bindings/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc h1:2Umr8WRDBKwCgGrQQ8yCdhn71bCuMJuecId2ClK80DU=
github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68 h1:n/1vutNb2x2tzNvVZvfU8frb5nI8hEBcRyX0oEVMtU0=
github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
Expand Down
4 changes: 2 additions & 2 deletions common/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ module morph-l2/common

go 1.24.0

replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.8-0.20260617072029-29056623cdb0
replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.8-0.20260622082553-4abd48c31b4d

replace github.com/morph-l2/go-ethereum => github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc
replace github.com/morph-l2/go-ethereum => github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68

require (
github.com/holiman/uint256 v1.2.4
Expand Down
2 changes: 2 additions & 0 deletions common/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc h1:2Umr8WRDBKwCgGrQQ8yCdhn71bCuMJuecId2ClK80DU=
github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68 h1:n/1vutNb2x2tzNvVZvfU8frb5nI8hEBcRyX0oEVMtU0=
github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
Expand Down
4 changes: 2 additions & 2 deletions contracts/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ module morph-l2/contract

go 1.24.0

replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.8-0.20260617072029-29056623cdb0
replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.8-0.20260622082553-4abd48c31b4d

replace github.com/morph-l2/go-ethereum => github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc
replace github.com/morph-l2/go-ethereum => github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68

require (
github.com/iden3/go-iden3-crypto v0.0.16
Expand Down
2 changes: 2 additions & 0 deletions contracts/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc h1:2Umr8WRDBKwCgGrQQ8yCdhn71bCuMJuecId2ClK80DU=
github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68 h1:n/1vutNb2x2tzNvVZvfU8frb5nI8hEBcRyX0oEVMtU0=
github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
Expand Down
4 changes: 2 additions & 2 deletions node/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ module morph-l2/node

go 1.24.0

replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.8-0.20260617072029-29056623cdb0
replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.8-0.20260622082553-4abd48c31b4d

replace github.com/morph-l2/go-ethereum => github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc
replace github.com/morph-l2/go-ethereum => github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68

require (
github.com/cenkalti/backoff/v4 v4.1.3
Expand Down
8 changes: 8 additions & 0 deletions node/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,16 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc h1:2Umr8WRDBKwCgGrQQ8yCdhn71bCuMJuecId2ClK80DU=
github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68 h1:n/1vutNb2x2tzNvVZvfU8frb5nI8hEBcRyX0oEVMtU0=
github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/tendermint v0.3.8-0.20260617072029-29056623cdb0 h1:LcRbLo0pQXev4z/6i65mVr/9XoFE9Zf7+tcqKItpE+M=
github.com/morph-l2/tendermint v0.3.8-0.20260617072029-29056623cdb0/go.mod h1:qpiwqfcCB89dBYfqVJOc/HjGxDp3OdDlthgttJJYyRs=
github.com/morph-l2/tendermint v0.3.8-0.20260622034124-c3cd60c45732 h1:7aM6NX2PLj7WRGnQBJ3bfVlByLVsJagVzvjuQjcUeUk=
github.com/morph-l2/tendermint v0.3.8-0.20260622034124-c3cd60c45732/go.mod h1:qpiwqfcCB89dBYfqVJOc/HjGxDp3OdDlthgttJJYyRs=
github.com/morph-l2/tendermint v0.3.8-0.20260622055959-eed7fed8ce2e h1:cTeHNzxDG9qr2iP6rgo2ql+0gHBeKDh9svonHus5HGw=
github.com/morph-l2/tendermint v0.3.8-0.20260622055959-eed7fed8ce2e/go.mod h1:qpiwqfcCB89dBYfqVJOc/HjGxDp3OdDlthgttJJYyRs=
github.com/morph-l2/tendermint v0.3.8-0.20260622082553-4abd48c31b4d h1:/LRd3UtaefI+IzFE6cdODGJTOrmWKdzrRGAMPMgeQMs=
github.com/morph-l2/tendermint v0.3.8-0.20260622082553-4abd48c31b4d/go.mod h1:qpiwqfcCB89dBYfqVJOc/HjGxDp3OdDlthgttJJYyRs=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
Expand Down
21 changes: 15 additions & 6 deletions node/hakeeper/block_fsm.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ type FSMDecodeError struct{ Err error }
func (e *FSMDecodeError) Error() string { return fmt.Sprintf("FSM decode: %v", e.Err) }
func (e *FSMDecodeError) Unwrap() error { return e.Err }

// FSMApplyError is returned when the business callback (geth applyBlock / saveSignature) fails.
// FSMApplyError is the panic value raised when the business callback
// (geth applyBlock / saveSignature) fails. FSM apply must not fail silently;
// see BlockFSM.Apply for why this is fatal rather than a returned error.
type FSMApplyError struct {
Height uint64
Err error
Expand Down Expand Up @@ -77,10 +79,12 @@ func (f *BlockFSM) SetOnBlockApplied(fn func(*types.BlockV2) error) {
// - Decode failure → returns FSMDecodeError. For the leader this propagates via
// Future.Response() and triggers a panic (invariant violation). For followers
// it is logged by Raft.
// - onApplied failure → returns FSMApplyError. For the leader this triggers a
// panic via Commit(). For followers, the block is NOT delivered to blockCh
// and appliedHeight is NOT advanced; the follower becomes degraded and
// requires manual resync.
// - onApplied failure → panics with FSMApplyError. Raft applies each committed
// entry exactly once and never retries, and a follower's Apply return value
// is discarded, so logging-and-skipping would strand geth at height-1
// forever (the next block's parent never lands) — a silent gap. Panicking
// fails the node fast (leader and follower alike) so process supervision /
// alerting catches it instead of the node silently diverging.
// - Success → block is delivered to blockCh (for P2P broadcast) and
// appliedHeight is advanced (for snapshot/log compaction).
func (f *BlockFSM) Apply(l *raft.Log) interface{} {
Expand All @@ -105,7 +109,12 @@ func (f *BlockFSM) Apply(l *raft.Log) interface{} {
if fn != nil {
t1 := time.Now()
if err := fn(block); err != nil {
return &FSMApplyError{Height: block.Number, Err: err}
// Fail-fast: Raft applies each committed entry exactly once and does
// not retry, and a follower's Apply return value is discarded. A
// silent skip would strand geth at height-1 forever (the next
// block's parent never lands). Panic so leader and follower alike
// crash loudly and get caught by process supervision / alerting.
panic(&FSMApplyError{Height: block.Number, Err: err})
}
onAppliedDur = time.Since(t1)
} else {
Expand Down
20 changes: 20 additions & 0 deletions node/hakeeper/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,26 @@ func (c *Config) Validate() error {
return fmt.Errorf("invalid rpc.listen_port: %d", c.RPC.ListenPort)
}

// Raft timing sanity. A non-positive heartbeat disables liveness; a leader
// lease >= heartbeat destabilizes leadership (hashicorp/raft also requires
// LeaderLeaseTimeout <= HeartbeatTimeout).
if c.Timeout.Heartbeat <= 0 {
return fmt.Errorf("timeout.heartbeat must be > 0, got %s", c.Timeout.Heartbeat)
}
if c.Timeout.LeaderLease <= 0 {
return fmt.Errorf("timeout.leader_lease must be > 0, got %s", c.Timeout.LeaderLease)
}
if c.Timeout.LeaderLease >= c.Timeout.Heartbeat {
return fmt.Errorf("timeout.leader_lease (%s) must be less than timeout.heartbeat (%s)",
c.Timeout.LeaderLease, c.Timeout.Heartbeat)
}

// TrailingLogs must be positive: snapshotting with 0 trailing logs truncates
// entries a lagging follower still needs, breaking catch-up.
if c.Snapshot.TrailingLogs == 0 {
return fmt.Errorf("snapshot.trailing_logs must be > 0")
}

// AdvertisedAddr must be a routable address (IP or hostname) after Resolve().
if c.Consensus.AdvertisedAddr != "" {
host, _, err := net.SplitHostPort(c.Consensus.AdvertisedAddr)
Expand Down
55 changes: 45 additions & 10 deletions node/hakeeper/rpc/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,43 @@ func authMiddleware(token string, next http.Handler) http.Handler {
})
}

// requiresAuth reports whether the request body contains any write JSON-RPC method.
// Handles both single requests ({...}) and batch requests ([...]).
// requiresAuth reports whether the request body must carry a write-auth token.
//
// It is fail-closed: it returns true (require a token) for anything it cannot
// positively prove to be read-only. Parsing mirrors the downstream
// go-ethereum JSON-RPC server (rpc/json.go readBatch + parseMessage): a
// streaming decoder reads the first JSON value (trailing bytes ignored) and a
// batch is split element-by-element. Using the same parser as the server, plus
// failing closed on any decode error, removes the differential where a
// malformed body classified as "no write method" by the middleware is still
// executed as a write method by the server.
func requiresAuth(body []byte) bool {
trimmed := bytes.TrimSpace(body)
if len(trimmed) == 0 {
return false
return true
}

// Read exactly the first JSON value, like the server's codec does. A second
// value or trailing bytes are ignored by both, so we classify what the
// server will actually execute.
dec := json.NewDecoder(bytes.NewReader(trimmed))
var raw json.RawMessage
if err := dec.Decode(&raw); err != nil {
return true
}

if trimmed[0] == '[' {
var batch []rpcEnvelope
if err := json.Unmarshal(trimmed, &batch); err != nil {
return false
if isJSONBatch(raw) {
bd := json.NewDecoder(bytes.NewReader(raw))
if _, err := bd.Token(); err != nil { // consume '['
return true
}
for _, req := range batch {
for bd.More() {
var req rpcEnvelope
if err := bd.Decode(&req); err != nil {
// The server decodes batch elements independently; an element we
// can't classify might still be executed, so fail closed.
return true
}
if writeRPCMethods[req.Method] {
return true
}
Expand All @@ -76,8 +99,20 @@ func requiresAuth(body []byte) bool {
}

var req rpcEnvelope
if err := json.Unmarshal(trimmed, &req); err != nil {
return false
if err := json.Unmarshal(raw, &req); err != nil {
return true
}
return writeRPCMethods[req.Method]
}

// isJSONBatch reports whether the first non-whitespace byte is '[', matching
// go-ethereum's rpc.isBatch so batch detection stays identical to the server.
func isJSONBatch(raw json.RawMessage) bool {
for _, c := range raw {
if c == 0x20 || c == 0x09 || c == 0x0a || c == 0x0d {
continue
}
return c == '['
}
return false
}
44 changes: 44 additions & 0 deletions node/hakeeper/rpc/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,47 @@ func TestAuthMiddleware_BodyReadable(t *testing.T) {
t.Fatalf("body not restored: got %q", captured)
}
}

// --- parser-mismatch / fail-closed regression tests ---

// A trailing byte after a valid object: the downstream streaming decoder ignores
// it and still executes the write method, so the middleware must require a token.
func TestAuthMiddleware_TrailingGarbageAfterWrite_NoToken_Returns401(t *testing.T) {
h := authMiddleware("secret", okHandler)
body := `{"jsonrpc":"2.0","method":"ha_removeServer","params":["node-2",1],"id":1}X`
req := httptest.NewRequest(http.MethodPost, "/", bytes.NewBufferString(body))
req.Header.Set("Content-Type", "application/json")
rr := httptest.NewRecorder()
h.ServeHTTP(rr, req)
if rr.Code != http.StatusUnauthorized {
t.Fatalf("expected 401 for trailing-garbage write request, got %d", rr.Code)
}
}

// A non-object leading element makes a strict whole-batch unmarshal fail, but the
// server decodes batch elements independently and would run the write method.
func TestAuthMiddleware_BatchInvalidElementThenWrite_NoToken_Returns401(t *testing.T) {
h := authMiddleware("secret", okHandler)
body := `[123,{"jsonrpc":"2.0","method":"ha_removeServer","params":["node-2",1],"id":1}]`
req := httptest.NewRequest(http.MethodPost, "/", bytes.NewBufferString(body))
req.Header.Set("Content-Type", "application/json")
rr := httptest.NewRecorder()
h.ServeHTTP(rr, req)
if rr.Code != http.StatusUnauthorized {
t.Fatalf("expected 401 for batch with invalid element + write method, got %d", rr.Code)
}
}

// Fail-closed: a body that cannot be proven read-only must require a token.
func TestAuthMiddleware_UnparseableBody_NoToken_Returns401(t *testing.T) {
h := authMiddleware("secret", okHandler)
for _, body := range []string{"", " ", "not-json", "123"} {
req := httptest.NewRequest(http.MethodPost, "/", bytes.NewBufferString(body))
req.Header.Set("Content-Type", "application/json")
rr := httptest.NewRecorder()
h.ServeHTTP(rr, req)
if rr.Code != http.StatusUnauthorized {
t.Fatalf("expected 401 for unparseable body %q, got %d", body, rr.Code)
}
}
}
17 changes: 14 additions & 3 deletions node/hakeeper/rpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,20 @@ func New(log log.Logger, listenAddr string, listenPort int, cons ConsensusAdapte

addr := fmt.Sprintf("%s:%d", listenAddr, listenPort)
httpSrv := &http.Server{
Addr: addr,
Handler: mux,
ReadHeaderTimeout: 10 * time.Second,
Addr: addr,
Handler: mux,
// Bound every phase so a slow client cannot pin a goroutine/connection
// indefinitely (slowloris). Requests/responses are tiny control-plane
// JSON-RPC, so the read side is kept tight. WriteTimeout is the handler
// execution budget: a write method runs a Raft membership op that waits up
// to raftTimeout (5s, see ha_service.go) before returning a clean error,
// so this must stay above 5s; otherwise the connection is cut mid-op while
// the Raft op keeps running server-side (WriteTimeout does not cancel the
// handler). 10s = 5s raft budget + margin for JSON/scheduling.
ReadHeaderTimeout: 5 * time.Second,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
IdleTimeout: 60 * time.Second,
}

return &Server{
Expand Down
4 changes: 2 additions & 2 deletions ops/l2-genesis/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ module morph-l2/morph-deployer

go 1.24.0

replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.8-0.20260617072029-29056623cdb0
replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.8-0.20260622082553-4abd48c31b4d

replace github.com/morph-l2/go-ethereum => github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc
replace github.com/morph-l2/go-ethereum => github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68

require (
github.com/holiman/uint256 v1.2.4
Expand Down
2 changes: 2 additions & 0 deletions ops/l2-genesis/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc h1:2Umr8WRDBKwCgGrQQ8yCdhn71bCuMJuecId2ClK80DU=
github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68 h1:n/1vutNb2x2tzNvVZvfU8frb5nI8hEBcRyX0oEVMtU0=
github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
Expand Down
4 changes: 2 additions & 2 deletions ops/tools/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ module morph-l2/tools

go 1.24.0

replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.8-0.20260617072029-29056623cdb0
replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.8-0.20260622082553-4abd48c31b4d

replace github.com/morph-l2/go-ethereum => github.com/morph-l2/go-ethereum v0.0.0-20260608072528-fe02cc1f10bc
replace github.com/morph-l2/go-ethereum => github.com/morph-l2/go-ethereum v1.10.14-0.20260622034103-0d7e79c95a68

require (
github.com/morph-l2/go-ethereum v1.10.14-0.20251219060125-03910bc750a2
Expand Down
Loading
Loading