Merge pull request #19993 from karalabe/istanbul-eip-integration

core/vm: enable istanbul EIPs in the jump table
This commit is contained in:
Péter Szilágyi 2019-08-23 11:55:43 +03:00 committed by GitHub
commit c8a1c0a115
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 6 deletions

View File

@ -132,6 +132,7 @@ type CParamsParams struct {
ByzantiumForkBlock *math.HexOrDecimal64 `json:"byzantiumForkBlock"` ByzantiumForkBlock *math.HexOrDecimal64 `json:"byzantiumForkBlock"`
ConstantinopleForkBlock *math.HexOrDecimal64 `json:"constantinopleForkBlock"` ConstantinopleForkBlock *math.HexOrDecimal64 `json:"constantinopleForkBlock"`
ConstantinopleFixForkBlock *math.HexOrDecimal64 `json:"constantinopleFixForkBlock"` ConstantinopleFixForkBlock *math.HexOrDecimal64 `json:"constantinopleFixForkBlock"`
IstanbulBlock *math.HexOrDecimal64 `json:"istanbulForkBlock"`
ChainID *math.HexOrDecimal256 `json:"chainID"` ChainID *math.HexOrDecimal256 `json:"chainID"`
MaximumExtraDataSize math.HexOrDecimal64 `json:"maximumExtraDataSize"` MaximumExtraDataSize math.HexOrDecimal64 `json:"maximumExtraDataSize"`
TieBreakingGas bool `json:"tieBreakingGas"` TieBreakingGas bool `json:"tieBreakingGas"`
@ -319,6 +320,7 @@ func (api *RetestethAPI) SetChainParams(ctx context.Context, chainParams ChainPa
byzantiumBlock *big.Int byzantiumBlock *big.Int
constantinopleBlock *big.Int constantinopleBlock *big.Int
petersburgBlock *big.Int petersburgBlock *big.Int
istanbulBlock *big.Int
) )
if chainParams.Params.HomesteadForkBlock != nil { if chainParams.Params.HomesteadForkBlock != nil {
homesteadBlock = big.NewInt(int64(*chainParams.Params.HomesteadForkBlock)) homesteadBlock = big.NewInt(int64(*chainParams.Params.HomesteadForkBlock))
@ -345,6 +347,10 @@ func (api *RetestethAPI) SetChainParams(ctx context.Context, chainParams ChainPa
if constantinopleBlock != nil && petersburgBlock == nil { if constantinopleBlock != nil && petersburgBlock == nil {
petersburgBlock = big.NewInt(100000000000) petersburgBlock = big.NewInt(100000000000)
} }
if chainParams.Params.IstanbulBlock != nil {
istanbulBlock = big.NewInt(int64(*chainParams.Params.IstanbulBlock))
}
genesis := &core.Genesis{ genesis := &core.Genesis{
Config: &params.ChainConfig{ Config: &params.ChainConfig{
ChainID: chainId, ChainID: chainId,
@ -357,6 +363,7 @@ func (api *RetestethAPI) SetChainParams(ctx context.Context, chainParams ChainPa
ByzantiumBlock: byzantiumBlock, ByzantiumBlock: byzantiumBlock,
ConstantinopleBlock: constantinopleBlock, ConstantinopleBlock: constantinopleBlock,
PetersburgBlock: petersburgBlock, PetersburgBlock: petersburgBlock,
IstanbulBlock: istanbulBlock,
}, },
Nonce: uint64(chainParams.Genesis.Nonce), Nonce: uint64(chainParams.Genesis.Nonce),
Timestamp: uint64(chainParams.Genesis.Timestamp), Timestamp: uint64(chainParams.Genesis.Timestamp),

View File

@ -93,6 +93,8 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
if !cfg.JumpTable[STOP].valid { if !cfg.JumpTable[STOP].valid {
var jt JumpTable var jt JumpTable
switch { switch {
case evm.chainRules.IsIstanbul:
jt = istanbulInstructionSet
case evm.chainRules.IsConstantinople: case evm.chainRules.IsConstantinople:
jt = constantinopleInstructionSet jt = constantinopleInstructionSet
case evm.chainRules.IsByzantium: case evm.chainRules.IsByzantium:

View File

@ -60,15 +60,27 @@ var (
spuriousDragonInstructionSet = newSpuriousDragonInstructionSet() spuriousDragonInstructionSet = newSpuriousDragonInstructionSet()
byzantiumInstructionSet = newByzantiumInstructionSet() byzantiumInstructionSet = newByzantiumInstructionSet()
constantinopleInstructionSet = newConstantinopleInstructionSet() constantinopleInstructionSet = newConstantinopleInstructionSet()
istanbulInstructionSet = newIstanbulInstructionSet()
) )
// JumpTable contains the EVM opcodes supported at a given fork. // JumpTable contains the EVM opcodes supported at a given fork.
type JumpTable [256]operation type JumpTable [256]operation
// NewConstantinopleInstructionSet returns the frontier, homestead // newIstanbulInstructionSet returns the frontier, homestead
// byzantium, contantinople and petersburg instructions.
func newIstanbulInstructionSet() JumpTable {
instructionSet := newConstantinopleInstructionSet()
enable1344(&instructionSet) // ChainID opcode - https://eips.ethereum.org/EIPS/eip-1344
enable1884(&instructionSet) // Reprice reader opcodes - https://eips.ethereum.org/EIPS/eip-1884
enable2200(&instructionSet) // Net metered SSTORE - https://eips.ethereum.org/EIPS/eip-2200
return instructionSet
}
// newConstantinopleInstructionSet returns the frontier, homestead
// byzantium and contantinople instructions. // byzantium and contantinople instructions.
func newConstantinopleInstructionSet() JumpTable { func newConstantinopleInstructionSet() JumpTable {
// instructions that can be executed during the byzantium phase.
instructionSet := newByzantiumInstructionSet() instructionSet := newByzantiumInstructionSet()
instructionSet[SHL] = operation{ instructionSet[SHL] = operation{
execute: opSHL, execute: opSHL,
@ -112,10 +124,9 @@ func newConstantinopleInstructionSet() JumpTable {
return instructionSet return instructionSet
} }
// NewByzantiumInstructionSet returns the frontier, homestead and // newByzantiumInstructionSet returns the frontier, homestead and
// byzantium instructions. // byzantium instructions.
func newByzantiumInstructionSet() JumpTable { func newByzantiumInstructionSet() JumpTable {
// instructions that can be executed during the homestead phase.
instructionSet := newSpuriousDragonInstructionSet() instructionSet := newSpuriousDragonInstructionSet()
instructionSet[STATICCALL] = operation{ instructionSet[STATICCALL] = operation{
execute: opStaticCall, execute: opStaticCall,
@ -177,7 +188,7 @@ func newTangerineWhistleInstructionSet() JumpTable {
return instructionSet return instructionSet
} }
// NewHomesteadInstructionSet returns the frontier and homestead // newHomesteadInstructionSet returns the frontier and homestead
// instructions that can be executed during the homestead phase. // instructions that can be executed during the homestead phase.
func newHomesteadInstructionSet() JumpTable { func newHomesteadInstructionSet() JumpTable {
instructionSet := newFrontierInstructionSet() instructionSet := newFrontierInstructionSet()
@ -194,7 +205,7 @@ func newHomesteadInstructionSet() JumpTable {
return instructionSet return instructionSet
} }
// NewFrontierInstructionSet returns the frontier instructions // newFrontierInstructionSet returns the frontier instructions
// that can be executed during the frontier phase. // that can be executed during the frontier phase.
func newFrontierInstructionSet() JumpTable { func newFrontierInstructionSet() JumpTable {
return JumpTable{ return JumpTable{

View File

@ -75,6 +75,18 @@ var Forks = map[string]*params.ChainConfig{
ConstantinopleBlock: big.NewInt(0), ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0),
}, },
"Istanbul": {
ChainID: big.NewInt(1),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
DAOForkBlock: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
},
"FrontierToHomesteadAt5": { "FrontierToHomesteadAt5": {
ChainID: big.NewInt(1), ChainID: big.NewInt(1),
HomesteadBlock: big.NewInt(5), HomesteadBlock: big.NewInt(5),
@ -117,6 +129,17 @@ var Forks = map[string]*params.ChainConfig{
ConstantinopleBlock: big.NewInt(5), ConstantinopleBlock: big.NewInt(5),
PetersburgBlock: big.NewInt(5), PetersburgBlock: big.NewInt(5),
}, },
"ConstantinopleFixToIstanbulAt5": {
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(5),
},
} }
// UnsupportedForkError is returned when a test requests a fork that isn't implemented. // UnsupportedForkError is returned when a test requests a fork that isn't implemented.