Skip to content

Commit 079447b

Browse files
authored
Merge pull request #1176 from permaweb/VinceJuliano/cu-owner-preference
feat(cu): add wallet preferrence for checkpoints
2 parents 4e60a91 + ac44415 commit 079447b

File tree

5 files changed

+61
-16
lines changed

5 files changed

+61
-16
lines changed

servers/cu/src/bootstrap.js

+1
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ export const createApis = async (ctx) => {
400400
PROCESS_IGNORE_ARWEAVE_CHECKPOINTS: ctx.PROCESS_IGNORE_ARWEAVE_CHECKPOINTS,
401401
IGNORE_ARWEAVE_CHECKPOINTS: ctx.IGNORE_ARWEAVE_CHECKPOINTS,
402402
PROCESS_CHECKPOINT_TRUSTED_OWNERS: ctx.PROCESS_CHECKPOINT_TRUSTED_OWNERS,
403+
PROCESS_CHECKPOINT_PREFERRED_OWNERS: ctx.PROCESS_CHECKPOINT_PREFERRED_OWNERS,
403404
readStateFromCheckpoint,
404405
hashWasmMemory: WasmClient.hashWasmMemoryWith({ logger: ctx.logger }),
405406
CHECKPONT_VALIDATION_STEPS: ctx.CHECKPONT_VALIDATION_STEPS,

servers/cu/src/config.js

+2
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ const CONFIG_ENVS = {
165165
PROCESS_IGNORE_ARWEAVE_CHECKPOINTS: process.env.PROCESS_IGNORE_ARWEAVE_CHECKPOINTS || [],
166166
IGNORE_ARWEAVE_CHECKPOINTS: process.env.IGNORE_ARWEAVE_CHECKPOINTS || [],
167167
PROCESS_CHECKPOINT_TRUSTED_OWNERS: process.env.PROCESS_CHECKPOINT_TRUSTED_OWNERS || [],
168+
PROCESS_CHECKPOINT_PREFERRED_OWNERS: process.env.PROCESS_CHECKPOINT_PREFERRED_OWNERS || [],
168169
PROCESS_MEMORY_CACHE_MAX_SIZE: process.env.PROCESS_MEMORY_CACHE_MAX_SIZE || bytes('1gb'),
169170
PROCESS_MEMORY_CACHE_TTL: process.env.PROCESS_MEMORY_CACHE_TTL || ms('24h'),
170171
PROCESS_MEMORY_CACHE_FILE_DIR: process.env.PROCESS_MEMORY_CACHE_FILE_DIR || tmpdir(),
@@ -221,6 +222,7 @@ const CONFIG_ENVS = {
221222
PROCESS_IGNORE_ARWEAVE_CHECKPOINTS: process.env.PROCESS_IGNORE_ARWEAVE_CHECKPOINTS || [],
222223
IGNORE_ARWEAVE_CHECKPOINTS: process.env.IGNORE_ARWEAVE_CHECKPOINTS || [],
223224
PROCESS_CHECKPOINT_TRUSTED_OWNERS: process.env.PROCESS_CHECKPOINT_TRUSTED_OWNERS || [],
225+
PROCESS_CHECKPOINT_PREFERRED_OWNERS: process.env.PROCESS_CHECKPOINT_PREFERRED_OWNERS || [],
224226
PROCESS_MEMORY_CACHE_MAX_SIZE: process.env.PROCESS_MEMORY_CACHE_MAX_SIZE || bytes('1gb'),
225227
PROCESS_MEMORY_CACHE_TTL: process.env.PROCESS_MEMORY_CACHE_TTL || ms('24h'),
226228
PROCESS_MEMORY_CACHE_FILE_DIR: process.env.PROCESS_MEMORY_CACHE_FILE_DIR || tmpdir(),

servers/cu/src/domain/model.js

+4
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ export const domainConfigSchema = z.object({
169169
* An array of trusted owner wallets that Arweave checkpoints can be queried from.
170170
*/
171171
PROCESS_CHECKPOINT_TRUSTED_OWNERS: commaDelimitedArraySchema,
172+
/**
173+
* A single wallet to prefer.
174+
*/
175+
PROCESS_CHECKPOINT_PREFERRED_OWNERS: commaDelimitedArraySchema,
172176
/**
173177
* An array of checkpoint ids that should not be used
174178
*/

servers/cu/src/effects/ao-process.js

+44-13
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,7 @@ export function findLatestProcessMemoryWith ({
798798
PROCESS_IGNORE_ARWEAVE_CHECKPOINTS,
799799
IGNORE_ARWEAVE_CHECKPOINTS,
800800
PROCESS_CHECKPOINT_TRUSTED_OWNERS,
801+
PROCESS_CHECKPOINT_PREFERRED_OWNERS,
801802
logger: _logger,
802803
readStateFromCheckpoint,
803804
hashWasmMemory,
@@ -851,15 +852,22 @@ export function findLatestProcessMemoryWith ({
851852
}
852853
`
853854

854-
const removeIgnoredCheckpoints = ({ checkpoints }) => {
855-
if (!checkpoints || !checkpoints.length) return { checkpoints: [] }
856-
return { checkpoints: checkpoints.filter((checkpoint) => !isCheckpointIgnored(checkpoint.node.id)) }
855+
const removeIgnoredCheckpoints = ({ checkpoints, preferredCheckponts }) => {
856+
if (!checkpoints || !checkpoints.length) return { checkpoints: [], preferredCheckponts }
857+
return { checkpoints: checkpoints.filter((checkpoint) => !isCheckpointIgnored(checkpoint.node.id)), preferredCheckponts }
857858
}
858859

859-
const findLatestVerified = async ({ checkpoints }) => {
860-
if (checkpoints.length <= CHECKPONT_VALIDATION_STEPS + CHECKPONT_VALIDATION_RETRIES) {
861-
if (checkpoints.length >= 1) {
862-
const sorted = checkpoints.sort((a, b) => {
860+
const removeIgnoredPreferredCheckpoints = ({ checkpoints, preferredCheckponts }) => {
861+
if (!preferredCheckponts || !preferredCheckponts.length) return { checkpoints, preferredCheckponts: [] }
862+
return { checkpoints, preferredCheckponts: preferredCheckponts.filter((checkpoint) => !isCheckpointIgnored(checkpoint.node.id)) }
863+
}
864+
865+
const findLatestVerified = async ({ checkpoints, preferredCheckponts }) => {
866+
const checkpointsToUse = preferredCheckponts.length > 0 ? preferredCheckponts : checkpoints
867+
868+
if (checkpointsToUse.length <= CHECKPONT_VALIDATION_STEPS + CHECKPONT_VALIDATION_RETRIES) {
869+
if (checkpointsToUse.length >= 1) {
870+
const sorted = checkpointsToUse.sort((a, b) => {
863871
return parseInt(
864872
b.node.tags.find((tag) => tag.name === 'Nonce').value) - parseInt(a.node.tags.find((tag) => tag.name === 'Nonce').value
865873
)
@@ -890,8 +898,8 @@ export function findLatestProcessMemoryWith ({
890898
}
891899
}
892900

893-
logger(`FINDING LATEST VERIFIED CHECKPOINT FROM LIST OF CHECKPOINTS OF LENGTH ${checkpoints.length}`)
894-
const oldestToNewestCheckpoints = [...checkpoints].reverse().sort((a, b) => {
901+
logger(`FINDING LATEST VERIFIED CHECKPOINT FROM LIST OF CHECKPOINTS OF LENGTH ${checkpointsToUse.length}`)
902+
const oldestToNewestCheckpoints = [...checkpointsToUse].reverse().sort((a, b) => {
895903
return parseInt(
896904
a.node.tags.find((tag) => tag.name === 'Nonce').value) - parseInt(b.node.tags.find((tag) => tag.name === 'Nonce').value
897905
)
@@ -959,7 +967,7 @@ export function findLatestProcessMemoryWith ({
959967
currentCheckpoint = nextCheckpoint
960968
}
961969

962-
if ((correct / CHECKPONT_VALIDATION_STEPS) > CHECKPONT_VALIDATION_THRESH) {
970+
if ((correct / CHECKPONT_VALIDATION_STEPS) >= CHECKPONT_VALIDATION_THRESH) {
963971
const finalTags = parseTags(currentCheckpoint.node.tags)
964972
logger(`Determined correct checkpoint id: ${currentCheckpoint.node.id} Process: ${finalTags.Process}`)
965973
logger(`Votes: ${correct}`)
@@ -998,9 +1006,10 @@ export function findLatestProcessMemoryWith ({
9981006
return true
9991007
}
10001008

1001-
const determineLatestVerifiedCheckpoint = (checkpoints) => {
1002-
return of({ checkpoints })
1009+
const determineLatestVerifiedCheckpoint = ({ checkpoints, preferredCheckponts}) => {
1010+
return of({ checkpoints, preferredCheckponts })
10031011
.map(removeIgnoredCheckpoints)
1012+
.map(removeIgnoredPreferredCheckpoints)
10041013
.chain(fromPromise(findLatestVerified))
10051014
}
10061015

@@ -1252,7 +1261,7 @@ export function findLatestProcessMemoryWith ({
12521261
return Rejected(args)
12531262
}
12541263

1255-
return of({ PROCESS_CHECKPOINT_TRUSTED_OWNERS })
1264+
return of({ PROCESS_CHECKPOINT_TRUSTED_OWNERS, PROCESS_CHECKPOINT_PREFERRED_OWNERS })
12561265
.chain(({ PROCESS_CHECKPOINT_TRUSTED_OWNERS }) => {
12571266
if (isEmpty(PROCESS_CHECKPOINT_TRUSTED_OWNERS)) return address()
12581267
return Resolved(PROCESS_CHECKPOINT_TRUSTED_OWNERS)
@@ -1267,6 +1276,28 @@ export function findLatestProcessMemoryWith ({
12671276
})
12681277
})
12691278
.map(path(['data', 'transactions', 'edges']))
1279+
.chain((nonPreferredCheckpoints) => {
1280+
if (isEmpty(PROCESS_CHECKPOINT_PREFERRED_OWNERS)) {
1281+
return of({ checkpoints: nonPreferredCheckpoints, preferredCheckponts: []})
1282+
}
1283+
return of(PROCESS_CHECKPOINT_PREFERRED_OWNERS)
1284+
.map((owners) => ifElse(Array.isArray, always(owners), always([owners]))(owners))
1285+
.chain((owners) => {
1286+
return queryCheckpoints({
1287+
query: GET_AO_PROCESS_CHECKPOINTS,
1288+
variables: { owners, processId, limit: 50 },
1289+
processId,
1290+
before: LATEST
1291+
})
1292+
})
1293+
.map(path(['data', 'transactions', 'edges']))
1294+
.map((preferredCheckponts) => {
1295+
return {
1296+
checkpoints: nonPreferredCheckpoints,
1297+
preferredCheckponts
1298+
}
1299+
})
1300+
})
12701301
.chain(determineLatestVerifiedCheckpoint)
12711302
.bimap(
12721303
(err) => {

servers/cu/src/effects/ao-process.test.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@ describe('ao-process', () => {
758758
PROCESS_IGNORE_ARWEAVE_CHECKPOINTS: [],
759759
IGNORE_ARWEAVE_CHECKPOINTS: [],
760760
PROCESS_CHECKPOINT_TRUSTED_OWNERS: [],
761+
PROCESS_CHECKPOINT_PREFERRED_OWNERS: [],
761762
CHECKPONT_VALIDATION_STEPS: 10,
762763
CHECKPONT_VALIDATION_RETRIES: 1,
763764
CHECKPONT_VALIDATION_THRESH: 0.75,
@@ -863,6 +864,7 @@ describe('ao-process', () => {
863864
const findLatestProcessMemory = findLatestProcessMemorySchema.implement(findLatestProcessMemoryWith({
864865
...deps,
865866
PROCESS_CHECKPOINT_TRUSTED_OWNERS: ['wallet-123', 'wallet-456'],
867+
PROCESS_CHECKPOINT_PREFERRED_OWNERS: [],
866868
queryGateway: async ({ query, variables }) => {
867869
try {
868870
assert.deepStrictEqual(variables, { owners: ['wallet-123', 'wallet-456'], processId: 'process-123', limit: 50 })
@@ -1211,7 +1213,8 @@ describe('ao-process', () => {
12111213
logger,
12121214
PROCESS_IGNORE_ARWEAVE_CHECKPOINTS: [],
12131215
IGNORE_ARWEAVE_CHECKPOINTS: [],
1214-
PROCESS_CHECKPOINT_TRUSTED_OWNERS: []
1216+
PROCESS_CHECKPOINT_TRUSTED_OWNERS: [],
1217+
PROCESS_CHECKPOINT_PREFERRED_OWNERS: []
12151218
}
12161219
const COLDSTART = {
12171220
src: 'cold_start',
@@ -1287,7 +1290,8 @@ describe('ao-process', () => {
12871290
logger,
12881291
PROCESS_IGNORE_ARWEAVE_CHECKPOINTS: [],
12891292
IGNORE_ARWEAVE_CHECKPOINTS: [],
1290-
PROCESS_CHECKPOINT_TRUSTED_OWNERS: []
1293+
PROCESS_CHECKPOINT_TRUSTED_OWNERS: [],
1294+
PROCESS_CHECKPOINT_PREFERRED_OWNERS: []
12911295
}
12921296

12931297
const findLatestProcessMemory = findLatestProcessMemorySchema.implement(findLatestProcessMemoryWith(deps))
@@ -1324,7 +1328,8 @@ describe('ao-process', () => {
13241328
logger,
13251329
PROCESS_IGNORE_ARWEAVE_CHECKPOINTS: [],
13261330
IGNORE_ARWEAVE_CHECKPOINTS: [],
1327-
PROCESS_CHECKPOINT_TRUSTED_OWNERS: []
1331+
PROCESS_CHECKPOINT_TRUSTED_OWNERS: [],
1332+
PROCESS_CHECKPOINT_PREFERRED_OWNERS: []
13281333
}
13291334

13301335
const findLatestProcessMemory = findLatestProcessMemorySchema.implement(findLatestProcessMemoryWith(deps))
@@ -1364,6 +1369,7 @@ describe('ao-process', () => {
13641369
PROCESS_IGNORE_ARWEAVE_CHECKPOINTS: [],
13651370
IGNORE_ARWEAVE_CHECKPOINTS: [],
13661371
PROCESS_CHECKPOINT_TRUSTED_OWNERS: [],
1372+
PROCESS_CHECKPOINT_PREFERRED_OWNERS: [],
13671373
fileExists: () => true,
13681374
DIR: 'fake/directory/'
13691375
}
@@ -1418,6 +1424,7 @@ describe('ao-process', () => {
14181424
logger,
14191425
PROCESS_IGNORE_ARWEAVE_CHECKPOINTS: [],
14201426
PROCESS_CHECKPOINT_TRUSTED_OWNERS: [],
1427+
PROCESS_CHECKPOINT_PREFERRED_OWNERS: [],
14211428
CHECKPONT_VALIDATION_STEPS: 10,
14221429
CHECKPONT_VALIDATION_RETRIES: 1,
14231430
CHECKPONT_VALIDATION_THRESH: 0.75,

0 commit comments

Comments
 (0)