Skip to content

Commit 8714420

Browse files
authored
Retain UNL validators in purge (#400)
## High Level Overview of Change <!-- Please include a summary/list of the changes. If too broad, please consider splitting into multiple PRs. If a relevant Asana task, please link it here. --> With current logic, if a validator has not participated in the consensus process for more than a week, it will be removed from the list. This led to an UNL validator, even though still in the UNL list, got removed by the logic. This PR would: - Retain inactive UNL validators that are still discoverable in the UNL list in the database, until it got removed from the list. - Increase the purging period from one week to thirty days. Resolves #395 Replaces #397 ### Type of Change <!-- Please check relevant options, delete irrelevant ones. --> - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Refactor (non-breaking change that only restructures code) - [ ] Tests (You added tests for code that already exists, or your new feature included in this PR) - [ ] Documentation Updates - [ ] Release
1 parent 9246ef6 commit 8714420

File tree

2 files changed

+101
-5
lines changed

2 files changed

+101
-5
lines changed

src/connection-manager/manifests.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,16 +244,20 @@ async function updateRevocations(): Promise<void> {
244244
}
245245

246246
/**
247-
* Deletes validators that are older than an hour.
247+
* Deletes validators that are older than 30 days.
248+
* UNL validators are not deleted even if they are older than 30 days.
248249
*
249250
* @returns Void.
250251
*/
251-
async function purgeOldValidators(): Promise<void> {
252-
const oneWeekAgo = new Date()
253-
oneWeekAgo.setDate(oneWeekAgo.getDate() - 7)
252+
export async function purgeOldValidators(): Promise<void> {
253+
const thirtyDaysAgo = new Date()
254+
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30)
254255
log.info('Deleting old validators')
255256
try {
256-
await query('validators').where('last_ledger_time', '<', oneWeekAgo).del()
257+
await query('validators')
258+
.where('last_ledger_time', '<', thirtyDaysAgo)
259+
.whereNull('unl')
260+
.del()
257261
} catch (err) {
258262
log.error(`Error purging old validators`, err)
259263
}

test/manifests/manifests.test.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
updateManifestsFromRippled,
66
updateUNLManifests,
77
updateUnls,
8+
purgeOldValidators,
89
} from '../../src/connection-manager/manifests'
910
import {
1011
destroy,
@@ -194,4 +195,95 @@ describe('manifest ingest', () => {
194195
unl: null,
195196
})
196197
})
198+
199+
test('purgeOldValidators - purges validator older than 30 days', async () => {
200+
const thirtyOneDaysAgo = new Date()
201+
thirtyOneDaysAgo.setDate(thirtyOneDaysAgo.getDate() - 31)
202+
203+
await query('validators').insert({
204+
signing_key: 'n9OldValidator1111111111111111111111111111111111111111111',
205+
master_key: 'nHOldValidator1111111111111111111111111111111111111111111',
206+
last_ledger_time: thirtyOneDaysAgo,
207+
})
208+
209+
// Verify validator exists before purge
210+
let validators = (await query('validators').select('*')) as Array<{
211+
signing_key: string
212+
}>
213+
expect(validators).toHaveLength(1)
214+
215+
// Run purge
216+
await purgeOldValidators()
217+
218+
// Verify validator was deleted
219+
validators = (await query('validators').select('*')) as Array<{
220+
signing_key: string
221+
}>
222+
expect(validators).toHaveLength(0)
223+
})
224+
225+
test('purgeOldValidators - keeps UNL validator even if older than 30 days', async () => {
226+
const thirtyOneDaysAgo = new Date()
227+
thirtyOneDaysAgo.setDate(thirtyOneDaysAgo.getDate() - 31)
228+
229+
// Insert a validator that matches the UNL (from unl1 fixture)
230+
await query('validators').insert({
231+
signing_key: 'n9LCf7NtwcyXVc5fYB6UVByRoQZqJDhrMUoKnr3GQB6mFqpcmMzg',
232+
master_key: 'nHBtDzdRDykxiuv7uSMPTcGexNm879RUUz5GW4h1qgjbtyvWZ1LE',
233+
unl: 'vl.ripple.com',
234+
last_ledger_time: thirtyOneDaysAgo,
235+
})
236+
237+
// Verify validator exists before purge
238+
let validators = (await query('validators').select('*')) as Array<{
239+
signing_key: string
240+
}>
241+
expect(validators.length).toBeGreaterThanOrEqual(1)
242+
243+
// Run purge
244+
await purgeOldValidators()
245+
246+
// Verify UNL validator was NOT deleted
247+
validators = (await query('validators').select('*')) as Array<{
248+
signing_key: string
249+
}>
250+
const unlValidator = validators.find(
251+
(validator) =>
252+
validator.signing_key ===
253+
'n9LCf7NtwcyXVc5fYB6UVByRoQZqJDhrMUoKnr3GQB6mFqpcmMzg',
254+
)
255+
expect(unlValidator).toBeDefined()
256+
expect(unlValidator?.signing_key).toBe(
257+
'n9LCf7NtwcyXVc5fYB6UVByRoQZqJDhrMUoKnr3GQB6mFqpcmMzg',
258+
)
259+
})
260+
261+
test('purgeOldValidators - keeps validator less than 30 days old', async () => {
262+
const tenDaysAgo = new Date()
263+
tenDaysAgo.setDate(tenDaysAgo.getDate() - 10)
264+
265+
await query('validators').insert({
266+
signing_key: 'n9RecentValidator11111111111111111111111111111111111111111',
267+
master_key: 'nHRecentValidator11111111111111111111111111111111111111111',
268+
last_ledger_time: tenDaysAgo,
269+
})
270+
271+
// Verify validator exists before purge
272+
let validators = (await query('validators').select('*')) as Array<{
273+
signing_key: string
274+
}>
275+
expect(validators).toHaveLength(1)
276+
277+
// Run purge
278+
await purgeOldValidators()
279+
280+
// Verify recent validator was NOT deleted
281+
validators = (await query('validators').select('*')) as Array<{
282+
signing_key: string
283+
}>
284+
expect(validators).toHaveLength(1)
285+
expect(validators[0].signing_key).toBe(
286+
'n9RecentValidator11111111111111111111111111111111111111111',
287+
)
288+
})
197289
})

0 commit comments

Comments
 (0)