feat: merkle batch payment support for large uploads - #2
Merged
Conversation
Drop UNIQUE(upload_id, tag_key) constraint to support multi-value tags
(e.g. multiple authors, multiple categories per document). Change tag
type from map[string]string to map[string][]string throughout services,
handlers, webhooks, and tests. Upload endpoint accepts both legacy
single-value {"key":"val"} and new {"key":["v1","v2"]} JSON formats.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Each Open(sqlite://:memory:) now creates a uniquely-named shared-cache DB (file:memdbN?mode=memory&cache=shared). This ensures all connections from the same pool see the same database (fixing 401s from webhook goroutines hitting empty DBs), while separate test cases each get their own isolated instance. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds automatic merkle batch payment handling for uploads with >= 64 chunks. The antd daemon now returns payment_type "merkle" for large files, and Indelible branches on this to use the gas-efficient payForMerkleTree() contract call instead of per-quote payForQuotes(). Changes: - internal/evm/abi.go: payForMerkleTree ABI, MerklePaymentMade event, MerklePoolCommitment and MerkleCandidateNode structs - internal/evm/signer.go: PayForMerkleTree() method with event parsing to extract winner_pool_hash, refactored sendTxWithReceipt() - internal/worker/upload.go: Branch on PreparedUpload.PaymentType, skip gas fee check for merkle (cost determined on-chain), unified transaction logging for both payment types The switching is fully automatic — antd decides based on chunk count and Indelible follows the payment_type in the prepare response. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
payment_type: "merkle"for large files — Indelible reads this and uses the gas-efficientpayForMerkleTree()contract callChanges
internal/evm/abi.go—payForMerkleTreeABI +MerklePaymentMadeevent +MerklePoolCommitment/MerkleCandidateNodestructsinternal/evm/signer.go—PayForMerkleTree()method: converts SDK types to ABI structs, ensures token allowance, submits tx, parseswinnerPoolHashfrom event logs. RefactoredsendTxWithReceipt()shared by both payment methodsinternal/worker/upload.go— Branches onPaymentType: merkle usesPayForMerkleTree+FinalizeMerkleUpload, wave_batch uses existingPayForQuotes+FinalizeUpload. Gas fee check skipped for merkle (cost determined on-chain). Transaction logging unifiedDepends on
Test plan
go build ./...— compiles cleango test ./...— all existing tests pass🤖 Generated with Claude Code