From ca747f268800590ee855b1ce593b61e95d073311 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 11 Apr 2014 08:28:30 -0400 Subject: [PATCH] Added the possibility for debug hooks during closure call --- ethchain/closure.go | 6 +++-- ethchain/state_manager.go | 2 +- ethchain/vm.go | 47 +++++---------------------------------- ethchain/vm_test.go | 2 +- 4 files changed, 12 insertions(+), 45 deletions(-) diff --git a/ethchain/closure.go b/ethchain/closure.go index 8e57a0d03f..3d15f2a990 100644 --- a/ethchain/closure.go +++ b/ethchain/closure.go @@ -69,10 +69,12 @@ func (c *Closure) Address() []byte { return c.object.Address() } -func (c *Closure) Call(vm *Vm, args []byte) []byte { +type DebugHook func(op OpCode) + +func (c *Closure) Call(vm *Vm, args []byte, hook DebugHook) []byte { c.Args = args - return vm.RunClosure(c) + return vm.RunClosure(c, hook) } func (c *Closure) Return(ret []byte) []byte { diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 3043c3d15c..111d2c019e 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -327,7 +327,7 @@ func (sm *StateManager) ProcessContract(contract *Contract, tx *Transaction, blo // XXX Tx data? Could be just an argument to the closure instead txData: nil, }) - closure.Call(vm, nil) + closure.Call(vm, nil, nil) // Update the account (refunds) sm.procState.UpdateAccount(tx.Sender(), caller) diff --git a/ethchain/vm.go b/ethchain/vm.go index dd99ee7905..dce972cc73 100644 --- a/ethchain/vm.go +++ b/ethchain/vm.go @@ -48,7 +48,7 @@ func NewVm(state *State, vars RuntimeVars) *Vm { var Pow256 = ethutil.BigPow(2, 256) -func (vm *Vm) RunClosure(closure *Closure) []byte { +func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) []byte { // If the amount of gas supplied is less equal to 0 if closure.Gas.Cmp(big.NewInt(0)) <= 0 { // TODO Do something @@ -372,7 +372,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte { // Create a new callable closure closure := NewClosure(closure, contract, contract.script, vm.state, gas, value) // Executer the closure and get the return value (if any) - ret := closure.Call(vm, args) + ret := closure.Call(vm, args, hook) mem.Set(retOffset.Int64(), retSize.Int64(), ret) case oRETURN: @@ -404,44 +404,9 @@ func (vm *Vm) RunClosure(closure *Closure) []byte { } pc.Add(pc, ethutil.Big1) + + if hook != nil { + hook(op) + } } } - -/* -func makeInlineTx(addr []byte, value, from, length *big.Int, contract *Contract, state *State) { - ethutil.Config.Log.Debugf(" => creating inline tx %x %v %v %v", addr, value, from, length) - j := int64(0) - dataItems := make([]string, int(length.Uint64())) - for i := from.Int64(); i < length.Int64(); i++ { - dataItems[j] = contract.GetMem(big.NewInt(j)).Str() - j++ - } - - tx := NewTransaction(addr, value, dataItems) - if tx.IsContract() { - contract := MakeContract(tx, state) - state.UpdateContract(contract) - } else { - account := state.GetAccount(tx.Recipient) - account.Amount.Add(account.Amount, tx.Value) - state.UpdateAccount(tx.Recipient, account) - } -} - -// Returns an address from the specified contract's address -func contractMemory(state *State, contractAddr []byte, memAddr *big.Int) *big.Int { - contract := state.GetContract(contractAddr) - if contract == nil { - log.Panicf("invalid contract addr %x", contractAddr) - } - val := state.trie.Get(memAddr.String()) - - // decode the object as a big integer - decoder := ethutil.NewValueFromBytes([]byte(val)) - if decoder.IsNil() { - return ethutil.BigFalse - } - - return decoder.BigInt() -} -*/ diff --git a/ethchain/vm_test.go b/ethchain/vm_test.go index 4075dfbc6b..5a1419c0f9 100644 --- a/ethchain/vm_test.go +++ b/ethchain/vm_test.go @@ -139,5 +139,5 @@ func TestRun4(t *testing.T) { // XXX Tx data? Could be just an argument to the closure instead txData: nil, }) - callerClosure.Call(vm, nil) + callerClosure.Call(vm, nil, nil) }