github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/vmbridge/keeper/evm_test.go (about) 1 package keeper_test 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "errors" 7 "fmt" 8 9 "github.com/ethereum/go-ethereum/accounts/abi" 10 "github.com/ethereum/go-ethereum/common" 11 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 12 sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors" 13 keeper2 "github.com/fibonacci-chain/fbc/x/vmbridge/keeper" 14 "github.com/fibonacci-chain/fbc/x/vmbridge/types" 15 wasmtypes "github.com/fibonacci-chain/fbc/x/wasm/types" 16 17 "math/big" 18 ) 19 20 func (suite *KeeperTestSuite) TestKeeper_SendToEvm() { 21 22 caller := suite.wasmContract.String() 23 contract := suite.evmContract.String() 24 recipient := sdk.AccAddress(common.BigToAddress(big.NewInt(1)).Bytes()).String() 25 amount := sdk.NewInt(1) 26 27 reset := func() { 28 caller = suite.wasmContract.String() 29 contract = suite.evmContract.String() 30 recipient = common.BigToAddress(big.NewInt(1)).String() 31 amount = sdk.NewInt(1) 32 } 33 testCases := []struct { 34 msg string 35 malleate func() 36 postcheck func() 37 error error 38 success bool 39 }{ 40 { 41 "caller(ex wasm),contract(0x),recipient(0x),amount(1)", 42 func() { 43 44 }, 45 func() { 46 aimAddr, err := sdk.AccAddressFromBech32(recipient) 47 suite.Require().NoError(err) 48 balance := suite.queryBalance(common.BytesToAddress(aimAddr.Bytes())) 49 suite.Require().Equal(amount.Int64(), balance.Int64()) 50 }, 51 nil, 52 true, 53 }, 54 { 55 "caller(ex wasm),contract(ex),recipient(0x),amount(1)", 56 func() { 57 temp, err := sdk.AccAddressFromBech32(contract) 58 suite.Require().NoError(err) 59 contract = temp.String() 60 }, 61 func() { 62 aimAddr, err := sdk.AccAddressFromBech32(recipient) 63 suite.Require().NoError(err) 64 balance := suite.queryBalance(common.BytesToAddress(aimAddr.Bytes())) 65 suite.Require().Equal(amount.Int64(), balance.Int64()) 66 }, 67 types.ErrIsNotETHAddr, 68 true, 69 }, 70 { 71 "caller(ex wasm),contract(0x),recipient(ex),amount(1)", 72 func() { 73 temp, err := sdk.AccAddressFromBech32(recipient) 74 suite.Require().NoError(err) 75 recipient = temp.String() 76 }, 77 func() { 78 aimAddr, err := sdk.AccAddressFromBech32(recipient) 79 suite.Require().NoError(err) 80 balance := suite.queryBalance(common.BytesToAddress(aimAddr.Bytes())) 81 suite.Require().Equal(amount.Int64(), balance.Int64()) 82 }, 83 types.ErrIsNotETHAddr, 84 true, 85 }, 86 { 87 "caller(ex wasm),contract(0x),recipient(0x),amount(0)", 88 func() { 89 amount = sdk.NewInt(0) 90 }, 91 func() { 92 aimAddr, err := sdk.AccAddressFromBech32(recipient) 93 suite.Require().NoError(err) 94 balance := suite.queryBalance(common.BytesToAddress(aimAddr.Bytes())) 95 suite.Require().Equal(amount.Int64(), balance.Int64()) 96 }, 97 nil, 98 true, 99 }, 100 { 101 "caller(ex wasm),contract(0x),recipient(0x),amount(-1)", 102 func() { 103 amount = sdk.NewInt(-1) 104 }, 105 func() { 106 107 }, 108 errors.New("[\"execution reverted\",\"0x4e487b710000000000000000000000000000000000000000000000000000000000000011\",\"HexData\",\"0x4e487b710000000000000000000000000000000000000000000000000000000000000011\"]"), 109 true, 110 }, 111 { 112 "caller(ex wasm),contract(0x),recipient(0x wasm),amount(1)", // recipent is not wasm addr but is check in SendToEvmEvent Check. 113 func() { 114 buffer := make([]byte, 32) 115 buffer[31] = 0x1 116 recipient = "0x" + hex.EncodeToString(buffer) 117 }, 118 func() { 119 aimAddr, err := sdk.AccAddressFromBech32(recipient) 120 suite.Require().NoError(err) 121 balance := suite.queryBalance(common.BytesToAddress(aimAddr.Bytes())) 122 suite.Require().Equal(amount.Int64(), balance.Int64()) 123 }, 124 nil, 125 //errors.New("[\"execution reverted\",\"execution reverted:ERC20: mint to the zero address\",\"HexData\",\"0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001f45524332303a206d696e7420746f20746865207a65726f206164647265737300\"]"), 126 true, 127 }, 128 { 129 "caller(ex wasm),contract(0x wasm),recipient(0x),amount(1)", 130 func() { 131 buffer := make([]byte, 32) 132 buffer[31] = 0x1 133 contract = "0x" + hex.EncodeToString(buffer) 134 }, 135 func() { 136 }, 137 errors.New("abi: attempting to unmarshall an empty string while arguments are expected"), 138 true, 139 }, 140 { 141 "caller(ex nowasm),contract(0x),recipient(0x),amount(1)", 142 func() { 143 buffer := make([]byte, 20) 144 buffer[19] = 0x1 145 caller = sdk.AccAddress(buffer).String() 146 }, 147 func() { 148 }, 149 errors.New("execution reverted"), 150 true, 151 }, 152 { 153 "caller(ex wasm is no exist in erc20 contrat),contract(ex),recipient(0x),amount(1)", 154 func() { 155 buffer := make([]byte, 32) 156 buffer[19] = 0x1 157 caller = sdk.AccAddress(buffer).String() 158 }, 159 func() { 160 }, 161 errors.New("execution reverted"), 162 true, 163 }, 164 { 165 "caller(0x wasm),contract(0x),recipient(ex),amount(1)", 166 func() { 167 wasmAddr, err := sdk.AccAddressFromBech32(caller) 168 suite.Require().NoError(err) 169 temp := hex.EncodeToString(wasmAddr.Bytes()) 170 suite.T().Log(temp) 171 caller = "0x" + temp 172 }, 173 func() { 174 }, 175 errors.New("execution reverted"), 176 true, 177 }, 178 } 179 for _, tc := range testCases { 180 suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { 181 suite.SetupTest() 182 reset() 183 tc.malleate() 184 185 success, err := suite.app.VMBridgeKeeper.SendToEvm(suite.ctx, caller, contract, recipient, amount) 186 if tc.error != nil { 187 suite.Require().EqualError(err, tc.error.Error()) 188 } else { 189 suite.Require().NoError(err) 190 suite.Require().Equal(tc.success, success) 191 tc.postcheck() 192 } 193 }) 194 } 195 } 196 197 func (suite *KeeperTestSuite) TestSendToWasmEventHandler_Handle() { 198 contractAccAddr, err := sdk.AccAddressFromBech32("fb1fnkz39vpxmukf6mp78essh8g0hrzp3gy9zqj7f") 199 suite.Require().NoError(err) 200 contract := common.BytesToAddress(contractAccAddr.Bytes()) 201 //addr := sdk.AccAddress{0x1} 202 ethAddr := common.BigToAddress(big.NewInt(1)) 203 var data []byte 204 205 testCases := []struct { 206 msg string 207 malleate func() 208 postcheck func() 209 error error 210 }{ 211 { 212 "normal topic,recipient is 0x", 213 func() { 214 wasmAddrStr := suite.wasmContract.String() 215 input, err := getSendToWasmEventData(wasmAddrStr, ethAddr.String(), big.NewInt(1)) 216 suite.Require().NoError(err) 217 data = input 218 }, 219 func() { 220 queryAddr := sdk.AccAddress(ethAddr.Bytes()) 221 result, err := suite.app.WasmKeeper.QuerySmart(suite.ctx, suite.wasmContract, []byte(fmt.Sprintf("{\"balance\":{\"address\":\"%s\"}}", queryAddr.String()))) 222 suite.Require().NoError(err) 223 suite.Require().Equal("{\"balance\":\"1\"}", string(result)) 224 }, 225 types.ErrIsNotFBCAddr, 226 }, 227 { 228 "normal topic,recipient is ex", 229 func() { 230 wasmAddrStr := suite.wasmContract.String() 231 queryAddr := sdk.AccAddress(ethAddr.Bytes()) 232 input, err := getSendToWasmEventData(wasmAddrStr, queryAddr.String(), big.NewInt(1)) 233 suite.Require().NoError(err) 234 data = input 235 }, 236 func() { 237 queryAddr := sdk.AccAddress(ethAddr.Bytes()) 238 result, err := suite.app.WasmKeeper.QuerySmart(suite.ctx, suite.wasmContract, []byte(fmt.Sprintf("{\"balance\":{\"address\":\"%s\"}}", queryAddr.String()))) 239 suite.Require().NoError(err) 240 suite.Require().Equal("{\"balance\":\"1\"}", string(result)) 241 }, 242 nil, 243 }, 244 { 245 "normal topic,amount is zero", 246 func() { 247 wasmAddrStr := suite.wasmContract.String() 248 queryAddr := sdk.AccAddress(ethAddr.Bytes()) 249 input, err := getSendToWasmEventData(wasmAddrStr, queryAddr.String(), big.NewInt(0)) 250 suite.Require().NoError(err) 251 data = input 252 }, 253 func() { 254 queryAddr := sdk.AccAddress(ethAddr.Bytes()) 255 result, err := suite.app.WasmKeeper.QuerySmart(suite.ctx, suite.wasmContract, []byte(fmt.Sprintf("{\"balance\":{\"address\":\"%s\"}}", queryAddr.String()))) 256 suite.Require().NoError(err) 257 suite.Require().Equal("{\"balance\":\"0\"}", string(result)) 258 }, 259 nil, 260 }, 261 { 262 "error input", 263 func() { 264 data = []byte("ddddddd") 265 }, 266 func() { 267 }, 268 nil, 269 }, 270 { 271 "wasmAddStr is not wasm", 272 func() { 273 wasmAddrStr := sdk.AccAddress(make([]byte, 20)).String() 274 input, err := getSendToWasmEventData(wasmAddrStr, sdk.AccAddress(ethAddr.Bytes()).String(), big.NewInt(1)) 275 suite.Require().NoError(err) 276 data = input 277 }, 278 func() { 279 }, 280 types.ErrIsNotWasmAddr, 281 }, 282 { 283 "wasmAddStr is not exist", 284 func() { 285 wasmAddrStr := sdk.AccAddress(make([]byte, 32)).String() 286 input, err := getSendToWasmEventData(wasmAddrStr, sdk.AccAddress(ethAddr.Bytes()).String(), big.NewInt(1)) 287 suite.Require().NoError(err) 288 data = input 289 }, 290 func() { 291 }, 292 sdkerrors.Wrap(wasmtypes.ErrNotFound, "contract"), 293 }, 294 { 295 "recipient is a error addr", 296 func() { 297 wasmAddrStr := suite.wasmContract.String() 298 input, err := getSendToWasmEventData(wasmAddrStr, "fb111", big.NewInt(1)) 299 suite.Require().NoError(err) 300 data = input 301 }, 302 func() { 303 }, 304 errors.New("decoding bech32 failed: invalid bech32 string length 5"), 305 }, 306 { 307 "caller is not expect", 308 func() { 309 contract = common.BigToAddress(big.NewInt(1000)) 310 wasmAddrStr := suite.wasmContract.String() 311 input, err := getSendToWasmEventData(wasmAddrStr, sdk.AccAddress(ethAddr.Bytes()).String(), big.NewInt(1)) 312 suite.Require().NoError(err) 313 data = input 314 }, 315 func() { 316 }, 317 errors.New("execute wasm contract failed: The Contract addr is not expect)"), 318 }, 319 } 320 for _, tc := range testCases { 321 suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { 322 suite.SetupTest() 323 324 handler := keeper2.NewSendToWasmEventHandler(*suite.keeper) 325 tc.malleate() 326 err := handler.Handle(suite.ctx, contract, data) 327 if tc.error != nil { 328 suite.Require().EqualError(err, tc.error.Error()) 329 } else { 330 suite.Require().NoError(err) 331 tc.postcheck() 332 } 333 }) 334 } 335 } 336 337 func (suite *KeeperTestSuite) TestSendToWasmEvent_Unpack() { 338 ethAddr := common.BigToAddress(big.NewInt(1)) 339 var data []byte 340 341 testCases := []struct { 342 msg string 343 malleate func() 344 postcheck func(wasmAddr string, recipient string, amount sdk.Int, err error) 345 error error 346 }{ 347 { 348 "normal topic", 349 func() { 350 wasmAddrStr := suite.wasmContract.String() 351 input, err := getSendToWasmEventData(wasmAddrStr, ethAddr.String(), big.NewInt(1)) 352 suite.Require().NoError(err) 353 data = input 354 }, 355 func(wasmAddr string, recipient string, amount sdk.Int, err error) { 356 suite.Require().NoError(err) 357 suite.Require().Equal(suite.wasmContract.String(), wasmAddr) 358 suite.Require().Equal(ethAddr.String(), recipient) 359 suite.Require().Equal(big.NewInt(1), amount.BigInt()) 360 }, 361 nil, 362 }, 363 { 364 "recipient is bytes", 365 func() { 366 testABIJson := "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"wasmAddr\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"recipient\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"__OKCSendToWasm\",\"type\":\"event\"}]" 367 368 testABIEvent, err := abi.JSON(bytes.NewReader([]byte(testABIJson))) 369 suite.Require().NoError(err) 370 371 ethAddrAcc, err := sdk.AccAddressFromBech32(ethAddr.String()) 372 suite.Require().NoError(err) 373 input, err := testABIEvent.Events[types.SendToWasmEventName].Inputs.Pack(suite.wasmContract.String(), []byte(ethAddrAcc.String()), big.NewInt(1)) 374 suite.Require().NoError(err) 375 data = input 376 }, 377 func(wasmAddr string, recipient string, amount sdk.Int, err error) { 378 suite.Require().NoError(err) 379 suite.Require().NotEqual(ethAddr.String(), recipient) 380 suite.Require().Equal(big.NewInt(1), amount.BigInt()) 381 }, 382 nil, 383 }, 384 { 385 "wasmAddr is bytes", 386 func() { 387 testABIJson := "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"wasmAddr\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"recipient\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"__OKCSendToWasm\",\"type\":\"event\"}]" 388 389 testABIEvent, err := abi.JSON(bytes.NewReader([]byte(testABIJson))) 390 suite.Require().NoError(err) 391 input, err := testABIEvent.Events[types.SendToWasmEventName].Inputs.Pack([]byte(suite.wasmContract.String()), ethAddr.String(), big.NewInt(1)) 392 suite.Require().NoError(err) 393 data = input 394 }, 395 func(wasmAddr string, recipient string, amount sdk.Int, err error) { 396 suite.Require().NoError(err) 397 suite.Require().Equal(suite.wasmContract.String(), wasmAddr) 398 suite.Require().Equal(ethAddr.String(), recipient) 399 suite.Require().Equal(big.NewInt(1), amount.BigInt()) 400 }, 401 nil, 402 }, 403 { 404 "event __OKCSendToWasm(string,uint256) ", 405 func() { 406 testABIJson := "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"recipient\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"__OKCSendToWasm\",\"type\":\"event\"}]" 407 408 testABIEvent, err := abi.JSON(bytes.NewReader([]byte(testABIJson))) 409 suite.Require().NoError(err) 410 input, err := testABIEvent.Events[types.SendToWasmEventName].Inputs.Pack(ethAddr.String(), big.NewInt(1)) 411 suite.Require().NoError(err) 412 data = input 413 }, 414 func(wasmAddr string, recipient string, amount sdk.Int, err error) { 415 }, 416 errors.New("abi: cannot marshal in to go type: length insufficient 160 require 16417"), 417 }, 418 { 419 "event __OKCSendToWasm(string,string,string,uint256) ", 420 func() { 421 testABIJson := "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"recipient2\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"recipient1\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"recipient\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"__OKCSendToWasm\",\"type\":\"event\"}]" 422 423 testABIEvent, err := abi.JSON(bytes.NewReader([]byte(testABIJson))) 424 suite.Require().NoError(err) 425 input, err := testABIEvent.Events[types.SendToWasmEventName].Inputs.Pack("1", "2", "3", big.NewInt(1)) 426 suite.Require().NoError(err) 427 data = input 428 }, 429 func(wasmAddr string, recipient string, amount sdk.Int, err error) { 430 suite.Require().Equal("1", wasmAddr) 431 suite.Require().Equal("2", recipient) 432 suite.Require().NotEqual(big.NewInt(1), amount.BigInt()) 433 }, 434 nil, 435 //errors.New("argument count mismatch: got 2 for 4"), 436 }, 437 { 438 "amount is negative", 439 func() { 440 testABIJson := "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"wasmAddr\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"recipient\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"int8\",\"name\":\"amount\",\"type\":\"int8\"}],\"name\":\"__OKCSendToWasm\",\"type\":\"event\"}]\n" 441 442 testABIEvent, err := abi.JSON(bytes.NewReader([]byte(testABIJson))) 443 suite.Require().NoError(err) 444 input, err := testABIEvent.Events[types.SendToWasmEventName].Inputs.Pack(suite.wasmContract.String(), ethAddr.String(), int8(-1)) 445 suite.T().Log(testABIEvent.Events[types.SendToWasmEventName].ID, types.SendToWasmEvent.ID) 446 suite.Require().NoError(err) 447 data = input 448 }, 449 func(wasmAddr string, recipient string, amount sdk.Int, err error) { 450 suite.Require().Equal(errors.New("recover err: NewIntFromBigInt() out of bound"), err) 451 suite.Require().Equal(suite.wasmContract.String(), wasmAddr) 452 suite.Require().Equal(ethAddr.String(), recipient) 453 }, 454 nil, 455 }, 456 } 457 458 for _, tc := range testCases { 459 suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { 460 suite.SetupTest() 461 462 tc.malleate() 463 unpacked, err := types.SendToWasmEvent.Inputs.Unpack(data) 464 if tc.error != nil { 465 suite.Require().EqualError(err, tc.error.Error()) 466 } else { 467 suite.Require().NoError(err) 468 feild1, field2, feild3, err := getUnpack(unpacked) 469 tc.postcheck(feild1, field2, feild3, err) 470 } 471 }) 472 } 473 } 474 475 func getUnpack(unpacked []interface{}) (wasmAddr string, recipient string, amount sdk.Int, err error) { 476 defer func() { 477 if r := recover(); r != nil { 478 err = fmt.Errorf("recover err: %v", r) 479 } 480 }() 481 wasmAddr, ok := unpacked[0].(string) 482 if !ok { 483 return wasmAddr, recipient, amount, errors.New("the 1 feild is not string") 484 } 485 486 recipient, ok = unpacked[1].(string) 487 if !ok { 488 return wasmAddr, recipient, amount, errors.New("the 2 feild is not string") 489 } 490 491 temp, ok := unpacked[2].(*big.Int) 492 if !ok { 493 return wasmAddr, recipient, amount, errors.New("the 3 feild is not *big.Int") 494 } 495 amount = sdk.NewIntFromBigInt(temp) 496 return 497 } 498 func getSendToWasmEventData(wasmAddr, recipient string, amount *big.Int) ([]byte, error) { 499 return types.SendToWasmEvent.Inputs.Pack(wasmAddr, recipient, amount) 500 }