github.com/Finschia/finschia-sdk@v0.48.1/x/foundation/msgs_test.go (about) 1 package foundation_test 2 3 import ( 4 "fmt" 5 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 6 "testing" 7 "time" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/Finschia/finschia-sdk/crypto/keys/secp256k1" 12 "github.com/Finschia/finschia-sdk/testutil/testdata" 13 sdk "github.com/Finschia/finschia-sdk/types" 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 msg.SetAuthorization(tc.authorization) 601 } 602 603 err := msg.ValidateBasic() 604 if !tc.valid { 605 require.Error(t, err) 606 return 607 } 608 require.NoError(t, err) 609 610 require.Equal(t, []sdk.AccAddress{tc.authority}, msg.GetSigners()) 611 }) 612 } 613 } 614 615 func TestMsgRevoke(t *testing.T) { 616 addrs := make([]sdk.AccAddress, 2) 617 for i := range addrs { 618 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 619 } 620 621 testCases := map[string]struct { 622 authority sdk.AccAddress 623 grantee sdk.AccAddress 624 msgTypeURL string 625 valid bool 626 }{ 627 "valid msg": { 628 authority: addrs[0], 629 grantee: addrs[1], 630 msgTypeURL: foundation.ReceiveFromTreasuryAuthorization{}.MsgTypeURL(), 631 valid: true, 632 }, 633 "empty authority": { 634 grantee: addrs[1], 635 msgTypeURL: foundation.ReceiveFromTreasuryAuthorization{}.MsgTypeURL(), 636 }, 637 "empty grantee": { 638 authority: addrs[0], 639 msgTypeURL: foundation.ReceiveFromTreasuryAuthorization{}.MsgTypeURL(), 640 }, 641 "empty url": { 642 authority: addrs[0], 643 grantee: addrs[1], 644 }, 645 } 646 647 for name, tc := range testCases { 648 t.Run(name, func(t *testing.T) { 649 msg := foundation.MsgRevoke{ 650 Authority: tc.authority.String(), 651 Grantee: tc.grantee.String(), 652 MsgTypeUrl: tc.msgTypeURL, 653 } 654 655 err := msg.ValidateBasic() 656 if !tc.valid { 657 require.Error(t, err) 658 return 659 } 660 require.NoError(t, err) 661 662 require.Equal(t, []sdk.AccAddress{tc.authority}, msg.GetSigners()) 663 }) 664 } 665 } 666 667 func TestAminoJSON(t *testing.T) { 668 addrs := make([]sdk.AccAddress, 3) 669 for i := range addrs { 670 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 671 } 672 673 testCases := map[string]struct { 674 msg legacytx.LegacyMsg 675 expected string 676 }{ 677 "MsgFundTreasury": { 678 &foundation.MsgFundTreasury{ 679 From: addrs[0].String(), 680 Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())), 681 }, 682 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()), 683 }, 684 "MsgVote": { 685 &foundation.MsgVote{ 686 ProposalId: 1, 687 Voter: addrs[0].String(), 688 Option: foundation.VOTE_OPTION_YES, 689 Metadata: "I'm YES", 690 Exec: foundation.Exec_EXEC_UNSPECIFIED, 691 }, 692 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()), 693 }, 694 "MsgExec": { 695 &foundation.MsgExec{ 696 ProposalId: 1, 697 Signer: addrs[0].String(), 698 }, 699 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()), 700 }, 701 "MsgLeaveFoundation": { 702 &foundation.MsgLeaveFoundation{Address: addrs[0].String()}, 703 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()), 704 }, 705 "MsgWithdrawProposal": { 706 &foundation.MsgWithdrawProposal{ 707 ProposalId: 1, 708 Address: addrs[0].String(), 709 }, 710 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()), 711 }, 712 } 713 714 for name, tc := range testCases { 715 tc := tc 716 717 t.Run(name, func(t *testing.T) { 718 require.Equal(t, tc.expected, string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{tc.msg}, "memo"))) 719 }) 720 } 721 } 722 723 func TestMsgSubmitProposalAminoJSON(t *testing.T) { 724 addrs := make([]sdk.AccAddress, 2) 725 for i := range addrs { 726 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 727 } 728 729 var proposer = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 730 731 testCases := map[string]struct { 732 msg sdk.Msg 733 expected string 734 }{ 735 "MsgUpdateParams": { 736 &foundation.MsgUpdateParams{ 737 Authority: addrs[0].String(), 738 Params: foundation.Params{FoundationTax: sdk.ZeroDec()}, 739 }, 740 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()), 741 }, 742 "MsgWithdrawFromTreasury": { 743 &foundation.MsgWithdrawFromTreasury{ 744 Authority: addrs[0].String(), 745 To: addrs[1].String(), 746 Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1000000))), 747 }, 748 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()), 749 }, 750 "MsgUpdateMembers": { 751 &foundation.MsgUpdateMembers{ 752 Authority: addrs[0].String(), 753 MemberUpdates: []foundation.MemberRequest{{ 754 Address: addrs[1].String(), 755 }}, 756 }, 757 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()), 758 }, 759 "MsgUpdateCensorship": { 760 &foundation.MsgUpdateCensorship{ 761 Authority: addrs[0].String(), 762 Censorship: foundation.Censorship{ 763 MsgTypeUrl: sdk.MsgTypeURL((*foundation.MsgWithdrawFromTreasury)(nil)), 764 Authority: foundation.CensorshipAuthorityGovernance, 765 }, 766 }, 767 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()), 768 }, 769 "MsgRevoke": { 770 &foundation.MsgRevoke{ 771 Authority: addrs[0].String(), 772 Grantee: addrs[1].String(), 773 MsgTypeUrl: foundation.ReceiveFromTreasuryAuthorization{}.MsgTypeURL(), 774 }, 775 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()), 776 }, 777 } 778 779 for name, tc := range testCases { 780 tc := tc 781 782 t.Run(name, func(t *testing.T) { 783 proposalMsg := &foundation.MsgSubmitProposal{ 784 Proposers: []string{proposer.String()}, 785 Metadata: name, 786 Exec: foundation.Exec_EXEC_TRY, 787 } 788 err := proposalMsg.SetMsgs([]sdk.Msg{tc.msg}) 789 require.NoError(t, err) 790 require.Equal(t, tc.expected, string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{proposalMsg}, "memo"))) 791 }) 792 } 793 } 794 795 func TestMsgUpdateDecisionPolicyAminoJson(t *testing.T) { 796 var ( 797 authority = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 798 proposer = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 799 ) 800 801 testCases := map[string]struct { 802 policy foundation.DecisionPolicy 803 expected string 804 }{ 805 "ThresholdDecisionPolicy": { 806 &foundation.ThresholdDecisionPolicy{ 807 Threshold: sdk.OneDec(), 808 Windows: &foundation.DecisionPolicyWindows{ 809 VotingPeriod: time.Hour, 810 }, 811 }, 812 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), 813 }, 814 "PercentageDecisionPolicy": { 815 &foundation.PercentageDecisionPolicy{ 816 Percentage: sdk.OneDec(), 817 Windows: &foundation.DecisionPolicyWindows{ 818 VotingPeriod: time.Hour, 819 }, 820 }, 821 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), 822 }, 823 } 824 825 for name, tc := range testCases { 826 tc := tc 827 828 t.Run(name, func(t *testing.T) { 829 policyMsg := &foundation.MsgUpdateDecisionPolicy{ 830 Authority: authority.String(), 831 } 832 err := policyMsg.SetDecisionPolicy(tc.policy) 833 require.NoError(t, err) 834 835 err = policyMsg.ValidateBasic() 836 require.NoError(t, err) 837 838 proposalMsg := &foundation.MsgSubmitProposal{ 839 Proposers: []string{proposer.String()}, 840 Metadata: name, 841 Exec: foundation.Exec_EXEC_TRY, 842 } 843 err = proposalMsg.SetMsgs([]sdk.Msg{policyMsg}) 844 require.NoError(t, err) 845 846 require.Equal(t, tc.expected, string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{proposalMsg}, "memo"))) 847 }) 848 } 849 } 850 851 func TestMsgGrantAminoJson(t *testing.T) { 852 var ( 853 operator = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 854 grantee = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 855 proposer = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 856 ) 857 858 testCases := map[string]struct { 859 authorization foundation.Authorization 860 expected string 861 }{ 862 "ReceiveFromTreasuryAuthorization": { 863 &foundation.ReceiveFromTreasuryAuthorization{}, 864 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()), 865 }, 866 } 867 868 for name, tc := range testCases { 869 tc := tc 870 871 t.Run(name, func(t *testing.T) { 872 grantMsg := &foundation.MsgGrant{ 873 Authority: operator.String(), 874 Grantee: grantee.String(), 875 } 876 err := grantMsg.SetAuthorization(tc.authorization) 877 require.NoError(t, err) 878 879 err = grantMsg.ValidateBasic() 880 require.NoError(t, err) 881 882 proposalMsg := &foundation.MsgSubmitProposal{ 883 Proposers: []string{proposer.String()}, 884 Metadata: name, 885 Exec: foundation.Exec_EXEC_TRY, 886 } 887 err = proposalMsg.SetMsgs([]sdk.Msg{grantMsg}) 888 require.NoError(t, err) 889 890 require.Equal(t, tc.expected, string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{proposalMsg}, "memo"))) 891 }) 892 } 893 }