Fixed call
This commit is contained in:
parent
7e6684d926
commit
9104dcc29c
|
@ -53,7 +53,8 @@ type Vm struct {
|
||||||
|
|
||||||
type RuntimeVars struct {
|
type RuntimeVars struct {
|
||||||
Origin []byte
|
Origin []byte
|
||||||
BlockNumber uint64
|
Block *Block
|
||||||
|
BlockNumber *big.Int
|
||||||
PrevHash []byte
|
PrevHash []byte
|
||||||
Coinbase []byte
|
Coinbase []byte
|
||||||
Time int64
|
Time int64
|
||||||
|
@ -90,14 +91,14 @@ var isRequireError = false
|
||||||
func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err error) {
|
func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err error) {
|
||||||
// Recover from any require exception
|
// Recover from any require exception
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil /*&& isRequireError*/ {
|
if r := recover(); r != nil {
|
||||||
ret = closure.Return(nil)
|
ret = closure.Return(nil)
|
||||||
err = fmt.Errorf("%v", r)
|
err = fmt.Errorf("%v", r)
|
||||||
fmt.Println("vm err", err)
|
fmt.Println("vm err", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ethutil.Config.Log.Debugf("[VM] Running %x\n", closure.object.Address())
|
ethutil.Config.Log.Debugf("[VM] (~) %x gas: %v (d) %x\n", closure.object.Address(), closure.Gas, closure.Args)
|
||||||
|
|
||||||
// Memory for the current closure
|
// Memory for the current closure
|
||||||
mem := &Memory{}
|
mem := &Memory{}
|
||||||
|
@ -128,7 +129,6 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
||||||
op := OpCode(val.Uint())
|
op := OpCode(val.Uint())
|
||||||
|
|
||||||
vm.Printf("(pc) %-3d -o- %-14s", 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)
|
gas := new(big.Int)
|
||||||
addStepGasUsage := func(amount *big.Int) {
|
addStepGasUsage := func(amount *big.Int) {
|
||||||
|
@ -188,7 +188,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
||||||
case CALL:
|
case CALL:
|
||||||
require(7)
|
require(7)
|
||||||
gas.Set(GasCall)
|
gas.Set(GasCall)
|
||||||
addStepGasUsage(stack.data[stack.Len()-2])
|
addStepGasUsage(stack.data[stack.Len()-1])
|
||||||
|
|
||||||
x := stack.data[stack.Len()-6].Uint64() + stack.data[stack.Len()-7].Uint64()
|
x := stack.data[stack.Len()-6].Uint64() + stack.data[stack.Len()-7].Uint64()
|
||||||
y := stack.data[stack.Len()-4].Uint64() + stack.data[stack.Len()-5].Uint64()
|
y := stack.data[stack.Len()-4].Uint64() + stack.data[stack.Len()-5].Uint64()
|
||||||
|
@ -208,9 +208,11 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
||||||
}
|
}
|
||||||
|
|
||||||
if !closure.UseGas(gas) {
|
if !closure.UseGas(gas) {
|
||||||
ethutil.Config.Log.Debugln("Insufficient gas", closure.Gas, gas)
|
err := fmt.Errorf("Insufficient gas for %v. req %v has %v", op, gas, closure.Gas)
|
||||||
|
|
||||||
return closure.Return(nil), fmt.Errorf("insufficient gas %v %v", closure.Gas, gas)
|
closure.UseGas(closure.Gas)
|
||||||
|
|
||||||
|
return closure.Return(nil), err
|
||||||
}
|
}
|
||||||
|
|
||||||
vm.Printf(" (g) %-3v (%v)", gas, closure.Gas)
|
vm.Printf(" (g) %-3v (%v)", gas, closure.Gas)
|
||||||
|
@ -431,7 +433,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
||||||
|
|
||||||
vm.Printf(" => %d", l)
|
vm.Printf(" => %d", l)
|
||||||
case CALLDATACOPY:
|
case CALLDATACOPY:
|
||||||
|
panic("not implemented")
|
||||||
case CODESIZE:
|
case CODESIZE:
|
||||||
|
stack.Push(big.NewInt(int64(len(closure.Script))))
|
||||||
case CODECOPY:
|
case CODECOPY:
|
||||||
var (
|
var (
|
||||||
size = int64(len(closure.Script))
|
size = int64(len(closure.Script))
|
||||||
|
@ -461,7 +465,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
||||||
case TIMESTAMP:
|
case TIMESTAMP:
|
||||||
stack.Push(big.NewInt(vm.vars.Time))
|
stack.Push(big.NewInt(vm.vars.Time))
|
||||||
case NUMBER:
|
case NUMBER:
|
||||||
stack.Push(big.NewInt(int64(vm.vars.BlockNumber)))
|
stack.Push(vm.vars.BlockNumber)
|
||||||
case DIFFICULTY:
|
case DIFFICULTY:
|
||||||
stack.Push(vm.vars.Diff)
|
stack.Push(vm.vars.Diff)
|
||||||
case GASLIMIT:
|
case GASLIMIT:
|
||||||
|
@ -595,10 +599,12 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
||||||
case CALL:
|
case CALL:
|
||||||
// TODO RE-WRITE
|
// TODO RE-WRITE
|
||||||
require(7)
|
require(7)
|
||||||
// Closure addr
|
|
||||||
addr := stack.Pop()
|
vm.Endl()
|
||||||
|
|
||||||
|
gas := stack.Pop()
|
||||||
// Pop gas and value of the stack.
|
// Pop gas and value of the stack.
|
||||||
gas, value := stack.Popn()
|
value, addr := stack.Popn()
|
||||||
// Pop input size and offset
|
// Pop input size and offset
|
||||||
inSize, inOffset := stack.Popn()
|
inSize, inOffset := stack.Popn()
|
||||||
// Pop return size and offset
|
// Pop return size and offset
|
||||||
|
@ -607,37 +613,34 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
||||||
// 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())
|
||||||
|
|
||||||
snapshot := vm.state.Snapshot()
|
//snapshot := vm.state.Snapshot()
|
||||||
|
|
||||||
closure.object.Nonce += 1
|
|
||||||
if closure.object.Amount.Cmp(value) < 0 {
|
if closure.object.Amount.Cmp(value) < 0 {
|
||||||
ethutil.Config.Log.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Amount)
|
ethutil.Config.Log.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Amount)
|
||||||
|
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
} else {
|
} else {
|
||||||
// Fetch the contract which will serve as the closure body
|
stateObject := vm.state.GetOrNewStateObject(addr.Bytes())
|
||||||
contract := vm.state.GetStateObject(addr.Bytes())
|
|
||||||
|
|
||||||
if contract != nil {
|
closure.object.SubAmount(value)
|
||||||
// Add the value to the state object
|
// Add the value to the state object
|
||||||
contract.AddAmount(value)
|
stateObject.AddAmount(value)
|
||||||
|
|
||||||
// Create a new callable closure
|
// Create a new callable closure
|
||||||
closure := NewClosure(closure, contract, contract.script, vm.state, gas, closure.Price)
|
closure := NewClosure(closure, stateObject, stateObject.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 {
|
||||||
stack.Push(ethutil.BigFalse)
|
|
||||||
// Reset the changes applied this object
|
|
||||||
vm.state.Revert(snapshot)
|
|
||||||
} else {
|
|
||||||
stack.Push(ethutil.BigTrue)
|
|
||||||
|
|
||||||
mem.Set(retOffset.Int64(), retSize.Int64(), ret)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ethutil.Config.Log.Debugf("Contract %x not found\n", addr.Bytes())
|
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
|
|
||||||
|
// Reset the changes applied this object
|
||||||
|
vm.state.ResetStateObject(stateObject)
|
||||||
|
|
||||||
|
ethutil.Config.Log.Debugf("Closure execution failed. %v\n", err)
|
||||||
|
} else {
|
||||||
|
stack.Push(ethutil.BigTrue)
|
||||||
|
|
||||||
|
mem.Set(retOffset.Int64(), retSize.Int64(), ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case RETURN:
|
case RETURN:
|
||||||
|
@ -645,6 +648,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
||||||
size, offset := stack.Popn()
|
size, offset := stack.Popn()
|
||||||
ret := mem.Get(offset.Int64(), size.Int64())
|
ret := mem.Get(offset.Int64(), size.Int64())
|
||||||
|
|
||||||
|
vm.Printf(" => 0x%x", ret).Endl()
|
||||||
|
|
||||||
return closure.Return(ret), nil
|
return closure.Return(ret), nil
|
||||||
case SUICIDE:
|
case SUICIDE:
|
||||||
require(1)
|
require(1)
|
||||||
|
@ -659,6 +664,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
|
||||||
|
|
||||||
fallthrough
|
fallthrough
|
||||||
case STOP: // Stop the closure
|
case STOP: // Stop the closure
|
||||||
|
vm.Endl()
|
||||||
|
|
||||||
return closure.Return(nil), nil
|
return closure.Return(nil), nil
|
||||||
default:
|
default:
|
||||||
ethutil.Config.Log.Debugf("Invalid opcode %x\n", op)
|
ethutil.Config.Log.Debugf("Invalid opcode %x\n", op)
|
||||||
|
|
Loading…
Reference in New Issue