Skip to content

Commit

Permalink
Add integration test and a few fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
2opremio committed May 16, 2024
1 parent 04bdced commit 57ecad1
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 190 deletions.
1 change: 1 addition & 0 deletions cmd/soroban-rpc/internal/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ func MustNew(cfg *config.Config) *Daemon {
Daemon: daemon,
EventStore: eventStore,
TransactionStore: transactionStore,
FeeStatWindows: feewindows,
Logger: logger,
LedgerReader: db.NewLedgerReader(dbConn),
LedgerEntryReader: db.NewLedgerEntryReader(dbConn),
Expand Down
11 changes: 7 additions & 4 deletions cmd/soroban-rpc/internal/feewindow/feewindow.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,20 +146,23 @@ func (fw *FeeWindows) IngestFees(meta xdr.LedgerCloseMeta) error {
if err != nil {
return err
}
feeCharged := uint64(tx.Result.Result.FeeCharged)
ops := tx.Envelope.Operations()
if len(ops) == 1 {
switch ops[0].Body.Type {
case xdr.OperationTypeInvokeHostFunction, xdr.OperationTypeExtendFootprintTtl, xdr.OperationTypeRestoreFootprint:
if tx.Envelope.V1 == nil || tx.Envelope.V1.Tx.Ext.SorobanData != nil {
// this shouldn't happen
if tx.UnsafeMeta.V != 3 || tx.UnsafeMeta.V3.SorobanMeta == nil || tx.UnsafeMeta.V3.SorobanMeta.Ext.V != 1 {
continue
}
inclusionFee := uint64(tx.Envelope.V1.Tx.Fee) - uint64(tx.Envelope.V1.Tx.Ext.SorobanData.ResourceFee)
sorobanFees := tx.UnsafeMeta.V3.SorobanMeta.Ext.V1
// TODO: this seems incorrect, since in integration tests it's larger than feeCharged
sorobanFeeCharged := sorobanFees.RentFeeCharged + sorobanFees.TotalNonRefundableResourceFeeCharged + sorobanFees.TotalRefundableResourceFeeCharged
inclusionFee := feeCharged - uint64(sorobanFeeCharged)
sorobanInclusionFees = append(sorobanInclusionFees, inclusionFee)
continue
}
}
classicFees = append(classicFees, uint64(tx.Envelope.Fee()))
classicFees = append(classicFees, feeCharged)

}
bucket := ledgerbucketwindow.LedgerBucket[[]uint64]{
Expand Down
2 changes: 1 addition & 1 deletion cmd/soroban-rpc/internal/jsonrpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ func NewJSONRPCHandler(cfg *config.Config, params HandlerParams) Handler {
},
{
methodName: "getFeeStats",
underlyingHandler: methods.NewGetFeeStats(params.FeeStatWindows, ledgerRangeGetter),
underlyingHandler: methods.NewGetFeeStatsHandler(params.FeeStatWindows, ledgerRangeGetter),
longName: "get_fee_stats",
queueLimit: cfg.RequestBacklogGetFeeStatsTransactionQueueLimit,
requestDurationLimit: cfg.MaxGetFeeStatsExecutionDuration,
Expand Down
4 changes: 2 additions & 2 deletions cmd/soroban-rpc/internal/methods/get_fee_stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ type GetFeeStatsResult struct {
LatestLedger uint32 `json:"latestLedger"`
}

// NewGetFeeStatsHandler returns a health check json rpc handler
func NewGetFeeStats(windows *feewindow.FeeWindows, ledgerRangeGetter LedgerRangeGetter) jrpc2.Handler {
// NewGetFeeStatsHandler returns a handler obtaining fee statistics
func NewGetFeeStatsHandler(windows *feewindow.FeeWindows, ledgerRangeGetter LedgerRangeGetter) jrpc2.Handler {
return NewHandler(func(ctx context.Context) (GetFeeStatsResult, error) {
result := GetFeeStatsResult{
SorobanInclusionFee: convertFeeDistribution(windows.SorobanInclusionFeeWindow.GetFeeDistribution()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ ENABLE_SOROBAN_DIAGNOSTIC_EVENTS=true
TESTING_MINIMUM_PERSISTENT_ENTRY_LIFETIME=10
TESTING_SOROBAN_HIGH_LIMIT_OVERRIDE=true

EMIT_SOROBAN_TRANSACTION_META_EXT_V1=true

[[VALIDATORS]]
NAME="local_core"
HOME_DOMAIN="core.local"
Expand Down
122 changes: 122 additions & 0 deletions cmd/soroban-rpc/internal/test/get_fee_stats_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package test

import (
"context"
"testing"

"github.com/creachadair/jrpc2"
"github.com/creachadair/jrpc2/jhttp"
"github.com/stellar/go/keypair"
"github.com/stellar/go/txnbuild"
"github.com/stellar/go/xdr"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/stellar/soroban-rpc/cmd/soroban-rpc/internal/methods"
)

func TestGetFeeStats(t *testing.T) {
test := NewTest(t, nil)

ch := jhttp.NewChannel(test.sorobanRPCURL(), nil)
client := jrpc2.NewClient(ch, nil)

sourceAccount := keypair.Root(StandaloneNetworkPassphrase)
address := sourceAccount.Address()
account := txnbuild.NewSimpleAccount(address, 0)

// Submit soroban transaction
contractBinary := getHelloWorldContract(t)
params := preflightTransactionParams(t, client, txnbuild.TransactionParams{
SourceAccount: &account,
IncrementSequenceNum: true,
Operations: []txnbuild.Operation{
createInstallContractCodeOperation(account.AccountID, contractBinary),
},
BaseFee: txnbuild.MinBaseFee,
Preconditions: txnbuild.Preconditions{
TimeBounds: txnbuild.NewInfiniteTimeout(),
},
})
tx, err := txnbuild.NewTransaction(params)
assert.NoError(t, err)
sorobanTxResponse := sendSuccessfulTransaction(t, client, sourceAccount, tx)
var sorobanTxResult xdr.TransactionResult
require.NoError(t, xdr.SafeUnmarshalBase64(sorobanTxResponse.ResultXdr, &sorobanTxResult))
sorobanTotalFee := sorobanTxResult.FeeCharged
var sorobanTxMeta xdr.TransactionMeta
require.NoError(t, xdr.SafeUnmarshalBase64(sorobanTxResponse.ResultMetaXdr, &sorobanTxMeta))
sorobanFees := sorobanTxMeta.MustV3().SorobanMeta.Ext.MustV1()
sorobanNonInclusionFee := sorobanFees.RentFeeCharged + sorobanFees.TotalRefundableResourceFeeCharged + sorobanFees.TotalNonRefundableResourceFeeCharged
sorobanInclusionFee := uint64(sorobanTotalFee - sorobanNonInclusionFee)

// Submit classic transaction
params = txnbuild.TransactionParams{
SourceAccount: &account,
IncrementSequenceNum: true,
Operations: []txnbuild.Operation{
&txnbuild.BumpSequence{BumpTo: account.Sequence + 100},
},
BaseFee: txnbuild.MinBaseFee,
Memo: nil,
Preconditions: txnbuild.Preconditions{
TimeBounds: txnbuild.NewInfiniteTimeout(),
},
}
tx, err = txnbuild.NewTransaction(params)
assert.NoError(t, err)
classicTxResponse := sendSuccessfulTransaction(t, client, sourceAccount, tx)
var classicTxResult xdr.TransactionResult
require.NoError(t, xdr.SafeUnmarshalBase64(classicTxResponse.ResultXdr, &classicTxResult))
classicFee := uint64(classicTxResult.FeeCharged)

var result methods.GetFeeStatsResult
if err := client.CallResult(context.Background(), "getFeeStats", nil, &result); err != nil {
t.Fatalf("rpc call failed: %v", err)
}
expectedResult := methods.GetFeeStatsResult{
SorobanInclusionFee: methods.FeeDistribution{
Max: sorobanInclusionFee,
Min: sorobanInclusionFee,
Mode: sorobanInclusionFee,
P10: sorobanInclusionFee,
P20: sorobanInclusionFee,
P30: sorobanInclusionFee,
P40: sorobanInclusionFee,
P50: sorobanInclusionFee,
P60: sorobanInclusionFee,
P70: sorobanInclusionFee,
P80: sorobanInclusionFee,
P90: sorobanInclusionFee,
P95: sorobanInclusionFee,
P99: sorobanInclusionFee,
FeeCount: 1,
LedgerCount: result.SorobanInclusionFee.LedgerCount,
},
InclusionFee: methods.FeeDistribution{
Max: classicFee,
Min: classicFee,
Mode: classicFee,
P10: classicFee,
P20: classicFee,
P30: classicFee,
P40: classicFee,
P50: classicFee,
P60: classicFee,
P70: classicFee,
P80: classicFee,
P90: classicFee,
P95: classicFee,
P99: classicFee,
FeeCount: 1,
LedgerCount: result.InclusionFee.LedgerCount,
},
LatestLedger: result.LatestLedger,
}
assert.Equal(t, expectedResult, result)

// check ledgers separately
assert.Greater(t, result.InclusionFee.LedgerCount, uint32(0))
assert.Greater(t, result.SorobanInclusionFee.LedgerCount, uint32(0))
assert.Greater(t, result.LatestLedger, uint32(0))
}
1 change: 0 additions & 1 deletion cmd/soroban-rpc/internal/test/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ const (
stellarCorePort = 11626
stellarCoreArchiveHost = "localhost:1570"
goModFile = "go.mod"
goMonorepoGithubPath = "github.com/stellar/go"

friendbotURL = "http://localhost:8000/friendbot"
// Needed when Core is run with ARTIFICIALLY_ACCELERATE_TIME_FOR_TESTING=true
Expand Down
74 changes: 30 additions & 44 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ require (
github.com/cenkalti/backoff/v4 v4.2.1
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
github.com/pelletier/go-toml v1.9.5
github.com/prometheus/client_golang v1.17.0
Expand All @@ -19,60 +18,50 @@ require (
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
github.com/stellar/go v0.0.0-20240424155418-4fa8e69a8be4
github.com/stretchr/testify v1.8.4
golang.org/x/mod v0.13.0
github.com/stretchr/testify v1.9.0
)

require (
cloud.google.com/go v0.112.0 // indirect
cloud.google.com/go/compute v1.23.3 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.5 // indirect
cloud.google.com/go/storage v1.37.0 // indirect
dario.cat/mergo v1.0.0 // indirect
cloud.google.com/go v0.112.2 // indirect
cloud.google.com/go/auth v0.3.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
cloud.google.com/go/compute/metadata v0.3.0 // indirect
cloud.google.com/go/iam v1.1.8 // indirect
cloud.google.com/go/storage v1.40.0 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect
github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
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/cloudflare/circl v1.3.5 // indirect
github.com/creachadair/mds v0.13.4 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/djherbis/fscache v0.10.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/googleapis/gax-go/v2 v2.12.3 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmoiron/sqlx v1.3.5 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.17.6 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.5.0
Expand All @@ -82,42 +71,39 @@ require (
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/segmentio/go-loggly v0.5.1-0.20171222203950-eb91657e62b2 // indirect
github.com/sergi/go-diff v1.3.1 // indirect
github.com/skeema/knownhosts v1.2.1 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.10.0 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/viper v1.17.0 // indirect
github.com/stellar/go-xdr v0.0.0-20231122183749-b53fb00bcac2 // indirect
github.com/stretchr/objx v0.5.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
go.opentelemetry.io/otel v1.21.0 // indirect
go.opentelemetry.io/otel/metric v1.21.0 // indirect
go.opentelemetry.io/otel/trace v1.21.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/oauth2 v0.16.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/mod v0.13.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/oauth2 v0.20.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.14.0 // indirect
google.golang.org/api v0.157.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240122161410-6c6643bf1457 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect
google.golang.org/grpc v1.60.1 // indirect
google.golang.org/protobuf v1.33.0 // indirect
google.golang.org/api v0.177.0 // indirect
google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 // indirect
google.golang.org/grpc v1.63.2 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/djherbis/atime.v1 v1.0.0 // indirect
gopkg.in/djherbis/stream.v1 v1.3.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/tylerb/graceful.v1 v1.2.15 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit 57ecad1

Please sign in to comment.