Skip to content

fix(bank): apply send restriction in InputOutputCoins#528

Merged
traviolus merged 2 commits into
mainfrom
fix/multi-send-restrict
Jun 10, 2026
Merged

fix(bank): apply send restriction in InputOutputCoins#528
traviolus merged 2 commits into
mainfrom
fix/multi-send-restrict

Conversation

@traviolus

Copy link
Copy Markdown
Contributor

Description

Closes: #XXXX


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

@traviolus traviolus requested a review from a team as a code owner June 10, 2026 09:22
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 79d5e10f-0b8c-416d-a529-1c4b2d498805

📥 Commits

Reviewing files that changed from the base of the PR and between bf64e0d and e99667a.

📒 Files selected for processing (1)
  • x/bank/keeper/send.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • x/bank/keeper/send.go

📝 Walkthrough

Walkthrough

InputOutputCoins now applies the keeper's sendRestriction to each decoded recipient, aborting on error, caches the post-restriction recipient address for account creation and MultiSend, and updates transfer events; a new test asserts restriction calls for SendCoins and InputOutputCoins.

Changes

Send Restriction Enforcement in InputOutputCoins

Layer / File(s) Summary
Apply send restrictions to each recipient output
x/bank/keeper/send.go, x/bank/keeper/send_test.go
InputOutputCoins decodes each output address, calls k.sendRestriction.apply() on the decoded recipient and caches the post-restriction address (outAddrs) for account creation and use in MultiSend; transfer event Recipient now uses the post-restriction address. Test TestInputOutputCoinsAppliesSendRestriction asserts the restriction is invoked once per SendCoins call and once per output in InputOutputCoins.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibble code where coins must pass the gate,
Each address checked before it meets its fate.
A hop, a rule, a careful little test,
Now every send is properly addressed. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: applying send restriction in the InputOutputCoins function, which matches the core modification shown in the raw summary.
Description check ✅ Passed The description relates to the changeset by mentioning the purpose of applying send restrictions in InputOutputCoins, though it lacks implementation details and issue references.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/multi-send-restrict

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 (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


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

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@beer-1 beer-1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
x/bank/keeper/send_test.go (1)

39-44: ⚡ Quick win

Strengthen the multi-send assertion to validate “once per output.”

Line 42 builds only one output, so calls == 1 cannot distinguish per-output vs per-transaction restriction behavior. Use at least two outputs and assert calls == len(outputs).

✅ Suggested test adjustment
 	// InputOutputCoins (MsgMultiSend) must apply the restriction once per output
 	calls = 0
 	in := banktypes.Input{Address: from.String(), Coins: coins}
-	outputs := []banktypes.Output{{Address: to.String(), Coins: coins}}
+	to2 := input.Faucet.NewFundedAccount(ctx, sdk.NewInt64Coin(denom, 1))
+	outputs := []banktypes.Output{
+		{Address: to.String(), Coins: sdk.NewCoins(sdk.NewInt64Coin(denom, 400))},
+		{Address: to2.String(), Coins: sdk.NewCoins(sdk.NewInt64Coin(denom, 600))},
+	}
 	require.NoError(t, bk.InputOutputCoins(ctx, in, outputs))
-	require.Equal(t, 1, calls)
+	require.Equal(t, len(outputs), calls)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@x/bank/keeper/send_test.go` around lines 39 - 44, The test currently only
uses one output so asserting calls == 1 doesn't prove the restriction is applied
per output; update the test in send_test.go around the InputOutputCoins call to
create at least two banktypes.Output entries (e.g., outputs :=
[]banktypes.Output{{...}, {...}}) and then assert require.Equal(t, len(outputs),
calls) after invoking bk.InputOutputCoins(ctx, in, outputs) so the assertion
verifies the restriction ran once for each output; reference the
variables/functions InputOutputCoins, bk, calls, in, and outputs when making the
change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@x/bank/keeper/send.go`:
- Around line 143-150: The code currently applies k.sendRestriction.apply which
can rewrite the recipient address into the local variable addr, but then caches
and emits the original output.Address, causing event/recipient desyncs and
possible map collisions; change the logic so that after calling
k.sendRestriction.apply you store and emit the rewritten addr (use
addrMap[output.Address] = addr but ensure events use addr.String()/addr.Bytes()
or the resolved addr variable instead of output.Address) and update the same fix
pattern in the other affected blocks (the sections around the 158-163 and
174-177 ranges) so all caching and event emission consistently use the
post-restriction recipient (addr) rather than the original output.Address.

---

Nitpick comments:
In `@x/bank/keeper/send_test.go`:
- Around line 39-44: The test currently only uses one output so asserting calls
== 1 doesn't prove the restriction is applied per output; update the test in
send_test.go around the InputOutputCoins call to create at least two
banktypes.Output entries (e.g., outputs := []banktypes.Output{{...}, {...}}) and
then assert require.Equal(t, len(outputs), calls) after invoking
bk.InputOutputCoins(ctx, in, outputs) so the assertion verifies the restriction
ran once for each output; reference the variables/functions InputOutputCoins,
bk, calls, in, and outputs when making the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6df85a24-3b15-4dfb-9e89-a9d0f3cc1360

📥 Commits

Reviewing files that changed from the base of the PR and between afbba19 and bf64e0d.

📒 Files selected for processing (2)
  • x/bank/keeper/send.go
  • x/bank/keeper/send_test.go

Comment thread x/bank/keeper/send.go Outdated
@traviolus traviolus requested a review from beer-1 June 10, 2026 09:42

@beer-1 beer-1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@traviolus traviolus merged commit 99a0fcc into main Jun 10, 2026
12 checks passed
@traviolus traviolus deleted the fix/multi-send-restrict branch June 10, 2026 09:55
@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 72.72727% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 38.51%. Comparing base (43f49af) to head (e99667a).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
x/bank/keeper/send.go 72.72% 2 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #528      +/-   ##
==========================================
+ Coverage   38.49%   38.51%   +0.02%     
==========================================
  Files         327      327              
  Lines       30693    30697       +4     
==========================================
+ Hits        11814    11823       +9     
+ Misses      16980    16973       -7     
- Partials     1899     1901       +2     
Files with missing lines Coverage Δ
x/bank/keeper/send.go 74.34% <72.72%> (+1.33%) ⬆️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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