diff options
author | obscuren <geffobscura@gmail.com> | 2014-05-28 18:05:46 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2014-05-28 18:05:46 +0800 |
commit | 73761f7af64432b6946934c3b1db646d8e99ef07 (patch) | |
tree | 80ec8827bcbca50b65e1ca8f155b6d348e87fc72 /ethchain/state_manager.go | |
parent | 1c01e9c0958d2706c522602663da7cfc40a88600 (diff) | |
download | dexon-73761f7af64432b6946934c3b1db646d8e99ef07.tar.gz dexon-73761f7af64432b6946934c3b1db646d8e99ef07.tar.zst dexon-73761f7af64432b6946934c3b1db646d8e99ef07.zip |
Closure call now returns the total usage as well
* Return the used gas value based on the UseGas and ReturnGas
Diffstat (limited to 'ethchain/state_manager.go')
-rw-r--r-- | ethchain/state_manager.go | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 2d2a32e2f..1a9e9f601 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -106,7 +106,7 @@ func (sm *StateManager) ApplyTransactions(state *State, block *Block, txs []*Tra usedGas, err := sm.ApplyTransaction(state, block, tx) if err != nil { ethutil.Config.Log.Infoln(err) - continue + //continue } accumelative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, usedGas)) @@ -119,7 +119,7 @@ func (sm *StateManager) ApplyTransactions(state *State, block *Block, txs []*Tra return receipts, txs } -func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transaction) (*big.Int, error) { +func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transaction) (totalGasUsed *big.Int, err error) { /* Applies transactions to the given state and creates new state objects where needed. @@ -129,9 +129,17 @@ func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transac assume there's a return value. The return value will be set to the script section of the state object. */ - totalGasUsed := big.NewInt(0) + var ( + addTotalGas = func(gas *big.Int) { totalGasUsed.Add(totalGasUsed, gas) } + gas = new(big.Int) + script []byte + ) + totalGasUsed = big.NewInt(0) + // Apply the transaction to the current state - err := sm.Ethereum.TxPool().ProcessTransaction(tx, state, false) + gas, err = sm.Ethereum.TxPool().ProcessTransaction(tx, state, false) + addTotalGas(gas) + if tx.CreatesContract() { if err == nil { // Create a new state object and the transaction @@ -141,30 +149,32 @@ func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transac // Evaluate the initialization script // and use the return value as the // script section for the state object. - script, err := sm.EvalScript(state, contract.Init(), contract, tx, block) + script, gas, err = sm.EvalScript(state, contract.Init(), contract, tx, block) + addTotalGas(gas) + if err != nil { - return nil, fmt.Errorf("[STATE] Error during init script run %v", err) + err = fmt.Errorf("[STATE] Error during init script run %v", err) + return } contract.script = script state.UpdateStateObject(contract) } else { - return nil, fmt.Errorf("[STATE] Unable to create contract") + err = fmt.Errorf("[STATE] Unable to create contract") } } else { - return nil, fmt.Errorf("[STATE] contract creation tx:", err) + err = fmt.Errorf("[STATE] contract creation tx: %v", err) } } else { // Find the state object at the "recipient" address. If // there's an object attempt to run the script. stateObject := state.GetStateObject(tx.Recipient) if err == nil && stateObject != nil && len(stateObject.Script()) > 0 { - sm.EvalScript(state, stateObject.Script(), stateObject, tx, block) - } else if err != nil { - return nil, fmt.Errorf("[STATE] process:", err) + _, gas, err = sm.EvalScript(state, stateObject.Script(), stateObject, tx, block) + addTotalGas(gas) } } - return totalGasUsed, nil + return } func (sm *StateManager) Process(block *Block, dontReact bool) error { @@ -349,7 +359,7 @@ func (sm *StateManager) Stop() { sm.bc.Stop() } -func (sm *StateManager) EvalScript(state *State, script []byte, object *StateObject, tx *Transaction, block *Block) (ret []byte, err error) { +func (sm *StateManager) EvalScript(state *State, script []byte, object *StateObject, tx *Transaction, block *Block) (ret []byte, gas *big.Int, err error) { account := state.GetAccount(tx.Sender()) err = account.ConvertGas(tx.Gas, tx.GasPrice) @@ -369,7 +379,7 @@ func (sm *StateManager) EvalScript(state *State, script []byte, object *StateObj Value: tx.Value, //Price: tx.GasPrice, }) - ret, err = closure.Call(vm, tx.Data, nil) + ret, gas, err = closure.Call(vm, tx.Data, nil) // Update the account (refunds) state.UpdateStateObject(account) |