Skip to content

Commit

Permalink
Quicker prune version by using one sql delete statement
Browse files Browse the repository at this point in the history
Add custom function to be able to get all keys which hold headers
without a proof and delete in one sql statement.

Does not resolve updating of headers with proof.
  • Loading branch information
kdeme committed Feb 7, 2025
1 parent 0bf3a78 commit 8008aef
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 3 deletions.
18 changes: 17 additions & 1 deletion fluffy/database/content_db.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import
results,
eth/db/kvstore,
eth/db/kvstore_sqlite3,
../network/history/[history_content],
../network/history/history_content,
../network/history/content/content_values_deprecated,
../network/wire/[portal_protocol, portal_protocol_config],
./content_db_custom_sql_functions
Expand Down Expand Up @@ -67,6 +67,7 @@ type
deleteOutOfRadiusStmt: SqliteStmt[(array[32, byte], array[32, byte]), void]
largestDistanceStmt: SqliteStmt[array[32, byte], array[32, byte]]
selectAllStmt: SqliteStmt[NoParams, ContentPair]
deleteBatchStmt: SqliteStmt[NoParams, void]

PutResultType* = enum
ContentStored
Expand Down Expand Up @@ -218,6 +219,10 @@ proc new*(
"Custom function isInRadius creation OK"
)

db.createCustomFunction("isWithoutProof", 1, isWithoutProof).expect(
"Custom function isWithoutProof creation OK"
)

let sizeStmt = db.prepareStmt(
"SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size();",
NoParams, int64,
Expand Down Expand Up @@ -257,6 +262,11 @@ proc new*(
let selectAllStmt =
db.prepareStmt("SELECT key, value FROM kvstore", NoParams, ContentPair)[]

let deleteBatchStmt = db.prepareStmt(
"DELETE FROM kvstore WHERE key IN (SELECT key FROM kvstore WHERE isWithoutProof(value) == 1)",
NoParams, void,
)[]

let contentDb = ContentDB(
kv: kvStore,
backend: db,
Expand All @@ -272,6 +282,7 @@ proc new*(
deleteOutOfRadiusStmt: deleteOutOfRadiusStmt,
largestDistanceStmt: largestDistanceStmt,
selectAllStmt: selectAllStmt,
deleteBatchStmt: deleteBatchStmt,
)

contentDb.setInitialRadius(radiusConfig)
Expand Down Expand Up @@ -494,6 +505,11 @@ proc iterateAllAndMigrateHeaderType*(db: ContentDB) =

notice "ContentDB migration done: ", contentAltered, contentDeleted

proc deleteAllHeadersWithoutProof*(db: ContentDB) =
notice "ContentDB migration: deleting all headers without proof"
db.deleteBatchStmt.exec().expectDb()
notice "ContentDB migration done"

proc createGetHandler*(db: ContentDB): DbGetHandler =
return (
proc(contentKey: ContentKeyByteList, contentId: ContentId): Opt[seq[byte]] =
Expand Down
35 changes: 34 additions & 1 deletion fluffy/database/content_db_custom_sql_functions.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@

{.push raises: [].}

import stew/ptrops, stint, sqlite3_abi, eth/db/kvstore_sqlite3
import
stew/ptrops,
stint,
sqlite3_abi,
eth/db/kvstore_sqlite3,
../common/common_types,
../network/history/content/content_values_deprecated

func xorDistance(a: openArray[byte], b: openArray[byte]): seq[byte] =
doAssert(a.len == b.len)
Expand Down Expand Up @@ -66,3 +72,30 @@ func isInRadius*(
ctx.sqlite3_result_int(cint 1)
else:
ctx.sqlite3_result_int(cint 0)

func isWithoutProofImpl(content: openArray[byte]): bool =
let headerWithProof = decodeSsz(content, BlockHeaderWithProofDeprecated).valueOr:
# Leave all other content as it is
return false

if headerWithProof.proof.proofType ==
BlockHeaderProofType.historicalHashesAccumulatorProof:
false
elif headerWithProof.proof.proofType == BlockHeaderProofType.none:
true
else:
false

func isWithoutProof*(
ctx: SqliteContext, n: cint, v: SqliteValue
) {.cdecl, gcsafe, raises: [].} =
doAssert(n == 1)

let
ptrs = makeUncheckedArray(v)
blob1Len = sqlite3_value_bytes(ptrs[][0])

if isWithoutProofImpl(makeOpenArray(sqlite3_value_blob(ptrs[][0]), byte, blob1Len)):
ctx.sqlite3_result_int(cint 1)
else:
ctx.sqlite3_result_int(cint 0)
2 changes: 1 addition & 1 deletion fluffy/portal_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ proc new*(

proc statusLogLoop(n: PortalNode) {.async: (raises: []).} =
try:
n.contentDB.iterateAllAndMigrateHeaderType()
n.contentDB.deleteAllHeadersWithoutProof()
while true:
# This is the data radius percentage compared to full storage. This will
# drop a lot when using the logbase2 scale, namely `/ 2` per 1 logaritmic
Expand Down

0 comments on commit 8008aef

Please sign in to comment.