Skip to content
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

feat: make blocktracker aware of block hashes #400

Merged
merged 6 commits into from
Jan 10, 2025

Conversation

fbac
Copy link
Collaborator

@fbac fbac commented Jan 8, 2025

Changelog

  • Make blockTracker aware of block hashes. This is the first step to enhance the indexer.
  • Minor format fixes.

Summary by CodeRabbit

Based on the comprehensive summary, here are the updated release notes:

  • New Features

    • Enhanced block tracking with block hash support across multiple components.
    • Added new utility functions for generating and converting block hashes.
  • Improvements

    • Updated database schema to include block hash tracking.
    • Standardized error message capitalization across various packages.
    • Refined block indexing and tracking mechanisms.
  • Chores

    • Updated configuration files for local network contracts.
    • Modified mock interfaces to support new block tracking functionality.

@fbac fbac requested a review from a team as a code owner January 8, 2025 18:46
Copy link

coderabbitai bot commented Jan 8, 2025

Warning

Rate limit exceeded

@fbac has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 18 minutes and 24 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.

📥 Commits

Reviewing files that changed from the base of the PR and between b14e1de and 7af3d16.

📒 Files selected for processing (3)
  • .gitignore (1 hunks)
  • pkg/indexer/blockTracker_test.go (6 hunks)
  • pkg/testutils/blockchain.go (1 hunks)

Walkthrough

This pull request introduces changes across multiple files to enhance block tracking and logging functionality. Key modifications include adding block hash support in database and indexing operations, updating configuration files for local network contracts, and standardizing error message formatting. The changes encompass database migrations, indexer logic, and test utilities, focusing on improving the precision and clarity of block-related operations.

Changes

File Change Summary
.gitignore Added contracts/config/anvil_localnet/ to ignored directories
contracts/config/anvil_localnet/GroupMessages.json Updated contract implementation and proxy addresses, reset deployment and upgrade block numbers
contracts/config/anvil_localnet/IdentityUpdates.json Updated contract implementation and proxy addresses, reset deployment and upgrade block numbers
pkg/db/queries.sql, pkg/db/queries/models.go, pkg/db/queries/queries.sql.go Added block_hash column to latest_block table and related structs
pkg/indexer/blockTracker.go Introduced Block struct, modified block tracking logic to include block hash
pkg/migrations/00003_add-latest-block.up.sql Added block_hash column to latest_block table schema
pkg/testutils/blockchain.go, pkg/testutils/random.go Added utility functions for hash generation and conversion
pkg/blockchain/registryAdmin.go, pkg/blockchain/signer.go, pkg/sync/syncWorker.go Standardized error message formatting by changing capitalization
pkg/indexer/indexer.go, pkg/indexer/interface.go, pkg/indexer/blockTracker_test.go, pkg/indexer/indexer_test.go, pkg/mocks/indexer/mock_IBlockTracker.go Updated method signatures and logic to incorporate block hash

Suggested reviewers

  • neekolas

Possibly related PRs


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
pkg/testutils/blockchain.go (1)

9-11: Add function documentation.

Consider adding a doc comment explaining the purpose and use case of this utility function. This would help other developers understand when to use this conversion function versus other hash generation utilities.

+// IntToHash converts an int64 to a common.Hash, useful for generating deterministic test hashes
 func IntToHash(x int64) common.Hash {
pkg/indexer/interface.go (1)

10-12: Consider consolidating block retrieval methods

To ensure atomic retrieval of the latest block data and prevent potential mismatches between the block number and hash, consider providing a single method that returns a Block struct containing both values.

Apply this diff to update the interface:

 type IBlockTracker interface {
-	GetLatestBlockNumber() uint64
-	GetLatestBlockHash() common.Hash
+	GetLatestBlock() *Block
 	UpdateLatestBlock(ctx context.Context, block uint64, hash common.Hash) error
 }

This change promotes consistency and simplifies the interface by encapsulating block data within a single method.

pkg/indexer/blockTracker_test.go (1)

87-91: Consider using a helper function for block updates in concurrent tests.

The block update code is repeated across multiple goroutines. Consider extracting it into a helper function for better maintainability.

+func updateBlock(ctx context.Context, t *testing.T, tracker *BlockTracker, blockNum uint64) {
+    err := tracker.UpdateLatestBlock(
+        ctx,
+        blockNum,
+        testutils.IntToHash(int64(blockNum))
+    )
+    require.NoError(t, err)
+}
pkg/indexer/indexer.go (1)

59-60: Minor: Consider removing trailing comma

The trailing comma after the validationService parameter, while valid, is inconsistent with Go's common style.

-	validationService mlsvalidate.MLSValidationService,
+	validationService mlsvalidate.MLSValidationService
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3356985 and 32558dd.

📒 Files selected for processing (18)
  • .gitignore (1 hunks)
  • contracts/config/anvil_localnet/GroupMessages.json (1 hunks)
  • contracts/config/anvil_localnet/IdentityUpdates.json (1 hunks)
  • pkg/blockchain/registryAdmin.go (1 hunks)
  • pkg/blockchain/signer.go (2 hunks)
  • pkg/db/queries.sql (1 hunks)
  • pkg/db/queries/models.go (1 hunks)
  • pkg/db/queries/queries.sql.go (2 hunks)
  • pkg/indexer/blockTracker.go (3 hunks)
  • pkg/indexer/blockTracker_test.go (5 hunks)
  • pkg/indexer/indexer.go (4 hunks)
  • pkg/indexer/indexer_test.go (1 hunks)
  • pkg/indexer/interface.go (1 hunks)
  • pkg/migrations/00003_add-latest-block.up.sql (1 hunks)
  • pkg/mocks/indexer/mock_IBlockTracker.go (5 hunks)
  • pkg/sync/syncWorker.go (3 hunks)
  • pkg/testutils/blockchain.go (1 hunks)
  • pkg/testutils/random.go (1 hunks)
✅ Files skipped from review due to trivial changes (4)
  • .gitignore
  • pkg/blockchain/registryAdmin.go
  • pkg/blockchain/signer.go
  • pkg/sync/syncWorker.go
🔇 Additional comments (15)
pkg/testutils/random.go (1)

66-69: Implementation looks good!

The function follows the established pattern of other random generators in this file. While the implementation is similar to RandomLogTopic, having a separate function provides better semantic clarity for tests specifically dealing with block hashes.

contracts/config/anvil_localnet/GroupMessages.json (2)

8-9: Consider implications of starting from block 0.

Setting both deploymentBlock and latestUpgradeBlock to 0 means the system will track from the genesis block. While this ensures no historical data is missed, verify if this aligns with the PR's objective of making blocktracker aware of block hashes.

Consider:

  1. Performance implications of tracking from block 0
  2. Whether historical data before the contract deployment is relevant
  3. If this change is temporary for testing purposes

4-5: Verify contract addresses match local network deployment.

The new addresses (0x5FbDB2315678... and 0xe7f1725E7734...) appear to be deterministic addresses commonly used in local Hardhat/Anvil networks. This is consistent with the file's location in the anvil_localnet directory.

✅ Verification successful

Contract addresses are valid and consistent with local network configuration.

The addresses follow Hardhat/Anvil's deterministic deployment pattern, with proper separation between contracts and consistent use of deployer/admin addresses across configurations. The configuration is correctly isolated to the local network environment.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify consistency of contract addresses across local network configs
# Look for any mismatches in contract addresses that might indicate inconsistent deployments

# Search for these addresses in other config files
echo "Checking for contract address consistency across config files:"
rg -l "0x5FbDB2315678afecb367f032d93F642f64180aa3|0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" contracts/config/

Length of output: 299


Script:

#!/bin/bash
# Find all JSON files in the config directory
echo "All JSON configuration files:"
fd -e json . contracts/config/

# Check if there are any other files mentioning "localnet" that might need updates
echo -e "\nFiles containing 'localnet':"
rg -l "localnet" contracts/config/

Length of output: 319


Script:

#!/bin/bash
# Check the content of both JSON files
echo "Content of GroupMessages.json:"
cat contracts/config/anvil_localnet/GroupMessages.json

echo -e "\nContent of IdentityUpdates.json:"
cat contracts/config/anvil_localnet/IdentityUpdates.json

Length of output: 1014

pkg/db/queries/queries.sql.go (2)

80-97: Verify database schema alignment with new queries

The GetLatestBlock function and the GetLatestBlockRow struct now include block_hash. Ensure that the database schema and migrations have been updated to include the block_hash column in the latest_block table.


389-405: Consistency in generated code and source SQL files

Changes in the generated queries.sql.go file reflect modifications in the SQL queries. Ensure that these changes originate from updates in the source SQL files and that the code generator (sqlc) is rerun to maintain consistency.

pkg/db/queries/models.go (1)

30-30: LGTM! Verify the corresponding SQL schema changes.

The addition of BlockHash []byte field to the LatestBlock struct is appropriate for storing block hashes.

Run this script to verify the corresponding SQL schema changes:

✅ Verification successful

Schema implementation verified and correct

The block_hash column is properly defined in the SQL schema:

  • Table creation with block_hash BYTEA NOT NULL
  • Appropriate CRUD operations in place
  • Consistent with the Go struct implementation
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the SQL schema changes for the block_hash column
# Expected: Find ALTER TABLE or CREATE TABLE statements adding block_hash column

rg -g "*.sql" "block_hash.*latest_block" 

Length of output: 42


Script:

#!/bin/bash
# Find all SQL files and their content
fd -e sql -x cat {}

Length of output: 6661

pkg/indexer/indexer_test.go (1)

22-24: LGTM! Test changes align with the new block hash functionality.

The initialization of newBlockHash and its usage in the mock expectations are appropriate.

Also applies to: 28-28

pkg/indexer/blockTracker_test.go (2)

38-45: LGTM! Comprehensive test coverage for block updates.

The test properly verifies both block number and hash updates, including the case where a higher block number is updated.


128-134: LGTM! Proper test isolation for multiple contract addresses.

The test correctly verifies that different contract addresses maintain separate block numbers and hashes.

pkg/mocks/indexer/mock_IBlockTracker.go (1)

26-44: LGTM! Mock implementation properly handles block hash functionality.

The mock implementation correctly handles the new block hash functionality with proper error checking for missing return values.

pkg/indexer/indexer.go (2)

150-150: Method rename reflects clearer intent

Good change! Renaming from GetLatestBlock to GetLatestBlockNumber better describes what the method returns.

Also applies to: 167-167


215-217: Verify error handling for block hash updates

The error from UpdateLatestBlock is logged but not propagated. Consider if this error should trigger a retry of the entire event processing.

✅ Verification successful

Current error handling is appropriate

The BlockTracker is a progress tracking mechanism where errors are non-fatal and shouldn't halt event processing. The current approach of logging errors is sufficient because:

  • Database errors or invalid hashes are infrastructure issues that wouldn't be resolved by retrying
  • Failed updates don't affect the integrity of already processed events
  • Errors are properly logged for monitoring and debugging purposes
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if there are any other places in the codebase where block tracker errors are handled differently
rg -A 3 "UpdateLatestBlock.*error" 

Length of output: 1165


Script:

#!/bin/bash
# Find implementation of UpdateLatestBlock
ast-grep --pattern 'func $_($_ *$_) UpdateLatestBlock(ctx context.Context, block uint64, hash common.Hash) error {
  $$$
}'

# Find all usages of UpdateLatestBlock
rg -B 3 -A 3 "UpdateLatestBlock\(ctx,"

Length of output: 2638


Script:

#!/bin/bash
# Find the BlockTracker implementation
fd blockTracker.go --exec cat {}

Length of output: 2709

pkg/migrations/00003_add-latest-block.up.sql (1)

3-4: Verify migration strategy for existing data

Adding a NOT NULL column to an existing table requires consideration of:

  1. How existing rows will be populated with block hashes
  2. Whether a corresponding down migration exists
  3. The deployment strategy to avoid breaking production
✅ Verification successful

Migration strategy is properly implemented

The NOT NULL constraints are safe as this is a new table creation rather than an alteration of an existing table. The down migration is also properly implemented with table drop.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for corresponding down migration
fd --type f "00003.*down.sql"

# Check if this is the latest migration
fd --type f "0000[4-9].*up.sql"

Length of output: 112


Script:

#!/bin/bash
# Check content of both migration files
echo "=== UP Migration ==="
cat pkg/migrations/00003_add-latest-block.up.sql
echo -e "\n=== DOWN Migration ==="
cat pkg/migrations/00003_add-latest-block.down.sql

Length of output: 385

contracts/config/anvil_localnet/IdentityUpdates.json (1)

4-5: LGTM: Local environment configuration updates

The changes to contract addresses and block numbers are specific to the local development environment (anvil_localnet).

Also applies to: 8-9

pkg/db/queries.sql (1)

117-118: LGTM: Consistent with schema changes

The SELECT query has been properly updated to include the new block_hash column.

pkg/indexer/blockTracker.go Outdated Show resolved Hide resolved
pkg/db/queries.sql Show resolved Hide resolved
@fbac fbac force-pushed the feat/store-block-number-and-hashes branch from 32558dd to 03a7564 Compare January 8, 2025 19:51
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
pkg/indexer/blockTracker.go (2)

28-31: Consider consistent synchronization approach for Block struct fields.

The Block struct uses atomic operations for number but relies on the parent's mutex for hash. This split approach could be confusing and error-prone. Consider either:

  1. Using the mutex for both fields
  2. Making the hash field atomic using atomic.Value
 type Block struct {
-	number atomic.Uint64
-	hash   common.Hash
+	mu     sync.RWMutex
+	number uint64
+	hash   common.Hash
 }

108-111: Improve Block initialization and error message.

Consider these improvements:

  1. Use composite literal for Block initialization
  2. Make the error message more descriptive by including the actual value
-	block := &Block{
-		number: atomic.Uint64{},
-		hash:   common.Hash{},
-	}
+	block := new(Block)

-		return block, fmt.Errorf(
-			"invalid block number %d for contract %s",
-			latestBlock.BlockNumber,
-			contractAddress,
-		)
+		return block, fmt.Errorf(
+			"expected non-negative block number but got %d for contract %s",
+			latestBlock.BlockNumber,
+			contractAddress,
+		)

Also applies to: 121-126

pkg/indexer/blockTracker_test.go (2)

38-45: Add test cases for hash validation and concurrent access.

Consider adding these test cases:

  1. Test invalid (empty) hash validation
  2. Test concurrent access to block hash

Example test case for invalid hash:

func TestUpdateLatestBlockWithInvalidHash(t *testing.T) {
    // ... setup code ...
    
    err = tracker.UpdateLatestBlock(ctx, 100, common.Hash{})
    require.Error(t, err)
    require.Contains(t, err.Error(), "invalid block hash")
}

87-91: Enhance concurrent update testing.

Consider these improvements to make the test more robust:

  1. Use different hash values instead of deriving from block number
  2. Add intermediate assertions during concurrent updates
-				err := tracker.UpdateLatestBlock(
-					ctx,
-					blockNum,
-					testutils.IntToHash(int64(blockNum)),
-				)
+				hash := testutils.RandomHash() // Add this helper
+				err := tracker.UpdateLatestBlock(ctx, blockNum, hash)
+				require.NoError(t, err)
+				
+				// Add intermediate verification
+				currentNum := tracker.GetLatestBlockNumber()
+				require.GreaterOrEqual(t, currentNum, blockNum)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32558dd and 03a7564.

📒 Files selected for processing (18)
  • .gitignore (1 hunks)
  • contracts/config/anvil_localnet/GroupMessages.json (1 hunks)
  • contracts/config/anvil_localnet/IdentityUpdates.json (1 hunks)
  • pkg/blockchain/registryAdmin.go (1 hunks)
  • pkg/blockchain/signer.go (2 hunks)
  • pkg/db/queries.sql (1 hunks)
  • pkg/db/queries/models.go (1 hunks)
  • pkg/db/queries/queries.sql.go (2 hunks)
  • pkg/indexer/blockTracker.go (3 hunks)
  • pkg/indexer/blockTracker_test.go (5 hunks)
  • pkg/indexer/indexer.go (4 hunks)
  • pkg/indexer/indexer_test.go (1 hunks)
  • pkg/indexer/interface.go (1 hunks)
  • pkg/migrations/00003_add-latest-block.up.sql (1 hunks)
  • pkg/mocks/indexer/mock_IBlockTracker.go (5 hunks)
  • pkg/sync/syncWorker.go (3 hunks)
  • pkg/testutils/blockchain.go (1 hunks)
  • pkg/testutils/random.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (14)
  • pkg/testutils/blockchain.go
  • pkg/db/queries/models.go
  • pkg/testutils/random.go
  • pkg/blockchain/signer.go
  • pkg/migrations/00003_add-latest-block.up.sql
  • pkg/indexer/indexer_test.go
  • pkg/indexer/interface.go
  • pkg/sync/syncWorker.go
  • contracts/config/anvil_localnet/GroupMessages.json
  • .gitignore
  • pkg/db/queries.sql
  • pkg/blockchain/registryAdmin.go
  • pkg/indexer/indexer.go
  • contracts/config/anvil_localnet/IdentityUpdates.json
🔇 Additional comments (4)
pkg/db/queries/queries.sql.go (2)

80-97: LGTM! Well-structured changes to support block hash tracking.

The addition of block hash tracking is implemented correctly with proper types and error handling.


399-407: LGTM! Clean implementation of block hash parameter handling.

The parameter struct and function changes are implemented correctly with proper error handling.

pkg/indexer/blockTracker.go (1)

57-61: LGTM! Thread-safe implementation.

The implementation correctly uses mutex synchronization for accessing the hash field, addressing the potential data race concern.

pkg/mocks/indexer/mock_IBlockTracker.go (1)

26-71: LGTM! Auto-generated mock implementation.

The mock implementation correctly reflects the interface changes for the new hash-aware block tracker.

pkg/db/queries/queries.sql.go Show resolved Hide resolved
pkg/indexer/blockTracker.go Outdated Show resolved Hide resolved
@fbac fbac force-pushed the feat/store-block-number-and-hashes branch from 03a7564 to e293c0d Compare January 8, 2025 20:05
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (3)
pkg/db/queries/queries.sql.go (2)

80-97: ⚠️ Potential issue

Add block hash validation to prevent reorg vulnerabilities

The query needs additional validation to handle chain reorganizations properly. Currently, it only retrieves the block hash without validating it against the previous state.

Consider modifying the query to:

  1. Compare block hashes when block numbers match
  2. Validate block parent hash for consistency
 SELECT
 	block_number,
 	block_hash
 FROM
 	latest_block
 WHERE
-	contract_address = $1
+	contract_address = $1
+	AND (
+		-- Allow higher block numbers
+		block_number > (SELECT block_number FROM latest_block WHERE contract_address = $1)
+		OR
+		-- For same block number, ensure hash matches to detect reorgs
+		(block_number = (SELECT block_number FROM latest_block WHERE contract_address = $1)
+		 AND block_hash = (SELECT block_hash FROM latest_block WHERE contract_address = $1))
+	)

389-405: ⚠️ Potential issue

Enhance block validation in SetLatestBlock query

The current WHERE clause only checks if the new block number is higher, which is insufficient for proper chain reorganization handling. This could allow blocks from a different chain fork to be inserted if they have higher numbers.

Consider enhancing the validation:

 INSERT INTO latest_block(contract_address, block_number, block_hash)
 	VALUES ($1, $2, $3)
 ON CONFLICT (contract_address)
 	DO UPDATE SET
 		block_number = $2, block_hash = $3
 	WHERE
-		$2 > latest_block.block_number
+		(
+			-- Allow higher blocks
+			$2 > latest_block.block_number
+			OR
+			-- For same height blocks, ensure hash matches to detect reorgs
+			($2 = latest_block.block_number AND $3 = latest_block.block_hash)
+		)
pkg/indexer/blockTracker.go (1)

81-89: ⚠️ Potential issue

Fix validation order in UpdateLatestBlock.

The hash validation happens after the DB update. If the hash is invalid, the DB would already be updated with an invalid state.

Move the validation before the DB update:

+	hashBytes := common.Hash(hash)
+	if hashBytes == (common.Hash{}) {
+		return fmt.Errorf("invalid block hash %s", hashBytes.String())
+	}
+
 	if err := bt.updateDB(ctx, block, hash); err != nil {
 		return err
 	}
-
-	hashBytes := common.Hash(hash)
-
-	if hashBytes == (common.Hash{}) {
-		return fmt.Errorf("invalid block hash %s", hashBytes.String())
-	}
🧹 Nitpick comments (3)
pkg/db/queries/queries.sql.go (1)

Line range hint 80-405: Consider enhancing chain reorganization handling

While adding block hash awareness is a good first step, the current design might not fully handle complex chain reorganization scenarios. Consider these architectural improvements:

  1. Maintain a block history table to track parent-child relationships
  2. Store a configurable number of recent blocks to handle deep reorgs
  3. Add ability to detect and recover from chain splits by reverting to the last common ancestor

Example schema for block history:

CREATE TABLE block_history (
    contract_address TEXT NOT NULL,
    block_number BIGINT NOT NULL,
    block_hash BYTEA NOT NULL,
    parent_hash BYTEA NOT NULL,
    is_canonical BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    PRIMARY KEY (contract_address, block_number, block_hash)
);
pkg/indexer/blockTracker.go (2)

28-31: LGTM! Good encapsulation of block-related data.

The new Block struct provides good encapsulation of block-related data with thread-safe operations on the block number.

Consider adding a comment to document that the hash field must be accessed under the BlockTracker.mu lock:

 type Block struct {
 	number atomic.Uint64
+	// hash must be accessed under BlockTracker.mu lock
 	hash   common.Hash
 }

109-134: Consider simplifying the Block initialization.

The implementation is correct, but the Block initialization could be more concise.

Consider this simpler initialization:

-	block := &Block{
-		number: atomic.Uint64{},
-		hash:   common.Hash{},
-	}
+	block := new(Block)

The zero value of atomic.Uint64 and common.Hash is already what we want.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 03a7564 and e293c0d.

📒 Files selected for processing (19)
  • .gitignore (1 hunks)
  • contracts/config/anvil_localnet/GroupMessages.json (1 hunks)
  • contracts/config/anvil_localnet/IdentityUpdates.json (1 hunks)
  • pkg/blockchain/registryAdmin.go (1 hunks)
  • pkg/blockchain/registryAdmin_test.go (1 hunks)
  • pkg/blockchain/signer.go (2 hunks)
  • pkg/db/queries.sql (1 hunks)
  • pkg/db/queries/models.go (1 hunks)
  • pkg/db/queries/queries.sql.go (2 hunks)
  • pkg/indexer/blockTracker.go (3 hunks)
  • pkg/indexer/blockTracker_test.go (5 hunks)
  • pkg/indexer/indexer.go (4 hunks)
  • pkg/indexer/indexer_test.go (1 hunks)
  • pkg/indexer/interface.go (1 hunks)
  • pkg/migrations/00003_add-latest-block.up.sql (1 hunks)
  • pkg/mocks/indexer/mock_IBlockTracker.go (4 hunks)
  • pkg/sync/syncWorker.go (3 hunks)
  • pkg/testutils/blockchain.go (1 hunks)
  • pkg/testutils/random.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (14)
  • .gitignore
  • pkg/blockchain/registryAdmin.go
  • pkg/testutils/random.go
  • pkg/testutils/blockchain.go
  • pkg/db/queries/models.go
  • pkg/migrations/00003_add-latest-block.up.sql
  • pkg/blockchain/signer.go
  • pkg/indexer/indexer_test.go
  • pkg/db/queries.sql
  • pkg/indexer/interface.go
  • contracts/config/anvil_localnet/GroupMessages.json
  • pkg/sync/syncWorker.go
  • pkg/indexer/indexer.go
  • contracts/config/anvil_localnet/IdentityUpdates.json
🔇 Additional comments (5)
pkg/blockchain/registryAdmin_test.go (1)

58-58: LGTM! Error message standardization.

The error message update aligns with the project-wide standardization of error messages (lowercase format) and provides better context.

Let's verify that this matches the actual error message in the implementation:

✅ Verification successful

✅ Error message verification successful

The error message in the test correctly matches the implementation in registryAdmin.go, where it's used to validate owner addresses.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the corresponding error message in the implementation
rg -l "invalid owner address provided" --type go

Length of output: 119


Script:

#!/bin/bash
# Get the context of the error message in the implementation
rg "invalid owner address provided" pkg/blockchain/registryAdmin.go -B 2 -A 2

Length of output: 191

pkg/indexer/blockTracker.go (2)

57-61: LGTM! Thread-safe implementation.

The method correctly acquires the mutex lock to safely access the hash field, addressing potential data race concerns.


97-102: LGTM! Clean DB update implementation.

The method correctly updates both block number and hash in the database.

pkg/indexer/blockTracker_test.go (1)

38-63: LGTM! Comprehensive test coverage.

The tests thoroughly verify both block number and hash updates, including:

  • Edge cases (lower/same block numbers)
  • Persistence verification
  • Concurrent updates
  • Multiple contract addresses

Also applies to: 87-91, 101-104, 138-141, 149-152

pkg/mocks/indexer/mock_IBlockTracker.go (1)

24-69: LGTM! Correctly generated mock implementation.

The mock implementation correctly reflects the interface changes with proper method signatures and type handling.

Also applies to: 71-89, 116-126, 142-144

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
pkg/indexer/blockTracker.go (2)

67-101: Well-structured update logic with proper validations!

Good improvements:

  • Double-check pattern for thread safety
  • Hash validation before DB update
  • Empty hash validation using custom error

Consider adding a comment explaining the double-check pattern for future maintainers.

 	// Quick check without lock
 	if block <= bt.latestBlock.number.Load() {
 		return nil
 	}
+
+	// Double-check pattern: re-verify after acquiring lock to prevent unnecessary DB updates
 	bt.mu.Lock()
 	defer bt.mu.Unlock()

116-142: Good implementation of block loading logic!

Consider wrapping the negative block number error with a custom error type for better error handling across the package.

+// ErrInvalidBlockNumber indicates that a negative block number was encountered
+var ErrInvalidBlockNumber = errors.New("invalid block number")

 func loadLatestBlock(...) (*Block, error) {
 	// ...
 	if latestBlock.BlockNumber < 0 {
-		return block, fmt.Errorf(
-			"invalid block number %d for contract %s",
-			latestBlock.BlockNumber,
-			contractAddress,
-		)
+		return block, fmt.Errorf("%w: %d for contract %s",
+			ErrInvalidBlockNumber,
+			latestBlock.BlockNumber,
+			contractAddress)
 	}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e293c0d and 792bfc7.

📒 Files selected for processing (2)
  • pkg/db/queries.sql (1 hunks)
  • pkg/indexer/blockTracker.go (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Test (Node)
  • GitHub Check: Lint-Go
🔇 Additional comments (5)
pkg/indexer/blockTracker.go (3)

28-35: Well-structured Block type and error definition!

Good use of atomic.Uint64 for thread-safe block number access and common.Hash for standardized hash representation.


57-64: Clean implementation of getter methods!

Good thread-safety practices:

  • Using atomic operations for block number
  • Proper mutex protection for hash access

105-110: Clean DB update implementation!

Correctly handles the new block hash parameter in the database update.

pkg/db/queries.sql (2)

107-114: Robust block update logic with reorg detection!

Good improvements:

  • Added block hash tracking
  • Update condition prevents unnecessary updates
  • Hash inequality check helps detect potential chain reorganizations

117-119: Clean SELECT query update!

Correctly retrieves both block number and hash to support the enhanced block tracking functionality.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
pkg/indexer/blockTracker.go (1)

63-99: Consider optimizing the hash comparison logic.

The function has good validation checks but could be optimized by moving the hash comparison before acquiring the mutex lock.

 func (bt *BlockTracker) UpdateLatestBlock(
 	ctx context.Context,
 	block uint64,
 	hashBytes []byte,
 ) error {
+	newHash := common.Hash(hashBytes)
+	if newHash == (common.Hash{}) {
+		return ErrEmptyBlockHash
+	}
+
 	// Quick check without lock
 	if block <= bt.latestBlock.number.Load() {
 		return nil
 	}
 
 	bt.mu.Lock()
 	defer bt.mu.Unlock()
 
 	// Re-check after acquiring lock
 	if block <= bt.latestBlock.number.Load() {
 		return nil
 	}
 
-	newHash := common.Hash(hashBytes)
-
-	if newHash == (common.Hash{}) {
-		return ErrEmptyBlockHash
-	}
-
 	if newHash == bt.latestBlock.hash {
 		return nil
 	}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 792bfc7 and b14e1de.

📒 Files selected for processing (7)
  • pkg/db/queries.sql (1 hunks)
  • pkg/db/queries/queries.sql.go (2 hunks)
  • pkg/indexer/blockTracker.go (3 hunks)
  • pkg/indexer/blockTracker_test.go (6 hunks)
  • pkg/indexer/indexer.go (4 hunks)
  • pkg/indexer/interface.go (1 hunks)
  • pkg/mocks/indexer/mock_IBlockTracker.go (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • pkg/indexer/interface.go
  • pkg/indexer/blockTracker_test.go
  • pkg/indexer/indexer.go
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Lint-Go
  • GitHub Check: Test (Node)
🔇 Additional comments (8)
pkg/indexer/blockTracker.go (4)

28-31: LGTM! Good encapsulation of block data.

The Block struct provides a clean encapsulation of block data with proper use of atomic operations for the block number.


33-35: LGTM! Clear error definition.

The error variable is well-defined and follows Go's error handling conventions.


57-60: LGTM! Thread-safe implementation.

The GetLatestBlock method correctly uses mutex synchronization to prevent data races.


113-138: LGTM! Proper initialization and error handling.

The loadLatestBlock function properly initializes the Block struct and handles potential errors.

pkg/db/queries.sql (2)

107-114: LGTM! Proper block hash handling with reorg protection.

The query correctly handles block hash updates and includes protection against chain reorganizations by validating both block number and hash.


118-119: LGTM! Complete block data retrieval.

The query retrieves both block number and hash, providing complete block information.

pkg/mocks/indexer/mock_IBlockTracker.go (1)

Line range hint 25-138: LGTM! Auto-generated mock implementation.

The mock implementation correctly reflects the interface changes.

pkg/db/queries/queries.sql.go (1)

Line range hint 80-406: LGTM! Auto-generated database access code.

The generated code correctly implements the SQL queries with proper type handling.

"github.com/ethereum/go-ethereum/common"
)

func IntToHash(x int64) common.Hash {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe Int64ToHash in case we need other functions for other types of ints?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Makes sense, renamed in the last commit.

@fbac fbac merged commit 235c2be into main Jan 10, 2025
6 of 7 checks passed
@fbac fbac deleted the feat/store-block-number-and-hashes branch January 10, 2025 16:29
@coderabbitai coderabbitai bot mentioned this pull request Jan 23, 2025
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.

2 participants