diff options
author | Gustav Simonsson <gustav.simonsson@gmail.com> | 2015-11-27 22:40:29 +0800 |
---|---|---|
committer | Jeffrey Wilcke <geffobscura@gmail.com> | 2016-02-18 17:08:11 +0800 |
commit | 371871d685d54b916aef28de689d6f0af7822083 (patch) | |
tree | e704b02ba2ffd2d1164001885fba15106b0f7d94 /core/vm/vm.go | |
parent | aa36a6ae4f24f07e2c470a21c93ff37ad5861982 (diff) | |
download | go-tangerine-371871d685d54b916aef28de689d6f0af7822083.tar.gz go-tangerine-371871d685d54b916aef28de689d6f0af7822083.tar.zst go-tangerine-371871d685d54b916aef28de689d6f0af7822083.zip |
parmas, crypto, core, core/vm: homestead consensus protocol changes
* change gas cost for contract creating txs
* invalidate signature with s value greater than secp256k1 N / 2
* OOG contract creation if not enough gas to store code
* new difficulty adjustment algorithm
* new DELEGATECALL op code
Diffstat (limited to 'core/vm/vm.go')
-rw-r--r-- | core/vm/vm.go | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/core/vm/vm.go b/core/vm/vm.go index 0c6bbcd42..863b2cc0d 100644 --- a/core/vm/vm.go +++ b/core/vm/vm.go @@ -160,7 +160,6 @@ func (self *Vm) Run(contract *Contract, input []byte) (ret []byte, err error) { // Get the memory location of pc op = contract.GetOp(pc) - // calculate the new memory size and gas price for the current executing opcode newMemSize, cost, err = calculateGasAndSize(self.env, contract, caller, op, statedb, mem, stack) if err != nil { @@ -177,7 +176,6 @@ func (self *Vm) Run(contract *Contract, input []byte) (ret []byte, err error) { mem.Resize(newMemSize.Uint64()) // Add a log message self.log(pc, op, contract.Gas, cost, mem, stack, contract, nil) - if opPtr := jumpTable[op]; opPtr.valid { if opPtr.fn != nil { opPtr.fn(instruction{}, &pc, self.env, contract, mem, stack) @@ -201,6 +199,35 @@ func (self *Vm) Run(contract *Contract, input []byte) (ret []byte, err error) { continue } + case CREATE: + var ( + value = stack.pop() + offset, size = stack.pop(), stack.pop() + input = mem.Get(offset.Int64(), size.Int64()) + gas = new(big.Int).Set(contract.Gas) + addr common.Address + ret []byte + suberr error + ) + contract.UseGas(contract.Gas) + ret, addr, suberr = self.env.Create(contract, input, gas, contract.Price, value) + if suberr != nil { + stack.push(new(big.Int)) + } else { + // gas < len(ret) * Createinstr.dataGas == NO_CODE + dataGas := big.NewInt(int64(len(ret))) + dataGas.Mul(dataGas, params.CreateDataGas) + if contract.UseGas(dataGas) { + self.env.Db().SetCode(addr, ret) + } else { + if params.IsHomestead(self.env.BlockNumber()) { + stack.push(new(big.Int)) + return nil, CodeStoreOutOfGasError + } + } + stack.push(addr.Big()) + } + case RETURN: offset, size := stack.pop(), stack.pop() ret := mem.GetPtr(offset.Int64(), size.Int64()) @@ -346,6 +373,13 @@ func calculateGasAndSize(env Environment, contract *Contract, caller ContractRef y := calcMemSize(stack.data[stack.len()-4], stack.data[stack.len()-5]) newMemSize = common.BigMax(x, y) + case DELEGATECALL: + gas.Add(gas, stack.data[stack.len()-1]) + + x := calcMemSize(stack.data[stack.len()-5], stack.data[stack.len()-6]) + y := calcMemSize(stack.data[stack.len()-3], stack.data[stack.len()-4]) + + newMemSize = common.BigMax(x, y) } quadMemGas(mem, newMemSize, gas) |