Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 30 additions & 8 deletions src/db/sql/verification-key-updates/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ export function getVerificationKeyUpdatesQuery(
WHERE parent.chain_status <> 'canonical'
AND child.id <> child.parent_id
),
-- Resolve the requested hash to the set of zkapp_updates rows that SET
-- that verification key, before touching any block. The set is small — one
-- row per distinct update that ever wrote this key — and MATERIALIZED
-- keeps the planner from inlining it back into the join tree, where it
-- would hash the whole of zkapp_updates and zkapp_account_update_body once
-- per query. Measured on a 681k-block devnet archive over the maximum
-- 10 000-block range: 405 ms inlined, 199 ms materialised.
target_updates AS MATERIALIZED (
SELECT zu.id
FROM zkapp_verification_key_hashes vkh
INNER JOIN zkapp_verification_keys vk ON vk.hash_id = vkh.id
INNER JOIN zkapp_updates zu ON zu.verification_key_id = vk.id
WHERE vkh.value = $1
),
full_chain AS (
SELECT b.*
FROM blocks b
Expand All @@ -71,7 +85,7 @@ export function getVerificationKeyUpdatesQuery(
zau.id AS account_update_id,
pk.value AS address,
t.value AS token_id,
vkh.value AS verification_key_hash,
$1::text AS verification_key_hash,
b.state_hash,
b.parent_hash,
b.height,
Expand All @@ -95,21 +109,29 @@ export function getVerificationKeyUpdatesQuery(
INNER JOIN LATERAL UNNEST(zc.zkapp_account_updates_ids)
WITH ORDINALITY AS update_ref(id, position) ON TRUE
INNER JOIN zkapp_account_update zau ON zau.id = update_ref.id
-- An account update SETS a verification key through update_id. The other
-- column that names a verification key on this table,
-- verification_key_hash_id, is the PRECONDITION: the key the update
-- requires the account to already have. Filtering on that one would answer
-- "who called this contract" instead of "who deployed it".
INNER JOIN zkapp_account_update_body zaub ON zaub.id = zau.body_id
INNER JOIN zkapp_updates zu ON zu.id = zaub.update_id
INNER JOIN zkapp_verification_keys vk ON vk.id = zu.verification_key_id
INNER JOIN zkapp_verification_key_hashes vkh ON vkh.id = vk.hash_id
AND zaub.update_id IN (SELECT id FROM target_updates)
INNER JOIN account_identifiers ai ON ai.id = zaub.account_identifier_id
INNER JOIN public_keys pk ON pk.id = ai.public_key_id
INNER JOIN tokens t ON t.id = ai.token_id
WHERE vkh.value = $1
AND bzc.status = 'applied'
WHERE bzc.status = 'applied'
${statusClause}
-- state_hash is what makes this order total. Two competing tips sit at the
-- same height, and pending_chain seeds from every block at the maximum
-- pending height, so both are in the answer. A command carried by both —
-- the normal case during a reorg; one command was measured in 8 blocks at
-- a single height on devnet — then produces rows that agree on height,
-- sequence_no, account-update position and zkapp_account_update.id alike.
ORDER BY
b.height ASC,
b.state_hash ASC,
bzc.sequence_no ASC,
update_ref.position ASC,
zau.id ASC
update_ref.position ASC
`,
params
);
Expand Down
Loading