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 Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
################## update dependencies ####################
ETHEREUM_SUBMODULE_COMMIT_OR_TAG := morph-v2.2.4
ETHEREUM_TARGET_VERSION := morph-v2.2.4
ETHEREUM_SUBMODULE_COMMIT_OR_TAG := morph-v2.2.5
ETHEREUM_TARGET_VERSION := morph-v2.2.5
TENDERMINT_TARGET_VERSION := v0.3.9


Expand Down
2 changes: 1 addition & 1 deletion bindings/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.24.0

replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.9

require github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3
require github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe

require (
github.com/VictoriaMetrics/fastcache v1.12.2 // indirect
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 v1.10.14-0.20260709072051-ffa95e0670a3 h1:vt1tCsMO0eFZQsNnI3KRk76V52ia19Z/Zbpk92x0w3Y=
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe h1:dYfgE9WDq58hiU0V0LmFkr2vUesbFaexyXfvirBVuEQ=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe/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
14 changes: 13 additions & 1 deletion common/batch/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/binary"
"fmt"
"io"
"math"

"morph-l2/common/codec/zstd"

Expand Down Expand Up @@ -242,11 +243,22 @@ func extractInnerTxFullBytes(firstByte byte, reader io.Reader) ([]byte, error) {
return nil, fmt.Errorf("declared tx size %d exceeds remaining %d bytes", size, lr.Len())
}

// Guard the reconstructed length against uint32 overflow before allocating.
// size is a uint32, so 1+sizeByteLen+size can exceed MaxUint32 and wrap to a
// tiny value, leaving fullTxBytes shorter than the copies below and
// panicking. The remaining-bytes guard above keeps this unreachable today,
// but computing in uint64 and rejecting overflow keeps it safe if the size
// type or the upstream bounds ever change.
fullLen := 1 + uint64(sizeByteLen) + uint64(size)
if fullLen > math.MaxUint32 {
return nil, fmt.Errorf("declared tx size %d overflows uint32 length prefix", size)
}

txRaw := make([]byte, size)
if err := binary.Read(reader, binary.BigEndian, txRaw); err != nil {
return nil, err
}
fullTxBytes := make([]byte, 1+uint32(sizeByteLen)+size)
fullTxBytes := make([]byte, fullLen)
copy(fullTxBytes[:1], []byte{firstByte})
copy(fullTxBytes[1:1+sizeByteLen], sizeByte)
copy(fullTxBytes[1+sizeByteLen:], txRaw)
Expand Down
2 changes: 1 addition & 1 deletion common/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.

require (
github.com/holiman/uint256 v1.2.4
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe
github.com/morph-l2/morph-da-codec/bindings/codec v0.0.0-20260727095527-681727561e38
github.com/stretchr/testify v1.10.0
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a
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 v1.10.14-0.20260709072051-ffa95e0670a3 h1:vt1tCsMO0eFZQsNnI3KRk76V52ia19Z/Zbpk92x0w3Y=
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe h1:dYfgE9WDq58hiU0V0LmFkr2vUesbFaexyXfvirBVuEQ=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/morph-da-codec/bindings/codec v0.0.0-20260727095527-681727561e38 h1:2OIgRP51TPMlpw9E82toxu/SQzN1hlYcxpJKC9jB0cs=
github.com/morph-l2/morph-da-codec/bindings/codec v0.0.0-20260727095527-681727561e38/go.mod h1:f6+BHrrHbRmEYplC1nmNjGdatQtMSa2CIK7CX8T1Nfc=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
Expand Down
2 changes: 1 addition & 1 deletion contracts/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.

require (
github.com/iden3/go-iden3-crypto v0.0.16
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe
github.com/stretchr/testify v1.10.0
)

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 v1.10.14-0.20260709072051-ffa95e0670a3 h1:vt1tCsMO0eFZQsNnI3KRk76V52ia19Z/Zbpk92x0w3Y=
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe h1:dYfgE9WDq58hiU0V0LmFkr2vUesbFaexyXfvirBVuEQ=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe/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
25 changes: 22 additions & 3 deletions node/derivation/beacon.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,20 +223,39 @@ func dataAndHashesFromTxs(txs types.Transactions, targetTx *types.Transaction) [
// eliminated by running derivation with confirmations=finalized, not by
// trying more beacons.
type FallbackBeaconClient struct {
clients []*L1BeaconClient
endpoints []string // parallel to clients, used only for logs/metrics
clients []*L1BeaconClient
// endpoints is parallel to clients and used only for logs/metrics; entries
// are pre-redacted to scheme://host so credentials embedded in the
// configured URLs never reach the metrics endpoint or log output.
endpoints []string
log tmlog.Logger
metrics *Metrics
}

// redactBeaconEndpoint reduces a beacon URL to scheme://host for use in
// metrics labels and logs. Hosted beacon providers commonly embed basic-auth
// userinfo or API keys in the URL (https://user:pass@host, ?apikey=...);
// exposing the raw string on /metrics or in aggregated logs would leak them.
// An endpoint that does not parse as an absolute URL collapses to a
// placeholder rather than echoing the raw string.
func redactBeaconEndpoint(raw string) string {
parsed, err := url.Parse(raw)
if err != nil || parsed.Scheme == "" || parsed.Host == "" {
return "<invalid-endpoint>"
}
return parsed.Scheme + "://" + parsed.Host
}

func NewFallbackBeaconClient(endpoints []string, log tmlog.Logger, metrics *Metrics) *FallbackBeaconClient {
clients := make([]*L1BeaconClient, 0, len(endpoints))
redacted := make([]string, 0, len(endpoints))
for _, endpoint := range endpoints {
clients = append(clients, NewL1BeaconClient(NewBasicHTTPClient(endpoint, log)))
redacted = append(redacted, redactBeaconEndpoint(endpoint))
}
return &FallbackBeaconClient{
clients: clients,
endpoints: endpoints,
endpoints: redacted,
log: log,
metrics: metrics,
}
Expand Down
20 changes: 20 additions & 0 deletions node/derivation/beacon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,26 @@ func TestGetBlob(t *testing.T) {

}

func TestRedactBeaconEndpoint(t *testing.T) {
cases := []struct {
name string
in string
want string
}{
{"plain", "https://beacon.example.com", "https://beacon.example.com"},
{"basic auth stripped", "https://user:secret@beacon.example.com:5052", "https://beacon.example.com:5052"},
{"api key in path and query stripped", "https://beacon.example.com/eth/key-abc123?apikey=secret", "https://beacon.example.com"},
{"not a url", "not a url", "<invalid-endpoint>"},
{"missing scheme", "beacon.example.com:5052", "<invalid-endpoint>"},
{"empty", "", "<invalid-endpoint>"},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
require.Equal(t, tc.want, redactBeaconEndpoint(tc.in))
})
}
}

func testTchRollupLog(l1Client *ethclient.Client, ctx context.Context, from, to uint64) ([]eth.Log, error) {
RollupContractAddress := common.HexToAddress("0x511d92b63ae7471fd5239bded29b76a446698a00")
query := ethereum.FilterQuery{
Expand Down
7 changes: 7 additions & 0 deletions node/derivation/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ func (c *Config) SetCliContext(ctx *cli.Context) error {

if c.VerifyMode == VerifyModeLayer1 {
c.MetricsPort = ctx.GlobalUint64(flags.MetricsPort.Name)
// Reject an out-of-range port up front: MetricsPort is a uint64, so a
// misconfigured value would only surface later as an invalid listen
// address whose ListenAndServe fails silently in the background. The
// default (26660) is always in range, so a valid config never trips this.
if c.MetricsPort == 0 || c.MetricsPort > 65535 {
return fmt.Errorf("--%s must be in 1..65535, got %d", flags.MetricsPort.Name, c.MetricsPort)
}
}

if ctx.GlobalIsSet(flags.DerivationReorgCheckDepth.Name) {
Expand Down
27 changes: 27 additions & 0 deletions node/derivation/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,32 @@ func TestVerifyMode_RejectsUnknown(t *testing.T) {
}
}

func TestMetricsPort_AcceptsDefaultInLayer1(t *testing.T) {
cfg := DefaultConfig()
if err := cfg.SetCliContext(newVerifyModeTestContext(t, map[string]string{
flags.DerivationVerifyMode.Name: VerifyModeLayer1,
})); err != nil {
t.Fatalf("layer1 with default metrics-port rejected: %v", err)
}
if cfg.MetricsPort != 26660 {
t.Fatalf("default metrics-port = %d, want 26660", cfg.MetricsPort)
}
}

func TestMetricsPort_RejectsOutOfRange(t *testing.T) {
cfg := DefaultConfig()
err := cfg.SetCliContext(newVerifyModeTestContext(t, map[string]string{
flags.DerivationVerifyMode.Name: VerifyModeLayer1,
flags.MetricsPort.Name: "70000",
}))
if err == nil {
t.Fatal("out-of-range metrics-port accepted, want error")
}
if !strings.Contains(err.Error(), flags.MetricsPort.Name) {
t.Fatalf("error should mention %q; got: %v", flags.MetricsPort.Name, err)
}
}

func TestBeaconRpcList(t *testing.T) {
for _, tc := range []struct {
name string
Expand Down Expand Up @@ -126,6 +152,7 @@ func newVerifyModeTestContext(t *testing.T, values map[string]string) *cli.Conte
for _, f := range []cli.Flag{
flags.LegacyValidatorMode,
flags.DerivationVerifyMode,
flags.MetricsPort,
flags.L1BeaconAddr,
flags.L2EngineJWTSecret,
} {
Expand Down
2 changes: 1 addition & 1 deletion node/derivation/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics {
Namespace: namespace,
Subsystem: metricsSubsystem,
Name: "beacon_request_failure_total",
Help: "Beacon requests that failed (transport error or non-200) per endpoint, before falling back to the next configured beacon.",
Help: "Beacon requests that failed (transport error, non-200, or an empty/incomplete sidecar set) per endpoint, before falling back to the next configured beacon.",
}, append(append([]string{}, labels...), "endpoint")),
}
}
Expand Down
2 changes: 1 addition & 1 deletion node/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/hashicorp/raft v1.7.3
github.com/hashicorp/raft-boltdb/v2 v2.3.1
github.com/mdlayher/vsock v1.2.1
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.17.0
github.com/spf13/viper v1.13.0
Expand Down
2 changes: 2 additions & 0 deletions node/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,8 @@ 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 v1.10.14-0.20260709072051-ffa95e0670a3 h1:vt1tCsMO0eFZQsNnI3KRk76V52ia19Z/Zbpk92x0w3Y=
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe h1:dYfgE9WDq58hiU0V0LmFkr2vUesbFaexyXfvirBVuEQ=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/tendermint v0.3.9 h1:0jiFtMpVmVImCAFrMFTIvTX7jfJwzaQFyLQoLccP5A8=
github.com/morph-l2/tendermint v0.3.9/go.mod h1:qpiwqfcCB89dBYfqVJOc/HjGxDp3OdDlthgttJJYyRs=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
Expand Down
2 changes: 1 addition & 1 deletion ops/l2-genesis/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.

require (
github.com/holiman/uint256 v1.2.4
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe
github.com/stretchr/testify v1.10.0
github.com/urfave/cli v1.22.17
)
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 v1.10.14-0.20260709072051-ffa95e0670a3 h1:vt1tCsMO0eFZQsNnI3KRk76V52ia19Z/Zbpk92x0w3Y=
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe h1:dYfgE9WDq58hiU0V0LmFkr2vUesbFaexyXfvirBVuEQ=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe/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
2 changes: 1 addition & 1 deletion ops/tools/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.24.0
replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.9

require (
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe
github.com/tendermint/tendermint v0.35.9
)

Expand Down
2 changes: 2 additions & 0 deletions ops/tools/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,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 v1.10.14-0.20260709072051-ffa95e0670a3 h1:vt1tCsMO0eFZQsNnI3KRk76V52ia19Z/Zbpk92x0w3Y=
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe h1:dYfgE9WDq58hiU0V0LmFkr2vUesbFaexyXfvirBVuEQ=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/tendermint v0.3.9 h1:0jiFtMpVmVImCAFrMFTIvTX7jfJwzaQFyLQoLccP5A8=
github.com/morph-l2/tendermint v0.3.9/go.mod h1:qpiwqfcCB89dBYfqVJOc/HjGxDp3OdDlthgttJJYyRs=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
Expand Down
11 changes: 10 additions & 1 deletion token-price-oracle/client/cex_feed.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ const (
okxTickerPath = "/api/v5/market/ticker"
)

// maxResponseBodyBytes caps how much of an HTTP price response is read into memory.
// Ticker and Hermes latest-price payloads are a few KB at most; the cap only exists
// so a compromised or misbehaving endpoint cannot stream an unbounded body and
// exhaust memory.
const maxResponseBodyBytes = 1 << 20 // 1 MiB

type cexPriceFetcher func(ctx context.Context, httpClient *http.Client, baseURL string, symbol string) (*big.Float, error)

// CEXPriceFeed fetches token prices from a centralized exchange REST API.
Expand Down Expand Up @@ -243,10 +249,13 @@ func getJSONWithHeaders(ctx context.Context, httpClient *http.Client, requestURL
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
body, err := io.ReadAll(io.LimitReader(resp.Body, maxResponseBodyBytes+1))
if err != nil {
return nil, fmt.Errorf("failed to read response body: %w", err)
}
if int64(len(body)) > maxResponseBodyBytes {
return nil, fmt.Errorf("response body exceeds %d byte limit", maxResponseBodyBytes)
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("HTTP status %d: %s", resp.StatusCode, string(body))
}
Expand Down
32 changes: 32 additions & 0 deletions token-price-oracle/client/cex_feed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,38 @@ func TestFetchOKXPrice(t *testing.T) {
}
}

func TestGetJSONRejectsOversizedBody(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
// Stream more than the cap so a compromised/misbehaving endpoint cannot
// force an unbounded allocation.
oversized := make([]byte, maxResponseBodyBytes+1)
w.Write(oversized)
}))
defer server.Close()

if _, err := getJSON(context.Background(), server.Client(), server.URL); err == nil {
t.Fatal("getJSON accepted an oversized response body, want error")
}
}

func TestGetJSONAcceptsBodyAtLimit(t *testing.T) {
payload := `{"symbol":"BTCUSDT","price":"64385.12"}`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(payload))
}))
defer server.Close()

body, err := getJSON(context.Background(), server.Client(), server.URL)
if err != nil {
t.Fatal(err)
}
if string(body) != payload {
t.Fatalf("body = %q, want %q", string(body), payload)
}
}

func TestParseFixedStablecoinPrice(t *testing.T) {
price, err := parseFixedStablecoinPrice("$1.0")
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion token-price-oracle/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ replace (
)

require (
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe
github.com/morph-l2/remote-signer-client/go v0.0.0-20260312080033-d078d86ddbe9
github.com/prometheus/client_golang v1.17.0
github.com/sirupsen/logrus v1.9.3
Expand Down
2 changes: 2 additions & 0 deletions token-price-oracle/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,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 v1.10.14-0.20260709072051-ffa95e0670a3 h1:vt1tCsMO0eFZQsNnI3KRk76V52ia19Z/Zbpk92x0w3Y=
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe h1:dYfgE9WDq58hiU0V0LmFkr2vUesbFaexyXfvirBVuEQ=
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe/go.mod h1:nkVzHjQWCOjvukQW8ittlwX+Xz9gmVHrP7mUi7zoHTs=
github.com/morph-l2/remote-signer-client/go v0.0.0-20260312080033-d078d86ddbe9 h1:d2nKLUgiEJsQmpSWEiGbsC+sZXQCM4y/3EzyXkoMM60=
github.com/morph-l2/remote-signer-client/go v0.0.0-20260312080033-d078d86ddbe9/go.mod h1:slD6GmYEwLHn4Yj/kO8/1QF3iaYlVVAXg2ZnGr8SW/8=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
Expand Down
2 changes: 1 addition & 1 deletion tx-submitter/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/crate-crypto/go-eth-kzg v1.4.0
github.com/holiman/uint256 v1.2.4
github.com/morph-l2/externalsign v0.3.1
github.com/morph-l2/go-ethereum v1.10.14-0.20260709072051-ffa95e0670a3
github.com/morph-l2/go-ethereum v1.10.14-0.20260810084402-5a13ad4d76fe
github.com/prometheus/client_golang v1.17.0
github.com/stretchr/testify v1.10.0
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a
Expand Down
Loading
Loading