Skip to content

Commit acf4f9e

Browse files
author
Darioush Jalali
authored
Start work on breaking cyclic dependency (#496)
1 parent 631e2a7 commit acf4f9e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+1812
-1525
lines changed

core/blockchain_reader.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ import (
3939
"github.com/ava-labs/subnet-evm/core/types"
4040
"github.com/ava-labs/subnet-evm/core/vm"
4141
"github.com/ava-labs/subnet-evm/params"
42-
"github.com/ava-labs/subnet-evm/precompile/feemanager"
43-
"github.com/ava-labs/subnet-evm/precompile/rewardmanager"
42+
"github.com/ava-labs/subnet-evm/precompile/contracts/feemanager"
43+
"github.com/ava-labs/subnet-evm/precompile/contracts/rewardmanager"
4444
"github.com/ethereum/go-ethereum/common"
4545
"github.com/ethereum/go-ethereum/event"
4646
)

core/genesis.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
307307
}
308308

309309
// Configure any stateful precompiles that should be enabled in the genesis.
310-
err = g.Config.ConfigurePrecompiles(nil, types.NewBlockWithHeader(head), statedb)
310+
err = ApplyPrecompileActivations(g.Config, nil, types.NewBlockWithHeader(head), statedb)
311311
if err != nil {
312312
panic(fmt.Sprintf("unable to configure precompiles in genesis block: %v", err))
313313
}

