mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core/vm: PAY opcode EIP-5920
This commit is contained in:
parent
ba2dd9385c
commit
4ed9a49e9d
4 changed files with 48 additions and 1 deletions
|
|
@ -37,6 +37,7 @@ var activators = map[int]func(*JumpTable){
|
||||||
1884: enable1884,
|
1884: enable1884,
|
||||||
1344: enable1344,
|
1344: enable1344,
|
||||||
1153: enable1153,
|
1153: enable1153,
|
||||||
|
5920: enable5920,
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableEIP enables the given EIP on the config.
|
// EnableEIP enables the given EIP on the config.
|
||||||
|
|
@ -55,6 +56,7 @@ func ValidEip(eipNum int) bool {
|
||||||
_, ok := activators[eipNum]
|
_, ok := activators[eipNum]
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func ActivateableEips() []string {
|
func ActivateableEips() []string {
|
||||||
var nums []string
|
var nums []string
|
||||||
for k := range activators {
|
for k := range activators {
|
||||||
|
|
@ -319,3 +321,27 @@ func enable6780(jt *JumpTable) {
|
||||||
maxStack: maxStack(1, 0),
|
maxStack: maxStack(1, 0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func enable5920(jt *JumpTable) {
|
||||||
|
jt[PAY] = &operation{
|
||||||
|
execute: opPay,
|
||||||
|
constantGas: params.WarmStorageReadCostEIP2929,
|
||||||
|
dynamicGas: gasPay,
|
||||||
|
minStack: minStack(2, 0),
|
||||||
|
maxStack: maxStack(2, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func opPay(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||||
|
if interpreter.readOnly {
|
||||||
|
return nil, ErrWriteProtection
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
addr = scope.Stack.pop()
|
||||||
|
amount = scope.Stack.pop()
|
||||||
|
)
|
||||||
|
if interpreter.evm.Context.CanTransfer(interpreter.evm.StateDB, scope.Contract.Address(), &amount) {
|
||||||
|
interpreter.evm.Context.Transfer(interpreter.evm.StateDB, scope.Contract.Address(), addr.Bytes20(), &amount)
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -477,3 +477,21 @@ func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me
|
||||||
}
|
}
|
||||||
return gas, nil
|
return gas, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func gasPay(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
|
var (
|
||||||
|
addr = stack.peek().Bytes20()
|
||||||
|
transfersValue = !stack.Back(1).IsZero()
|
||||||
|
)
|
||||||
|
gas, err := gasEip2929AccountCheck(evm, contract, stack, mem, memorySize)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if transfersValue {
|
||||||
|
gas += params.CallValueTransferGas
|
||||||
|
if evm.StateDB.Empty(addr) {
|
||||||
|
gas += params.CallNewAccountGas
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gas, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
|
||||||
return nil, ErrOutOfGas
|
return nil, ErrOutOfGas
|
||||||
}
|
}
|
||||||
if operation.dynamicGas != nil {
|
if operation.dynamicGas != nil {
|
||||||
// All ops with a dynamic memory usage also has a dynamic gas cost.
|
// All ops with a dynamic memory usage also have a dynamic gas cost.
|
||||||
var memorySize uint64
|
var memorySize uint64
|
||||||
// calculate the new memory size and expand the memory to fit
|
// calculate the new memory size and expand the memory to fit
|
||||||
// the operation
|
// the operation
|
||||||
|
|
|
||||||
|
|
@ -218,6 +218,7 @@ const (
|
||||||
DELEGATECALL OpCode = 0xf4
|
DELEGATECALL OpCode = 0xf4
|
||||||
CREATE2 OpCode = 0xf5
|
CREATE2 OpCode = 0xf5
|
||||||
|
|
||||||
|
PAY OpCode = 0xf9
|
||||||
STATICCALL OpCode = 0xfa
|
STATICCALL OpCode = 0xfa
|
||||||
REVERT OpCode = 0xfd
|
REVERT OpCode = 0xfd
|
||||||
INVALID OpCode = 0xfe
|
INVALID OpCode = 0xfe
|
||||||
|
|
@ -391,6 +392,7 @@ var opCodeToString = [256]string{
|
||||||
CALLCODE: "CALLCODE",
|
CALLCODE: "CALLCODE",
|
||||||
DELEGATECALL: "DELEGATECALL",
|
DELEGATECALL: "DELEGATECALL",
|
||||||
CREATE2: "CREATE2",
|
CREATE2: "CREATE2",
|
||||||
|
PAY: "PAY",
|
||||||
STATICCALL: "STATICCALL",
|
STATICCALL: "STATICCALL",
|
||||||
REVERT: "REVERT",
|
REVERT: "REVERT",
|
||||||
INVALID: "INVALID",
|
INVALID: "INVALID",
|
||||||
|
|
@ -554,6 +556,7 @@ var stringToOp = map[string]OpCode{
|
||||||
"REVERT": REVERT,
|
"REVERT": REVERT,
|
||||||
"INVALID": INVALID,
|
"INVALID": INVALID,
|
||||||
"SELFDESTRUCT": SELFDESTRUCT,
|
"SELFDESTRUCT": SELFDESTRUCT,
|
||||||
|
"PAY": PAY,
|
||||||
}
|
}
|
||||||
|
|
||||||
// StringToOp finds the opcode whose name is stored in `str`.
|
// StringToOp finds the opcode whose name is stored in `str`.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue