-
Notifications
You must be signed in to change notification settings - Fork 7
services: Implement call to getLedgers
and start parsing the xdr.LedgerCloseMeta
#197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
mu := sync.Mutex{} | ||
var allTxHashes []string | ||
var errs []error | ||
|
||
// Submit tasks to the pool | ||
for _, ledger := range getLedgersResponse.Ledgers { | ||
ledger := ledger // Create a new variable to avoid closure issues | ||
pool.Submit(func() { | ||
txHashes, err := m.processLedger(ctx, ledger) | ||
mu.Lock() | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I plan to use toid to order the transactions in the database. It's calculated like this.
getLedgers
and start parsing the xdr.LedgerCloseMetagetLedgers
and start parsing the xdr.LedgerCloseMeta
getLedgers
and start parsing the xdr.LedgerCloseMetagetLedgers
and start parsing the xdr.LedgerCloseMeta
internal/services/ingest.go
Outdated
func (m *ingestService) fetchNextLedgersBatch(ctx context.Context, startLedger uint32) (GetLedgersResponse, error) { | ||
rpcHealth, err := m.rpcService.GetHealth() | ||
if err != nil { | ||
return GetLedgersResponse{}, fmt.Errorf("getting rpc health: %w", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In cases where RPC becomes unhealthy for a few mins and then healthy again, this would stop the ingestion and terminate right? How about we terminate ingestion process only if RPC stays unhealthy for a certain threshold. Otherwise we keep letting it try and fetch the ledgers batch until then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, good point! I'll work on that 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in dc0f8a5
if latestLedgerSynced >= rpcNewestLedger { | ||
return LedgerSeqRange{}, true | ||
} | ||
ledgerRange.StartLedger = max(latestLedgerSynced+1, rpcOldestLedger) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do a max()
here would that mean if wallet-backend is at 5 and rpc's oldest ledger is at 8, it would skip ingesting 6, 7? If we are ingesting using GetLedgers
by getting ledgers in bulk, do we want to allow WB catch up to RPC instead of skipping ledgers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do a max() here would that mean if wallet-backend is at 5 and rpc's oldest ledger is at 8, it would skip ingesting 6, 7?
I think we don't have another option here, right? If we have [oldestLedger: 8, newestLedger: 20]
, we can only ingest within that window, as the RPC doesn't have anything older than ledger 8
available for ingestion.
log.Ctx(ctx).Debugf("🚧 Got %d transactions for ledger %d", len(transactions), xdrLedgerCloseMeta.LedgerSequence()) | ||
txHashes := make([]string, 0, len(transactions)) | ||
for _, tx := range transactions { | ||
txHashes = append(txHashes, tx.Hash.HexString()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is still in TODO, I am assuming this will return a list of types.Transaction
structs instead of tx hash strings? Because what would be the use of the tx hashes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you're right! I'm returning txHashes because I'd like to log something short. But the output will definitely be actual objects!
… a new IngestStoreModel, since it relates to a different database table.
… used by the stellar-rpc package dependency
866e082
to
169087f
Compare
…e fetched from the RPC, based on the RPC available ledgers and the local "curstor"
…d limit, since this is how the API is meant to be used.
169087f
to
5369197
Compare
5369197
to
dc0f8a5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements a new getLedgers
RPC endpoint in the indexer’s RPC service, adds parallel ledger batch ingestion logic to the ingest service (with advisory locking), and introduces a dedicated IngestStoreModel
to track the ingestion cursor.
- Added
GetLedgers
toRPCService
, updated error handling, and tests inrpc_service_test.go
. - Extended ingest service with a new
Run
loop to fetch and process ledger batches in parallel. - Introduced
IngestStoreModel
and updatedModels
to support ingest cursor storage.
Reviewed Changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
internal/services/rpc_service.go | Added GetLedgers method and updated sendRPCRequest error message |
internal/services/rpc_service_test.go | New tests for GetLedgers and error path adjustments |
internal/services/ingest.go | New Run logic with batch fetching, parallel processing, and locking |
internal/services/mocks.go | Added GetLedgers mock method |
internal/services/ingest_test.go | Tests for getLedgerSeqRange and getLedgerTransactions |
internal/indexer/types/types.go | Changed Transaction.LedgerNumber from int64 to uint32 |
internal/data/ingest_store.go | New IngestStoreModel for cursor persistence |
internal/data/models.go | Registered IngestStoreModel in Models |
Comments suppressed due to low confidence (5)
internal/indexer/types/types.go:21
- Changing LedgerNumber from int64 to uint32 is a breaking change in the API contract; downstream consumers expecting signed integers may be impacted.
LedgerNumber uint32 `json:"ledgerNumber,omitempty" db:"ledger_number"`
internal/services/rpc_service.go:147
- [nitpick] Consider adding a comment for the
GetLedgersResponse
type alias to document its purpose and linkage toprotocol.GetLedgersResponse
.
type GetLedgersResponse protocol.GetLedgersResponse
internal/services/ingest_test.go:36
- Consider adding tests for
fetchNextLedgersBatch
to cover cases where RPC indicates ingestion is in sync (ErrAlreadyInSync
) and RPC call failures for more complete coverage.
func Test_getLedgerSeqRange(t *testing.T) {
internal/services/rpc_service.go:161
- Missing import for "encoding/json"; the call to json.Unmarshal will not compile without importing the package.
err = json.Unmarshal(resultBytes, &result)
What
Update the indexer code to stream from
{RPC}.getLedgers
and break down the results from ledgerRange -> ledgers -> transactions.Also, (pseudo) process the ledgers in parallel.
Why
As part of the new indexer implementation.
Future Work
I haven't added many tests to the ingest service yet, since this code will still evolve quite a bit.
Issue that this PR addresses
Partially address #128
Checklist
PR Structure
all
if the changes are broad or impact many packages.Thoroughness
Release