Skip to content

Commit

Permalink
add precompiles to named fork config; fix issue with maps on fork con…
Browse files Browse the repository at this point in the history
…figs
  • Loading branch information
mycodecrafting committed Feb 7, 2025
1 parent 1f1aacd commit 8497d10
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 23 deletions.
2 changes: 1 addition & 1 deletion core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig

// Set up precompiles
evm.precompileManager = NewPrecompileManager(evm)
evm.precompileManager.RegisterMap(pconfig.PrecompileConfig(chainConfig, blockCtx.BlockNumber.Uint64(), blockCtx.Time))
evm.precompileManager.RegisterMap(pconfig.GetPrecompiles(chainConfig, blockCtx.BlockNumber.Uint64(), blockCtx.Time))

return evm
}
Expand Down
2 changes: 1 addition & 1 deletion grpc/execution/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestExecutionService_GetGenesisInfo(t *testing.T) {
hashedRollupId := sha256.Sum256([]byte(ethservice.BlockChain().Config().AstriaRollupName))

require.True(t, bytes.Equal(genesisInfo.RollupId.Inner, hashedRollupId[:]), "RollupId is not correct")
require.Equal(t, genesisInfo.GetSequencerStartBlockHeight(), ethservice.BlockChain().Config().AstriaForks.GetForkAtHeight(1).Sequencer.StartHeight, "SequencerInitialHeight is not correct")
require.Equal(t, genesisInfo.GetSequencerStartHeight(), ethservice.BlockChain().Config().AstriaForks.GetForkAtHeight(1).Sequencer.StartHeight, "SequencerInitialHeight is not correct")
require.Equal(t, genesisInfo.GetCelestiaBlockVariance(), ethservice.BlockChain().Config().AstriaForks.GetForkAtHeight(1).Celestia.HeightVariance, "CelestiaHeightVariance is not correct")
require.True(t, serviceV1Alpha1.genesisInfoCalled, "GetGenesisInfo should be called")
}
Expand Down
75 changes: 63 additions & 12 deletions params/astria_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ type AstriaForks struct {
}

type AstriaForkConfig struct {
Height uint64 `json:"height"`
Halt bool `json:"halt,omitempty"`
SnapshotChecksum string `json:"snapshotChecksum,omitempty"`
ExtraDataOverride hexutil.Bytes `json:"extraDataOverride,omitempty"`
FeeCollector *common.Address `json:"feeCollector,omitempty"`
EIP1559Params *AstriaEIP1559Params `json:"eip1559Params,omitempty"`
Sequencer *AstriaSequencerConfig `json:"sequencer,omitempty"`
Celestia *AstriaCelestiaConfig `json:"celestia,omitempty"`
BridgeAddresses []AstriaBridgeAddressConfig `json:"bridgeAddresses,omitempty"`
Height uint64 `json:"height"`
Halt bool `json:"halt,omitempty"`
SnapshotChecksum string `json:"snapshotChecksum,omitempty"`
ExtraDataOverride hexutil.Bytes `json:"extraDataOverride,omitempty"`
FeeCollector *common.Address `json:"feeCollector,omitempty"`
EIP1559Params *AstriaEIP1559Params `json:"eip1559Params,omitempty"`
Sequencer *AstriaSequencerConfig `json:"sequencer,omitempty"`
Celestia *AstriaCelestiaConfig `json:"celestia,omitempty"`
BridgeAddresses []AstriaBridgeAddressConfig `json:"bridgeAddresses,omitempty"`
Precompiles map[common.Address]PrecompileType `json:"precompiles,omitempty"`
}

type AstriaForkData struct {
Expand All @@ -44,6 +45,7 @@ type AstriaForkData struct {
Celestia AstriaCelestiaConfig
BridgeAddresses map[string]*AstriaBridgeAddressConfig // astria bridge addess to config for that bridge account
BridgeAllowedAssets map[string]struct{} // a set of allowed asset IDs structs are left empty
Precompiles map[common.Address]PrecompileType
}

type AstriaSequencerConfig struct {
Expand Down Expand Up @@ -114,9 +116,22 @@ func NewAstriaForks(forks map[string]AstriaForkConfig) (*AstriaForks, error) {
if i > 0 {
// Copy previous fork's configuration as the base
orderedForks[i] = orderedForks[i-1]
} else {
// set default values
orderedForks[i] = GetDefaultAstriaForkData()

// maps are pointers, so we need to create new maps for each fork
orderedForks[i].BridgeAddresses = make(map[string]*AstriaBridgeAddressConfig)
orderedForks[i].BridgeAllowedAssets = make(map[string]struct{})
orderedForks[i].Precompiles = make(map[common.Address]PrecompileType)

// Copy previous fork's maps if needed
for k, v := range orderedForks[i-1].BridgeAddresses {
orderedForks[i].BridgeAddresses[k] = v
}
for k, v := range orderedForks[i-1].BridgeAllowedAssets {
orderedForks[i].BridgeAllowedAssets[k] = v
}
for k, v := range orderedForks[i-1].Precompiles {
orderedForks[i].Precompiles[k] = v
}
}

// Set fork-specific fields
Expand Down Expand Up @@ -186,6 +201,17 @@ func NewAstriaForks(forks map[string]AstriaForkConfig) (*AstriaForks, error) {
}
}
}

// add precompiles
if len(currentFork.Precompiles) > 0 {
for addr, pType := range currentFork.Precompiles {
orderedForks[i].Precompiles[addr] = pType
}
}

if orderedForks[i].Precompiles == nil {
orderedForks[i].Precompiles = make(map[common.Address]PrecompileType)
}
}

if err := validateAstriaForks(orderedForks); err != nil {
Expand Down Expand Up @@ -229,6 +255,12 @@ func validateAstriaForks(forks []AstriaForkData) error {
if fork.FeeCollector == (common.Address{}) {
log.Warn("fee asset collectors not set, assets will be burned", "fork", fork.Name)
}

for _, pType := range fork.Precompiles {
if err := pType.Validate(); err != nil {
return fmt.Errorf("fork %s: invalid precompile %s", fork.Name, pType)
}
}
} else {
log.Warn("fork will halt", "fork", fork.Name, "height", fork.Height)
}
Expand All @@ -249,6 +281,7 @@ func GetDefaultAstriaForkData() AstriaForkData {
},
BridgeAddresses: make(map[string]*AstriaBridgeAddressConfig),
BridgeAllowedAssets: make(map[string]struct{}),
Precompiles: make(map[common.Address]PrecompileType),
}
}

Expand Down Expand Up @@ -370,3 +403,21 @@ func (abc *AstriaBridgeAddressConfig) ScaledDepositAmount(deposit *big.Int) *big

return new(big.Int).Mul(deposit, multiplier)
}

// PrecompileType represents the type of precompile to enable
type PrecompileType string

const (
PrecompileBase64 PrecompileType = "base64"
// Add other precompile types here as needed
)

// Validate ensures the PrecompileType is a known value
func (p PrecompileType) Validate() error {
switch p {
case PrecompileBase64:
return nil
default:
return fmt.Errorf("unknown precompile type: %s", p)
}
}
23 changes: 22 additions & 1 deletion params/astria_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,9 @@ func TestAstriaForksInheritance(t *testing.T) {
ElasticityMultiplier: 4,
BaseFeeChangeDenominator: 16,
},
Precompiles: map[common.Address]PrecompileType{
common.HexToAddress("0x01"): PrecompileBase64,
},
},
"fork3": {
Height: 251,
Expand All @@ -483,7 +486,9 @@ func TestAstriaForksInheritance(t *testing.T) {
ChainID: "chain3",
StartHeight: 325,
},
// EIP1559Params should be inherited from fork2
Precompiles: map[common.Address]PrecompileType{
common.HexToAddress("0x02"): PrecompileBase64,
},
},
}

Expand All @@ -501,6 +506,7 @@ func TestAstriaForksInheritance(t *testing.T) {
t.Logf(" Sequencer:")
t.Logf(" ChainID: %s", fork.Sequencer.ChainID)
t.Logf(" StartHeight: %d", fork.Sequencer.StartHeight)
t.Logf(" Precompiles: %v", fork.Precompiles)
}

type testCheck struct {
Expand All @@ -513,6 +519,7 @@ func TestAstriaForksInheritance(t *testing.T) {
celestiaChainID string
celestiaStartHeight uint64
celestiaHeightVariance uint64
precompiles map[common.Address]PrecompileType
}

tests := []struct {
Expand All @@ -533,6 +540,7 @@ func TestAstriaForksInheritance(t *testing.T) {
celestiaChainID: "celestia1",
celestiaStartHeight: 1,
celestiaHeightVariance: 100,
precompiles: map[common.Address]PrecompileType{},
},
},
{
Expand All @@ -548,6 +556,9 @@ func TestAstriaForksInheritance(t *testing.T) {
celestiaChainID: "celestia1",
celestiaStartHeight: 1,
celestiaHeightVariance: 100,
precompiles: map[common.Address]PrecompileType{
common.HexToAddress("0x01"): PrecompileBase64,
},
},
},
{
Expand All @@ -563,6 +574,9 @@ func TestAstriaForksInheritance(t *testing.T) {
celestiaChainID: "celestia1",
celestiaStartHeight: 1,
celestiaHeightVariance: 100,
precompiles: map[common.Address]PrecompileType{
common.HexToAddress("0x01"): PrecompileBase64,
},
},
},
{
Expand All @@ -578,6 +592,10 @@ func TestAstriaForksInheritance(t *testing.T) {
celestiaChainID: "celestia1",
celestiaStartHeight: 1,
celestiaHeightVariance: 100,
precompiles: map[common.Address]PrecompileType{
common.HexToAddress("0x01"): PrecompileBase64,
common.HexToAddress("0x02"): PrecompileBase64,
},
},
},
}
Expand Down Expand Up @@ -613,6 +631,9 @@ func TestAstriaForksInheritance(t *testing.T) {
if got := fork.Celestia.HeightVariance; got != test.checks.celestiaHeightVariance {
t.Errorf("Celestia.HeightVariance = %v, want %v", got, test.checks.celestiaHeightVariance)
}
if !reflect.DeepEqual(fork.Precompiles, test.checks.precompiles) {
t.Errorf("Precompiles = %v, want %v", fork.Precompiles, test.checks.precompiles)
}
})
}
}
40 changes: 32 additions & 8 deletions precompile/config/config.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,43 @@
package config

import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/precompile"
pcbase64 "github.com/ethereum/go-ethereum/precompile/contracts/base64"
)

var NullPrecompiles = precompile.PrecompileMap{}

// Cache of initialized precompiles for each fork
var precompileCache = make(map[string]precompile.PrecompileMap)

// return precompiles that are enabled at height
func PrecompileConfig(chainConfig *params.ChainConfig, height uint64, timestamp uint64) precompile.PrecompileMap {
// Example, enable the base64 precompile at address 0x0000000000000000000000000000000000001000:
// (add `import pcbase64 "github.com/ethereum/go-ethereum/precompile/contracts/base64"`)
// return precompile.PrecompileMap{
// common.HexToAddress("0x01000"): pcbase64.NewBase64(),
// }

return NullPrecompiles
func GetPrecompiles(chainConfig *params.ChainConfig, height uint64, timestamp uint64) precompile.PrecompileMap {
fork := chainConfig.GetAstriaForks().GetForkAtHeight(height)

// Return early if no precompiles configured
if len(fork.Precompiles) == 0 {
return NullPrecompiles
}

// Check if we've already initialized precompiles for this fork
if cached, exists := precompileCache[fork.Name]; exists {
return cached
}

// Initialize precompiles for this fork
precompiles := make(precompile.PrecompileMap)
for addr, precompileType := range fork.Precompiles {
switch precompileType {
case params.PrecompileBase64:
precompiles[addr] = pcbase64.NewBase64()
default:
log.Error("Unknown precompile type", "type", precompileType, "address", addr)
}
}

// Cache the initialized precompiles
precompileCache[fork.Name] = precompiles
return precompiles
}

0 comments on commit 8497d10

Please sign in to comment.