core/vm: EIP-2315, JUMPSUB for the EVM (#20619)
* core/vm: implement EIP 2315, subroutines for the EVM * core/vm: eip 2315 - lintfix + check jump dest validity + check ret stack size constraints logger: markdown-friendly traces, validate jumpdest, more testcase, correct opcodes * core/vm: update subroutines acc to eip: disallow walk-into * core/vm/eips: gas cost changes for subroutines * core/vm: update opcodes for EIP-2315 * core/vm: define RETURNSUB as a 'jumping' operation + review concerns Co-authored-by: Martin Holst Swende <martin@swende.se>
This commit is contained in:
@ -664,6 +664,39 @@ func opJumpdest(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) (
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opBeginSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
return nil, ErrInvalidSubroutineEntry
|
||||
}
|
||||
|
||||
func opJumpSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
if len(callContext.rstack.data) >= 1023 {
|
||||
return nil, ErrReturnStackExceeded
|
||||
}
|
||||
pos := callContext.stack.pop()
|
||||
if !pos.IsUint64() {
|
||||
return nil, ErrInvalidJump
|
||||
}
|
||||
posU64 := pos.Uint64()
|
||||
if !callContext.contract.validJumpSubdest(posU64) {
|
||||
return nil, ErrInvalidJump
|
||||
}
|
||||
callContext.rstack.push(*pc)
|
||||
*pc = posU64 + 1
|
||||
interpreter.intPool.put(pos)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opReturnSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
if len(callContext.rstack.data) == 0 {
|
||||
return nil, ErrInvalidRetsub
|
||||
}
|
||||
// Other than the check that the return stack is not empty, there is no
|
||||
// need to validate the pc from 'returns', since we only ever push valid
|
||||
//values onto it via jumpsub.
|
||||
*pc = callContext.rstack.pop() + 1
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opPc(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.push(interpreter.intPool.get().SetUint64(*pc))
|
||||
return nil, nil
|
||||
|
Reference in New Issue
Block a user