Skip to content

Conversation

beer-1
Copy link
Member

@beer-1 beer-1 commented Oct 12, 2025

Description

This is following of PR #159, add missing migration flow in IBC refund flow

Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • included the correct type prefix in the PR title, you can find examples of the prefixes below:
  • confirmed ! in the type prefix if API or client breaking change
  • targeted the correct branch
  • provided a link to the relevant issue or specification
  • reviewed "Files changed" and left comments if necessary
  • included the necessary unit and integration tests
  • updated the relevant documentation or specification, including comments for documenting Go code
  • confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic, API design and naming, documentation is accurate, tests and test coverage

Summary by CodeRabbit

  • New Features

    • Handles failed or timed-out IBC transfers by refunding migrated tokens back as OP tokens and emitting a dedicated refund event; acknowledgement processing now ensures balances are corrected.
  • Documentation

    • Expands migration specs with failure-handling guidance, clarifies middleware behavior, and improves example formatting.
  • Tests

    • Adds tests covering refund behavior on acknowledgements and timeouts, including bypass scenarios.
  • Chores

    • Updates ignore rules to exclude a local cache directory from version control.

@beer-1 beer-1 self-assigned this Oct 12, 2025
@beer-1 beer-1 requested a review from a team as a code owner October 12, 2025 07:39
Copy link

coderabbitai bot commented Oct 12, 2025

Walkthrough

Adds .gocache to .gitignore; expands migration spec with failure-handling text; adds a refund event constant; extends IBC middleware to accept a codec, parse acknowledgements/timeouts, detect refunded IBC vouchers, and refund/mint OP tokens; updates tests and mocks to cover new flows.

Changes

Cohort / File(s) Summary
Repository config
.\gitignore
Add comment # codex and new ignore rule .gocache/.
Migration specs
specs/migration/readme.md, specs/migration/technical_specification.md
Reformat fenced examples; add failure-handling text for outbound IBC transfers (acknowledgements/timeouts), describe refund->burn->mint flow and new event emission.
Event constants
x/opchild/middleware/migration/events.go
Add exported constant EventTypeHandleMigratedTokenRefund = "handle_migrated_token_refund".
Middleware implementation
x/opchild/middleware/migration/ibc_module.go
Add cdc codec.Codec field and constructor parameter; add OnAcknowledgementPacket method; refactor OnRecvPacket/OnTimeoutPacket to use lookupPacket and isAckError; detect refunded vouchers, call OP keeper, and emit refund event.
Middleware tests
x/opchild/middleware/migration/ibc_module_test.go
Create/pass a codec (ProtoCodec) into NewIBCMiddleware; add tests for acknowledgement error refunds and timeout refunds and no-op sender-chain cases; assert balances and event emission.
Test utilities / mocks
x/opchild/middleware/migration/common_test.go
Add onAcknowledgement and onTimeout hooks to MockTransferApp and invoke them in corresponding handlers.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Relayer
  participant IBC as IBCMiddleware
  participant App as UnderlyingApp
  participant Bank as BankKeeper
  participant OP as OPChildKeeper
  participant Events as EventBus

  Note over IBC: OnAcknowledgementPacket flow (codec-aware)
  Relayer->>IBC: Acknowledgement(packet, ackBytes)
  IBC->>IBC: isAckError(ackBytes) using cdc
  alt Ack success
    IBC->>App: OnAcknowledgementPacket(...)
    App-->>IBC: result
  else Ack error (failed transfer)
    IBC->>IBC: lookupPacket(packet) -> (token, ibcDenom)
    IBC->>Bank: BalanceBefore(sender, ibcDenom)
    IBC->>App: OnAcknowledgementPacket(...) (delegate)
    App-->>IBC: result
    IBC->>Bank: BalanceAfter(sender, ibcDenom)
    IBC->>IBC: delta = after - before
    alt delta > 0 (voucher refunded)
      IBC->>OP: HandleMigratedTokenRefund(sender, ibcDenom, delta)
      OP-->>IBC: burned voucher & minted OP
      IBC->>Events: Emit(EventTypeHandleMigratedTokenRefund)
    else No refund detected
      Note over IBC: no migration action
    end
  end
Loading
sequenceDiagram
  autonumber
  participant Relayer
  participant IBC as IBCMiddleware
  participant App as UnderlyingApp
  participant Bank as BankKeeper
  participant OP as OPChildKeeper
  participant Events as EventBus

  Note over IBC: OnTimeoutPacket flow
  Relayer->>IBC: Timeout(packet)
  IBC->>IBC: lookupPacket(packet) -> (token, ibcDenom)
  IBC->>Bank: BalanceBefore(sender, ibcDenom)
  IBC->>App: OnTimeoutPacket(...)
  App-->>IBC: result
  IBC->>Bank: BalanceAfter(sender, ibcDenom)
  IBC->>IBC: delta = after - before
  alt delta > 0 (voucher refunded on timeout)
    IBC->>OP: HandleMigratedTokenRefund(sender, ibcDenom, delta)
    OP-->>IBC: burned voucher & minted OP
    IBC->>Events: Emit(EventTypeHandleMigratedTokenRefund)
  else No refund detected
    Note over IBC: no migration action
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

I hopped through packets, sniffed a timeout trace,
A codec in my pouch to read each tiny case.
I burned odd vouchers, munched refunds into OP,
Emitted tiny events, then hopped away with glee.
🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly and concisely summarizes the main enhancement—adding the missing migration flow within the IBC refund process—which matches the core changes across middleware logic, event definitions, tests, and documentation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/add-missing-refund-migration

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

Copy link

codecov bot commented Oct 12, 2025

