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

@ -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:
pc.Add(pc, ethutil.Big1)
a := int64(op) - int64(PUSH1) + 1
if int(pc.Int64()+a) > len(script) {
return nil
}
data := script[pc.Int64() : pc.Int64()+a]
if len(data) == 0 {
data = []byte{0}

@ -1,6 +1,7 @@
package ethchain
import (
"fmt"
"github.com/ethereum/eth-go/ethcrypto"
"github.com/ethereum/eth-go/ethtrie"
"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
//
// The object manifest is used to keep changes to the state so we can keep track of the changes

@ -150,6 +150,10 @@ done:
receipts = append(receipts, receipt)
handled = append(handled, tx)
if ethutil.Config.Diff {
state.CreateOutputForDiff()
}
}
parent.GasUsed = totalUsedGas
@ -183,6 +187,10 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
// before that.
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)
defer func() {
if err != nil {

@ -31,6 +31,7 @@ type Debugger interface {
BreakHook(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
SetCode(byteCode []byte)
}
type Vm struct {
@ -90,7 +91,12 @@ func (self *Vm) Endl() *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)
@ -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.
if len(closure.Script) == 0 {
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 (
op OpCode
@ -149,7 +160,7 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
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)
@ -456,9 +467,9 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
vm.Printf(" => %x", data)
// 0x30 range
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:
require(1)
@ -664,9 +675,9 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
)
// 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++ {
ethcrypto.CreateAddress(closure.object.Address(), closure.object.Nonce+i)
ethcrypto.CreateAddress(closure.Address(), closure.N().Uint64()+i)
}
closure.object.Nonce++
@ -706,6 +717,11 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
vm.Printf("CREATE success")
}
vm.Endl()
// Debug hook
if vm.Dbg != nil {
vm.Dbg.SetCode(closure.Script)
}
case CALL:
require(7)
@ -749,6 +765,11 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
mem.Set(retOffset.Int64(), retSize.Int64(), ret)
}
// Debug hook
if vm.Dbg != nil {
vm.Dbg.SetCode(closure.Script)
}
}
case RETURN:
require(2)
@ -786,6 +807,8 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
if vm.Dbg != nil {
for _, instrNo := range vm.Dbg.BreakPoints() {
if pc.Cmp(big.NewInt(instrNo)) == 0 {
vm.Stepping = true
if !vm.Dbg.BreakHook(prevStep, op, mem, stack, closure.Object()) {
return nil, nil
}

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

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