aboutsummaryrefslogtreecommitdiffstats
path: root/ethchain/vm.go
diff options
context:
space:
mode:
Diffstat (limited to 'ethchain/vm.go')
-rw-r--r--ethchain/vm.go77
1 files changed, 62 insertions, 15 deletions
diff --git a/ethchain/vm.go b/ethchain/vm.go
index ebdc58659..e17264697 100644
--- a/ethchain/vm.go
+++ b/ethchain/vm.go
@@ -5,6 +5,7 @@ import (
"fmt"
"github.com/ethereum/eth-go/ethutil"
_ "github.com/obscuren/secp256k1-go"
+ "math"
_ "math"
"math/big"
)
@@ -18,6 +19,7 @@ var (
GasCreate = big.NewInt(100)
GasCall = big.NewInt(20)
GasMemory = big.NewInt(1)
+ GasData = big.NewInt(5)
GasTx = big.NewInt(500)
)
@@ -116,9 +118,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
gas.Add(gas, amount)
}
+ var newMemSize uint64 = 0
switch op {
- case SHA3:
- setStepGasUsage(GasSha)
case SLOAD:
setStepGasUsage(GasSLoad)
case SSTORE:
@@ -135,27 +136,61 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
setStepGasUsage(new(big.Int).Mul(mult, GasSStore))
case BALANCE:
setStepGasUsage(GasBalance)
- case CREATE:
+ case MSTORE:
+ require(2)
+ newMemSize = stack.Peek().Uint64() + 32
+ case MSTORE8:
+ require(2)
+ newMemSize = stack.Peek().Uint64() + 1
+ case RETURN:
+ require(2)
+
+ newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-2].Uint64()
+ case SHA3:
+ require(2)
+
+ setStepGasUsage(GasSha)
+
+ newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-2].Uint64()
+ case CALLDATACOPY:
require(3)
- args := stack.Get(big.NewInt(3))
- initSize := new(big.Int).Add(args[1], args[0])
+ newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-3].Uint64()
+ case CODECOPY:
+ require(3)
- setStepGasUsage(CalculateTxGas(initSize))
+ newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-3].Uint64()
case CALL:
+ require(7)
setStepGasUsage(GasCall)
- case MLOAD, MSIZE, MSTORE8, MSTORE:
- setStepGasUsage(GasMemory)
+
+ 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()
+
+ newMemSize = uint64(math.Max(float64(x), float64(y)))
+ case CREATE:
+ require(3)
+ setStepGasUsage(GasCreate)
+
+ newMemSize = stack.data[stack.Len()-2].Uint64() + stack.data[stack.Len()-3].Uint64()
default:
setStepGasUsage(GasStep)
}
+ newMemSize = (newMemSize + 31) / 32 * 32
+ if newMemSize > uint64(mem.Len()) {
+ m := GasMemory.Uint64() * (newMemSize - uint64(mem.Len())) / 32
+ setStepGasUsage(big.NewInt(int64(m)))
+ }
+
if !closure.UseGas(gas) {
ethutil.Config.Log.Debugln("Insufficient gas", closure.Gas, gas)
return closure.Return(nil), fmt.Errorf("insufficient gas %v %v", closure.Gas, gas)
}
+ mem.Resize(newMemSize)
+
switch op {
case LOG:
stack.Print()
@@ -340,6 +375,23 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
case CALLDATACOPY:
case CODESIZE:
case CODECOPY:
+ var (
+ size = int64(len(closure.Script))
+ mOff = stack.Pop().Int64()
+ cOff = stack.Pop().Int64()
+ l = stack.Pop().Int64()
+ )
+
+ if cOff > size {
+ cOff = 0
+ l = 0
+ } else if cOff+l > size {
+ l = 0
+ }
+
+ code := closure.Script[cOff : cOff+l]
+
+ mem.Set(mOff, l, code)
case GASPRICE:
stack.Push(closure.Price)
@@ -448,7 +500,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
// Transfer all remaining gas to the new
// contract so it may run the init script
gas := new(big.Int).Set(closure.Gas)
- closure.UseGas(gas)
+ //closure.UseGas(gas)
// Create the closure
c := NewClosure(closure.callee,
@@ -498,12 +550,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
if contract != nil {
// Prepay for the gas
- // If gas is set to 0 use all remaining gas for the next call
- if gas.Cmp(big.NewInt(0)) == 0 {
- // Copy
- gas = new(big.Int).Set(closure.Gas)
- }
- closure.UseGas(gas)
+ //closure.UseGas(gas)
// Add the value to the state object
contract.AddAmount(value)