From 34c8045d5be6488e9800c24e1e696e1b912f344c Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Jun 2014 18:05:46 +0200 Subject: Fixed issue where JUMPI would do an equally check with 1 instead of GT --- ethchain/vm.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'ethchain/vm.go') diff --git a/ethchain/vm.go b/ethchain/vm.go index 77a08faa6..690433180 100644 --- a/ethchain/vm.go +++ b/ethchain/vm.go @@ -120,7 +120,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro var newMemSize uint64 = 0 switch op { case STOP: + gas.Set(ethutil.Big0) case SUICIDE: + gas.Set(ethutil.Big0) case SLOAD: gas.Set(GasSLoad) case SSTORE: @@ -296,6 +298,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro case EQ: require(2) x, y := stack.Popn() + fmt.Printf("%x == %x\n", x, y) // x == y if x.Cmp(y) == 0 { stack.Push(ethutil.BigTrue) @@ -365,12 +368,14 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro offset := stack.Pop().Int64() var data []byte - if len(closure.Args) >= int(offset+32) { - data = closure.Args[offset : offset+32] + if len(closure.Args) >= int(offset) { + l := int64(math.Min(float64(offset+32), float64(len(closure.Args)))) + data = closure.Args[offset : offset+l] } else { data = []byte{0} } + fmt.Println("CALLDATALOAD", string(data), len(data), "==", len(closure.Args)) stack.Push(ethutil.BigD(data)) case CALLDATASIZE: stack.Push(big.NewInt(int64(len(closure.Args)))) @@ -452,12 +457,11 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro require(1) loc := stack.Pop() val := closure.GetMem(loc) - //fmt.Println("get", val.BigInt(), "@", loc) stack.Push(val.BigInt()) case SSTORE: require(2) val, loc := stack.Popn() - //fmt.Println("storing", val, "@", loc) + fmt.Println("storing", string(val.Bytes()), "@", string(loc.Bytes())) closure.SetStorage(loc, ethutil.NewValue(val)) // Add the change to manifest @@ -471,7 +475,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro case JUMPI: require(2) cond, pos := stack.Popn() - if cond.Cmp(ethutil.BigTrue) == 0 { + if cond.Cmp(ethutil.BigTrue) >= 0 { pc = pos //pc.Sub(pc, ethutil.Big1) continue -- cgit v1.2.3 From ca79360fd7621a96382c0304e74e0d1f39b739fc Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Jun 2014 18:49:26 +0200 Subject: Verbose logging for VM --- ethchain/vm.go | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) (limited to 'ethchain/vm.go') diff --git a/ethchain/vm.go b/ethchain/vm.go index 690433180..7a4e30a33 100644 --- a/ethchain/vm.go +++ b/ethchain/vm.go @@ -45,6 +45,10 @@ type Vm struct { state *State stateManager *StateManager + + Verbose bool + + logStr string } type RuntimeVars struct { @@ -58,6 +62,23 @@ type RuntimeVars struct { Value *big.Int } +func (self *Vm) Printf(format string, v ...interface{}) *Vm { + if self.Verbose { + self.logStr += fmt.Sprintf(format, v...) + } + + return self +} + +func (self *Vm) Endl() *Vm { + if self.Verbose { + ethutil.Config.Log.Infoln(self.logStr) + self.logStr = "" + } + + return self +} + func NewVm(state *State, stateManager *StateManager, vars RuntimeVars) *Vm { return &Vm{vars: vars, state: state, stateManager: stateManager} } @@ -95,8 +116,6 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro step := 0 prevStep := 0 - ethutil.Config.Log.Debugf("# op\n") - for { prevStep = step // The base for all big integer arithmetic @@ -108,7 +127,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro // Get the opcode (it must be an opcode!) op := OpCode(val.Uint()) - ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String()) + vm.Printf("(pc) %-3d -o- %-14s", pc, op.String()) + //ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String()) gas := new(big.Int) addStepGasUsage := func(amount *big.Int) { @@ -193,6 +213,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro return closure.Return(nil), fmt.Errorf("insufficient gas %v %v", closure.Gas, gas) } + vm.Printf(" (g) %-3v (%v)", gas, closure.Gas) + mem.Resize(newMemSize) switch op { @@ -428,6 +450,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro pc.Add(pc, a.Sub(a, big.NewInt(1))) step += int(op) - int(PUSH1) + 1 + + vm.Printf(" => %#x", data.Bytes()) case POP: require(1) stack.Pop() @@ -448,11 +472,15 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro // Pop value of the stack val, mStart := stack.Popn() mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(val, 256)) + + vm.Printf(" => %#x", val) case MSTORE8: require(2) val, mStart := stack.Popn() base.And(val, new(big.Int).SetInt64(0xff)) mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(base, 256)) + + vm.Printf(" => %#x", val) case SLOAD: require(1) loc := stack.Pop() @@ -466,18 +494,23 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro // Add the change to manifest vm.state.manifest.AddStorageChange(closure.Object(), loc.Bytes(), val) + + vm.Printf(" => %#x", val) case JUMP: require(1) pc = stack.Pop() // Reduce pc by one because of the increment that's at the end of this for loop - //pc.Sub(pc, ethutil.Big1) + vm.Printf(" ~> %v", pc).Endl() + continue case JUMPI: require(2) cond, pos := stack.Popn() if cond.Cmp(ethutil.BigTrue) >= 0 { pc = pos - //pc.Sub(pc, ethutil.Big1) + + vm.Printf(" ~> %v", pc).Endl() + continue } case PC: @@ -603,6 +636,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro pc.Add(pc, ethutil.Big1) + vm.Endl() + if hook != nil { if !hook(prevStep, op, mem, stack, closure.Object()) { return nil, nil -- cgit v1.2.3 From 8a885c2606fbf675770cf40b31f9ceb5ef8acae9 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 18 Jun 2014 00:25:58 +0200 Subject: Fixed GT and LT --- ethchain/vm.go | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) (limited to 'ethchain/vm.go') diff --git a/ethchain/vm.go b/ethchain/vm.go index 7a4e30a33..9dbc13ead 100644 --- a/ethchain/vm.go +++ b/ethchain/vm.go @@ -97,7 +97,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro } }() - ethutil.Config.Log.Debugf("[VM] Running closure %x\n", closure.object.Address()) + ethutil.Config.Log.Debugf("[VM] Running %x\n", closure.object.Address()) // Memory for the current closure mem := &Memory{} @@ -301,7 +301,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro stack.Push(base) case LT: require(2) - x, y := stack.Popn() + y, x := stack.Popn() // x < y if x.Cmp(y) < 0 { stack.Push(ethutil.BigTrue) @@ -310,7 +310,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro } case GT: require(2) - x, y := stack.Popn() + y, x := stack.Popn() + vm.Printf(" %v > %v", x, y) + // x > y if x.Cmp(y) > 0 { stack.Push(ethutil.BigTrue) @@ -382,7 +384,10 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro case ORIGIN: stack.Push(ethutil.BigD(vm.vars.Origin)) case CALLER: - stack.Push(ethutil.BigD(closure.caller.Address())) + caller := closure.caller.Address() + stack.Push(ethutil.BigD(caller)) + + vm.Printf(" => %x", caller) case CALLVALUE: stack.Push(vm.vars.Value) case CALLDATALOAD: @@ -397,10 +402,14 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro data = []byte{0} } - fmt.Println("CALLDATALOAD", string(data), len(data), "==", len(closure.Args)) + vm.Printf(" => 0x%x", data) + stack.Push(ethutil.BigD(data)) case CALLDATASIZE: - stack.Push(big.NewInt(int64(len(closure.Args)))) + l := int64(len(closure.Args)) + stack.Push(big.NewInt(l)) + + vm.Printf(" => %d", l) case CALLDATACOPY: case CODESIZE: case CODECOPY: @@ -451,7 +460,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro step += int(op) - int(PUSH1) + 1 - vm.Printf(" => %#x", data.Bytes()) + vm.Printf(" => 0x%x", data.Bytes()) case POP: require(1) stack.Pop() @@ -473,19 +482,21 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro val, mStart := stack.Popn() mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(val, 256)) - vm.Printf(" => %#x", val) + vm.Printf(" => 0x%x", val) case MSTORE8: require(2) val, mStart := stack.Popn() base.And(val, new(big.Int).SetInt64(0xff)) mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(base, 256)) - vm.Printf(" => %#x", val) + vm.Printf(" => 0x%x", val) case SLOAD: require(1) loc := stack.Pop() val := closure.GetMem(loc) stack.Push(val.BigInt()) + + vm.Printf(" {} 0x%x", val) case SSTORE: require(2) val, loc := stack.Popn() @@ -495,7 +506,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro // Add the change to manifest vm.state.manifest.AddStorageChange(closure.Object(), loc.Bytes(), val) - vm.Printf(" => %#x", val) + vm.Printf(" => 0x%x", val) case JUMP: require(1) pc = stack.Pop() @@ -509,9 +520,11 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro if cond.Cmp(ethutil.BigTrue) >= 0 { pc = pos - vm.Printf(" ~> %v", pc).Endl() + vm.Printf(" (t) ~> %v", pc).Endl() continue + } else { + vm.Printf(" (f)") } case PC: stack.Push(pc) -- cgit v1.2.3 From 2565a79575c6a6b839a6585c9ad3ebbcf7db9115 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 18 Jun 2014 00:32:48 +0200 Subject: Swapped vars --- ethchain/vm.go | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) (limited to 'ethchain/vm.go') diff --git a/ethchain/vm.go b/ethchain/vm.go index 9dbc13ead..f83258430 100644 --- a/ethchain/vm.go +++ b/ethchain/vm.go @@ -226,28 +226,28 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro require(2) x, y := stack.Popn() // (x + y) % 2 ** 256 - base.Add(x, y) + base.Add(y, x) // Pop result back on the stack stack.Push(base) case SUB: require(2) x, y := stack.Popn() // (x - y) % 2 ** 256 - base.Sub(x, y) + base.Sub(y, x) // Pop result back on the stack stack.Push(base) case MUL: require(2) x, y := stack.Popn() // (x * y) % 2 ** 256 - base.Mul(x, y) + base.Mul(y, x) // Pop result back on the stack stack.Push(base) case DIV: require(2) x, y := stack.Popn() // floor(x / y) - base.Div(x, y) + base.Div(y, x) // Pop result back on the stack stack.Push(base) case SDIV: @@ -270,7 +270,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro case MOD: require(2) x, y := stack.Popn() - base.Mod(x, y) + base.Mod(y, x) stack.Push(base) case SMOD: require(2) @@ -292,7 +292,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro case EXP: require(2) x, y := stack.Popn() - base.Exp(x, y, Pow256) + base.Exp(y, x, Pow256) stack.Push(base) case NEG: @@ -302,6 +302,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro case LT: require(2) y, x := stack.Popn() + vm.Printf(" %v < %v", x, y) // x < y if x.Cmp(y) < 0 { stack.Push(ethutil.BigTrue) @@ -342,20 +343,11 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro case AND: require(2) x, y := stack.Popn() - if (x.Cmp(ethutil.BigTrue) >= 0) && (y.Cmp(ethutil.BigTrue) >= 0) { - stack.Push(ethutil.BigTrue) - } else { - stack.Push(ethutil.BigFalse) - } - + stack.Push(base.And(y, x)) case OR: require(2) x, y := stack.Popn() - if (x.Cmp(ethutil.BigInt0) >= 0) || (y.Cmp(ethutil.BigInt0) >= 0) { - stack.Push(ethutil.BigTrue) - } else { - stack.Push(ethutil.BigFalse) - } + stack.Push(base.Or(y, x)) case XOR: require(2) x, y := stack.Popn() -- cgit v1.2.3 From dc9c9369e0b44873dedfdf37195268f0e524872d Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 18 Jun 2014 00:36:23 +0200 Subject: log --- ethchain/vm.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'ethchain/vm.go') diff --git a/ethchain/vm.go b/ethchain/vm.go index f83258430..b8ba72c7e 100644 --- a/ethchain/vm.go +++ b/ethchain/vm.go @@ -323,7 +323,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro case EQ: require(2) x, y := stack.Popn() - fmt.Printf("%x == %x\n", x, y) + vm.Printf(" %v == %v", y, x) + // x == y if x.Cmp(y) == 0 { stack.Push(ethutil.BigTrue) @@ -343,15 +344,21 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro case AND: require(2) x, y := stack.Popn() + vm.Printf(" %v & %v", y, x) + stack.Push(base.And(y, x)) case OR: require(2) x, y := stack.Popn() + vm.Printf(" %v | %v", y, x) + stack.Push(base.Or(y, x)) case XOR: require(2) x, y := stack.Popn() - stack.Push(base.Xor(x, y)) + vm.Printf(" %v ^ %v", y, x) + + stack.Push(base.Xor(y, x)) case BYTE: require(2) val, th := stack.Popn() -- cgit v1.2.3