Minor updates on gas and removed/refactored old code.

This commit is contained in:
obscuren 2014-12-20 02:21:13 +01:00
parent f5b8f3d41b
commit 1508a23a6f
6 changed files with 55 additions and 42 deletions

View File

@ -142,6 +142,7 @@ done:
receipt := types.NewReceipt(state.Root(), cumulative) receipt := types.NewReceipt(state.Root(), cumulative)
receipt.SetLogs(state.Logs()) receipt.SetLogs(state.Logs())
receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
chainlogger.Debugln(receipt)
// Notify all subscribers // Notify all subscribers
if !transientProcess { if !transientProcess {
@ -214,7 +215,8 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
receiptSha := types.DeriveSha(receipts) receiptSha := types.DeriveSha(receipts)
if bytes.Compare(receiptSha, block.ReceiptSha) != 0 { if bytes.Compare(receiptSha, block.ReceiptSha) != 0 {
chainlogger.Debugln(receipts) //chainlogger.Debugf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha)
fmt.Printf("%x\n", ethutil.Encode(receipts))
err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha) err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha)
return return
} }

View File

@ -3,6 +3,7 @@ package core
import ( import (
"fmt" "fmt"
"math/big" "math/big"
"time"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/vm" "github.com/ethereum/go-ethereum/vm"
@ -12,7 +13,6 @@ type Execution struct {
env vm.Environment env vm.Environment
address, input []byte address, input []byte
Gas, price, value *big.Int Gas, price, value *big.Int
object *state.StateObject
SkipTransfer bool SkipTransfer bool
} }
@ -35,8 +35,6 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret
env := self.env env := self.env
evm := vm.New(env, vm.DebugVmTy) evm := vm.New(env, vm.DebugVmTy)
chainlogger.Debugf("pre state %x\n", env.State().Root())
if env.Depth() == vm.MaxCallDepth { if env.Depth() == vm.MaxCallDepth {
// Consume all gas (by not returning it) and return a depth error // Consume all gas (by not returning it) and return a depth error
return nil, vm.DepthError{} return nil, vm.DepthError{}
@ -55,13 +53,12 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret
} }
snapshot := env.State().Copy() snapshot := env.State().Copy()
defer func() { start := time.Now()
env.State().Set(snapshot)
chainlogger.Debugf("post state %x\n", env.State().Root())
}()
self.object = to
ret, err = evm.Run(to, caller, code, self.value, self.Gas, self.price, self.input) ret, err = evm.Run(to, caller, code, self.value, self.Gas, self.price, self.input)
if err != nil {
env.State().Set(snapshot)
}
chainlogger.Debugf("vm took %v\n", time.Since(start))
return return
} }

View File

