-
Notifications
You must be signed in to change notification settings - Fork 39
Start indexing at custom block height #827
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
Conversation
|
""" WalkthroughThis change refactors Changes
Sequence Diagram(s)sequenceDiagram
participant RpcLogStreamer
participant ContractConfig
participant BlockchainNode
participant SubscriptionChannel
participant Logger
RpcLogStreamer->>ContractConfig: Initialize watcher with Address and eventChannel
RpcLogStreamer->>BlockchainNode: Backfill logs in pages until highest block considering unsafe reorg distance
RpcLogStreamer-->>Logger: Log backfill progress and fromBlock
RpcLogStreamer->>SubscriptionChannel: Build subscription channel with exponential backoff retries
SubscriptionChannel->>BlockchainNode: Subscribe to live logs via websocket
RpcLogStreamer->>SubscriptionChannel: Receive live logs and send to eventChannel
Possibly related PRs
Suggested labels
Suggested reviewers
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (1.64.8)Error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🧰 Additional context used🧠 Learnings (2)📓 Common learningspkg/blockchain/rpcLogStreamer.go (1)⏰ Context from checks skipped due to timeout of 90000ms (5)
🔇 Additional comments (8)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. |
There was a problem hiding this 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 (1)
pkg/indexer/common/block_tracker.go (1)
140-148: Persist the “bootstrap” block to avoid repeated RPC hitsWhen no DB row exists you fetch the
startBlockfrom the chain but do not insert it into the database.
Every newBlockTrackerfor the same address will therefore query the RPC node again untilUpdateLatestBlockis called elsewhere.Consider persisting immediately:
if err != nil && errors.Is(err, sql.ErrNoRows) { onchainBlock, err := client.BlockByNumber(ctx, big.NewInt(int64(startBlock))) if err != nil { return nil, err } + if err := querier.SetLatestBlock(ctx, queries.SetLatestBlockParams{ + ContractAddress: address.Hex(), + BlockNumber: int64(onchainBlock.NumberU64()), + BlockHash: onchainBlock.Hash().Bytes(), + }); err != nil { + return nil, err + } block.save(onchainBlock.NumberU64(), onchainBlock.Hash().Bytes()) return block, nil }This prevents unnecessary RPC traffic and keeps all instances in sync.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
pkg/blockchain/rpcLogStreamer.go(1 hunks)pkg/config/options.go(1 hunks)pkg/indexer/app_chain/app_chain.go(6 hunks)pkg/indexer/app_chain/contracts/group_message.go(2 hunks)pkg/indexer/app_chain/contracts/identity_update.go(2 hunks)pkg/indexer/common/block_tracker.go(4 hunks)pkg/indexer/common/block_tracker_test.go(6 hunks)pkg/indexer/common/log_handler.go(4 hunks)
🧰 Additional context used
🧠 Learnings (1)
pkg/indexer/common/block_tracker.go (1)
Learnt from: fbac
PR: xmtp/xmtpd#800
File: pkg/indexer/app_chain/app_chain.go:70-71
Timestamp: 2025-05-19T09:19:00.735Z
Learning: The `GetLatestBlock()` method in `BlockTracker` returns `(uint64, []byte)` representing the latest block number and hash, with no error return. It defaults to returning 0 for the block number when no block has been stored yet, as it maintains values in an in-memory cache.
🪛 GitHub Check: Lint-Go
pkg/indexer/common/block_tracker_test.go
[failure] 10-10:
"github.com/stretchr/testify/assert" imported and not used (typecheck)
🪛 GitHub Actions: Lint
pkg/indexer/common/block_tracker_test.go
[error] 10-10: "github.com/stretchr/testify/assert" imported and not used (typecheck)
⏰ Context from checks skipped due to timeout of 90000ms (5)
- GitHub Check: Push Docker Images to GitHub Packages (xmtpd-cli)
- GitHub Check: Push Docker Images to GitHub Packages (xmtpd)
- GitHub Check: Upgrade Tests
- GitHub Check: Test (Node)
- GitHub Check: Code Review
🔇 Additional comments (9)
pkg/blockchain/rpcLogStreamer.go (2)
138-142: Code refactoring improves readability.Organizing related variable declarations into a single
varblock improves code organization and readability.
148-148: Good addition of startup logging.Adding this log statement provides better visibility into the watcher's initialization, making it easier to track when watchers start and their initial block numbers.
pkg/indexer/common/log_handler.go (2)
152-152: Added blockNumber to enhance error tracking.Adding the block number parameter to the retry function signature is an important enhancement that will help with debugging and tracing errors.
185-188: Improved error logging with block context.Including the block number in error logs provides essential context for troubleshooting issues, especially during retries in blockchain processing.
pkg/indexer/app_chain/contracts/group_message.go (2)
39-39: Added support for custom start block.Adding the
startBlockparameter enables specifying a custom starting block for the group message broadcaster, supporting the PR's main objective.
47-52: Updated NewBlockTracker call with client and startBlock.The modified call passes the required parameters to initialize the block tracker with a specific start block, appropriately utilizing the new parameter.
pkg/indexer/app_chain/contracts/identity_update.go (2)
42-42: Added support for custom start block.Adding the
startBlockparameter enables specifying a custom starting block for the identity update broadcaster, supporting the PR's main objective.
51-57: Updated NewBlockTracker call with client and startBlock.The modified call passes the required parameters to initialize the block tracker with a specific start block, appropriately utilizing the new parameter.
pkg/config/options.go (1)
34-41: Validate zero-value default for new start-block flagsAdding
GroupMessageBroadcasterStartBlockandIdentityUpdateBroadcasterStartBlockwith a default of0makes “genesis” the implicit start point. That is fine, but if the intent was “use the latest on-chain head when unset”, callers must remember to translate a0into “fetch latest”. Please double-check downstream assumptions (e.g.block_tracker.goalways fetchesstartBlockeven when zero).
Replace HTTP RPC connections with WebSocket subscriptions and add configurable start block heights for blockchain event indexingThis pull request replaces HTTP-based blockchain connections with WebSocket subscriptions for real-time event monitoring and adds configurable start block heights for contract event indexing. The changes include: • WebSocket Migration: Updates 📍Where to StartStart with the Macroscope summarized 66a6b70. |
|
what's the motivation behind this? Why would we want to NOT index from 0? |
| GroupMessageBroadcasterAddress string `long:"group-message-broadcaster-address" env:"XMTPD_APP_CHAIN_GROUP_MESSAGE_BROADCAST_ADDRESS" description:"Group message broadcaster contract address"` | ||
| GroupMessageBroadcasterStartBlock uint64 `long:"group-message-broadcaster-start-block" env:"XMTPD_APP_CHAIN_GROUP_MESSAGE_BROADCAST_START_BLOCK" description:"Start block for the group message broadcaster" default:"0"` | ||
| IdentityUpdateBroadcasterAddress string `long:"identity-update-broadcaster-address" env:"XMTPD_APP_CHAIN_IDENTITY_UPDATE_BROADCAST_ADDRESS" description:"Identity update broadcaster contract address"` | ||
| IdentityUpdateBroadcasterStartBlock uint64 `long:"identity-update-broadcaster-start-block" env:"XMTPD_APP_CHAIN_IDENTITY_UPDATE_BROADCAST_START_BLOCK" description:"Start block for the identity update broadcaster" default:"0"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do we expect these block numbers to come from? It seems like the only sensible input would be the block numbers our contract was deployed at. I'd expect that would come from some deployment artifact JSON rather than an environment variable or command line arg.
Or is the idea that the deployment artifact would make its way into the environment variables somehow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO ideally it's the deployment artifact setting those. I left this as an open implementation intentionally to modify it later, when the deployment artifact implementation is finished.
We never want to index from 0. We only want to index from the block where the contract was deployed. |
|
Ah that makes sense! I guess its an optimization and if it is not set, it is should be safe. |
seems to be per chain. If you want it per contract, you should synch with @deluca-mike and the contracts repo |
This is per environment. A file like this can be obtained for anvil/local, testing, staging, and prod, and should be made available for each release in the |
### Implement WebSocket subscription support in RpcLogStreamer to enable real-time event indexing * High Impact: Adds WebSocket subscription capabilities to `RpcLogStreamer` in [rpcLogStreamer.go](https://github.com/xmtp/xmtpd/pull/828/files#diff-7c09882fdc2ca1e5719483f613a8646adbf3750ccba69267c09948639d406ebd) with exponential backoff reconnection logic and implements dual-channel event handling in [log_handler.go](https://github.com/xmtp/xmtpd/pull/828/files#diff-a31c080b060abb8bd9dfa4d6092255d7f851497acd426d985f03ee9c70389d3c) * Medium Impact: Introduces WebSocket URL configuration and validation in [options.go](https://github.com/xmtp/xmtpd/pull/828/files#diff-6731fb6f709392ce3e37d3b0c42074cddbce566dad2bab86af24ba7585eeb57c) and [validation.go](https://github.com/xmtp/xmtpd/pull/828/files#diff-3e0b3707cc5d712d06d1eeb6a67c10b45a7ba0b27e972924d71df3c8e539f23b) * Low Impact: Updates test configurations and environment variables across multiple files to use WebSocket protocol instead of HTTP #### 📍Where to Start Start with the `RpcLogStreamer` implementation in [rpcLogStreamer.go](https://github.com/xmtp/xmtpd/pull/828/files#diff-7c09882fdc2ca1e5719483f613a8646adbf3750ccba69267c09948639d406ebd) which contains the core WebSocket subscription logic and handles both backfill and subscription channels. ---- _[Macroscope](https://app.macroscope.com) summarized a3b5dc4._ <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added support for real-time subscription-based log streaming alongside existing backfill mechanisms, enabling near real-time event processing. - Introduced dedicated subscription channels for contract event handling and log indexing. - Added WebSocket URL fields to configuration with deprecation notices for HTTP URLs. - **Refactor** - Unified event streaming into a single event channel per contract with robust subscription management including retry and backoff. - Updated event handling to use separate channels for event and reorg notifications with improved context cancellation and channel management. - Standardized naming conventions and improved logging for contract configuration fields. - Reorganized test setups to accommodate dual log channels and structured test state. - Enhanced log indexing to handle reorg events with clearer control flow and metrics emission. - **Bug Fixes** - Improved validation for blockchain connection URLs by actively testing WebSocket connectivity. - **Chores** - Updated environment and test configurations to use WebSocket URLs instead of HTTP for blockchain connections. - Declared the WebSocket package as a direct dependency. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
pkg/indexer/settlement_chain/settlement_chain.go (1)
56-81: 💡 Verification agent🧩 Analysis chain
Verify start block validation for contract initialization.
The start block parameters are passed directly to the constructors without visible validation. Ensure that invalid start blocks (e.g., blocks that haven't been mined yet) are properly handled either here or in the respective constructors.
🏁 Script executed:
#!/bin/bash # Description: Check if start block validation exists in the PayerRegistry and PayerReportManager constructors # Search for validation logic in the constructors ast-grep --pattern 'func NewPayerRegistry($$$) { $$$ }' ast-grep --pattern 'func NewPayerReportManager($$$) { $$$ }' # Check for any validation of start blocks rg -A 10 "startBlock|StartBlock" pkg/indexer/settlement_chain/contracts/Length of output: 3576
Validate startBlock in both contract constructors
Neither NewPayerRegistry nor NewPayerReportManager checks that the provided startBlock is ≤ the chain’s current head. Passing a future block will cause the block tracker to error at runtime. Add explicit validation of
startBlockbefore initializing the tracker and return a clear error if it’s out of range.Locations to update:
- pkg/indexer/settlement_chain/contracts/payer_registry.go → func NewPayerRegistry
- pkg/indexer/settlement_chain/contracts/payer_report_manager.go → func NewPayerReportManager
Suggested diff inside each constructor, before calling c.NewBlockTracker(..., startBlock):
+ // ensure the start block isn’t ahead of the chain + latest, err := client.BlockNumber(ctx) + if err != nil { + return nil, fmt.Errorf("failed to fetch latest block: %w", err) + } + if startBlock > latest { + return nil, fmt.Errorf("startBlock %d is greater than latest block %d", startBlock, latest) + }Also add or update unit tests to cover an out-of-range startBlock.
♻️ Duplicate comments (4)
pkg/config/validation.go (1)
259-259:⚠️ Potential issueFix potential nil pointer dereference in connection cleanup.
The unguarded call to
conn.Close()can result in a nil pointer dereference if the dial fails andconnis nil.Apply this fix to prevent potential panics:
- _ = conn.Close() + if conn != nil { + _ = conn.Close() + }pkg/config/options.go (1)
43-45: Document the source and purpose of start block configurations.As discussed in previous reviews, these start blocks should ideally come from deployment artifacts. Until that implementation is complete, consider:
- Adding comments explaining that these represent contract deployment blocks
- Documenting that 0 means "start from the beginning" vs actual deployment block
- Adding validation to ensure start blocks don't exceed the current chain height
Also applies to: 62-64
pkg/blockchain/rpcLogStreamer.go (2)
166-167:⚠️ Potential issueCritical: Implement log buffering to prevent potential log loss.
As noted in the retrieved learnings, the log buffer implementation is planned for a subsequent PR. However, without buffering, there's a risk of losing logs during the transition from backfill to subscription mode. The TODOs indicate awareness of this issue.
Consider implementing at least a basic buffer to prevent log loss, even if the full implementation comes later.
Also applies to: 233-234
271-275:⚠️ Potential issueReturn actual highestBlock value instead of 0.
When
fromBlock > highestBlock, the function returns 0 forhighestBlockwhich could cause issues with downstream logic like reorg distance calculations.- return []types.Log{}, nil, 0, nil + return []types.Log{}, nil, highestBlock, nil
🧹 Nitpick comments (6)
cmd/cli/cli_test.go (1)
13-13: Consider updating variable name to reflect WebSocket protocol.The variable
httpAddressnow contains a WebSocket URL (ws://localhost:8545), which creates a naming inconsistency. Consider renaming towsAddressorrpcAddressto better reflect the actual protocol being used.- httpAddress := "ws://localhost:8545" + wsAddress := "ws://localhost:8545"Also consider whether the CLI flag name
--http-addressshould be updated to reflect that it now expects WebSocket URLs, or if the flag should accept both HTTP and WebSocket URLs for backward compatibility.pkg/server/server_test.go (1)
45-45: LGTM! Consider field naming consistency.The change to WebSocket URL is correct and consistent with the broader migration to WebSocket-based RPC connections.
Note that the field name
RpcURLnow contains a WebSocket URL, which might be confusing. If this field name is part of the configuration struct inpkg/config/options.go, consider whether it should be renamed toWssURLor similar to better reflect the protocol change.dev/local.env (1)
12-12: LGTM! Consider backward compatibility and naming.The change to WebSocket URL is correct and aligns with the WebSocket migration across the codebase. This change affects multiple downstream variables (lines 15-16, 31) which is appropriate.
Consider the following improvements:
Naming consistency: The variable
RPC_URLnow specifically contains a WebSocket URL. Consider renaming toWSS_URLor documenting thatRPC_URLspecifically refers to WebSocket URLs.Backward compatibility: If external systems or documentation reference this as an HTTP URL, ensure they are updated accordingly.
-# Local Anvil container RPC URL. Default to 7545, as it's the port exposed by docker-compose. +# Local Anvil container WebSocket RPC URL. Default to 7545, as it's the port exposed by docker-compose.pkg/config/options.go (1)
35-38: Consider adding migration timeline and validation for WssURL.While the deprecation approach allows gradual migration, having both RpcURL and WssURL could cause confusion. Consider:
- Adding a clear timeline for when RpcURL will be removed
- Implementing validation for WssURL alongside RpcURL validation
- Logging warnings when RpcURL is used
Also applies to: 49-52
pkg/blockchain/rpcLogStreamer.go (2)
21-25: Consider making timing constants configurable per chain.Different chains have different block times and characteristics. Consider making these values configurable through
RpcLogStreamerOptionto allow tuning per chain:
backfillBlocks: Different chains may handle different batch sizessleepTimeOnError/sleepTimeNoLogs: Faster chains might benefit from shorter sleep times
406-436: Consider consolidating filter query builders to reduce duplication.The two filter query builder functions have significant overlap. Consider refactoring to reduce duplication:
-func buildFilterQuery( - contractConfig ContractConfig, - fromBlock uint64, - toBlock uint64, -) ethereum.FilterQuery { - addresses := []common.Address{contractConfig.Address} - topics := [][]common.Hash{} - for _, topic := range contractConfig.Topics { - topics = append(topics, []common.Hash{topic}) - } - - return ethereum.FilterQuery{ - FromBlock: new(big.Int).SetUint64(fromBlock), - ToBlock: new(big.Int).SetUint64(toBlock), - Addresses: addresses, - Topics: topics, - } -} - -func buildSubscriptionFilterQuery(cfg ContractConfig) ethereum.FilterQuery { - addresses := []common.Address{cfg.Address} - topics := [][]common.Hash{} - for _, topic := range cfg.Topics { - topics = append(topics, []common.Hash{topic}) - } - - return ethereum.FilterQuery{ - Addresses: addresses, - Topics: topics, - } -} +func buildBaseFilterQuery(cfg ContractConfig) ethereum.FilterQuery { + addresses := []common.Address{cfg.Address} + topics := [][]common.Hash{} + for _, topic := range cfg.Topics { + topics = append(topics, []common.Hash{topic}) + } + + return ethereum.FilterQuery{ + Addresses: addresses, + Topics: topics, + } +} + +func buildFilterQuery( + contractConfig ContractConfig, + fromBlock uint64, + toBlock uint64, +) ethereum.FilterQuery { + query := buildBaseFilterQuery(contractConfig) + query.FromBlock = new(big.Int).SetUint64(fromBlock) + query.ToBlock = new(big.Int).SetUint64(toBlock) + return query +} + +func buildSubscriptionFilterQuery(cfg ContractConfig) ethereum.FilterQuery { + return buildBaseFilterQuery(cfg) +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
cmd/cli/cli_test.go(1 hunks)dev/local.env(1 hunks)go.mod(1 hunks)pkg/blockchain/rpcLogStreamer.go(8 hunks)pkg/blockchain/rpcLogStreamer_test.go(2 hunks)pkg/config/options.go(1 hunks)pkg/config/validation.go(4 hunks)pkg/indexer/app_chain/app_chain.go(8 hunks)pkg/indexer/common/log_handler.go(2 hunks)pkg/indexer/common/log_handler_test.go(5 hunks)pkg/indexer/settlement_chain/contracts/payer_registry.go(2 hunks)pkg/indexer/settlement_chain/contracts/payer_report_manager.go(2 hunks)pkg/indexer/settlement_chain/settlement_chain.go(4 hunks)pkg/server/server_test.go(1 hunks)pkg/testutils/anvil/anvil.go(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- go.mod
🚧 Files skipped from review as they are similar to previous changes (2)
- pkg/indexer/app_chain/app_chain.go
- pkg/indexer/common/log_handler.go
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: fbac
PR: xmtp/xmtpd#828
File: pkg/blockchain/rpcLogStreamer.go:0-0
Timestamp: 2025-05-22T11:22:58.453Z
Learning: The log buffer for RpcLogStreamer will be implemented in a subsequent PR with a minimum size equal to lagFromHighestBlock to prevent potential log loss during transition from backfill to subscription mode.
pkg/blockchain/rpcLogStreamer.go (1)
Learnt from: fbac
PR: xmtp/xmtpd#800
File: pkg/blockchain/rpcLogStreamer.go:0-0
Timestamp: 2025-05-19T09:45:00.127Z
Learning: In the blockchain RpcLogStreamer implementation, backfillChannel and reorgChannel are meant to be internal implementation details that are managed by the streamer itself, not provided by external callers. This is why they are maintained as unexported fields with getter methods for access.
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: Test (Node)
- GitHub Check: Upgrade Tests
- GitHub Check: Code Review
🔇 Additional comments (14)
pkg/testutils/anvil/anvil.go (1)
103-103:Details
❓ Verification inconclusive
LGTM! Verify blockchain client WebSocket support.
The change to WebSocket URL format is correct and aligns with the broader migration to WebSocket-based RPC connections.
Please verify that
blockchain.NewClient()properly supports WebSocket URLs by running this verification:
🏁 Script executed:
#!/bin/bash # Description: Verify blockchain.NewClient supports WebSocket URLs # Expected: Function should handle both ws:// and http:// schemes ast-grep --pattern 'func NewClient($_, $url $_) { $$$ }' # Also check if there are any URL scheme validations rg -A 5 -B 5 "ws://" pkg/blockchain/Length of output: 97
I’ll locate and inspect the
NewClientimplementation and any related dialing logic to confirm WebSocket support.
🏁 Script executed:
#!/bin/bash # Locate and inspect NewClient in pkg/blockchain grep -R "func NewClient" -n pkg/blockchain | while IFS=: read -r file line _; do echo "=== $file:$line ===" sed -n "$((line-5)),$((line+50))p" "$file" done # Search for underlying dial calls that handle URL schemes grep -R "Dial(" -n pkg/blockchainLength of output: 1433
Confirm WebSocket support in
ethclient.DialContextI’ve located your
NewClientimplementation— it simply delegates to:func NewClient(ctx context.Context, rpcUrl string) (*ethclient.Client, error) { return ethclient.DialContext(ctx, rpcUrl) }Since DialContext is part of go-ethereum’s RPC package, it should inherently handle
ws:///wss://schemes. Please verify against the version of go-ethereum you’re importing thatethclient.DialContextindeed accepts and negotiates WebSocket URLs.pkg/blockchain/rpcLogStreamer_test.go (2)
46-46: LGTM: Struct field rename aligned with API changes.The rename from
ContractAddresstoAddressinContractConfigis consistent with the broader API refactoring.
59-59: LGTM: Test updated for new method signature.The test correctly adapts to the updated
GetNextPagemethod that now accepts a context parameter and returns an additional highest block number value.pkg/indexer/settlement_chain/contracts/payer_registry.go (2)
43-43: LGTM: Start block parameter added for configurable indexing.The addition of
startBlock uint64parameter enables starting contract event indexing from a specified block height, which aligns with the PR objectives for optimization.
50-56: LGTM: Block tracker initialization updated with client and start block.The explicit passing of
clientandstartBlocktoNewBlockTrackercorrectly implements the enhanced block tracking functionality that can initialize from on-chain data when no DB record exists.pkg/config/validation.go (2)
10-10: LGTM: Gorilla WebSocket dependency added for validation.The addition of the Gorilla WebSocket package supports the new WebSocket URL validation functionality.
117-122: LGTM: Enhanced validation with WebSocket connectivity checks.The replacement of simple field presence validation with active WebSocket connection validation ensures URLs are reachable before use, which improves configuration reliability.
Also applies to: 150-155
pkg/indexer/settlement_chain/contracts/payer_report_manager.go (2)
41-41: LGTM: Start block parameter added for configurable indexing.The addition of
startBlock uint64parameter enables starting contract event indexing from a specified block height, consistent with the system-wide enhancement for optimized indexing.
48-54: LGTM: Block tracker initialization updated with client and start block.The explicit passing of
clientandstartBlocktoNewBlockTrackercorrectly implements the enhanced block tracking functionality, consistent with similar changes inPayerRegistry.pkg/indexer/settlement_chain/settlement_chain.go (1)
95-112: LGTM! Consistent field naming across the codebase.The renaming from
ContractAddresstoAddressis consistent with the refactoring in other files and improves code clarity.pkg/config/options.go (1)
34-65: Well-structured configuration with clear separation of concerns.The separation of AppChainOptions and SettlementChainOptions provides good modularity and makes the configuration intent clear.
pkg/indexer/common/log_handler_test.go (1)
22-55: Excellent test refactoring for improved maintainability.The
logHandlerTeststruct provides better encapsulation and ensures consistent setup across tests. The proper cleanup of channels and context in defer blocks prevents resource leaks.pkg/blockchain/rpcLogStreamer.go (2)
29-36: LGTM! Consistent naming improvements.The field renaming improves clarity and consistency across the codebase. The channel buffer sizes are appropriate for event streaming.
Also applies to: 70-75
301-384: Excellent implementation of subscription with automatic retry.The subscription handling with exponential backoff provides robust recovery from temporary connection issues. The use of
MaxDisconnectTimeas a circuit breaker is a good pattern.
327e181 to
66a6b70
Compare
Add custom start block configuration for contract event indexing to enable indexing from specified block heights
Introduces configuration options and implementation for custom start block heights in contract event indexing. Key changes include:
GroupMessageBroadcasterStartBlockandIdentityUpdateBroadcasterStartBlockconfiguration options in options.goBlockTrackerinitialization in block_tracker.go to support starting from specified block numbersGroupMessageBroadcasterandIdentityUpdateBroadcasterin group_message.go and identity_update.go to accept start block parameters📍Where to Start
Start with the configuration changes in options.go to understand the new start block parameters, then review the
BlockTrackermodifications in block_tracker.go which implements the core functionality.Macroscope summarized f96b584.
Summary by CodeRabbit
New Features
Improvements
Bug Fixes
Tests