Codecov Report

❌ Patch coverage is 66.66667% with 37 lines in your changes missing coverage. Please review.
✅ Project coverage is 51.99%. Comparing base (1c8ee7f) to head (2a3ba8a).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
x/opchild/middleware/migration/ibc_module.go 66.66% 25 Missing and 12 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #164      +/-   ##
==========================================
+ Coverage   51.69%   51.99%   +0.30%     
==========================================
  Files          62       62              
  Lines        5186     5281      +95     
==========================================
+ Hits         2681     2746      +65     
- Misses       1977     1996      +19     
- Partials      528      539      +11     
Files with missing lines Coverage Δ
x/opchild/middleware/migration/ibc_module.go 50.71% <66.66%> (+14.50%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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)
x/opchild/middleware/migration/ibc_module.go (1)

274-394: Consider refactoring to eliminate duplication between OnAcknowledgementPacket and OnTimeoutPacket.

OnAcknowledgementPacket (lines 274-336) and OnTimeoutPacket (lines 338-394) share nearly identical logic:

  • Parse packet with lookupPacket
  • Check migration registration
  • Measure balance before/after underlying app call
  • Burn IBC token and mint L2 token
  • Emit refund event

The only difference is the initial error-acknowledgement check in OnAcknowledgementPacket.

Consider extracting the common logic into a private helper method:

func (im IBCMiddleware) handleRefund(
	ctx sdk.Context,
	packet channeltypes.Packet,
	sender sdk.AccAddress,
	ibcDenom string,
	data transfertypes.FungibleTokenPacketData,
) error {
	// get the before balance
	beforeBalance := im.bankKeeper.GetBalance(ctx, sender, ibcDenom)

	// call the underlying IBC module (caller passes the appropriate method)
	// This part would need to be parameterized

	// if the balance is not changed, do nothing
	afterBalance := im.bankKeeper.GetBalance(ctx, sender, ibcDenom)
	if afterBalance.Amount.LTE(beforeBalance.Amount) {
		return nil
	}

	// compute the difference
	diff := afterBalance.Amount.Sub(beforeBalance.Amount)

	// burn IBC token and mint L2 token
	ibcCoin := sdk.NewCoin(ibcDenom, diff)
	l2Coin, err := im.opChildKeeper.HandleMigratedTokenDeposit(ctx, sender, ibcCoin, "")
	if err != nil {
		return err
	}

	ctx.EventManager().EmitEvent(sdk.NewEvent(
		EventTypeHandleMigratedTokenRefund,
		sdk.NewAttribute(AttributeKeyReceiver, data.Sender),
		sdk.NewAttribute(AttributeKeyIbcDenom, ibcDenom),
		sdk.NewAttribute(AttributeKeyAmount, l2Coin.String()),
	))

	return nil
}

Then call this helper from both methods after their respective checks and before the underlying app call.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 09f4512 and 2a3ba8a.

📒 Files selected for processing (3)
  • specs/migration/readme.md (1 hunks)
  • specs/migration/technical_specification.md (2 hunks)
  • x/opchild/middleware/migration/ibc_module.go (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • specs/migration/readme.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: spellcheck
  • GitHub Check: golangci-lint
  • GitHub Check: Run test and upload codecov
  • GitHub Check: Analyze (go)
🔇 Additional comments (8)
x/opchild/middleware/migration/ibc_module.go (6)

9-9: LGTM: Codec integration is correct.

The addition of codec.Codec to the middleware is necessary for parsing acknowledgements in isAckError and is consistently integrated across import, struct field, constructor parameter, and initialization.

Also applies to: 33-33, 56-56, 64-64


221-226: LGTM: Refactoring improves maintainability.

The use of lookupPacket helper eliminates code duplication and makes the intent clearer. The early-return pattern when ok=false is appropriate.


328-333: Verify attribute key naming and memo usage.

Two observations:

  1. Attribute naming inconsistency: Line 330 uses AttributeKeyReceiver but sets it to data.Sender. Consider renaming to AttributeKeySender for clarity, or update the variable name if "receiver" is intended to represent the refund recipient.

  2. Empty memo: Line 323 passes an empty string "" as the memo to HandleMigratedTokenDeposit. Verify this is the intended behavior for refund scenarios, as opposed to preserving the original memo from the failed transfer.


396-425: LGTM: lookupPacket helper correctly handles both receive and send paths.

The function properly:

  • Parses transfer packet data
  • Distinguishes between receive and send scenarios
  • Checks token origin using ReceiverChainIsSource/SenderChainIsSource
  • Computes the correct prefixed IBC denom

Note: Line 400 silently returns false on unmarshal errors, treating non-transfer packets as not needing migration checks. This is appropriate for the middleware pattern.


437-445: LGTM: isAckError correctly detects error acknowledgements.

The helper properly uses the codec to unmarshal the acknowledgement and checks the success status. The fallback to false on unmarshal error is safe, as it will pass through to the underlying app.


329-329: EventTypeHandleMigratedTokenRefund constant exists; no action required.

specs/migration/technical_specification.md (2)

28-30: LGTM: Documentation accurately describes the new functionality.

The updated key functions list correctly includes OnAcknowledgementPacket and OnTimeoutPacket, with clear descriptions of their refund behavior.


132-140: LGTM: Comprehensive documentation of failure handling logic.

The new "Failure Handling" section clearly documents:

  • Detection of failed acknowledgements and timeouts
  • The refund flow using HandleMigratedTokenDeposit
  • Event emission with EventTypeHandleMigratedTokenRefund

This accurately reflects the implementation and provides good technical detail.

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.

1 participant