precompile

package
v0.0.0-...-7e2f347 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 28, 2022 License: GPL-3.0, LGPL-3.0 Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ModifyAllowListGasCost = writeGasCostPerSlot
	ReadAllowListGasCost   = readGasCostPerSlot

	RegisterAssetGasCost = writeGasCostPerSlot
	GetAssetGasCost      = readGasCostPerSlot

	MintGasCost = 30_000

	SetFeeConfigGasCost     = writeGasCostPerSlot * (numFeeConfigField + 1) // plus one for setting last changed at
	GetFeeConfigGasCost     = readGasCostPerSlot * numFeeConfigField
	GetLastChangedAtGasCost = readGasCostPerSlot
)

Gas costs for stateful precompiles

Variables

View Source
var (
	ContractDeployerAllowListAddress = common.HexToAddress("0x0200000000000000000000000000000000000000")
	ContractNativeMinterAddress      = common.HexToAddress("0x0200000000000000000000000000000000000001")
	TxAllowListAddress               = common.HexToAddress("0x0200000000000000000000000000000000000002")
	FeeConfigManagerAddress          = common.HexToAddress("0x0200000000000000000000000000000000000003")
	ContractDeployerAssetAddress     = common.HexToAddress("0x0300000000000000000000000000000000000000")

	UsedAddresses = []common.Address{
		ContractDeployerAllowListAddress,
		ContractNativeMinterAddress,
		TxAllowListAddress,
		FeeConfigManagerAddress,
		ContractDeployerAssetAddress,
	}
)

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. 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.

View Source
var (
	ContractDeployerAssetPrecompile = createAssetPrecompile(ContractDeployerAssetAddress)
)
View Source
var (
	DefaultAsset = commontype.Asset{}
)

Functions

func CalculateFunctionSelector

func CalculateFunctionSelector(functionSignature string) []byte

CalculateFunctionSelector returns the 4 byte function selector that results from [functionSignature] Ex. the function setBalance(addr address, balance uint256) should be passed in as the string: "setBalance(address,uint256)"

func CheckConfigure

func CheckConfigure(chainConfig ChainConfig, parentTimestamp *big.Int, blockContext BlockContext, precompileConfig StatefulPrecompileConfig, state StateDB)

CheckConfigure checks if [config] is activated by the transition from block at [parentTimestamp] to [currentTimestamp]. If it does, then it calls Configure on [config] to make the necessary state update to enable the StatefulPrecompile. Note: this function is called within genesis to configure the starting state if it [config] specifies that it should be configured at genesis, or happens during block processing to update the state before processing the given block. TODO: add ability to call Configure at different timestamps, so that developers can easily re-configure by updating the stateful precompile config. Assumes that [config] is non-nil.

func GetFeeConfigLastChangedAt

func GetFeeConfigLastChangedAt(stateDB StateDB) *big.Int

func GetStoredFeeConfig

func GetStoredFeeConfig(stateDB StateDB) commontype.FeeConfig

GetStoredFeeConfig returns fee config from contract storage in given state

func PackFeeConfig

func PackFeeConfig(feeConfig commontype.FeeConfig) ([]byte, error)

PackFeeConfig packs [feeConfig] without the selector into the appropriate arguments for fee config operations.

func PackGetFeeConfigInput

func PackGetFeeConfigInput() []byte

PackGetFeeConfigInput packs the getFeeConfig signature

func PackGetLastChangedAtInput

func PackGetLastChangedAtInput() []byte

PackGetLastChangedAtInput packs the getFeeConfigLastChangedAt signature

func PackMintInput

func PackMintInput(address common.Address, amount *big.Int) ([]byte, error)

PackMintInput packs [address] and [amount] into the appropriate arguments for minting operation. Assumes that [amount] can be represented by 32 bytes.

func PackModifyAllowList

func PackModifyAllowList(address common.Address, role AllowListRole) ([]byte, error)

PackModifyAllowList packs [address] and [role] into the appropriate arguments for modifying the allow list. Note: [role] is not packed in the input value returned, but is instead used as a selector for the function selector that should be encoded in the input.

func PackReadAllowList

func PackReadAllowList(address common.Address) []byte

PackReadAllowList packs [address] into the input data to the read allow list function

func PackSetFeeConfig

func PackSetFeeConfig(feeConfig commontype.FeeConfig) ([]byte, error)

PackSetFeeConfig packs [feeConfig] with the selector into the appropriate arguments for setting fee config operations.

func SetContractDeployerAllowListStatus

func SetContractDeployerAllowListStatus(stateDB StateDB, address common.Address, role AllowListRole)

SetContractDeployerAllowListStatus sets the permissions of [address] to [role] for the contract deployer allow list. assumes [role] has already been verified as valid.

func SetContractNativeMinterStatus

func SetContractNativeMinterStatus(stateDB StateDB, address common.Address, role AllowListRole)

SetContractNativeMinterStatus sets the permissions of [address] to [role] for the minter list. assumes [role] has already been verified as valid.

func SetFeeConfigManagerStatus

func SetFeeConfigManagerStatus(stateDB StateDB, address common.Address, role AllowListRole)

SetFeeConfigManagerStatus sets the permissions of [address] to [role] for the fee config manager list. assumes [role] has already been verified as valid.

func SetTxAllowListStatus

func SetTxAllowListStatus(stateDB StateDB, address common.Address, role AllowListRole)

SetTxAllowListStatus sets the permissions of [address] to [role] for the tx allow list. assumes [role] has already been verified as valid.

func StoreFeeConfig

func StoreFeeConfig(stateDB StateDB, feeConfig commontype.FeeConfig, blockContext BlockContext) error

StoreFeeConfig stores given [feeConfig] and block number in the [blockContext] to the [stateDB]. A validation on [feeConfig] is done before storing.

func UnpackFeeConfigInput

func UnpackFeeConfigInput(input []byte) (commontype.FeeConfig, error)

UnpackFeeConfigInput attempts to unpack [input] into the arguments to the fee config precompile assumes that [input] does not include selector (omits first 4 bytes in PackSetFeeConfigInput)

func UnpackMintInput

func UnpackMintInput(input []byte) (common.Address, *big.Int, error)

UnpackMintInput attempts to unpack [input] into the arguments to the mint precompile assumes that [input] does not include selector (omits first 4 bytes in PackMintInput)

Types

type AllowListConfig

type AllowListConfig struct {
	BlockTimestamp *big.Int `json:"blockTimestamp"`

	AllowListAdmins []common.Address `json:"adminAddresses"`
}

AllowListConfig specifies the configuration of the allow list. Specifies the block timestamp at which it goes into effect as well as the initial set of allow list admins.

func (*AllowListConfig) Configure

func (c *AllowListConfig) Configure(state StateDB, precompileAddr common.Address)

Configure initializes the address space of [precompileAddr] by initializing the role of each of the addresses in [AllowListAdmins].

func (*AllowListConfig) Timestamp

func (c *AllowListConfig) Timestamp() *big.Int

Timestamp returns the timestamp at which the allow list should be enabled

type AllowListRole

type AllowListRole common.Hash

Enum constants for valid AllowListRole

var (
	AllowListNoRole  AllowListRole = AllowListRole(common.BigToHash(big.NewInt(0))) // No role assigned - this is equivalent to common.Hash{} and deletes the key from the DB when set
	AllowListEnabled AllowListRole = AllowListRole(common.BigToHash(big.NewInt(1))) // Deployers are allowed to create new contracts
	AllowListAdmin   AllowListRole = AllowListRole(common.BigToHash(big.NewInt(2))) // Admin - allowed to modify both the admin and deployer list as well as deploy contracts

	// Error returned when an invalid write is attempted
	ErrCannotModifyAllowList = errors.New("non-admin cannot modify allow list")
)

func GetContractDeployerAllowListStatus

func GetContractDeployerAllowListStatus(stateDB StateDB, address common.Address) AllowListRole

GetContractDeployerAllowListStatus returns the role of [address] for the contract deployer allow list.

func GetContractNativeMinterStatus

func GetContractNativeMinterStatus(stateDB StateDB, address common.Address) AllowListRole

GetContractNativeMinterStatus returns the role of [address] for the minter list.

func GetFeeConfigManagerStatus

func GetFeeConfigManagerStatus(stateDB StateDB, address common.Address) AllowListRole

GetFeeConfigManagerStatus returns the role of [address] for the fee config manager list.

func GetTxAllowListStatus

func GetTxAllowListStatus(stateDB StateDB, address common.Address) AllowListRole

