mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-28 16:47:22 +00:00
Move EOF activation to Osaka
Add support for the Osaka fork and move all EOF activation and side effects to that fork.
This commit is contained in:
parent
56ff85a808
commit
257e27c8ed
15 changed files with 95 additions and 23 deletions
|
|
@ -32,7 +32,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
jt = vm.NewPragueEOFInstructionSetForTesting()
|
||||
jt = vm.NewOsakaEOFInstructionSetForTesting()
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ func FuzzEofParsing(f *testing.F) {
|
|||
// And do the fuzzing
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
var (
|
||||
jt = vm.NewPragueEOFInstructionSetForTesting()
|
||||
jt = vm.NewOsakaEOFInstructionSetForTesting()
|
||||
c vm.Container
|
||||
)
|
||||
cpy := common.CopyBytes(data)
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ func applyEOFChecks(prestate *Prestate, chainConfig *params.ChainConfig) error {
|
|||
)
|
||||
err = c.UnmarshalBinary(acc.Code, false)
|
||||
if err == nil {
|
||||
jt := vm.NewPragueEOFInstructionSetForTesting()
|
||||
jt := vm.NewOsakaEOFInstructionSetForTesting()
|
||||
err = c.ValidateCode(&jt, false)
|
||||
}
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -277,6 +277,7 @@ func TestVerkleGenesisCommit(t *testing.T) {
|
|||
ShanghaiTime: &verkleTime,
|
||||
CancunTime: &verkleTime,
|
||||
PragueTime: &verkleTime,
|
||||
OsakaTime: &verkleTime,
|
||||
VerkleTime: &verkleTime,
|
||||
TerminalTotalDifficulty: big.NewInt(0),
|
||||
TerminalTotalDifficultyPassed: true,
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
vmerr error // vm errors do not effect consensus and are therefore not assigned to err
|
||||
)
|
||||
if contractCreation {
|
||||
ret, _, st.gasRemaining, vmerr = st.evm.Create(sender, msg.Data, st.gasRemaining, value, rules.IsPrague)
|
||||
ret, _, st.gasRemaining, vmerr = st.evm.Create(sender, msg.Data, st.gasRemaining, value, rules.IsOsaka)
|
||||
// Special case for EOF, if the initcode or deployed code is
|
||||
// invalid, the tx is considered valid (so update nonce), but
|
||||
// gas for initcode execution is not consumed.
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ func TestValidateCode(t *testing.T) {
|
|||
data: make([]byte, 0),
|
||||
subContainers: make([]*Container, 0),
|
||||
}
|
||||
_, err := validateCode(test.code, test.section, container, &pragueEOFInstructionSet, false)
|
||||
_, err := validateCode(test.code, test.section, container, &osakaEOFInstructionSet, false)
|
||||
if !errors.Is(err, test.err) {
|
||||
t.Errorf("test %d (%s): unexpected error (want: %v, got: %v)", i, common.Bytes2Hex(test.code), test.err, err)
|
||||
}
|
||||
|
|
@ -277,7 +277,7 @@ func BenchmarkRJUMPI(b *testing.B) {
|
|||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := validateCode(code, 0, container, &pragueEOFInstructionSet, false)
|
||||
_, err := validateCode(code, 0, container, &osakaEOFInstructionSet, false)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
|
@ -309,7 +309,7 @@ func BenchmarkRJUMPV(b *testing.B) {
|
|||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := validateCode(code, 0, container, &pragueEOFInstructionSet, false)
|
||||
_, err := validateCode(code, 0, container, &osakaEOFInstructionSet, false)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
|
@ -357,7 +357,7 @@ func BenchmarkEOFValidation(b *testing.B) {
|
|||
if err := container2.UnmarshalBinary(bin, true); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
if err := container2.ValidateCode(&pragueEOFInstructionSet, false); err != nil {
|
||||
if err := container2.ValidateCode(&osakaEOFInstructionSet, false); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -412,7 +412,7 @@ func BenchmarkEOFValidation2(b *testing.B) {
|
|||
if err := container2.UnmarshalBinary(bin, true); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
if err := container2.ValidateCode(&pragueEOFInstructionSet, false); err != nil {
|
||||
if err := container2.ValidateCode(&osakaEOFInstructionSet, false); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -468,7 +468,7 @@ func BenchmarkEOFValidation3(b *testing.B) {
|
|||
if err := container2.UnmarshalBinary(bin, true); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
if err := container2.ValidateCode(&pragueEOFInstructionSet, false); err != nil {
|
||||
if err := container2.ValidateCode(&osakaEOFInstructionSet, false); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -494,7 +494,7 @@ func BenchmarkRJUMPI_2(b *testing.B) {
|
|||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := validateCode(code, 0, container, &pragueEOFInstructionSet, false)
|
||||
_, err := validateCode(code, 0, container, &osakaEOFInstructionSet, false)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
|
@ -512,6 +512,6 @@ func FuzzValidate(f *testing.F) {
|
|||
f.Fuzz(func(_ *testing.T, code []byte, maxStack uint16) {
|
||||
var container Container
|
||||
container.types = append(container.types, &functionMetadata{inputs: 0, outputs: 0x80, maxStackHeight: maxStack})
|
||||
validateCode(code, 0, &container, &pragueEOFInstructionSet, true)
|
||||
validateCode(code, 0, &container, &osakaEOFInstructionSet, true)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -578,8 +578,8 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address, valu
|
|||
|
||||
// Reject code starting with 0xEF if EIP-3541 is enabled.
|
||||
if len(ret) >= 1 && HasEOFByte(ret) {
|
||||
if evm.chainRules.IsPrague && isInitcodeEOF {
|
||||
// Don't reject EOF contracts after Prague
|
||||
if evm.chainRules.IsOsaka && isInitcodeEOF {
|
||||
// Don't reject EOF contracts after Osaka
|
||||
} else if evm.chainRules.IsLondon {
|
||||
return ret, ErrInvalidCode
|
||||
}
|
||||
|
|
@ -669,7 +669,7 @@ func (evm *EVM) GetVMContext() *tracing.VMContext {
|
|||
|
||||
// parseContainer tries to parse an EOF container if the Shanghai fork is active. It expects the code to already be validated.
|
||||
func (evm *EVM) parseContainer(b []byte) *Container {
|
||||
if evm.chainRules.IsPrague {
|
||||
if evm.chainRules.IsOsaka {
|
||||
var c Container
|
||||
if err := c.UnmarshalBinary(b, false); err != nil && strings.HasPrefix(err.Error(), "invalid magic") {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter {
|
|||
}
|
||||
}
|
||||
evm.Config.ExtraEips = extraEips
|
||||
return &EVMInterpreter{evm: evm, table: table, tableEOF: &pragueEOFInstructionSet}
|
||||
return &EVMInterpreter{evm: evm, table: table, tableEOF: &osakaEOFInstructionSet}
|
||||
}
|
||||
|
||||
// Run loops and evaluates the contract's code with the given input data and returns
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ var (
|
|||
mergeInstructionSet = newMergeInstructionSet()
|
||||
shanghaiInstructionSet = newShanghaiInstructionSet()
|
||||
cancunInstructionSet = newCancunInstructionSet()
|
||||
osakaEOFInstructionSet = newOsakaEOFInstructionSet()
|
||||
verkleInstructionSet = newVerkleInstructionSet()
|
||||
pragueEOFInstructionSet = newPragueEOFInstructionSet()
|
||||
)
|
||||
|
||||
// JumpTable contains the EVM opcodes supported at a given fork.
|
||||
|
|
@ -91,11 +91,11 @@ func newVerkleInstructionSet() JumpTable {
|
|||
return validate(instructionSet)
|
||||
}
|
||||
|
||||
func NewPragueEOFInstructionSetForTesting() JumpTable {
|
||||
return newPragueEOFInstructionSet()
|
||||
func NewOsakaEOFInstructionSetForTesting() JumpTable {
|
||||
return newOsakaEOFInstructionSet()
|
||||
}
|
||||
|
||||
func newPragueEOFInstructionSet() JumpTable {
|
||||
func newOsakaEOFInstructionSet() JumpTable {
|
||||
instructionSet := newCancunInstructionSet()
|
||||
enableEOF(&instructionSet)
|
||||
return validate(instructionSet)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ func LookupInstructionSet(rules params.Rules) (JumpTable, error) {
|
|||
switch {
|
||||
case rules.IsVerkle:
|
||||
return newCancunInstructionSet(), errors.New("verkle-fork not defined yet")
|
||||
case rules.IsOsaka:
|
||||
return newCancunInstructionSet(), errors.New("osaka-fork not defined yet")
|
||||
case rules.IsPrague:
|
||||
return newCancunInstructionSet(), errors.New("prague-fork not defined yet")
|
||||
case rules.IsCancun:
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
|||
input,
|
||||
cfg.GasLimit,
|
||||
uint256.MustFromBig(cfg.Value),
|
||||
rules.IsPrague,
|
||||
rules.IsOsaka,
|
||||
)
|
||||
return code, address, leftOverGas, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1098,6 +1098,10 @@ func overrideConfig(original *params.ChainConfig, override *params.ChainConfig)
|
|||
copy.PragueTime = timestamp
|
||||
canon = false
|
||||
}
|
||||
if timestamp := override.OsakaTime; timestamp != nil {
|
||||
copy.OsakaTime = timestamp
|
||||
canon = false
|
||||
}
|
||||
if timestamp := override.VerkleTime; timestamp != nil {
|
||||
copy.VerkleTime = timestamp
|
||||
canon = false
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ var (
|
|||
ShanghaiTime: nil,
|
||||
CancunTime: nil,
|
||||
PragueTime: nil,
|
||||
OsakaTime: nil,
|
||||
VerkleTime: nil,
|
||||
TerminalTotalDifficulty: nil,
|
||||
TerminalTotalDifficultyPassed: true,
|
||||
|
|
@ -185,6 +186,7 @@ var (
|
|||
ShanghaiTime: nil,
|
||||
CancunTime: nil,
|
||||
PragueTime: nil,
|
||||
OsakaTime: nil,
|
||||
VerkleTime: nil,
|
||||
TerminalTotalDifficulty: nil,
|
||||
TerminalTotalDifficultyPassed: false,
|
||||
|
|
@ -215,6 +217,7 @@ var (
|
|||
ShanghaiTime: nil,
|
||||
CancunTime: nil,
|
||||
PragueTime: nil,
|
||||
OsakaTime: nil,
|
||||
VerkleTime: nil,
|
||||
TerminalTotalDifficulty: nil,
|
||||
TerminalTotalDifficultyPassed: false,
|
||||
|
|
@ -245,6 +248,7 @@ var (
|
|||
ShanghaiTime: newUint64(0),
|
||||
CancunTime: newUint64(0),
|
||||
PragueTime: nil,
|
||||
OsakaTime: nil,
|
||||
VerkleTime: nil,
|
||||
TerminalTotalDifficulty: big.NewInt(0),
|
||||
TerminalTotalDifficultyPassed: true,
|
||||
|
|
@ -274,7 +278,7 @@ var (
|
|||
MergeNetsplitBlock: nil,
|
||||
ShanghaiTime: nil,
|
||||
CancunTime: nil,
|
||||
PragueTime: nil,
|
||||
OsakaTime: nil,
|
||||
VerkleTime: nil,
|
||||
TerminalTotalDifficulty: nil,
|
||||
TerminalTotalDifficultyPassed: false,
|
||||
|
|
@ -325,6 +329,7 @@ type ChainConfig struct {
|
|||
ShanghaiTime *uint64 `json:"shanghaiTime,omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai)
|
||||
CancunTime *uint64 `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun)
|
||||
PragueTime *uint64 `json:"pragueTime,omitempty"` // Prague switch time (nil = no fork, 0 = already on prague)
|
||||
OsakaTime *uint64 `json:"osakaTime,omitempty"` // Osaka switch time (nil = no fork, 0 = already on osaka)
|
||||
VerkleTime *uint64 `json:"verkleTime,omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle)
|
||||
|
||||
// TerminalTotalDifficulty is the amount of total difficulty reached by
|
||||
|
|
@ -450,6 +455,9 @@ func (c *ChainConfig) Description() string {
|
|||
if c.PragueTime != nil {
|
||||
banner += fmt.Sprintf(" - Prague: @%-10v\n", *c.PragueTime)
|
||||
}
|
||||
if c.OsakaTime != nil {
|
||||
banner += fmt.Sprintf(" - Osaka: @%-10v\n", *c.OsakaTime)
|
||||
}
|
||||
if c.VerkleTime != nil {
|
||||
banner += fmt.Sprintf(" - Verkle: @%-10v\n", *c.VerkleTime)
|
||||
}
|
||||
|
|
@ -551,6 +559,11 @@ func (c *ChainConfig) IsPrague(num *big.Int, time uint64) bool {
|
|||
return c.IsLondon(num) && isTimestampForked(c.PragueTime, time)
|
||||
}
|
||||
|
||||
// IsOsaka returns whether time is either equal to the Prague fork time or greater.
|
||||
func (c *ChainConfig) IsOsaka(num *big.Int, time uint64) bool {
|
||||
return c.IsLondon(num) && isTimestampForked(c.OsakaTime, time)
|
||||
}
|
||||
|
||||
// IsVerkle returns whether time is either equal to the Verkle fork time or greater.
|
||||
func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool {
|
||||
return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time)
|
||||
|
|
@ -615,6 +628,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
|
|||
{name: "shanghaiTime", timestamp: c.ShanghaiTime},
|
||||
{name: "cancunTime", timestamp: c.CancunTime, optional: true},
|
||||
{name: "pragueTime", timestamp: c.PragueTime, optional: true},
|
||||
{name: "osakaTime", timestamp: c.OsakaTime, optional: true},
|
||||
{name: "verkleTime", timestamp: c.VerkleTime, optional: true},
|
||||
} {
|
||||
if lastFork.name != "" {
|
||||
|
|
@ -719,6 +733,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int,
|
|||
if isForkTimestampIncompatible(c.PragueTime, newcfg.PragueTime, headTimestamp) {
|
||||
return newTimestampCompatError("Prague fork timestamp", c.PragueTime, newcfg.PragueTime)
|
||||
}
|
||||
if isForkTimestampIncompatible(c.OsakaTime, newcfg.OsakaTime, headTimestamp) {
|
||||
return newTimestampCompatError("Osaka fork timestamp", c.OsakaTime, newcfg.OsakaTime)
|
||||
}
|
||||
if isForkTimestampIncompatible(c.VerkleTime, newcfg.VerkleTime, headTimestamp) {
|
||||
return newTimestampCompatError("Verkle fork timestamp", c.VerkleTime, newcfg.VerkleTime)
|
||||
}
|
||||
|
|
@ -741,6 +758,8 @@ func (c *ChainConfig) LatestFork(time uint64) forks.Fork {
|
|||
london := c.LondonBlock
|
||||
|
||||
switch {
|
||||
case c.IsOsaka(london, time):
|
||||
return forks.Osaka
|
||||
case c.IsPrague(london, time):
|
||||
return forks.Prague
|
||||
case c.IsCancun(london, time):
|
||||
|
|
@ -892,7 +911,7 @@ type Rules struct {
|
|||
IsEIP2929, IsEIP4762 bool
|
||||
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
|
||||
IsBerlin, IsLondon bool
|
||||
IsMerge, IsShanghai, IsCancun, IsPrague bool
|
||||
IsMerge, IsShanghai, IsCancun, IsPrague, IsOsaka bool
|
||||
IsVerkle bool
|
||||
}
|
||||
|
||||
|
|
@ -922,6 +941,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules
|
|||
IsShanghai: isMerge && c.IsShanghai(num, timestamp),
|
||||
IsCancun: isMerge && c.IsCancun(num, timestamp),
|
||||
IsPrague: isMerge && c.IsPrague(num, timestamp),
|
||||
IsOsaka: isMerge && c.IsOsaka(num, timestamp),
|
||||
IsVerkle: isVerkle,
|
||||
IsEIP4762: isVerkle,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,4 +39,5 @@ const (
|
|||
Shanghai
|
||||
Cancun
|
||||
Prague
|
||||
Osaka
|
||||
)
|
||||
|
|
|
|||
|
|
@ -396,6 +396,50 @@ var Forks = map[string]*params.ChainConfig{
|
|||
PragueTime: u64(15_000),
|
||||
DepositContractAddress: params.MainnetChainConfig.DepositContractAddress,
|
||||
},
|
||||
"Osaka": {
|
||||
ChainID: big.NewInt(1),
|
||||
HomesteadBlock: big.NewInt(0),
|
||||
EIP150Block: big.NewInt(0),
|
||||
EIP155Block: big.NewInt(0),
|
||||
EIP158Block: big.NewInt(0),
|
||||
ByzantiumBlock: big.NewInt(0),
|
||||
ConstantinopleBlock: big.NewInt(0),
|
||||
PetersburgBlock: big.NewInt(0),
|
||||
IstanbulBlock: big.NewInt(0),
|
||||
MuirGlacierBlock: big.NewInt(0),
|
||||
BerlinBlock: big.NewInt(0),
|
||||
LondonBlock: big.NewInt(0),
|
||||
ArrowGlacierBlock: big.NewInt(0),
|
||||
MergeNetsplitBlock: big.NewInt(0),
|
||||
TerminalTotalDifficulty: big.NewInt(0),
|
||||
ShanghaiTime: u64(0),
|
||||
CancunTime: u64(0),
|
||||
PragueTime: u64(0),
|
||||
OsakaTime: u64(0),
|
||||
DepositContractAddress: params.MainnetChainConfig.DepositContractAddress,
|
||||
},
|
||||
"PragueToOsakaAtTime15k": {
|
||||
ChainID: big.NewInt(1),
|
||||
HomesteadBlock: big.NewInt(0),
|
||||
EIP150Block: big.NewInt(0),
|
||||
EIP155Block: big.NewInt(0),
|
||||
EIP158Block: big.NewInt(0),
|
||||
ByzantiumBlock: big.NewInt(0),
|
||||
ConstantinopleBlock: big.NewInt(0),
|
||||
PetersburgBlock: big.NewInt(0),
|
||||
IstanbulBlock: big.NewInt(0),
|
||||
MuirGlacierBlock: big.NewInt(0),
|
||||
BerlinBlock: big.NewInt(0),
|
||||
LondonBlock: big.NewInt(0),
|
||||
ArrowGlacierBlock: big.NewInt(0),
|
||||
MergeNetsplitBlock: big.NewInt(0),
|
||||
TerminalTotalDifficulty: big.NewInt(0),
|
||||
ShanghaiTime: u64(0),
|
||||
CancunTime: u64(0),
|
||||
PragueTime: u64(0),
|
||||
OsakaTime: u64(15_000),
|
||||
DepositContractAddress: params.MainnetChainConfig.DepositContractAddress,
|
||||
},
|
||||
}
|
||||
|
||||
// AvailableForks returns the set of defined fork names
|
||||
|
|
|
|||
Loading…
Reference in a new issue