Skip to content

⚡ Bolt: Optimized Blockchain Integrity Verification#399

Open
RohanExploit wants to merge 1 commit intomainfrom
bolt-optimized-blockchain-verification-12726119415941833147
Open

⚡ Bolt: Optimized Blockchain Integrity Verification#399
RohanExploit wants to merge 1 commit intomainfrom
bolt-optimized-blockchain-verification-12726119415941833147

Conversation

@RohanExploit
Copy link
Owner

@RohanExploit RohanExploit commented Feb 16, 2026

This PR implements a significant performance optimization and integrity improvement for the blockchain-style report verification system.

💡 What: Added a previous_integrity_hash column to the Issue model and updated the verification logic to use this stored hash instead of querying the predecessor record. Also expanded the hash calculation to cover more critical fields (reference_id, latitude, longitude, user_email).

🎯 Why: Previously, verifying a report's integrity required two database queries (one for the current record, one for the predecessor). This added unnecessary latency. By storing the predecessor's hash on the record itself, we achieve O(1) link verification relative to database round-trips.

📊 Impact: Reduces database queries by 50% for integrity verification checks. Improves security coverage of the cryptographic seal.

🔬 Measurement: Verified with tests/test_blockchain.py. Legacy records remain verifiable through a fallback subquery mechanism.


PR created automatically by Jules for task 12726119415941833147 started by @RohanExploit


Summary by cubic

Adds previous_integrity_hash to Issue and updates hashing to include reference_id, latitude, longitude, and user_email. This enables O(1) blockchain verification, cutting integrity-check DB calls from 2 to 1 and improving hash coverage while keeping legacy records valid.

  • Migration
    • Run migrate_db to add previous_integrity_hash to issues (handled in init_db).
    • No backfill needed; new issues populate the column.
    • Legacy records verify via fallback subquery and the old hash format.

Written for commit 9c60e6d. Summary will update on new commits.

- Added `previous_integrity_hash` to `Issue` model to enable O(1) link verification.
- Updated `create_issue` to populate `previous_integrity_hash` and include more fields in the hash for better integrity.
- Optimized `verify_blockchain_integrity` to reduce database queries from 2 to 1.
- Maintained backward compatibility for legacy records.
- Updated tests to reflect the new hash format and verification logic.

Co-authored-by: RohanExploit <178623867+RohanExploit@users.noreply.github.com>
@google-labs-jules
Copy link
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Copilot AI review requested due to automatic review settings February 16, 2026 14:08
@netlify
Copy link

netlify bot commented Feb 16, 2026

Deploy Preview for fixmybharat canceled.

Name Link
🔨 Latest commit 9c60e6d
🔍 Latest deploy log https://app.netlify.com/projects/fixmybharat/deploys/699324c339bb3200086a8a0a

@github-actions
Copy link

🙏 Thank you for your contribution, @RohanExploit!

PR Details:

Quality Checklist:
Please ensure your PR meets the following criteria:

  • Code follows the project's style guidelines
  • Self-review of code completed
  • Code is commented where necessary
  • Documentation updated (if applicable)
  • No new warnings generated
  • Tests added/updated (if applicable)
  • All tests passing locally
  • No breaking changes to existing functionality

Review Process:

  1. Automated checks will run on your code
  2. A maintainer will review your changes
  3. Address any requested changes promptly
  4. Once approved, your PR will be merged! 🎉

Note: The maintainers will monitor code quality and ensure the overall project flow isn't broken.

@coderabbitai
Copy link

coderabbitai bot commented Feb 16, 2026

Warning

Rate limit exceeded

@RohanExploit has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 3 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bolt-optimized-blockchain-verification-12726119415941833147

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 5 files

Copy link
Contributor

Copilot AI left a 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 implements a performance optimization for the blockchain-style integrity verification system by adding a previous_integrity_hash column to store the predecessor's hash directly on each issue record. This reduces database queries from 2 to 1 during verification. The PR also expands the hash calculation to include additional fields (reference_id, latitude, longitude, user_email) for enhanced security coverage.