GetTxAllowListStatus returns the role of [address] for the contract deployer allow list.

func (AllowListRole) IsAdmin

func (s AllowListRole) IsAdmin() bool

IsAdmin returns true if [s] indicates the permission to modify the allow list.

func (AllowListRole) IsEnabled

func (s AllowListRole) IsEnabled() bool

IsEnabled returns true if [s] indicates that it has permission to access the resource.

func (AllowListRole) IsNoRole

func (s AllowListRole) IsNoRole() bool

IsNoRole returns true if [s] indicates no specific role.

func (AllowListRole) Valid

func (s AllowListRole) Valid() bool

Valid returns true iff [s] represents a valid role.

type AssetConfig

type AssetConfig struct {
	BlockTimestamp *big.Int `json:"blockTimestamp"`
}

func (*AssetConfig) Configure

func (asset *AssetConfig) Configure(_ StateDB, _ common.Address)

func (*AssetConfig) Timestamp

func (asset *AssetConfig) Timestamp() *big.Int

type AssetDB

type AssetDB interface {
	GetAll() []commontype.Asset
	RegisterAsset(assetId common.Hash, owner common.Address, name string)
	GetAsset(assetId common.Hash) (commontype.Asset, error)
	GetAssetByOwner(owner common.Address) []commontype.Asset
	UpdateLocation(assetId common.Hash, location string) error
	UpdateName(assetId common.Hash, name string) error
}

type AssetLocation

type AssetLocation string

type BlockContext

type BlockContext interface {
	Number() *big.Int
	Timestamp() *big.Int
}

type ChainConfig

type ChainConfig interface {
	// GetFeeConfig returns the original FeeConfig that was set in the genesis.
	GetFeeConfig() commontype.FeeConfig
}

ChainConfig provides an interface for accessing the chain configuration information.

type ContractDeployerAllowListConfig

type ContractDeployerAllowListConfig struct {
	AllowListConfig
}

ContractDeployerAllowListConfig wraps AllowListConfig and uses it to implement the StatefulPrecompileConfig interface while adding in the contract deployer specific precompile address.

func (*ContractDeployerAllowListConfig) Address

Address returns the address of the contract deployer allow list.

func (*ContractDeployerAllowListConfig) Configure

Configure configures [state] with the desired admins based on [c].

func (*ContractDeployerAllowListConfig) Contract

Contract returns the singleton stateful precompiled contract to be used for the allow list.

type ContractDeployerAssetConfig

type ContractDeployerAssetConfig struct {
	AssetConfig
}

func (*ContractDeployerAssetConfig) Address

func (*ContractDeployerAssetConfig) Configure

func (c *ContractDeployerAssetConfig) Configure(_ ChainConfig, state StateDB, _ BlockContext)

func (*ContractDeployerAssetConfig) Contract

type ContractNativeMinterConfig

type ContractNativeMinterConfig struct {
	AllowListConfig
}

ContractNativeMinterConfig wraps AllowListConfig and uses it to implement the StatefulPrecompileConfig interface while adding in the ContractNativeMinter specific precompile address.

func (*ContractNativeMinterConfig) Address

Address returns the address of the native minter contract.

func (*ContractNativeMinterConfig) Configure

func (c *ContractNativeMinterConfig) Configure(_ ChainConfig, state StateDB, _ BlockContext)

Configure configures [state] with the desired admins based on [c].

func (*ContractNativeMinterConfig) Contract

Contract returns the singleton stateful precompiled contract to be used for the native minter.

type FeeConfigManagerConfig

type FeeConfigManagerConfig struct {
	AllowListConfig // Config for the fee config manager allow list
}

FeeConfigManagerConfig wraps AllowListConfig and uses it to implement the StatefulPrecompileConfig interface while adding in the FeeConfigManager specific precompile address.

func (*FeeConfigManagerConfig) Address

func (c *FeeConfigManagerConfig) Address() common.Address

Address returns the address of the fee config manager contract.

func (*FeeConfigManagerConfig) Configure

func (c *FeeConfigManagerConfig) Configure(chainConfig ChainConfig, state StateDB, blockContext BlockContext)

Configure configures [state] with the desired admins based on [c].

func (*FeeConfigManagerConfig) Contract

Contract returns the singleton stateful precompiled contract to be used for the fee manager.

type PrecompileAccessibleState

type PrecompileAccessibleState interface {
	GetStateDB() StateDB
	GetAssetDB() AssetDB
	GetBlockContext() BlockContext
}

PrecompileAccessibleState defines the interface exposed to stateful precompile contracts

type RunStatefulPrecompileFunc

type RunStatefulPrecompileFunc func(accessibleState PrecompileAccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error)

type StateDB

type StateDB interface {
	GetState(common.Address, common.Hash) common.Hash
	SetState(common.Address, common.Hash, common.Hash)

	SetCode(common.Address, []byte)

	SetNonce(common.Address, uint64)
	GetNonce(common.Address) uint64

	GetBalance(common.Address) *big.Int
	AddBalance(common.Address, *big.Int)
	SubBalance(common.Address, *big.Int)

	CreateAccount(common.Address)
	Exist(common.Address) bool
}

StateDB is the interface for accessing EVM state

type StatefulPrecompileConfig

type StatefulPrecompileConfig interface {
	// Address returns the address where the stateful precompile is accessible.
	Address() common.Address
	// Timestamp returns the timestamp at which this stateful precompile should be enabled.
	// 1) 0 indicates that the precompile should be enabled from genesis.
	// 2) n indicates that the precompile should be enabled in the first block with timestamp >= [n].
	// 3) nil indicates that the precompile is never enabled.
	Timestamp() *big.Int
	// Configure is called on the first block where the stateful precompile should be enabled.
	// This allows the stateful precompile to configure its own state via [StateDB] and [BlockContext] as necessary.
	// This function must be deterministic since it will impact the EVM state. If a change to the
	// config causes a change to the state modifications made in Configure, then it cannot be safely
	// made to the config after the network upgrade has gone into effect.
	//
	// Configure is called on the first block where the stateful precompile should be enabled. This
	// provides the config the ability to set its initial state and should only modify the state within
	// its own address space.
	Configure(ChainConfig, StateDB, BlockContext)
	// Contract returns a thread-safe singleton that can be used as the StatefulPrecompiledContract when
	// this config is enabled.
	Contract() StatefulPrecompiledContract
}

StatefulPrecompileConfig defines the interface for a stateful precompile to

type StatefulPrecompiledContract

type StatefulPrecompiledContract interface {
	// Run executes the precompiled contract.
	Run(accessibleState PrecompileAccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error)
}

StatefulPrecompiledContract is the interface for executing a precompiled contract

var (

	// Singleton StatefulPrecompiledContract for minting native assets by permissioned callers.
	ContractNativeMinterPrecompile StatefulPrecompiledContract = createNativeMinterPrecompile(ContractNativeMinterAddress)

	ErrCannotMint = errors.New("non-enabled cannot mint")
)
var (

	// Singleton StatefulPrecompiledContract for setting fee configs by permissioned callers.
	FeeConfigManagerPrecompile StatefulPrecompiledContract = createFeeConfigManagerPrecompile(FeeConfigManagerAddress)

	ErrCannotChangeFee = errors.New("non-enabled cannot change fee config")
)
var (

	// Singleton StatefulPrecompiledContract for W/R access to the contract deployer allow list.
	TxAllowListPrecompile StatefulPrecompiledContract = createAllowListPrecompile(TxAllowListAddress)

	ErrSenderAddressNotAllowListed = errors.New("cannot issue transaction from non-allow listed address")
)
var (

	// Singleton StatefulPrecompiledContract for W/R access to the contract deployer allow list.
	ContractDeployerAllowListPrecompile StatefulPrecompiledContract = createAllowListPrecompile(ContractDeployerAllowListAddress)
)

type TxAllowListConfig

type TxAllowListConfig struct {
	AllowListConfig
}

TxAllowListConfig wraps AllowListConfig and uses it to implement the StatefulPrecompileConfig interface while adding in the TxAllowList specific precompile address.

func (*TxAllowListConfig) Address

func (c *TxAllowListConfig) Address() common.Address

Address returns the address of the contract deployer allow list.

func (*TxAllowListConfig) Configure

func (c *TxAllowListConfig) Configure(_ ChainConfig, state StateDB, _ BlockContext)

Configure configures [state] with the desired admins based on [c].

func (*TxAllowListConfig) Contract

Contract returns the singleton stateful precompiled contract to be used for the allow list.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL