Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add initial precompile configs and handle them #226

Merged
merged 39 commits into from
Sep 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
5359f70
add initial precompile configs and handle them
ceyonur Aug 24, 2022
8a488c5
add verify to precompile configs
ceyonur Aug 25, 2022
538f598
add unit tests for initial configs and verify
ceyonur Aug 25, 2022
9c7c30c
Merge branch 'master' into trustless-precompile-configs
ceyonur Aug 25, 2022
27e207f
add a nil check for initial fee config verification
ceyonur Aug 26, 2022
1d5100b
Merge branch 'trustless-precompile-configs' of github.com:ava-labs/su…
ceyonur Aug 26, 2022
97d3472
conditionally verify allowlist
ceyonur Aug 26, 2022
e70a808
Update precompile/stateful_precompile_config.go
ceyonur Aug 29, 2022
38cc210
add config test to precompile package
ceyonur Aug 30, 2022
55d59e4
add 0 test case for gas limit
ceyonur Aug 30, 2022
258ae40
add comments for allowlist storage keys
ceyonur Aug 30, 2022
c60ec84
move allow list role to different file
ceyonur Aug 31, 2022
bf00bb5
Update precompile/allow_list.go
ceyonur Aug 31, 2022
65bd9e8
rename test
ceyonur Aug 31, 2022
dfd41f5
Update precompile/allow_list.go
ceyonur Aug 31, 2022
8075ba1
rename test & use func to create config
ceyonur Aug 31, 2022
d351f9a
Merge branch 'trustless-precompile-configs' of github.com:ava-labs/su…
ceyonur Aug 31, 2022
3ffa6dc
Remove unnecessary role checks
ceyonur Aug 31, 2022
1e3ab67
Merge branch 'master' into trustless-precompile-configs
ceyonur Sep 1, 2022
b844bbb
use config constructor for precompile tests
ceyonur Sep 1, 2022
2777e0e
Update accounts/abi/bind/precompile_template.go
ceyonur Sep 1, 2022
83a9db6
Update precompile/contract_native_minter.go
ceyonur Sep 1, 2022
415a32b
Update precompile/contract_deployer_allow_list.go
ceyonur Sep 1, 2022
333aa8b
Update precompile/allow_list.go
ceyonur Sep 1, 2022
abfa39e
add equals methods
ceyonur Sep 1, 2022
2d3a517
Merge branch 'trustless-precompile-configs' of github.com:ava-labs/su…
ceyonur Sep 1, 2022
77e4fc3
Merge branch 'master' into trustless-precompile-configs
ceyonur Sep 14, 2022
1013b59
add new test cases for precompile configs
ceyonur Sep 15, 2022
a9d8b49
use hex to address in tests
ceyonur Sep 15, 2022
dad95da
rename helper function
ceyonur Sep 15, 2022
d754ae6
add verify to contract native minter
ceyonur Sep 15, 2022
78e65f2
add fee config tests
ceyonur Sep 16, 2022
66a686e
add positive cases
ceyonur Sep 16, 2022
3964fe5
add equal tesets for precompile configs
ceyonur Sep 16, 2022
42139cd
Update commontype/fee_config_test.go
ceyonur Sep 20, 2022
9affef3
remove comment
ceyonur Sep 20, 2022
4cc1c40
Merge branch 'trustless-precompile-configs' of github.com:ava-labs/su…
ceyonur Sep 20, 2022
56a6d05
precompile: add formatted errors to precompile verify (#262)
aaronbuchwald Sep 22, 2022
a3c2a19
Merge branch 'master' into trustless-precompile-configs
aaronbuchwald Sep 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions accounts/abi/bind/precompile_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,20 @@ func (c *{{.Contract.Type}}Config) Contract() StatefulPrecompiledContract {
return {{.Contract.Type}}Precompile
}

// Verify tries to verify {{.Contract.Type}}Config and returns an error accordingly.
func (c *{{.Contract.Type}}Config) Verify() error {
{{if .Contract.AllowList}}
// Verify AllowList first
if err := c.AllowListConfig.Verify(); err != nil {
return err
}
{{end}}
// CUSTOM CODE STARTS HERE
// Add your own custom verify code for {{.Contract.Type}}Config here
// and return an error accordingly
return nil
}

{{if .Contract.AllowList}}
// Get{{.Contract.Type}}AllowListStatus returns the role of [address] for the {{.Contract.Type}} list.
func Get{{.Contract.Type}}AllowListStatus(stateDB StateDB, address common.Address) AllowListRole {
Expand All @@ -203,6 +217,10 @@ func Get{{.Contract.Type}}AllowListStatus(stateDB StateDB, address common.Addres

// Set{{.Contract.Type}}AllowListStatus sets the permissions of [address] to [role] for the
// {{.Contract.Type}} list. Assumes [role] has already been verified as valid.
// This stores the [role] in the contract storage with address [{{.Contract.Type}}Address]
// and [address] hash. It means that any reusage of the [address] key for different value
// conflicts with the same slot [role] is stored.
// Precompile implementations must use a different key than [address] for their storage.
func Set{{.Contract.Type}}AllowListStatus(stateDB StateDB, address common.Address, role AllowListRole) {
setAllowListRole(stateDB, {{.Contract.Type}}Address, address, role)
}
Expand Down
17 changes: 17 additions & 0 deletions commontype/fee_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"math/big"

"github.com/ava-labs/subnet-evm/utils"
"github.com/ethereum/go-ethereum/common"
)

Expand Down Expand Up @@ -81,6 +82,22 @@ func (f *FeeConfig) Verify() error {
return f.checkByteLens()
}

// Equal checks if given [other] is same with this FeeConfig.
func (f *FeeConfig) Equal(other *FeeConfig) bool {
aaronbuchwald marked this conversation as resolved.
Show resolved Hide resolved
if other == nil {
return false
}

return utils.BigNumEqual(f.GasLimit, other.GasLimit) &&
f.TargetBlockRate == other.TargetBlockRate &&
utils.BigNumEqual(f.MinBaseFee, other.MinBaseFee) &&
utils.BigNumEqual(f.TargetGas, other.TargetGas) &&
utils.BigNumEqual(f.BaseFeeChangeDenominator, other.BaseFeeChangeDenominator) &&
utils.BigNumEqual(f.MinBlockGasCost, other.MinBlockGasCost) &&
utils.BigNumEqual(f.MaxBlockGasCost, other.MaxBlockGasCost) &&
utils.BigNumEqual(f.BlockGasCostStep, other.BlockGasCostStep)
}

// checkByteLens checks byte lengths against common.HashLen (32 bytes) and returns error
func (f *FeeConfig) checkByteLens() error {
if isBiggerThanHashLen(f.GasLimit) {
Expand Down
140 changes: 140 additions & 0 deletions commontype/fee_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// (c) 2019-2022, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package commontype

import (
"math/big"
"testing"

"github.com/stretchr/testify/require"
)

var validFeeConfig = FeeConfig{
GasLimit: big.NewInt(8_000_000),
TargetBlockRate: 2, // in seconds

MinBaseFee: big.NewInt(25_000_000_000),
TargetGas: big.NewInt(15_000_000),
BaseFeeChangeDenominator: big.NewInt(36),

MinBlockGasCost: big.NewInt(0),
MaxBlockGasCost: big.NewInt(1_000_000),
BlockGasCostStep: big.NewInt(200_000),
}

func TestVerify(t *testing.T) {
tests := []struct {
name string
config *FeeConfig
expectedError string
}{
{
name: "invalid GasLimit in FeeConfig",
config: func() *FeeConfig { c := validFeeConfig; c.GasLimit = big.NewInt(0); return &c }(),
expectedError: "gasLimit = 0 cannot be less than or equal to 0",
},
{
name: "invalid TargetBlockRate in FeeConfig",
config: func() *FeeConfig { c := validFeeConfig; c.TargetBlockRate = 0; return &c }(),
expectedError: "targetBlockRate = 0 cannot be less than or equal to 0",
},
{
name: "invalid MinBaseFee in FeeConfig",
config: func() *FeeConfig { c := validFeeConfig; c.MinBaseFee = big.NewInt(-1); return &c }(),
expectedError: "minBaseFee = -1 cannot be less than 0",
},
{
name: "invalid TargetGas in FeeConfig",
config: func() *FeeConfig { c := validFeeConfig; c.TargetGas = big.NewInt(0); return &c }(),
expectedError: "targetGas = 0 cannot be less than or equal to 0",
},
{
name: "invalid BaseFeeChangeDenominator in FeeConfig",
config: func() *FeeConfig { c := validFeeConfig; c.BaseFeeChangeDenominator = big.NewInt(0); return &c }(),
expectedError: "baseFeeChangeDenominator = 0 cannot be less than or equal to 0",
},
{
name: "invalid MinBlockGasCost in FeeConfig",
config: func() *FeeConfig { c := validFeeConfig; c.MinBlockGasCost = big.NewInt(-1); return &c }(),
expectedError: "minBlockGasCost = -1 cannot be less than 0",
},
{
name: "valid FeeConfig",
config: &validFeeConfig,
expectedError: "",
},
{
name: "MinBlockGasCost bigger than MaxBlockGasCost in FeeConfig",
config: func() *FeeConfig {
c := validFeeConfig
c.MinBlockGasCost = big.NewInt(2)
c.MaxBlockGasCost = big.NewInt(1)
return &c
}(),
expectedError: "minBlockGasCost = 2 cannot be greater than maxBlockGasCost = 1",
},
{
name: "invalid BlockGasCostStep in FeeConfig",
config: func() *FeeConfig { c := validFeeConfig; c.BlockGasCostStep = big.NewInt(-1); return &c }(),
expectedError: "blockGasCostStep = -1 cannot be less than 0",
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := test.config.Verify()
if test.expectedError == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), test.expectedError)
}
})
}
}

func TestEqual(t *testing.T) {
tests := []struct {
name string
a *FeeConfig
b *FeeConfig
expected bool
}{
{
name: "equal",
a: &validFeeConfig,
b: &FeeConfig{
GasLimit: big.NewInt(8_000_000),
TargetBlockRate: 2, // in seconds

MinBaseFee: big.NewInt(25_000_000_000),
TargetGas: big.NewInt(15_000_000),
BaseFeeChangeDenominator: big.NewInt(36),

MinBlockGasCost: big.NewInt(0),
MaxBlockGasCost: big.NewInt(1_000_000),
BlockGasCostStep: big.NewInt(200_000),
},
expected: true,
},
{
name: "not equal",
a: &validFeeConfig,
b: func() *FeeConfig { c := validFeeConfig; c.GasLimit = big.NewInt(1); return &c }(),
expected: false,
},
{
name: "not equal nil",
a: &validFeeConfig,
b: nil,
expected: false,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
require.Equal(t, test.expected, test.a.Equal(test.b))
})
}
}
2 changes: 1 addition & 1 deletion core/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func TestStatefulPrecompilesConfigure(t *testing.T) {
"allow list enabled in genesis": {
getConfig: func() *params.ChainConfig {
config := *params.TestChainConfig
config.ContractDeployerAllowListConfig = precompile.NewContractDeployerAllowListConfig(big.NewInt(0), []common.Address{addr})
config.ContractDeployerAllowListConfig = precompile.NewContractDeployerAllowListConfig(big.NewInt(0), []common.Address{addr}, nil)
return &config
},
assertState: func(t *testing.T, sdb *state.StateDB) {
Expand Down
2 changes: 1 addition & 1 deletion core/state_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ func TestBadTxAllowListBlock(t *testing.T) {
SubnetEVMTimestamp: big.NewInt(0),
},
PrecompileUpgrade: params.PrecompileUpgrade{
TxAllowListConfig: precompile.NewTxAllowListConfig(big.NewInt(0), []common.Address{}),
TxAllowListConfig: precompile.NewTxAllowListConfig(big.NewInt(0), nil, nil),
},
}
signer = types.LatestSigner(config)
Expand Down
Loading