core/genesis_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import (
3939
"github.com/ava-labs/subnet-evm/ethdb"
4040
"github.com/ava-labs/subnet-evm/params"
4141
"github.com/ava-labs/subnet-evm/precompile/allowlist"
42-
"github.com/ava-labs/subnet-evm/precompile/deployerallowlist"
42+
"github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist"
4343
"github.com/davecgh/go-spew/spew"
4444
"github.com/ethereum/go-ethereum/common"
4545
"github.com/stretchr/testify/assert"
@@ -192,7 +192,7 @@ func TestStatefulPrecompilesConfigure(t *testing.T) {
192192
getConfig: func() *params.ChainConfig {
193193
config := *params.TestChainConfig
194194
config.GenesisPrecompiles = params.ChainConfigPrecompiles{
195-
deployerallowlist.ConfigKey: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(0), []common.Address{addr}, nil),
195+
deployerallowlist.ConfigKey: deployerallowlist.NewConfig(big.NewInt(0), []common.Address{addr}, nil),
196196
}
197197
return &config
198198
},
@@ -268,10 +268,10 @@ func TestPrecompileActivationAfterHeaderBlock(t *testing.T) {
268268
require.Greater(block.Time(), bc.lastAccepted.Time())
269269

270270
activatedGenesis := customg
271-
contractDeployerConfig := deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(51), nil, nil)
271+
contractDeployerConfig := deployerallowlist.NewConfig(big.NewInt(51), nil, nil)
272272
activatedGenesis.Config.UpgradeConfig.PrecompileUpgrades = []params.PrecompileUpgrade{
273273
{
274-
StatefulPrecompileConfig: contractDeployerConfig,
274+
Config: contractDeployerConfig,
275275
},
276276
}
277277

core/state_processor.go

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ import (
3535
"github.com/ava-labs/subnet-evm/core/types"
3636
"github.com/ava-labs/subnet-evm/core/vm"
3737
"github.com/ava-labs/subnet-evm/params"
38+
"github.com/ava-labs/subnet-evm/precompile/contract"
39+
"github.com/ava-labs/subnet-evm/precompile/modules"
3840
"github.com/ethereum/go-ethereum/common"
3941
"github.com/ethereum/go-ethereum/crypto"
4042
"github.com/ethereum/go-ethereum/log"
@@ -79,7 +81,7 @@ func (p *StateProcessor) Process(block *types.Block, parent *types.Header, state
7981
)
8082

8183
// Configure any stateful precompiles that should go into effect during this block.
82-
err := p.config.ConfigurePrecompiles(new(big.Int).SetUint64(parent.Time), block, statedb)
84+
err := ApplyPrecompileActivations(p.config, new(big.Int).SetUint64(parent.Time), block, statedb)
8385
if err != nil {
8486
log.Error("failed to configure precompiles processing block", "hash", block.Hash(), "number", block.NumberU64(), "timestamp", block.Time(), "err", err)
8587
return nil, nil, 0, err
@@ -168,3 +170,50 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
168170
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg)
169171
return applyTransaction(msg, config, author, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv)
170172
}
173+
174+
// ApplyPrecompileActivations checks if any of the precompiles specified by the chain config are enabled or disabled by the block
175+
// transition from [parentTimestamp] to the timestamp set in [blockContext]. If this is the case, it calls [Configure]
176+
// to apply the necessary state transitions for the upgrade.
177+
// This function is called:
178+
// - within genesis setup to configure the starting state for precompiles enabled at genesis,
179+
// - during block processing to update the state before processing the given block.
180+
// - during block producing to apply the precompile upgrades before producing the block.
181+
func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *big.Int, blockContext contract.BlockContext, statedb *state.StateDB) error {
182+
blockTimestamp := blockContext.Timestamp()
183+
// Note: RegisteredModules returns precompiles sorted by module addresses.
184+
// This is important because we want to configure precompiles in the same order
185+
// so that the state is deterministic.
186+
for _, module := range modules.RegisteredModules() {
187+
key := module.ConfigKey
188+
for _, activatingConfig := range c.GetActivatingPrecompileConfigs(module.Address, parentTimestamp, blockTimestamp, c.PrecompileUpgrades) {
189+
// If this transition activates the upgrade, configure the stateful precompile.
190+
// (or deconfigure it if it is being disabled.)
191+
if activatingConfig.IsDisabled() {
192+
log.Info("Disabling precompile", "name", key)
193+
statedb.Suicide(module.Address)
194+
// Calling Finalise here effectively commits Suicide call and wipes the contract state.
195+
// This enables re-configuration of the same contract state in the same block.
196+
// Without an immediate Finalise call after the Suicide, a reconfigured precompiled state can be wiped out
197+
// since Suicide will be committed after the reconfiguration.
198+
statedb.Finalise(true)
199+
} else {
200+
module, ok := modules.GetPrecompileModule(key)
201+
if !ok {
202+
return fmt.Errorf("could not find module for activating precompile, name: %s", key)
203+
}
204+
log.Info("Activating new precompile", "name", key, "config", activatingConfig)
205+
// Set the nonce of the precompile's address (as is done when a contract is created) to ensure
206+
// that it is marked as non-empty and will not be cleaned up when the statedb is finalized.
207+
statedb.SetNonce(module.Address, 1)
208+
// Set the code of the precompile's address to a non-zero length byte slice to ensure that the precompile
209+
// can be called from within Solidity contracts. Solidity adds a check before invoking a contract to ensure
210+
// that it does not attempt to invoke a non-existent contract.
211+
statedb.SetCode(module.Address, []byte{0x1})
212+
if err := module.Configure(c, activatingConfig, statedb, blockContext); err != nil {
213+
return fmt.Errorf("could not configure precompile, name: %s, reason: %w", key, err)
214+
}
215+
}
216+
}
217+
}
218+
return nil
219+
}

core/state_processor_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,17 @@ import (
3636
"github.com/ava-labs/subnet-evm/core/types"
3737
"github.com/ava-labs/subnet-evm/core/vm"
3838
"github.com/ava-labs/subnet-evm/params"
39-
"github.com/ava-labs/subnet-evm/precompile/txallowlist"
39+
"github.com/ava-labs/subnet-evm/precompile/contracts/txallowlist"
4040
"github.com/ava-labs/subnet-evm/trie"
4141
"github.com/ethereum/go-ethereum/common"
4242
"github.com/ethereum/go-ethereum/crypto"
4343
"golang.org/x/crypto/sha3"
4444
)
4545

