Skip to content

Conversation

@davidli1997
Copy link
Contributor

@davidli1997 davidli1997 commented Nov 7, 2025

Changelist

  • Added SendFromAccountToAccount keeper function to the x/sending module
  • This function enables sending coins from one x/bank account to another x/bank account
  • The function validates the message, converts addresses, and delegates to bankKeeper.SendCoins
  • Updated TestAppModuleBasic_RegisterInterfaces to reflect 2 new registered message types (8→10)

Test Plan

Unit Test

  • Added TestSendFromAccountToAccount with comprehensive test cases:
    • Success: send between user accounts
    • Success: send to module account
    • Success: send to self
    • Success: send 0 amount
    • Error: insufficient funds
  • Added TestSendFromAccountToAccount_InvalidMsg to verify empty sender validation
  • Added TestSendFromAccountToAccount_InvalidRecipient to verify invalid recipient address validation
  • Added TestSendFromAccountToAccount_InvalidSender to verify invalid sender address validation

Author/Reviewer Checklist

  • If this PR has changes that result in a different app state given the same prior state and transaction list, manually add the state-breaking label.
  • If the PR has breaking postgres changes to the indexer add the indexer-postgres-breaking label.
  • If this PR isn't state-breaking but has changes that modify behavior in PrepareProposal or ProcessProposal, manually add the label proposal-breaking.
  • If this PR is one of many that implement a specific feature, manually label them all feature:[feature-name].
  • If you wish to for mergify-bot to automatically create a PR to backport your change to a release branch, manually add the label backport/[branch-name].
  • Manually add any of the following labels: refactor, chore, bug.

Summary by CodeRabbit

  • New Features
    • Account-to-account transfer capability with authority validation for secure inter-account fund transfers
    • New RPC endpoint to invoke account-to-account transfers with address and coin validation
  • Metrics
    • Added telemetry metric for account-to-account sends
  • Tests
    • Added unit tests covering validation and keeper transfer scenarios

@davidli1997 davidli1997 requested a review from a team as a code owner November 7, 2025 20:17
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 7, 2025

Walkthrough

Adds a governance-authority msg and RPC to transfer coins between two x/bank accounts: proto, TypeScript codegen, Go message type and validation, keeper and msgServer logic, BankKeeper interface update, tests, mocks, metrics, and message registrations.

Changes

Cohort / File(s) Summary
Proto definitions
proto/dydxprotocol/sending/transfer.proto, proto/dydxprotocol/sending/tx.proto
New message MsgSendFromAccountToAccount (authority, sender, recipient, coin) with signer option; new RPC SendFromAccountToAccount and response MsgSendFromAccountToAccountResponse.
Generated TypeScript code
indexer/packages/v4-protos/src/codegen/dydxprotocol/sending/transfer.ts, indexer/packages/v4-protos/src/codegen/dydxprotocol/sending/tx.rpc.msg.ts, indexer/packages/v4-protos/src/codegen/dydxprotocol/sending/tx.ts
Codegen for new message and response: interfaces/SDK types, encode/decode/fromPartial, and RPC client method sendFromAccountToAccount bound in MsgClientImpl.
Go message type & validation
protocol/x/sending/types/message_send_from_account_to_account.go, protocol/x/sending/types/message_send_from_account_to_account_test.go
New MsgSendFromAccountToAccount with constructor and ValidateBasic (authority, sender, recipient, coin) plus table-driven tests covering valid and invalid cases.
Keeper & msgServer
protocol/x/sending/keeper/transfer.go, protocol/x/sending/keeper/msg_server_create_transfer.go, protocol/x/sending/keeper/transfer_test.go
Keeper method SendFromAccountToAccount performing ValidateBasic, Bech32→AccAddress conversion, and bankKeeper.SendCoins; msgServer handler performs authority check, delegates to Keeper, updates telemetry; unit tests for success and error cases.
Interface updates
protocol/x/sending/types/expected_keepers.go, protocol/x/sending/types/types.go
Added SendCoins(ctx, fromAddr, toAddr, amt) to BankKeeper expected interface and SendFromAccountToAccount(ctx, msg) to SendingKeeper interface.
Message registration & internal lists
protocol/app/msgs/all_msgs.go, protocol/app/msgs/internal_msgs.go, protocol/app/msgs/internal_msgs_test.go
Registered /dydxprotocol.sending.MsgSendFromAccountToAccount and its response in AllTypeMessages and internal messages; updated tests to expect new entries.
Mocks, metrics, and ante
protocol/mocks/SendingKeeper.go, protocol/lib/metrics/constants.go, protocol/lib/ante/internal_msg.go
Added mock SendFromAccountToAccount method, metric constant SendFromAccountToAccount, and added type to IsInternalMsg switch.
CI workflow triggers
.github/workflows/* (three workflows)
Added davidli/transfer_governance branch to push triggers in indexer and protocol build workflows.
Module registration test update
protocol/x/sending/module_test.go
Import reordering and updated expected interface registration count (8 → 10).

Sequence Diagram

sequenceDiagram
    participant CLI as Client
    participant MS as MsgServer
    participant K as Keeper
    participant BK as BankKeeper

    CLI->>MS: SendFromAccountToAccount(msg)
    rect rgb(230,240,255)
      note right of MS: authority check
      MS->>MS: verify authority
    end
    MS->>K: SendFromAccountToAccount(msg)
    rect rgb(230,240,255)
      note right of K: message validation & address conversion
      K->>K: msg.ValidateBasic()
      K->>K: Bech32 → AccAddress (sender, recipient)
    end
    K->>BK: SendCoins(sender, recipient, coin)
    BK-->>K: result
    K-->>MS: result (ok / err)
    rect rgb(230,240,255)
      note right of MS: telemetry update, respond
      MS->>MS: update metrics
    end
    MS-->>CLI: MsgSendFromAccountToAccountResponse / Error
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Areas to focus:
    • ValidateBasic consistency with existing MsgSendFromModuleToAccount
    • Correct SDK context usage and Bech32→AccAddress conversion in Keeper
    • Compatibility of added BankKeeper SendCoins signature with x/bank implementations
    • Tests: duplicated test block in transfer_test.go (remove duplicate) and ensure coverage aligns with edge cases

Possibly related PRs

Suggested reviewers

  • vincentwschau
  • shrenujb
  • teddyding

Poem

🐰 I nibble code beneath the moon,
A carrot-led, precise small tune,
From account to account I hop,
Coins scurry — never stop,
Hooray! The transfer's in my loop! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: introducing a new governance message for account-level transfers.
Description check ✅ Passed The PR description provides a detailed changelist, comprehensive test plan, and includes the required author/reviewer checklist.
✨ 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 davidli/transfer_governance

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.

❤️ Share

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

@davidli1997 davidli1997 changed the title Create new governance message for account level transfer [ENG-1305] Create new governance message for account level transfer Nov 10, 2025
@linear
Copy link

linear bot commented Nov 10, 2025

Copy link
Contributor

@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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2af124a and 34b009d.

📒 Files selected for processing (6)
  • .github/workflows/indexer-build-and-push-dev-staging.yml (1 hunks)
  • .github/workflows/protocol-build-and-push-snapshot.yml (1 hunks)
  • .github/workflows/protocol-build-and-push.yml (1 hunks)
  • protocol/app/msgs/internal_msgs_test.go (1 hunks)
  • protocol/x/sending/keeper/transfer_test.go (1 hunks)
  • protocol/x/sending/module_test.go (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .github/workflows/protocol-build-and-push.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • protocol/app/msgs/internal_msgs_test.go
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: hwray
Repo: dydxprotocol/v4-chain PR: 2551
File: protocol/x/subaccounts/keeper/subaccount.go:852-865
Timestamp: 2024-11-15T16:00:11.304Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
Learnt from: hwray
Repo: dydxprotocol/v4-chain PR: 2551
File: protocol/x/clob/types/expected_keepers.go:86-90
Timestamp: 2024-11-15T16:17:29.092Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/clob/types/expected_keepers.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
Learnt from: hwray
Repo: dydxprotocol/v4-chain PR: 2551
File: protocol/x/subaccounts/keeper/subaccount.go:833-850
Timestamp: 2024-11-15T15:59:28.095Z
Learning: The function `GetInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.
📚 Learning: 2025-05-24T00:45:00.519Z
Learnt from: anmolagrawal345
Repo: dydxprotocol/v4-chain PR: 2837
File: proto/dydxprotocol/clob/order.proto:4-4
Timestamp: 2025-05-24T00:45:00.519Z
Learning: In the dydxprotocol/v4-chain repository, cosmos_proto dependencies are managed through buf.yaml configuration rather than being physically present in the repository. The import "cosmos_proto/cosmos.proto" is a standard pattern used across 28+ proto files for cosmos address annotations like (cosmos_proto.scalar) = "cosmos.AddressString".

Applied to files:

  • protocol/x/sending/module_test.go
📚 Learning: 2024-11-15T16:00:11.304Z
Learnt from: hwray
Repo: dydxprotocol/v4-chain PR: 2551
File: protocol/x/subaccounts/keeper/subaccount.go:852-865
Timestamp: 2024-11-15T16:00:11.304Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.

Applied to files:

  • protocol/x/sending/keeper/transfer_test.go
📚 Learning: 2024-11-15T15:59:28.095Z
Learnt from: hwray
Repo: dydxprotocol/v4-chain PR: 2551
File: protocol/x/subaccounts/keeper/subaccount.go:833-850
Timestamp: 2024-11-15T15:59:28.095Z
Learning: The function `GetInsuranceFundBalance` in `protocol/x/subaccounts/keeper/subaccount.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.

Applied to files:

  • protocol/x/sending/keeper/transfer_test.go
📚 Learning: 2024-11-15T16:17:29.092Z
Learnt from: hwray
Repo: dydxprotocol/v4-chain PR: 2551
File: protocol/x/clob/types/expected_keepers.go:86-90
Timestamp: 2024-11-15T16:17:29.092Z
Learning: The function `GetCrossInsuranceFundBalance` in `protocol/x/clob/types/expected_keepers.go` already existed and was just moved in this PR; changes to its error handling may be out of scope.

Applied to files:

  • protocol/x/sending/keeper/transfer_test.go
🧬 Code graph analysis (1)
protocol/x/sending/keeper/transfer_test.go (5)
protocol/testutil/constants/addresses.go (2)
  • AliceAccAddress (10-10)
  • BobAccAddress (11-11)
protocol/testutil/keeper/sending.go (1)
  • SendingKeepers (40-44)
protocol/x/sending/types/expected_keepers.go (1)
  • BankKeeper (78-92)
protocol/x/subaccounts/types/expected_keepers.go (1)
  • BankKeeper (88-104)
protocol/lib/module_addresses.go (1)
  • GovModuleAddress (10-10)
⏰ 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). (55)
  • GitHub Check: test-coverage-upload
  • GitHub Check: test-race
  • GitHub Check: unit-end-to-end-and-integration
  • GitHub Check: check-bc-breaking
  • GitHub Check: format
  • GitHub Check: v4-proto-js-gen
  • GitHub Check: protocol-gen
  • GitHub Check: v4-proto-py-gen
  • GitHub Check: indexer-gen
  • GitHub Check: check-sample-pregenesis-up-to-date
  • GitHub Check: benchmark
  • GitHub Check: build
  • GitHub Check: golangci-lint
  • GitHub Check: build-and-push-mainnet
  • GitHub Check: build-and-push-testnet
  • GitHub Check: container-tests
  • GitHub Check: (Dev) Build and Push ECS Services / call-build-and-push-vulcan / (vulcan) Build and Push
  • GitHub Check: (Staging) Build and Push ECS Services / call-build-and-push-vulcan / (vulcan) Build and Push
  • GitHub Check: (Staging) Build and Push ECS Services / call-build-and-push-ecs-service-ender / (ender) Build and Push
  • GitHub Check: (Staging) Build and Push ECS Services / call-build-and-push-auxo-lambda / (auxo) Build and Push Lambda
  • GitHub Check: (Staging) Build and Push ECS Services / call-build-and-push-bazooka-lambda / (bazooka) Build and Push Lambda
  • GitHub Check: (Staging) Build and Push ECS Services / call-build-and-push-ecs-service-comlink / (comlink) Build and Push
  • GitHub Check: (Dev4) Build and Push ECS Services / call-build-and-push-vulcan / (vulcan) Build and Push
  • GitHub Check: (Staging) Build and Push ECS Services / call-build-and-push-ecs-service-roundtable / (roundtable) Build and Push
  • GitHub Check: (Dev4) Build and Push ECS Services / call-build-and-push-ecs-service-socks / (socks) Build and Push
  • GitHub Check: (Staging) Build and Push ECS Services / call-build-and-push-ecs-service-socks / (socks) Build and Push
  • GitHub Check: (Dev4) Build and Push ECS Services / call-build-and-push-ecs-service-comlink / (comlink) Build and Push
  • GitHub Check: (Dev4) Build and Push ECS Services / call-build-and-push-auxo-lambda / (auxo) Build and Push Lambda
  • GitHub Check: (Dev4) Build and Push ECS Services / call-build-and-push-ecs-service-ender / (ender) Build and Push
  • GitHub Check: (Dev4) Build and Push ECS Services / call-build-and-push-bazooka-lambda / (bazooka) Build and Push Lambda
  • GitHub Check: (Dev4) Build and Push ECS Services / call-build-and-push-ecs-service-roundtable / (roundtable) Build and Push
  • GitHub Check: (Dev) Build and Push ECS Services / call-build-and-push-ecs-service-roundtable / (roundtable) Build and Push
  • GitHub Check: (Dev) Build and Push ECS Services / call-build-and-push-bazooka-lambda / (bazooka) Build and Push Lambda
  • GitHub Check: (Dev) Build and Push ECS Services / call-build-and-push-ecs-service-ender / (ender) Build and Push
  • GitHub Check: (Dev) Build and Push ECS Services / call-build-and-push-ecs-service-socks / (socks) Build and Push
  • GitHub Check: (Dev) Build and Push ECS Services / call-build-and-push-auxo-lambda / (auxo) Build and Push Lambda
  • GitHub Check: (Dev) Build and Push ECS Services / call-build-and-push-ecs-service-comlink / (comlink) Build and Push
  • GitHub Check: (Dev2) Build and Push ECS Services / call-build-and-push-auxo-lambda / (auxo) Build and Push Lambda
  • GitHub Check: (Dev2) Build and Push ECS Services / call-build-and-push-bazooka-lambda / (bazooka) Build and Push Lambda
  • GitHub Check: (Dev2) Build and Push ECS Services / call-build-and-push-ecs-service-comlink / (comlink) Build and Push
  • GitHub Check: (Dev2) Build and Push ECS Services / call-build-and-push-ecs-service-roundtable / (roundtable) Build and Push
  • GitHub Check: (Dev2) Build and Push ECS Services / call-build-and-push-vulcan / (vulcan) Build and Push
  • GitHub Check: (Dev2) Build and Push ECS Services / call-build-and-push-ecs-service-socks / (socks) Build and Push
  • GitHub Check: (Dev2) Build and Push ECS Services / call-build-and-push-ecs-service-ender / (ender) Build and Push
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: build-and-push-dev4
  • GitHub Check: build-and-push-dev
  • GitHub Check: build-and-push-snapshot-staging
  • GitHub Check: build-and-push-snapshot-dev
  • GitHub Check: build-and-push-snapshot-dev2
  • GitHub Check: build-and-push-snapshot-dev4
  • GitHub Check: build-and-push-staging
  • GitHub Check: build-and-push-dev2
  • GitHub Check: Summary
🔇 Additional comments (6)
.github/workflows/protocol-build-and-push-snapshot.yml (1)

9-9: Consider removing the feature branch trigger before merge.

Adding davidli/transfer_governance (a temporary feature branch) to the CI/CD workflow triggers creates technical debt. Once this branch is deleted after the PR merges, the workflow configuration will reference a non-existent branch.

This branch should either be removed from the configuration before merging, or this change should be conditional/temporary if there's a specific reason to enable snapshot builds on this branch during development.

Is this trigger intended to persist after the PR merges, or should it be removed as part of the merge process?

protocol/x/sending/module_test.go (2)

11-12: LGTM - Import organization improved.

The import reordering enhances code organization by properly grouping local project imports.


83-83: Interface registration count verified—no changes needed.

The interface registry count of 10 is correct. The MsgServer interface in the sending module contains 5 RPC methods, each generating a request and response message type (5 methods × 2 = 10 types). The new SendFromAccountToAccount RPC method adds 2 types (MsgSendFromAccountToAccount and MsgSendFromAccountToAccountResponse), accounting for the increase from 8 to 10. Both message types exist and are properly integrated into the message service descriptor.

protocol/x/sending/keeper/transfer_test.go (3)

779-790: LGTM - Invalid message validation.

The test correctly validates that an empty sender address is rejected with an appropriate error message.


792-804: LGTM - Invalid recipient validation.

The test correctly validates that an invalid recipient address is rejected.


806-818: LGTM - Invalid sender validation.

The test correctly validates that an invalid sender address is rejected, completing comprehensive validation coverage for the new message type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants