Problem: no proper error for unsupported opcode

This commit is contained in:
mmsqe 2024-03-28 21:52:13 +08:00
parent 0183c7ad82
commit 9b7188f259
No known key found for this signature in database
GPG key ID: 1A484011063C7678
3 changed files with 30 additions and 18 deletions

View file

@ -37,6 +37,7 @@ var (
ErrGasUintOverflow = errors.New("gas uint64 overflow") ErrGasUintOverflow = errors.New("gas uint64 overflow")
ErrInvalidCode = errors.New("invalid code: must not begin with 0xef") ErrInvalidCode = errors.New("invalid code: must not begin with 0xef")
ErrNonceUintOverflow = errors.New("nonce uint64 overflow") ErrNonceUintOverflow = errors.New("nonce uint64 overflow")
ErrUnsupportedRandom = errors.New("unsupported random")
// errStopToken is an internal token indicating interpreter loop termination, // errStopToken is an internal token indicating interpreter loop termination,
// never returned to outside callers. // never returned to outside callers.

View file

@ -476,6 +476,9 @@ func opDifficulty(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
} }
func opRandom(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { func opRandom(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
if interpreter.evm.Context.Random == nil {
return nil, ErrUnsupportedRandom
}
v := new(uint256.Int).SetBytes(interpreter.evm.Context.Random.Bytes()) v := new(uint256.Int).SetBytes(interpreter.evm.Context.Random.Bytes())
scope.Stack.push(v) scope.Stack.push(v)
return nil, nil return nil, nil

View file

@ -719,32 +719,40 @@ func TestCreate2Addreses(t *testing.T) {
func TestRandom(t *testing.T) { func TestRandom(t *testing.T) {
type testcase struct { type testcase struct {
name string name string
random common.Hash random *common.Hash
err error
} }
keccak256Hash := crypto.Keccak256Hash([]byte{0x01, 0x02, 0x03})
for _, tt := range []testcase{ for _, tt := range []testcase{
{name: "empty hash", random: common.Hash{}}, {name: "nil random", random: nil, err: ErrUnsupportedRandom},
{name: "1", random: common.Hash{0}}, {name: "empty hash", random: &common.Hash{}},
{name: "emptyCodeHash", random: types.EmptyCodeHash}, {name: "1", random: &common.Hash{0}},
{name: "hash(0x010203)", random: crypto.Keccak256Hash([]byte{0x01, 0x02, 0x03})}, {name: "emptyCodeHash", random: &types.EmptyCodeHash},
{name: "hash(0x010203)", random: &keccak256Hash},
} { } {
var ( var (
env = NewEVM(BlockContext{Random: &tt.random}, TxContext{}, nil, params.TestChainConfig, Config{}) env = NewEVM(BlockContext{Random: tt.random}, TxContext{}, nil, params.TestChainConfig, Config{})
stack = newstack() stack = newstack()
pc = uint64(0) pc = uint64(0)
evmInterpreter = env.interpreter evmInterpreter = env.interpreter
) )
opRandom(&pc, evmInterpreter, &ScopeContext{nil, stack, nil}) _, err := opRandom(&pc, evmInterpreter, &ScopeContext{nil, stack, nil})
if len(stack.data) != 1 { if tt.err != nil {
t.Errorf("Expected one item on stack after %v, got %d: ", tt.name, len(stack.data)) if err != tt.err {
} t.Errorf("Testcase %v: expected %v, got %v", tt.name, tt.err, err)
actual := stack.pop() }
expected, overflow := uint256.FromBig(new(big.Int).SetBytes(tt.random.Bytes())) } else {
if overflow { if len(stack.data) != 1 {
t.Errorf("Testcase %v: invalid overflow", tt.name) t.Errorf("Expected one item on stack after %v, got %d: ", tt.name, len(stack.data))
} }
if actual.Cmp(expected) != 0 { actual := stack.pop()
t.Errorf("Testcase %v: expected %x, got %x", tt.name, expected, actual) expected, overflow := uint256.FromBig(new(big.Int).SetBytes(tt.random.Bytes()))
if overflow {
t.Errorf("Testcase %v: invalid overflow", tt.name)
}
if actual.Cmp(expected) != 0 {
t.Errorf("Testcase %v: expected %x, got %x", tt.name, expected, actual)
}
} }
} }
} }