Skip to content

Commit d4b050f

Browse files
authored
Re-index the events table with a combined topic/contract and ID (#510)
* Drop P22 integration tests
1 parent 0141792 commit d4b050f

File tree

8 files changed

+61
-41
lines changed

8 files changed

+61
-41
lines changed

.github/workflows/stellar-rpc.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,12 @@ jobs:
9090
strategy:
9191
matrix:
9292
os: [ ubuntu-22.04 ]
93-
protocol-version: [ 22, 23 ]
93+
protocol-version: [ 23 ]
9494
runs-on: ${{ matrix.os }}
9595
env:
9696
STELLAR_RPC_INTEGRATION_TESTS_ENABLED: true
9797
STELLAR_RPC_INTEGRATION_TESTS_CORE_MAX_SUPPORTED_PROTOCOL: ${{ matrix.protocol-version }}
9898
STELLAR_RPC_INTEGRATION_TESTS_CAPTIVE_CORE_BIN: /usr/bin/stellar-core
99-
PROTOCOL_22_CORE_DEBIAN_PKG_VERSION: 23.0.1-2670.050eacf11.focal
100-
PROTOCOL_22_CORE_DOCKER_IMG: stellar/stellar-core:23.0.1-2670.050eacf11.focal
10199
PROTOCOL_23_CORE_DEBIAN_PKG_VERSION: 23.0.1-2670.050eacf11.focal
102100
PROTOCOL_23_CORE_DOCKER_IMG: stellar/stellar-core:23.0.1-2670.050eacf11.focal
103101

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22

33
## Unreleased
44

5+
**This release includes a database migration.** This migration may take up to an hour to build new indices, depending on your hardware; please deploy accordingly.
6+
57
### Added
68
- The RPC's `Client` now has a new method `LoadAccount` which returns an SDK-compatible `Account` interface for a public key ([#481](https://github.com/stellar/stellar-rpc/pull/481/)).
79

10+
### Fixed
11+
- `getLedgers` performance has been improved ([#505](https://github.com/stellar/stellar-rpc/pull/505)).
12+
- `getEvents` performance has been drastically improved ([#510](https://github.com/stellar/stellar-rpc/pull/510)).
13+
814

915
## [v23.0.2](https://github.com/stellar/stellar-rpc/compare/v23.0.1...v23.0.2)
1016

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ go-test: build-libs
7676

7777
test: go-test rust-test
7878

79+
bench:
80+
go test -run=None -bench=. ./...
81+
7982
clean:
8083
cargo clean
8184
go clean ./...

cmd/stellar-rpc/docker/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ ENV RUSTUP_HOME=/rust/.rust
1313
ENV PATH="/usr/local/go/bin:$CARGO_HOME/bin:${PATH}"
1414
ENV DEBIAN_FRONTEND=noninteractive
1515
RUN apt-get update
16-
RUN apt-get install -y build-essential
16+
RUN apt-get install -y build-essential jq
1717
RUN apt-get clean
1818

1919
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $RUST_TOOLCHAIN_VERSION

cmd/stellar-rpc/internal/db/event.go

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ func (eventHandler *eventHandler) GetEvents(
305305
contractIDs [][]byte,
306306
topics NestedTopicArray,
307307
eventTypes []int,
308-
f ScanFunction,
308+
scanner ScanFunction,
309309
) error {
310310
start := time.Now()
311311

@@ -348,6 +348,7 @@ func (eventHandler *eventHandler) GetEvents(
348348
rows, err := eventHandler.db.Query(ctx, rowQ)
349349
if err != nil {
350350
eventHandler.log.
351+
WithError(err).
351352
WithField("duration", time.Since(start)).
352353
WithField("start", cursorRange.Start.String()).
353354
WithField("end", cursorRange.End.String()).
@@ -363,56 +364,53 @@ func (eventHandler *eventHandler) GetEvents(
363364

364365
defer rows.Close()
365366

366-
foundRows := false
367-
for rows.Next() {
368-
foundRows = true
369-
var row struct {
370-
eventCursorID string `db:"id"`
371-
eventData []byte `db:"event_data"`
372-
transactionHash []byte `db:"transaction_hash"`
373-
ledgerCloseTime int64 `db:"ledger_close_time"`
374-
}
367+
type rowResult struct {
368+
eventCursorID string
369+
eventData []byte
370+
transactionHash []byte
371+
ledgerCloseTime int64
372+
}
375373

376-
err = rows.Scan(&row.eventCursorID, &row.eventData, &row.transactionHash, &row.ledgerCloseTime)
377-
if err != nil {
378-
return fmt.Errorf("failed to scan row: %w", err)
374+
foundRows := 0
375+
for rows.Next() {
376+
foundRows++
377+
378+
row := rowResult{}
379+
if err := rows.Scan(
380+
&row.eventCursorID,
381+
&row.eventData,
382+
&row.transactionHash,
383+
&row.ledgerCloseTime,
384+
); err != nil {
385+
return errors.Join(err, errors.New("failed to scan row"))
379386
}
380387

381-
id, eventData, ledgerCloseTime := row.eventCursorID, row.eventData, row.ledgerCloseTime
388+
id, ledgerCloseTime := row.eventCursorID, row.ledgerCloseTime
382389
transactionHash := row.transactionHash
383390
cur, err := protocol.ParseCursor(id)
384391
if err != nil {
385392
return errors.Join(err, errors.New("failed to parse cursor"))
386393
}
387394

388-
var eventXDR xdr.DiagnosticEvent
389-
err = xdr.SafeUnmarshal(eventData, &eventXDR)
390-
if err != nil {
395+
var event xdr.DiagnosticEvent
396+
if err := event.UnmarshalBinary(row.eventData); err != nil {
391397
return errors.Join(err, errors.New("failed to decode event"))
392398
}
399+
393400
txHash := xdr.Hash(transactionHash)
394-
if !f(eventXDR, cur, ledgerCloseTime, &txHash) {
401+
if !scanner(event, cur, ledgerCloseTime, &txHash) {
395402
return nil
396403
}
397404
}
398-
if !foundRows {
399-
eventHandler.log.
400-
WithField("duration", time.Since(start)).
401-
WithField("start", cursorRange.Start.String()).
402-
WithField("end", cursorRange.End.String()).
403-
WithField("contractIds", encodedContractIDs).
404-
WithField("eventTypes", eventTypes).
405-
WithField("Topics", topics).
406-
Debugf(
407-
"No events found for ledger range",
408-
)
409-
}
410405

411406
eventHandler.log.
412-
WithField("startLedgerSequence", cursorRange.Start.Ledger).
413-
WithField("endLedgerSequence", cursorRange.End.Ledger).
414407
WithField("duration", time.Since(start)).
415-
Debugf("Fetched and decoded all the events with filters - contractIDs: %v ", encodedContractIDs)
408+
WithField("start", cursorRange.Start.String()).
409+
WithField("end", cursorRange.End.String()).
410+
WithField("contractIds", encodedContractIDs).
411+
WithField("eventTypes", eventTypes).
412+
WithField("Topics", topics).
413+
Debugf("Found %d events for ledger range", foundRows)
416414

417415
return rows.Err()
418416
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-- +migrate Up
2+
DROP INDEX idx_contract_id;
3+
DROP INDEX idx_topic1;
4+
5+
CREATE INDEX idx_id_contract_id ON events (contract_id, id);
6+
CREATE INDEX idx_id_topic1 ON events (topic1, id);
7+
8+
-- +migrate Down
9+
DROP INDEX idx_id_contract_id;
10+
DROP INDEX idx_id_topic1;
11+
12+
CREATE INDEX idx_contract_id ON events (contract_id);
13+
CREATE INDEX idx_topic1 ON events (topic1);

cmd/stellar-rpc/internal/methods/get_events.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ func (h eventsRPCHandler) getEvents(ctx context.Context, request protocol.GetEve
170170
eventTypes := combineEventTypes(request.Filters)
171171

172172
// Scan function to apply filters
173-
eventScanFunction := func(
173+
var eventScanFunction db.ScanFunction = func(
174174
event xdr.DiagnosticEvent, cursor protocol.Cursor, ledgerCloseTimestamp int64, txHash *xdr.Hash,
175175
) bool {
176176
if request.Matches(event) {

cmd/stellar-rpc/internal/methods/get_events_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,15 +1030,17 @@ func BenchmarkGetEvents(b *testing.B) {
10301030
now := time.Now().UTC()
10311031

10321032
writer := db.NewReadWriter(log, dbx, interfaces.MakeNoOpDeamon(), 10, 10, passphrase)
1033-
write, err := writer.NewTx(ctx)
1034-
require.NoError(b, err)
1035-
ledgerW, eventW := write.LedgerWriter(), write.EventWriter()
10361033

10371034
for i := range []int{1, 2, 3} {
1035+
write, err := writer.NewTx(ctx)
1036+
require.NoError(b, err)
1037+
ledgerW, eventW := write.LedgerWriter(), write.EventWriter()
1038+
10381039
txMeta := getTxMetaWithContractEvents(contractID)
10391040
ledgerCloseMeta := ledgerCloseMetaWithEvents(uint32(i), now.Unix(), txMeta...)
10401041
require.NoError(b, ledgerW.InsertLedger(ledgerCloseMeta), "ingestion failed for ledger ")
10411042
require.NoError(b, eventW.InsertEvents(ledgerCloseMeta), "ingestion failed for events ")
1043+
10421044
require.NoError(b, write.Commit(ledgerCloseMeta, nil))
10431045
}
10441046

0 commit comments

Comments
 (0)