Special diff output for execution

This commit is contained in:
obscuren 2014-07-11 16:04:09 +02:00
parent ff151f9fbc
commit 9010857677
6 changed files with 57 additions and 8 deletions

View File

@ -24,6 +24,10 @@ func Disassemble(script []byte) (asm []string) {
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32: case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
pc.Add(pc, ethutil.Big1) pc.Add(pc, ethutil.Big1)
a := int64(op) - int64(PUSH1) + 1 a := int64(op) - int64(PUSH1) + 1
if int(pc.Int64()+a) > len(script) {
return nil
}
data := script[pc.Int64() : pc.Int64()+a] data := script[pc.Int64() : pc.Int64()+a]
if len(data) == 0 { if len(data) == 0 {
data = []byte{0} data = []byte{0}

View File

@ -1,6 +1,7 @@
package ethchain package ethchain
import ( import (
"fmt"
"github.com/ethereum/eth-go/ethcrypto" "github.com/ethereum/eth-go/ethcrypto"
"github.com/ethereum/eth-go/ethtrie" "github.com/ethereum/eth-go/ethtrie"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
@ -208,6 +209,16 @@ func (self *State) Update() {
} }
} }
// Debug stuff
func (self *State) CreateOutputForDiff() {
for addr, stateObject := range self.stateObjects {
fmt.Printf("0x%x 0x%x 0x%x 0x%x\n", addr, stateObject.state.Root(), stateObject.Amount.Bytes(), stateObject.Nonce)
stateObject.state.EachStorage(func(addr string, value *ethutil.Value) {
fmt.Printf("0x%x 0x%x\n", addr, value.Bytes())
})
}
}
// Object manifest // Object manifest
// //
// The object manifest is used to keep changes to the state so we can keep track of the changes // The object manifest is used to keep changes to the state so we can keep track of the changes

View File

@ -150,6 +150,10 @@ done:
receipts = append(receipts, receipt) receipts = append(receipts, receipt)
handled = append(handled, tx) handled = append(handled, tx)
if ethutil.Config.Diff {
state.CreateOutputForDiff()
}
} }
parent.GasUsed = totalUsedGas parent.GasUsed = totalUsedGas
@ -183,6 +187,10 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
// before that. // before that.
defer state.Reset() defer state.Reset()
if ethutil.Config.Diff {
fmt.Printf("## 0x%x 0x%x ##\n", block.Hash(), block.Number)
}
receipts, err := sm.ApplyDiff(state, parent, block) receipts, err := sm.ApplyDiff(state, parent, block)
defer func() { defer func() {
if err != nil { if err != nil {

View File

@ -31,6 +31,7 @@ type Debugger interface {
BreakHook(step int, op OpCode, mem *Memory, stack *Stack, stateObject *StateObject) bool BreakHook(step int, op OpCode, mem *Memory, stack *Stack, stateObject *StateObject) bool
StepHook(step int, op OpCode, mem *Memory, stack *Stack, stateObject *StateObject) bool StepHook(step int, op OpCode, mem *Memory, stack *Stack, stateObject *StateObject) bool
BreakPoints() []int64 BreakPoints() []int64
SetCode(byteCode []byte)
} }
type Vm struct { type Vm struct {
@ -90,7 +91,12 @@ func (self *Vm) Endl() *Vm {
} }
func NewVm(state *State, stateManager *StateManager, vars RuntimeVars) *Vm { func NewVm(state *State, stateManager *StateManager, vars RuntimeVars) *Vm {
return &Vm{vars: vars, state: state, stateManager: stateManager, logTy: LogTyPretty} lt := LogTyPretty
if ethutil.Config.Diff {
lt = LogTyDiff
}
return &Vm{vars: vars, state: state, stateManager: stateManager, logTy: lt}
} }
var Pow256 = ethutil.BigPow(2, 256) var Pow256 = ethutil.BigPow(2, 256)
@ -107,12 +113,17 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
} }
}() }()
// Debug hook
if vm.Dbg != nil {
vm.Dbg.SetCode(closure.Script)
}
// Don't bother with the execution if there's no code. // Don't bother with the execution if there's no code.
if len(closure.Script) == 0 { if len(closure.Script) == 0 {
return closure.Return(nil), nil return closure.Return(nil), nil
} }
vmlogger.Debugf("(%s) %x gas: %v (d) %x\n", vm.Fn, closure.object.Address(), closure.Gas, closure.Args) vmlogger.Debugf("(%s) %x gas: %v (d) %x\n", vm.Fn, closure.Address(), closure.Gas, closure.Args)
var ( var (
op OpCode op OpCode
@ -149,7 +160,7 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
b = []byte{0} b = []byte{0}
} }
fmt.Printf("%x %x %x %x\n", closure.object.Address(), b, []byte{byte(op)}, closure.Gas.Bytes()) fmt.Printf("%x %x %x %x\n", closure.Address(), b, []byte{byte(op)}, closure.Gas.Bytes())
} }
gas := new(big.Int) gas := new(big.Int)
@ -456,9 +467,9 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
vm.Printf(" => %x", data) vm.Printf(" => %x", data)
// 0x30 range // 0x30 range
case ADDRESS: case ADDRESS:
stack.Push(ethutil.BigD(closure.Object().Address())) stack.Push(ethutil.BigD(closure.Address()))
vm.Printf(" => %x", closure.Object().Address()) vm.Printf(" => %x", closure.Address())
case BALANCE: case BALANCE:
require(1) require(1)
@ -664,9 +675,9 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
) )
// Generate a new address // Generate a new address
addr := ethcrypto.CreateAddress(closure.object.Address(), closure.object.Nonce) addr := ethcrypto.CreateAddress(closure.Address(), closure.N().Uint64())
for i := uint64(0); vm.state.GetStateObject(addr) != nil; i++ { for i := uint64(0); vm.state.GetStateObject(addr) != nil; i++ {
ethcrypto.CreateAddress(closure.object.Address(), closure.object.Nonce+i) ethcrypto.CreateAddress(closure.Address(), closure.N().Uint64()+i)
} }
closure.object.Nonce++ closure.object.Nonce++
@ -706,6 +717,11 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
vm.Printf("CREATE success") vm.Printf("CREATE success")
} }
vm.Endl() vm.Endl()
// Debug hook
if vm.Dbg != nil {
vm.Dbg.SetCode(closure.Script)
}
case CALL: case CALL:
require(7) require(7)
@ -749,6 +765,11 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
mem.Set(retOffset.Int64(), retSize.Int64(), ret) mem.Set(retOffset.Int64(), retSize.Int64(), ret)
} }
// Debug hook
if vm.Dbg != nil {
vm.Dbg.SetCode(closure.Script)
}
} }
case RETURN: case RETURN:
require(2) require(2)
@ -786,6 +807,8 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
if vm.Dbg != nil { if vm.Dbg != nil {
for _, instrNo := range vm.Dbg.BreakPoints() { for _, instrNo := range vm.Dbg.BreakPoints() {
if pc.Cmp(big.NewInt(instrNo)) == 0 { if pc.Cmp(big.NewInt(instrNo)) == 0 {
vm.Stepping = true
if !vm.Dbg.BreakHook(prevStep, op, mem, stack, closure.Object()) { if !vm.Dbg.BreakHook(prevStep, op, mem, stack, closure.Object()) {
return nil, nil return nil, nil
} }

View File

@ -20,6 +20,8 @@ import (
"time" "time"
) )
const seedTextFileUri string = "http://www.ethereum.org/servers.poc3.txt"
var ethlogger = ethlog.NewLogger("SERV") var ethlogger = ethlog.NewLogger("SERV")
func eachPeer(peers *list.List, callback func(*Peer, *list.Element)) { func eachPeer(peers *list.List, callback func(*Peer, *list.Element)) {
@ -416,7 +418,7 @@ func (s *Ethereum) Seed() {
s.ProcessPeerList(peers) s.ProcessPeerList(peers)
} else { } else {
// Fallback to servers.poc3.txt // Fallback to servers.poc3.txt
resp, err := http.Get("http://www.ethereum.org/servers.poc3.txt") resp, err := http.Get(seedTextFileUri)
if err != nil { if err != nil {
ethlogger.Warnln("Fetching seed failed:", err) ethlogger.Warnln("Fetching seed failed:", err)
return return

View File

@ -13,6 +13,7 @@ type ConfigManager struct {
ExecPath string ExecPath string
Debug bool Debug bool
Diff bool
Paranoia bool Paranoia bool
conf *globalconf.GlobalConf conf *globalconf.GlobalConf