github.com/dim4egster/coreth@v0.10.2/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  	"math/big"
     8  
     9  	"github.com/ethereum/go-ethereum/common"
    10  
    11  	"github.com/dim4egster/coreth/utils"
    12  )
    13  
    14  // StatefulPrecompileConfig defines the interface for a stateful precompile to
    15  type StatefulPrecompileConfig interface {
    16  	// Address returns the address where the stateful precompile is accessible.
    17  	Address() common.Address
    18  	// Timestamp returns the timestamp at which this stateful precompile should be enabled.
    19  	// 1) 0 indicates that the precompile should be enabled from genesis.
    20  	// 2) n indicates that the precompile should be enabled in the first block with timestamp >= [n].
    21  	// 3) nil indicates that the precompile is never enabled.
    22  	Timestamp() *big.Int
    23  	// Configure is called on the first block where the stateful precompile should be enabled.
    24  	// This allows the stateful precompile to configure its own state via [StateDB] as necessary.
    25  	// This function must be deterministic since it will impact the EVM state. If a change to the
    26  	// config causes a change to the state modifications made in Configure, then it cannot be safely
    27  	// made to the config after the network upgrade has gone into effect.
    28  	//
    29  	// Configure is called on the first block where the stateful precompile should be enabled. This
    30  	// provides the config the ability to set its initial state and should only modify the state within
    31  	// its own address space.
    32  	Configure(ChainConfig, StateDB, BlockContext)
    33  	// Contract returns a thread-safe singleton that can be used as the StatefulPrecompiledContract when
    34  	// this config is enabled.
    35  	Contract() StatefulPrecompiledContract
    36  }
    37  
    38  // CheckConfigure checks if [config] is activated by the transition from block at [parentTimestamp] to the timestamp
    39  // set in [blockContext].
    40  // If it does, then it calls Configure on [precompileConfig] to make the necessary state update to enable the StatefulPrecompile.
    41  // Note: this function is called within genesis to configure the starting state if [precompileConfig] specifies that it should be
    42  // configured at genesis, or happens during block processing to update the state before processing the given block.
    43  // TODO: add ability to call Configure at different timestamps, so that developers can easily re-configure by updating the
    44  // stateful precompile config.
    45  // Assumes that [config] is non-nil.
    46  func CheckConfigure(chainConfig ChainConfig, parentTimestamp *big.Int, blockContext BlockContext, precompileConfig StatefulPrecompileConfig, state StateDB) {
    47  	forkTimestamp := precompileConfig.Timestamp()
    48  	// If the network upgrade goes into effect within this transition, configure the stateful precompile
    49  	if utils.IsForkTransition(forkTimestamp, parentTimestamp, blockContext.Timestamp()) {
    50  		// Set the nonce of the precompile's address (as is done when a contract is created) to ensure
    51  		// that it is marked as non-empty and will not be cleaned up when the statedb is finalized.
    52  		state.SetNonce(precompileConfig.Address(), 1)
    53  		// Set the code of the precompile's address to a non-zero length byte slice to ensure that the precompile
    54  		// can be called from within Solidity contracts. Solidity adds a check before invoking a contract to ensure
    55  		// that it does not attempt to invoke a non-existent contract.
    56  		state.SetCode(precompileConfig.Address(), []byte{0x1})
    57  		precompileConfig.Configure(chainConfig, state, blockContext)
    58  	}
    59  }