Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f53fb36
update getTransactionByHash to use views
cjonas9 Aug 27, 2026
d118470
add GetLedgerView to leaderReaderTx interface + implement
cjonas9 Aug 27, 2026
ead9b30
update mocks
cjonas9 Aug 27, 2026
ddc1970
update getTransactions handler
cjonas9 Aug 27, 2026
7c0d6b8
update mocks
cjonas9 Aug 27, 2026
eb2380d
update tests w/ new golden strings
cjonas9 Aug 27, 2026
e69a1e7
port finalizations, reduce comment verbosity
cjonas9 Aug 27, 2026
9bbacce
restore sparseLedgerReader Tx-level GetLedgerView
cjonas9 Aug 31, 2026
0e5bce8
store: a raw, loan-shaped ledger accessor on the serving read Tx
tamirms Aug 31, 2026
cdbf2e7
store: promote the view-to-Transaction reshape out of the v2 adapter
tamirms Aug 31, 2026
84566e7
methods: walk getTransactions' page over raw ledger bytes, not a deco…
tamirms Aug 31, 2026
de73010
drop Tx-level GetLedgerView, restore the divergence-pinning fixtures
cjonas9 Aug 31, 2026
e8a3581
rename to withLedgerRawFromDB, specify loan in comment
cjonas9 Sep 1, 2026
c4f606b
bump SDK past the view-arity fix, delete the interim repair
cjonas9 Sep 1, 2026
7490db0
bump SDK + remove InSuccessfulContractCall from getEventsV1 protocol …
cjonas9 Sep 1, 2026
12a916c
update tests w/ new golden strings
cjonas9 Aug 27, 2026
7eae4d9
restore sparseLedgerReader Tx-level GetLedgerView
cjonas9 Aug 31, 2026
20b8882
store: a raw, loan-shaped ledger accessor on the serving read Tx
tamirms Aug 31, 2026
c7b0991
drop Tx-level GetLedgerView, restore the divergence-pinning fixtures
cjonas9 Aug 31, 2026
7c8493a
undo needless whitespace changes
cjonas9 Sep 4, 2026
c81f9d7
bump sdk to version with SHA d8c8acf
cjonas9 Sep 4, 2026
0736b1a
move getTransactions differential suite to its own PR
cjonas9 Sep 4, 2026
7fe1731
remove stale reference to differential test suite
cjonas9 Sep 4, 2026
0202a08
Merge branch feature/full-history into getTxByHash-views
cjonas9 Sep 8, 2026
c88a6ee
add test pinning legacy v0 meta behavior change
cjonas9 Sep 8, 2026
6da5576
update unused mock field
cjonas9 Sep 8, 2026
97c3919
update cursor behavior described in LedgerReaderTx comment
cjonas9 Sep 8, 2026
3799131
fix err when txnViewRange == 0
cjonas9 Sep 11, 2026
a77a2ed
use transactionInfo in GetTransaction
cjonas9 Sep 11, 2026
834af4d
add changelog notes
cjonas9 Sep 11, 2026
14814e4
set cursor before early return with TransactionOrder at 0
cjonas9 Sep 11, 2026
78f0fb5
fix transaction.go stale comment
cjonas9 Sep 11, 2026
47bcd19
remove double-blank line in CHANGELOG
cjonas9 Sep 11, 2026
a32fcd1
fix incorrect comment about ledgers being loaned
cjonas9 Sep 11, 2026
735e19b
remove GetLedger from Tx interface
cjonas9 Sep 11, 2026
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: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
### Changed
* `getTransactions` now scans at most 10,000 ledgers per request. On a sparse range a page can come back short — or even empty — while still carrying a `cursor`, so a response shorter than `limit` no longer implies end-of-data. Every response carries a `cursor`; to tell a sparse scan window from the tip, compare the cursor's ledger part against `latestLedger` and keep paging while it is below ([#908](https://github.com/stellar/stellar-rpc/pull/908)).
* `getEvents` now rejects malformed contract IDs in filters with `-32602`: a `C…` string with a valid checksum but wrong-length payload used to decode and silently match nothing, and now errors under the SDK's stricter SEP-23 strkey parsing ([#908](https://github.com/stellar/stellar-rpc/pull/908)).
* `getTransactions` now returns `-32603` (internal error) instead of `-32602` (invalid params) when the node cannot parse a transaction out of its own stored ledger meta in both rpcv1 and rpcv2. Because the request parameters are valid in that case, the previous error was misleading ([#962](https://github.com/stellar/stellar-rpc/pull/962)).
* `getTransaction` and `getTransactions` now serve transactions with legacy `TransactionMeta` V0. This changes wire behavior for BOTH rpcv1 and rpcv2 (though in practice only a full-history node retains ledgers old enough to carry V0 meta). Such a transaction used to fail the request with `-32603` ("unsupported TransactionMeta version: 0"), and in `getTransactions` one V0 transaction failed the whole page. They are now returned like any other pre-Soroban transaction, with no events ([#962](https://github.com/stellar/stellar-rpc/pull/962)).

## [v28.0.1](https://github.com/stellar/stellar-rpc/compare/v28.0.0...v28.0.1)

Expand Down
140 changes: 70 additions & 70 deletions cmd/stellar-rpc/internal/methods/get_events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,16 +146,16 @@ func TestGetEvents(t *testing.T) {
})
require.NoError(t, err)
expected = append(expected, protocol.EventInfo{
EventType: protocol.EventTypeContract,
Ledger: 1,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4",
ID: id,
TopicXDR: []string{value},
ValueXDR: value,
TransactionHash: ledgerCloseMeta.TransactionHash(i).HexString(),
OpIndex: 0,
TxIndex: uint32(i + 1),
EventType: protocol.EventTypeContract,
Ledger: 1,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4",
ID: id,
TopicXDR: []string{value},
ValueXDR: value,
TransactionHash: ledgerCloseMeta.TransactionHash(i).HexString(),
OpIndex: 0,
TxIndex: uint32(i + 1),
})
}
cursor := protocol.MaxCursor
Expand Down Expand Up @@ -305,16 +305,16 @@ func TestGetEvents(t *testing.T) {
require.NoError(t, err)
expected := []protocol.EventInfo{
{
EventType: protocol.EventTypeContract,
Ledger: 1,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4",
ID: id,
TopicXDR: []string{counterXdr, value},
ValueXDR: value,
TransactionHash: ledgerCloseMeta.TransactionHash(4).HexString(),
TxIndex: 5,
OpIndex: 0,
EventType: protocol.EventTypeContract,
Ledger: 1,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4",
ID: id,
TopicXDR: []string{counterXdr, value},
ValueXDR: value,
TransactionHash: ledgerCloseMeta.TransactionHash(4).HexString(),
TxIndex: 5,
OpIndex: 0,
},
}

Expand Down Expand Up @@ -496,16 +496,16 @@ func TestGetEvents(t *testing.T) {
// flexible topic length matching
expected := []protocol.EventInfo{
{
EventType: protocol.EventTypeContract,
Ledger: 1,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4",
ID: id,
TopicXDR: []string{counterXdr, value, value, counterXdr},
ValueXDR: value,
TransactionHash: ledgerCloseMeta.TransactionHash(4).HexString(),
TxIndex: 5,
OpIndex: 0,
EventType: protocol.EventTypeContract,
Ledger: 1,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4",
ID: id,
TopicXDR: []string{counterXdr, value, value, counterXdr},
ValueXDR: value,
TransactionHash: ledgerCloseMeta.TransactionHash(4).HexString(),
TxIndex: 5,
OpIndex: 0,
},
}
require.NoError(t, err)
Expand Down Expand Up @@ -670,16 +670,16 @@ func TestGetEvents(t *testing.T) {
require.NoError(t, err)
expected := []protocol.EventInfo{
{
EventType: protocol.EventTypeContract,
Ledger: 1,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: strkey.MustEncode(strkey.VersionByteContract, contractID[:]),
ID: id,
TopicXDR: []string{counterXdr, value},
ValueXDR: value,
TransactionHash: ledgerCloseMeta.TransactionHash(3).HexString(),
TxIndex: 4,
OpIndex: 0,
EventType: protocol.EventTypeContract,
Ledger: 1,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: strkey.MustEncode(strkey.VersionByteContract, contractID[:]),
ID: id,
TopicXDR: []string{counterXdr, value},
ValueXDR: value,
TransactionHash: ledgerCloseMeta.TransactionHash(3).HexString(),
TxIndex: 4,
OpIndex: 0,
},
}
cursor := protocol.MaxCursor
Expand Down Expand Up @@ -758,16 +758,16 @@ func TestGetEvents(t *testing.T) {
id := protocol.Cursor{Ledger: 1, Tx: 1, Op: 0, Event: 1}.String()
expected := []protocol.EventInfo{
{
EventType: protocol.EventTypeSystem,
Ledger: 1,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: strkey.MustEncode(strkey.VersionByteContract, contractID[:]),
ID: id,
TopicXDR: []string{counterXdr},
ValueXDR: counterXdr,
TransactionHash: ledgerCloseMeta.TransactionHash(0).HexString(),
TxIndex: 1,
OpIndex: 0,
EventType: protocol.EventTypeSystem,
Ledger: 1,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: strkey.MustEncode(strkey.VersionByteContract, contractID[:]),
ID: id,
TopicXDR: []string{counterXdr},
ValueXDR: counterXdr,
TransactionHash: ledgerCloseMeta.TransactionHash(0).HexString(),
TxIndex: 1,
OpIndex: 0,
},
}
cursor := protocol.MaxCursor
Expand Down Expand Up @@ -842,16 +842,16 @@ func TestGetEvents(t *testing.T) {
value, err := xdr.MarshalBase64(txMeta[i].MustV3().SorobanMeta.Events[0].Body.MustV0().Data)
require.NoError(t, err)
expected = append(expected, protocol.EventInfo{
EventType: protocol.EventTypeContract,
Ledger: 1,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4",
ID: id,
TopicXDR: []string{value},
ValueXDR: value,
TransactionHash: ledgerCloseMeta.TransactionHash(i).HexString(),
TxIndex: uint32(i + 1),
OpIndex: 0,
EventType: protocol.EventTypeContract,
Ledger: 1,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4",
ID: id,
TopicXDR: []string{value},
ValueXDR: value,
TransactionHash: ledgerCloseMeta.TransactionHash(i).HexString(),
TxIndex: uint32(i + 1),
OpIndex: 0,
})
}
cursor := expected[len(expected)-1].ID
Expand Down Expand Up @@ -954,16 +954,16 @@ func TestGetEvents(t *testing.T) {
expectedXdr, err := xdr.MarshalBase64(xdr.ScVal{Type: xdr.ScValTypeScvSymbol, Sym: &symbols[i]})
require.NoError(t, err)
expected = append(expected, protocol.EventInfo{
EventType: protocol.EventTypeContract,
Ledger: 5,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: strkey.MustEncode(strkey.VersionByteContract, contractID[:]),
ID: id,
TopicXDR: []string{counterXdr},
ValueXDR: expectedXdr,
TransactionHash: ledgerCloseMeta.TransactionHash(i).HexString(),
TxIndex: uint32(i + 1),
OpIndex: 0,
EventType: protocol.EventTypeContract,
Ledger: 5,
LedgerClosedAt: now.Format(time.RFC3339),
ContractID: strkey.MustEncode(strkey.VersionByteContract, contractID[:]),
ID: id,
TopicXDR: []string{counterXdr},
ValueXDR: expectedXdr,
TransactionHash: ledgerCloseMeta.TransactionHash(i).HexString(),
TxIndex: uint32(i + 1),
OpIndex: 0,
})
}
cursor := expected[len(expected)-1].ID
Expand Down
61 changes: 10 additions & 51 deletions cmd/stellar-rpc/internal/methods/get_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package methods

import (
"context"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
Expand All @@ -16,7 +15,6 @@ import (
"github.com/stellar/stellar-rpc/cmd/stellar-rpc/internal/store"
)

//nolint:funlen
func GetTransaction(
ctx context.Context,
log *log.Entry,
Expand Down Expand Up @@ -63,70 +61,31 @@ func GetTransaction(
LatestLedgerCloseTime: storeRange.LastLedger.CloseTime,
OldestLedger: storeRange.FirstLedger.Sequence,
OldestLedgerCloseTime: storeRange.FirstLedger.CloseTime,
TransactionDetails: protocol.TransactionDetails{
TransactionHash: request.Hash,
},
}

if errors.Is(getTxErr, store.ErrNoTransaction) {
switch {
case errors.Is(getTxErr, store.ErrNoTransaction):
response.Status = protocol.TransactionStatusNotFound
return response, nil
} else if getTxErr != nil {
case getTxErr != nil:
log.WithError(getTxErr).
WithField("hash", txHash).
Errorf("failed to fetch transaction")
return response, &jrpc2.Error{
Code: jrpc2.InternalError,
Message: getTxErr.Error(),
}
}

response.ApplicationOrder = tx.ApplicationOrder
response.FeeBump = tx.FeeBump
response.Ledger = tx.Ledger.Sequence
response.LedgerCloseTime = tx.Ledger.CloseTime

switch request.Format {
case protocol.FormatJSON:
result, envelope, meta, convErr := transactionToJSON(tx)
if convErr != nil {
return response, &jrpc2.Error{
Code: jrpc2.InternalError,
Message: convErr.Error(),
}
}
diagEvents, convErr := jsonifySlice(xdr.DiagnosticEvent{}, tx.Events)
if convErr != nil {
return response, &jrpc2.Error{
Code: jrpc2.InternalError,
Message: convErr.Error(),
}
}

response.ResultJSON = result
response.EnvelopeJSON = envelope
response.ResultMetaJSON = meta
response.DiagnosticEventsJSON = diagEvents

response.Events, convErr = BuildEventsJSONFromTransaction(tx)
if convErr != nil {
default:
txInfo, ferr := transactionInfo(tx, request.Format)
if ferr != nil {
return response, &jrpc2.Error{
Code: jrpc2.InternalError,
Message: convErr.Error(),
Message: ferr.Error(),
}
}
default:
response.ResultXDR = base64.StdEncoding.EncodeToString(tx.Result)
response.EnvelopeXDR = base64.StdEncoding.EncodeToString(tx.Envelope)
response.ResultMetaXDR = base64.StdEncoding.EncodeToString(tx.Meta)
response.DiagnosticEventsXDR = base64EncodeSlice(tx.Events)
response.Events = BuildEventsXDRFromTransaction(tx)
}

response.Status = protocol.TransactionStatusFailed
if tx.Successful {
response.Status = protocol.TransactionStatusSuccess
response.TransactionDetails = txInfo.TransactionDetails
response.LedgerCloseTime = txInfo.LedgerCloseTime
}
response.TransactionHash = request.Hash
return response, nil
}

Expand Down
Loading
Loading