Skip to content

Commit 34b009d

Browse files
committed
Add tests for sending from account to account
1 parent 2af124a commit 34b009d

File tree

6 files changed

+191
-4
lines changed

6 files changed

+191
-4
lines changed

.github/workflows/indexer-build-and-push-dev-staging.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on: # yamllint disable-line rule:truthy
66
- main
77
- 'release/indexer/v[0-9]+.[0-9]+.x' # e.g. release/indexer/v0.1.x
88
- 'release/indexer/v[0-9]+.x' # e.g. release/indexer/v1.x
9+
- davidli/transfer_governance
910
# TODO(DEC-837): Customize github build and push to ECR by service with paths
1011

1112
jobs:

.github/workflows/protocol-build-and-push-snapshot.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on: # yamllint disable-line rule:truthy
66
- main
77
- 'release/protocol/v[0-9]+.[0-9]+.x' # e.g. release/protocol/v0.1.x
88
- 'release/protocol/v[0-9]+.x' # e.g. release/protocol/v1.x
9+
- davidli/transfer_governance
910

1011
jobs:
1112
build-and-push-snapshot-dev:

.github/workflows/protocol-build-and-push.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on: # yamllint disable-line rule:truthy
66
- main
77
- 'release/protocol/v[0-9]+.[0-9]+.x' # e.g. release/protocol/v0.1.x
88
- 'release/protocol/v[0-9]+.x' # e.g. release/protocol/v1.x
9+
- davidli/transfer_governance
910

1011
jobs:
1112
build-and-push-dev:

protocol/app/msgs/internal_msgs_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,10 @@ func TestInternalMsgSamples_Gov_Key(t *testing.T) {
166166
"/dydxprotocol.rewards.MsgUpdateParamsResponse",
167167

168168
// sending
169-
"/dydxprotocol.sending.MsgSendFromModuleToAccount",
170-
"/dydxprotocol.sending.MsgSendFromModuleToAccountResponse",
171169
"/dydxprotocol.sending.MsgSendFromAccountToAccount",
172170
"/dydxprotocol.sending.MsgSendFromAccountToAccountResponse",
171+
"/dydxprotocol.sending.MsgSendFromModuleToAccount",
172+
"/dydxprotocol.sending.MsgSendFromModuleToAccountResponse",
173173

174174
// stats
175175
"/dydxprotocol.stats.MsgUpdateParams",

protocol/x/sending/keeper/transfer_test.go

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,3 +633,186 @@ func TestSendFromModuleToAccount_InvalidRecipient(t *testing.T) {
633633
)
634634
require.ErrorContains(t, err, "Account address is invalid")
635635
}
636+
637+
func TestSendFromAccountToAccount(t *testing.T) {
638+
testDenom := "TestSendFromAccountToAccount/Coin"
639+
testModuleName := "bridge"
640+
tests := map[string]struct {
641+
// Setup.
642+
initialSenderBalance int64
643+
balanceToSend int64
644+
senderAddress string
645+
recipientAddress string
646+
// Expectations
647+
expectedErrContains string
648+
}{
649+
"Success - send between user accounts": {
650+
initialSenderBalance: 1000,
651+
balanceToSend: 100,
652+
senderAddress: constants.AliceAccAddress.String(),
653+
recipientAddress: constants.BobAccAddress.String(),
654+
},
655+
"Success - send to module account": {
656+
initialSenderBalance: 1000,
657+
balanceToSend: 100,
658+
senderAddress: constants.AliceAccAddress.String(),
659+
recipientAddress: authtypes.NewModuleAddress("community_treasury").String(),
660+
},
661+
"Success - send to self": {
662+
initialSenderBalance: 1000,
663+
balanceToSend: 100,
664+
senderAddress: constants.AliceAccAddress.String(),
665+
recipientAddress: constants.AliceAccAddress.String(),
666+
},
667+
"Success - send 0 amount": {
668+
initialSenderBalance: 700,
669+
balanceToSend: 0,
670+
senderAddress: constants.AliceAccAddress.String(),
671+
recipientAddress: constants.BobAccAddress.String(),
672+
},
673+
"Error - insufficient funds": {
674+
initialSenderBalance: 100,
675+
balanceToSend: 101,
676+
senderAddress: constants.AliceAccAddress.String(),
677+
recipientAddress: constants.BobAccAddress.String(),
678+
expectedErrContains: "insufficient funds",
679+
},
680+
}
681+
682+
for name, tc := range tests {
683+
t.Run(name, func(t *testing.T) {
684+
// Initiate keepers and fund sender with initial balance.
685+
ks := keepertest.SendingKeepers(t)
686+
ctx, sendingKeeper, bankKeeper := ks.Ctx, ks.SendingKeeper, ks.BankKeeper
687+
688+
senderAddr := sdk.MustAccAddressFromBech32(tc.senderAddress)
689+
690+
// Mint coins to bridging module and transfer to sender account
691+
err := bankKeeper.MintCoins(
692+
ctx,
693+
testModuleName,
694+
sdk.NewCoins(sdk.NewCoin(testDenom, sdkmath.NewInt(tc.initialSenderBalance))),
695+
)
696+
require.NoError(t, err)
697+
err = bankKeeper.SendCoinsFromModuleToAccount(
698+
ctx,
699+
testModuleName,
700+
senderAddr,
701+
sdk.NewCoins(sdk.NewCoin(testDenom, sdkmath.NewInt(tc.initialSenderBalance))),
702+
)
703+
require.NoError(t, err)
704+
705+
startingSenderBalance := bankKeeper.GetBalance(
706+
ctx,
707+
senderAddr,
708+
testDenom,
709+
)
710+
startingRecipientBalance := bankKeeper.GetBalance(
711+
ctx,
712+
sdk.MustAccAddressFromBech32(tc.recipientAddress),
713+
testDenom,
714+
)
715+
716+
// Send coins from account to account.
717+
err = sendingKeeper.SendFromAccountToAccount(
718+
ctx,
719+
&types.MsgSendFromAccountToAccount{
720+
Authority: lib.GovModuleAddress.String(),
721+
Sender: tc.senderAddress,
722+
Recipient: tc.recipientAddress,
723+
Coin: sdk.NewCoin(testDenom, sdkmath.NewInt(tc.balanceToSend)),
724+
},
725+
)
726+
727+
// Verify ending balances and error.
728+
endingSenderBalance := bankKeeper.GetBalance(
729+
ctx,
730+
senderAddr,
731+
testDenom,
732+
)
733+
endingRecipientBalance := bankKeeper.GetBalance(
734+
ctx,
735+
sdk.MustAccAddressFromBech32(tc.recipientAddress),
736+
testDenom,
737+
)
738+
739+
if tc.expectedErrContains != "" { // if error should occur.
740+
// Verify that error is as expected.
741+
require.ErrorContains(t, err, tc.expectedErrContains)
742+
// Verify that sender balance is unchanged.
743+
require.Equal(
744+
t,
745+
startingSenderBalance.Amount.Int64(),
746+
endingSenderBalance.Amount.Int64(),
747+
)
748+
// Verify that recipient balance is unchanged.
749+
require.Equal(
750+
t,
751+
startingRecipientBalance.Amount.Int64(),
752+
endingRecipientBalance.Amount.Int64(),
753+
)
754+
} else { // if send should succeed.
755+
// Verify that no error occurred.
756+
require.NoError(t, err)
757+
if tc.senderAddress == tc.recipientAddress {
758+
// If account sent to itself, verify that balance is unchanged.
759+
require.Equal(t, startingSenderBalance, endingSenderBalance)
760+
} else {
761+
// Otherwise, verify that sender balance is reduced by amount sent.
762+
require.Equal(
763+
t,
764+
startingSenderBalance.Amount.Int64()-tc.balanceToSend,
765+
endingSenderBalance.Amount.Int64(),
766+
)
767+
// Verify that recipient balance is increased by amount sent.
768+
require.Equal(
769+
t,
770+
startingRecipientBalance.Amount.Int64()+tc.balanceToSend,
771+
endingRecipientBalance.Amount.Int64(),
772+
)
773+
}
774+
}
775+
})
776+
}
777+
}
778+
779+
func TestSendFromAccountToAccount_InvalidMsg(t *testing.T) {
780+
msgEmptySender := &types.MsgSendFromAccountToAccount{
781+
Authority: lib.GovModuleAddress.String(),
782+
Sender: "",
783+
Recipient: constants.AliceAccAddress.String(),
784+
Coin: sdk.NewCoin("adv4tnt", sdkmath.NewInt(100)),
785+
}
786+
787+
ks := keepertest.SendingKeepers(t)
788+
err := ks.SendingKeeper.SendFromAccountToAccount(ks.Ctx, msgEmptySender)
789+
require.ErrorContains(t, err, "Account address is invalid")
790+
}
791+
792+
func TestSendFromAccountToAccount_InvalidRecipient(t *testing.T) {
793+
ks := keepertest.SendingKeepers(t)
794+
err := ks.SendingKeeper.SendFromAccountToAccount(
795+
ks.Ctx,
796+
&types.MsgSendFromAccountToAccount{
797+
Authority: lib.GovModuleAddress.String(),
798+
Sender: constants.AliceAccAddress.String(),
799+
Recipient: "dydx1abc", // invalid recipient address
800+
Coin: sdk.NewCoin("adv4tnt", sdkmath.NewInt(1)),
801+
},
802+
)
803+
require.ErrorContains(t, err, "Account address is invalid")
804+
}
805+
806+
func TestSendFromAccountToAccount_InvalidSender(t *testing.T) {
807+
ks := keepertest.SendingKeepers(t)
808+
err := ks.SendingKeeper.SendFromAccountToAccount(
809+
ks.Ctx,
810+
&types.MsgSendFromAccountToAccount{
811+
Authority: lib.GovModuleAddress.String(),
812+
Sender: "dydx1abc", // invalid sender address
813+
Recipient: constants.AliceAccAddress.String(),
814+
Coin: sdk.NewCoin("adv4tnt", sdkmath.NewInt(1)),
815+
},
816+
)
817+
require.ErrorContains(t, err, "Account address is invalid")
818+
}

protocol/x/sending/module_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package sending_test
33
import (
44
"bytes"
55
"encoding/json"
6-
"github.com/dydxprotocol/v4-chain/protocol/app/module"
76
"net/http"
87
"net/http/httptest"
98
"reflect"
109
"testing"
1110

11+
"github.com/dydxprotocol/v4-chain/protocol/app/module"
12+
1213
"github.com/cosmos/cosmos-sdk/client"
1314
"github.com/cosmos/cosmos-sdk/codec"
1415
"github.com/cosmos/cosmos-sdk/codec/types"
@@ -79,7 +80,7 @@ func TestAppModuleBasic_RegisterInterfaces(t *testing.T) {
7980
// due to it using an unexported method on the interface thus we use reflection to access the field
8081
// directly that contains the registrations.
8182
fv := reflect.ValueOf(registry).Elem().FieldByName("implInterfaces")
82-
require.Len(t, fv.MapKeys(), 8)
83+
require.Len(t, fv.MapKeys(), 10)
8384
}
8485

8586
func TestAppModuleBasic_DefaultGenesis(t *testing.T) {

0 commit comments

Comments
 (0)