github.com/Finschia/finschia-sdk@v0.49.1/x/foundation/msgs_test.go (about) 1 package foundation_test 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/require" 9 10 "github.com/Finschia/finschia-sdk/crypto/keys/secp256k1" 11 "github.com/Finschia/finschia-sdk/testutil/testdata" 12 sdk "github.com/Finschia/finschia-sdk/types" 13 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 14 "github.com/Finschia/finschia-sdk/x/auth/legacy/legacytx" 15 "github.com/Finschia/finschia-sdk/x/foundation" 16 ) 17 18 func TestMsgUpdateParams(t *testing.T) { 19 addrs := make([]sdk.AccAddress, 1) 20 for i := range addrs { 21 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 22 } 23 24 testCases := map[string]struct { 25 authority sdk.AccAddress 26 params foundation.Params 27 valid bool 28 }{ 29 "handler for MsgUpdateParams removed, ValidateBasic should throw error always": { 30 authority: addrs[0], 31 params: foundation.Params{ 32 FoundationTax: sdk.ZeroDec(), 33 }, 34 valid: false, 35 }, 36 } 37 38 for name, tc := range testCases { 39 t.Run(name, func(t *testing.T) { 40 msg := foundation.MsgUpdateParams{ 41 Authority: tc.authority.String(), 42 Params: tc.params, 43 } 44 45 err := msg.ValidateBasic() 46 require.Error(t, err) 47 require.ErrorIs(t, err, sdkerrors.ErrUnknownRequest) 48 }) 49 msg := foundation.MsgUpdateParams{ 50 addrs[0].String(), 51 foundation.Params{}, 52 } 53 // Note: Dummy test for coverage of deprecated message 54 _ = msg.GetSigners() 55 _ = msg.String() 56 _, _ = msg.Descriptor() 57 _ = msg.GetSignBytes() 58 _, _ = msg.Marshal() 59 msg.ProtoMessage() 60 msg.Reset() 61 _ = msg.Route() 62 _ = msg.Size() 63 _ = msg.Type() 64 _ = msg.XXX_Size() 65 } 66 } 67 68 func TestMsgFundTreasury(t *testing.T) { 69 addrs := make([]sdk.AccAddress, 1) 70 for i := range addrs { 71 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 72 } 73 74 testCases := map[string]struct { 75 from sdk.AccAddress 76 amount sdk.Int 77 valid bool 78 }{ 79 "valid msg": { 80 from: addrs[0], 81 amount: sdk.OneInt(), 82 valid: true, 83 }, 84 "empty from": { 85 amount: sdk.OneInt(), 86 }, 87 "zero amount": { 88 from: addrs[0], 89 amount: sdk.ZeroInt(), 90 }, 91 } 92 93 for name, tc := range testCases { 94 t.Run(name, func(t *testing.T) { 95 msg := foundation.MsgFundTreasury{ 96 From: tc.from.String(), 97 Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, tc.amount)), 98 } 99 100 err := msg.ValidateBasic() 101 if !tc.valid { 102 require.Error(t, err) 103 return 104 } 105 require.NoError(t, err) 106 107 require.Equal(t, []sdk.AccAddress{tc.from}, msg.GetSigners()) 108 }) 109 } 110 } 111 112 func TestMsgWithdrawFromTreasury(t *testing.T) { 113 addrs := make([]sdk.AccAddress, 2) 114 for i := range addrs { 115 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 116 } 117 118 testCases := map[string]struct { 119 authority sdk.AccAddress 120 to sdk.AccAddress 121 amount sdk.Int 122 valid bool 123 }{ 124 "valid msg": { 125 authority: addrs[0], 126 to: addrs[1], 127 amount: sdk.OneInt(), 128 valid: true, 129 }, 130 "empty authority": { 131 to: addrs[1], 132 amount: sdk.OneInt(), 133 }, 134 "empty to": { 135 authority: addrs[0], 136 amount: sdk.OneInt(), 137 }, 138 "zero amount": { 139 authority: addrs[0], 140 to: addrs[1], 141 amount: sdk.ZeroInt(), 142 }, 143 } 144 145 for name, tc := range testCases { 146 t.Run(name, func(t *testing.T) { 147 msg := foundation.MsgWithdrawFromTreasury{ 148 Authority: tc.authority.String(), 149 To: tc.to.String(), 150 Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, tc.amount)), 151 } 152 153 err := msg.ValidateBasic() 154 if !tc.valid { 155 require.Error(t, err) 156 return 157 } 158 require.NoError(t, err) 159 160 require.Equal(t, []sdk.AccAddress{tc.authority}, msg.GetSigners()) 161 }) 162 } 163 } 164 165 func TestMsgUpdateMembers(t *testing.T) { 166 addrs := make([]sdk.AccAddress, 2) 167 for i := range addrs { 168 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 169 } 170 171 testCases := map[string]struct { 172 authority sdk.AccAddress 173 members []foundation.MemberRequest 174 valid bool 175 }{ 176 "valid msg": { 177 authority: addrs[0], 178 members: []foundation.MemberRequest{{ 179 Address: addrs[1].String(), 180 }}, 181 valid: true, 182 }, 183 "empty authority": { 184 members: []foundation.MemberRequest{{ 185 Address: addrs[1].String(), 186 }}, 187 }, 188 "empty requests": { 189 authority: addrs[0], 190 }, 191 "invalid requests": { 192 authority: addrs[0], 193 members: []foundation.MemberRequest{{}}, 194 }, 195 } 196 197 for name, tc := range testCases { 198 t.Run(name, func(t *testing.T) { 199 msg := foundation.MsgUpdateMembers{ 200 Authority: tc.authority.String(), 201 MemberUpdates: tc.members, 202 } 203 204 err := msg.ValidateBasic() 205 if !tc.valid { 206 require.Error(t, err) 207 return 208 } 209 require.NoError(t, err) 210 211 require.Equal(t, []sdk.AccAddress{tc.authority}, msg.GetSigners()) 212 }) 213 } 214 } 215 216 func TestMsgUpdateDecisionPolicy(t *testing.T) { 217 addrs := make([]sdk.AccAddress, 1) 218 for i := range addrs { 219 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 220 } 221 222 testCases := map[string]struct { 223 authority sdk.AccAddress 224 policy foundation.DecisionPolicy 225 valid bool 226 }{ 227 "valid threshold policy": { 228 authority: addrs[0], 229 policy: &foundation.ThresholdDecisionPolicy{ 230 Threshold: sdk.OneDec(), 231 Windows: &foundation.DecisionPolicyWindows{ 232 VotingPeriod: time.Hour, 233 }, 234 }, 235 valid: true, 236 }, 237 "valid percentage policy": { 238 authority: addrs[0], 239 policy: &foundation.PercentageDecisionPolicy{ 240 Percentage: sdk.OneDec(), 241 Windows: &foundation.DecisionPolicyWindows{ 242 VotingPeriod: time.Hour, 243 }, 244 }, 245 valid: true, 246 }, 247 "empty authority": { 248 policy: &foundation.ThresholdDecisionPolicy{ 249 Threshold: sdk.OneDec(), 250 Windows: &foundation.DecisionPolicyWindows{ 251 VotingPeriod: time.Hour, 252 }, 253 }, 254 }, 255 "empty policy": { 256 authority: addrs[0], 257 }, 258 "zero threshold": { 259 authority: addrs[0], 260 policy: &foundation.ThresholdDecisionPolicy{ 261 Threshold: sdk.ZeroDec(), 262 Windows: &foundation.DecisionPolicyWindows{ 263 VotingPeriod: time.Hour, 264 }, 265 }, 266 }, 267 "zero voting period": { 268 authority: addrs[0], 269 policy: &foundation.ThresholdDecisionPolicy{ 270 Threshold: sdk.OneDec(), 271 Windows: &foundation.DecisionPolicyWindows{}, 272 }, 273 }, 274 "invalid percentage": { 275 authority: addrs[0], 276 policy: &foundation.PercentageDecisionPolicy{ 277 Percentage: sdk.NewDec(2), 278 Windows: &foundation.DecisionPolicyWindows{ 279 VotingPeriod: time.Hour, 280 }, 281 }, 282 }, 283 } 284 285 for name, tc := range testCases { 286 t.Run(name, func(t *testing.T) { 287 msg := foundation.MsgUpdateDecisionPolicy{ 288 Authority: tc.authority.String(), 289 } 290 if tc.policy != nil { 291 err := msg.SetDecisionPolicy(tc.policy) 292 require.NoError(t, err) 293 } 294 295 err := msg.ValidateBasic() 296 if !tc.valid { 297 require.Error(t, err) 298 return 299 } 300 require.NoError(t, err) 301 302 require.Equal(t, []sdk.AccAddress{tc.authority}, msg.GetSigners()) 303 }) 304 } 305 } 306 307 func TestMsgSubmitProposal(t *testing.T) { 308 addrs := make([]sdk.AccAddress, 1) 309 for i := range addrs { 310 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 311 } 312 313 testCases := map[string]struct { 314 proposers []sdk.AccAddress 315 msgs []sdk.Msg 316 exec foundation.Exec 317 valid bool 318 }{ 319 "valid msg": { 320 proposers: []sdk.AccAddress{addrs[0]}, 321 msgs: []sdk.Msg{testdata.NewTestMsg()}, 322 valid: true, 323 }, 324 "empty proposers": { 325 msgs: []sdk.Msg{testdata.NewTestMsg()}, 326 }, 327 "invalid proposer": { 328 proposers: []sdk.AccAddress{nil}, 329 msgs: []sdk.Msg{testdata.NewTestMsg()}, 330 }, 331 "duplicate proposers": { 332 proposers: []sdk.AccAddress{addrs[0], addrs[0]}, 333 msgs: []sdk.Msg{testdata.NewTestMsg()}, 334 }, 335 "empty msgs": { 336 proposers: []sdk.AccAddress{addrs[0]}, 337 }, 338 "invalid msg": { 339 proposers: []sdk.AccAddress{addrs[0]}, 340 msgs: []sdk.Msg{&foundation.MsgWithdrawFromTreasury{}}, 341 }, 342 "invalid exec": { 343 proposers: []sdk.AccAddress{addrs[0]}, 344 msgs: []sdk.Msg{testdata.NewTestMsg()}, 345 exec: -1, 346 }, 347 } 348 349 for name, tc := range testCases { 350 t.Run(name, func(t *testing.T) { 351 var proposers []string 352 for _, proposer := range tc.proposers { 353 proposers = append(proposers, proposer.String()) 354 } 355 356 msg := foundation.MsgSubmitProposal{ 357 Proposers: proposers, 358 Exec: tc.exec, 359 } 360 err := msg.SetMsgs(tc.msgs) 361 require.NoError(t, err) 362 363 err = msg.ValidateBasic() 364 if !tc.valid { 365 require.Error(t, err) 366 return 367 } 368 require.NoError(t, err) 369 370 require.Equal(t, tc.proposers, msg.GetSigners()) 371 }) 372 } 373 } 374 375 func TestMsgWithdrawProposal(t *testing.T) { 376 addrs := make([]sdk.AccAddress, 1) 377 for i := range addrs { 378 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 379 } 380 381 testCases := map[string]struct { 382 id uint64 383 address sdk.AccAddress 384 valid bool 385 }{ 386 "valid msg": { 387 id: 1, 388 address: addrs[0], 389 valid: true, 390 }, 391 "empty proposal id": { 392 address: addrs[0], 393 }, 394 "empty address": { 395 id: 1, 396 }, 397 } 398 399 for name, tc := range testCases { 400 t.Run(name, func(t *testing.T) { 401 msg := foundation.MsgWithdrawProposal{ 402 ProposalId: tc.id, 403 Address: tc.address.String(), 404 } 405 406 err := msg.ValidateBasic() 407 if !tc.valid { 408 require.Error(t, err) 409 return 410 } 411 require.NoError(t, err) 412 413 require.Equal(t, []sdk.AccAddress{tc.address}, msg.GetSigners()) 414 }) 415 } 416 } 417 418 func TestMsgVote(t *testing.T) { 419 addrs := make([]sdk.AccAddress, 1) 420 for i := range addrs { 421 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 422 } 423 424 testCases := map[string]struct { 425 id uint64 426 voter sdk.AccAddress 427 option foundation.VoteOption 428 exec foundation.Exec 429 valid bool 430 }{ 431 "valid msg": { 432 id: 1, 433 voter: addrs[0], 434 option: foundation.VOTE_OPTION_YES, 435 valid: true, 436 }, 437 "empty proposal id": { 438 voter: addrs[0], 439 option: foundation.VOTE_OPTION_YES, 440 }, 441 "empty voter": { 442 id: 1, 443 option: foundation.VOTE_OPTION_YES, 444 }, 445 "empty option": { 446 id: 1, 447 voter: addrs[0], 448 }, 449 "invalid option": { 450 id: 1, 451 voter: addrs[0], 452 option: -1, 453 }, 454 "invalid exec": { 455 id: 1, 456 voter: addrs[0], 457 option: foundation.VOTE_OPTION_YES, 458 exec: -1, 459 }, 460 } 461 462 for name, tc := range testCases { 463 t.Run(name, func(t *testing.T) { 464 msg := foundation.MsgVote{ 465 ProposalId: tc.id, 466 Voter: tc.voter.String(), 467 Option: tc.option, 468 Exec: tc.exec, 469 } 470 471 err := msg.ValidateBasic() 472 if !tc.valid { 473 require.Error(t, err) 474 return 475 } 476 require.NoError(t, err) 477 478 require.Equal(t, []sdk.AccAddress{tc.voter}, msg.GetSigners()) 479 }) 480 } 481 } 482 483 func TestMsgExec(t *testing.T) { 484 addrs := make([]sdk.AccAddress, 1) 485 for i := range addrs { 486 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 487 } 488 489 testCases := map[string]struct { 490 id uint64 491 signer sdk.AccAddress 492 valid bool 493 }{ 494 "valid msg": { 495 id: 1, 496 signer: addrs[0], 497 valid: true, 498 }, 499 "empty proposal id": { 500 signer: addrs[0], 501 }, 502 "empty signer": { 503 id: 1, 504 }, 505 } 506 507 for name, tc := range testCases { 508 t.Run(name, func(t *testing.T) { 509 msg := foundation.MsgExec{ 510 ProposalId: tc.id, 511 Signer: tc.signer.String(), 512 } 513 514 err := msg.ValidateBasic() 515 if !tc.valid { 516 require.Error(t, err) 517 return 518 } 519 require.NoError(t, err) 520 521 require.Equal(t, []sdk.AccAddress{tc.signer}, msg.GetSigners()) 522 }) 523 } 524 } 525 526 func TestMsgLeaveFoundation(t *testing.T) { 527 addrs := make([]sdk.AccAddress, 1) 528 for i := range addrs { 529 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 530 } 531 532 testCases := map[string]struct { 533 address sdk.AccAddress 534 valid bool 535 }{ 536 "valid msg": { 537 address: addrs[0], 538 valid: true, 539 }, 540 "empty address": {}, 541 } 542 543 for name, tc := range testCases { 544 t.Run(name, func(t *testing.T) { 545 msg := foundation.MsgLeaveFoundation{ 546 Address: tc.address.String(), 547 } 548 549 err := msg.ValidateBasic() 550 if !tc.valid { 551 require.Error(t, err) 552 return 553 } 554 require.NoError(t, err) 555 556 require.Equal(t, []sdk.AccAddress{tc.address}, msg.GetSigners()) 557 }) 558 } 559 } 560 561 func TestMsgGrant(t *testing.T) { 562 addrs := make([]sdk.AccAddress, 2) 563 for i := range addrs { 564 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 565 } 566 567 testCases := map[string]struct { 568 authority sdk.AccAddress 569 grantee sdk.AccAddress 570 authorization foundation.Authorization 571 valid bool 572 }{ 573 "valid msg": { 574 authority: addrs[0], 575 grantee: addrs[1], 576 authorization: &foundation.ReceiveFromTreasuryAuthorization{}, 577 valid: true, 578 }, 579 "empty authority": { 580 grantee: addrs[1], 581 authorization: &foundation.ReceiveFromTreasuryAuthorization{}, 582 }, 583 "empty grantee": { 584 authority: addrs[0], 585 authorization: &foundation.ReceiveFromTreasuryAuthorization{}, 586 }, 587 "empty authorization": { 588 authority: addrs[0], 589 grantee: addrs[1], 590 }, 591 } 592 593 for name, tc := range testCases { 594 t.Run(name, func(t *testing.T) { 595 msg := foundation.MsgGrant{ 596 Authority: tc.authority.String(), 597 Grantee: tc.grantee.String(), 598 } 599 if tc.authorization != nil { 600 err := msg.SetAuthorization(tc.authorization) 601 require.NoError(t, err) 602 } 603 604 err := msg.ValidateBasic() 605 if !tc.valid { 606 require.Error(t, err) 607 return 608 } 609 require.NoError(t, err) 610 611 require.Equal(t, []sdk.AccAddress{tc.authority}, msg.GetSigners()) 612 }) 613 } 614 } 615 616 func TestMsgRevoke(t *testing.T) { 617 addrs := make([]sdk.AccAddress, 2) 618 for i := range addrs { 619 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 620 } 621 622 testCases := map[string]struct { 623 authority sdk.AccAddress 624 grantee sdk.AccAddress 625 msgTypeURL string 626 valid bool 627 }{ 628 "valid msg": { 629 authority: addrs[0], 630 grantee: addrs[1], 631 msgTypeURL: foundation.ReceiveFromTreasuryAuthorization{}.MsgTypeURL(), 632 valid: true, 633 }, 634 "empty authority": { 635 grantee: addrs[1], 636 msgTypeURL: foundation.ReceiveFromTreasuryAuthorization{}.MsgTypeURL(), 637 }, 638 "empty grantee": { 639 authority: addrs[0], 640 msgTypeURL: foundation.ReceiveFromTreasuryAuthorization{}.MsgTypeURL(), 641 }, 642 "empty url": { 643 authority: addrs[0], 644 grantee: addrs[1], 645 }, 646 } 647 648 for name, tc := range testCases { 649 t.Run(name, func(t *testing.T) { 650 msg := foundation.MsgRevoke{ 651 Authority: tc.authority.String(), 652 Grantee: tc.grantee.String(), 653 MsgTypeUrl: tc.msgTypeURL, 654 } 655 656 err := msg.ValidateBasic() 657 if !tc.valid { 658 require.Error(t, err) 659 return 660 } 661 require.NoError(t, err) 662 663 require.Equal(t, []sdk.AccAddress{tc.authority}, msg.GetSigners()) 664 }) 665 } 666 } 667 668 func TestAminoJSON(t *testing.T) { 669 addrs := make([]sdk.AccAddress, 3) 670 for i := range addrs { 671 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 672 } 673 674 testCases := map[string]struct { 675 msg legacytx.LegacyMsg 676 expected string 677 }{ 678 "MsgFundTreasury": { 679 &foundation.MsgFundTreasury{ 680 From: addrs[0].String(), 681 Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), 682 }, 683 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgFundTreasury\",\"value\":{\"amount\":[{\"amount\":\"1\",\"denom\":\"stake\"}],\"from\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 684 }, 685 "MsgVote": { 686 &foundation.MsgVote{ 687 ProposalId: 1, 688 Voter: addrs[0].String(), 689 Option: foundation.VOTE_OPTION_YES, 690 Metadata: "I'm YES", 691 Exec: foundation.Exec_EXEC_UNSPECIFIED, 692 }, 693 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgVote\",\"value\":{\"metadata\":\"I'm YES\",\"option\":1,\"proposal_id\":\"1\",\"voter\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 694 }, 695 "MsgExec": { 696 &foundation.MsgExec{ 697 ProposalId: 1, 698 Signer: addrs[0].String(), 699 }, 700 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgExec\",\"value\":{\"proposal_id\":\"1\",\"signer\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 701 }, 702 "MsgLeaveFoundation": { 703 &foundation.MsgLeaveFoundation{Address: addrs[0].String()}, 704 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgLeaveFoundation\",\"value\":{\"address\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 705 }, 706 "MsgWithdrawProposal": { 707 &foundation.MsgWithdrawProposal{ 708 ProposalId: 1, 709 Address: addrs[0].String(), 710 }, 711 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgWithdrawProposal\",\"value\":{\"address\":\"%s\",\"proposal_id\":\"1\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 712 }, 713 } 714 715 for name, tc := range testCases { 716 t.Run(name, func(t *testing.T) { 717 require.Equal(t, tc.expected, string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{tc.msg}, "memo"))) 718 }) 719 } 720 } 721 722 func TestMsgSubmitProposalAminoJSON(t *testing.T) { 723 addrs := make([]sdk.AccAddress, 2) 724 for i := range addrs { 725 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 726 } 727 728 proposer := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 729 730 testCases := map[string]struct { 731 msg sdk.Msg 732 expected string 733 }{ 734 "MsgUpdateParams": { 735 &foundation.MsgUpdateParams{ 736 Authority: addrs[0].String(), 737 Params: foundation.Params{FoundationTax: sdk.ZeroDec()}, 738 }, 739 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgSubmitProposal\",\"value\":{\"exec\":1,\"messages\":[{\"type\":\"lbm-sdk/MsgUpdateParams\",\"value\":{\"authority\":\"%s\",\"params\":{\"foundation_tax\":\"0.000000000000000000\"}}}],\"metadata\":\"MsgUpdateParams\",\"proposers\":[\"%s\"]}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), proposer.String()), 740 }, 741 "MsgWithdrawFromTreasury": { 742 &foundation.MsgWithdrawFromTreasury{ 743 Authority: addrs[0].String(), 744 To: addrs[1].String(), 745 Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1000000))), 746 }, 747 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgSubmitProposal\",\"value\":{\"exec\":1,\"messages\":[{\"type\":\"lbm-sdk/MsgWithdrawFromTreasury\",\"value\":{\"amount\":[{\"amount\":\"1000000\",\"denom\":\"stake\"}],\"authority\":\"%s\",\"to\":\"%s\"}}],\"metadata\":\"MsgWithdrawFromTreasury\",\"proposers\":[\"%s\"]}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String(), proposer.String()), 748 }, 749 "MsgUpdateMembers": { 750 &foundation.MsgUpdateMembers{ 751 Authority: addrs[0].String(), 752 MemberUpdates: []foundation.MemberRequest{{ 753 Address: addrs[1].String(), 754 }}, 755 }, 756 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgSubmitProposal\",\"value\":{\"exec\":1,\"messages\":[{\"type\":\"lbm-sdk/MsgUpdateMembers\",\"value\":{\"authority\":\"%s\",\"member_updates\":[{\"address\":\"%s\"}]}}],\"metadata\":\"MsgUpdateMembers\",\"proposers\":[\"%s\"]}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String(), proposer.String()), 757 }, 758 "MsgUpdateCensorship": { 759 &foundation.MsgUpdateCensorship{ 760 Authority: addrs[0].String(), 761 Censorship: foundation.Censorship{ 762 MsgTypeUrl: sdk.MsgTypeURL((*foundation.MsgWithdrawFromTreasury)(nil)), 763 Authority: foundation.CensorshipAuthorityGovernance, 764 }, 765 }, 766 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgSubmitProposal\",\"value\":{\"exec\":1,\"messages\":[{\"type\":\"lbm-sdk/MsgUpdateCensorship\",\"value\":{\"authority\":\"%s\",\"censorship\":{\"authority\":1,\"msg_type_url\":\"/lbm.foundation.v1.MsgWithdrawFromTreasury\"}}}],\"metadata\":\"MsgUpdateCensorship\",\"proposers\":[\"%s\"]}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), proposer.String()), 767 }, 768 "MsgRevoke": { 769 &foundation.MsgRevoke{ 770 Authority: addrs[0].String(), 771 Grantee: addrs[1].String(), 772 MsgTypeUrl: foundation.ReceiveFromTreasuryAuthorization{}.MsgTypeURL(), 773 }, 774 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgSubmitProposal\",\"value\":{\"exec\":1,\"messages\":[{\"type\":\"lbm-sdk/MsgRevoke\",\"value\":{\"authority\":\"%s\",\"grantee\":\"%s\",\"msg_type_url\":\"/lbm.foundation.v1.MsgWithdrawFromTreasury\"}}],\"metadata\":\"MsgRevoke\",\"proposers\":[\"%s\"]}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String(), proposer.String()), 775 }, 776 } 777 778 for name, tc := range testCases { 779 t.Run(name, func(t *testing.T) { 780 proposalMsg := &foundation.MsgSubmitProposal{ 781 Proposers: []string{proposer.String()}, 782 Metadata: name, 783 Exec: foundation.Exec_EXEC_TRY, 784 } 785 err := proposalMsg.SetMsgs([]sdk.Msg{tc.msg}) 786 require.NoError(t, err) 787 require.Equal(t, tc.expected, string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{proposalMsg}, "memo"))) 788 }) 789 } 790 } 791 792 func TestMsgUpdateDecisionPolicyAminoJson(t *testing.T) { 793 var ( 794 authority = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 795 proposer = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 796 ) 797 798 testCases := map[string]struct { 799 policy foundation.DecisionPolicy 800 expected string 801 }{ 802 "ThresholdDecisionPolicy": { 803 &foundation.ThresholdDecisionPolicy{ 804 Threshold: sdk.OneDec(), 805 Windows: &foundation.DecisionPolicyWindows{ 806 VotingPeriod: time.Hour, 807 }, 808 }, 809 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgSubmitProposal\",\"value\":{\"exec\":1,\"messages\":[{\"type\":\"lbm-sdk/MsgUpdateDecisionPolicy\",\"value\":{\"authority\":\"%s\",\"decision_policy\":{\"type\":\"lbm-sdk/ThresholdDecisionPolicy\",\"value\":{\"threshold\":\"1.000000000000000000\",\"windows\":{\"min_execution_period\":\"0\",\"voting_period\":\"3600000000000\"}}}}}],\"metadata\":\"ThresholdDecisionPolicy\",\"proposers\":[\"%s\"]}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", authority, proposer), 810 }, 811 "PercentageDecisionPolicy": { 812 &foundation.PercentageDecisionPolicy{ 813 Percentage: sdk.OneDec(), 814 Windows: &foundation.DecisionPolicyWindows{ 815 VotingPeriod: time.Hour, 816 }, 817 }, 818 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgSubmitProposal\",\"value\":{\"exec\":1,\"messages\":[{\"type\":\"lbm-sdk/MsgUpdateDecisionPolicy\",\"value\":{\"authority\":\"%s\",\"decision_policy\":{\"type\":\"lbm-sdk/PercentageDecisionPolicy\",\"value\":{\"percentage\":\"1.000000000000000000\",\"windows\":{\"min_execution_period\":\"0\",\"voting_period\":\"3600000000000\"}}}}}],\"metadata\":\"PercentageDecisionPolicy\",\"proposers\":[\"%s\"]}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", authority, proposer), 819 }, 820 } 821 822 for name, tc := range testCases { 823 t.Run(name, func(t *testing.T) { 824 policyMsg := &foundation.MsgUpdateDecisionPolicy{ 825 Authority: authority.String(), 826 } 827 err := policyMsg.SetDecisionPolicy(tc.policy) 828 require.NoError(t, err) 829 830 err = policyMsg.ValidateBasic() 831 require.NoError(t, err) 832 833 proposalMsg := &foundation.MsgSubmitProposal{ 834 Proposers: []string{proposer.String()}, 835 Metadata: name, 836 Exec: foundation.Exec_EXEC_TRY, 837 } 838 err = proposalMsg.SetMsgs([]sdk.Msg{policyMsg}) 839 require.NoError(t, err) 840 841 require.Equal(t, tc.expected, string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{proposalMsg}, "memo"))) 842 }) 843 } 844 } 845 846 func TestMsgGrantAminoJson(t *testing.T) { 847 var ( 848 operator = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 849 grantee = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 850 proposer = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 851 ) 852 853 testCases := map[string]struct { 854 authorization foundation.Authorization 855 expected string 856 }{ 857 "ReceiveFromTreasuryAuthorization": { 858 &foundation.ReceiveFromTreasuryAuthorization{}, 859 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgSubmitProposal\",\"value\":{\"exec\":1,\"messages\":[{\"type\":\"lbm-sdk/MsgGrant\",\"value\":{\"authority\":\"%s\",\"authorization\":{\"type\":\"lbm-sdk/ReceiveFromTreasuryAuthorization\",\"value\":{}},\"grantee\":\"%s\"}}],\"metadata\":\"ReceiveFromTreasuryAuthorization\",\"proposers\":[\"%s\"]}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", operator.String(), grantee.String(), proposer.String()), 860 }, 861 } 862 863 for name, tc := range testCases { 864 t.Run(name, func(t *testing.T) { 865 grantMsg := &foundation.MsgGrant{ 866 Authority: operator.String(), 867 Grantee: grantee.String(), 868 } 869 err := grantMsg.SetAuthorization(tc.authorization) 870 require.NoError(t, err) 871 872 err = grantMsg.ValidateBasic() 873 require.NoError(t, err) 874 875 proposalMsg := &foundation.MsgSubmitProposal{ 876 Proposers: []string{proposer.String()}, 877 Metadata: name, 878 Exec: foundation.Exec_EXEC_TRY, 879 } 880 err = proposalMsg.SetMsgs([]sdk.Msg{grantMsg}) 881 require.NoError(t, err) 882 883 require.Equal(t, tc.expected, string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{proposalMsg}, "memo"))) 884 }) 885 } 886 }