Removed value from closure.

This commit is contained in:
obscuren 2014-05-08 14:20:45 +02:00
parent 554f4f6f7d
commit f0440e85dc
4 changed files with 21 additions and 15 deletions

View File

@ -24,20 +24,18 @@ type Closure struct {
Gas *big.Int Gas *big.Int
Price *big.Int Price *big.Int
Value *big.Int
Args []byte Args []byte
} }
// Create a new closure for the given data items // Create a new closure for the given data items
func NewClosure(callee, object *StateObject, script []byte, state *State, gas, price, val *big.Int) *Closure { func NewClosure(callee, object *StateObject, script []byte, state *State, gas, price *big.Int) *Closure {
c := &Closure{callee: callee, object: object, Script: script, State: state, Args: nil} c := &Closure{callee: callee, object: object, Script: script, State: state, Args: nil}
// In most cases gas, price and value are pointers to transaction objects // In most cases gas, price and value are pointers to transaction objects
// and we don't want the transaction's values to change. // and we don't want the transaction's values to change.
c.Gas = new(big.Int).Set(gas) c.Gas = new(big.Int).Set(gas)
c.Price = new(big.Int).Set(price) c.Price = new(big.Int).Set(price)
c.Value = new(big.Int).Set(val)
return c return c
} }

View File

@ -323,7 +323,7 @@ func (sm *StateManager) EvalScript(script []byte, object *StateObject, tx *Trans
return return
} }
closure := NewClosure(account, object, script, sm.procState, tx.Gas, tx.GasPrice, tx.Value) closure := NewClosure(account, object, script, sm.procState, tx.Gas, tx.GasPrice)
vm := NewVm(sm.procState, sm, RuntimeVars{ vm := NewVm(sm.procState, sm, RuntimeVars{
Origin: account.Address(), Origin: account.Address(),
BlockNumber: block.BlockInfo().Number, BlockNumber: block.BlockInfo().Number,

View File

@ -97,8 +97,8 @@ const (
// 0xf0 range - closures // 0xf0 range - closures
oCREATE = 0xf0 oCREATE = 0xf0
oCALL = 0xf2 oCALL = 0xf1
oRETURN = 0xf3 oRETURN = 0xf2
// 0x70 range - other // 0x70 range - other
oLOG = 0xfe // XXX Unofficial oLOG = 0xfe // XXX Unofficial

View File

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
_ "github.com/obscuren/secp256k1-go" _ "github.com/obscuren/secp256k1-go"
"log"
_ "math" _ "math"
"math/big" "math/big"
) )
@ -96,7 +95,6 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
if ethutil.Config.Debug { if ethutil.Config.Debug {
ethutil.Config.Log.Debugf("# op\n") ethutil.Config.Log.Debugf("# op\n")
} }
fmt.Println(closure.Script) fmt.Println(closure.Script)
for { for {
@ -320,13 +318,12 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
case oADDRESS: case oADDRESS:
stack.Push(ethutil.BigD(closure.Object().Address())) stack.Push(ethutil.BigD(closure.Object().Address()))
case oBALANCE: case oBALANCE:
stack.Push(closure.Value) stack.Push(closure.object.Amount)
case oORIGIN: case oORIGIN:
stack.Push(ethutil.BigD(vm.vars.Origin)) stack.Push(ethutil.BigD(vm.vars.Origin))
case oCALLER: case oCALLER:
stack.Push(ethutil.BigD(closure.Callee().Address())) stack.Push(ethutil.BigD(closure.Callee().Address()))
case oCALLVALUE: case oCALLVALUE:
log.Println("Value:", vm.vars.Value)
stack.Push(vm.vars.Value) stack.Push(vm.vars.Value)
case oCALLDATALOAD: case oCALLDATALOAD:
require(1) require(1)
@ -406,13 +403,15 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
require(1) require(1)
pc = stack.Pop() pc = stack.Pop()
// Reduce pc by one because of the increment that's at the end of this for loop // Reduce pc by one because of the increment that's at the end of this for loop
pc.Sub(pc, ethutil.Big1) //pc.Sub(pc, ethutil.Big1)
continue
case oJUMPI: case oJUMPI:
require(2) require(2)
cond, pos := stack.Popn() cond, pos := stack.Popn()
if cond.Cmp(ethutil.BigTrue) == 0 { if cond.Cmp(ethutil.BigTrue) == 0 {
pc = pos pc = pos
pc.Sub(pc, ethutil.Big1) //pc.Sub(pc, ethutil.Big1)
continue
} }
case oPC: case oPC:
stack.Push(pc) stack.Push(pc)
@ -441,8 +440,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
contract.initScript, contract.initScript,
vm.state, vm.state,
gas, gas,
closure.Price, closure.Price)
value)
// Call the closure and set the return value as // Call the closure and set the return value as
// main script. // main script.
closure.Script, err = closure.Call(vm, nil, hook) closure.Script, err = closure.Call(vm, nil, hook)
@ -469,10 +467,13 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
break break
} }
// Get the arguments from the memory // Get the arguments from the memory
args := mem.Get(inOffset.Int64(), inSize.Int64()) args := mem.Get(inOffset.Int64(), inSize.Int64())
// Fetch the contract which will serve as the closure body // Fetch the contract which will serve as the closure body
contract := vm.state.GetContract(addr.Bytes()) contract := vm.state.GetContract(addr.Bytes())
fmt.Println("before", contract.Amount)
if contract != nil { if contract != nil {
// Prepay for the gas // Prepay for the gas
@ -482,8 +483,12 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
gas = new(big.Int).Set(closure.Gas) gas = new(big.Int).Set(closure.Gas)
} }
closure.Gas.Sub(closure.Gas, gas) closure.Gas.Sub(closure.Gas, gas)
// Add the value to the state object
contract.AddAmount(value)
// Create a new callable closure // Create a new callable closure
closure := NewClosure(closure.Object(), contract, contract.script, vm.state, gas, closure.Price, value) closure := NewClosure(closure.Object(), contract, contract.script, vm.state, gas, closure.Price)
// Executer the closure and get the return value (if any) // Executer the closure and get the return value (if any)
ret, err := closure.Call(vm, args, hook) ret, err := closure.Call(vm, args, hook)
if err != nil { if err != nil {
@ -496,6 +501,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
vm.stateManager.manifest.AddObjectChange(contract) vm.stateManager.manifest.AddObjectChange(contract)
} }
vm.state.SetStateObject(contract)
fmt.Println("after", contract.Amount)
mem.Set(retOffset.Int64(), retSize.Int64(), ret) mem.Set(retOffset.Int64(), retSize.Int64(), ret)
} else { } else {
ethutil.Config.Log.Debugf("Contract %x not found\n", addr.Bytes()) ethutil.Config.Log.Debugf("Contract %x not found\n", addr.Bytes())