Skip to content

feat(pdp): add transaction tracking for root additions (synapse branch) #530

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

Merged
merged 5 commits into from
Jun 18, 2025

Conversation

rvagg
Copy link
Member

@rvagg rvagg commented Jun 12, 2025

  • Add Location header to root addition response with tx hash
  • Add GET /proof-sets/{id}/roots/added/{txHash} endpoint for status checks
  • Implement handleGetProofSetRoot for retrieving root details
  • Return confirmed root IDs after transaction confirmation
  • Use lowercase transaction hashes consistently in database operations

rvagg added 2 commits June 12, 2025 13:00
- Add Location header to root addition response with tx hash
- Add GET /proof-sets/{id}/roots/added/{txHash} endpoint for status checks
- Implement handleGetProofSetRoot for retrieving root details
- Return confirmed root IDs after transaction confirmation
@rvagg
Copy link
Member Author

rvagg commented Jun 12, 2025

@LexLuthr this is also probably appropriate for main branch too, let me know if you want me to open it there as well so we have less to reconcile in the future. There may be other things we want to look at where this branch has diverged because we've solved a bunch of problems already that are relevant to the main branch, but we have a few temporary compromises that shouldn't be ported across (like null auth and probably the shorter confirmation time, although shortening it from what it is on main would be good). I'm worried about them getting so out of sync that reconciling later on is going to be hard and I'm happy to help squash and pick things apart if you want.

@aarshkshah1992 would you mind reviewing this please?

rvagg added a commit to FilOzone/synapse-sdk that referenced this pull request Jun 12, 2025
…rification

Ref: filecoin-project/curio#530

- Read new Location header with txHash to root addition responses in Curio handlers
- Implement g endpoint for checking transaction status
- Make verification mandatory for servers that advertise tracking capability
- Add enhanced callbacks (onRootAdded with transaction, onRootConfirmed with IDs)
- Maintain backward compatibility with servers that don't provide tracking
- Add 7-minute timeout for root addition verification process
@rvagg
Copy link
Member Author

rvagg commented Jun 12, 2025

Forgot to mention this is related to this issue: #520 and it will be closed by merging.

rvagg added a commit to FilOzone/synapse-sdk that referenced this pull request Jun 12, 2025
…rification

Ref: filecoin-project/curio#530

- Read new Location header with txHash to root addition responses in Curio handlers
- Implement g endpoint for checking transaction status
- Make verification mandatory for servers that advertise tracking capability
- Add enhanced callbacks (onRootAdded with transaction, onRootConfirmed with IDs)
- Maintain backward compatibility with servers that don't provide tracking
- Add 7-minute timeout for root addition verification process
rvagg added a commit to FilOzone/synapse-sdk that referenced this pull request Jun 12, 2025
…rification

Ref: filecoin-project/curio#530

- Read new Location header with txHash to root addition responses in Curio handlers
- Implement g endpoint for checking transaction status
- Make verification mandatory for servers that advertise tracking capability
- Add enhanced callbacks (onRootAdded with transaction, onRootConfirmed with IDs)
- Maintain backward compatibility with servers that don't provide tracking
- Add 7-minute timeout for root addition verification process
@aarshkshah1992 aarshkshah1992 self-requested a review June 12, 2025 08:04
// Step 4: Query pdp_proofset_root_adds for this transaction
type RootAddInfo struct {
Root string `db:"root"`
AddMessageIndex int `db:"add_message_index"`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is AddMessageIndex ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All quite well documented here actually:

-- proofset root adds - tracking add-root messages which didn't land yet, so don't have a known root_id
CREATE TABLE pdp_proofset_root_adds (
proofset BIGINT NOT NULL, -- pdp_proof_sets.id
root TEXT NOT NULL, -- root cid (piececid v2)
add_message_hash TEXT NOT NULL REFERENCES message_waits_eth(signed_tx_hash) ON DELETE CASCADE,
add_message_ok BOOLEAN, -- set to true when the add message is processed
add_message_index BIGINT NOT NULL, -- index of root in the add message
-- aggregation roots (aggregated like pieces in filecoin sectors)
subroot TEXT NOT NULL, -- subroot cid (piececid v2), with no aggregation this == root
subroot_offset BIGINT NOT NULL, -- offset of the subroot in the root (padded byte offset)
subroot_size BIGINT NOT NULL, -- size of the subroot (padded piece size)
pdp_pieceref BIGINT NOT NULL, -- pdp_piecerefs.id
CONSTRAINT pdp_proofset_root_adds_root_id_unique PRIMARY KEY (proofset, add_message_hash, subroot_offset),
FOREIGN KEY (proofset) REFERENCES pdp_proof_sets(id) ON DELETE CASCADE, -- cascade, if we drop a proofset, we no longer care about the roots
FOREIGN KEY (pdp_pieceref) REFERENCES pdp_piecerefs(id) ON DELETE SET NULL -- sets null on delete so that it's easy to notice and clean up
);

add_message_index BIGINT NOT NULL, -- index of root in the add message

So an "AddRoots" can be multiple roots, and this just gives you an index for that list. I'm not sure how useful that is to the end user, and we already use add_message_index as the ORDER BY, so 🤷 Is this just going to be 0...? I guess so.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm open to not including this on the response btw, I think it's mainly useful for sorting and I think there's an implicit assumption that this will be 0...n in the results anyway that should hole true.

Copy link
Collaborator

@aarshkshah1992 aarshkshah1992 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed

rvagg added a commit to FilOzone/synapse-sdk that referenced this pull request Jun 12, 2025
…rification

Ref: filecoin-project/curio#530

- Read new Location header with txHash to root addition responses in Curio handlers
- Implement g endpoint for checking transaction status
- Make verification mandatory for servers that advertise tracking capability
- Add enhanced callbacks (onRootAdded with transaction, onRootConfirmed with IDs)
- Maintain backward compatibility with servers that don't provide tracking
- Add 7-minute timeout for root addition verification process
@rvagg
Copy link
Member Author

rvagg commented Jun 13, 2025

I added a new commit here after I ran into problems actually using this - the immediate deletion of the record when the tx lands means that querying for it fails. But we don't do this for createproofset so I've now aligned the impl to that:

fix(pdp): retain root addition records to prevent 404s on status queries

Previously, pdp_proofset_root_adds records were deleted after processing,
causing clients to receive 404 errors when querying transaction status
after successful root additions. This created a poor UX as clients couldn't
verify transaction outcomes if they queried too late.

This change aligns root addition tracking with proof set creation by:
- Adding roots_added column to mark processed records instead of deleting
- Updating watcher to UPDATE instead of DELETE when processing completes
- Including roots_added status in API response for client visibility

The fix ensures transaction status remains queryable indefinitely while
maintaining backward compatibility. Existing records will be processed
normally with roots_added=FALSE by default.

API enhancement: /pdp/proof-sets/{id}/roots/added/{txHash} now includes
"rootsAdded" field indicating if roots were fully processed.

Previously, pdp_proofset_root_adds records were deleted after processing,
causing clients to receive 404 errors when querying transaction status
after successful root additions. This created a poor UX as clients couldn't
verify transaction outcomes if they queried too late.

This change aligns root addition tracking with proof set creation by:
- Adding roots_added column to mark processed records instead of deleting
- Updating watcher to UPDATE instead of DELETE when processing completes
- Including roots_added status in API response for client visibility

The fix ensures transaction status remains queryable indefinitely while
maintaining backward compatibility. Existing records will be processed
normally with roots_added=FALSE by default.

API enhancement: /pdp/proof-sets/{id}/roots/added/{txHash} now includes
"rootsAdded" field indicating if roots were fully processed.
Copy link
Collaborator

@aarshkshah1992 aarshkshah1992 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

func (p *PDPService) handleGetRootAdditionStatus(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

// Step 1: Verify that the request is authorized using ECDSA JWT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment misleading since in general its not JWT and its hardcoded to not be JWT right now

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but I'm just following the pattern in the file that exists now:

$ grep 'Verify that the request' pdp/handlers.go 
        // Verify that the request is authorized using ECDSA JWT
        // Step 1: Verify that the request is authorized using ECDSA JWT
        // Step 1: Verify that the request is authorized using ECDSA JWT
        // Step 1: Verify that the request is authorized using ECDSA JWT
        // Step 1: Verify that the request is authorized using ECDSA JWT
        // Step 1: Verify that the request is authorized using ECDSA JWT
        // Step 1: Verify that the request is authorized using ECDSA JWT
        // Step 1: Verify that the request is authorized using ECDSA JWT

Do you want me to remove all of those, or just these new ones?

firstRootsAdded := rootAdds[0].RootsAdded
for _, ra := range rootAdds[1:] {
if ra.RootsAdded != firstRootsAdded {
http.Error(w, "Inconsistent rootsAdded state for this transaction's roots", http.StatusInternalServerError)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not so sure what value we get out of this. It feels like we're testing the consistency model of yugabyte and I don't really care as a user for the purposes of this call. I actually just care about the blockchain consistency model.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar feeling about RootsAdded return value. As user I care about chain and upload commitment and this seems to be some extraneous other bookkeeping.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, your call, Aarsh and I went back and forth on this and I don't think I care. I'll remove the checks and rootsAdded.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, actually no I remember now - we added this new field to the database, roots_added, it's the final check that tells us that Curio has fully processed it and it's onboarded. It's the direct equivalent of proofset_created. SO I need roots_added, it's just a question of whether we're OK trusting that the first row we get from the DB is representative of the whole lot. Perhaps there's a Curio-bug-reason that makes the first one false and the rest true; that's the logic that lead to all the looping and checking. So, your call on this but I'd really like the roots_added from for the SDK

`, proofSetID, rootCids)
if err != nil {
log.Warnf("Failed to query confirmed roots: %v", err)
// Don't fail the request, just log the warning
Copy link
Collaborator

@ZenGround0 ZenGround0 Jun 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whats the rationale on returning anyway with no root IDs? It would be simpler for the client if this were to just fail right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we could be in an in-between state. We get into this branch because add_message_ok is set on the pdp_proofset_root_adds table, but it's set because of a change in transaction status on the message_waits_eth table by the pdp_proofset_add_message_status_change stored procedure. Then, separate to that the WatcherRootAdd task polls pdp_proofset_root_adds to look for these add_message_ok and roots_added status changes and eventually updates pdp_proofset_roots which is what we are reading here.

So there is a moment where rootAdds[0].AddMessageOK is true but this SELECT statement won't return anything because our background task hasn't followed up on it. If we fail at that point then we're telling the user that there's a problem completing the root add, but in reality we're just closing it out and the next time they query it should return everything is 👍 .

Copy link
Collaborator

@ZenGround0 ZenGround0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I like it

http.Error(w, "Invalid proof set ID", http.StatusBadRequest)
ctx := r.Context()

// Step 1: Verify that the request is authorized using ECDSA JWT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: comment

@ZenGround0 ZenGround0 merged commit be1eacb into filecoin-project:synapse Jun 18, 2025
14 of 15 checks passed
@rvagg rvagg deleted the rvagg/addroot-enhanced branch June 19, 2025 00:23
LexLuthr pushed a commit that referenced this pull request Jul 22, 2025
* ServiceAuth and NullAuth (#512)

* ServiceAuth and NullAuth

* fix

---------

Co-authored-by: zenground0 <ZenGround0@users.noreply.github.com>

* Fix/public service sql mig (#516)

* Add sql migration function to enable public service with dummy key

* Fix typo

---------

Co-authored-by: zenground0 <ZenGround0@users.noreply.github.com>

* Tigher busy waiting (#521)

Co-authored-by: zenground0 <ZenGround0@users.noreply.github.com>

* fix (#523)

Co-authored-by: zenground0 <ZenGround0@users.noreply.github.com>

* Look in pdp piecerefs to check for actual readiness (#525)

* Look in pdp piecerefs to check for actual readiness

* fix

---------

Co-authored-by: zenground0 <ZenGround0@users.noreply.github.com>

* YOLO (#526)

Co-authored-by: zenground0 <ZenGround0@users.noreply.github.com>

* Remove unpadding transformation from root size (#529)

Co-authored-by: zenground0 <ZenGround0@users.noreply.github.com>

* feat(pdp): add transaction tracking for root additions (synapse branch) (#530)

* feat(pdp): add transaction tracking for root additions

- Add Location header to root addition response with tx hash
- Add GET /proof-sets/{id}/roots/added/{txHash} endpoint for status checks
- Implement handleGetProofSetRoot for retrieving root details
- Return confirmed root IDs after transaction confirmation

* fix(pdp): use lowercase transaction hashes consistently in database operations

* fix(pdp): retain root addition records to prevent 404s on status queries

Previously, pdp_proofset_root_adds records were deleted after processing,
causing clients to receive 404 errors when querying transaction status
after successful root additions. This created a poor UX as clients couldn't
verify transaction outcomes if they queried too late.

This change aligns root addition tracking with proof set creation by:
- Adding roots_added column to mark processed records instead of deleting
- Updating watcher to UPDATE instead of DELETE when processing completes
- Including roots_added status in API response for client visibility

The fix ensures transaction status remains queryable indefinitely while
maintaining backward compatibility. Existing records will be processed
normally with roots_added=FALSE by default.

API enhancement: /pdp/proof-sets/{id}/roots/added/{txHash} now includes
"rootsAdded" field indicating if roots were fully processed.

* fix(pdp): extra checks to make sure the db entries are consistent

* fix(pdp): address review feedback

* chore(pdp): add more logging; don't bail early on tx error (#549)

* chore(pdp): add transaction processing logging

* chore(pdp): tweak logging statements

* fix(chain): improve chain scheduler robustness and eth tx monitoring (#553)

- Add mutex protection and notification timeout handling to CurioChainSched
- Implement timeout protection for eth client calls to prevent indefinite blocking
- Add comprehensive test coverage for chain scheduler and eth message watcher
- Extract interfaces (EthClient, TaskEngine, EthTransactionManager) for testability

* chore(logs): log proof data as hex (#551)

---------

Co-authored-by: ZenGround0 <5515260+ZenGround0@users.noreply.github.com>
Co-authored-by: zenground0 <ZenGround0@users.noreply.github.com>
Co-authored-by: Rod Vagg <rod@vagg.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants