Cancel agreements when indexers accept on-chain after rejecting off-chain#561
Merged
Conversation
… cancellation Port battle-tested RPC client patterns from rewards-eligibility-oracle to Rust for sending on-chain transactions. This enables the Dipper to call cancelIndexingAgreementByPayer on the SubgraphService contract when indexers fail to accept proposals. Implementation: - RPC provider pool with automatic failover and rotation - Exponential backoff retry (1s, 2s, 4s... capped at 30s) - Gas estimation with safety bounds (floor/ceiling/buffer) - Nonce management with conflict detection and refresh - EIP-1559 gas pricing with configurable multiplier and cap - Conditional dispatch: AlloyChainClient when enabled, StubChainClient otherwise Configuration (disabled by default): - chain_client.enabled, providers, chain_id, subgraph_service_address - Gas tuning: gas_price_multiplier, max_gas_price_gwei, gas_buffer_multiplier, gas_floor Closes #560 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…red timeout - Fix critical ABI mismatch: cancelIndexingAgreementByPayer takes bytes16 not bytes32 (verified against SubgraphServiceExtension.sol) - Encode agreement ID as FixedBytes<16> directly instead of padding to 32 - Add .from(signer.address()) to transaction request so gas estimation simulates the correct sender - Replace hardcoded 30s send timeout with the configured request_timeout - Expose request_timeout() getter on RpcProviderPool for send_transaction - Remove unreachable dead code in execute() loop (safety check and fallthrough error path) - Fix stale StubChainClient doc comment Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ChainListenerConfig only queries a subgraph, it does not send transactions. gas_price_multiplier and max_gas_price_gwei belong on ChainClientConfig, where they are already defined and used. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
No code path inspects transaction receipts, so this variant was never constructible. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Member
Author
|
Merging to unblock future development. |
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.
Motivation
An indexer can reject a proposal off-chain while still accepting the same agreement on-chain before the deadline expires. This leaves Dipper with an active commitment to an indexer that already refused the work — with no way to undo it.
This PR adds the ability to cancel those agreements on-chain, freeing up the work to be reassigned.
Summary
Disabled by default. Enable via config:
{ "chain_client": { "enabled": true, "providers": ["https://arb1.arbitrum.io/rpc"], "chain_id": 42161, "subgraph_service_address": "0x...", "gas_price_multiplier": 1.2, "max_gas_price_gwei": 100 } }Closes #560