|
1 | 1 | package vm |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "errors" |
4 | 5 | "fmt" |
5 | 6 | "math" |
6 | 7 | "math/big" |
7 | 8 |
|
8 | 9 | "github.com/ethereum/go-ethereum/common" |
9 | 10 | "github.com/ethereum/go-ethereum/core" |
| 11 | + ethtypes "github.com/ethereum/go-ethereum/core/types" |
10 | 12 | gethtypes "github.com/ethereum/go-ethereum/core/types" |
11 | 13 | "github.com/ethereum/go-ethereum/params" |
12 | 14 |
|
@@ -624,6 +626,173 @@ func (s *KeeperTestSuite) TestApplyTransaction() { |
624 | 626 | } |
625 | 627 | } |
626 | 628 |
|
| 629 | +type testHooks struct { |
| 630 | + postProcessing func(ctx sdk.Context, sender common.Address, msg core.Message, receipt *ethtypes.Receipt) error |
| 631 | +} |
| 632 | + |
| 633 | +func (h *testHooks) PostTxProcessing(ctx sdk.Context, sender common.Address, msg core.Message, receipt *ethtypes.Receipt) error { |
| 634 | + return h.postProcessing(ctx, sender, msg, receipt) |
| 635 | +} |
| 636 | + |
| 637 | +func (s *KeeperTestSuite) TestApplyTransactionWithTxPostProcessing() { |
| 638 | + s.EnableFeemarket = true |
| 639 | + defer func() { s.EnableFeemarket = false }() |
| 640 | + |
| 641 | + testCases := []struct { |
| 642 | + name string |
| 643 | + setup func(s *KeeperTestSuite) |
| 644 | + do func(s *KeeperTestSuite) |
| 645 | + after func(s *KeeperTestSuite) |
| 646 | + }{ |
| 647 | + { |
| 648 | + "pass - evm tx succeeds, post processing is called, the balance is changed", |
| 649 | + func(s *KeeperTestSuite) { |
| 650 | + s.Network.App.GetEVMKeeper().SetHooks( |
| 651 | + keeper.NewMultiEvmHooks( |
| 652 | + &testHooks{ |
| 653 | + postProcessing: func(ctx sdk.Context, sender common.Address, msg core.Message, receipt *ethtypes.Receipt) error { |
| 654 | + return nil |
| 655 | + }, |
| 656 | + }, |
| 657 | + ), |
| 658 | + ) |
| 659 | + }, |
| 660 | + func(s *KeeperTestSuite) { |
| 661 | + senderBefore := s.Network.App.GetBankKeeper().GetBalance(s.Network.GetContext(), s.Keyring.GetAccAddr(0), "aatom").Amount |
| 662 | + recipientBefore := s.Network.App.GetBankKeeper().GetBalance(s.Network.GetContext(), s.Keyring.GetAccAddr(1), "aatom").Amount |
| 663 | + |
| 664 | + // Generate a transfer tx message |
| 665 | + sender := s.Keyring.GetKey(0) |
| 666 | + recipient := s.Keyring.GetAddr(1) |
| 667 | + transferAmt := big.NewInt(100) |
| 668 | + |
| 669 | + tx, err := s.Factory.GenerateSignedEthTx(sender.Priv, types.EvmTxArgs{ |
| 670 | + To: &recipient, |
| 671 | + Amount: transferAmt, |
| 672 | + }) |
| 673 | + s.Require().NoError(err) |
| 674 | + |
| 675 | + ethMsg := tx.GetMsgs()[0].(*types.MsgEthereumTx) |
| 676 | + res, err := s.Network.App.GetEVMKeeper().ApplyTransaction(s.Network.GetContext(), ethMsg.AsTransaction()) |
| 677 | + s.Require().NoError(err) |
| 678 | + s.Require().False(res.Failed()) |
| 679 | + |
| 680 | + senderAfter := s.Network.App.GetBankKeeper().GetBalance(s.Network.GetContext(), s.Keyring.GetAccAddr(0), "aatom").Amount |
| 681 | + recipientAfter := s.Network.App.GetBankKeeper().GetBalance(s.Network.GetContext(), s.Keyring.GetAccAddr(1), "aatom").Amount |
| 682 | + s.Require().Equal(senderBefore.Sub(sdkmath.NewIntFromBigInt(transferAmt)), senderAfter) |
| 683 | + s.Require().Equal(recipientBefore.Add(sdkmath.NewIntFromBigInt(transferAmt)), recipientAfter) |
| 684 | + }, |
| 685 | + func(s *KeeperTestSuite) {}, |
| 686 | + }, |
| 687 | + { |
| 688 | + "pass - evm tx succeeds, post processing is called but fails, the balance is unchanged", |
| 689 | + func(s *KeeperTestSuite) { |
| 690 | + s.Network.App.GetEVMKeeper().SetHooks( |
| 691 | + keeper.NewMultiEvmHooks( |
| 692 | + &testHooks{ |
| 693 | + postProcessing: func(ctx sdk.Context, sender common.Address, msg core.Message, receipt *ethtypes.Receipt) error { |
| 694 | + return errors.New("post processing failed :(") |
| 695 | + }, |
| 696 | + }, |
| 697 | + ), |
| 698 | + ) |
| 699 | + }, |
| 700 | + func(s *KeeperTestSuite) { |
| 701 | + senderBefore := s.Network.App.GetBankKeeper().GetBalance(s.Network.GetContext(), s.Keyring.GetAccAddr(0), "aatom").Amount |
| 702 | + recipientBefore := s.Network.App.GetBankKeeper().GetBalance(s.Network.GetContext(), s.Keyring.GetAccAddr(1), "aatom").Amount |
| 703 | + |
| 704 | + // Generate a transfer tx message |
| 705 | + sender := s.Keyring.GetKey(0) |
| 706 | + recipient := s.Keyring.GetAddr(1) |
| 707 | + transferAmt := big.NewInt(100) |
| 708 | + |
| 709 | + tx, err := s.Factory.GenerateSignedEthTx(sender.Priv, types.EvmTxArgs{ |
| 710 | + To: &recipient, |
| 711 | + Amount: transferAmt, |
| 712 | + }) |
| 713 | + s.Require().NoError(err) |
| 714 | + |
| 715 | + ethMsg := tx.GetMsgs()[0].(*types.MsgEthereumTx) |
| 716 | + res, err := s.Network.App.GetEVMKeeper().ApplyTransaction(s.Network.GetContext(), ethMsg.AsTransaction()) |
| 717 | + s.Require().NoError(err) |
| 718 | + s.Require().True(res.Failed()) |
| 719 | + |
| 720 | + senderAfter := s.Network.App.GetBankKeeper().GetBalance(s.Network.GetContext(), s.Keyring.GetAccAddr(0), "aatom").Amount |
| 721 | + recipientAfter := s.Network.App.GetBankKeeper().GetBalance(s.Network.GetContext(), s.Keyring.GetAccAddr(1), "aatom").Amount |
| 722 | + s.Require().Equal(senderBefore, senderAfter) |
| 723 | + s.Require().Equal(recipientBefore, recipientAfter) |
| 724 | + }, |
| 725 | + func(s *KeeperTestSuite) {}, |
| 726 | + }, |
| 727 | + { |
| 728 | + "evm tx fails, post processing is called and persisted, the balance is not changed", |
| 729 | + func(s *KeeperTestSuite) { |
| 730 | + s.Network.App.GetEVMKeeper().SetHooks( |
| 731 | + keeper.NewMultiEvmHooks( |
| 732 | + &testHooks{ |
| 733 | + postProcessing: func(ctx sdk.Context, sender common.Address, msg core.Message, receipt *ethtypes.Receipt) error { |
| 734 | + return s.Network.App.GetMintKeeper().MintCoins( |
| 735 | + ctx, sdk.NewCoins(sdk.NewCoin("arandomcoin", sdkmath.NewInt(100))), |
| 736 | + ) |
| 737 | + }, |
| 738 | + }, |
| 739 | + ), |
| 740 | + ) |
| 741 | + }, |
| 742 | + func(s *KeeperTestSuite) { |
| 743 | + senderBefore := s.Network.App.GetBankKeeper().GetBalance(s.Network.GetContext(), s.Keyring.GetAccAddr(0), "aatom").Amount |
| 744 | + recipientBefore := s.Network.App.GetBankKeeper().GetBalance(s.Network.GetContext(), s.Keyring.GetAccAddr(1), "aatom").Amount |
| 745 | + |
| 746 | + // Generate a transfer tx message |
| 747 | + sender := s.Keyring.GetKey(0) |
| 748 | + recipient := s.Keyring.GetAddr(1) |
| 749 | + transferAmt := senderBefore.Add(sdkmath.NewInt(100)) // transfer more than the balance |
| 750 | + |
| 751 | + tx, err := s.Factory.GenerateSignedEthTx(sender.Priv, types.EvmTxArgs{ |
| 752 | + To: &recipient, |
| 753 | + Amount: transferAmt.BigInt(), |
| 754 | + }) |
| 755 | + s.Require().NoError(err) |
| 756 | + |
| 757 | + ethMsg := tx.GetMsgs()[0].(*types.MsgEthereumTx) |
| 758 | + res, err := s.Network.App.GetEVMKeeper().ApplyTransaction(s.Network.GetContext(), ethMsg.AsTransaction()) |
| 759 | + s.Require().NoError(err) |
| 760 | + s.Require().True(res.Failed()) |
| 761 | + |
| 762 | + senderAfter := s.Network.App.GetBankKeeper().GetBalance(s.Network.GetContext(), s.Keyring.GetAccAddr(0), "aatom").Amount |
| 763 | + recipientAfter := s.Network.App.GetBankKeeper().GetBalance(s.Network.GetContext(), s.Keyring.GetAccAddr(1), "aatom").Amount |
| 764 | + s.Require().Equal(senderBefore, senderAfter) |
| 765 | + s.Require().Equal(recipientBefore, recipientAfter) |
| 766 | + }, |
| 767 | + func(s *KeeperTestSuite) { |
| 768 | + // check if the mint module has "arandomcoin" in its balance, it was minted in the post processing, proving that the post processing was called |
| 769 | + // and that it can persist state even when the tx fails |
| 770 | + balance := s.Network.App.GetBankKeeper().GetBalance(s.Network.GetContext(), s.Network.App.GetAccountKeeper().GetModuleAddress("mint"), "arandomcoin") |
| 771 | + s.Require().Equal(sdkmath.NewInt(100), balance.Amount) |
| 772 | + }, |
| 773 | + }, |
| 774 | + } |
| 775 | + |
| 776 | + for _, tc := range testCases { |
| 777 | + s.Run(fmt.Sprintf("Case %s", tc.name), func() { |
| 778 | + s.SetupTest() |
| 779 | + |
| 780 | + tc.setup(s) |
| 781 | + |
| 782 | + // set bounded cosmos block gas limit |
| 783 | + ctx := s.Network.GetContext().WithBlockGasMeter(storetypes.NewGasMeter(1e6)) |
| 784 | + err := s.Network.App.GetBankKeeper().MintCoins(ctx, "mint", sdk.NewCoins(sdk.NewCoin("aatom", sdkmath.NewInt(3e18)))) |
| 785 | + s.Require().NoError(err) |
| 786 | + err = s.Network.App.GetBankKeeper().SendCoinsFromModuleToModule(ctx, "mint", "fee_collector", sdk.NewCoins(sdk.NewCoin("aatom", sdkmath.NewInt(3e18)))) |
| 787 | + s.Require().NoError(err) |
| 788 | + |
| 789 | + tc.do(s) |
| 790 | + |
| 791 | + tc.after(s) |
| 792 | + }) |
| 793 | + } |
| 794 | +} |
| 795 | + |
627 | 796 | func (s *KeeperTestSuite) TestApplyMessage() { |
628 | 797 | s.EnableFeemarket = true |
629 | 798 | defer func() { s.EnableFeemarket = false }() |
|
0 commit comments