@ -186,13 +186,13 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
vmenv := self.VmEnv() vmenv := self.VmEnv()
var ref vm.ClosureRef var ref vm.ClosureRef
if MessageCreatesContract(msg) { if MessageCreatesContract(msg) {
self.rec = MakeContract(msg, self.state) contract := MakeContract(msg, self.state)
ret, err, ref = vmenv.Create(sender, contract.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value)
ret, err, ref = vmenv.Create(sender, self.rec.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value)
if err == nil { if err == nil {
dataGas := big.NewInt(int64(len(ret))) dataGas := big.NewInt(int64(len(ret)))
dataGas.Mul(dataGas, vm.GasCreateByte) dataGas.Mul(dataGas, vm.GasCreateByte)
if err = self.UseGas(dataGas); err == nil { if err = self.UseGas(dataGas); err == nil {
//self.state.SetCode(ref.Address(), ret)
ref.SetCode(ret) ref.SetCode(ret)
} }
} }
@ -218,20 +218,19 @@ func MakeContract(msg Message, state *state.StateDB) *state.StateObject {
} }
func (self *StateTransition) RefundGas() { func (self *StateTransition) RefundGas() {
coinbaseSub := new(big.Int).Set(self.gas)
uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2)
for addr, ref := range self.state.Refunds() {
refund := ethutil.BigMin(uhalf, ref)
coinbaseSub.Add(self.gas, refund)
self.state.AddBalance([]byte(addr), refund.Mul(refund, self.msg.GasPrice()))
}
coinbase, sender := self.Coinbase(), self.From() coinbase, sender := self.Coinbase(), self.From()
coinbase.RefundGas(coinbaseSub, self.msg.GasPrice())
// Return remaining gas // Return remaining gas
remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice()) remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice())
sender.AddAmount(remaining) sender.AddAmount(remaining)
uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2)
for addr, ref := range self.state.Refunds() {
refund := ethutil.BigMin(uhalf, ref)
self.gas.Add(self.gas, refund)
self.state.AddBalance([]byte(addr), refund.Mul(refund, self.msg.GasPrice()))
}
coinbase.RefundGas(self.gas, self.msg.GasPrice())
} }
func (self *StateTransition) GasUsed() *big.Int { func (self *StateTransition) GasUsed() *big.Int {

View File

@ -94,6 +94,13 @@ func (self *StateDB) GetCode(addr []byte) []byte {
return nil return nil
} }
func (self *StateDB) SetCode(addr, code []byte) {
stateObject := self.GetStateObject(addr)
if stateObject != nil {
stateObject.SetCode(code)
}
}
func (self *StateDB) GetState(a, b []byte) []byte { func (self *StateDB) GetState(a, b []byte) []byte {
stateObject := self.GetStateObject(a) stateObject := self.GetStateObject(a)
if stateObject != nil { if stateObject != nil {

View File

@ -2,6 +2,7 @@ package vm
import ( import (
"errors" "errors"
"fmt"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
@ -74,3 +75,7 @@ func (self *Log) Data() []byte {
func (self *Log) RlpData() interface{} { func (self *Log) RlpData() interface{} {
return []interface{}{self.address, ethutil.ByteSliceToInterface(self.topics), self.data} return []interface{}{self.address, ethutil.ByteSliceToInterface(self.topics), self.data}
} }
func (self *Log) String() string {
return fmt.Sprintf("[A=%x T=%x D=%x]", self.address, self.topics, self.data)
}

View File

@ -108,13 +108,13 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
} }
) )
vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], closure.Address(), len(code), closure.Gas, callData)
// Don't bother with the execution if there's no code. // Don't bother with the execution if there's no code.
if len(code) == 0 { if len(code) == 0 {
return closure.Return(nil), nil return closure.Return(nil), nil
} }
vmlogger.Debugf("(%d) (%x) %x gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], closure.Address(), closure.Gas, callData)
for { for {
prevStep = step prevStep = step
// The base for all big integer arithmetic // The base for all big integer arithmetic
@ -134,6 +134,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
addStepGasUsage(GasStep) addStepGasUsage(GasStep)
var newMemSize *big.Int = ethutil.Big0 var newMemSize *big.Int = ethutil.Big0
var additionalGas *big.Int = new(big.Int)
// Stack Check, memory resize & gas phase // Stack Check, memory resize & gas phase
switch op { switch op {
// Stack checks only // Stack checks only
@ -213,22 +214,24 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2]) newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
case SHA3: case SHA3:
require(2) require(2)
gas.Set(GasSha) gas.Set(GasSha)
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2]) newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
additionalGas.Set(stack.data[stack.Len()-2])
case CALLDATACOPY: case CALLDATACOPY:
require(2) require(2)
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3]) newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
additionalGas.Set(stack.data[stack.Len()-3])
case CODECOPY: case CODECOPY:
require(3) require(3)
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3]) newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
additionalGas.Set(stack.data[stack.Len()-3])
case EXTCODECOPY: case EXTCODECOPY:
require(4) require(4)
newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4]) newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4])
additionalGas.Set(stack.data[stack.Len()-4])
case CALL, CALLCODE: case CALL, CALLCODE:
require(7) require(7)
gas.Set(GasCall) gas.Set(GasCall)
@ -245,20 +248,23 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3]) newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3])
} }
switch op {
case CALLDATACOPY, CODECOPY, EXTCODECOPY:
additionalGas.Add(additionalGas, u256(31))
additionalGas.Div(additionalGas, u256(32))
addStepGasUsage(additionalGas)
case SHA3:
additionalGas.Add(additionalGas, u256(31))
additionalGas.Div(additionalGas, u256(32))
additionalGas.Mul(additionalGas, GasSha3Byte)
addStepGasUsage(additionalGas)
}
if newMemSize.Cmp(ethutil.Big0) > 0 { if newMemSize.Cmp(ethutil.Big0) > 0 {
newMemSize.Add(newMemSize, u256(31)) newMemSize.Add(newMemSize, u256(31))
newMemSize.Div(newMemSize, u256(32)) newMemSize.Div(newMemSize, u256(32))
newMemSize.Mul(newMemSize, u256(32)) newMemSize.Mul(newMemSize, u256(32))
switch op {
case CALLDATACOPY, CODECOPY, EXTCODECOPY:
addStepGasUsage(new(big.Int).Div(newMemSize, u256(32)))
case SHA3:
g := new(big.Int).Div(newMemSize, u256(32))
g.Mul(g, GasSha3Byte)
addStepGasUsage(g)
}
if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 { if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len()))) memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
memGasUsage.Mul(GasMemory, memGasUsage) memGasUsage.Mul(GasMemory, memGasUsage)
@ -643,9 +649,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
case CODECOPY, EXTCODECOPY: case CODECOPY, EXTCODECOPY:
var code []byte var code []byte
if op == EXTCODECOPY { if op == EXTCODECOPY {
addr := stack.Pop().Bytes() code = statedb.GetCode(stack.Pop().Bytes())
code = statedb.GetCode(addr)
} else { } else {
code = closure.Code code = closure.Code
} }
@ -663,12 +667,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
} else if cOff+l > size { } else if cOff+l > size {
l = uint64(math.Min(float64(cOff+l), float64(size))) l = uint64(math.Min(float64(cOff+l), float64(size)))
} }
codeCopy := code[cOff : cOff+l] codeCopy := code[cOff : cOff+l]
mem.Set(mOff, l, codeCopy) mem.Set(mOff, l, codeCopy)
self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, code[cOff:cOff+l]) self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, codeCopy)
case GASPRICE: case GASPRICE:
stack.Push(closure.Price) stack.Push(closure.Price)
@ -891,7 +894,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
size, offset := stack.Popn() size, offset := stack.Popn()
ret := mem.Get(offset.Int64(), size.Int64()) ret := mem.Get(offset.Int64(), size.Int64())
self.Printf(" => (%d) 0x%x", len(ret), ret).Endl() self.Printf(" => [%v, %v] (%d) 0x%x", offset, size, len(ret), ret).Endl()
return closure.Return(ret), nil return closure.Return(ret), nil
case SUICIDE: case SUICIDE: