diff --git a/cmd/soroban-rpc/internal/config/config.go b/cmd/soroban-rpc/internal/config/config.go index 1f89ab2b..15e69f6b 100644 --- a/cmd/soroban-rpc/internal/config/config.go +++ b/cmd/soroban-rpc/internal/config/config.go @@ -28,6 +28,7 @@ type Config struct { EventLedgerRetentionWindow uint32 FriendbotURL string HistoryArchiveURLs []string + HistoryArchiveUserAgent string IngestionTimeout time.Duration LogFormat LogFormat LogLevel logrus.Level @@ -64,6 +65,13 @@ type Config struct { flagset *pflag.FlagSet } +func (cfg *Config) ExtendedUserAgent(extension string) string { + if cfg.HistoryArchiveUserAgent == "" { + return extension + } + return cfg.HistoryArchiveUserAgent + "/" + extension +} + func (cfg *Config) SetValues(lookupEnv func(string) (string, bool)) error { // We start with the defaults if err := cfg.loadDefaults(); err != nil { diff --git a/cmd/soroban-rpc/internal/config/config_test.go b/cmd/soroban-rpc/internal/config/config_test.go index 67769a3c..df006b7e 100644 --- a/cmd/soroban-rpc/internal/config/config_test.go +++ b/cmd/soroban-rpc/internal/config/config_test.go @@ -51,6 +51,14 @@ func TestConfigLoadDefaults(t *testing.T) { assert.Equal(t, uint(runtime.NumCPU()), cfg.PreflightWorkerCount) } +func TestConfigExtendedUserAgent(t *testing.T) { + cfg := Config{ + HistoryArchiveUserAgent: "Test", + } + require.NoError(t, cfg.loadDefaults()) + assert.Equal(t, "Test/123", cfg.ExtendedUserAgent("123")) +} + func TestConfigLoadFlagsDefaultValuesOverrideExisting(t *testing.T) { // Set up a config with an existing non-default value cfg := Config{ diff --git a/cmd/soroban-rpc/internal/config/options_test.go b/cmd/soroban-rpc/internal/config/options_test.go index 958306ab..00b1654f 100644 --- a/cmd/soroban-rpc/internal/config/options_test.go +++ b/cmd/soroban-rpc/internal/config/options_test.go @@ -26,7 +26,7 @@ func TestAllConfigFieldsMustHaveASingleOption(t *testing.T) { // Allow us to explicitly exclude any fields on the Config struct, which are not going to have Options. // e.g. "ConfigPath" - excluded := map[string]bool{} + excluded := map[string]bool{"HistoryArchiveUserAgent": true} cfg := Config{} cfgValue := reflect.ValueOf(cfg) diff --git a/cmd/soroban-rpc/internal/daemon/daemon.go b/cmd/soroban-rpc/internal/daemon/daemon.go index d2ee9c3a..7658b096 100644 --- a/cmd/soroban-rpc/internal/daemon/daemon.go +++ b/cmd/soroban-rpc/internal/daemon/daemon.go @@ -19,6 +19,7 @@ import ( "github.com/stellar/go/ingest/ledgerbackend" supporthttp "github.com/stellar/go/support/http" supportlog "github.com/stellar/go/support/log" + "github.com/stellar/go/support/storage" "github.com/stellar/go/xdr" "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal" @@ -121,7 +122,7 @@ func newCaptiveCore(cfg *config.Config, logger *supportlog.Entry) (*ledgerbacken CheckpointFrequency: cfg.CheckpointFrequency, Log: logger.WithField("subservice", "stellar-core"), Toml: captiveCoreToml, - UserAgent: "captivecore", + UserAgent: cfg.ExtendedUserAgent("captivecore"), UseDB: true, } return ledgerbackend.NewCaptive(captiveConfig) @@ -144,12 +145,18 @@ func MustNew(cfg *config.Config) *Daemon { if len(cfg.HistoryArchiveURLs) == 0 { logger.Fatal("no history archives url were provided") } - historyArchive, err := historyarchive.Connect( - cfg.HistoryArchiveURLs[0], + + historyArchive, err := historyarchive.NewArchivePool( + cfg.HistoryArchiveURLs, historyarchive.ArchiveOptions{ + NetworkPassphrase: cfg.NetworkPassphrase, CheckpointFrequency: cfg.CheckpointFrequency, + ConnectOptions: storage.ConnectOptions{ + Context: context.Background(), + UserAgent: cfg.HistoryArchiveUserAgent}, }, ) + if err != nil { logger.WithError(err).Fatal("could not connect to history archive") } diff --git a/cmd/soroban-rpc/internal/events/events.go b/cmd/soroban-rpc/internal/events/events.go index e854cd77..d4352983 100644 --- a/cmd/soroban-rpc/internal/events/events.go +++ b/cmd/soroban-rpc/internal/events/events.go @@ -19,7 +19,7 @@ type event struct { diagnosticEventXDR []byte txIndex uint32 eventIndex uint32 - txHash *xdr.Hash // intentionally stored as a pointer to save memory (amortized as soon as there are two events in a transaction) + txHash *xdr.Hash // intentionally stored as a pointer to save memory (amortized as soon as there are two events in a transaction) } func (e event) cursor(ledgerSeq uint32) Cursor { diff --git a/cmd/soroban-rpc/internal/ingest/ledgerentry.go b/cmd/soroban-rpc/internal/ingest/ledgerentry.go index 0b8fc48f..1e16efe3 100644 --- a/cmd/soroban-rpc/internal/ingest/ledgerentry.go +++ b/cmd/soroban-rpc/internal/ingest/ledgerentry.go @@ -38,10 +38,10 @@ func (s *Service) ingestLedgerEntryChanges(ctx context.Context, reader ingest.Ch results := changeStatsProcessor.GetResults() for stat, value := range results.Map() { stat = strings.Replace(stat, "stats_", "change_", 1) - s.ledgerStatsMetric. + s.metrics.ledgerStatsMetric. With(prometheus.Labels{"type": stat}).Add(float64(value.(int64))) } - s.ingestionDurationMetric. + s.metrics.ingestionDurationMetric. With(prometheus.Labels{"type": "ledger_entries"}).Observe(time.Since(startTime).Seconds()) return ctx.Err() } @@ -66,10 +66,10 @@ func (s *Service) ingestTempLedgerEntryEvictions( } for evictionType, count := range counts { - s.ledgerStatsMetric. + s.metrics.ledgerStatsMetric. With(prometheus.Labels{"type": evictionType}).Add(float64(count)) } - s.ingestionDurationMetric. + s.metrics.ingestionDurationMetric. With(prometheus.Labels{"type": "evicted_temp_ledger_entries"}).Observe(time.Since(startTime).Seconds()) return ctx.Err() } diff --git a/cmd/soroban-rpc/internal/ingest/service.go b/cmd/soroban-rpc/internal/ingest/service.go index 6240f7cb..2cc082cb 100644 --- a/cmd/soroban-rpc/internal/ingest/service.go +++ b/cmd/soroban-rpc/internal/ingest/service.go @@ -73,19 +73,24 @@ func newService(cfg Config) *Service { []string{"type"}, ) - cfg.Daemon.MetricsRegistry().MustRegister(ingestionDurationMetric, latestLedgerMetric, ledgerStatsMetric) + cfg.Daemon.MetricsRegistry().MustRegister( + ingestionDurationMetric, + latestLedgerMetric, + ledgerStatsMetric) service := &Service{ - logger: cfg.Logger, - db: cfg.DB, - eventStore: cfg.EventStore, - transactionStore: cfg.TransactionStore, - ledgerBackend: cfg.LedgerBackend, - networkPassPhrase: cfg.NetworkPassPhrase, - timeout: cfg.Timeout, - ingestionDurationMetric: ingestionDurationMetric, - latestLedgerMetric: latestLedgerMetric, - ledgerStatsMetric: ledgerStatsMetric, + logger: cfg.Logger, + db: cfg.DB, + eventStore: cfg.EventStore, + transactionStore: cfg.TransactionStore, + ledgerBackend: cfg.LedgerBackend, + networkPassPhrase: cfg.NetworkPassPhrase, + timeout: cfg.Timeout, + metrics: Metrics{ + ingestionDurationMetric: ingestionDurationMetric, + latestLedgerMetric: latestLedgerMetric, + ledgerStatsMetric: ledgerStatsMetric, + }, } return service @@ -119,21 +124,25 @@ func startService(service *Service, cfg Config) { }) } -type Service struct { - logger *log.Entry - db db.ReadWriter - eventStore *events.MemoryStore - transactionStore *transactions.MemoryStore - ledgerBackend backends.LedgerBackend - timeout time.Duration - networkPassPhrase string - done context.CancelFunc - wg sync.WaitGroup +type Metrics struct { ingestionDurationMetric *prometheus.SummaryVec latestLedgerMetric prometheus.Gauge ledgerStatsMetric *prometheus.CounterVec } +type Service struct { + logger *log.Entry + db db.ReadWriter + eventStore *events.MemoryStore + transactionStore *transactions.MemoryStore + ledgerBackend backends.LedgerBackend + timeout time.Duration + networkPassPhrase string + done context.CancelFunc + wg sync.WaitGroup + metrics Metrics +} + func (s *Service) Close() error { s.done() s.wg.Wait() @@ -286,9 +295,9 @@ func (s *Service) ingest(ctx context.Context, sequence uint32) error { } s.logger.Debugf("Ingested ledger %d", sequence) - s.ingestionDurationMetric. + s.metrics.ingestionDurationMetric. With(prometheus.Labels{"type": "total"}).Observe(time.Since(startTime).Seconds()) - s.latestLedgerMetric.Set(float64(sequence)) + s.metrics.latestLedgerMetric.Set(float64(sequence)) return nil } @@ -297,7 +306,7 @@ func (s *Service) ingestLedgerCloseMeta(tx db.WriteTx, ledgerCloseMeta xdr.Ledge if err := tx.LedgerWriter().InsertLedger(ledgerCloseMeta); err != nil { return err } - s.ingestionDurationMetric. + s.metrics.ingestionDurationMetric. With(prometheus.Labels{"type": "ledger_close_meta"}).Observe(time.Since(startTime).Seconds()) if err := s.eventStore.IngestEvents(ledgerCloseMeta); err != nil { diff --git a/cmd/soroban-rpc/internal/ingest/service_test.go b/cmd/soroban-rpc/internal/ingest/service_test.go index c2e4def0..a517562d 100644 --- a/cmd/soroban-rpc/internal/ingest/service_test.go +++ b/cmd/soroban-rpc/internal/ingest/service_test.go @@ -65,6 +65,7 @@ func TestRetryRunningIngestion(t *testing.T) { func TestIngestion(t *testing.T) { mockDB := &MockDB{} mockLedgerBackend := &ledgerbackend.MockDatabaseBackend{} + daemon := interfaces.MakeNoOpDeamon() config := Config{ Logger: supportlog.New(), diff --git a/cmd/soroban-rpc/internal/test/archive_test.go b/cmd/soroban-rpc/internal/test/archive_test.go new file mode 100644 index 00000000..127e6e61 --- /dev/null +++ b/cmd/soroban-rpc/internal/test/archive_test.go @@ -0,0 +1,25 @@ +package test + +import ( + "net/http" + "sync" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestArchiveUserAgent(t *testing.T) { + userAgents := sync.Map{} + cfg := &TestConfig{ + historyArchiveProxyCallback: func(r *http.Request) { + userAgents.Store(r.Header["User-Agent"][0], "") + }, + } + NewTest(t, cfg) + + _, ok := userAgents.Load("testing") + assert.True(t, ok, "rpc service should set user agent for history archives") + + _, ok = userAgents.Load("testing/captivecore") + assert.True(t, ok, "rpc captive core should set user agent for history archives") +} diff --git a/cmd/soroban-rpc/internal/test/cli_test.go b/cmd/soroban-rpc/internal/test/cli_test.go index db138c86..d1a5b901 100644 --- a/cmd/soroban-rpc/internal/test/cli_test.go +++ b/cmd/soroban-rpc/internal/test/cli_test.go @@ -296,7 +296,7 @@ func getCLIDefaultAccount(t *testing.T) string { } func NewCLITest(t *testing.T) *Test { - test := NewTest(t) + test := NewTest(t, nil) fundAccount(t, test, getCLIDefaultAccount(t), "1000000") return test } diff --git a/cmd/soroban-rpc/internal/test/cors_test.go b/cmd/soroban-rpc/internal/test/cors_test.go index 2e0cdb3e..ede91fd8 100644 --- a/cmd/soroban-rpc/internal/test/cors_test.go +++ b/cmd/soroban-rpc/internal/test/cors_test.go @@ -13,7 +13,7 @@ import ( // Specifically, when we include an Origin header in the request, a soroban-rpc should response // with a corresponding Access-Control-Allow-Origin. func TestCORS(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) request, err := http.NewRequest("POST", test.sorobanRPCURL(), bytes.NewBufferString("{\"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"getHealth\"}")) require.NoError(t, err) diff --git a/cmd/soroban-rpc/internal/test/get_ledger_entries_test.go b/cmd/soroban-rpc/internal/test/get_ledger_entries_test.go index 46b0b25d..889b4e04 100644 --- a/cmd/soroban-rpc/internal/test/get_ledger_entries_test.go +++ b/cmd/soroban-rpc/internal/test/get_ledger_entries_test.go @@ -18,7 +18,7 @@ import ( ) func TestGetLedgerEntriesNotFound(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -56,7 +56,7 @@ func TestGetLedgerEntriesNotFound(t *testing.T) { } func TestGetLedgerEntriesInvalidParams(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -74,7 +74,7 @@ func TestGetLedgerEntriesInvalidParams(t *testing.T) { } func TestGetLedgerEntriesSucceeds(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) diff --git a/cmd/soroban-rpc/internal/test/get_ledger_entry_test.go b/cmd/soroban-rpc/internal/test/get_ledger_entry_test.go index dd4879d5..b453f4d8 100644 --- a/cmd/soroban-rpc/internal/test/get_ledger_entry_test.go +++ b/cmd/soroban-rpc/internal/test/get_ledger_entry_test.go @@ -18,7 +18,7 @@ import ( ) func TestGetLedgerEntryNotFound(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -51,7 +51,7 @@ func TestGetLedgerEntryNotFound(t *testing.T) { } func TestGetLedgerEntryInvalidParams(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -67,7 +67,7 @@ func TestGetLedgerEntryInvalidParams(t *testing.T) { } func TestGetLedgerEntrySucceeds(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) diff --git a/cmd/soroban-rpc/internal/test/get_network_test.go b/cmd/soroban-rpc/internal/test/get_network_test.go index 39805d86..9c8ef266 100644 --- a/cmd/soroban-rpc/internal/test/get_network_test.go +++ b/cmd/soroban-rpc/internal/test/get_network_test.go @@ -12,7 +12,7 @@ import ( ) func TestGetNetworkSucceeds(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) diff --git a/cmd/soroban-rpc/internal/test/health_test.go b/cmd/soroban-rpc/internal/test/health_test.go index 4afbf7f8..517b374d 100644 --- a/cmd/soroban-rpc/internal/test/health_test.go +++ b/cmd/soroban-rpc/internal/test/health_test.go @@ -11,7 +11,7 @@ import ( ) func TestHealth(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) diff --git a/cmd/soroban-rpc/internal/test/integration.go b/cmd/soroban-rpc/internal/test/integration.go index ea918d13..d3755a9c 100644 --- a/cmd/soroban-rpc/internal/test/integration.go +++ b/cmd/soroban-rpc/internal/test/integration.go @@ -3,6 +3,10 @@ package test import ( "context" "fmt" + "net/http" + "net/http/httptest" + "net/http/httputil" + "net/url" "os" "os/exec" "os/signal" @@ -30,9 +34,11 @@ const ( StandaloneNetworkPassphrase = "Standalone Network ; February 2017" stellarCoreProtocolVersion = 20 stellarCorePort = 11626 + stellarCoreArchiveHost = "localhost:1570" goModFile = "go.mod" goMonorepoGithubPath = "github.com/stellar/go" - friendbotURL = "http://localhost:8000/friendbot" + + friendbotURL = "http://localhost:8000/friendbot" // Needed when Core is run with ARTIFICIALLY_ACCELERATE_TIME_FOR_TESTING=true checkpointFrequency = 8 sorobanRPCPort = 8000 @@ -40,6 +46,10 @@ const ( helloWorldContractPath = "../../../../target/wasm32-unknown-unknown/test-wasms/test_hello_world.wasm" ) +type TestConfig struct { + historyArchiveProxyCallback func(*http.Request) +} + type Test struct { t *testing.T @@ -47,6 +57,9 @@ type Test struct { daemon *daemon.Daemon + historyArchiveProxy *httptest.Server + historyArchiveProxyCallback func(*http.Request) + coreClient *stellarcore.Client masterAccount txnbuild.Account @@ -54,7 +67,7 @@ type Test struct { shutdownCalls []func() } -func NewTest(t *testing.T) *Test { +func NewTest(t *testing.T, cfg *TestConfig) *Test { if os.Getenv("SOROBAN_RPC_INTEGRATION_TESTS_ENABLED") == "" { t.Skip("skipping integration test: SOROBAN_RPC_INTEGRATION_TESTS_ENABLED not set") } @@ -71,6 +84,19 @@ func NewTest(t *testing.T) *Test { AccountID: i.MasterKey().Address(), Sequence: 0, } + if cfg != nil { + i.historyArchiveProxyCallback = cfg.historyArchiveProxyCallback + } + + proxy := httputil.NewSingleHostReverseProxy(&url.URL{Scheme: "http", Host: stellarCoreArchiveHost}) + + i.historyArchiveProxy = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if i.historyArchiveProxyCallback != nil { + i.historyArchiveProxyCallback(r) + } + proxy.ServeHTTP(w, r) + })) + i.runComposeCommand("up", "--detach", "--quiet-pull", "--no-color") i.prepareShutdownHandlers() i.coreClient = &stellarcore.Client{URL: "http://localhost:" + strconv.Itoa(stellarCorePort)} @@ -138,7 +164,7 @@ func (i *Test) launchDaemon(coreBinaryPath string) { config.CaptiveCoreHTTPPort = 0 config.FriendbotURL = friendbotURL config.NetworkPassphrase = StandaloneNetworkPassphrase - config.HistoryArchiveURLs = []string{"http://localhost:1570"} + config.HistoryArchiveURLs = []string{i.historyArchiveProxy.URL} config.LogLevel = logrus.DebugLevel config.SQLiteDBPath = path.Join(i.t.TempDir(), "soroban_rpc.sqlite") config.IngestionTimeout = 10 * time.Minute @@ -146,6 +172,7 @@ func (i *Test) launchDaemon(coreBinaryPath string) { config.CheckpointFrequency = checkpointFrequency config.MaxHealthyLedgerLatency = time.Second * 10 config.PreflightEnableDebug = true + config.HistoryArchiveUserAgent = "testing" i.daemon = daemon.MustNew(&config) go i.daemon.Run() @@ -203,6 +230,9 @@ func (i *Test) prepareShutdownHandlers() { if i.daemon != nil { i.daemon.Close() } + if i.historyArchiveProxy != nil { + i.historyArchiveProxy.Close() + } i.runComposeCommand("down", "-v") }, ) diff --git a/cmd/soroban-rpc/internal/test/metrics_test.go b/cmd/soroban-rpc/internal/test/metrics_test.go index 5608a2f9..b807cb77 100644 --- a/cmd/soroban-rpc/internal/test/metrics_test.go +++ b/cmd/soroban-rpc/internal/test/metrics_test.go @@ -14,7 +14,7 @@ import ( ) func TestMetrics(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) metrics := getMetrics(test) buildMetric := fmt.Sprintf( "soroban_rpc_build_info{branch=\"%s\",build_timestamp=\"%s\",commit=\"%s\",goversion=\"%s\",version=\"%s\"} 1", diff --git a/cmd/soroban-rpc/internal/test/simulate_transaction_test.go b/cmd/soroban-rpc/internal/test/simulate_transaction_test.go index ec785050..12387530 100644 --- a/cmd/soroban-rpc/internal/test/simulate_transaction_test.go +++ b/cmd/soroban-rpc/internal/test/simulate_transaction_test.go @@ -189,7 +189,7 @@ func preflightTransactionParams(t *testing.T, client *jrpc2.Client, params txnbu } func TestSimulateTransactionSucceeds(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -307,7 +307,7 @@ func TestSimulateTransactionSucceeds(t *testing.T) { } func TestSimulateTransactionWithAuth(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -365,7 +365,7 @@ func TestSimulateTransactionWithAuth(t *testing.T) { } func TestSimulateInvokeContractTransactionSucceeds(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -550,7 +550,7 @@ func TestSimulateInvokeContractTransactionSucceeds(t *testing.T) { } func TestSimulateTransactionError(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -590,7 +590,7 @@ func TestSimulateTransactionError(t *testing.T) { } func TestSimulateTransactionMultipleOperations(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -625,7 +625,7 @@ func TestSimulateTransactionMultipleOperations(t *testing.T) { } func TestSimulateTransactionWithoutInvokeHostFunction(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -656,7 +656,7 @@ func TestSimulateTransactionWithoutInvokeHostFunction(t *testing.T) { } func TestSimulateTransactionUnmarshalError(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -673,7 +673,7 @@ func TestSimulateTransactionUnmarshalError(t *testing.T) { } func TestSimulateTransactionExtendAndRestoreFootprint(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -906,7 +906,7 @@ func waitUntilLedgerEntryTTL(t *testing.T, client *jrpc2.Client, ledgerKey xdr.L } func TestSimulateInvokePrng_u64_in_range(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -1017,7 +1017,7 @@ func TestSimulateInvokePrng_u64_in_range(t *testing.T) { } func TestSimulateSystemEvent(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -1125,7 +1125,7 @@ func TestSimulateSystemEvent(t *testing.T) { err = xdr.SafeUnmarshalBase64(response.TransactionData, &transactionData) require.NoError(t, err) assert.InDelta(t, 6856, uint32(transactionData.Resources.ReadBytes), 200) - + // the resulting fee is derived from compute factors and a default padding is applied to instructions by preflight // for test purposes, the most deterministic way to assert the resulting fee is expected value in test scope, is to capture // the resulting fee from current preflight output and re-plug it in here, rather than try to re-implement the cost-model algo diff --git a/cmd/soroban-rpc/internal/test/transaction_test.go b/cmd/soroban-rpc/internal/test/transaction_test.go index 1cd0d198..9027bc58 100644 --- a/cmd/soroban-rpc/internal/test/transaction_test.go +++ b/cmd/soroban-rpc/internal/test/transaction_test.go @@ -21,7 +21,7 @@ import ( ) func TestSendTransactionSucceedsWithoutResults(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -46,7 +46,7 @@ func TestSendTransactionSucceedsWithoutResults(t *testing.T) { } func TestSendTransactionSucceedsWithResults(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -110,7 +110,7 @@ func TestSendTransactionSucceedsWithResults(t *testing.T) { } func TestSendTransactionBadSequence(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -152,7 +152,7 @@ func TestSendTransactionBadSequence(t *testing.T) { } func TestSendTransactionFailedInsufficientResourceFee(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -204,7 +204,7 @@ func TestSendTransactionFailedInsufficientResourceFee(t *testing.T) { } func TestSendTransactionFailedInLedger(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) @@ -266,7 +266,7 @@ func TestSendTransactionFailedInLedger(t *testing.T) { } func TestSendTransactionFailedInvalidXDR(t *testing.T) { - test := NewTest(t) + test := NewTest(t, nil) ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) client := jrpc2.NewClient(ch, nil) diff --git a/cmd/soroban-rpc/main.go b/cmd/soroban-rpc/main.go index 130ea78d..e7e8713b 100644 --- a/cmd/soroban-rpc/main.go +++ b/cmd/soroban-rpc/main.go @@ -26,6 +26,7 @@ func main() { fmt.Fprintln(os.Stderr, err) os.Exit(1) } + cfg.HistoryArchiveUserAgent = fmt.Sprintf("soroban-rpc/%s", config.Version) daemon.MustNew(&cfg).Run() }, }