Skip to content

Commit 4e279a5

Browse files
author
Shawn Reuland
committed
#5571: use getHealth to discriminate between beyond latest and out of range conditions
1 parent 800b635 commit 4e279a5

File tree

3 files changed

+84
-169
lines changed

3 files changed

+84
-169
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ require (
1313
github.com/adjust/goautoneg v0.0.0-20150426214442-d788f35a0315
1414
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
1515
github.com/aws/aws-sdk-go v1.45.27
16-
github.com/creachadair/jrpc2 v1.2.0
1716
github.com/djherbis/fscache v0.10.1
1817
github.com/elazarl/go-bindata-assetfs v1.0.1
1918
github.com/getsentry/raven-go v0.2.0
@@ -58,6 +57,7 @@ require (
5857

5958
require (
6059
github.com/cenkalti/backoff/v4 v4.3.0
60+
github.com/creachadair/jrpc2 v1.2.0
6161
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da
6262
github.com/docker/docker v27.3.1+incompatible
6363
github.com/docker/go-connections v0.5.0

ingest/ledgerbackend/rpc_backend.go

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"sync/atomic"
1010
"time"
1111

12-
"github.com/creachadair/jrpc2"
1312
"github.com/stellar/go/xdr"
1413
rpc "github.com/stellar/stellar-rpc/client"
1514
"github.com/stellar/stellar-rpc/protocol"
@@ -26,15 +25,16 @@ func (e *RPCLedgerMissingError) Error() string {
2625
return fmt.Sprintf("ledger %d was not present on rpc", e.Sequence)
2726
}
2827

29-
type RPCLedgerBeyondLatestError struct{}
28+
type rpcLedgerBeyondLatestError struct{}
3029

31-
func (e RPCLedgerBeyondLatestError) Error() string {
30+
func (e rpcLedgerBeyondLatestError) Error() string {
3231
return "ledger is not available on the RPC server yet"
3332
}
3433

3534
// The minimum required RPC client methods used by RPCLedgerBackend.
3635
type RPCLedgerGetter interface {
3736
GetLedgers(ctx context.Context, req protocol.GetLedgersRequest) (protocol.GetLedgersResponse, error)
37+
GetHealth(ctx context.Context) (protocol.GetHealthResponse, error) // <-- Added
3838
}
3939

4040
type RPCLedgerBackend struct {
@@ -144,7 +144,7 @@ func (b *RPCLedgerBackend) GetLedger(ctx context.Context, sequence uint32) (xdr.
144144
return lcm, nil
145145
}
146146

147-
var beyondErr *RPCLedgerBeyondLatestError
147+
var beyondErr *rpcLedgerBeyondLatestError
148148
if !(errors.As(err, &beyondErr)) {
149149
return xdr.LedgerCloseMeta{}, err
150150
}
@@ -180,7 +180,7 @@ func (b *RPCLedgerBackend) PrepareRange(ctx context.Context, ledgerRange Range)
180180
_, err := b.getBufferedLedger(ctx, ledgerRange.from)
181181
if err != nil {
182182
// beyond latest is handled later in GetLedger
183-
var beyondErr *RPCLedgerBeyondLatestError
183+
var beyondErr *rpcLedgerBeyondLatestError
184184
if !(errors.As(err, &beyondErr)) {
185185
return err
186186
}
@@ -238,7 +238,16 @@ func (b *RPCLedgerBackend) getBufferedLedger(ctx context.Context, sequence uint3
238238
return lcm, nil
239239
}
240240

241-
// Ledger not in buffer, fetch a small batch from RPC starting from the requested sequence
241+
// Check if requested ledger is beyond the RPC retention window using GetHealth
242+
health, err := b.client.GetHealth(ctx)
243+
if err != nil {
244+
return xdr.LedgerCloseMeta{}, fmt.Errorf("failed to get health from RPC: %w", err)
245+
}
246+
if sequence > health.LatestLedger {
247+
return xdr.LedgerCloseMeta{}, &rpcLedgerBeyondLatestError{}
248+
}
249+
250+
// attempt to fetch a small batch from RPC starting from the requested sequence
242251
req := protocol.GetLedgersRequest{
243252
StartLedger: sequence,
244253
Pagination: &protocol.LedgerPaginationOptions{
@@ -248,23 +257,11 @@ func (b *RPCLedgerBackend) getBufferedLedger(ctx context.Context, sequence uint3
248257

249258
ledgers, err := b.client.GetLedgers(ctx, req)
250259
if err != nil {
251-
// InvalidRequest code is the most specific error code provided for invalid range requests.
252-
// https://github.com/stellar/stellar-rpc/pull/407/
253-
// if received, assume it's range problem to enable retry.
254-
var rpcErr *jrpc2.Error
255-
if errors.As(err, &rpcErr) && rpcErr.Code == jrpc2.InvalidRequest {
256-
return xdr.LedgerCloseMeta{}, &RPCLedgerBeyondLatestError{}
257-
}
258-
return xdr.LedgerCloseMeta{}, fmt.Errorf("failed to get ledgers starting from %d: %w", sequence, err)
260+
return xdr.LedgerCloseMeta{}, err
259261
}
260262

261263
b.initBuffer()
262264

263-
// Check if requested ledger is beyond the RPC retention window
264-
if sequence > ledgers.LatestLedger {
265-
return xdr.LedgerCloseMeta{}, &RPCLedgerBeyondLatestError{}
266-
}
267-
268265
// Populate buffer with new ledgers
269266
for _, ledger := range ledgers.Ledgers {
270267
var lcm xdr.LedgerCloseMeta

0 commit comments

Comments
 (0)