Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement EIP-3198 and opcode BASEFEE #458

Merged
merged 1 commit into from
Mar 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ var TIPXDCX = big.NewInt(38383838)
var TIPXDCXLending = big.NewInt(38383838)
var TIPXDCXCancellationFee = big.NewInt(38383838)
var TIPXDCXCancellationFeeTestnet = big.NewInt(38383838)
var BerlinBlock = big.NewInt(9999999999)
var LondonBlock = big.NewInt(9999999999)

var TIPXDCXTestnet = big.NewInt(38383838)
var IsTestnet bool = false
Expand Down
2 changes: 2 additions & 0 deletions common/constants/constants.go.devnet
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ var TIPXDCX = big.NewInt(225000)
var TIPXDCXLending = big.NewInt(225000)
var TIPXDCXCancellationFee = big.NewInt(225000)
var TIPXDCXCancellationFeeTestnet = big.NewInt(225000)
var BerlinBlock = big.NewInt(9999999999)
var LondonBlock = big.NewInt(9999999999)

var TIPXDCXTestnet = big.NewInt(0)
var IsTestnet bool = false
Expand Down
2 changes: 2 additions & 0 deletions common/constants/constants.go.testnet
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ var TIPXDCX = big.NewInt(23779191)
var TIPXDCXLending = big.NewInt(23779191)
var TIPXDCXCancellationFee = big.NewInt(23779191)
var TIPXDCXCancellationFeeTestnet = big.NewInt(23779191)
var BerlinBlock = big.NewInt(9999999999)
var LondonBlock = big.NewInt(9999999999)

var TIPXDCXTestnet = big.NewInt(23779191)
var IsTestnet bool = false
Expand Down
22 changes: 22 additions & 0 deletions core/vm/eips.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package vm
import (
"fmt"

"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/params"
"github.com/holiman/uint256"
)
Expand All @@ -28,6 +29,8 @@ import (
// defined jump tables are not polluted.
func EnableEIP(eipNum int, jt *JumpTable) error {
switch eipNum {
case 3898:
enable3198(jt)
case 2200:
enable2200(jt)
case 1884:
Expand Down Expand Up @@ -90,3 +93,22 @@ func enable2200(jt *JumpTable) {
jt[SLOAD].constantGas = params.SloadGasEIP2200
jt[SSTORE].dynamicGas = gasSStoreEIP2200
}

// enable3198 applies EIP-3198 (BASEFEE Opcode)
// - Adds an opcode that returns the current block's base fee.
func enable3198(jt *JumpTable) {
// New opcode
jt[BASEFEE] = &operation{
execute: opBaseFee,
constantGas: GasQuickStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
}
}

// opBaseFee implements BASEFEE opcode
func opBaseFee(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
baseFee, _ := uint256.FromBig(common.MinGasPrice50x)
callContext.stack.push(baseFee)
return nil, nil
}
12 changes: 7 additions & 5 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ type (
// run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter.
func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, error) {
if contract.CodeAddr != nil {
precompiles := PrecompiledContractsHomestead
if evm.chainRules.IsByzantium {
precompiles = PrecompiledContractsByzantium
}
if evm.chainRules.IsIstanbul {
var precompiles map[common.Address]PrecompiledContract
switch {
case evm.chainRules.IsIstanbul:
precompiles = PrecompiledContractsIstanbul
case evm.chainRules.IsByzantium:
precompiles = PrecompiledContractsByzantium
default:
precompiles = PrecompiledContractsHomestead
}
if p := precompiles[*contract.CodeAddr]; p != nil {
switch p.(type) {
Expand Down
4 changes: 4 additions & 0 deletions core/vm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
// If jump table was not initialised we set the default one.
if cfg.JumpTable == nil {
switch {
case evm.chainRules.IsLondon:
cfg.JumpTable = &londonInstructionSet
case evm.chainRules.IsBerlin:
cfg.JumpTable = &berlinInstructionSet
case evm.chainRules.IsIstanbul:
cfg.JumpTable = &istanbulInstructionSet
case evm.chainRules.IsConstantinople:
Expand Down
19 changes: 19 additions & 0 deletions core/vm/jump_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,30 @@ var (
byzantiumInstructionSet = newByzantiumInstructionSet()
constantinopleInstructionSet = newConstantinopleInstructionSet()
istanbulInstructionSet = newIstanbulInstructionSet()
berlinInstructionSet = newBerlinInstructionSet()
londonInstructionSet = newLondonInstructionSet()
)

// JumpTable contains the EVM opcodes supported at a given fork.
type JumpTable [256]*operation

// newLondonInstructionSet returns the frontier, homestead, byzantium,
// constantinople, istanbul, petersburg, berlin and london instructions.
func newLondonInstructionSet() JumpTable {
instructionSet := newBerlinInstructionSet()
// enable3529(&instructionSet) // EIP-3529: Reduction in refunds https://eips.ethereum.org/EIPS/eip-3529
enable3198(&instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198
return instructionSet
}

// newBerlinInstructionSet returns the frontier, homestead, byzantium,
// constantinople, istanbul, petersburg and berlin instructions.
func newBerlinInstructionSet() JumpTable {
instructionSet := newIstanbulInstructionSet()
// enable2929(&instructionSet) // Gas cost increases for state access opcodes https://eips.ethereum.org/EIPS/eip-2929
return instructionSet
}

// newIstanbulInstructionSet returns the frontier, homestead
// byzantium, contantinople and petersburg instructions.
func newIstanbulInstructionSet() JumpTable {
Expand Down
3 changes: 3 additions & 0 deletions core/vm/opcodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ const (
GASLIMIT OpCode = 0x45
CHAINID OpCode = 0x46
SELFBALANCE OpCode = 0x47
BASEFEE OpCode = 0x48
)

// 0x50 range - 'storage' and execution.
Expand Down Expand Up @@ -280,6 +281,7 @@ var opCodeToString = [256]string{
GASLIMIT: "GASLIMIT",
CHAINID: "CHAINID",
SELFBALANCE: "SELFBALANCE",
BASEFEE: "BASEFEE",

// 0x50 range - 'storage' and execution.
POP: "POP",
Expand Down Expand Up @@ -445,6 +447,7 @@ var stringToOp = map[string]OpCode{
"DIFFICULTY": DIFFICULTY,
"GASLIMIT": GASLIMIT,
"SELFBALANCE": SELFBALANCE,
"BASEFEE": BASEFEE,
"POP": POP,
"MLOAD": MLOAD,
"MSTORE": MSTORE,
Expand Down
26 changes: 25 additions & 1 deletion params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@ type ChainConfig struct {

ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium)
ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
BerlinBlock *big.Int `json:"berlinBlock,omitempty"` // Berlin switch block (nil = no fork, 0 = already on berlin)
LondonBlock *big.Int `json:"londonBlock,omitempty"` // London switch block (nil = no fork, 0 = already on london)

// Various consensus engines
Ethash *EthashConfig `json:"ethash,omitempty"`
Expand Down Expand Up @@ -498,7 +500,7 @@ func (c *ChainConfig) String() string {
default:
engine = "unknown"
}
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Engine: %v}",
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v BerlinBlock: %v LondonBlock: %v Engine: %v}",
c.ChainId,
c.HomesteadBlock,
c.DAOForkBlock,
Expand All @@ -508,6 +510,8 @@ func (c *ChainConfig) String() string {
c.EIP158Block,
c.ByzantiumBlock,
c.ConstantinopleBlock,
c.BerlinBlock,
c.LondonBlock,
engine,
)
}
Expand Down Expand Up @@ -554,6 +558,16 @@ func (c *ChainConfig) IsIstanbul(num *big.Int) bool {
return isForked(common.TIPXDCXCancellationFee, num)
}

// IsBerlin returns whether num is either equal to the Berlin fork block or greater.
func (c *ChainConfig) IsBerlin(num *big.Int) bool {
return isForked(common.BerlinBlock, num)
}

// IsLondon returns whether num is either equal to the London fork block or greater.
func (c *ChainConfig) IsLondon(num *big.Int) bool {
return isForked(common.LondonBlock, num)
}

func (c *ChainConfig) IsTIP2019(num *big.Int) bool {
return isForked(common.TIP2019Block, num)
}
Expand Down Expand Up @@ -655,6 +669,13 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi
if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) {
return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
}
if isForkIncompatible(c.BerlinBlock, newcfg.BerlinBlock, head) {
return newCompatError("Berlin fork block", c.BerlinBlock, newcfg.BerlinBlock)
}
if isForkIncompatible(c.LondonBlock, newcfg.LondonBlock, head) {
return newCompatError("London fork block", c.LondonBlock, newcfg.LondonBlock)
}

return nil
}

Expand Down Expand Up @@ -722,6 +743,7 @@ type Rules struct {
ChainId *big.Int
IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
IsBerlin, IsLondon bool
}

func (c *ChainConfig) Rules(num *big.Int) Rules {
Expand All @@ -739,5 +761,7 @@ func (c *ChainConfig) Rules(num *big.Int) Rules {
IsConstantinople: c.IsConstantinople(num),
IsPetersburg: c.IsPetersburg(num),
IsIstanbul: c.IsIstanbul(num),
IsBerlin: c.IsBerlin(num),
IsLondon: c.IsLondon(num),
}
}