github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/wasm/keeper/handler_plugin_encoders_test.go (about) 1 package keeper 2 3 import ( 4 "testing" 5 6 ibcadapter "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/ibc-adapter" 7 8 "github.com/golang/protobuf/proto" 9 //ibctransfertypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/transfer/types" 10 //clienttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types" 11 //channeltypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/04-channel/types" 12 "github.com/stretchr/testify/assert" 13 14 wasmvmtypes "github.com/CosmWasm/wasmvm/types" 15 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 16 banktypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank" 17 18 //distributiontypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/distribution/types" 19 //stakingtypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking/types" 20 "github.com/stretchr/testify/require" 21 22 //"github.com/fibonacci-chain/fbc/x/wasm/keeper/wasmtesting" 23 "github.com/fibonacci-chain/fbc/x/wasm/types" 24 ) 25 26 func TestEncoding(t *testing.T) { 27 var ( 28 addr1 = RandomAccountAddress(t) 29 addr2 = RandomAccountAddress(t) 30 addr3 = RandomAccountAddress(t) 31 invalidAddr = "xrnd1d02kd90n38qvr3qb9qof83fn2d2" 32 ) 33 valAddr := make(sdk.ValAddress, types.SDKAddrLen) 34 valAddr[0] = 12 35 valAddr2 := make(sdk.ValAddress, types.SDKAddrLen) 36 valAddr2[1] = 123 37 38 jsonMsg := types.RawContractMessage(`{"foo": 123}`) 39 coins := sdk.Coins{ 40 sdk.NewInt64Coin("uatom", 12345), 41 sdk.NewInt64Coin("utgd", 54321), 42 } 43 bankMsg := &banktypes.MsgSendAdapter{ 44 FromAddress: addr2.String(), 45 ToAddress: addr1.String(), 46 Amount: sdk.CoinsToCoinAdapters(coins), 47 } 48 bankMsgBin, err := proto.Marshal(bankMsg) 49 require.NoError(t, err) 50 51 cases := map[string]struct { 52 sender sdk.AccAddress 53 srcMsg wasmvmtypes.CosmosMsg 54 srcContractIBCPort string 55 transferPortSource types.ICS20TransferPortSource 56 // set if valid 57 output []ibcadapter.Msg 58 // set if invalid 59 isError bool 60 }{ 61 "simple send": { 62 sender: addr1, 63 srcMsg: wasmvmtypes.CosmosMsg{ 64 Bank: &wasmvmtypes.BankMsg{ 65 Send: &wasmvmtypes.SendMsg{ 66 ToAddress: addr2.String(), 67 Amount: []wasmvmtypes.Coin{ 68 { 69 Denom: "uatom", 70 Amount: "12345000000000000000000", 71 }, 72 { 73 Denom: "usdt", 74 Amount: "54321000000000000000000", 75 }, 76 }, 77 }, 78 }, 79 }, 80 output: []ibcadapter.Msg{ 81 &banktypes.MsgSendAdapter{ 82 FromAddress: addr1.String(), 83 ToAddress: addr2.String(), 84 Amount: sdk.CoinsToCoinAdapters(sdk.Coins{ 85 sdk.NewInt64Coin("uatom", 12345), 86 sdk.NewInt64Coin("usdt", 54321), 87 }), 88 }, 89 }, 90 }, 91 "invalid send amount": { 92 sender: addr1, 93 srcMsg: wasmvmtypes.CosmosMsg{ 94 Bank: &wasmvmtypes.BankMsg{ 95 Send: &wasmvmtypes.SendMsg{ 96 ToAddress: addr2.String(), 97 Amount: []wasmvmtypes.Coin{ 98 { 99 Denom: "uatom", 100 Amount: "123000000000000000000.456", 101 }, 102 }, 103 }, 104 }, 105 }, 106 isError: true, 107 }, 108 "invalid address": { 109 sender: addr1, 110 srcMsg: wasmvmtypes.CosmosMsg{ 111 Bank: &wasmvmtypes.BankMsg{ 112 Send: &wasmvmtypes.SendMsg{ 113 ToAddress: invalidAddr, 114 Amount: []wasmvmtypes.Coin{ 115 { 116 Denom: "uatom", 117 Amount: "7890000000000000000000", 118 }, 119 }, 120 }, 121 }, 122 }, 123 isError: false, // addresses are checked in the handler 124 output: []ibcadapter.Msg{ 125 &banktypes.MsgSendAdapter{ 126 FromAddress: addr1.String(), 127 ToAddress: invalidAddr, 128 Amount: sdk.CoinsToCoinAdapters(sdk.Coins{ 129 sdk.NewInt64Coin("uatom", 7890), 130 }), 131 }, 132 }, 133 }, 134 "wasm execute": { 135 sender: addr1, 136 srcMsg: wasmvmtypes.CosmosMsg{ 137 Wasm: &wasmvmtypes.WasmMsg{ 138 Execute: &wasmvmtypes.ExecuteMsg{ 139 ContractAddr: addr2.String(), 140 Msg: jsonMsg, 141 Funds: []wasmvmtypes.Coin{ 142 { 143 Denom: "eth", 144 Amount: "12000000000000000000", 145 }, 146 }, 147 }, 148 }, 149 }, 150 output: []ibcadapter.Msg{ 151 &types.MsgExecuteContract{ 152 Sender: addr1.String(), 153 Contract: addr2.String(), 154 Msg: jsonMsg, 155 Funds: sdk.CoinsToCoinAdapters(sdk.NewCoins(sdk.NewInt64Coin("eth", 12))), 156 }, 157 }, 158 }, 159 "wasm instantiate": { 160 sender: addr1, 161 srcMsg: wasmvmtypes.CosmosMsg{ 162 Wasm: &wasmvmtypes.WasmMsg{ 163 Instantiate: &wasmvmtypes.InstantiateMsg{ 164 CodeID: 7, 165 Msg: jsonMsg, 166 Funds: []wasmvmtypes.Coin{ 167 { 168 Denom: "eth", 169 Amount: "123000000000000000000", 170 }, 171 }, 172 Label: "myLabel", 173 Admin: addr2.String(), 174 }, 175 }, 176 }, 177 output: []ibcadapter.Msg{ 178 &types.MsgInstantiateContract{ 179 Sender: addr1.String(), 180 CodeID: 7, 181 Label: "myLabel", 182 Msg: jsonMsg, 183 Funds: sdk.CoinsToCoinAdapters(sdk.NewCoins(sdk.NewInt64Coin("eth", 123))), 184 Admin: addr2.String(), 185 }, 186 }, 187 }, 188 "wasm migrate": { 189 sender: addr2, 190 srcMsg: wasmvmtypes.CosmosMsg{ 191 Wasm: &wasmvmtypes.WasmMsg{ 192 Migrate: &wasmvmtypes.MigrateMsg{ 193 ContractAddr: addr1.String(), 194 NewCodeID: 12, 195 Msg: jsonMsg, 196 }, 197 }, 198 }, 199 output: []ibcadapter.Msg{ 200 &types.MsgMigrateContract{ 201 Sender: addr2.String(), 202 Contract: addr1.String(), 203 CodeID: 12, 204 Msg: jsonMsg, 205 }, 206 }, 207 }, 208 "wasm update admin": { 209 sender: addr2, 210 srcMsg: wasmvmtypes.CosmosMsg{ 211 Wasm: &wasmvmtypes.WasmMsg{ 212 UpdateAdmin: &wasmvmtypes.UpdateAdminMsg{ 213 ContractAddr: addr1.String(), 214 Admin: addr3.String(), 215 }, 216 }, 217 }, 218 output: []ibcadapter.Msg{ 219 &types.MsgUpdateAdmin{ 220 Sender: addr2.String(), 221 Contract: addr1.String(), 222 NewAdmin: addr3.String(), 223 }, 224 }, 225 }, 226 "wasm clear admin": { 227 sender: addr2, 228 srcMsg: wasmvmtypes.CosmosMsg{ 229 Wasm: &wasmvmtypes.WasmMsg{ 230 ClearAdmin: &wasmvmtypes.ClearAdminMsg{ 231 ContractAddr: addr1.String(), 232 }, 233 }, 234 }, 235 output: []ibcadapter.Msg{ 236 &types.MsgClearAdmin{ 237 Sender: addr2.String(), 238 Contract: addr1.String(), 239 }, 240 }, 241 }, 242 //"staking delegate": { 243 // sender: addr1, 244 // srcMsg: wasmvmtypes.CosmosMsg{ 245 // Staking: &wasmvmtypes.StakingMsg{ 246 // Delegate: &wasmvmtypes.DelegateMsg{ 247 // Validator: valAddr.String(), 248 // Amount: wasmvmtypes.NewCoin(777, "stake"), 249 // }, 250 // }, 251 // }, 252 // output: []sdk.Msg{ 253 // &stakingtypes.MsgDelegate{ 254 // DelegatorAddress: addr1.String(), 255 // ValidatorAddress: valAddr.String(), 256 // Amount: sdk.NewInt64Coin("stake", 777), 257 // }, 258 // }, 259 //}, 260 //"staking delegate to non-validator": { 261 // sender: addr1, 262 // srcMsg: wasmvmtypes.CosmosMsg{ 263 // Staking: &wasmvmtypes.StakingMsg{ 264 // Delegate: &wasmvmtypes.DelegateMsg{ 265 // Validator: addr2.String(), 266 // Amount: wasmvmtypes.NewCoin(777, "stake"), 267 // }, 268 // }, 269 // }, 270 // isError: false, // fails in the handler 271 // output: []sdk.Msg{ 272 // &stakingtypes.MsgDelegate{ 273 // DelegatorAddress: addr1.String(), 274 // ValidatorAddress: addr2.String(), 275 // Amount: sdk.NewInt64Coin("stake", 777), 276 // }, 277 // }, 278 //}, 279 //"staking undelegate": { 280 // sender: addr1, 281 // srcMsg: wasmvmtypes.CosmosMsg{ 282 // Staking: &wasmvmtypes.StakingMsg{ 283 // Undelegate: &wasmvmtypes.UndelegateMsg{ 284 // Validator: valAddr.String(), 285 // Amount: wasmvmtypes.NewCoin(555, "stake"), 286 // }, 287 // }, 288 // }, 289 // output: []sdk.Msg{ 290 // &stakingtypes.MsgUndelegate{ 291 // DelegatorAddress: addr1.String(), 292 // ValidatorAddress: valAddr.String(), 293 // Amount: sdk.NewInt64Coin("stake", 555), 294 // }, 295 // }, 296 //}, 297 //"staking redelegate": { 298 // sender: addr1, 299 // srcMsg: wasmvmtypes.CosmosMsg{ 300 // Staking: &wasmvmtypes.StakingMsg{ 301 // Redelegate: &wasmvmtypes.RedelegateMsg{ 302 // SrcValidator: valAddr.String(), 303 // DstValidator: valAddr2.String(), 304 // Amount: wasmvmtypes.NewCoin(222, "stake"), 305 // }, 306 // }, 307 // }, 308 // output: []sdk.Msg{ 309 // &stakingtypes.MsgBeginRedelegate{ 310 // DelegatorAddress: addr1.String(), 311 // ValidatorSrcAddress: valAddr.String(), 312 // ValidatorDstAddress: valAddr2.String(), 313 // Amount: sdk.NewInt64Coin("stake", 222), 314 // }, 315 // }, 316 //}, 317 //"staking withdraw (explicit recipient)": { 318 // sender: addr1, 319 // srcMsg: wasmvmtypes.CosmosMsg{ 320 // Distribution: &wasmvmtypes.DistributionMsg{ 321 // WithdrawDelegatorReward: &wasmvmtypes.WithdrawDelegatorRewardMsg{ 322 // Validator: valAddr2.String(), 323 // }, 324 // }, 325 // }, 326 // output: []sdk.Msg{ 327 // &distributiontypes.MsgWithdrawDelegatorReward{ 328 // DelegatorAddress: addr1.String(), 329 // ValidatorAddress: valAddr2.String(), 330 // }, 331 // }, 332 //}, 333 //"staking set withdraw address": { 334 // sender: addr1, 335 // srcMsg: wasmvmtypes.CosmosMsg{ 336 // Distribution: &wasmvmtypes.DistributionMsg{ 337 // SetWithdrawAddress: &wasmvmtypes.SetWithdrawAddressMsg{ 338 // Address: addr2.String(), 339 // }, 340 // }, 341 // }, 342 // output: []sdk.Msg{ 343 // &distributiontypes.MsgSetWithdrawAddress{ 344 // DelegatorAddress: addr1.String(), 345 // WithdrawAddress: addr2.String(), 346 // }, 347 // }, 348 //}, 349 "stargate encoded bank msg": { 350 sender: addr2, 351 srcMsg: wasmvmtypes.CosmosMsg{ 352 Stargate: &wasmvmtypes.StargateMsg{ 353 TypeURL: "/cosmos.bank.v1beta1.MsgSend", 354 Value: bankMsgBin, 355 }, 356 }, 357 output: []ibcadapter.Msg{bankMsg}, 358 }, 359 "stargate encoded invalid typeUrl": { 360 sender: addr2, 361 srcMsg: wasmvmtypes.CosmosMsg{ 362 Stargate: &wasmvmtypes.StargateMsg{ 363 TypeURL: "/cosmos.bank.v2.MsgSend", 364 Value: bankMsgBin, 365 }, 366 }, 367 isError: true, 368 }, 369 //"IBC transfer with block timeout": { 370 // sender: addr1, 371 // srcContractIBCPort: "myIBCPort", 372 // srcMsg: wasmvmtypes.CosmosMsg{ 373 // IBC: &wasmvmtypes.IBCMsg{ 374 // Transfer: &wasmvmtypes.TransferMsg{ 375 // ChannelID: "myChanID", 376 // ToAddress: addr2.String(), 377 // Amount: wasmvmtypes.Coin{ 378 // Denom: "ALX", 379 // Amount: "1", 380 // }, 381 // Timeout: wasmvmtypes.IBCTimeout{ 382 // Block: &wasmvmtypes.IBCTimeoutBlock{Revision: 1, Height: 2}, 383 // }, 384 // }, 385 // }, 386 // }, 387 // transferPortSource: wasmtesting.MockIBCTransferKeeper{GetPortFn: func(ctx sdk.Context) string { 388 // return "myTransferPort" 389 // }}, 390 // output: []sdk.Msg{ 391 // &ibctransfertypes.MsgTransfer{ 392 // SourcePort: "myTransferPort", 393 // SourceChannel: "myChanID", 394 // Token: sdk.Coin{ 395 // Denom: "ALX", 396 // Amount: sdk.NewInt(1), 397 // }, 398 // Sender: addr1.String(), 399 // Receiver: addr2.String(), 400 // TimeoutHeight: clienttypes.Height{RevisionNumber: 1, RevisionHeight: 2}, 401 // }, 402 // }, 403 //}, 404 //"IBC transfer with time timeout": { 405 // sender: addr1, 406 // srcContractIBCPort: "myIBCPort", 407 // srcMsg: wasmvmtypes.CosmosMsg{ 408 // IBC: &wasmvmtypes.IBCMsg{ 409 // Transfer: &wasmvmtypes.TransferMsg{ 410 // ChannelID: "myChanID", 411 // ToAddress: addr2.String(), 412 // Amount: wasmvmtypes.Coin{ 413 // Denom: "ALX", 414 // Amount: "1", 415 // }, 416 // Timeout: wasmvmtypes.IBCTimeout{Timestamp: 100}, 417 // }, 418 // }, 419 // }, 420 // transferPortSource: wasmtesting.MockIBCTransferKeeper{GetPortFn: func(ctx sdk.Context) string { 421 // return "transfer" 422 // }}, 423 // output: []sdk.Msg{ 424 // &ibctransfertypes.MsgTransfer{ 425 // SourcePort: "transfer", 426 // SourceChannel: "myChanID", 427 // Token: sdk.Coin{ 428 // Denom: "ALX", 429 // Amount: sdk.NewInt(1), 430 // }, 431 // Sender: addr1.String(), 432 // Receiver: addr2.String(), 433 // TimeoutTimestamp: 100, 434 // }, 435 // }, 436 //}, 437 //"IBC transfer with time and height timeout": { 438 // sender: addr1, 439 // srcContractIBCPort: "myIBCPort", 440 // srcMsg: wasmvmtypes.CosmosMsg{ 441 // IBC: &wasmvmtypes.IBCMsg{ 442 // Transfer: &wasmvmtypes.TransferMsg{ 443 // ChannelID: "myChanID", 444 // ToAddress: addr2.String(), 445 // Amount: wasmvmtypes.Coin{ 446 // Denom: "ALX", 447 // Amount: "1", 448 // }, 449 // Timeout: wasmvmtypes.IBCTimeout{Timestamp: 100, Block: &wasmvmtypes.IBCTimeoutBlock{Height: 1, Revision: 2}}, 450 // }, 451 // }, 452 // }, 453 // transferPortSource: wasmtesting.MockIBCTransferKeeper{GetPortFn: func(ctx sdk.Context) string { 454 // return "transfer" 455 // }}, 456 // output: []sdk.Msg{ 457 // &ibctransfertypes.MsgTransfer{ 458 // SourcePort: "transfer", 459 // SourceChannel: "myChanID", 460 // Token: sdk.Coin{ 461 // Denom: "ALX", 462 // Amount: sdk.NewInt(1), 463 // }, 464 // Sender: addr1.String(), 465 // Receiver: addr2.String(), 466 // TimeoutTimestamp: 100, 467 // TimeoutHeight: clienttypes.NewHeight(2, 1), 468 // }, 469 // }, 470 //}, 471 //"IBC close channel": { 472 // sender: addr1, 473 // srcContractIBCPort: "myIBCPort", 474 // srcMsg: wasmvmtypes.CosmosMsg{ 475 // IBC: &wasmvmtypes.IBCMsg{ 476 // CloseChannel: &wasmvmtypes.CloseChannelMsg{ 477 // ChannelID: "channel-1", 478 // }, 479 // }, 480 // }, 481 // output: []sdk.Msg{ 482 // &channeltypes.MsgChannelCloseInit{ 483 // PortId: "wasm." + addr1.String(), 484 // ChannelId: "channel-1", 485 // Signer: addr1.String(), 486 // }, 487 // }, 488 //}, 489 //"Gov vote: yes": { 490 // sender: addr1, 491 // srcContractIBCPort: "myIBCPort", 492 // srcMsg: wasmvmtypes.CosmosMsg{ 493 // Gov: &wasmvmtypes.GovMsg{ 494 // Vote: &wasmvmtypes.VoteMsg{ProposalId: 1, Vote: wasmvmtypes.Yes}, 495 // }, 496 // }, 497 // output: []sdk.Msg{ 498 // &govtypes.MsgVote{ 499 // ProposalId: 1, 500 // Voter: addr1.String(), 501 // Option: govtypes.OptionYes, 502 // }, 503 // }, 504 //}, 505 //"Gov vote: No": { 506 // sender: addr1, 507 // srcContractIBCPort: "myIBCPort", 508 // srcMsg: wasmvmtypes.CosmosMsg{ 509 // Gov: &wasmvmtypes.GovMsg{ 510 // Vote: &wasmvmtypes.VoteMsg{ProposalId: 1, Vote: wasmvmtypes.No}, 511 // }, 512 // }, 513 // output: []sdk.Msg{ 514 // &govtypes.MsgVote{ 515 // ProposalId: 1, 516 // Voter: addr1.String(), 517 // Option: govtypes.OptionNo, 518 // }, 519 // }, 520 //}, 521 //"Gov vote: Abstain": { 522 // sender: addr1, 523 // srcContractIBCPort: "myIBCPort", 524 // srcMsg: wasmvmtypes.CosmosMsg{ 525 // Gov: &wasmvmtypes.GovMsg{ 526 // Vote: &wasmvmtypes.VoteMsg{ProposalId: 10, Vote: wasmvmtypes.Abstain}, 527 // }, 528 // }, 529 // output: []sdk.Msg{ 530 // &govtypes.MsgVote{ 531 // ProposalId: 10, 532 // Voter: addr1.String(), 533 // Option: govtypes.OptionAbstain, 534 // }, 535 // }, 536 //}, 537 //"Gov vote: No with veto": { 538 // sender: addr1, 539 // srcContractIBCPort: "myIBCPort", 540 // srcMsg: wasmvmtypes.CosmosMsg{ 541 // Gov: &wasmvmtypes.GovMsg{ 542 // Vote: &wasmvmtypes.VoteMsg{ProposalId: 1, Vote: wasmvmtypes.NoWithVeto}, 543 // }, 544 // }, 545 // output: []sdk.Msg{ 546 // &govtypes.MsgVote{ 547 // ProposalId: 1, 548 // Voter: addr1.String(), 549 // Option: govtypes.OptionNoWithVeto, 550 // }, 551 // }, 552 //}, 553 } 554 encodingConfig := MakeEncodingConfig(t) 555 for name, tc := range cases { 556 t.Run(name, func(t *testing.T) { 557 var ctx sdk.Context 558 encoder := DefaultEncoders(encodingConfig.Marshaler.GetProtocMarshal(), tc.transferPortSource) 559 res, err := encoder.Encode(ctx, tc.sender, tc.srcContractIBCPort, tc.srcMsg) 560 if tc.isError { 561 require.Error(t, err) 562 } else { 563 require.NoError(t, err) 564 assert.Equal(t, tc.output, res) 565 } 566 }) 567 } 568 } 569 570 func TestConvertWasmCoinToSdkCoin(t *testing.T) { 571 specs := map[string]struct { 572 src wasmvmtypes.Coin 573 expErr bool 574 expVal sdk.Coin 575 }{ 576 "all good": { 577 src: wasmvmtypes.Coin{ 578 Denom: "foo", 579 Amount: "1", 580 }, 581 expVal: sdk.NewCoin("foo", sdk.NewIntFromUint64(1)), 582 }, 583 "negative amount": { 584 src: wasmvmtypes.Coin{ 585 Denom: "foo", 586 Amount: "-1", 587 }, 588 expErr: true, 589 }, 590 "denom to short": { 591 src: wasmvmtypes.Coin{ 592 Denom: "f", 593 Amount: "1", 594 }, 595 expErr: false, 596 expVal: sdk.NewCoin("f", sdk.NewIntFromUint64(1)), 597 }, 598 "invalid demum char": { 599 src: wasmvmtypes.Coin{ 600 Denom: "&fff", 601 Amount: "1", 602 }, 603 expErr: true, 604 }, 605 "not a number amount": { 606 src: wasmvmtypes.Coin{ 607 Denom: "foo", 608 Amount: "bar", 609 }, 610 expErr: true, 611 }, 612 } 613 for name, spec := range specs { 614 t.Run(name, func(t *testing.T) { 615 gotVal, gotErr := ConvertWasmCoinToSdkCoin(spec.src) 616 if spec.expErr { 617 require.Error(t, gotErr) 618 return 619 } 620 require.NoError(t, gotErr) 621 got := sdk.Coin{ 622 Denom: gotVal.Denom, 623 Amount: gotVal.Amount.ToDec(), 624 } 625 assert.Equal(t, spec.expVal, got) 626 }) 627 } 628 }