Draft
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Write operations (CreateBucket, DeleteBucket, PutObject, DeleteObject) now return ErrReadOnly immediately when no submitter is wired in. Previously PutObject would silently write to SQLite with no Celestia anchor (height=0, empty commitments), producing orphaned data. ErrReadOnly maps to 405 MethodNotAllowed in the HTTP error handler. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- object.go: escape LIKE wildcards (%, _, \) in ListObjects prefix to prevent unintended pattern matching on user-supplied keys - object.go: populate Object.Namespace from o.ns on read instead of scanning per-row DB value, eliminating stale-config drift - server.go: remove dead handleBucket wrapper, route GET bucket directly to handleListObjects - server.go: clamp max-keys to 1000 per S3 spec - server.go: apply http.MaxBytesReader before reading PUT body so oversized requests are rejected at the network layer, not after buffering the full payload in memory - service.go: detect http.MaxBytesError from MaxBytesReader and map to ErrObjectTooLarge - auth.go: validate X-Amz-Date is within ±15 min to prevent replay attacks with captured signed requests - tests: update to use mockSubmitter for write ops, fix stale hardcoded SigV4 timestamp, add TestService_ReadOnly coverage Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Empty PUTs skip Celestia submission and store locally with Height=0 and no commitments. This is intentional to preserve S3 tool compatibility (e.g. folder placeholder keys like "prefix/"). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Critical fixes: - server.go: parsePath now uses r.URL.RawPath to avoid double-decoding; percent-encoded characters in keys (e.g. %2F) are preserved through path splitting and decoded per-segment - server.go: remove query-param priority over HTTP method in bucket router; DELETE/PUT/HEAD on a bucket with query params now routes correctly instead of falling through to handleListObjects - object.go: wrap DeleteBucket count check and delete in a single transaction to close TOCTOU race where a concurrent write could sneak in between the two separate queries Medium fixes: - object.go: remove redundant GetBucket call from PutObject; the SQLite FK constraint enforces bucket existence and is detected via isSQLiteFKConstraint → ErrBucketNotFound - migrations/005: drop idx_s3_objects_bucket; the composite index on (bucket, key) already covers all bucket-only lookups - service.go: validate bucket names (3-63 chars, lowercase alphanum + hyphen, no leading/trailing hyphen, not an IP address) and key length (max 1024 bytes); new ErrInvalidBucketName and ErrKeyTooLong errors map to 400 in the HTTP layer Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- auth.go: refactor authenticateRequest into focused helpers (parseAuthorizationHeader, validateCredentialScope, validateAmzDate, payloadHashFromRequest) for readability and testability - server.go: additional hardening from review - service.go: minor fix - integration_test.go: expand S3 integration coverage - object.go: additional store hardening - object_test.go: expand ObjectStore test coverage Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Celestia now serves as a verification layer, not storage. PutObject computes SHA256 of the object, builds a ~200-byte CommitmentEnvelope (bucket, key, size, sha256, etag), and submits that JSON to Celestia. Raw object data remains cached in SQLite and served from there. - Add CommitmentEnvelope struct and SHA256 field to Object - Update ObjectStore.PutObject interface to carry sha256 param - Squash migrations 004+005 into single final schema with sha256 column - Update store and all tests for new interface and envelope assertions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Verify X-Amz-Content-Sha256 header matches actual body on PutObject (SigV4 compliance; prevents body substitution after signing) - Handle content-length as canonical header for SigV4 compatibility - Check bucket existence before submitting to Celestia to avoid orphaned on-chain commitments for non-existent buckets - Add readRequestBody helper to buffer+restore body for hash check Co-Authored-By: Claude Sonnet 4.6 <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
PutObjectsubmits a small JSONCommitmentEnvelope(~200 bytes) containing SHA256 + object metadata to Celestia, not raw dataGetObjectserves from the local cache; users can prove data authenticity by hashing a downloaded object and comparing against the on-chain SHA256 recordCreateBucket,DeleteBucket,PutObject,DeleteObject) are blocked with405 Method Not Allowedwhen no Celestia submitter is configured (read-only mode)parsePathusesr.URL.RawPathto avoid double URL-decoding of%2Fin object keysDeleteBucketwrapped in a transaction to prevent TOCTOU race between empty-check and deletemaxObjectSizelimit (2 MB) is independent of Celestia's blob size since only the envelope is submittedsha256column from the start, noAUTOINCREMENToverhead, single composite index)Architecture
CommitmentEnvelope (submitted to Celestia)
{ "version": 1, "bucket": "my-bucket", "key": "path/to/file.txt", "content_type": "text/plain", "size": 1234, "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "etag": "d41d8cd98f00b204e9800998ecf8427e" }Test plan
just testpasses with-raceobj.SHA256non-empty →sha256sumof downloaded body matches405 Method Not Allowed413 Request Entity Too Large400 Bad RequestTestService_PutObject_WithSubmitterverifies submitted blob is aCommitmentEnvelope, not raw dataTestObjectStore_ObjectCRUDverifies SHA256 round-trips through SQLite🤖 Generated with Claude Code