@@ -21,31 +21,31 @@ import (
21
21
"math/big"
22
22
23
23
"github.com/ethereum/go-ethereum/common"
24
- "github.com/ethereum/go-ethereum/core/state"
25
24
"github.com/ethereum/go-ethereum/core/vm"
26
25
"github.com/ethereum/go-ethereum/logger"
27
26
"github.com/ethereum/go-ethereum/logger/glog"
28
27
"github.com/ethereum/go-ethereum/params"
29
28
)
30
29
31
30
/*
32
- * The State transitioning model
33
- *
34
- * A state transition is a change made when a transaction is applied to the current world state
35
- * The state transitioning model does all all the necessary work to work out a valid new state root.
36
- * 1) Nonce handling
37
- * 2) Pre pay / buy gas of the coinbase (miner)
38
- * 3) Create a new state object if the recipient is \0*32
39
- * 4) Value transfer
40
- * == If contract creation ==
41
- * 4a) Attempt to run transaction data
42
- * 4b) If valid, use result as code for the new state object
43
- * == end ==
44
- * 5) Run Script section
45
- * 6) Derive new state root
46
- */
31
+ The State Transitioning Model
32
+
33
+ A state transition is a change made when a transaction is applied to the current world state
34
+ The state transitioning model does all all the necessary work to work out a valid new state root.
35
+
36
+ 1) Nonce handling
37
+ 2) Pre pay gas
38
+ 3) Create a new state object if the recipient is \0*32
39
+ 4) Value transfer
40
+ == If contract creation ==
41
+ 4a) Attempt to run transaction data
42
+ 4b) If valid, use result as code for the new state object
43
+ == end ==
44
+ 5) Run Script section
45
+ 6) Derive new state root
46
+ */
47
47
type StateTransition struct {
48
- gp GasPool
48
+ gp * GasPool
49
49
msg Message
50
50
gas , gasPrice * big.Int
51
51
initialGas * big.Int
@@ -94,7 +94,7 @@ func IntrinsicGas(data []byte) *big.Int {
94
94
return igas
95
95
}
96
96
97
- func ApplyMessage (env vm.Environment , msg Message , gp GasPool ) ([]byte , * big.Int , error ) {
97
+ func ApplyMessage (env vm.Environment , msg Message , gp * GasPool ) ([]byte , * big.Int , error ) {
98
98
var st = StateTransition {
99
99
gp : gp ,
100
100
env : env ,
@@ -158,7 +158,7 @@ func (self *StateTransition) buyGas() error {
158
158
if sender .Balance ().Cmp (mgval ) < 0 {
159
159
return fmt .Errorf ("insufficient ETH for gas (%x). Req %v, has %v" , sender .Address ().Bytes ()[:4 ], mgval , sender .Balance ())
160
160
}
161
- if err = self .gp .SubGas (mgas , self . gasPrice ); err != nil {
161
+ if err = self .gp .SubGas (mgas ); err != nil {
162
162
return err
163
163
}
164
164
self .addGas (mgas )
@@ -180,9 +180,9 @@ func (self *StateTransition) preCheck() (err error) {
180
180
return NonceError (msg .Nonce (), n )
181
181
}
182
182
183
- // Pre-pay gas / Buy gas of the coinbase account
183
+ // Pre-pay gas
184
184
if err = self .buyGas (); err != nil {
185
- if state . IsGasLimitErr (err ) {
185
+ if IsGasLimitErr (err ) {
186
186
return err
187
187
}
188
188
return InvalidTxError (err )
@@ -246,17 +246,21 @@ func (self *StateTransition) transitionDb() (ret []byte, usedGas *big.Int, err e
246
246
}
247
247
248
248
func (self * StateTransition ) refundGas () {
249
+ // Return eth for remaining gas to the sender account,
250
+ // exchanged at the original rate.
249
251
sender , _ := self .from () // err already checked
250
- // Return remaining gas
251
252
remaining := new (big.Int ).Mul (self .gas , self .gasPrice )
252
253
sender .AddBalance (remaining )
253
254
255
+ // Apply refund counter, capped to half of the used gas.
254
256
uhalf := remaining .Div (self .gasUsed (), common .Big2 )
255
257
refund := common .BigMin (uhalf , self .state .GetRefund ())
256
258
self .gas .Add (self .gas , refund )
257
259
self .state .AddBalance (sender .Address (), refund .Mul (refund , self .gasPrice ))
258
260
259
- self .gp .AddGas (self .gas , self .gasPrice )
261
+ // Also return remaining gas to the block gas counter so it is
262
+ // available for the next transaction.
263
+ self .gp .AddGas (self .gas )
260
264
}
261
265
262
266
func (self * StateTransition ) gasUsed () * big.Int {
0 commit comments