From 6fb6e6679eb7c329ac9013d0c879a7c4b17daca5 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Wed, 10 Jun 2015 12:57:37 +0200
Subject: [PATCH] core/vm, core/state: added storage to structured vm logging

---
 core/state/state_object.go | 16 ++++++++++++++++
 core/vm/environment.go     | 11 ++++++-----
 core/vm/vm.go              | 13 ++++++++++---
 core/vm_logger.go          |  8 +++++++-
 4 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/core/state/state_object.go b/core/state/state_object.go
index bfc4ebc6c..6d2455d79 100644
--- a/core/state/state_object.go
+++ b/core/state/state_object.go
@@ -336,6 +336,22 @@ func (self *StateObject) Nonce() uint64 {
 	return self.nonce
 }
 
+func (self *StateObject) EachStorage(cb func(key, value []byte)) {
+	// When iterating over the storage check the cache first
+	for h, v := range self.storage {
+		cb([]byte(h), v.Bytes())
+	}
+
+	it := self.State.trie.Iterator()
+	for it.Next() {
+		// ignore cached values
+		key := self.State.trie.GetKey(it.Key)
+		if _, ok := self.storage[string(key)]; !ok {
+			cb(key, it.Value)
+		}
+	}
+}
+
 //
 // Encoding
 //
diff --git a/core/vm/environment.go b/core/vm/environment.go
index 31d5d5ea6..25bd2515e 100644
--- a/core/vm/environment.go
+++ b/core/vm/environment.go
@@ -34,11 +34,12 @@ type Environment interface {
 }
 
 type StructLog struct {
-	Pc     uint64
-	Op     OpCode
-	Gas    *big.Int
-	Memory []byte
-	Stack  []*big.Int
+	Pc      uint64
+	Op      OpCode
+	Gas     *big.Int
+	Memory  []byte
+	Stack   []*big.Int
+	Storage map[common.Hash][]byte
 }
 
 type Account interface {
diff --git a/core/vm/vm.go b/core/vm/vm.go
index 7c4a7ce6d..e4f6e9268 100644
--- a/core/vm/vm.go
+++ b/core/vm/vm.go
@@ -95,7 +95,7 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
 		// Get the memory location of pc
 		op = context.GetOp(pc)
 
-		self.log(pc, op, context.Gas, mem, stack)
+		self.log(pc, op, context.Gas, mem, stack, context)
 
 		newMemSize, gas, err := self.calculateGasAndSize(context, caller, op, statedb, mem, stack)
 		if err != nil {
@@ -778,13 +778,20 @@ func (self *Vm) RunPrecompiled(p *PrecompiledAccount, callData []byte, context *
 	}
 }
 
-func (self *Vm) log(pc uint64, op OpCode, gas *big.Int, memory *Memory, stack *Stack) {
+func (self *Vm) log(pc uint64, op OpCode, gas *big.Int, memory *Memory, stack *Stack, context *Context) {
 	if Debug {
 		mem := make([]byte, len(memory.Data()))
 		copy(mem, memory.Data())
 		stck := make([]*big.Int, len(stack.Data()))
 		copy(stck, stack.Data())
-		self.env.AddStructLog(StructLog{pc, op, new(big.Int).Set(gas), mem, stck})
+
+		object := context.self.(*state.StateObject)
+		storage := make(map[common.Hash][]byte)
+		object.EachStorage(func(k, v []byte) {
+			storage[common.BytesToHash(k)] = v
+		})
+
+		self.env.AddStructLog(StructLog{pc, op, new(big.Int).Set(gas), mem, stck, storage})
 	}
 }
 
diff --git a/core/vm_logger.go b/core/vm_logger.go
index 84fa71b24..d0742380e 100644
--- a/core/vm_logger.go
+++ b/core/vm_logger.go
@@ -12,7 +12,7 @@ import (
 func VmStdErrFormat(logs []vm.StructLog) {
 	fmt.Fprintf(os.Stderr, "VM Stats %d ops\n", len(logs))
 	for _, log := range logs {
-		fmt.Fprintf(os.Stderr, "PC %-3d - %-14s\n", log.Pc, log.Op)
+		fmt.Fprintf(os.Stderr, "PC %08d: %s\n", log.Pc, log.Op)
 		fmt.Fprintln(os.Stderr, "STACK =", len(log.Stack))
 		for i, item := range log.Stack {
 			fmt.Fprintf(os.Stderr, "%04d: %x\n", i, common.LeftPadBytes(item.Bytes(), 32))
@@ -36,5 +36,11 @@ func VmStdErrFormat(logs []vm.StructLog) {
 			addr++
 			fmt.Fprintln(os.Stderr, str)
 		}
+
+		fmt.Fprintln(os.Stderr, "STORAGE =", len(log.Storage))
+		for h, item := range log.Storage {
+			fmt.Fprintf(os.Stderr, "%x: %x\n", h, common.LeftPadBytes(item, 32))
+		}
+
 	}
 }
-- 
GitLab