Skip to content

Commit

Permalink
Reserve address spaces for custom precompiles (#176)
Browse files Browse the repository at this point in the history
* Reserve address spaces for custom precompiles

* Add comment documenting the reason for reserving address prefix 0x01 for coreth precompiles
  • Loading branch information
aaronbuchwald authored Aug 1, 2022
1 parent 1a02bee commit bf21bdc
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 15 deletions.
17 changes: 5 additions & 12 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,14 @@ var (
_ precompile.BlockContext = &BlockContext{}
)

var prohibitedAddresses = map[common.Address]struct{}{
constants.BlackholeAddr: {},
}

func init() {
for _, addr := range precompile.UsedAddresses {
prohibitedAddresses[addr] = struct{}{}
}
}

// IsProhibited returns true if [addr] is in the prohibited list of addresses which should
// not be allowed as an EOA or newly created contract address.
func IsProhibited(addr common.Address) bool {
_, ok := prohibitedAddresses[addr]
return ok
if addr == constants.BlackholeAddr {
return true
}

return precompile.ReservedAddress(addr)
}

// emptyCodeHash is used by create to ensure deployment is disallowed to already
Expand Down
47 changes: 44 additions & 3 deletions precompile/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@

package precompile

import "github.com/ethereum/go-ethereum/common"
import (
"fmt"

"github.com/ethereum/go-ethereum/common"
)

// Gas costs for stateful precompiles
const (
Expand All @@ -23,8 +27,11 @@ const (
// Designated addresses of stateful precompiles
// Note: it is important that none of these addresses conflict with each other or any other precompiles
// in core/vm/contracts.go.
// We start at 0x0200000000000000000000000000000000000000 and will increment by 1 from here to reduce
// the risk of conflicts.
// The first stateful precompiles were added in coreth to support nativeAssetCall and nativeAssetBalance. New stateful precompiles
// originating in coreth will continue at this prefix, so we reserve this range in subnet-evm so that they can be migrated into
// subnet-evm without issue. These start at the address: 0x0100000000000000000000000000000000000000 and will increment by 1.
// Optional precompiles implemented in subnet-evm start at 0x0200000000000000000000000000000000000000 and will increment by 1
// from here to reduce the risk of conflicts.
// For forks of subnet-evm, users should start at 0x0300000000000000000000000000000000000000 to ensure
// that their own modifications do not conflict with stateful precompiles that may be added to subnet-evm
// in the future.
Expand All @@ -40,4 +47,38 @@ var (
TxAllowListAddress,
FeeConfigManagerAddress,
}
reservedRanges = []AddressRange{
{
common.HexToAddress("0x0100000000000000000000000000000000000000"),
common.HexToAddress("0x01000000000000000000000000000000000000ff"),
},
{
common.HexToAddress("0x0200000000000000000000000000000000000000"),
common.HexToAddress("0x02000000000000000000000000000000000000ff"),
},
{
common.HexToAddress("0x0300000000000000000000000000000000000000"),
common.HexToAddress("0x03000000000000000000000000000000000000ff"),
},
}
)

// UsedAddress returns true if [addr] is in a reserved range for custom precompiles
func ReservedAddress(addr common.Address) bool {
for _, reservedRange := range reservedRanges {
if reservedRange.Contains(addr) {
return true
}
}

return false
}

func init() {
// Ensure that every address used by a precompile is in a reserved range.
for _, addr := range UsedAddresses {
if !ReservedAddress(addr) {
panic(fmt.Errorf("address %s used for stateful precompile but not specified in any reserved range", addr))
}
}
}
26 changes: 26 additions & 0 deletions precompile/reserved_range.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package precompile

import (
"bytes"

"github.com/ethereum/go-ethereum/common"
)

// Gas costs for stateful precompiles
// can be added here eg.
// const MintGasCost = 30_000

// AddressRange represents a continuous range of addresses
type AddressRange struct {
Start common.Address
End common.Address
}

// Contains returns true iff [addr] is contained within the (inclusive)
func (a *AddressRange) Contains(addr common.Address) bool {
addrBytes := addr.Bytes()
return bytes.Compare(addrBytes, a.Start[:]) >= 0 && bytes.Compare(addrBytes, a.End[:]) <= 0
}

0 comments on commit bf21bdc

Please sign in to comment.