@@ -11,14 +11,17 @@ import (
11
11
12
12
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
13
13
sdk "github.com/cosmos/cosmos-sdk/types"
14
+ govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
14
15
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
15
16
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
16
17
17
18
"github.com/cosmos/gaia/v15/ante"
18
19
"github.com/cosmos/gaia/v15/app/helpers"
19
20
)
20
21
21
- func TestVoteSpamDecorator (t * testing.T ) {
22
+ // Test that the GovVoteDecorator rejects v1beta1 vote messages from accounts with less than 1 atom staked
23
+ // Submitting v1beta1.VoteMsg should not be possible through the CLI, but it's still possible to craft a transaction
24
+ func TestVoteSpamDecoratorGovV1Beta1 (t * testing.T ) {
22
25
gaiaApp := helpers .Setup (t )
23
26
ctx := gaiaApp .NewUncachedContext (true , tmproto.Header {})
24
27
decorator := ante .NewGovVoteDecorator (gaiaApp .AppCodec (), gaiaApp .StakingKeeper )
@@ -56,6 +59,12 @@ func TestVoteSpamDecorator(t *testing.T) {
56
59
validators []sdk.ValAddress
57
60
expectPass bool
58
61
}{
62
+ {
63
+ name : "delegate 0 atom" ,
64
+ bondAmt : sdk .ZeroInt (),
65
+ validators : []sdk.ValAddress {valAddr1 },
66
+ expectPass : false ,
67
+ },
59
68
{
60
69
name : "delegate 0.1 atom" ,
61
70
bondAmt : sdk .NewInt (100000 ),
@@ -97,12 +106,14 @@ func TestVoteSpamDecorator(t *testing.T) {
97
106
}
98
107
99
108
// Delegate tokens
100
- amt := tc .bondAmt .Quo (sdk .NewInt (int64 (len (tc .validators ))))
101
- for _ , valAddr := range tc .validators {
102
- val , found := stakingKeeper .GetValidator (ctx , valAddr )
103
- require .True (t , found )
104
- _ , err := stakingKeeper .Delegate (ctx , delegator , amt , stakingtypes .Unbonded , val , true )
105
- require .NoError (t , err )
109
+ if ! tc .bondAmt .IsZero () {
110
+ amt := tc .bondAmt .Quo (sdk .NewInt (int64 (len (tc .validators ))))
111
+ for _ , valAddr := range tc .validators {
112
+ val , found := stakingKeeper .GetValidator (ctx , valAddr )
113
+ require .True (t , found )
114
+ _ , err := stakingKeeper .Delegate (ctx , delegator , amt , stakingtypes .Unbonded , val , true )
115
+ require .NoError (t , err )
116
+ }
106
117
}
107
118
108
119
// Create vote message
@@ -121,3 +132,118 @@ func TestVoteSpamDecorator(t *testing.T) {
121
132
}
122
133
}
123
134
}
135
+
136
+ // Test that the GovVoteDecorator rejects v1 vote messages from accounts with less than 1 atom staked
137
+ // Usually, only v1.VoteMsg can be submitted using the CLI.
138
+ func TestVoteSpamDecoratorGovV1 (t * testing.T ) {
139
+ gaiaApp := helpers .Setup (t )
140
+ ctx := gaiaApp .NewUncachedContext (true , tmproto.Header {})
141
+ decorator := ante .NewGovVoteDecorator (gaiaApp .AppCodec (), gaiaApp .StakingKeeper )
142
+ stakingKeeper := gaiaApp .StakingKeeper
143
+
144
+ // Get validator
145
+ valAddr1 := stakingKeeper .GetAllValidators (ctx )[0 ].GetOperator ()
146
+
147
+ // Create one more validator
148
+ pk := ed25519 .GenPrivKeyFromSecret ([]byte {uint8 (13 )}).PubKey ()
149
+ validator2 , err := stakingtypes .NewValidator (
150
+ sdk .ValAddress (pk .Address ()),
151
+ pk ,
152
+ stakingtypes.Description {},
153
+ )
154
+ valAddr2 := validator2 .GetOperator ()
155
+ require .NoError (t , err )
156
+ // Make sure the validator is bonded so it's not removed on Undelegate
157
+ validator2 .Status = stakingtypes .Bonded
158
+ stakingKeeper .SetValidator (ctx , validator2 )
159
+ err = stakingKeeper .SetValidatorByConsAddr (ctx , validator2 )
160
+ require .NoError (t , err )
161
+ stakingKeeper .SetNewValidatorByPowerIndex (ctx , validator2 )
162
+ err = stakingKeeper .Hooks ().AfterValidatorCreated (ctx , validator2 .GetOperator ())
163
+ require .NoError (t , err )
164
+
165
+ // Get delegator (this account was created during setup)
166
+ addr := gaiaApp .AccountKeeper .GetAccountAddressByID (ctx , 0 )
167
+ delegator , err := sdk .AccAddressFromBech32 (addr )
168
+ require .NoError (t , err )
169
+
170
+ tests := []struct {
171
+ name string
172
+ bondAmt math.Int
173
+ validators []sdk.ValAddress
174
+ expectPass bool
175
+ }{
176
+ {
177
+ name : "delegate 0 atom" ,
178
+ bondAmt : sdk .ZeroInt (),
179
+ validators : []sdk.ValAddress {valAddr1 },
180
+ expectPass : false ,
181
+ },
182
+ {
183
+ name : "delegate 0.1 atom" ,
184
+ bondAmt : sdk .NewInt (100000 ),
185
+ validators : []sdk.ValAddress {valAddr1 },
186
+ expectPass : false ,
187
+ },
188
+ {
189
+ name : "delegate 1 atom" ,
190
+ bondAmt : sdk .NewInt (1000000 ),
191
+ validators : []sdk.ValAddress {valAddr1 },
192
+ expectPass : true ,
193
+ },
194
+ {
195
+ name : "delegate 1 atom to two validators" ,
196
+ bondAmt : sdk .NewInt (1000000 ),
197
+ validators : []sdk.ValAddress {valAddr1 , valAddr2 },
198
+ expectPass : true ,
199
+ },
200
+ {
201
+ name : "delegate 0.9 atom to two validators" ,
202
+ bondAmt : sdk .NewInt (900000 ),
203
+ validators : []sdk.ValAddress {valAddr1 , valAddr2 },
204
+ expectPass : false ,
205
+ },
206
+ {
207
+ name : "delegate 10 atom" ,
208
+ bondAmt : sdk .NewInt (10000000 ),
209
+ validators : []sdk.ValAddress {valAddr1 },
210
+ expectPass : true ,
211
+ },
212
+ }
213
+
214
+ for _ , tc := range tests {
215
+ // Unbond all tokens for this delegator
216
+ delegations := stakingKeeper .GetAllDelegatorDelegations (ctx , delegator )
217
+ for _ , del := range delegations {
218
+ _ , err := stakingKeeper .Undelegate (ctx , delegator , del .GetValidatorAddr (), del .GetShares ())
219
+ require .NoError (t , err )
220
+ }
221
+
222
+ // Delegate tokens
223
+ if ! tc .bondAmt .IsZero () {
224
+ amt := tc .bondAmt .Quo (sdk .NewInt (int64 (len (tc .validators ))))
225
+ for _ , valAddr := range tc .validators {
226
+ val , found := stakingKeeper .GetValidator (ctx , valAddr )
227
+ require .True (t , found )
228
+ _ , err := stakingKeeper .Delegate (ctx , delegator , amt , stakingtypes .Unbonded , val , true )
229
+ require .NoError (t , err )
230
+ }
231
+ }
232
+
233
+ // Create vote message
234
+ msg := govv1 .NewMsgVote (
235
+ delegator ,
236
+ 0 ,
237
+ govv1 .VoteOption_VOTE_OPTION_YES ,
238
+ "new-v1-vote-message-test" ,
239
+ )
240
+
241
+ // Validate vote message
242
+ err := decorator .ValidateVoteMsgs (ctx , []sdk.Msg {msg })
243
+ if tc .expectPass {
244
+ require .NoError (t , err , "expected %v to pass" , tc .name )
245
+ } else {
246
+ require .Error (t , err , "expected %v to fail" , tc .name )
247
+ }
248
+ }
249
+ }
0 commit comments