github.com/MetalBlockchain/subnet-evm@v0.6.3/params/precompile_config_test.go (about)

     1  // (c) 2022 Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package params
     5  
     6  import (
     7  	"encoding/json"
     8  	"math/big"
     9  	"testing"
    10  
    11  	"github.com/MetalBlockchain/subnet-evm/commontype"
    12  	"github.com/MetalBlockchain/subnet-evm/precompile/contracts/deployerallowlist"
    13  	"github.com/MetalBlockchain/subnet-evm/precompile/contracts/feemanager"
    14  	"github.com/MetalBlockchain/subnet-evm/precompile/contracts/nativeminter"
    15  	"github.com/MetalBlockchain/subnet-evm/precompile/contracts/rewardmanager"
    16  	"github.com/MetalBlockchain/subnet-evm/precompile/contracts/txallowlist"
    17  	"github.com/MetalBlockchain/subnet-evm/utils"
    18  	"github.com/ethereum/go-ethereum/common"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  func TestVerifyWithChainConfig(t *testing.T) {
    23  	admins := []common.Address{{1}}
    24  	baseConfig := *TestChainConfig
    25  	config := &baseConfig
    26  	config.GenesisPrecompiles = Precompiles{
    27  		txallowlist.ConfigKey: txallowlist.NewConfig(utils.NewUint64(2), nil, nil, nil),
    28  	}
    29  	config.PrecompileUpgrades = []PrecompileUpgrade{
    30  		{
    31  			// disable TxAllowList at timestamp 4
    32  			txallowlist.NewDisableConfig(utils.NewUint64(4)),
    33  		},
    34  		{
    35  			// re-enable TxAllowList at timestamp 5
    36  			txallowlist.NewConfig(utils.NewUint64(5), admins, nil, nil),
    37  		},
    38  	}
    39  
    40  	// check this config is valid
    41  	err := config.Verify()
    42  	require.NoError(t, err)
    43  
    44  	// same precompile cannot be configured twice for the same timestamp
    45  	badConfig := *config
    46  	badConfig.PrecompileUpgrades = append(
    47  		badConfig.PrecompileUpgrades,
    48  		PrecompileUpgrade{
    49  			Config: txallowlist.NewDisableConfig(utils.NewUint64(5)),
    50  		},
    51  	)
    52  	err = badConfig.Verify()
    53  	require.ErrorContains(t, err, "config block timestamp (5) <= previous timestamp (5) of same key")
    54  
    55  	// cannot enable a precompile without disabling it first.
    56  	badConfig = *config
    57  	badConfig.PrecompileUpgrades = append(
    58  		badConfig.PrecompileUpgrades,
    59  		PrecompileUpgrade{
    60  			Config: txallowlist.NewConfig(utils.NewUint64(5), admins, nil, nil),
    61  		},
    62  	)
    63  	err = badConfig.Verify()
    64  	require.ErrorContains(t, err, "disable should be [true]")
    65  }
    66  
    67  func TestVerifyWithChainConfigAtNilTimestamp(t *testing.T) {
    68  	admins := []common.Address{{0}}
    69  	baseConfig := *TestChainConfig
    70  	config := &baseConfig
    71  	config.PrecompileUpgrades = []PrecompileUpgrade{
    72  		// this does NOT enable the precompile, so it should be upgradeable.
    73  		{Config: txallowlist.NewConfig(nil, nil, nil, nil)},
    74  	}
    75  	require.False(t, config.IsPrecompileEnabled(txallowlist.ContractAddress, 0)) // check the precompile is not enabled.
    76  	config.PrecompileUpgrades = []PrecompileUpgrade{
    77  		{
    78  			// enable TxAllowList at timestamp 5
    79  			Config: txallowlist.NewConfig(utils.NewUint64(5), admins, nil, nil),
    80  		},
    81  	}
    82  
    83  	// check this config is valid
    84  	require.NoError(t, config.Verify())
    85  }
    86  
    87  func TestVerifyPrecompileUpgrades(t *testing.T) {
    88  	admins := []common.Address{{1}}
    89  	tests := []struct {
    90  		name          string
    91  		upgrades      []PrecompileUpgrade
    92  		expectedError string
    93  	}{
    94  		{
    95  			name: "enable and disable tx allow list",
    96  			upgrades: []PrecompileUpgrade{
    97  				{
    98  					Config: txallowlist.NewConfig(utils.NewUint64(1), admins, nil, nil),
    99  				},
   100  				{
   101  					Config: txallowlist.NewDisableConfig(utils.NewUint64(2)),
   102  				},
   103  			},
   104  			expectedError: "",
   105  		},
   106  		{
   107  			name: "invalid allow list config in tx allowlist",
   108  			upgrades: []PrecompileUpgrade{
   109  				{
   110  					Config: txallowlist.NewConfig(utils.NewUint64(1), admins, nil, nil),
   111  				},
   112  				{
   113  					Config: txallowlist.NewDisableConfig(utils.NewUint64(2)),
   114  				},
   115  				{
   116  					Config: txallowlist.NewConfig(utils.NewUint64(3), admins, admins, admins),
   117  				},
   118  			},
   119  			expectedError: "cannot set address",
   120  		},
   121  		{
   122  			name: "invalid initial fee manager config",
   123  			upgrades: []PrecompileUpgrade{
   124  				{
   125  					Config: feemanager.NewConfig(utils.NewUint64(3), admins, nil, nil,
   126  						func() *commontype.FeeConfig {
   127  							feeConfig := DefaultFeeConfig
   128  							feeConfig.GasLimit = big.NewInt(-1)
   129  							return &feeConfig
   130  						}()),
   131  				},
   132  			},
   133  			expectedError: "gasLimit = -1 cannot be less than or equal to 0",
   134  		},
   135  		{
   136  			name: "invalid initial fee manager config gas limit 0",
   137  			upgrades: []PrecompileUpgrade{
   138  				{
   139  					Config: feemanager.NewConfig(utils.NewUint64(3), admins, nil, nil,
   140  						func() *commontype.FeeConfig {
   141  							feeConfig := DefaultFeeConfig
   142  							feeConfig.GasLimit = common.Big0
   143  							return &feeConfig
   144  						}()),
   145  				},
   146  			},
   147  			expectedError: "gasLimit = 0 cannot be less than or equal to 0",
   148  		},
   149  		{
   150  			name: "different upgrades are allowed to configure same timestamp for different precompiles",
   151  			upgrades: []PrecompileUpgrade{
   152  				{
   153  					Config: txallowlist.NewConfig(utils.NewUint64(1), admins, nil, nil),
   154  				},
   155  				{
   156  					Config: feemanager.NewConfig(utils.NewUint64(1), admins, nil, nil, nil),
   157  				},
   158  			},
   159  			expectedError: "",
   160  		},
   161  		{
   162  			name: "different upgrades must be monotonically increasing",
   163  			upgrades: []PrecompileUpgrade{
   164  				{
   165  					Config: txallowlist.NewConfig(utils.NewUint64(2), admins, nil, nil),
   166  				},
   167  				{
   168  					Config: feemanager.NewConfig(utils.NewUint64(1), admins, nil, nil, nil),
   169  				},
   170  			},
   171  			expectedError: "config block timestamp (1) < previous timestamp (2)",
   172  		},
   173  		{
   174  			name: "upgrades with same keys are not allowed to configure same timestamp for same precompiles",
   175  			upgrades: []PrecompileUpgrade{
   176  				{
   177  					Config: txallowlist.NewConfig(utils.NewUint64(1), admins, nil, nil),
   178  				},
   179  				{
   180  					Config: txallowlist.NewDisableConfig(utils.NewUint64(1)),
   181  				},
   182  			},
   183  			expectedError: "config block timestamp (1) <= previous timestamp (1) of same key",
   184  		},
   185  	}
   186  	for _, tt := range tests {
   187  		t.Run(tt.name, func(t *testing.T) {
   188  			require := require.New(t)
   189  			baseConfig := *TestChainConfig
   190  			config := &baseConfig
   191  			config.PrecompileUpgrades = tt.upgrades
   192  
   193  			err := config.Verify()
   194  			if tt.expectedError == "" {
   195  				require.NoError(err)
   196  			} else {
   197  				require.ErrorContains(err, tt.expectedError)
   198  			}
   199  		})
   200  	}
   201  }
   202  
   203  func TestVerifyPrecompiles(t *testing.T) {
   204  	admins := []common.Address{{1}}
   205  	tests := []struct {
   206  		name          string
   207  		precompiles   Precompiles
   208  		expectedError string
   209  	}{
   210  		{
   211  			name: "invalid allow list config in tx allowlist",
   212  			precompiles: Precompiles{
   213  				txallowlist.ConfigKey: txallowlist.NewConfig(utils.NewUint64(3), admins, admins, admins),
   214  			},
   215  			expectedError: "cannot set address",
   216  		},
   217  		{
   218  			name: "invalid initial fee manager config",
   219  			precompiles: Precompiles{
   220  				feemanager.ConfigKey: feemanager.NewConfig(utils.NewUint64(3), admins, nil, nil,
   221  					func() *commontype.FeeConfig {
   222  						feeConfig := DefaultFeeConfig
   223  						feeConfig.GasLimit = big.NewInt(-1)
   224  						return &feeConfig
   225  					}()),
   226  			},
   227  			expectedError: "gasLimit = -1 cannot be less than or equal to 0",
   228  		},
   229  	}
   230  	for _, tt := range tests {
   231  		t.Run(tt.name, func(t *testing.T) {
   232  			require := require.New(t)
   233  			baseConfig := *TestChainConfig
   234  			config := &baseConfig
   235  			config.GenesisPrecompiles = tt.precompiles
   236  
   237  			err := config.Verify()
   238  			if tt.expectedError == "" {
   239  				require.NoError(err)
   240  			} else {
   241  				require.ErrorContains(err, tt.expectedError)
   242  			}
   243  		})
   244  	}
   245  }
   246  
   247  func TestVerifyRequiresSortedTimestamps(t *testing.T) {
   248  	admins := []common.Address{{1}}
   249  	baseConfig := *TestChainConfig
   250  	config := &baseConfig
   251  	config.PrecompileUpgrades = []PrecompileUpgrade{
   252  		{
   253  			Config: txallowlist.NewConfig(utils.NewUint64(2), admins, nil, nil),
   254  		},
   255  		{
   256  			Config: deployerallowlist.NewConfig(utils.NewUint64(1), admins, nil, nil),
   257  		},
   258  	}
   259  
   260  	// block timestamps must be monotonically increasing, so this config is invalid
   261  	err := config.Verify()
   262  	require.ErrorContains(t, err, "config block timestamp (1) < previous timestamp (2)")
   263  }
   264  
   265  func TestGetPrecompileConfig(t *testing.T) {
   266  	require := require.New(t)
   267  	baseConfig := *TestChainConfig
   268  	config := &baseConfig
   269  	config.GenesisPrecompiles = Precompiles{
   270  		deployerallowlist.ConfigKey: deployerallowlist.NewConfig(utils.NewUint64(10), nil, nil, nil),
   271  	}
   272  
   273  	deployerConfig := config.getActivePrecompileConfig(deployerallowlist.ContractAddress, 0)
   274  	require.Nil(deployerConfig)
   275  
   276  	deployerConfig = config.getActivePrecompileConfig(deployerallowlist.ContractAddress, 10)
   277  	require.NotNil(deployerConfig)
   278  
   279  	deployerConfig = config.getActivePrecompileConfig(deployerallowlist.ContractAddress, 11)
   280  	require.NotNil(deployerConfig)
   281  
   282  	txAllowListConfig := config.getActivePrecompileConfig(txallowlist.ContractAddress, 0)
   283  	require.Nil(txAllowListConfig)
   284  }
   285  
   286  func TestPrecompileUpgradeUnmarshalJSON(t *testing.T) {
   287  	require := require.New(t)
   288  
   289  	upgradeBytes := []byte(`
   290  			{
   291  				"precompileUpgrades": [
   292  					{
   293  						"rewardManagerConfig": {
   294  							"blockTimestamp": 1671542573,
   295  							"adminAddresses": [
   296  								"0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"
   297  							],
   298  							"initialRewardConfig": {
   299  								"allowFeeRecipients": true
   300  							}
   301  						}
   302  					},
   303  					{
   304  						"contractNativeMinterConfig": {
   305  							"blockTimestamp": 1671543172,
   306  							"disable": false
   307  						}
   308  					}
   309  				]
   310  			}
   311  	`)
   312  
   313  	var upgradeConfig UpgradeConfig
   314  	err := json.Unmarshal(upgradeBytes, &upgradeConfig)
   315  	require.NoError(err)
   316  
   317  	require.Len(upgradeConfig.PrecompileUpgrades, 2)
   318  
   319  	rewardManagerConf := upgradeConfig.PrecompileUpgrades[0]
   320  	require.Equal(rewardManagerConf.Key(), rewardmanager.ConfigKey)
   321  	testRewardManagerConfig := rewardmanager.NewConfig(
   322  		utils.NewUint64(1671542573),
   323  		[]common.Address{common.HexToAddress("0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC")},
   324  		nil,
   325  		nil,
   326  		&rewardmanager.InitialRewardConfig{
   327  			AllowFeeRecipients: true,
   328  		})
   329  	require.True(rewardManagerConf.Equal(testRewardManagerConfig))
   330  
   331  	nativeMinterConfig := upgradeConfig.PrecompileUpgrades[1]
   332  	require.Equal(nativeMinterConfig.Key(), nativeminter.ConfigKey)
   333  	expectedNativeMinterConfig := nativeminter.NewConfig(utils.NewUint64(1671543172), nil, nil, nil, nil)
   334  	require.True(nativeMinterConfig.Equal(expectedNativeMinterConfig))
   335  
   336  	// Marshal and unmarshal again and check that the result is the same
   337  	upgradeBytes2, err := json.Marshal(upgradeConfig)
   338  	require.NoError(err)
   339  	var upgradeConfig2 UpgradeConfig
   340  	err = json.Unmarshal(upgradeBytes2, &upgradeConfig2)
   341  	require.NoError(err)
   342  	require.Equal(upgradeConfig, upgradeConfig2)
   343  }