github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/evm/types/proposal_test.go (about)

     1  package types
     2  
     3  import (
     4  	"math/big"
     5  	"strings"
     6  	"testing"
     7  
     8  	ethcmn "github.com/ethereum/go-ethereum/common"
     9  	"github.com/fibonacci-chain/fbc/libs/tendermint/types"
    10  	govtypes "github.com/fibonacci-chain/fbc/x/gov/types"
    11  	"github.com/stretchr/testify/suite"
    12  )
    13  
    14  const (
    15  	expectedTitle                                           = "default title"
    16  	expectedDescription                                     = "default description"
    17  	expectedManageContractDeploymentWhitelistProposalString = `ManageContractDeploymentWhitelistProposal:
    18   Title:					default title
    19   Description:        	default description
    20   Type:                	ManageContractDeploymentWhitelist
    21   IsAdded:				true
    22   DistributorAddrs:
    23  						fb1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpvmzvy
    24  						fb1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpu60h3k`
    25  	expectedManageContractBlockedListProposalString = `ManageContractBlockedListProposal:
    26   Title:					default title
    27   Description:        	default description
    28   Type:                	ManageContractBlockedList
    29   IsAdded:				true
    30   ContractAddrs:
    31  						fb1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpvmzvy
    32  						fb1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpu60h3k`
    33  	expectedManageContractMethodBlockedListProposalString = `ManageContractMethodBlockedListProposal:
    34   Title:					default title
    35   Description:        	default description
    36   Type:                	ManageContractMethodBlockedList
    37   IsAdded:				true
    38   ContractList:
    39  						Address: fb1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpvmzvy
    40  Method List:
    41  Sign: 0x11111111Extra: TEST1
    42  Sign: 0x22222222Extra: TEST2
    43  						Address: fb1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpu60h3k
    44  Method List:
    45  Sign: 0x33333333Extra: TEST3
    46  Sign: 0x44444444Extra: TEST4`
    47  )
    48  
    49  type ProposalTestSuite struct {
    50  	suite.Suite
    51  	strBuilder          strings.Builder
    52  	addrs               AddressList
    53  	blockedContractList BlockedContractList
    54  }
    55  
    56  func TestProposalTestSuite(t *testing.T) {
    57  	proposalTestSuite := ProposalTestSuite{
    58  		addrs: AddressList{
    59  			ethcmn.BytesToAddress([]byte{0x0}).Bytes(),
    60  			ethcmn.BytesToAddress([]byte{0x1}).Bytes(),
    61  		},
    62  		blockedContractList: BlockedContractList{
    63  			BlockedContract{
    64  				Address: ethcmn.BytesToAddress([]byte{0x0}).Bytes(),
    65  				BlockMethods: ContractMethods{
    66  					ContractMethod{Sign: "0x11111111", Extra: "TEST1"},
    67  					ContractMethod{Sign: "0x22222222", Extra: "TEST2"},
    68  				},
    69  			},
    70  			BlockedContract{
    71  				Address: ethcmn.BytesToAddress([]byte{0x1}).Bytes(),
    72  				BlockMethods: ContractMethods{
    73  					ContractMethod{Sign: "0x33333333", Extra: "TEST3"},
    74  					ContractMethod{Sign: "0x44444444", Extra: "TEST4"},
    75  				},
    76  			},
    77  		},
    78  	}
    79  	suite.Run(t, &proposalTestSuite)
    80  }
    81  
    82  func (suite *ProposalTestSuite) TestProposal_ManageContractDeploymentWhitelistProposal() {
    83  	proposal := NewManageContractDeploymentWhitelistProposal(
    84  		expectedTitle,
    85  		expectedDescription,
    86  		suite.addrs,
    87  		true,
    88  	)
    89  
    90  	suite.Require().Equal(expectedTitle, proposal.GetTitle())
    91  	suite.Require().Equal(expectedDescription, proposal.GetDescription())
    92  	suite.Require().Equal(RouterKey, proposal.ProposalRoute())
    93  	suite.Require().Equal(proposalTypeManageContractDeploymentWhitelist, proposal.ProposalType())
    94  	suite.Require().Equal(expectedManageContractDeploymentWhitelistProposalString, proposal.String())
    95  
    96  	testCases := []struct {
    97  		msg           string
    98  		prepare       func()
    99  		expectedError bool
   100  	}{
   101  		{
   102  			"pass",
   103  			func() {},
   104  			false,
   105  		},
   106  		{
   107  			"empty title",
   108  			func() {
   109  				proposal.Title = ""
   110  			},
   111  			true,
   112  		},
   113  		{
   114  			"overlong title",
   115  			func() {
   116  				for i := 0; i < govtypes.MaxTitleLength+1; i++ {
   117  					suite.strBuilder.WriteByte('a')
   118  				}
   119  				proposal.Title = suite.strBuilder.String()
   120  			},
   121  			true,
   122  		},
   123  		{
   124  			"empty description",
   125  			func() {
   126  				proposal.Description = ""
   127  				proposal.Title = expectedTitle
   128  			},
   129  			true,
   130  		},
   131  		{
   132  			"overlong description",
   133  			func() {
   134  				suite.strBuilder.Reset()
   135  				for i := 0; i < govtypes.MaxDescriptionLength+1; i++ {
   136  					suite.strBuilder.WriteByte('a')
   137  				}
   138  				proposal.Description = suite.strBuilder.String()
   139  			},
   140  			true,
   141  		},
   142  		{
   143  			"duplicated distributor addresses",
   144  			func() {
   145  				// add a duplicated address into DistributorAddrs
   146  				proposal.DistributorAddrs = append(proposal.DistributorAddrs, proposal.DistributorAddrs[0])
   147  				proposal.Description = expectedDescription
   148  			},
   149  			true,
   150  		},
   151  		{
   152  			"empty distributor addresses",
   153  			func() {
   154  				proposal.DistributorAddrs = nil
   155  			},
   156  			true,
   157  		},
   158  		{
   159  			"oversize distributor addresses",
   160  			func() {
   161  				for i := int64(0); i <= maxAddressListLength; i++ {
   162  					testAddr := ethcmn.BigToAddress(big.NewInt(i)).Bytes()
   163  					proposal.DistributorAddrs = append(proposal.DistributorAddrs, testAddr)
   164  				}
   165  			},
   166  			true,
   167  		},
   168  	}
   169  
   170  	for _, tc := range testCases {
   171  		suite.Run(tc.msg, func() {
   172  			tc.prepare()
   173  
   174  			err := proposal.ValidateBasic()
   175  
   176  			if tc.expectedError {
   177  				suite.Require().Error(err)
   178  			} else {
   179  				suite.Require().NoError(err)
   180  			}
   181  		})
   182  	}
   183  }
   184  
   185  func (suite *ProposalTestSuite) TestProposal_ManageContractBlockedListProposal() {
   186  	proposal := NewManageContractBlockedListProposal(
   187  		expectedTitle,
   188  		expectedDescription,
   189  		suite.addrs,
   190  		true,
   191  	)
   192  
   193  	suite.Require().Equal(expectedTitle, proposal.GetTitle())
   194  	suite.Require().Equal(expectedDescription, proposal.GetDescription())
   195  	suite.Require().Equal(RouterKey, proposal.ProposalRoute())
   196  	suite.Require().Equal(proposalTypeManageContractBlockedList, proposal.ProposalType())
   197  	suite.Require().Equal(expectedManageContractBlockedListProposalString, proposal.String())
   198  
   199  	testCases := []struct {
   200  		msg           string
   201  		prepare       func()
   202  		expectedError bool
   203  	}{
   204  		{
   205  			"pass",
   206  			func() {},
   207  			false,
   208  		},
   209  		{
   210  			"empty title",
   211  			func() {
   212  				proposal.Title = ""
   213  			},
   214  			true,
   215  		},
   216  		{
   217  			"overlong title",
   218  			func() {
   219  				for i := 0; i < govtypes.MaxTitleLength+1; i++ {
   220  					suite.strBuilder.WriteByte('a')
   221  				}
   222  				proposal.Title = suite.strBuilder.String()
   223  			},
   224  			true,
   225  		},
   226  		{
   227  			"empty description",
   228  			func() {
   229  				proposal.Description = ""
   230  				proposal.Title = expectedTitle
   231  			},
   232  			true,
   233  		},
   234  		{
   235  			"overlong description",
   236  			func() {
   237  				suite.strBuilder.Reset()
   238  				for i := 0; i < govtypes.MaxDescriptionLength+1; i++ {
   239  					suite.strBuilder.WriteByte('a')
   240  				}
   241  				proposal.Description = suite.strBuilder.String()
   242  			},
   243  			true,
   244  		},
   245  		{
   246  			"duplicated contract addresses",
   247  			func() {
   248  				// add a duplicated address into ContractAddrs
   249  				proposal.ContractAddrs = append(proposal.ContractAddrs, proposal.ContractAddrs[0])
   250  				proposal.Description = expectedDescription
   251  			},
   252  			true,
   253  		},
   254  		{
   255  			"empty contract addresses",
   256  			func() {
   257  				proposal.ContractAddrs = nil
   258  			},
   259  			true,
   260  		},
   261  		{
   262  			"oversize contract addresses",
   263  			func() {
   264  				for i := int64(0); i <= maxAddressListLength; i++ {
   265  					testAddr := ethcmn.BigToAddress(big.NewInt(i)).Bytes()
   266  					proposal.ContractAddrs = append(proposal.ContractAddrs, testAddr)
   267  				}
   268  			},
   269  			true,
   270  		},
   271  	}
   272  
   273  	for _, tc := range testCases {
   274  		suite.Run(tc.msg, func() {
   275  			tc.prepare()
   276  
   277  			err := proposal.ValidateBasic()
   278  
   279  			if tc.expectedError {
   280  				suite.Require().Error(err)
   281  			} else {
   282  				suite.Require().NoError(err)
   283  			}
   284  		})
   285  	}
   286  }
   287  
   288  func (suite *ProposalTestSuite) TestProposal_ManageContractMethodBlockedListProposal() {
   289  	proposal := NewManageContractMethodBlockedListProposal(
   290  		expectedTitle,
   291  		expectedDescription,
   292  		suite.blockedContractList,
   293  		true,
   294  	)
   295  
   296  	suite.Require().Equal(expectedTitle, proposal.GetTitle())
   297  	suite.Require().Equal(expectedDescription, proposal.GetDescription())
   298  	suite.Require().Equal(RouterKey, proposal.ProposalRoute())
   299  	suite.Require().Equal(proposalTypeManageContractMethodBlockedList, proposal.ProposalType())
   300  	suite.Require().Equal(expectedManageContractMethodBlockedListProposalString, proposal.String())
   301  
   302  	testCases := []struct {
   303  		msg           string
   304  		prepare       func()
   305  		expectedError bool
   306  	}{
   307  		{
   308  			"pass",
   309  			func() {},
   310  			false,
   311  		},
   312  		{
   313  			"empty title",
   314  			func() {
   315  				proposal.Title = ""
   316  			},
   317  			true,
   318  		},
   319  		{
   320  			"overlong title",
   321  			func() {
   322  				for i := 0; i < govtypes.MaxTitleLength+1; i++ {
   323  					suite.strBuilder.WriteByte('a')
   324  				}
   325  				proposal.Title = suite.strBuilder.String()
   326  			},
   327  			true,
   328  		},
   329  		{
   330  			"empty description",
   331  			func() {
   332  				proposal.Description = ""
   333  				proposal.Title = expectedTitle
   334  			},
   335  			true,
   336  		},
   337  		{
   338  			"overlong description",
   339  			func() {
   340  				suite.strBuilder.Reset()
   341  				for i := 0; i < govtypes.MaxDescriptionLength+1; i++ {
   342  					suite.strBuilder.WriteByte('a')
   343  				}
   344  				proposal.Description = suite.strBuilder.String()
   345  			},
   346  			true,
   347  		},
   348  		{
   349  			"duplicated contract addresses",
   350  			func() {
   351  				// add a duplicated address into ContractAddrs
   352  				proposal.ContractList = append(proposal.ContractList, proposal.ContractList[0])
   353  				proposal.Description = expectedDescription
   354  			},
   355  			true,
   356  		},
   357  		{
   358  			"empty contract addresses",
   359  			func() {
   360  				proposal.ContractList = nil
   361  			},
   362  			true,
   363  		},
   364  		{
   365  			"oversize contract addresses",
   366  			func() {
   367  				for i := int64(0); i <= maxAddressListLength; i++ {
   368  					testAddr := ethcmn.BigToAddress(big.NewInt(i)).Bytes()
   369  					testbc := BlockedContract{Address: testAddr, BlockMethods: nil}
   370  					proposal.ContractList = append(proposal.ContractList, testbc)
   371  				}
   372  			},
   373  			true,
   374  		},
   375  		{
   376  			"empty contract addresses",
   377  			func() {
   378  				for i := int64(0); i <= maxAddressListLength; i++ {
   379  					testbc := BlockedContract{Address: nil, BlockMethods: nil}
   380  					proposal.ContractList = append(proposal.ContractList, testbc)
   381  				}
   382  			},
   383  			true,
   384  		},
   385  		{
   386  			"duplicated contract method",
   387  			func() {
   388  				proposal.ContractList[0].BlockMethods = append(proposal.ContractList[0].BlockMethods, proposal.ContractList[0].BlockMethods...)
   389  			},
   390  			true,
   391  		},
   392  	}
   393  
   394  	for _, tc := range testCases {
   395  		suite.Run(tc.msg, func() {
   396  			tc.prepare()
   397  
   398  			err := proposal.ValidateBasic()
   399  
   400  			if tc.expectedError {
   401  				suite.Require().Error(err)
   402  			} else {
   403  				suite.Require().NoError(err)
   404  			}
   405  		})
   406  	}
   407  }
   408  
   409  func (suite *ProposalTestSuite) TestProposal_ManageSysContractAddressProposal() {
   410  
   411  	const expectedManageSysContractAddressProposalString = `ManageSysContractAddressProposal:
   412   Title:					default title
   413   Description:        	default description
   414   Type:                	ManageSysContractAddress
   415   ContractAddr:          fb1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpvmzvy
   416   IsAdded:				true`
   417  
   418  	proposal := NewManageSysContractAddressProposal(
   419  		expectedTitle,
   420  		expectedDescription,
   421  		ethcmn.BytesToAddress([]byte{0x0}).Bytes(),
   422  		true,
   423  	)
   424  	types.UnittestOnlySetMilestoneVenus3Height(-1)
   425  	suite.Require().Equal(expectedTitle, proposal.GetTitle())
   426  	suite.Require().Equal(expectedDescription, proposal.GetDescription())
   427  	suite.Require().Equal(RouterKey, proposal.ProposalRoute())
   428  	suite.Require().Equal(proposalTypeManageSysContractAddress, proposal.ProposalType())
   429  	suite.Require().Equal(expectedManageSysContractAddressProposalString, proposal.String())
   430  
   431  	testCases := []struct {
   432  		msg           string
   433  		prepare       func()
   434  		expectedError bool
   435  	}{
   436  		{
   437  			"pass",
   438  			func() {
   439  			},
   440  			false,
   441  		},
   442  		{
   443  			"pass",
   444  			func() {
   445  				proposal.IsAdded = false
   446  				proposal.ContractAddr = nil
   447  			},
   448  			false,
   449  		},
   450  		{
   451  			"empty title",
   452  			func() {
   453  				proposal.Title = ""
   454  			},
   455  			true,
   456  		},
   457  		{
   458  			"overlong title",
   459  			func() {
   460  				for i := 0; i < govtypes.MaxTitleLength+1; i++ {
   461  					suite.strBuilder.WriteByte('a')
   462  				}
   463  				proposal.Title = suite.strBuilder.String()
   464  			},
   465  			true,
   466  		},
   467  		{
   468  			"empty description",
   469  			func() {
   470  				proposal.Description = ""
   471  				proposal.Title = expectedTitle
   472  			},
   473  			true,
   474  		},
   475  		{
   476  			"overlong description",
   477  			func() {
   478  				suite.strBuilder.Reset()
   479  				for i := 0; i < govtypes.MaxDescriptionLength+1; i++ {
   480  					suite.strBuilder.WriteByte('a')
   481  				}
   482  				proposal.Description = suite.strBuilder.String()
   483  			},
   484  			true,
   485  		},
   486  		{
   487  			"is_added true, contract address required",
   488  			func() {
   489  				proposal.IsAdded = true
   490  				proposal.ContractAddr = nil
   491  			},
   492  			true,
   493  		},
   494  	}
   495  
   496  	for _, tc := range testCases {
   497  		suite.Run(tc.msg, func() {
   498  			tc.prepare()
   499  
   500  			err := proposal.ValidateBasic()
   501  
   502  			if tc.expectedError {
   503  				suite.Require().Error(err)
   504  			} else {
   505  				suite.Require().NoError(err)
   506  			}
   507  		})
   508  	}
   509  }
   510  
   511  func (suite *ProposalTestSuite) TestFixShortAddr() {
   512  	testCases := []struct {
   513  		msg           string
   514  		shouldFix     bool
   515  		contractList  BlockedContractList
   516  		expectedFixed bool
   517  	}{
   518  		{
   519  			"pass after fix",
   520  			true,
   521  			[]BlockedContract{{Address: []byte{0x3}}},
   522  			true,
   523  		},
   524  		{
   525  			"not pass if not fix",
   526  			false,
   527  			[]BlockedContract{{Address: []byte{0x3}}},
   528  			false,
   529  		},
   530  	}
   531  	for _, tc := range testCases {
   532  		suite.Run(tc.msg, func() {
   533  
   534  			proposal := NewManageContractMethodBlockedListProposal(
   535  				"default title",
   536  				"default description",
   537  				tc.contractList,
   538  				true,
   539  			)
   540  			if tc.shouldFix {
   541  				proposal.FixShortAddr()
   542  			}
   543  
   544  			if tc.expectedFixed {
   545  				suite.Require().Equal(len(proposal.ContractList[0].Address), 20)
   546  			} else {
   547  				suite.Require().NotEqual(len(proposal.ContractList[0].Address), 20)
   548  			}
   549  		})
   550  	}
   551  }