Skip to content

Commit

Permalink
core: enable Shanghai EIPs (#1970)
Browse files Browse the repository at this point in the history
  • Loading branch information
buddh0 authored Nov 20, 2023
1 parent 497fdf8 commit 0224d48
Show file tree
Hide file tree
Showing 12 changed files with 151 additions and 76 deletions.
1 change: 1 addition & 0 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ jobs:
CGO_CFLAGS_ALLOW: "-O -D__BLST_PORTABLE__"
ANDROID_HOME: "" # Skip android test
run: |
git submodule update --init --depth 1 --recursive
go mod download
make test
44 changes: 43 additions & 1 deletion consensus/misc/eip1559/eip1559.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
)
Expand All @@ -45,5 +47,45 @@ func VerifyEIP1559Header(config *params.ChainConfig, parent, header *types.Heade

// CalcBaseFee calculates the basefee of the header.
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
return new(big.Int).SetUint64(params.InitialBaseFee)
if config.Parlia != nil {
return new(big.Int).SetUint64(params.InitialBaseFee)
}

// If the current block is the first EIP-1559 block, return the InitialBaseFee.
if !config.IsLondon(parent.Number) {
return new(big.Int).SetUint64(params.InitialBaseFee)
}

parentGasTarget := parent.GasLimit / config.ElasticityMultiplier()
// If the parent gasUsed is the same as the target, the baseFee remains unchanged.
if parent.GasUsed == parentGasTarget {
return new(big.Int).Set(parent.BaseFee)
}

var (
num = new(big.Int)
denom = new(big.Int)
)

if parent.GasUsed > parentGasTarget {
// If the parent block used more gas than its target, the baseFee should increase.
// max(1, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
num.SetUint64(parent.GasUsed - parentGasTarget)
num.Mul(num, parent.BaseFee)
num.Div(num, denom.SetUint64(parentGasTarget))
num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator()))
baseFeeDelta := math.BigMax(num, common.Big1)

return num.Add(parent.BaseFee, baseFeeDelta)
} else {
// Otherwise if the parent block used less gas than its target, the baseFee should decrease.
// max(0, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
num.SetUint64(parentGasTarget - parent.GasUsed)
num.Mul(num, parent.BaseFee)
num.Div(num, denom.SetUint64(parentGasTarget))
num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator()))
baseFee := num.Sub(parent.BaseFee, num)

return math.BigMax(baseFee, common.Big0)
}
}
5 changes: 5 additions & 0 deletions consensus/misc/eip1559/eip1559_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ func copyConfig(original *params.ChainConfig) *params.ChainConfig {

func config() *params.ChainConfig {
config := copyConfig(params.TestChainConfig)
config.Ethash = nil
config.Parlia = &params.ParliaConfig{
Period: 3,
Epoch: 200,
}
config.LondonBlock = big.NewInt(5)
return config
}
Expand Down
2 changes: 1 addition & 1 deletion core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ func (g *Genesis) ToBlock() *types.Block {
var withdrawals []*types.Withdrawal
if conf := g.Config; conf != nil {
num := big.NewInt(int64(g.Number))
if conf.IsShanghai(num, g.Timestamp) {
if conf.Parlia == nil && conf.IsShanghai(num, g.Timestamp) {
head.WithdrawalsHash = &types.EmptyWithdrawalsHash
withdrawals = make([]*types.Withdrawal, 0)
}
Expand Down
2 changes: 1 addition & 1 deletion core/vm/jump_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func newCancunInstructionSet() JumpTable {
}

func newShanghaiInstructionSet() JumpTable {
instructionSet := newMergeInstructionSet()
instructionSet := newLondonInstructionSet()
enable3855(&instructionSet) // PUSH0 instruction
enable3860(&instructionSet) // Limit and meter initcode

Expand Down
141 changes: 75 additions & 66 deletions eth/filters/filter_test.go

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,12 @@ func (c *ChainConfig) String() string {
engine = "unknown"
}

return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v,Luban: %v, Plato: %v, Hertz: %v, Engine: %v}",
var ShanghaiTime *big.Int
if c.ShanghaiTime != nil {
ShanghaiTime = big.NewInt(0).SetUint64(*c.ShanghaiTime)
}

return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v,Luban: %v, Plato: %v, Hertz: %v, ShanghaiTime: %d, Engine: %v}",
c.ChainID,
c.HomesteadBlock,
c.DAOForkBlock,
Expand Down Expand Up @@ -561,6 +566,7 @@ func (c *ChainConfig) String() string {
c.LubanBlock,
c.PlatoBlock,
c.HertzBlock,
ShanghaiTime,
engine,
)
}
Expand Down
5 changes: 4 additions & 1 deletion tests/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestBlockchain(t *testing.T) {
// For speedier CI-runs, the line below can be uncommented, so those are skipped.
// For now, in hardfork-times (Berlin), we run the tests both as StateTests and
// as blockchain tests, since the latter also covers things like receipt root
bt.skipLoad(`^GeneralStateTests/`)
// bt.skipLoad(`^GeneralStateTests/`)

// Skip random failures due to selfish mining test
bt.skipLoad(`.*bcForgedTest/bcForkUncle\.json`)
Expand All @@ -49,6 +49,9 @@ func TestBlockchain(t *testing.T) {
// using 4.6 TGas
bt.skipLoad(`.*randomStatetest94.json.*`)

bt.runonly(`^GeneralStateTests/Shanghai`)
bt.runonly(`^Pyspecs/shanghai/eip3.*`)

bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) {
if err := bt.checkFailure(t, test.Run(false, rawdb.HashScheme, nil)); err != nil {
t.Errorf("test in hash mode without snapshotter failed: %v", err)
Expand Down
13 changes: 10 additions & 3 deletions tests/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ type testMatcher struct {
failpat []testFailure
skiploadpat []*regexp.Regexp
slowpat []*regexp.Regexp
runonlylistpat *regexp.Regexp
runonlylistpat []*regexp.Regexp
}

type testConfig struct {
Expand Down Expand Up @@ -127,7 +127,7 @@ func (tm *testMatcher) fails(pattern string, reason string) {
}

func (tm *testMatcher) runonly(pattern string) {
tm.runonlylistpat = regexp.MustCompile(pattern)
tm.runonlylistpat = append(tm.runonlylistpat, regexp.MustCompile(pattern))
}

// config defines chain config for tests matching the pattern.
Expand Down Expand Up @@ -220,7 +220,14 @@ func (tm *testMatcher) runTestFile(t *testing.T, path, name string, runTest inte
t.Skip(r)
}
if tm.runonlylistpat != nil {
if !tm.runonlylistpat.MatchString(name) {
match := false
for _, pat := range tm.runonlylistpat {
if pat.MatchString(name) {
match = true
break
}
}
if !match {
t.Skip("Skipped by runonly")
}
}
Expand Down
2 changes: 2 additions & 0 deletions tests/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ func TestState(t *testing.T) {
st.fails(`stEIP4844-blobtransactions/opcodeBlobhashOutOfRange.json`, "test has incorrect state root")
st.fails(`stEIP4844-blobtransactions/opcodeBlobhBounds.json`, "test has incorrect state root")

st.runonly(`^Shanghai`)

// For Istanbul, older tests were moved into LegacyTests
for _, dir := range []string{
filepath.Join(baseDir, "EIPTests", "StateTests"),
Expand Down
2 changes: 1 addition & 1 deletion tests/state_test_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
// And _now_ get the state root
root := statedb.IntermediateRoot(config.IsEIP158(block.Number()))
statedb.SetExpectedStateRoot(root)
root, _, err = statedb.Commit(block.NumberU64(), nil)
root, _, _ = statedb.Commit(block.NumberU64(), nil)
return triedb, snaps, statedb, root, err
}

Expand Down
2 changes: 1 addition & 1 deletion trie/triedb/pathdb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func New(diskdb ethdb.Database, config *Config) *Database {
// mechanism also ensures that at most one **non-readOnly** database
// is opened at the same time to prevent accidental mutation.
if ancient, err := diskdb.AncientDatadir(); err == nil && ancient != "" && !db.readOnly {
offset := uint64(0) //TODO(Nathan): just for passing compilation
offset := uint64(0) // differ from in block data, only metadata is used in state data
freezer, err := rawdb.NewStateFreezer(ancient, false, offset)
if err != nil {
log.Crit("Failed to open state history freezer", "err", err)
Expand Down

0 comments on commit 0224d48

Please sign in to comment.