Changes:

  • Added previous_integrity_hash column to the Issue model with database migration
  • Updated issue creation logic to compute and store blockchain hashes using expanded field set
  • Modified verification endpoint to use stored predecessor hash with legacy fallback for backward compatibility

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
backend/models.py Added previous_integrity_hash column definition to Issue model
backend/init_db.py Added database migration to create previous_integrity_hash column
backend/routers/issues.py Updated issue creation to compute and store hashes with more fields; updated verification to use stored hash with legacy fallback
tests/test_blockchain.py Updated tests to use new hash format with all fields and set previous_integrity_hash on test issues
.jules/bolt.md Added documentation of the optimization pattern and learning
Comments suppressed due to low confidence (2)

tests/test_blockchain.py:69

  • Missing test coverage for the legacy fallback path. The verification logic has a fallback for legacy records where previous_integrity_hash is NULL (lines 641-646 in backend/routers/issues.py), but there's no test case that creates a legacy-format issue and verifies it. Consider adding a test case that creates an Issue with integrity_hash computed using the old format (description|category|prev_hash) and previous_integrity_hash=None, then verifies it successfully validates.
def test_blockchain_verification_success(client, db_session):
    # Create first issue with new hash format and previous_integrity_hash
    ref1 = "ref1"
    hash1_content = f"{ref1}|First issue|Road|None|None|None|"
    hash1 = hashlib.sha256(hash1_content.encode()).hexdigest()

    issue1 = Issue(
        reference_id=ref1,
        description="First issue",
        category="Road",
        integrity_hash=hash1,
        previous_integrity_hash=""
    )
    db_session.add(issue1)
    db_session.commit()
    db_session.refresh(issue1)

    # Create second issue chained to first
    ref2 = "ref2"
    hash2_content = f"{ref2}|Second issue|Garbage|None|None|None|{hash1}"
    hash2 = hashlib.sha256(hash2_content.encode()).hexdigest()

    issue2 = Issue(
        reference_id=ref2,
        description="Second issue",
        category="Garbage",
        integrity_hash=hash2,
        previous_integrity_hash=hash1
    )
    db_session.add(issue2)
    db_session.commit()
    db_session.refresh(issue2)

    # Verify first issue
    response = client.get(f"/api/issues/{issue1.id}/blockchain-verify")
    assert response.status_code == 200
    data = response.json()
    assert data["is_valid"] == True
    assert data["current_hash"] == hash1

    # Verify second issue
    response = client.get(f"/api/issues/{issue2.id}/blockchain-verify")
    assert response.status_code == 200
    data = response.json()
    assert data["is_valid"] == True
    assert data["current_hash"] == hash2

tests/test_blockchain.py:69

  • Consider adding an integration test that creates an issue via the POST /api/issues endpoint and then verifies its blockchain integrity via the GET /api/issues/{id}/blockchain-verify endpoint. This would ensure the end-to-end flow works correctly, including reference_id generation, hash calculation with all the new fields, and previous_integrity_hash storage.
def test_blockchain_verification_success(client, db_session):
    # Create first issue with new hash format and previous_integrity_hash
    ref1 = "ref1"
    hash1_content = f"{ref1}|First issue|Road|None|None|None|"
    hash1 = hashlib.sha256(hash1_content.encode()).hexdigest()

    issue1 = Issue(
        reference_id=ref1,
        description="First issue",
        category="Road",
        integrity_hash=hash1,
        previous_integrity_hash=""
    )
    db_session.add(issue1)
    db_session.commit()
    db_session.refresh(issue1)

    # Create second issue chained to first
    ref2 = "ref2"
    hash2_content = f"{ref2}|Second issue|Garbage|None|None|None|{hash1}"
    hash2 = hashlib.sha256(hash2_content.encode()).hexdigest()

    issue2 = Issue(
        reference_id=ref2,
        description="Second issue",
        category="Garbage",
        integrity_hash=hash2,
        previous_integrity_hash=hash1
    )
    db_session.add(issue2)
    db_session.commit()
    db_session.refresh(issue2)

    # Verify first issue
    response = client.get(f"/api/issues/{issue1.id}/blockchain-verify")
    assert response.status_code == 200
    data = response.json()
    assert data["is_valid"] == True
    assert data["current_hash"] == hash1

    # Verify second issue
    response = client.get(f"/api/issues/{issue2.id}/blockchain-verify")
    assert response.status_code == 200
    data = response.json()
    assert data["is_valid"] == True
    assert data["current_hash"] == hash2

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +27 to +43
hash1_content = f"{ref1}|First issue|Road|None|None|None|"
hash1 = hashlib.sha256(hash1_content.encode()).hexdigest()

issue1 = Issue(
reference_id=ref1,
description="First issue",
category="Road",
integrity_hash=hash1
integrity_hash=hash1,
previous_integrity_hash=""
)
db_session.add(issue1)
db_session.commit()
db_session.refresh(issue1)

# Create second issue chained to first
hash2_content = f"Second issue|Garbage|{hash1}"
ref2 = "ref2"
hash2_content = f"{ref2}|Second issue|Garbage|None|None|None|{hash1}"
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The test uses string literal "None" for null values in the hash (e.g., "None|None|None"), which matches the behavior of f-strings when formatting Python None values. However, this implicit behavior is not documented in the code or test comments. Consider adding a comment explaining that Python's f-string conversion of None to "None" is intentional and expected, or use an explicit conversion function for clarity.

Copilot uses AI. Check for mistakes.
hash_content = f"{description}|{category}|{prev_hash}"
# Bolt: Improved integrity by including more fields in the hash
# Chaining logic: hash(ref_id|description|category|lat|lon|email|prev_hash)
hash_content = f"{ref_id}|{description}|{category}|{latitude}|{longitude}|{user_email}|{prev_hash}"
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

When latitude, longitude, or user_email are None, the f-string will convert them to the string "None" in the hash content. While this is consistent with the test expectations (line 27, 43), it could lead to ambiguity. For example, a user_email of "None" (the string) vs None (the value) would produce the same hash. Consider using a more explicit representation like empty strings or "null" to avoid potential collisions, or add validation to prevent these field values from being the string "None".

Suggested change
hash_content = f"{ref_id}|{description}|{category}|{latitude}|{longitude}|{user_email}|{prev_hash}"
def _normalize_hash_field(value: Any) -> str:
"""Normalize values for hash generation to avoid None -> 'None' ambiguity."""
if value is None:
return "null"
return str(value)
hash_content = "|".join(
[
str(ref_id),
str(description),
str(category),
_normalize_hash_field(latitude),
_normalize_hash_field(longitude),
_normalize_hash_field(user_email),
str(prev_hash),
]
)

Copilot uses AI. Check for mistakes.
hash_content = f"{description}|{category}|{prev_hash}"
# Bolt: Improved integrity by including more fields in the hash
# Chaining logic: hash(ref_id|description|category|lat|lon|email|prev_hash)
hash_content = f"{ref_id}|{description}|{category}|{latitude}|{longitude}|{user_email}|{prev_hash}"
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The hash content uses pipe "|" as a delimiter, but none of the fields are sanitized or escaped. If description, category, or user_email contain pipe characters, it could lead to hash collisions or ambiguity. For example, "A|B" + "C" vs "A" + "B|C" would be indistinguishable. Consider using a delimiter that's guaranteed not to appear in the data, using length-prefixed encoding, or escaping pipe characters in the input fields before hashing.

Copilot uses AI. Check for mistakes.
Comment on lines 175 to 178
prev_issue = await run_in_threadpool(
lambda: db.query(Issue.integrity_hash).order_by(Issue.id.desc()).first()
)
prev_hash = prev_issue[0] if prev_issue and prev_issue[0] else ""
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

There's a potential race condition in the blockchain chain creation. If two requests create issues simultaneously, both might fetch the same previous_integrity_hash (lines 175-178), leading to two issues with the same previous hash - creating a fork in the chain rather than a linear chain. Consider using a database lock or transaction isolation to ensure only one issue can be added to the chain at a time, or implement logic to detect and handle forks in the verification endpoint.

Copilot uses AI. Check for mistakes.
action_plan=None,
integrity_hash=integrity_hash
integrity_hash=integrity_hash,
previous_integrity_hash=prev_hash # Bolt: Store predecessor hash for O(1) verification
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The comment says "O(1) verification" but this is slightly misleading. The verification is O(1) in terms of database queries (1 query vs 2), but the computational complexity is still the same. Consider updating the comment to say "O(1) database queries" or "reduces database queries from 2 to 1" for clarity.

Suggested change
previous_integrity_hash=prev_hash # Bolt: Store predecessor hash for O(1) verification
previous_integrity_hash=prev_hash # Bolt: Store predecessor hash to enable O(1) database lookup during verification

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant