From 59328520f14ab4d7f67f80736bcd5f6e883014da Mon Sep 17 00:00:00 2001 From: George Date: Fri, 25 Oct 2024 12:37:21 -0700 Subject: [PATCH] Add back in Protocol 22 non-breaking changes for a transition period (#317) * Add both versions of getVersionInfo in * Make createdAt properly non-breaking * Revert "Remove pagingToken from getEvents (#297)" This reverts commit 44db01f8c6aef623a10a83c0a27f728c918d9a04. * Ignore the latest version since it matches the one being used --- .../internal/integrationtest/migrate_test.go | 5 +++ .../internal/integrationtest/upgrade_test.go | 7 ++-- .../internal/methods/get_events.go | 6 +++- .../internal/methods/get_events_test.go | 6 ++++ .../internal/methods/get_transaction.go | 10 ++++-- .../internal/methods/get_transaction_test.go | 18 +++++----- .../internal/methods/get_transactions.go | 33 ++++++++++++------- .../internal/methods/get_transactions_test.go | 22 +++++++------ .../internal/methods/get_version_info.go | 22 ++++++++++--- 9 files changed, 87 insertions(+), 42 deletions(-) diff --git a/cmd/soroban-rpc/internal/integrationtest/migrate_test.go b/cmd/soroban-rpc/internal/integrationtest/migrate_test.go index 750b8b82..7358bc06 100644 --- a/cmd/soroban-rpc/internal/integrationtest/migrate_test.go +++ b/cmd/soroban-rpc/internal/integrationtest/migrate_test.go @@ -31,6 +31,11 @@ func TestMigrate(t *testing.T) { // This version of RPC wasn't published as a docker container continue } + if originVersion == "22.0.0-rc2" { + // This version of RPC can't be upgraded to since that's the one + // set in the soroban_rpc.yml file + continue + } t.Run(originVersion, func(t *testing.T) { testMigrateFromVersion(t, originVersion) }) diff --git a/cmd/soroban-rpc/internal/integrationtest/upgrade_test.go b/cmd/soroban-rpc/internal/integrationtest/upgrade_test.go index efd26cb2..70f9343a 100644 --- a/cmd/soroban-rpc/internal/integrationtest/upgrade_test.go +++ b/cmd/soroban-rpc/internal/integrationtest/upgrade_test.go @@ -23,10 +23,11 @@ func TestUpgradeFrom20To21(t *testing.T) { test.UploadHelloWorldContract() - // Upgrade to protocol 21 and re-upload the contract, which should cause a caching of the contract - // estimations + // Upgrade to protocol 21 and re-upload the contract, which should cause a + // caching of the contract estimations test.UpgradeProtocol(21) - // Wait for the ledger to advance, so that the simulation library passes the right protocol number + // Wait for the ledger to advance, so that the simulation library passes the + // right protocol number rpcDB := test.GetDaemon().GetDB() initialLedgerSequence, err := db.NewLedgerEntryReader(rpcDB).GetLatestLedgerSequence(context.Background()) require.NoError(t, err) diff --git a/cmd/soroban-rpc/internal/methods/get_events.go b/cmd/soroban-rpc/internal/methods/get_events.go index e63f9132..933e6d81 100644 --- a/cmd/soroban-rpc/internal/methods/get_events.go +++ b/cmd/soroban-rpc/internal/methods/get_events.go @@ -92,6 +92,8 @@ type EventInfo struct { ContractID string `json:"contractId"` ID string `json:"id"` + // Deprecated: PagingToken field is deprecated, please use Cursor at top level for pagination + PagingToken string `json:"pagingToken"` InSuccessfulContractCall bool `json:"inSuccessfulContractCall"` TransactionHash string `json:"txHash"` @@ -337,7 +339,8 @@ type PaginationOptions struct { type GetEventsResponse struct { Events []EventInfo `json:"events"` LatestLedger uint32 `json:"latestLedger"` - // Cursor represents last populated event ID if total events reach the limit or end of the search window + // Cursor represents last populated event ID if total events reach the limit + // or end of the search window Cursor string `json:"cursor"` } @@ -553,6 +556,7 @@ func eventInfoForEvent( Ledger: int32(cursor.Ledger), LedgerClosedAt: ledgerClosedAt, ID: cursor.String(), + PagingToken: cursor.String(), InSuccessfulContractCall: event.InSuccessfulContractCall, TransactionHash: txHash, } diff --git a/cmd/soroban-rpc/internal/methods/get_events_test.go b/cmd/soroban-rpc/internal/methods/get_events_test.go index 81a9c169..cd06b0e3 100644 --- a/cmd/soroban-rpc/internal/methods/get_events_test.go +++ b/cmd/soroban-rpc/internal/methods/get_events_test.go @@ -649,6 +649,7 @@ func TestGetEvents(t *testing.T) { LedgerClosedAt: now.Format(time.RFC3339), ContractID: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4", ID: id, + PagingToken: id, TopicXDR: []string{value}, ValueXDR: value, InSuccessfulContractCall: true, @@ -795,6 +796,7 @@ func TestGetEvents(t *testing.T) { LedgerClosedAt: now.Format(time.RFC3339), ContractID: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4", ID: id, + PagingToken: id, TopicXDR: []string{counterXdr, value}, ValueXDR: value, InSuccessfulContractCall: true, @@ -941,6 +943,7 @@ func TestGetEvents(t *testing.T) { LedgerClosedAt: now.Format(time.RFC3339), ContractID: strkey.MustEncode(strkey.VersionByteContract, contractID[:]), ID: id, + PagingToken: id, TopicXDR: []string{counterXdr, value}, ValueXDR: value, InSuccessfulContractCall: true, @@ -1017,6 +1020,7 @@ func TestGetEvents(t *testing.T) { LedgerClosedAt: now.Format(time.RFC3339), ContractID: strkey.MustEncode(strkey.VersionByteContract, contractID[:]), ID: id, + PagingToken: id, TopicXDR: []string{counterXdr}, ValueXDR: counterXdr, InSuccessfulContractCall: true, @@ -1089,6 +1093,7 @@ func TestGetEvents(t *testing.T) { LedgerClosedAt: now.Format(time.RFC3339), ContractID: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4", ID: id, + PagingToken: id, TopicXDR: []string{value}, ValueXDR: value, InSuccessfulContractCall: true, @@ -1190,6 +1195,7 @@ func TestGetEvents(t *testing.T) { LedgerClosedAt: now.Format(time.RFC3339), ContractID: strkey.MustEncode(strkey.VersionByteContract, contractID[:]), ID: id, + PagingToken: id, TopicXDR: []string{counterXdr}, ValueXDR: expectedXdr, InSuccessfulContractCall: true, diff --git a/cmd/soroban-rpc/internal/methods/get_transaction.go b/cmd/soroban-rpc/internal/methods/get_transaction.go index e6882b96..f08c89f6 100644 --- a/cmd/soroban-rpc/internal/methods/get_transaction.go +++ b/cmd/soroban-rpc/internal/methods/get_transaction.go @@ -38,8 +38,14 @@ type GetTransactionResponse struct { // LatestLedgerCloseTime is the unix timestamp of when the oldest ledger was closed. OldestLedgerCloseTime int64 `json:"oldestLedgerCloseTime,string"` - // Many of the fields below are only present if Status is not TransactionNotFound. - TransactionInfo + // Many of the fields below are only present if Status is not + // TransactionNotFound. + TransactionDetails + // LedgerCloseTime is the unix timestamp of when the transaction was + // included in the ledger. It isn't part of `TransactionInfo` because of a + // bug in which `createdAt` in getTransactions is encoded as a number + // whereas in getTransaction (singular) it's encoded as a string. + LedgerCloseTime int64 `json:"createdAt,string"` } type GetTransactionRequest struct { diff --git a/cmd/soroban-rpc/internal/methods/get_transaction_test.go b/cmd/soroban-rpc/internal/methods/get_transaction_test.go index 38e6d5a3..847b2e6e 100644 --- a/cmd/soroban-rpc/internal/methods/get_transaction_test.go +++ b/cmd/soroban-rpc/internal/methods/get_transaction_test.go @@ -36,7 +36,7 @@ func TestGetTransaction(t *testing.T) { tx, err := GetTransaction(ctx, log, store, ledgerReader, GetTransactionRequest{hash, ""}) require.NoError(t, err) require.Equal(t, GetTransactionResponse{ - TransactionInfo: TransactionInfo{ + TransactionDetails: TransactionDetails{ Status: TransactionStatusNotFound, }, }, tx) @@ -60,7 +60,7 @@ func TestGetTransaction(t *testing.T) { LatestLedgerCloseTime: 2625, OldestLedger: 101, OldestLedgerCloseTime: 2625, - TransactionInfo: TransactionInfo{ + TransactionDetails: TransactionDetails{ Status: TransactionStatusSuccess, ApplicationOrder: 1, FeeBump: false, @@ -68,9 +68,9 @@ func TestGetTransaction(t *testing.T) { ResultXDR: expectedTxResult, ResultMetaXDR: expectedTxMeta, Ledger: 101, - LedgerCloseTime: 2625, DiagnosticEventsXDR: []string{}, }, + LedgerCloseTime: 2625, }, tx) // ingest another (failed) transaction @@ -85,7 +85,7 @@ func TestGetTransaction(t *testing.T) { LatestLedgerCloseTime: 2650, OldestLedger: 101, OldestLedgerCloseTime: 2625, - TransactionInfo: TransactionInfo{ + TransactionDetails: TransactionDetails{ Status: TransactionStatusSuccess, ApplicationOrder: 1, FeeBump: false, @@ -93,9 +93,9 @@ func TestGetTransaction(t *testing.T) { ResultXDR: expectedTxResult, ResultMetaXDR: expectedTxMeta, Ledger: 101, - LedgerCloseTime: 2625, DiagnosticEventsXDR: []string{}, }, + LedgerCloseTime: 2625, }, tx) // the new transaction should also be there @@ -116,7 +116,7 @@ func TestGetTransaction(t *testing.T) { LatestLedgerCloseTime: 2650, OldestLedger: 101, OldestLedgerCloseTime: 2625, - TransactionInfo: TransactionInfo{ + TransactionDetails: TransactionDetails{ Status: TransactionStatusFailed, ApplicationOrder: 1, FeeBump: false, @@ -124,9 +124,9 @@ func TestGetTransaction(t *testing.T) { ResultXDR: expectedTxResult, ResultMetaXDR: expectedTxMeta, Ledger: 102, - LedgerCloseTime: 2650, DiagnosticEventsXDR: []string{}, }, + LedgerCloseTime: 2650, }, tx) // Test Txn with events @@ -151,7 +151,7 @@ func TestGetTransaction(t *testing.T) { tx, err = GetTransaction(ctx, log, store, ledgerReader, GetTransactionRequest{hash, ""}) require.NoError(t, err) require.Equal(t, GetTransactionResponse{ - TransactionInfo: TransactionInfo{ + TransactionDetails: TransactionDetails{ Status: TransactionStatusSuccess, ApplicationOrder: 1, FeeBump: false, @@ -159,9 +159,9 @@ func TestGetTransaction(t *testing.T) { ResultXDR: expectedTxResult, ResultMetaXDR: expectedTxMeta, Ledger: 103, - LedgerCloseTime: 2675, DiagnosticEventsXDR: []string{expectedEventsMeta}, }, + LedgerCloseTime: 2675, LatestLedger: 103, LatestLedgerCloseTime: 2675, OldestLedger: 101, diff --git a/cmd/soroban-rpc/internal/methods/get_transactions.go b/cmd/soroban-rpc/internal/methods/get_transactions.go index beb0affe..3d1d7efe 100644 --- a/cmd/soroban-rpc/internal/methods/get_transactions.go +++ b/cmd/soroban-rpc/internal/methods/get_transactions.go @@ -55,14 +55,15 @@ func (req GetTransactionsRequest) isValid(maxLimit uint, ledgerRange ledgerbucke return IsValidFormat(req.Format) } -type TransactionInfo struct { +type TransactionDetails struct { // Status is one of: TransactionSuccess, TransactionFailed, TransactionNotFound. Status string `json:"status"` - // TransactionHash is the hex encoded hash of the transaction. Note that for fee-bump transaction - // this will be the hash of the fee-bump transaction instead of the inner transaction hash. + // TransactionHash is the hex encoded hash of the transaction. Note that for + // fee-bump transaction this will be the hash of the fee-bump transaction + // instead of the inner transaction hash. TransactionHash string `json:"txHash"` - // ApplicationOrder is the index of the transaction among all the transactions - // for that ledger. + // ApplicationOrder is the index of the transaction among all the + // transactions for that ledger. ApplicationOrder int32 `json:"applicationOrder"` // FeeBump indicates whether the transaction is a feebump transaction FeeBump bool `json:"feeBump"` @@ -81,8 +82,14 @@ type TransactionInfo struct { DiagnosticEventsJSON []json.RawMessage `json:"diagnosticEventsJson,omitempty"` // Ledger is the sequence of the ledger which included the transaction. Ledger uint32 `json:"ledger"` - // LedgerCloseTime is the unix timestamp of when the transaction was included in the ledger. - LedgerCloseTime int64 `json:"createdAt,string"` +} + +type TransactionInfo struct { + TransactionDetails + + // LedgerCloseTime is the unix timestamp of when the transaction was + // included in the ledger. + LedgerCloseTime int64 `json:"createdAt"` } // GetTransactionsResponse encapsulates the response structure for getTransactions queries. @@ -197,11 +204,13 @@ func (h transactionsRPCHandler) processTransactionsInLedger( } txInfo := TransactionInfo{ - TransactionHash: tx.TransactionHash, - ApplicationOrder: tx.ApplicationOrder, - FeeBump: tx.FeeBump, - Ledger: tx.Ledger.Sequence, - LedgerCloseTime: tx.Ledger.CloseTime, + TransactionDetails: TransactionDetails{ + TransactionHash: tx.TransactionHash, + ApplicationOrder: tx.ApplicationOrder, + FeeBump: tx.FeeBump, + Ledger: tx.Ledger.Sequence, + }, + LedgerCloseTime: tx.Ledger.CloseTime, } switch format { diff --git a/cmd/soroban-rpc/internal/methods/get_transactions_test.go b/cmd/soroban-rpc/internal/methods/get_transactions_test.go index 24e3f429..531ed9de 100644 --- a/cmd/soroban-rpc/internal/methods/get_transactions_test.go +++ b/cmd/soroban-rpc/internal/methods/get_transactions_test.go @@ -21,16 +21,18 @@ const ( ) var expectedTransactionInfo = TransactionInfo{ - Status: "SUCCESS", - TransactionHash: "b0d0b35dcaed0152d62fbbaa28ed3fa4991c87e7e169a8fca2687b17ee26ca2d", - ApplicationOrder: 1, - FeeBump: false, - Ledger: 1, - LedgerCloseTime: 125, - EnvelopeXDR: "AAAAAgAAAQCAAAAAAAAAAD8MNL+TrQ2ZcdBMzJD3BVEcg4qtlzSkovsNegP8f+iaAAAAAQAAAAD///+dAAAAAAAAAAAAAAAAAAAAAAAAAAA=", //nolint:lll - ResultMetaXDR: "AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAA", - ResultXDR: "AAAAAAAAAGQAAAAAAAAAAAAAAAA=", - DiagnosticEventsXDR: []string{}, + TransactionDetails{ + Status: "SUCCESS", + TransactionHash: "b0d0b35dcaed0152d62fbbaa28ed3fa4991c87e7e169a8fca2687b17ee26ca2d", + ApplicationOrder: 1, + FeeBump: false, + Ledger: 1, + EnvelopeXDR: "AAAAAgAAAQCAAAAAAAAAAD8MNL+TrQ2ZcdBMzJD3BVEcg4qtlzSkovsNegP8f+iaAAAAAQAAAAD///+dAAAAAAAAAAAAAAAAAAAAAAAAAAA=", //nolint:lll + ResultMetaXDR: "AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAA", + ResultXDR: "AAAAAAAAAGQAAAAAAAAAAAAAAAA=", + DiagnosticEventsXDR: []string{}, + }, + 125, } // createTestLedger Creates a test ledger with 2 transactions diff --git a/cmd/soroban-rpc/internal/methods/get_version_info.go b/cmd/soroban-rpc/internal/methods/get_version_info.go index 038bf54a..cb73cb35 100644 --- a/cmd/soroban-rpc/internal/methods/get_version_info.go +++ b/cmd/soroban-rpc/internal/methods/get_version_info.go @@ -19,6 +19,14 @@ type GetVersionInfoResponse struct { BuildTimestamp string `json:"buildTimestamp"` CaptiveCoreVersion string `json:"captiveCoreVersion"` ProtocolVersion uint32 `json:"protocolVersion"` + //nolint:tagliatelle + CommitHashDeprecated string `json:"commit_hash"` + //nolint:tagliatelle + BuildTimestampDeprecated string `json:"build_timestamp"` + //nolint:tagliatelle + CaptiveCoreVersionDeprecated string `json:"captive_core_version"` + //nolint:tagliatelle + ProtocolVersionDeprecated uint32 `json:"protocol_version"` } func NewGetVersionInfoHandler( @@ -37,11 +45,15 @@ func NewGetVersionInfoHandler( } return GetVersionInfoResponse{ - Version: config.Version, - CommitHash: config.CommitHash, - BuildTimestamp: config.BuildTimestamp, - CaptiveCoreVersion: captiveCoreVersion, - ProtocolVersion: protocolVersion, + Version: config.Version, + CommitHash: config.CommitHash, + CommitHashDeprecated: config.CommitHash, + BuildTimestamp: config.BuildTimestamp, + BuildTimestampDeprecated: config.BuildTimestamp, + CaptiveCoreVersion: captiveCoreVersion, + CaptiveCoreVersionDeprecated: captiveCoreVersion, + ProtocolVersion: protocolVersion, + ProtocolVersionDeprecated: protocolVersion, }, nil }) }