diff --git a/ingest/ledgerbackend/captive_core_backend.go b/ingest/ledgerbackend/captive_core_backend.go index d965d932e6..a69a222eb5 100644 --- a/ingest/ledgerbackend/captive_core_backend.go +++ b/ingest/ledgerbackend/captive_core_backend.go @@ -390,23 +390,37 @@ func (c *CaptiveStellarCore) PrepareRange(ledgerRange Range) error { // IsPrepared returns true if a given ledgerRange is prepared. func (c *CaptiveStellarCore) IsPrepared(ledgerRange Range) (bool, error) { - if c.nextLedger == 0 { - return false, nil + lastLedger := uint32(0) + if c.lastLedger != nil { + lastLedger = *c.lastLedger } - if c.lastLedger == nil { - return c.nextLedger <= ledgerRange.from, nil + cachedLedger := uint32(0) + if c.cachedMeta != nil { + cachedLedger = c.cachedMeta.LedgerSequence() + } + + return c.isPrepared(c.nextLedger, lastLedger, cachedLedger, ledgerRange), nil +} + +func (*CaptiveStellarCore) isPrepared(nextLedger, lastLedger, cachedLedger uint32, ledgerRange Range) bool { + if nextLedger == 0 { + return false + } + + if lastLedger == 0 { + return nextLedger <= ledgerRange.from || cachedLedger == ledgerRange.from } - // From now on: c.lastLedger != nil so current range is bounded + // From now on: lastLedger != 0 so current range is bounded if ledgerRange.bounded { - return c.nextLedger <= ledgerRange.from && - c.nextLedger <= *c.lastLedger, nil + return (nextLedger <= ledgerRange.from || cachedLedger == ledgerRange.from) && + lastLedger >= ledgerRange.to } // Requested range is unbounded but current one is bounded - return false, nil + return false } // GetLedger returns true when ledger is found and it's LedgerCloseMeta. diff --git a/ingest/ledgerbackend/captive_core_backend_test.go b/ingest/ledgerbackend/captive_core_backend_test.go index 17da495a5d..98f6fe72b8 100644 --- a/ingest/ledgerbackend/captive_core_backend_test.go +++ b/ingest/ledgerbackend/captive_core_backend_test.go @@ -1067,3 +1067,37 @@ func TestCaptiveRunFromParams(t *testing.T) { }) } } + +func TestCaptiveIsPrepared(t *testing.T) { + var tests = []struct { + nextLedger uint32 + lastLedger uint32 + cachedLedger uint32 + ledgerRange Range + result bool + }{ + {0, 0, 0, UnboundedRange(100), false}, + {100, 0, 0, UnboundedRange(101), true}, + {101, 0, 100, UnboundedRange(100), true}, + {100, 200, 0, UnboundedRange(100), false}, + + {100, 200, 0, BoundedRange(100, 200), true}, + {100, 200, 0, BoundedRange(100, 201), false}, + {100, 201, 0, BoundedRange(100, 200), true}, + {101, 200, 100, BoundedRange(100, 200), true}, + } + + for _, tc := range tests { + t.Run(fmt.Sprintf("next_%d_last_%d_cached_%d_range_%v", tc.nextLedger, tc.lastLedger, tc.cachedLedger, tc.ledgerRange), func(t *testing.T) { + captiveBackend := CaptiveStellarCore{} + + result := captiveBackend.isPrepared( + tc.nextLedger, + tc.lastLedger, + tc.cachedLedger, + tc.ledgerRange, + ) + assert.Equal(t, tc.result, result) + }) + } +}