@@ -43,6 +43,31 @@ func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) {
43
43
code = context .Code
44
44
value = context .value
45
45
price = context .Price
46
+
47
+ op OpCode // current opcode
48
+ codehash = crypto .Sha3Hash (code ) // codehash is used when doing jump dest caching
49
+ mem = NewMemory () // bound memory
50
+ stack = newstack () // local stack
51
+ statedb = self .env .State () // current state
52
+ // For optimisation reason we're using uint64 as the program counter.
53
+ // It's theoretically possible to go above 2^64. The YP defines the PC to be uint256. Pratically much less so feasible.
54
+ pc = uint64 (0 ) // program counter
55
+
56
+ // jump evaluates and checks whether the given jump destination is a valid one
57
+ // if valid move the `pc` otherwise return an error.
58
+ jump = func (from uint64 , to * big.Int ) error {
59
+ if ! context .jumpdests .has (codehash , code , to ) {
60
+ nop := context .GetOp (to .Uint64 ())
61
+ return fmt .Errorf ("invalid jump destination (%v) %v" , nop , to )
62
+ }
63
+
64
+ pc = to .Uint64 ()
65
+
66
+ return nil
67
+ }
68
+
69
+ newMemSize * big.Int
70
+ cost * big.Int
46
71
)
47
72
48
73
// User defer pattern to check for an error and, based on the error being nil or not, use all gas and return.
@@ -52,6 +77,7 @@ func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) {
52
77
}
53
78
54
79
if err != nil {
80
+ self .log (pc , op , context .Gas , cost , mem , stack , context , err )
55
81
56
82
// In case of a VM exception (known exceptions) all gas consumed (panics NOT included).
57
83
context .UseGas (context .Gas )
@@ -71,30 +97,6 @@ func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) {
71
97
return context .Return (nil ), nil
72
98
}
73
99
74
- var (
75
- op OpCode // current opcode
76
- codehash = crypto .Sha3Hash (code ) // codehash is used when doing jump dest caching
77
- mem = NewMemory () // bound memory
78
- stack = newstack () // local stack
79
- statedb = self .env .State () // current state
80
- // For optimisation reason we're using uint64 as the program counter.
81
- // It's theoretically possible to go above 2^64. The YP defines the PC to be uint256. Pratically much less so feasible.
82
- pc = uint64 (0 ) // program counter
83
-
84
- // jump evaluates and checks whether the given jump destination is a valid one
85
- // if valid move the `pc` otherwise return an error.
86
- jump = func (from uint64 , to * big.Int ) error {
87
- if ! context .jumpdests .has (codehash , code , to ) {
88
- nop := context .GetOp (to .Uint64 ())
89
- return fmt .Errorf ("invalid jump destination (%v) %v" , nop , to )
90
- }
91
-
92
- pc = to .Uint64 ()
93
-
94
- return nil
95
- }
96
- )
97
-
98
100
for {
99
101
// The base for all big integer arithmetic
100
102
base := new (big.Int )
@@ -103,24 +105,23 @@ func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) {
103
105
op = context .GetOp (pc )
104
106
105
107
// calculate the new memory size and gas price for the current executing opcode
106
- newMemSize , gas , err : = self .calculateGasAndSize (context , caller , op , statedb , mem , stack )
108
+ newMemSize , cost , err = self .calculateGasAndSize (context , caller , op , statedb , mem , stack )
107
109
if err != nil {
108
110
return nil , err
109
111
}
110
112
111
- self .log (pc , op , context .Gas , gas , mem , stack , context )
112
-
113
113
// Use the calculated gas. When insufficient gas is present, use all gas and return an
114
114
// Out Of Gas error
115
- if ! context .UseGas (gas ) {
116
- tmp := new (big.Int ).Set (context .Gas )
115
+ if ! context .UseGas (cost ) {
117
116
118
117
context .UseGas (context .Gas )
119
118
120
- return context .Return (nil ), OOG ( gas , tmp )
119
+ return context .Return (nil ), OutOfGasError {}
121
120
}
122
121
// Resize the memory calculated previously
123
122
mem .Resize (newMemSize .Uint64 ())
123
+ // Add a log message
124
+ self .log (pc , op , context .Gas , cost , mem , stack , context , nil )
124
125
125
126
switch op {
126
127
case ADD :
@@ -783,15 +784,13 @@ func (self *Vm) RunPrecompiled(p *PrecompiledAccount, input []byte, context *Con
783
784
784
785
return context .Return (ret ), nil
785
786
} else {
786
- tmp := new (big.Int ).Set (context .Gas )
787
-
788
- return nil , OOG (gas , tmp )
787
+ return nil , OutOfGasError {}
789
788
}
790
789
}
791
790
792
791
// log emits a log event to the environment for each opcode encountered. This is not to be confused with the
793
792
// LOG* opcode.
794
- func (self * Vm ) log (pc uint64 , op OpCode , gas , cost * big.Int , memory * Memory , stack * stack , context * Context ) {
793
+ func (self * Vm ) log (pc uint64 , op OpCode , gas , cost * big.Int , memory * Memory , stack * stack , context * Context , err error ) {
795
794
if Debug {
796
795
mem := make ([]byte , len (memory .Data ()))
797
796
copy (mem , memory .Data ())
@@ -804,7 +803,7 @@ func (self *Vm) log(pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, st
804
803
storage [common .BytesToHash (k )] = v
805
804
})
806
805
807
- self .env .AddStructLog (StructLog {pc , op , new (big.Int ).Set (gas ), cost , mem , stck , storage })
806
+ self .env .AddStructLog (StructLog {pc , op , new (big.Int ).Set (gas ), cost , mem , stck , storage , err })
808
807
}
809
808
}
810
809
0 commit comments