github.com/MetalBlockchain/subnet-evm@v0.4.9/precompile/stateful_precompile_config.go (about)

     1  // (c) 2019-2020, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package precompile
     5  
     6  import (
     7  	"fmt"
     8  	"math/big"
     9  
    10  	"github.com/ethereum/go-ethereum/common"
    11  )
    12  
    13  // StatefulPrecompileConfig defines the interface for a stateful precompile to
    14  type StatefulPrecompileConfig interface {
    15  	// Address returns the address where the stateful precompile is accessible.
    16  	Address() common.Address
    17  	// Timestamp returns the timestamp at which this stateful precompile should be enabled.
    18  	// 1) 0 indicates that the precompile should be enabled from genesis.
    19  	// 2) n indicates that the precompile should be enabled in the first block with timestamp >= [n].
    20  	// 3) nil indicates that the precompile is never enabled.
    21  	Timestamp() *big.Int
    22  	// IsDisabled returns true if this network upgrade should disable the precompile.
    23  	IsDisabled() bool
    24  	// Equal returns true if the provided argument configures the same precompile with the same parameters.
    25  	Equal(StatefulPrecompileConfig) bool
    26  	// Configure is called on the first block where the stateful precompile should be enabled.
    27  	// This allows the stateful precompile to configure its own state via [StateDB] and [BlockContext] as necessary.
    28  	// This function must be deterministic since it will impact the EVM state. If a change to the
    29  	// config causes a change to the state modifications made in Configure, then it cannot be safely
    30  	// made to the config after the network upgrade has gone into effect.
    31  	//
    32  	// Configure is called on the first block where the stateful precompile should be enabled. This
    33  	// provides the config the ability to set its initial state and should only modify the state within
    34  	// its own address space.
    35  	Configure(ChainConfig, StateDB, BlockContext)
    36  	// Contract returns a thread-safe singleton that can be used as the StatefulPrecompiledContract when
    37  	// this config is enabled.
    38  	Contract() StatefulPrecompiledContract
    39  	// Verify is called on startup and an error is treated as fatal. Configure can assume the Config has passed verification.
    40  	Verify() error
    41  
    42  	fmt.Stringer
    43  }
    44  
    45  // Configure sets the nonce and code to non-empty values then calls Configure on [precompileConfig] to make the necessary
    46  // state update to enable the StatefulPrecompile.
    47  // Assumes that [precompileConfig] is non-nil.
    48  func Configure(chainConfig ChainConfig, blockContext BlockContext, precompileConfig StatefulPrecompileConfig, state StateDB) {
    49  	// Set the nonce of the precompile's address (as is done when a contract is created) to ensure
    50  	// that it is marked as non-empty and will not be cleaned up when the statedb is finalized.
    51  	state.SetNonce(precompileConfig.Address(), 1)
    52  	// Set the code of the precompile's address to a non-zero length byte slice to ensure that the precompile
    53  	// can be called from within Solidity contracts. Solidity adds a check before invoking a contract to ensure
    54  	// that it does not attempt to invoke a non-existent contract.
    55  	state.SetCode(precompileConfig.Address(), []byte{0x1})
    56  	precompileConfig.Configure(chainConfig, state, blockContext)
    57  }