Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow array parameters in JSONRPC methods #121

Merged
merged 6 commits into from
Apr 16, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
# resolution options, using npm release or a gh ref:
#
# option #1, set the version of stellar-sdk based on a npm release version
SYSTEM_TEST_JS_STELLAR_SDK_NPM_VERSION: 11.1.0
SYSTEM_TEST_JS_STELLAR_SDK_NPM_VERSION: 11.3.0
# option #2, set the version of stellar-sdk used as a ref to a gh repo if
# a value is set on SYSTEM_TEST_JS_STELLAR_SDK_GH_REPO, it takes
# precedence over any SYSTEM_TEST_JS_STELLAR_SDK_NPM_VERSION
Expand Down
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/get_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"time"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"

"github.com/stellar/go/strkey"
"github.com/stellar/go/support/errors"
Expand Down Expand Up @@ -429,7 +428,7 @@ func NewGetEventsHandler(eventsStore *events.MemoryStore, maxLimit, defaultLimit
maxLimit: maxLimit,
defaultLimit: defaultLimit,
}
return handler.New(func(ctx context.Context, request GetEventsRequest) (GetEventsResponse, error) {
return NewHandler(func(ctx context.Context, request GetEventsRequest) (GetEventsResponse, error) {
return eventsHandler.getEvents(request)
})
}
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/get_latest_ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"

"github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/db"
)
Expand All @@ -20,7 +19,7 @@ type GetLatestLedgerResponse struct {

// NewGetLatestLedgerHandler returns a JSON RPC handler to retrieve the latest ledger entry from Stellar core.
func NewGetLatestLedgerHandler(ledgerEntryReader db.LedgerEntryReader, ledgerReader db.LedgerReader) jrpc2.Handler {
return handler.New(func(ctx context.Context) (GetLatestLedgerResponse, error) {
return NewHandler(func(ctx context.Context) (GetLatestLedgerResponse, error) {
tx, err := ledgerEntryReader.NewTx(ctx)
if err != nil {
return GetLatestLedgerResponse{}, &jrpc2.Error{
Expand Down
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/get_ledger_entries.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"
"github.com/stellar/go/support/log"
"github.com/stellar/go/xdr"

Expand Down Expand Up @@ -40,7 +39,7 @@ const getLedgerEntriesMaxKeys = 200

// NewGetLedgerEntriesHandler returns a JSON RPC handler to retrieve the specified ledger entries from Stellar Core.
func NewGetLedgerEntriesHandler(logger *log.Entry, ledgerEntryReader db.LedgerEntryReader) jrpc2.Handler {
return handler.New(func(ctx context.Context, request GetLedgerEntriesRequest) (GetLedgerEntriesResponse, error) {
return NewHandler(func(ctx context.Context, request GetLedgerEntriesRequest) (GetLedgerEntriesResponse, error) {
if len(request.Keys) > getLedgerEntriesMaxKeys {
return GetLedgerEntriesResponse{}, &jrpc2.Error{
Code: jrpc2.InvalidParams,
Expand Down
4 changes: 1 addition & 3 deletions cmd/soroban-rpc/internal/methods/get_ledger_entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import (
"fmt"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"

"github.com/stellar/go/support/log"
"github.com/stellar/go/xdr"

Expand All @@ -33,7 +31,7 @@ type GetLedgerEntryResponse struct {
// Deprecated. use NewGetLedgerEntriesHandler instead.
// TODO(https://github.com/stellar/soroban-tools/issues/374) remove after getLedgerEntries is deployed.
func NewGetLedgerEntryHandler(logger *log.Entry, ledgerEntryReader db.LedgerEntryReader) jrpc2.Handler {
return handler.New(func(ctx context.Context, request GetLedgerEntryRequest) (GetLedgerEntryResponse, error) {
return NewHandler(func(ctx context.Context, request GetLedgerEntryRequest) (GetLedgerEntryResponse, error) {
var key xdr.LedgerKey
if err := xdr.SafeUnmarshalBase64(request.Key, &key); err != nil {
logger.WithError(err).WithField("request", request).
Expand Down
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/get_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"

"github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/daemon/interfaces"
)
Expand All @@ -20,7 +19,7 @@ type GetNetworkResponse struct {
// NewGetNetworkHandler returns a json rpc handler to for the getNetwork method
func NewGetNetworkHandler(daemon interfaces.Daemon, networkPassphrase, friendbotURL string) jrpc2.Handler {
coreClient := daemon.CoreClient()
return handler.New(func(ctx context.Context, request GetNetworkRequest) (GetNetworkResponse, error) {
return NewHandler(func(ctx context.Context, request GetNetworkRequest) (GetNetworkResponse, error) {
info, err := coreClient.Info(ctx)
if err != nil {
return GetNetworkResponse{}, (&jrpc2.Error{
Expand Down
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/get_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"fmt"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"
"github.com/stellar/go/xdr"

"github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/ledgerbucketwindow"
Expand Down Expand Up @@ -121,7 +120,7 @@ func GetTransaction(getter transactionGetter, request GetTransactionRequest) (Ge

// NewGetTransactionHandler returns a get transaction json rpc handler
func NewGetTransactionHandler(getter transactionGetter) jrpc2.Handler {
return handler.New(func(ctx context.Context, request GetTransactionRequest) (GetTransactionResponse, error) {
return NewHandler(func(ctx context.Context, request GetTransactionRequest) (GetTransactionResponse, error) {
return GetTransaction(getter, request)
})
}
17 changes: 17 additions & 0 deletions cmd/soroban-rpc/internal/methods/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package methods

import (
"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"
)

func NewHandler(fn any) jrpc2.Handler {
fi, err := handler.Check(fn)
if err != nil {
panic(err)
}
// explicitly disable array arguments since otherwise we cannot add
// new method arguments without breaking backwards compatibility with clients
fi.AllowArray(false)
return fi.Wrap()
}
60 changes: 60 additions & 0 deletions cmd/soroban-rpc/internal/methods/handler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package methods

import (
"context"
"testing"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"
"github.com/stretchr/testify/assert"
)

type Request struct {
Parameter string `json:"parameter"`
}

func TestNewHandlerNoArrayParameters(t *testing.T) {
callCount := 0
f := func(ctx context.Context, request Request) error {
callCount++
assert.Equal(t, "bar", request.Parameter)
return nil
}
objectRequest := `{
"jsonrpc": "2.0",
"id": 1,
"method": "foo",
"params": { "parameter": "bar" }
}`
requests, err := jrpc2.ParseRequests([]byte(objectRequest))
assert.NoError(t, err)
assert.Len(t, requests, 1)
finalObjectRequest := requests[0].ToRequest()

// object parameters should work with our handlers
customHandler := NewHandler(f)
_, err = customHandler(context.Background(), finalObjectRequest)
assert.NoError(t, err)
assert.Equal(t, 1, callCount)

arrayRequest := `{
"jsonrpc": "2.0",
"id": 1,
"method": "foo",
"params": ["bar"]
}`
requests, err = jrpc2.ParseRequests([]byte(arrayRequest))
assert.NoError(t, err)
assert.Len(t, requests, 1)
finalArrayRequest := requests[0].ToRequest()

// Array requests should work with the normal handler, but not with our handlers
stdHandler := handler.New(f)
_, err = stdHandler(context.Background(), finalArrayRequest)
assert.NoError(t, err)
assert.Equal(t, 2, callCount)

_, err = customHandler(context.Background(), finalArrayRequest)
assert.Error(t, err)
assert.Contains(t, err.Error(), "invalid parameters")
}
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"time"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"

"github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/ledgerbucketwindow"
)
Expand All @@ -24,7 +23,7 @@ type LedgerRangeGetter interface {

// NewHealthCheck returns a health check json rpc handler
func NewHealthCheck(retentionWindow uint32, ledgerRangeGetter LedgerRangeGetter, maxHealthyLedgerLatency time.Duration) jrpc2.Handler {
return handler.New(func(ctx context.Context) (HealthCheckResult, error) {
return NewHandler(func(ctx context.Context) (HealthCheckResult, error) {
ledgerRange := ledgerRangeGetter.GetLedgerRange()
if ledgerRange.LastLedger.Sequence < 1 {
return HealthCheckResult{}, jrpc2.Error{
Expand Down
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/send_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/hex"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"
"github.com/stellar/go/network"
proto "github.com/stellar/go/protocols/stellarcore"
"github.com/stellar/go/support/log"
Expand Down Expand Up @@ -47,7 +46,7 @@ type SendTransactionRequest struct {
// NewSendTransactionHandler returns a submit transaction json rpc handler
func NewSendTransactionHandler(daemon interfaces.Daemon, logger *log.Entry, ledgerRangeGetter LedgerRangeGetter, passphrase string) jrpc2.Handler {
submitter := daemon.CoreClient()
return handler.New(func(ctx context.Context, request SendTransactionRequest) (SendTransactionResponse, error) {
return NewHandler(func(ctx context.Context, request SendTransactionRequest) (SendTransactionResponse, error) {
var envelope xdr.TransactionEnvelope
err := xdr.SafeUnmarshalBase64(request.Transaction, &envelope)
if err != nil {
Expand Down
3 changes: 1 addition & 2 deletions cmd/soroban-rpc/internal/methods/simulate_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strings"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/handler"
"github.com/stellar/go/support/log"
"github.com/stellar/go/xdr"

Expand Down Expand Up @@ -159,7 +158,7 @@ type PreflightGetter interface {
// NewSimulateTransactionHandler returns a json rpc handler to run preflight simulations
func NewSimulateTransactionHandler(logger *log.Entry, ledgerEntryReader db.LedgerEntryReader, ledgerReader db.LedgerReader, getter PreflightGetter) jrpc2.Handler {

return handler.New(func(ctx context.Context, request SimulateTransactionRequest) SimulateTransactionResponse {
return NewHandler(func(ctx context.Context, request SimulateTransactionRequest) SimulateTransactionResponse {
var txEnvelope xdr.TransactionEnvelope
if err := xdr.SafeUnmarshalBase64(request.Transaction, &txEnvelope); err != nil {
logger.WithError(err).WithField("request", request).
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ toolchain go1.22.1
require (
github.com/Masterminds/squirrel v1.5.4
github.com/cenkalti/backoff/v4 v4.2.1
github.com/creachadair/jrpc2 v1.1.2
github.com/creachadair/jrpc2 v1.2.0
github.com/go-chi/chi v4.1.2+incompatible
github.com/go-git/go-git/v5 v5.9.0
github.com/mattn/go-sqlite3 v1.14.17
Expand Down Expand Up @@ -74,7 +74,7 @@ require (
github.com/aws/aws-sdk-go v1.45.27 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/creachadair/mds v0.3.0 // indirect
github.com/creachadair/mds v0.13.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
Expand Down Expand Up @@ -109,7 +109,7 @@ require (
golang.org/x/crypto v0.16.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creachadair/jrpc2 v1.1.2 h1:UOYMipEFYlwd5qmcvs9GZBurn3oXt1UDIX5JLjWWFzo=
github.com/creachadair/jrpc2 v1.1.2/go.mod h1:JcCe2Eny3lIvVwZLm92WXyU+tNUgTBWFCLMsfNkjEGk=
github.com/creachadair/mds v0.3.0 h1:uKbCKVtd3iOKVv3uviOm13fFNfe9qoCXJh1Vo7y3Kr0=
github.com/creachadair/mds v0.3.0/go.mod h1:4vrFYUzTXMJpMBU+OA292I6IUxKWCCfZkgXg+/kBZMo=
github.com/creachadair/jrpc2 v1.2.0 h1:SXr0OgnwM0X18P+HccJP0uT3KGSDk/BCSRlJBvE2bMY=
github.com/creachadair/jrpc2 v1.2.0/go.mod h1:66uKSdr6tR5ZeNvkIjDSbbVUtOv0UhjS/vcd8ECP7Iw=
github.com/creachadair/mds v0.13.4 h1:RgU0MhiVqkzp6/xtNWhK6Pw7tDeaVuGFtA0UA2RBYvY=
github.com/creachadair/mds v0.13.4/go.mod h1:4vrFYUzTXMJpMBU+OA292I6IUxKWCCfZkgXg+/kBZMo=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -543,8 +543,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
Loading