aboutsummaryrefslogtreecommitdiffstats
path: root/vm
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2015-03-10 00:55:01 +0800
committerobscuren <geffobscura@gmail.com>2015-03-10 00:55:01 +0800
commit8560004f380dc688a1171ad5aeffa593aae41193 (patch)
treefea395acf042b51e97a86e2c4cbcf8c16b2912b7 /vm
parent9723191b19f6ddc12f0c3376ede7529b2d72e6a2 (diff)
parent676a0de58d3d7c508b0eeeff192d2095a46f7382 (diff)
downloaddexon-8560004f380dc688a1171ad5aeffa593aae41193.tar.gz
dexon-8560004f380dc688a1171ad5aeffa593aae41193.tar.zst
dexon-8560004f380dc688a1171ad5aeffa593aae41193.zip
wip
Diffstat (limited to 'vm')
-rw-r--r--vm/address.go18
-rw-r--r--vm/common.go71
-rw-r--r--vm/vm.go261
-rw-r--r--vm/vm_jit.go25
4 files changed, 233 insertions, 142 deletions
diff --git a/vm/address.go b/vm/address.go
index 1c9369ab7..b1345da8f 100644
--- a/vm/address.go
+++ b/vm/address.go
@@ -32,23 +32,23 @@ func PrecompiledContracts() map[string]*PrecompiledAccount {
// SHA256
string(ethutil.LeftPadBytes([]byte{2}, 20)): &PrecompiledAccount{func(l int) *big.Int {
- n := big.NewInt(int64(l+31)/32 + 1)
- n.Mul(n, GasSha256)
- return n
+ n := big.NewInt(int64(l+31) / 32)
+ n.Mul(n, GasSha256Word)
+ return n.Add(n, GasSha256Base)
}, sha256Func},
// RIPEMD160
string(ethutil.LeftPadBytes([]byte{3}, 20)): &PrecompiledAccount{func(l int) *big.Int {
- n := big.NewInt(int64(l+31)/32 + 1)
- n.Mul(n, GasRipemd)
- return n
+ n := big.NewInt(int64(l+31) / 32)
+ n.Mul(n, GasRipemdWord)
+ return n.Add(n, GasRipemdBase)
}, ripemd160Func},
string(ethutil.LeftPadBytes([]byte{4}, 20)): &PrecompiledAccount{func(l int) *big.Int {
- n := big.NewInt(int64(l+31)/32 + 1)
- n.Mul(n, GasMemCpy)
+ n := big.NewInt(int64(l+31) / 32)
+ n.Mul(n, GasIdentityWord)
- return n
+ return n.Add(n, GasIdentityBase)
}, memCpy},
}
}
diff --git a/vm/common.go b/vm/common.go
index 45a7187a9..b391bb8c2 100644
--- a/vm/common.go
+++ b/vm/common.go
@@ -9,6 +9,9 @@ import (
var vmlogger = logger.NewLogger("VM")
+// Global Debug flag indicating Debug VM (full logging)
+var Debug bool
+
type Type byte
const (
@@ -31,26 +34,52 @@ func NewVm(env Environment) VirtualMachine {
}
var (
- GasStep = big.NewInt(1)
- GasSha = big.NewInt(10)
- GasSLoad = big.NewInt(20)
- GasSStore = big.NewInt(100)
- GasSStoreRefund = big.NewInt(100)
- GasBalance = big.NewInt(20)
- GasCreate = big.NewInt(100)
- GasCall = big.NewInt(20)
- GasCreateByte = big.NewInt(5)
- GasSha3Byte = big.NewInt(10)
- GasSha256Byte = big.NewInt(50)
- GasRipemdByte = big.NewInt(50)
- GasMemory = big.NewInt(1)
- GasData = big.NewInt(5)
- GasTx = big.NewInt(500)
- GasLog = big.NewInt(32)
- GasSha256 = big.NewInt(50)
- GasRipemd = big.NewInt(50)
- GasEcrecover = big.NewInt(500)
- GasMemCpy = big.NewInt(1)
+ GasQuickStep = big.NewInt(2)
+ GasFastestStep = big.NewInt(3)
+ GasFastStep = big.NewInt(5)
+ GasMidStep = big.NewInt(8)
+ GasSlowStep = big.NewInt(10)
+ GasExtStep = big.NewInt(20)
+
+ GasStorageGet = big.NewInt(50)
+ GasStorageAdd = big.NewInt(20000)
+ GasStorageMod = big.NewInt(5000)
+ GasLogBase = big.NewInt(375)
+ GasLogTopic = big.NewInt(375)
+ GasLogByte = big.NewInt(8)
+ GasCreate = big.NewInt(32000)
+ GasCreateByte = big.NewInt(200)
+ GasCall = big.NewInt(40)
+ GasCallValueTransfer = big.NewInt(9000)
+ GasStipend = big.NewInt(2300)
+ GasCallNewAccount = big.NewInt(25000)
+ GasReturn = big.NewInt(0)
+ GasStop = big.NewInt(0)
+ GasJumpDest = big.NewInt(1)
+
+ RefundStorage = big.NewInt(15000)
+ RefundSuicide = big.NewInt(24000)
+
+ GasMemWord = big.NewInt(3)
+ GasQuadCoeffDenom = big.NewInt(512)
+ GasContractByte = big.NewInt(200)
+ GasTransaction = big.NewInt(21000)
+ GasTxDataNonzeroByte = big.NewInt(68)
+ GasTxDataZeroByte = big.NewInt(4)
+ GasTx = big.NewInt(21000)
+ GasExp = big.NewInt(10)
+ GasExpByte = big.NewInt(10)
+
+ GasSha3Base = big.NewInt(30)
+ GasSha3Word = big.NewInt(6)
+ GasSha256Base = big.NewInt(60)
+ GasSha256Word = big.NewInt(12)
+ GasRipemdBase = big.NewInt(600)
+ GasRipemdWord = big.NewInt(12)
+ GasEcrecover = big.NewInt(3000)
+ GasIdentityBase = big.NewInt(15)
+ GasIdentityWord = big.NewInt(3)
+ GasCopyWord = big.NewInt(3)
Pow256 = ethutil.BigPow(2, 256)
@@ -59,6 +88,8 @@ var (
U256 = ethutil.U256
S256 = ethutil.S256
+
+ Zero = ethutil.Big0
)
const MaxCallDepth = 1025
diff --git a/vm/vm.go b/vm/vm.go
index 1f386d47c..3647d7a5e 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -30,11 +30,8 @@ type Vm struct {
func New(env Environment) *Vm {
lt := LogTyPretty
- if ethutil.Config.Diff {
- lt = LogTyDiff
- }
- return &Vm{debug: false, env: env, logTy: lt, Recoverable: true}
+ return &Vm{debug: Debug, env: env, logTy: lt, Recoverable: true}
}
func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
@@ -399,7 +396,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
stack.Push(ethutil.BigD(data))
- self.Printf(" => %x", data)
+ self.Printf(" => (%v) %x", size, data)
// 0x30 range
case ADDRESS:
stack.Push(ethutil.BigD(context.Address()))
@@ -408,7 +405,12 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
case BALANCE:
addr := stack.Pop().Bytes()
- balance := statedb.GetBalance(addr)
+ var balance *big.Int
+ if statedb.GetStateObject(addr) != nil {
+ balance = statedb.GetBalance(addr)
+ } else {
+ balance = base
+ }
stack.Push(balance)
@@ -666,7 +668,6 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
}
addr = ref.Address()
- fmt.Printf("CREATE %X\n", addr)
stack.Push(ethutil.BigD(addr))
}
@@ -691,6 +692,10 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
// Get the arguments from the memory
args := mem.Get(inOffset.Int64(), inSize.Int64())
+ if len(value.Bytes()) > 0 {
+ gas.Add(gas, GasStipend)
+ }
+
var (
ret []byte
err error
@@ -731,6 +736,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
self.Printf(" => (%x) %v", receiver.Address()[:4], balance)
receiver.AddBalance(balance)
+
statedb.Delete(context.Address())
fallthrough
@@ -767,156 +773,211 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
}
}
-func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) {
- gas := new(big.Int)
- addStepGasUsage := func(amount *big.Int) {
- if amount.Cmp(ethutil.Big0) >= 0 {
- gas.Add(gas, amount)
- }
+type req struct {
+ stack int
+ gas *big.Int
+}
+
+var _baseCheck = map[OpCode]req{
+ // Req Stack Gas price
+ ADD: {2, GasFastestStep},
+ LT: {2, GasFastestStep},
+ GT: {2, GasFastestStep},
+ SLT: {2, GasFastestStep},
+ SGT: {2, GasFastestStep},
+ EQ: {2, GasFastestStep},
+ ISZERO: {1, GasFastestStep},
+ SUB: {2, GasFastestStep},
+ AND: {2, GasFastestStep},
+ OR: {2, GasFastestStep},
+ XOR: {2, GasFastestStep},
+ NOT: {1, GasFastestStep},
+ BYTE: {2, GasFastestStep},
+ CALLDATALOAD: {1, GasFastestStep},
+ CALLDATACOPY: {3, GasFastestStep},
+ MLOAD: {1, GasFastestStep},
+ MSTORE: {2, GasFastestStep},
+ MSTORE8: {2, GasFastestStep},
+ CODECOPY: {3, GasFastestStep},
+ MUL: {2, GasFastStep},
+ DIV: {2, GasFastStep},
+ SDIV: {2, GasFastStep},
+ MOD: {2, GasFastStep},
+ SMOD: {2, GasFastStep},
+ SIGNEXTEND: {2, GasFastStep},
+ ADDMOD: {3, GasMidStep},
+ MULMOD: {3, GasMidStep},
+ JUMP: {1, GasMidStep},
+ JUMPI: {2, GasSlowStep},
+ EXP: {2, GasSlowStep},
+ ADDRESS: {0, GasQuickStep},
+ ORIGIN: {0, GasQuickStep},
+ CALLER: {0, GasQuickStep},
+ CALLVALUE: {0, GasQuickStep},
+ CODESIZE: {0, GasQuickStep},
+ GASPRICE: {0, GasQuickStep},
+ COINBASE: {0, GasQuickStep},
+ TIMESTAMP: {0, GasQuickStep},
+ NUMBER: {0, GasQuickStep},
+ CALLDATASIZE: {0, GasQuickStep},
+ DIFFICULTY: {0, GasQuickStep},
+ GASLIMIT: {0, GasQuickStep},
+ POP: {0, GasQuickStep},
+ PC: {0, GasQuickStep},
+ MSIZE: {0, GasQuickStep},
+ GAS: {0, GasQuickStep},
+ BLOCKHASH: {1, GasExtStep},
+ BALANCE: {0, GasExtStep},
+ EXTCODESIZE: {1, GasExtStep},
+ EXTCODECOPY: {4, GasExtStep},
+ SLOAD: {1, GasStorageGet},
+ SSTORE: {2, Zero},
+ SHA3: {1, GasSha3Base},
+ CREATE: {3, GasCreate},
+ CALL: {7, GasCall},
+ CALLCODE: {7, GasCall},
+ JUMPDEST: {0, GasJumpDest},
+ SUICIDE: {1, Zero},
+ RETURN: {2, Zero},
+}
+
+func baseCheck(op OpCode, stack *Stack, gas *big.Int) {
+ if r, ok := _baseCheck[op]; ok {
+ stack.require(r.stack)
+
+ gas.Add(gas, r.gas)
}
+}
+
+func toWordSize(size *big.Int) *big.Int {
+ tmp := new(big.Int)
+ tmp.Add(size, u256(31))
+ tmp.Div(tmp, u256(32))
+ return tmp
+}
- addStepGasUsage(GasStep)
+func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) {
+ var (
+ gas = new(big.Int)
+ newMemSize *big.Int = new(big.Int)
+ )
+ baseCheck(op, stack, gas)
- var newMemSize *big.Int = ethutil.Big0
- var additionalGas *big.Int = new(big.Int)
// Stack Check, memory resize & gas phase
switch op {
- // Stack checks only
- case ISZERO, CALLDATALOAD, POP, JUMP, NOT, EXTCODESIZE, BLOCKHASH: // 1
- stack.require(1)
- case JUMPI, ADD, SUB, DIV, MUL, SDIV, MOD, SMOD, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE, SIGNEXTEND: // 2
- stack.require(2)
- case ADDMOD, MULMOD: // 3
- stack.require(3)
+ case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
+ gas.Set(GasFastestStep)
case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
n := int(op - SWAP1 + 2)
stack.require(n)
+ gas.Set(GasFastestStep)
case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
n := int(op - DUP1 + 1)
stack.require(n)
+ gas.Set(GasFastestStep)
case LOG0, LOG1, LOG2, LOG3, LOG4:
n := int(op - LOG0)
stack.require(n + 2)
- gas.Set(GasLog)
- addStepGasUsage(new(big.Int).Mul(big.NewInt(int64(n)), GasLog))
-
mSize, mStart := stack.Peekn()
- addStepGasUsage(mSize)
+
+ gas.Add(gas, GasLogBase)
+ gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(n)), GasLogTopic))
+ gas.Add(gas, new(big.Int).Mul(mSize, GasLogByte))
newMemSize = calcMemSize(mStart, mSize)
case EXP:
- stack.require(2)
-
- gas.Set(big.NewInt(int64(len(stack.data[stack.Len()-2].Bytes()) + 1)))
- // Gas only
- case STOP:
- gas.Set(ethutil.Big0)
- case SUICIDE:
- stack.require(1)
-
- gas.Set(ethutil.Big0)
- case SLOAD:
- stack.require(1)
-
- gas.Set(GasSLoad)
- // Memory resize & Gas
+ gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(len(stack.data[stack.Len()-2].Bytes()))), GasExpByte))
case SSTORE:
stack.require(2)
- var mult *big.Int
+ var g *big.Int
y, x := stack.Peekn()
val := statedb.GetState(context.Address(), x.Bytes())
if len(val) == 0 && len(y.Bytes()) > 0 {
// 0 => non 0
- mult = ethutil.Big3
+ g = GasStorageAdd
} else if len(val) > 0 && len(y.Bytes()) == 0 {
- statedb.Refund(self.env.Origin(), GasSStoreRefund)
+ statedb.Refund(self.env.Origin(), RefundStorage)
- mult = ethutil.Big0
+ g = GasStorageMod
} else {
// non 0 => non 0 (or 0 => 0)
- mult = ethutil.Big1
+ g = GasStorageMod
+ }
+ gas.Set(g)
+ case SUICIDE:
+ if !statedb.IsDeleted(context.Address()) {
+ statedb.Refund(self.env.Origin(), RefundSuicide)
}
- gas.Set(new(big.Int).Mul(mult, GasSStore))
- case BALANCE:
- stack.require(1)
- gas.Set(GasBalance)
- case MSTORE:
- stack.require(2)
- newMemSize = calcMemSize(stack.Peek(), u256(32))
case MLOAD:
- stack.require(1)
-
newMemSize = calcMemSize(stack.Peek(), u256(32))
case MSTORE8:
- stack.require(2)
newMemSize = calcMemSize(stack.Peek(), u256(1))
+ case MSTORE:
+ newMemSize = calcMemSize(stack.Peek(), u256(32))
case RETURN:
- stack.require(2)
-
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
case SHA3:
- stack.require(2)
- gas.Set(GasSha)
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
- additionalGas.Set(stack.data[stack.Len()-2])
- case CALLDATACOPY:
- stack.require(3)
+ words := toWordSize(stack.data[stack.Len()-2])
+ gas.Add(gas, words.Mul(words, GasSha3Word))
+ case CALLDATACOPY:
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
- additionalGas.Set(stack.data[stack.Len()-3])
- case CODECOPY:
- stack.require(3)
+ words := toWordSize(stack.data[stack.Len()-3])
+ gas.Add(gas, words.Mul(words, GasCopyWord))
+ case CODECOPY:
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
- additionalGas.Set(stack.data[stack.Len()-3])
- case EXTCODECOPY:
- stack.require(4)
+ words := toWordSize(stack.data[stack.Len()-3])
+ gas.Add(gas, words.Mul(words, GasCopyWord))
+ case EXTCODECOPY:
newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4])
- additionalGas.Set(stack.data[stack.Len()-4])
+
+ words := toWordSize(stack.data[stack.Len()-4])
+ gas.Add(gas, words.Mul(words, GasCopyWord))
+
+ case CREATE:
+ newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3])
case CALL, CALLCODE:
- stack.require(7)
- gas.Set(GasCall)
- addStepGasUsage(stack.data[stack.Len()-1])
+ gas.Add(gas, stack.data[stack.Len()-1])
+
+ if op == CALL {
+ if self.env.State().GetStateObject(stack.data[stack.Len()-2].Bytes()) == nil {
+ gas.Add(gas, GasCallNewAccount)
+ }
+ }
+
+ if len(stack.data[stack.Len()-3].Bytes()) > 0 {
+ gas.Add(gas, GasCallValueTransfer)
+ }
x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7])
y := calcMemSize(stack.data[stack.Len()-4], stack.data[stack.Len()-5])
newMemSize = ethutil.BigMax(x, y)
- case CREATE:
- stack.require(3)
- gas.Set(GasCreate)
-
- newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3])
- }
-
- switch op {
- case CALLDATACOPY, CODECOPY, EXTCODECOPY:
- additionalGas.Add(additionalGas, u256(31))
- additionalGas.Div(additionalGas, u256(32))
- addStepGasUsage(additionalGas)
- case SHA3:
- additionalGas.Add(additionalGas, u256(31))
- additionalGas.Div(additionalGas, u256(32))
- additionalGas.Mul(additionalGas, GasSha3Byte)
- addStepGasUsage(additionalGas)
}
if newMemSize.Cmp(ethutil.Big0) > 0 {
- newMemSize.Add(newMemSize, u256(31))
- newMemSize.Div(newMemSize, u256(32))
- newMemSize.Mul(newMemSize, u256(32))
+ newMemSizeWords := toWordSize(newMemSize)
+ newMemSize.Mul(newMemSizeWords, u256(32))
if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
- memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
- memGasUsage.Mul(GasMemory, memGasUsage)
- memGasUsage.Div(memGasUsage, u256(32))
-
- addStepGasUsage(memGasUsage)
+ oldSize := toWordSize(big.NewInt(int64(mem.Len())))
+ pow := new(big.Int).Exp(oldSize, ethutil.Big2, Zero)
+ linCoef := new(big.Int).Mul(oldSize, GasMemWord)
+ quadCoef := new(big.Int).Div(pow, GasQuadCoeffDenom)
+ oldTotalFee := new(big.Int).Add(linCoef, quadCoef)
+
+ pow.Exp(newMemSizeWords, ethutil.Big2, Zero)
+ linCoef = new(big.Int).Mul(newMemSizeWords, GasMemWord)
+ quadCoef = new(big.Int).Div(pow, GasQuadCoeffDenom)
+ newTotalFee := new(big.Int).Add(linCoef, quadCoef)
+
+ gas.Add(gas, new(big.Int).Sub(newTotalFee, oldTotalFee))
}
-
}
return newMemSize, gas
diff --git a/vm/vm_jit.go b/vm/vm_jit.go
index 38cab57da..9d26957f0 100644
--- a/vm/vm_jit.go
+++ b/vm/vm_jit.go
@@ -50,6 +50,7 @@ type RuntimeData struct {
timestamp int64
code *byte
codeSize uint64
+ codeHash i256
}
func hash2llvm(h []byte) i256 {
@@ -180,6 +181,7 @@ func (self *JitVm) Run(me, caller ContextRef, code []byte, value, gas, price *bi
self.data.timestamp = self.env.Time()
self.data.code = getDataPtr(code)
self.data.codeSize = uint64(len(code))
+ self.data.codeHash = hash2llvm(crypto.Sha3(code)) // TODO: Get already computed hash?
jit := C.evmjit_create()
retCode := C.evmjit_run(jit, unsafe.Pointer(&self.data), unsafe.Pointer(self))
@@ -197,12 +199,12 @@ func (self *JitVm) Run(me, caller ContextRef, code []byte, value, gas, price *bi
receiverAddr := llvm2hashRef(bswap(&self.data.address))
receiver := state.GetOrNewStateObject(receiverAddr)
balance := state.GetBalance(me.Address())
- receiver.AddAmount(balance)
+ receiver.AddBalance(balance)
state.Delete(me.Address())
}
}
-
- C.evmjit_destroy(jit);
+
+ C.evmjit_destroy(jit)
return
}
@@ -278,7 +280,7 @@ func env_blockhash(_vm unsafe.Pointer, _number unsafe.Pointer, _result unsafe.Po
}
//export env_call
-func env_call(_vm unsafe.Pointer, _gas unsafe.Pointer, _receiveAddr unsafe.Pointer, _value unsafe.Pointer, inDataPtr unsafe.Pointer, inDataLen uint64, outDataPtr *byte, outDataLen uint64, _codeAddr unsafe.Pointer) bool {
+func env_call(_vm unsafe.Pointer, _gas *int64, _receiveAddr unsafe.Pointer, _value unsafe.Pointer, inDataPtr unsafe.Pointer, inDataLen uint64, outDataPtr *byte, outDataLen uint64, _codeAddr unsafe.Pointer) bool {
vm := (*JitVm)(_vm)
//fmt.Printf("env_call (depth %d)\n", vm.Env().Depth())
@@ -297,8 +299,7 @@ func env_call(_vm unsafe.Pointer, _gas unsafe.Pointer, _receiveAddr unsafe.Point
inData := C.GoBytes(inDataPtr, C.int(inDataLen))
outData := llvm2bytesRef(outDataPtr, outDataLen)
codeAddr := llvm2hash((*i256)(_codeAddr))
- llvmGas := (*i256)(_gas)
- gas := llvm2big(llvmGas)
+ gas := big.NewInt(*_gas)
var out []byte
var err error
if bytes.Equal(codeAddr, receiveAddr) {
@@ -306,7 +307,7 @@ func env_call(_vm unsafe.Pointer, _gas unsafe.Pointer, _receiveAddr unsafe.Point
} else {
out, err = vm.env.CallCode(vm.me, codeAddr, inData, gas, vm.price, value)
}
- *llvmGas = big2llvm(gas)
+ *_gas = gas.Int64()
if err == nil {
copy(outData, out)
return true
@@ -317,7 +318,7 @@ func env_call(_vm unsafe.Pointer, _gas unsafe.Pointer, _receiveAddr unsafe.Point
}
//export env_create
-func env_create(_vm unsafe.Pointer, _gas unsafe.Pointer, _value unsafe.Pointer, initDataPtr unsafe.Pointer, initDataLen uint64, _result unsafe.Pointer) {
+func env_create(_vm unsafe.Pointer, _gas *int64, _value unsafe.Pointer, initDataPtr unsafe.Pointer, initDataLen uint64, _result unsafe.Pointer) {
vm := (*JitVm)(_vm)
value := llvm2big((*i256)(_value))
@@ -325,9 +326,7 @@ func env_create(_vm unsafe.Pointer, _gas unsafe.Pointer, _value unsafe.Pointer,
result := (*i256)(_result)
*result = i256{}
- llvmGas := (*i256)(_gas)
- gas := llvm2big(llvmGas)
-
+ gas := big.NewInt(*_gas)
ret, suberr, ref := vm.env.Create(vm.me, nil, initData, gas, vm.price, value)
if suberr == nil {
dataGas := big.NewInt(int64(len(ret))) // TODO: Nto the best design. env.Create can do it, it has the reference to gas counter
@@ -335,7 +334,7 @@ func env_create(_vm unsafe.Pointer, _gas unsafe.Pointer, _value unsafe.Pointer,
gas.Sub(gas, dataGas)
*result = hash2llvm(ref.Address())
}
- *llvmGas = big2llvm(gas)
+ *_gas = gas.Int64()
}
//export env_log
@@ -358,7 +357,7 @@ func env_log(_vm unsafe.Pointer, dataPtr unsafe.Pointer, dataLen uint64, _topic1
topics = append(topics, llvm2hash((*i256)(_topic4)))
}
- vm.Env().AddLog(state.NewLog(vm.me.Address(), topics, data))
+ vm.Env().AddLog(state.NewLog(vm.me.Address(), topics, data, vm.env.BlockNumber().Uint64()))
}
//export env_extcode