4646
var (
47-
config = params.TestChainConfig
48-
signer = types.LatestSigner(config)
49-
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
47+
chainConfig = params.TestChainConfig
48+
signer = types.LatestSigner(chainConfig)
49+
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
5050
)
5151

5252
func makeTx(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *types.Transaction {
@@ -71,12 +71,12 @@ func mkDynamicTx(nonce uint64, to common.Address, gasLimit uint64, gasTipCap, ga
7171
// blockchain imports bad blocks, meaning blocks which have valid headers but
7272
// contain invalid transactions
7373
func TestStateProcessorErrors(t *testing.T) {
74-
config.FeeConfig.MinBaseFee = params.TestMaxBaseFee
74+
chainConfig.FeeConfig.MinBaseFee = params.TestMaxBaseFee
7575
{ // Tests against a 'recent' chain definition
7676
var (
7777
db = rawdb.NewMemoryDatabase()
7878
gspec = &Genesis{
79-
Config: config,
79+
Config: chainConfig,
8080
Alloc: GenesisAlloc{
8181
common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): GenesisAccount{
8282
Balance: big.NewInt(2000000000000000000), // 2 ether
@@ -254,7 +254,7 @@ func TestStateProcessorErrors(t *testing.T) {
254254
var (
255255
db = rawdb.NewMemoryDatabase()
256256
gspec = &Genesis{
257-
Config: config,
257+
Config: chainConfig,
258258
Alloc: GenesisAlloc{
259259
common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): GenesisAccount{
260260
Balance: big.NewInt(1000000000000000000), // 1 ether
@@ -316,7 +316,7 @@ func TestBadTxAllowListBlock(t *testing.T) {
316316
SubnetEVMTimestamp: big.NewInt(0),
317317
},
318318
GenesisPrecompiles: params.ChainConfigPrecompiles{
319-
txallowlist.ConfigKey: txallowlist.NewTxAllowListConfig(big.NewInt(0), nil, nil),
319+
txallowlist.ConfigKey: txallowlist.NewConfig(big.NewInt(0), nil, nil),
320320
},
321321
}
322322
signer = types.LatestSigner(config)

core/state_transition.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import (
3636
"github.com/ava-labs/subnet-evm/core/types"
3737
"github.com/ava-labs/subnet-evm/core/vm"
3838
"github.com/ava-labs/subnet-evm/params"
39-
"github.com/ava-labs/subnet-evm/precompile/txallowlist"
39+
"github.com/ava-labs/subnet-evm/precompile/contracts/txallowlist"
4040
"github.com/ava-labs/subnet-evm/vmerrs"
4141
"github.com/ethereum/go-ethereum/common"
4242
)

core/test_blockchain.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ import (
1717
"github.com/ava-labs/subnet-evm/ethdb"
1818
"github.com/ava-labs/subnet-evm/params"
1919
"github.com/ava-labs/subnet-evm/precompile/allowlist"
20-
"github.com/ava-labs/subnet-evm/precompile/deployerallowlist"
21-
"github.com/ava-labs/subnet-evm/precompile/feemanager"
20+
"github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist"
21+
"github.com/ava-labs/subnet-evm/precompile/contracts/feemanager"
2222
"github.com/ethereum/go-ethereum/common"
2323
"github.com/ethereum/go-ethereum/crypto"
2424
"github.com/stretchr/testify/assert"
@@ -1549,8 +1549,8 @@ func TestStatefulPrecompiles(t *testing.T, create func(db ethdb.Database, chainC
15491549
config := *params.TestChainConfig
15501550
// Set all of the required config parameters
15511551
config.GenesisPrecompiles = params.ChainConfigPrecompiles{
1552-
deployerallowlist.ConfigKey: deployerallowlist.NewContractDeployerAllowListConfig(big.NewInt(0), []common.Address{addr1}, nil),
1553-
feemanager.ConfigKey: feemanager.NewFeeManagerConfig(big.NewInt(0), []common.Address{addr1}, nil, nil),
1552+
deployerallowlist.ConfigKey: deployerallowlist.NewConfig(big.NewInt(0), []common.Address{addr1}, nil),
1553+
feemanager.ConfigKey: feemanager.NewConfig(big.NewInt(0), []common.Address{addr1}, nil, nil),
15541554
}
15551555
gspec := &Genesis{
15561556
Config: &config,

core/tx_pool.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ import (
4242
"github.com/ava-labs/subnet-evm/core/types"
4343
"github.com/ava-labs/subnet-evm/metrics"
4444
"github.com/ava-labs/subnet-evm/params"
45-
"github.com/ava-labs/subnet-evm/precompile/feemanager"
46-
"github.com/ava-labs/subnet-evm/precompile/txallowlist"
45+
"github.com/ava-labs/subnet-evm/precompile/contracts/feemanager"
46+
"github.com/ava-labs/subnet-evm/precompile/contracts/txallowlist"
4747

4848
"github.com/ethereum/go-ethereum/common"
4949
"github.com/ethereum/go-ethereum/common/prque"

core/vm/contracts.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ import (
3535

3636
"github.com/ava-labs/subnet-evm/constants"
3737
"github.com/ava-labs/subnet-evm/params"
38-
"github.com/ava-labs/subnet-evm/precompile"
38+
"github.com/ava-labs/subnet-evm/precompile/contract"
39+
"github.com/ava-labs/subnet-evm/precompile/modules"
3940
"github.com/ava-labs/subnet-evm/vmerrs"
4041
"github.com/ethereum/go-ethereum/common"
4142
"github.com/ethereum/go-ethereum/common/math"
@@ -57,7 +58,7 @@ type PrecompiledContract interface {
5758

5859
// PrecompiledContractsHomestead contains the default set of pre-compiled Ethereum
5960
// contracts used in the Frontier and Homestead releases.
60-
var PrecompiledContractsHomestead = map[common.Address]precompile.StatefulPrecompiledContract{
61+
var PrecompiledContractsHomestead = map[common.Address]contract.StatefulPrecompiledContract{
6162
common.BytesToAddress([]byte{1}): newWrappedPrecompiledContract(&ecrecover{}),
6263
common.BytesToAddress([]byte{2}): newWrappedPrecompiledContract(&sha256hash{}),
6364
common.BytesToAddress([]byte{3}): newWrappedPrecompiledContract(&ripemd160hash{}),
@@ -66,7 +67,7 @@ var PrecompiledContractsHomestead = map[common.Address]precompile.StatefulPrecom
6667

6768
// PrecompiledContractsByzantium contains the default set of pre-compiled Ethereum
6869
// contracts used in the Byzantium release.
69-
var PrecompiledContractsByzantium = map[common.Address]precompile.StatefulPrecompiledContract{
70+
var PrecompiledContractsByzantium = map[common.Address]contract.StatefulPrecompiledContract{
7071
common.BytesToAddress([]byte{1}): newWrappedPrecompiledContract(&ecrecover{}),
7172
common.BytesToAddress([]byte{2}): newWrappedPrecompiledContract(&sha256hash{}),
7273
common.BytesToAddress([]byte{3}): newWrappedPrecompiledContract(&ripemd160hash{}),
@@ -79,7 +80,7 @@ var PrecompiledContractsByzantium = map[common.Address]precompile.StatefulPrecom
7980

8081
// PrecompiledContractsIstanbul contains the default set of pre-compiled Ethereum
8182
// contracts used in the Istanbul release.
82-
var PrecompiledContractsIstanbul = map[common.Address]precompile.StatefulPrecompiledContract{
83+
var PrecompiledContractsIstanbul = map[common.Address]contract.StatefulPrecompiledContract{
8384
common.BytesToAddress([]byte{1}): newWrappedPrecompiledContract(&ecrecover{}),
8485
common.BytesToAddress([]byte{2}): newWrappedPrecompiledContract(&sha256hash{}),
8586
common.BytesToAddress([]byte{3}): newWrappedPrecompiledContract(&ripemd160hash{}),
@@ -93,7 +94,7 @@ var PrecompiledContractsIstanbul = map[common.Address]precompile.StatefulPrecomp
9394

9495
// PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum
9596
// contracts used in the Berlin release.
96-
var PrecompiledContractsBerlin = map[common.Address]precompile.StatefulPrecompiledContract{
97+
var PrecompiledContractsBerlin = map[common.Address]contract.StatefulPrecompiledContract{
9798
common.BytesToAddress([]byte{1}): newWrappedPrecompiledContract(&ecrecover{}),
9899
common.BytesToAddress([]byte{2}): newWrappedPrecompiledContract(&sha256hash{}),
99100
common.BytesToAddress([]byte{3}): newWrappedPrecompiledContract(&ripemd160hash{}),
@@ -107,7 +108,7 @@ var PrecompiledContractsBerlin = map[common.Address]precompile.StatefulPrecompil
107108

108109
// PrecompiledContractsBLS contains the set of pre-compiled Ethereum
109110
// contracts specified in EIP-2537. These are exported for testing purposes.
110-
var PrecompiledContractsBLS = map[common.Address]precompile.StatefulPrecompiledContract{
111+
var PrecompiledContractsBLS = map[common.Address]contract.StatefulPrecompiledContract{
111112
common.BytesToAddress([]byte{10}): newWrappedPrecompiledContract(&bls12381G1Add{}),
112113
common.BytesToAddress([]byte{11}): newWrappedPrecompiledContract(&bls12381G1Mul{}),
113114
common.BytesToAddress([]byte{12}): newWrappedPrecompiledContract(&bls12381G1MultiExp{}),
@@ -158,8 +159,8 @@ func init() {
158159

159160
// Ensure that this package will panic during init if there is a conflict present with the declared
160161
// precompile addresses.
161-
for _, module := range precompile.RegisteredModules() {
162-
address := module.Address()
162+
for _, module := range modules.RegisteredModules() {
163+
address := module.Address
163164
if _, ok := PrecompileAllNativeAddresses[address]; ok {
164165
panic(fmt.Errorf("precompile address collides with existing native address: %s", address))
165166
}

core/vm/contracts_stateful.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
package vm
55

66
import (
7-
"github.com/ava-labs/subnet-evm/precompile"
7+
"github.com/ava-labs/subnet-evm/precompile/contract"
88
"github.com/ethereum/go-ethereum/common"
99
)
1010

@@ -16,16 +16,16 @@ type wrappedPrecompiledContract struct {
1616

1717
// newWrappedPrecompiledContract returns a wrapped version of [PrecompiledContract] to be executed according to the StatefulPrecompiledContract
1818
// interface.
19-
func newWrappedPrecompiledContract(p PrecompiledContract) precompile.StatefulPrecompiledContract {
19+
func newWrappedPrecompiledContract(p PrecompiledContract) contract.StatefulPrecompiledContract {
2020
return &wrappedPrecompiledContract{p: p}
2121
}
2222

2323
// Run implements the StatefulPrecompiledContract interface
24-
func (w *wrappedPrecompiledContract) Run(accessibleState precompile.PrecompileAccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) {
24+
func (w *wrappedPrecompiledContract) Run(accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) {
2525
return RunPrecompiledContract(w.p, input, suppliedGas)
2626
}
2727

2828
// RunStatefulPrecompiledContract confirms runs [precompile] with the specified parameters.
29-
func RunStatefulPrecompiledContract(precompile precompile.StatefulPrecompiledContract, accessibleState precompile.PrecompileAccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) {
29+
func RunStatefulPrecompiledContract(precompile contract.StatefulPrecompiledContract, accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) {
3030
return precompile.Run(accessibleState, caller, addr, input, suppliedGas, readOnly)
3131
}

0 commit comments

Comments
 (0)