core/vm, params: implement EXTCODEHASH opcode (#17202)
* core/vm, params: implement EXTCODEHASH opcode * core, params: tiny fixes and polish * core: add function description
This commit is contained in:
parent
cab1cff11c
commit
2433349c80
@ -241,6 +241,10 @@ func gasExtCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Sta
|
|||||||
return gas, nil
|
return gas, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func gasExtCodeHash(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
|
return gt.ExtcodeHash, nil
|
||||||
|
}
|
||||||
|
|
||||||
func gasMLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
func gasMLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
var overflow bool
|
var overflow bool
|
||||||
gas, err := memoryGasCost(mem, memorySize)
|
gas, err := memoryGasCost(mem, memorySize)
|
||||||
|
@ -496,6 +496,38 @@ func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, sta
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// opExtCodeHash returns the code hash of a specified account.
|
||||||
|
// There are several cases when the function is called, while we can relay everything
|
||||||
|
// to `state.GetCodeHash` function to ensure the correctness.
|
||||||
|
// (1) Caller tries to get the code hash of a normal contract account, state
|
||||||
|
// should return the relative code hash and set it as the result.
|
||||||
|
//
|
||||||
|
// (2) Caller tries to get the code hash of a non-existent account, state should
|
||||||
|
// return common.Hash{} and zero will be set as the result.
|
||||||
|
//
|
||||||
|
// (3) Caller tries to get the code hash for an account without contract code,
|
||||||
|
// state should return emptyCodeHash(0xc5d246...) as the result.
|
||||||
|
//
|
||||||
|
// (4) Caller tries to get the code hash of a precompiled account, the result
|
||||||
|
// should be zero or emptyCodeHash.
|
||||||
|
//
|
||||||
|
// It is worth noting that in order to avoid unnecessary create and clean,
|
||||||
|
// all precompile accounts on mainnet have been transferred 1 wei, so the return
|
||||||
|
// here should be emptyCodeHash.
|
||||||
|
// If the precompile account is not transferred any amount on a private or
|
||||||
|
// customized chain, the return value will be zero.
|
||||||
|
//
|
||||||
|
// (5) Caller tries to get the code hash for an account which is marked as suicided
|
||||||
|
// in the current transaction, the code hash of this account should be returned.
|
||||||
|
//
|
||||||
|
// (6) Caller tries to get the code hash for an account which is marked as deleted,
|
||||||
|
// this account should be regarded as a non-existent account and zero should be returned.
|
||||||
|
func opExtCodeHash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
|
slot := stack.peek()
|
||||||
|
slot.SetBytes(evm.StateDB.GetCodeHash(common.BigToAddress(slot)).Bytes())
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice))
|
stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -80,6 +80,12 @@ func newConstantinopleInstructionSet() [256]operation {
|
|||||||
validateStack: makeStackFunc(2, 1),
|
validateStack: makeStackFunc(2, 1),
|
||||||
valid: true,
|
valid: true,
|
||||||
}
|
}
|
||||||
|
instructionSet[EXTCODEHASH] = operation{
|
||||||
|
execute: opExtCodeHash,
|
||||||
|
gasCost: gasExtCodeHash,
|
||||||
|
validateStack: makeStackFunc(1, 1),
|
||||||
|
valid: true,
|
||||||
|
}
|
||||||
instructionSet[CREATE2] = operation{
|
instructionSet[CREATE2] = operation{
|
||||||
execute: opCreate2,
|
execute: opCreate2,
|
||||||
gasCost: gasCreate2,
|
gasCost: gasCreate2,
|
||||||
|
@ -90,6 +90,7 @@ const (
|
|||||||
EXTCODECOPY
|
EXTCODECOPY
|
||||||
RETURNDATASIZE
|
RETURNDATASIZE
|
||||||
RETURNDATACOPY
|
RETURNDATACOPY
|
||||||
|
EXTCODEHASH
|
||||||
)
|
)
|
||||||
|
|
||||||
// 0x40 range - block operations.
|
// 0x40 range - block operations.
|
||||||
@ -267,6 +268,7 @@ var opCodeToString = map[OpCode]string{
|
|||||||
EXTCODECOPY: "EXTCODECOPY",
|
EXTCODECOPY: "EXTCODECOPY",
|
||||||
RETURNDATASIZE: "RETURNDATASIZE",
|
RETURNDATASIZE: "RETURNDATASIZE",
|
||||||
RETURNDATACOPY: "RETURNDATACOPY",
|
RETURNDATACOPY: "RETURNDATACOPY",
|
||||||
|
EXTCODEHASH: "EXTCODEHASH",
|
||||||
|
|
||||||
// 0x40 range - block operations.
|
// 0x40 range - block operations.
|
||||||
BLOCKHASH: "BLOCKHASH",
|
BLOCKHASH: "BLOCKHASH",
|
||||||
@ -435,6 +437,7 @@ var stringToOp = map[string]OpCode{
|
|||||||
"EXTCODECOPY": EXTCODECOPY,
|
"EXTCODECOPY": EXTCODECOPY,
|
||||||
"RETURNDATASIZE": RETURNDATASIZE,
|
"RETURNDATASIZE": RETURNDATASIZE,
|
||||||
"RETURNDATACOPY": RETURNDATACOPY,
|
"RETURNDATACOPY": RETURNDATACOPY,
|
||||||
|
"EXTCODEHASH": EXTCODEHASH,
|
||||||
"BLOCKHASH": BLOCKHASH,
|
"BLOCKHASH": BLOCKHASH,
|
||||||
"COINBASE": COINBASE,
|
"COINBASE": COINBASE,
|
||||||
"TIMESTAMP": TIMESTAMP,
|
"TIMESTAMP": TIMESTAMP,
|
||||||
|
@ -211,6 +211,8 @@ func (c *ChainConfig) GasTable(num *big.Int) GasTable {
|
|||||||
return GasTableHomestead
|
return GasTableHomestead
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
|
case c.IsConstantinople(num):
|
||||||
|
return GasTableConstantinople
|
||||||
case c.IsEIP158(num):
|
case c.IsEIP158(num):
|
||||||
return GasTableEIP158
|
return GasTableEIP158
|
||||||
case c.IsEIP150(num):
|
case c.IsEIP150(num):
|
||||||
|
@ -20,6 +20,7 @@ package params
|
|||||||
type GasTable struct {
|
type GasTable struct {
|
||||||
ExtcodeSize uint64
|
ExtcodeSize uint64
|
||||||
ExtcodeCopy uint64
|
ExtcodeCopy uint64
|
||||||
|
ExtcodeHash uint64
|
||||||
Balance uint64
|
Balance uint64
|
||||||
SLoad uint64
|
SLoad uint64
|
||||||
Calls uint64
|
Calls uint64
|
||||||
@ -63,7 +64,7 @@ var (
|
|||||||
CreateBySuicide: 25000,
|
CreateBySuicide: 25000,
|
||||||
}
|
}
|
||||||
// GasTableEIP158 contain the gas re-prices for
|
// GasTableEIP158 contain the gas re-prices for
|
||||||
// the EIP15* phase.
|
// the EIP155/EIP158 phase.
|
||||||
GasTableEIP158 = GasTable{
|
GasTableEIP158 = GasTable{
|
||||||
ExtcodeSize: 700,
|
ExtcodeSize: 700,
|
||||||
ExtcodeCopy: 700,
|
ExtcodeCopy: 700,
|
||||||
@ -73,6 +74,20 @@ var (
|
|||||||
Suicide: 5000,
|
Suicide: 5000,
|
||||||
ExpByte: 50,
|
ExpByte: 50,
|
||||||
|
|
||||||
|
CreateBySuicide: 25000,
|
||||||
|
}
|
||||||
|
// GasTableConstantinople contain the gas re-prices for
|
||||||
|
// the constantinople phase.
|
||||||
|
GasTableConstantinople = GasTable{
|
||||||
|
ExtcodeSize: 700,
|
||||||
|
ExtcodeCopy: 700,
|
||||||
|
ExtcodeHash: 400,
|
||||||
|
Balance: 400,
|
||||||
|
SLoad: 200,
|
||||||
|
Calls: 700,
|
||||||
|
Suicide: 5000,
|
||||||
|
ExpByte: 50,
|
||||||
|
|
||||||
CreateBySuicide: 25000,
|
CreateBySuicide: 25000,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user