Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 2 additions & 28 deletions core/vm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,34 +103,8 @@ type EVMInterpreter struct {

// NewEVMInterpreter returns a new instance of the Interpreter.
func NewEVMInterpreter(evm *EVM) *EVMInterpreter {
// If jump table was not initialised we set the default one.
var table *JumpTable
switch {
case evm.chainRules.IsCancun:
table = &cancunInstructionSet
case evm.chainRules.IsShanghai:
table = &shanghaiInstructionSet
case evm.chainRules.IsMerge:
table = &mergeInstructionSet
case evm.chainRules.IsLondon:
table = &londonInstructionSet
case evm.chainRules.IsBerlin:
table = &berlinInstructionSet
case evm.chainRules.IsIstanbul:
table = &istanbulInstructionSet
case evm.chainRules.IsConstantinople:
table = &constantinopleInstructionSet
case evm.chainRules.IsByzantium:
table = &byzantiumInstructionSet
case evm.chainRules.IsEIP158:
table = &spuriousDragonInstructionSet
case evm.chainRules.IsEIP150:
table = &tangerineWhistleInstructionSet
case evm.chainRules.IsHomestead:
table = &homesteadInstructionSet
default:
table = &frontierInstructionSet
}
instructionSet := newInstructionSet(evm.chainRules)
table := &instructionSet

var extraEips []int
if len(evm.Config.ExtraEips) > 0 {
Expand Down
59 changes: 58 additions & 1 deletion core/vm/jump_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,63 @@ func validate(jt JumpTable) JumpTable {
return jt
}

// newInstructionSet returns the instruction set for the given rules, applying any necessary modifications.
// This function centralizes the instruction set selection and Satoshi-specific modifications.
func newInstructionSet(rules params.Rules) JumpTable {
var instructionSet *JumpTable

switch {
case rules.IsCancun:
instructionSet = &cancunInstructionSet
case rules.IsShanghai:
instructionSet = &shanghaiInstructionSet
case rules.IsMerge:
instructionSet = &mergeInstructionSet
case rules.IsLondon:
instructionSet = &londonInstructionSet
case rules.IsBerlin:
instructionSet = &berlinInstructionSet
case rules.IsIstanbul:
instructionSet = &istanbulInstructionSet
case rules.IsConstantinople:
instructionSet = &constantinopleInstructionSet
case rules.IsByzantium:
instructionSet = &byzantiumInstructionSet
case rules.IsEIP158:
instructionSet = &spuriousDragonInstructionSet
case rules.IsEIP150:
instructionSet = &tangerineWhistleInstructionSet
case rules.IsHomestead:
instructionSet = &homesteadInstructionSet
default:
instructionSet = &frontierInstructionSet
}

// Apply Satoshi-specific modifications
// We need to copy the jump table to avoid modifying the global instruction sets
if rules.IsSatoshi {
copied := copyJumpTable(instructionSet)
return newSatoshiRevertDifficultyInstructionSet(*copied)
}

return *instructionSet
}

// Satoshi related instructions

// newSatoshiRevertDifficultyInstructionSet reverts the PREVRANDAO opcode to DIFFICULTY opcode,
// as Satoshi doesn't implement the PREVRANDAO opcode.
func newSatoshiRevertDifficultyInstructionSet(instructionSet JumpTable) JumpTable {
instructionSet[DIFFICULTY] = &operation{
execute: opDifficulty,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
}
return validate(instructionSet)
}

// Ethereum instructions
func newCancunInstructionSet() JumpTable {
instructionSet := newShanghaiInstructionSet()
enable4844(&instructionSet) // EIP-4844 (BLOBHASH opcode)
Expand All @@ -91,7 +148,7 @@ func newCancunInstructionSet() JumpTable {
}

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

Expand Down
37 changes: 9 additions & 28 deletions core/vm/jump_table_export.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,19 @@ import (
"github.com/ethereum/go-ethereum/params"
)

// LookupInstructionSet returns the instruction set for the fork configured by
// the rules.
func LookupInstructionSet(rules params.Rules) (JumpTable, error) {
// LookupInstructionSet returns the instruction set for the fork configured by the rules.
func LookupInstructionSet(rules params.Rules) (table JumpTable, err error) {
table = newInstructionSet(rules)

// Set error for unsupported forks
switch {
case rules.IsVerkle:
return newCancunInstructionSet(), errors.New("verkle-fork not defined yet")
err = errors.New("verkle-fork not defined yet")
case rules.IsPrague:
return newCancunInstructionSet(), errors.New("prague-fork not defined yet")
case rules.IsCancun:
return newCancunInstructionSet(), nil
case rules.IsShanghai:
return newShanghaiInstructionSet(), nil
case rules.IsMerge:
return newMergeInstructionSet(), nil
case rules.IsLondon:
return newLondonInstructionSet(), nil
case rules.IsBerlin:
return newBerlinInstructionSet(), nil
case rules.IsIstanbul:
return newIstanbulInstructionSet(), nil
case rules.IsConstantinople:
return newConstantinopleInstructionSet(), nil
case rules.IsByzantium:
return newByzantiumInstructionSet(), nil
case rules.IsEIP158:
return newSpuriousDragonInstructionSet(), nil
case rules.IsEIP150:
return newTangerineWhistleInstructionSet(), nil
case rules.IsHomestead:
return newHomesteadInstructionSet(), nil
err = errors.New("prague-fork not defined yet")
}
return newFrontierInstructionSet(), nil

return table, err
}

// Stack returns the minimum and maximum stack requirements.
Expand Down
7 changes: 7 additions & 0 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,11 @@ func (c *ChainConfig) String() string {
)
}

// IsSatoshi returns whether the chain is a Satoshi chain.
func (c *ChainConfig) IsSatoshi() bool {
return c.Satoshi != nil
}

// IsHomestead returns whether num is either equal to the homestead block or greater.
func (c *ChainConfig) IsHomestead(num *big.Int) bool {
return isBlockForked(c.HomesteadBlock, num)
Expand Down Expand Up @@ -1200,6 +1205,7 @@ func (err *ConfigCompatError) Error() string {
// phases.
type Rules struct {
ChainID *big.Int
IsSatoshi bool
IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
IsBerlin, IsLondon bool
Expand All @@ -1219,6 +1225,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules
isMerge = isMerge && c.IsLondon(num)
return Rules{
ChainID: new(big.Int).Set(chainID),
IsSatoshi: c.IsSatoshi(),
IsHomestead: c.IsHomestead(num),
IsEIP150: c.IsEIP150(num),
IsEIP155: c.IsEIP155(num),
Expand Down
Loading