Skip to content

Commit

Permalink
Merge pull request #109 from bobanetwork/add-granite-hardfork
Browse files Browse the repository at this point in the history
Add Granite hardfork
  • Loading branch information
boyuan-chen authored Aug 22, 2024
2 parents 7ca3cd6 + d52d33f commit 7c7d111
Show file tree
Hide file tree
Showing 15 changed files with 375 additions and 21 deletions.
7 changes: 7 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ var (
Name: "override.fjord",
Usage: "Manually specify the Optimism Fjord fork timestamp, overriding the bundled setting",
}
OverrideOptimismGraniteFlag = flags.BigFlag{
Name: "override.granite",
Usage: "Manually specify the Optimism Granite fork timestamp, overriding the bundled setting",
}
// Ethash settings
EthashCachesInMemoryFlag = cli.IntFlag{
Name: "ethash.cachesinmem",
Expand Down Expand Up @@ -1971,6 +1975,9 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C
cfg.OverrideOptimismFjordTime = flags.GlobalBig(ctx, OverrideOptimismFjordFlag.Name)
cfg.TxPool.OptimismFjordTime = cfg.OverrideOptimismFjordTime
}
if ctx.IsSet(OverrideOptimismGraniteFlag.Name) {
cfg.OverrideOptimismGraniteTime = flags.GlobalBig(ctx, OverrideOptimismGraniteFlag.Name)
}
if ctx.IsSet(InternalConsensusFlag.Name) && clparams.EmbeddedSupported(cfg.NetworkID) {
cfg.InternalCL = ctx.Bool(InternalConsensusFlag.Name)
}
Expand Down
4 changes: 4 additions & 0 deletions core/genesis_write.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ type ChainOverrides struct {
OverrideOptimismCanyonTime *big.Int
OverrideOptimismEcotoneTime *big.Int
OverrideOptimismFjordTime *big.Int
OverrideOptimismGraniteTime *big.Int
}

// CommitGenesisBlock writes or updates the genesis block in db.
Expand Down Expand Up @@ -152,6 +153,9 @@ func WriteGenesisBlock(tx kv.RwTx, genesis *types.Genesis, overrides *ChainOverr
if overrides.OverrideOptimismFjordTime != nil {
config.FjordTime = overrides.OverrideOptimismFjordTime
}
if overrides.OverrideOptimismGraniteTime != nil {
config.GraniteTime = overrides.OverrideOptimismGraniteTime
}
}

if (storedHash == libcommon.Hash{}) {
Expand Down
41 changes: 41 additions & 0 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,22 @@ var PrecompiledContractsFjord = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
}

// PrecompiledContractsGranite contains the default set of pre-compiled Ethereum
// contracts used in the Granite release.
var PrecompiledContractsGranite = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{1}): &ecrecover{},
libcommon.BytesToAddress([]byte{2}): &sha256hash{},
libcommon.BytesToAddress([]byte{3}): &ripemd160hash{},
libcommon.BytesToAddress([]byte{4}): &dataCopy{},
libcommon.BytesToAddress([]byte{5}): &bigModExp{eip2565: true},
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
libcommon.BytesToAddress([]byte{8}): &bn256PairingGranite{},
libcommon.BytesToAddress([]byte{9}): &blake2F{},
libcommon.BytesToAddress([]byte{0x0a}): &pointEvaluation{},
libcommon.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
}

var PrecompiledContractsNapoli = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{0x01}): &ecrecover{},
libcommon.BytesToAddress([]byte{0x02}): &sha256hash{},
Expand Down Expand Up @@ -167,6 +183,7 @@ var PrecompiledContractsPrague = map[libcommon.Address]PrecompiledContract{
}

var (
PrecompiledAddressesGranite []libcommon.Address
PrecompiledAddressesFjord []libcommon.Address
PrecompiledAddressesPrague []libcommon.Address
PrecompiledAddressesNapoli []libcommon.Address
Expand Down Expand Up @@ -196,6 +213,9 @@ func init() {
for k := range PrecompiledContractsFjord {
PrecompiledAddressesFjord = append(PrecompiledAddressesFjord, k)
}
for k := range PrecompiledContractsGranite {
PrecompiledAddressesGranite = append(PrecompiledAddressesGranite, k)
}
for k := range PrecompiledContractsNapoli {
PrecompiledAddressesNapoli = append(PrecompiledAddressesNapoli, k)
}
Expand All @@ -207,6 +227,8 @@ func init() {
// ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules *chain.Rules) []libcommon.Address {
switch {
case rules.IsOptimismGranite:
return PrecompiledAddressesGranite
case rules.IsOptimismFjord:
return PrecompiledAddressesFjord
case rules.IsPrague:
Expand Down Expand Up @@ -595,6 +617,9 @@ var (

// errBadPairingInput is returned if the bn256 pairing input is invalid.
errBadPairingInput = errors.New("bad elliptic curve pairing size")

// errBadPairingInputSize is returned if the bn256 pairing input size is invalid.
errBadPairingInputSize = errors.New("bad elliptic curve pairing input size")
)

// runBn256Pairing implements the Bn256Pairing precompile, referenced by both
Expand Down Expand Up @@ -628,6 +653,22 @@ func runBn256Pairing(input []byte) ([]byte, error) {
return false32Byte, nil
}

// bn256PairingGranite implements a pairing pre-compile for the bn256 curve
// conforming to Granite consensus rules.
type bn256PairingGranite struct{}

// RequiredGas returns the gas required to execute the pre-compiled contract.
func (c *bn256PairingGranite) RequiredGas(input []byte) uint64 {
return new(bn256PairingIstanbul).RequiredGas(input)
}

func (c *bn256PairingGranite) Run(input []byte) ([]byte, error) {
if len(input) > int(params.Bn256PairingMaxInputSizeGranite) {
return nil, errBadPairingInputSize
}
return runBn256Pairing(input)
}

// bn256PairingIstanbul implements a pairing pre-compile for the bn256 curve
// conforming to Istanbul consensus rules.
type bn256PairingIstanbul struct{}
Expand Down
12 changes: 11 additions & 1 deletion core/vm/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
libcommon "github.com/ledgerwatch/erigon-lib/common"

"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/params"
)

// precompiledTest defines the input/output pairs for precompiled contract tests.
Expand Down Expand Up @@ -56,7 +57,7 @@ var allPrecompiles = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true},
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
libcommon.BytesToAddress([]byte{8}): &bn256PairingGranite{},
libcommon.BytesToAddress([]byte{9}): &blake2F{},
libcommon.BytesToAddress([]byte{10}): &bls12381G1Add{},
libcommon.BytesToAddress([]byte{11}): &bls12381G1Mul{},
Expand Down Expand Up @@ -279,6 +280,15 @@ func TestPrecompileBlake2FMalformedInput(t *testing.T) {
}
}

func TestPrecompileBn256PairingTooLargeInput(t *testing.T) {
big := make([]byte, params.Bn256PairingMaxInputSizeGranite+1)
testPrecompiledFailure("08", precompiledFailureTest{
Input: common.Bytes2Hex(big),
ExpectedError: "bad elliptic curve pairing input size",
Name: "bn256Pairing_input_too_big",
}, t)
}

func TestPrecompiledEcrecover(t *testing.T) { testJson("ecRecover", "01", t) }

func testJson(name, addr string, t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ var emptyCodeHash = crypto.Keccak256Hash(nil)
func (evm *EVM) precompile(addr libcommon.Address) (PrecompiledContract, bool) {
var precompiles map[libcommon.Address]PrecompiledContract
switch {
case evm.chainRules.IsOptimismGranite:
precompiles = PrecompiledContractsGranite
case evm.chainRules.IsOptimismFjord:
precompiles = PrecompiledContractsFjord
case evm.chainRules.IsPrague:
Expand Down
14 changes: 13 additions & 1 deletion erigon-lib/chain/chain_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ type Config struct {
// Delta: the Delta upgrade does not affect the execution-layer, and is thus not configurable in the chain config.
EcotoneTime *big.Int `json:"ecotoneTime,omitempty"` // Ecotone switch time (nil = no fork, 0 = already on optimism ecotone)
FjordTime *big.Int `json:"fjordTime,omitempty"` // Fjord switch time (nil = no fork, 0 = already on optimism fjord)
GraniteTime *big.Int `json:"graniteTime,omitempty"` // Granite switch time (nil = no fork, 0 = already on Optimism Granite)

// Optional EIP-4844 parameters
MinBlobGasPrice *uint64 `json:"minBlobGasPrice,omitempty"`
Expand Down Expand Up @@ -125,7 +126,7 @@ type BorConfig interface {
func (c *Config) String() string {
engine := c.getEngine()

return fmt.Sprintf("{ChainID: %v, Homestead: %v, DAO: %v, Tangerine Whistle: %v, Spurious Dragon: %v, Byzantium: %v, Constantinople: %v, Petersburg: %v, Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Gray Glacier: %v, Terminal Total Difficulty: %v, Merge Netsplit: %v, Shanghai: %v, Cancun: %v, Prague: %v, Osaka: %v, BedrockBlock: %v, RegolithTime: %v, CanyonTime: %v, EcotoneTime: %v, FjordTime: %v, Engine: %v , NoPruneContracts: %v}",
return fmt.Sprintf("{ChainID: %v, Homestead: %v, DAO: %v, Tangerine Whistle: %v, Spurious Dragon: %v, Byzantium: %v, Constantinople: %v, Petersburg: %v, Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Gray Glacier: %v, Terminal Total Difficulty: %v, Merge Netsplit: %v, Shanghai: %v, Cancun: %v, Prague: %v, Osaka: %v, BedrockBlock: %v, RegolithTime: %v, CanyonTime: %v, EcotoneTime: %v, FjordTime: %v, GraniteTime: %v, Engine: %v , NoPruneContracts: %v}",
c.ChainID,
c.HomesteadBlock,
c.DAOForkBlock,
Expand All @@ -151,6 +152,7 @@ func (c *Config) String() string {
c.CanyonTime,
c.EcotoneTime,
c.FjordTime,
c.GraniteTime,
engine,
c.NoPruneContracts,
)
Expand Down Expand Up @@ -293,6 +295,10 @@ func (c *Config) IsFjord(time uint64) bool {
return isForked(c.FjordTime, time)
}

func (c *Config) IsGranite(time uint64) bool {
return isForked(c.GraniteTime, time)
}

// IsOptimism returns whether the node is an optimism node or not.
func (c *Config) IsOptimism() bool {
return c.Optimism != nil
Expand All @@ -319,6 +325,10 @@ func (c *Config) IsOptimismFjord(time uint64) bool {
return c.IsOptimism() && c.IsFjord(time)
}

func (c *Config) IsOptimismGranite(time uint64) bool {
return c.IsOptimism() && c.IsGranite(time)
}

// IsOptimismPreBedrock returns true iff this is an optimism node & bedrock is not yet active
func (c *Config) IsOptimismPreBedrock(num uint64) bool {
return c.IsOptimism() && !c.IsBedrock(num)
Expand Down Expand Up @@ -612,6 +622,7 @@ type Rules struct {
IsAura bool
IsOptimismBedrock, IsOptimismRegolith bool
IsOptimismCanyon, IsOptimismFjord bool
IsOptimismGranite bool
}

// Rules ensures c's ChainID is not nil and returns a new Rules instance
Expand Down Expand Up @@ -642,6 +653,7 @@ func (c *Config) Rules(num uint64, time uint64) *Rules {
IsOptimismRegolith: c.IsOptimismRegolith(time),
IsOptimismCanyon: c.IsOptimismCanyon(time),
IsOptimismFjord: c.IsOptimismFjord(time),
IsOptimismGranite: c.IsOptimismGranite(time),
}
}

Expand Down
7 changes: 7 additions & 0 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger
OverrideOptimismCanyonTime: config.OverrideOptimismCanyonTime,
OverrideOptimismEcotoneTime: config.OverrideOptimismEcotoneTime,
OverrideOptimismFjordTime: config.OverrideOptimismFjordTime,
OverrideOptimismGraniteTime: config.OverrideOptimismGraniteTime,
OverridePragueTime: config.OverridePragueTime,
}
chainConfig, genesis, genesisErr = core.WriteGenesisBlock(tx, genesisSpec, overrides, tmpdir, logger)
Expand All @@ -337,6 +338,12 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger
if chainConfig.EcotoneTime == nil {
log.Warn("Optimism EcotoneTime has not been set")
}
if chainConfig.FjordTime == nil {
log.Warn("Optimism FjordTime has not been set")
}
if chainConfig.GraniteTime == nil {
log.Warn("Optimism GraniteTime has not been set")
}
}

setBorDefaultMinerGasPrice(chainConfig, config, logger)
Expand Down
1 change: 1 addition & 0 deletions eth/ethconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ type Config struct {
OverrideOptimismCanyonTime *big.Int `toml:",omitempty"`
OverrideOptimismEcotoneTime *big.Int `toml:",omitempty"`
OverrideOptimismFjordTime *big.Int `toml:",omitempty"`
OverrideOptimismGraniteTime *big.Int `toml:",omitempty"`

// Embedded Silkworm support
SilkwormExecution bool
Expand Down
Loading

0 comments on commit 7c7d111

Please sign in to comment.