-
Notifications
You must be signed in to change notification settings - Fork 0
feat: update insertBlockInfo to return proper status #235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Rayane Charif <rayane.charif@gonative.cc>
Reviewer's GuideRefactors CFStorage.insertBlockInfo to return a typed InsertBlockResult describing whether a block write was inserted, updated, or skipped, wires this result through the Indexer, optimizes the underlying D1 operations with a batched existence check + upsert, and updates tests and types accordingly. Sequence diagram for Indexer.processBlock using InsertBlockResultsequenceDiagram
actor Node
participant Indexer
participant Storage
participant CFStorage
participant D1
participant Logger
Node->>Indexer: processBlock(blockInfo, rawBlockBuffer)
Indexer->>Storage: insertBlockInfo(blockInfo)
activate Storage
Storage->>CFStorage: insertBlockInfo(blockInfo)
activate CFStorage
CFStorage->>D1: batch([checkRowStmt, insertStmt])
D1-->>CFStorage: [checkResult, upsertResult]
CFStorage-->>Storage: InsertBlockResult(status, changed)
deactivate CFStorage
Storage-->>Indexer: InsertBlockResult(status, changed)
deactivate Storage
alt result.changed is false
Indexer->>Logger: debug(msg=Skipping block, status=result.status)
Indexer-->>Node: return
else result.changed is true
Indexer->>Logger: debug(msg=Processing block, status=result.status)
Indexer-->>Node: continue processing
end
Class diagram for updated Storage, CFStorage, Indexer, and InsertBlockResultclassDiagram
class BlockQueueRecord
class BtcNet
class InsertBlockResult {
<<type_alias>>
+status
+changed
}
class Storage {
<<interface>>
+markBlockAsProcessed(hash, network BtcNet) Promise~void~
+insertBlockInfo(blockMessage BlockQueueRecord) Promise~InsertBlockResult~
+getLatestBlockHeight(network BtcNet) Promise~number_or_null~
+getChainTip(network BtcNet) Promise~number_or_null~
+setChainTip(height, network BtcNet) Promise~void~
}
class CFStorage {
+d1
+insertBlockInfo(b BlockQueueRecord) Promise~InsertBlockResult~
}
class Indexer {
+storage Storage
+processBlock(blockInfo BlockQueueRecord, rawBlockBuffer) Promise~void~
}
Storage <|.. CFStorage
Indexer --> Storage : uses
Indexer --> InsertBlockResult : consumes
CFStorage --> InsertBlockResult : produces
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey - I've found 1 issue, and left some high level feedback:
- Since you already rely on the upsert’s
meta.changes, you can likely avoid the separateSELECT+ race-prone existence check and instead deriveinserted/updated/skippedfrom a singleINSERT ... ON CONFLICT ... RETURNING(if supported) or from the upsert result alone, which would simplify the logic and make it more robust under concurrency. - When throwing
new Error("Batch operation failed"), consider including which part of the batch failed (e.g., missing check vs upsert result and relevant block identifiers) to make operational debugging of storage issues easier.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Since you already rely on the upsert’s `meta.changes`, you can likely avoid the separate `SELECT` + race-prone existence check and instead derive `inserted/updated/skipped` from a single `INSERT ... ON CONFLICT ... RETURNING` (if supported) or from the upsert result alone, which would simplify the logic and make it more robust under concurrency.
- When throwing `new Error("Batch operation failed")`, consider including which part of the batch failed (e.g., missing check vs upsert result and relevant block identifiers) to make operational debugging of storage issues easier.
## Individual Comments
### Comment 1
<location> `packages/btcindexer/src/cf-storage.ts:94-97` </location>
<code_context>
+ throw new Error("Batch operation failed");
+ }
+
+ const wasFound = checkResult.results.length > 0;
+ const rowsChanged = upsertResult.meta.changes > 0;
+
+ if (!wasFound) {
+ return { status: "inserted", changed: true };
+ } else if (rowsChanged) {
</code_context>
<issue_to_address>
**issue (bug_risk):** The status inference can be incorrect under races where another writer inserts between the check and upsert.
This assumes `wasFound === false` means we inserted a new row. With concurrent writers, a race can occur: we run `SELECT 1` and see no row, another writer inserts the same `(height, network)`, and then our `INSERT ... ON CONFLICT DO UPDATE` actually executes an `UPDATE`. In that case `wasFound` is `false` but we updated, not inserted. Consider deriving the status from something that reflects the actual DML path (e.g., additional `meta` info or a single consolidated statement), or at least treating the `!wasFound && rowsChanged` case specially.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR enhances the block storage API by replacing boolean return values with a structured InsertBlockResult type that clearly indicates whether a block was inserted, updated, or skipped. This improvement provides better observability and more informative logging throughout the indexer.
Key Changes:
- Introduced
InsertBlockResultdiscriminated union type with three states: "inserted", "updated", and "skipped" - Modified
CFStorage.insertBlockInfoto returnInsertBlockResultand use batched queries to determine the operation outcome - Updated indexer logging to leverage the detailed status information
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| packages/btcindexer/src/models.ts | Added InsertBlockResult type definition as a discriminated union |
| packages/btcindexer/src/storage.ts | Updated Storage interface to return InsertBlockResult instead of boolean |
| packages/btcindexer/src/cf-storage.ts | Implemented batched query approach with pre-check SELECT to determine insert vs. update status |
| packages/btcindexer/src/btcindexer.ts | Updated block processing to use InsertBlockResult and improved skip logging |
| packages/btcindexer/src/storage.test.ts | Updated test assertions to validate structured result objects |
| packages/btcindexer/src/btcindexer.test.ts | Updated stale block protection tests to assert on structured results |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Rayane Charif <rayane.charif@gonative.cc>
Signed-off-by: Rayane Charif <rayane.charif@gonative.cc>
Signed-off-by: Rayane Charif <rayane.charif@gonative.cc>
Description
Closes: #214
Summary by Sourcery
Return structured insert status from block storage writes and propagate it through the indexer.
New Features:
Enhancements:
Tests: