Moved gas limit err check to buy gas
This commit is contained in:
parent
b836267401
commit
9f62d441a7
|
@ -97,7 +97,7 @@ func (sm *StateManager) BlockChain() *BlockChain {
|
|||
return sm.bc
|
||||
}
|
||||
|
||||
func (self *StateManager) ProcessTransactions(coinbase []byte, state *State, block, parent *Block, txs Transactions) (Receipts, Transactions, Transactions, error) {
|
||||
func (self *StateManager) ProcessTransactions(coinbase *StateObject, state *State, block, parent *Block, txs Transactions) (Receipts, Transactions, Transactions, error) {
|
||||
var (
|
||||
receipts Receipts
|
||||
handled, unhandled Transactions
|
||||
|
@ -177,9 +177,12 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea
|
|||
}
|
||||
fmt.Println(block.Receipts())
|
||||
|
||||
coinbase := state.GetOrNewStateObject(block.Coinbase)
|
||||
coinbase.gasPool = block.CalcGasLimit(parent)
|
||||
|
||||
// Process the transactions on to current block
|
||||
//sm.ApplyTransactions(block.Coinbase, state, parent, block.Transactions())
|
||||
sm.ProcessTransactions(block.Coinbase, state, block, parent, block.Transactions())
|
||||
sm.ProcessTransactions(coinbase, state, block, parent, block.Transactions())
|
||||
|
||||
// Block validation
|
||||
if err := sm.ValidateBlock(block); err != nil {
|
||||
|
@ -194,7 +197,6 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea
|
|||
return err
|
||||
}
|
||||
|
||||
//if !sm.compState.Cmp(state) {
|
||||
if !block.State().Cmp(state) {
|
||||
return fmt.Errorf("Invalid merkle root.\nrec: %x\nis: %x", block.State().trie.Root, state.trie.Root)
|
||||
}
|
||||
|
|
|
@ -17,6 +17,11 @@ type StateObject struct {
|
|||
state *State
|
||||
script []byte
|
||||
initScript []byte
|
||||
|
||||
// Total gas pool is the total amount of gas currently
|
||||
// left if this object is the coinbase. Gas is directly
|
||||
// purchased of the coinbase.
|
||||
gasPool *big.Int
|
||||
}
|
||||
|
||||
// Converts an transaction in to a state object
|
||||
|
@ -139,14 +144,22 @@ func (c *StateObject) ConvertGas(gas, price *big.Int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (self *StateObject) SetGasPool(gasLimit *big.Int) {
|
||||
self.gasPool = new(big.Int).Set(gasLimit)
|
||||
|
||||
ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "%x fuel (+ %v)", self.Address(), self.gasPool)
|
||||
}
|
||||
|
||||
func (self *StateObject) BuyGas(gas, price *big.Int) error {
|
||||
if self.gasPool.Cmp(gas) < 0 {
|
||||
return GasLimitError(self.gasPool, gas)
|
||||
}
|
||||
|
||||
rGas := new(big.Int).Set(gas)
|
||||
rGas.Mul(rGas, price)
|
||||
|
||||
self.AddAmount(rGas)
|
||||
|
||||
// TODO Do sub from TotalGasPool
|
||||
// and check if enough left
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -158,7 +171,9 @@ func (self *StateObject) Copy() *StateObject {
|
|||
stCopy.ScriptHash = make([]byte, len(self.ScriptHash))
|
||||
copy(stCopy.ScriptHash, self.ScriptHash)
|
||||
stCopy.Nonce = self.Nonce
|
||||
stCopy.state = self.state.Copy()
|
||||
if self.state != nil {
|
||||
stCopy.state = self.state.Copy()
|
||||
}
|
||||
stCopy.script = make([]byte, len(self.script))
|
||||
copy(stCopy.script, self.script)
|
||||
stCopy.initScript = make([]byte, len(self.initScript))
|
||||
|
|
|
@ -32,8 +32,8 @@ type StateTransition struct {
|
|||
cb, rec, sen *StateObject
|
||||
}
|
||||
|
||||
func NewStateTransition(coinbase []byte, tx *Transaction, state *State, block *Block) *StateTransition {
|
||||
return &StateTransition{coinbase, tx, new(big.Int), state, block, nil, nil, nil}
|
||||
func NewStateTransition(coinbase *StateObject, tx *Transaction, state *State, block *Block) *StateTransition {
|
||||
return &StateTransition{coinbase.Address(), tx, new(big.Int), state, block, coinbase, nil, nil}
|
||||
}
|
||||
|
||||
func (self *StateTransition) Coinbase() *StateObject {
|
||||
|
|
|
@ -169,7 +169,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||
case CALL:
|
||||
require(7)
|
||||
gas.Set(GasCall)
|
||||
addStepGasUsage(stack.data[stack.Len()-1])
|
||||
addStepGasUsage(stack.data[stack.Len()-2])
|
||||
|
||||
x := stack.data[stack.Len()-6].Uint64() + stack.data[stack.Len()-7].Uint64()
|
||||
y := stack.data[stack.Len()-4].Uint64() + stack.data[stack.Len()-5].Uint64()
|
||||
|
@ -529,6 +529,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||
vm.state.UpdateStateObject(contract)
|
||||
}
|
||||
case CALL:
|
||||
// TODO RE-WRITE
|
||||
require(7)
|
||||
// Closure addr
|
||||
addr := stack.Pop()
|
||||
|
@ -538,46 +539,44 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
|||
inSize, inOffset := stack.Popn()
|
||||
// Pop return size and offset
|
||||
retSize, retOffset := stack.Popn()
|
||||
// Make sure there's enough gas
|
||||
if closure.Gas.Cmp(gas) < 0 {
|
||||
stack.Push(ethutil.BigFalse)
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
// Get the arguments from the memory
|
||||
args := mem.Get(inOffset.Int64(), inSize.Int64())
|
||||
|
||||
snapshot := vm.state.Snapshot()
|
||||
|
||||
// Fetch the contract which will serve as the closure body
|
||||
contract := vm.state.GetStateObject(addr.Bytes())
|
||||
closure.object.Nonce += 1
|
||||
if closure.object.Amount.Cmp(value) < 0 {
|
||||
ethutil.Config.Log.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Amount)
|
||||
|
||||
if contract != nil {
|
||||
// Prepay for the gas
|
||||
//closure.UseGas(gas)
|
||||
|
||||
// Add the value to the state object
|
||||
contract.AddAmount(value)
|
||||
|
||||
// Create a new callable closure
|
||||
closure := NewClosure(closure, contract, contract.script, vm.state, gas, closure.Price)
|
||||
// Executer the closure and get the return value (if any)
|
||||
ret, _, err := closure.Call(vm, args, hook)
|
||||
if err != nil {
|
||||
stack.Push(ethutil.BigFalse)
|
||||
// Reset the changes applied this object
|
||||
vm.state.Revert(snapshot)
|
||||
} else {
|
||||
stack.Push(ethutil.BigTrue)
|
||||
|
||||
vm.state.UpdateStateObject(contract)
|
||||
|
||||
mem.Set(retOffset.Int64(), retSize.Int64(), ret)
|
||||
}
|
||||
} else {
|
||||
ethutil.Config.Log.Debugf("Contract %x not found\n", addr.Bytes())
|
||||
stack.Push(ethutil.BigFalse)
|
||||
} else {
|
||||
// Fetch the contract which will serve as the closure body
|
||||
contract := vm.state.GetStateObject(addr.Bytes())
|
||||
|
||||
if contract != nil {
|
||||
// Add the value to the state object
|
||||
contract.AddAmount(value)
|
||||
|
||||
// Create a new callable closure
|
||||
closure := NewClosure(closure, contract, contract.script, vm.state, gas, closure.Price)
|
||||
// Executer the closure and get the return value (if any)
|
||||
ret, _, err := closure.Call(vm, args, hook)
|
||||
if err != nil {
|
||||
stack.Push(ethutil.BigFalse)
|
||||
// Reset the changes applied this object
|
||||
vm.state.Revert(snapshot)
|
||||
} else {
|
||||
stack.Push(ethutil.BigTrue)
|
||||
|
||||
vm.state.UpdateStateObject(contract)
|
||||
|
||||
mem.Set(retOffset.Int64(), retSize.Int64(), ret)
|
||||
}
|
||||
} else {
|
||||
ethutil.Config.Log.Debugf("Contract %x not found\n", addr.Bytes())
|
||||
stack.Push(ethutil.BigFalse)
|
||||
}
|
||||
}
|
||||
case RETURN:
|
||||
require(2)
|
||||
|
|
|
@ -139,7 +139,8 @@ func (self *Miner) mineNewBlock() {
|
|||
|
||||
// Accumulate all valid transaction and apply them to the new state
|
||||
// Error may be ignored. It's not important during mining
|
||||
receipts, txs, unhandledTxs, err := stateManager.ProcessTransactions(self.block.Coinbase, self.block.State(), self.block, self.block, self.txs)
|
||||
coinbase := self.block.State().GetOrNewStateObject(self.block.Coinbase)
|
||||
receipts, txs, unhandledTxs, err := stateManager.ProcessTransactions(coinbase, self.block.State(), self.block, self.block, self.txs)
|
||||
if err != nil {
|
||||
ethutil.Config.Log.Debugln("[MINER]", err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue