@@ -19,6 +19,7 @@ package vm
1919import (
2020 "bytes"
2121 "encoding/json"
22+ "errors"
2223 "fmt"
2324 "os"
2425 "testing"
@@ -763,10 +764,11 @@ func TestEIP8024_Execution(t *testing.T) {
763764 evm := NewCVM (BlockContext {}, nil , params .TestChainConfig , Config {})
764765
765766 tests := []struct {
766- name string
767- codeHex string
768- wantErr bool
769- wantVals []uint64
767+ name string
768+ codeHex string
769+ wantErr error
770+ wantOpcode OpCode
771+ wantVals []uint64
770772 }{
771773 {
772774 name : "DUPN" ,
@@ -819,55 +821,70 @@ func TestEIP8024_Execution(t *testing.T) {
819821 },
820822 },
821823 {
822- name : "INVALID_SWAPN_LOW" ,
823- codeHex : "e75b" ,
824- wantErr : true ,
824+ name : "INVALID_SWAPN_LOW" ,
825+ codeHex : "e75b" ,
826+ wantErr : & ErrInvalidOpCode {},
827+ wantOpcode : SWAPN ,
825828 },
826829 {
827830 name : "JUMP over INVALID_DUPN" ,
828831 codeHex : "600456e65b" ,
829- wantErr : false ,
832+ wantErr : nil ,
833+ },
834+ {
835+ name : "UNDERFLOW_DUPN_1" ,
836+ codeHex : "6000808080808080808080808080808080e600" ,
837+ wantErr : & ErrStackUnderflow {},
838+ wantOpcode : DUPN ,
830839 },
831840 // Additional test cases
832841 {
833- name : "INVALID_DUPN_LOW" ,
834- codeHex : "e65b" ,
835- wantErr : true ,
842+ name : "INVALID_DUPN_LOW" ,
843+ codeHex : "e65b" ,
844+ wantErr : & ErrInvalidOpCode {},
845+ wantOpcode : DUPN ,
836846 },
837847 {
838- name : "INVALID_EXCHANGE_LOW" ,
839- codeHex : "e850" ,
840- wantErr : true ,
848+ name : "INVALID_EXCHANGE_LOW" ,
849+ codeHex : "e850" ,
850+ wantErr : & ErrInvalidOpCode {},
851+ wantOpcode : EXCHANGE ,
841852 },
842853 {
843- name : "INVALID_DUPN_HIGH" ,
844- codeHex : "e67f" ,
845- wantErr : true ,
854+ name : "INVALID_DUPN_HIGH" ,
855+ codeHex : "e67f" ,
856+ wantErr : & ErrInvalidOpCode {},
857+ wantOpcode : DUPN ,
846858 },
847859 {
848- name : "INVALID_SWAPN_HIGH" ,
849- codeHex : "e77f" ,
850- wantErr : true ,
860+ name : "INVALID_SWAPN_HIGH" ,
861+ codeHex : "e77f" ,
862+ wantErr : & ErrInvalidOpCode {},
863+ wantOpcode : SWAPN ,
851864 },
852865 {
853- name : "INVALID_EXCHANGE_HIGH" ,
854- codeHex : "e87f" ,
855- wantErr : true ,
866+ name : "INVALID_EXCHANGE_HIGH" ,
867+ codeHex : "e87f" ,
868+ wantErr : & ErrInvalidOpCode {},
869+ wantOpcode : EXCHANGE ,
856870 },
857871 {
858- name : "UNDERFLOW_DUPN" ,
859- codeHex : "5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe600" , // (n=17, need 17 items, have 16)
860- wantErr : true ,
872+ name : "UNDERFLOW_DUPN_2" ,
873+ codeHex : "5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe600" , // (n=17, need 17 items, have 16)
874+ wantErr : & ErrStackUnderflow {},
875+ wantOpcode : DUPN ,
861876 },
862877 {
863- name : "UNDERFLOW_SWAPN" ,
864- codeHex : "5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe700" , // (n=17, need 18 items, have 17)
865- wantErr : true ,
878+ name : "UNDERFLOW_SWAPN" ,
879+ codeHex : "5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe700" , // (n=17, need 18 items, have 17)
880+ wantErr : & ErrStackUnderflow {},
881+ wantOpcode : SWAPN ,
866882 },
867883 {
868- name : "UNDERFLOW_EXCHANGE" ,
869- codeHex : "60016002e801" , // (n,m)=(1,2), need 3 items, have 2
870- wantErr : true ,
884+ name : "UNDERFLOW_EXCHANGE" ,
885+ codeHex : "60016002e801" , // (n,m)=(1,2), need 3 items, have 2
886+ wantErr : & ErrStackUnderflow {},
887+ wantOpcode : EXCHANGE ,
871888 },
872889 {
873890 name : "PC_INCREMENT" ,
@@ -883,6 +900,7 @@ func TestEIP8024_Execution(t *testing.T) {
883900 pc := uint64 (0 )
884901 scope := & ScopeContext {Stack : stack , Contract : & Contract {Code : code }}
885902 var err error
903+ var errOp OpCode
886904 for pc < uint64 (len (code )) && err == nil {
887905 op := code [pc ]
888906 switch OpCode (op ) {
@@ -908,14 +926,37 @@ func TestEIP8024_Execution(t *testing.T) {
908926 case EXCHANGE :
909927 _ , err = opExchange (& pc , evm , scope )
910928 default :
911- err = & ErrInvalidOpCode {opcode : OpCode (op )}
929+ t .Fatalf ("unexpected opcode %s at pc=%d" , OpCode (op ), pc )
930+ }
931+ if err != nil {
932+ errOp = OpCode (op )
912933 }
913934 pc ++
914935 }
915- if tc .wantErr {
936+ if tc .wantErr != nil {
937+ // Fail because we wanted an error, but didn't get one.
916938 if err == nil {
917939 t .Fatalf ("expected error, got nil" )
918940 }
941+ // Fail if the wrong opcode threw an error.
942+ if errOp != tc .wantOpcode {
943+ t .Fatalf ("expected error from opcode %s, got %s" , tc .wantOpcode , errOp )
944+ }
945+ // Fail if we don't get the error we expect.
946+ switch tc .wantErr .(type ) {
947+ case * ErrInvalidOpCode :
948+ var want * ErrInvalidOpCode
949+ if ! errors .As (err , & want ) {
950+ t .Fatalf ("expected ErrInvalidOpCode, got %v" , err )
951+ }
952+ case * ErrStackUnderflow :
953+ var want * ErrStackUnderflow
954+ if ! errors .As (err , & want ) {
955+ t .Fatalf ("expected ErrStackUnderflow, got %v" , err )
956+ }
957+ default :
958+ t .Fatalf ("unsupported wantErr type %T" , tc .wantErr )
959+ }
919960 return
920961 }
921962 if err != nil {
0 commit comments