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 }