-
Notifications
You must be signed in to change notification settings - Fork 6
EIP 214 - First draft #22
Changes from 1 commit
4c06bdf
ac64cad
6011a28
9e6882e
10d1730
c91dd38
f0ac799
76ae058
3ab0fe3
2a577cf
b262d8a
d90fcb8
933cadb
61b178b
5c3969f
ca44ce1
7398d54
08ef773
282cfdd
600a074
b971191
bafb553
37e20ae
e0d4a7d
3373805
da71442
3fabc96
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,17 +17,20 @@ | |
package core | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"math/big" | ||
|
||
"github.com/eth-classic/go-ethereum/common" | ||
"github.com/eth-classic/go-ethereum/core/vm" | ||
"github.com/eth-classic/go-ethereum/crypto" | ||
"github.com/ethereum/go-ethereum/params" | ||
) | ||
|
||
var ( | ||
callCreateDepthMax = 1024 // limit call/create stack | ||
errCallCreateDepth = fmt.Errorf("Max call depth exceeded (%d)", callCreateDepthMax) | ||
ErrDepth = errors.New("max call depth exceeded") | ||
) | ||
|
||
// Call executes within the given contract | ||
|
@@ -52,6 +55,13 @@ func DelegateCall(env vm.Environment, caller vm.ContractRef, addr common.Address | |
return ret, err | ||
} | ||
|
||
//StaticCall | ||
func StaticCall(env vm.Environment, caller vm.ContractRef, addr common.Address, input []byte, gas, gasPrice *big.Int) (ret []byte, err error) { | ||
callerAddr := caller.Address() | ||
ret, err = execStaticCall(env, caller, &callerAddr, input, gas, gasPrice) | ||
return ret, err | ||
} | ||
|
||
// Create creates a new contract with the given code | ||
func Create(env vm.Environment, caller vm.ContractRef, code []byte, gas, gasPrice, value *big.Int) (ret []byte, address common.Address, err error) { | ||
ret, address, err = exec(env, caller, nil, nil, crypto.Keccak256Hash(code), nil, code, gas, gasPrice, value) | ||
|
@@ -174,6 +184,52 @@ func execDelegateCall(env vm.Environment, caller vm.ContractRef, originAddr, toA | |
return ret, addr, err | ||
} | ||
|
||
// StaticCall executes the contract associated with the addr with the given input | ||
// as parameters while disallowing any modifications to the state during the call. | ||
// Opcodes that attempt to perform such modifications will result in exceptions | ||
// instead of performing the modifications. | ||
func execStaticCall(env vm.Environment, caller vm.ContractRef, addr *common.Address, input []byte, gas, gasPrice *big.Int) (ret []byte, err error) { | ||
evm := env.Vm() | ||
|
||
//evm.vmConfig.NoRecursion not necessary? | ||
if env.Depth() > 0 { | ||
return nil, nil | ||
} | ||
|
||
// Fail if we're trying to execute above the call depth limit | ||
if env.Depth() > int(params.CallCreateDepth) { | ||
return nil, ErrDepth | ||
} | ||
|
||
//Account Ref Correct? | ||
var ( | ||
to = env.Db().GetAccount(*addr) | ||
snapshot = env.SnapshotDatabase() | ||
) | ||
// Initialise a new contract and set the code that is to be used by the EVM. | ||
// The contract is a scoped environment for this execution context only. | ||
contract := vm.NewContract(caller, to, new(big.Int), gas, gasPrice).AsDelegates | ||
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this copied from ETH? I don't see many of these lines referencing ETC variables |
||
|
||
// We do an AddBalance of zero here, just in order to trigger a touch. | ||
// This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium, | ||
// but is the correct thing to do and matters on other networks, in tests, and potential | ||
// future scenarios | ||
evm.StateDB.AddBalance(addr, bigZero) | ||
|
||
// When an error was returned by the EVM or when setting the creation code | ||
// above we revert to the snapshot and consume any gas remaining. Additionally | ||
// when we're in Homestead this also counts for code storage gas errors. | ||
ret, err = run(evm, contract, input, true) | ||
if err != nil { | ||
evm.StateDB.RevertToSnapshot(snapshot) | ||
if err != errExecutionReverted { | ||
contract.UseGas(contract.Gas) | ||
} | ||
} | ||
return ret, contract.Gas, err | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. function signature has (ret []byte, err error) return, should be only two values |
||
} | ||
|
||
// generic transfer method | ||
func Transfer(from, to vm.Account, amount *big.Int) { | ||
from.SubBalance(amount) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,13 +17,17 @@ | |
package vm | ||
|
||
import ( | ||
"errors" | ||
"math/big" | ||
|
||
"github.com/eth-classic/go-ethereum/common" | ||
"github.com/eth-classic/go-ethereum/crypto" | ||
) | ||
|
||
var callStipend = big.NewInt(2300) // Free gas given at beginning of call. | ||
var ( | ||
callStipend = big.NewInt(2300) // Free gas given at beginning of call. | ||
errExecutionReverted = errors.New("evm: execution reverted") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is for EIP140 REVERT opcode, which isn't currently implemented in development |
||
) | ||
|
||
type instrFn func(instr instruction, pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack) | ||
|
||
|
@@ -511,6 +515,23 @@ func opDelegateCall(instr instruction, pc *uint64, env Environment, contract *Co | |
} | ||
} | ||
|
||
func opStaticCall(pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack) ([]byte, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ETC doesn't handle returns on these functions, you should match the function signature from related calls in this file to allow you to attach it to the JumpTable reference of STATICCALL |
||
// Pop other call parameters. | ||
gas, addr, inOffset, inSize, outOffset, outSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() | ||
toAddr := common.BigToAddress(addr) | ||
// Get arguments from the memory. | ||
args := memory.Get(inOffset.Int64(), inSize.Int64()) | ||
|
||
ret, err := env.StaticCall(contract, toAddr, args, gas) | ||
if err != nil { | ||
stack.push(new(big.Int)) | ||
} else { | ||
stack.push(big.NewInt(1)) | ||
memory.Set(outOffset.Uint64(), outSize.Uint64(), ret) | ||
} | ||
return ret, nil | ||
} | ||
|
||
func opSuicide(instr instruction, pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack) { | ||
balance := env.Db().GetBalance(contract.Address()) | ||
env.Db().AddBalance(common.BigToAddress(stack.pop()), balance) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -164,6 +164,7 @@ func newJumpTable(ruleset RuleSet, blockNumber *big.Int) vmJumpTable { | |
jumpTable[JUMP] = jumpPtr{nil, true} | ||
jumpTable[JUMPI] = jumpPtr{nil, true} | ||
jumpTable[STOP] = jumpPtr{nil, true} | ||
jumpTable[STATICCALL] = jumpPtr{nil, true} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should attach the opStaticCall function here Edit: also it should be targeted toward Atlantis only, which you will be able to do once the refactor PR is merged |
||
|
||
return jumpTable | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -169,6 +169,9 @@ func (evm *EVM) Run(contract *Contract, input []byte) (ret []byte, err error) { | |
fallthrough | ||
case STOP: // Stop the contract | ||
return nil, nil | ||
case STATICCALL: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. STATICCALL should not exit the vm execution (or somebody correct me) these lines either way should be removed once you attach the function to JumpTable[STATICCALL] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You need to also dynamically set gas and size in this file in the calculateGasAndSize(...) function Edit: Use Call as reference, as well as the ETH implementation for calculating gas of the call |
||
//Call StaticCall | ||
return opStaticCall(nil, evm.env, contract, mem, stack) | ||
} | ||
} | ||
} else { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,39 @@ | ||
module github.com/eth-classic/go-ethereum | ||
|
||
require ( | ||
github.com/allegro/bigcache v1.2.0 // indirect | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why was it necessary to update the go modules? |
||
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708 // indirect | ||
github.com/boltdb/bolt v1.3.1 | ||
github.com/davecgh/go-spew v1.1.1 | ||
github.com/deckarep/golang-set v1.7.1 // indirect | ||
github.com/denisbrodbeck/machineid v0.8.0 //mark | ||
github.com/edsrzf/mmap-go v1.0.0 // indirect | ||
github.com/elastic/gosigar v0.10.1 // indirect | ||
github.com/eth-classic/benchmark v0.0.0-20190401191651-0f5bf26f7cd8 | ||
github.com/eth-classic/ethash v0.0.0-20190401191819-b3fdb17512de | ||
github.com/ethereum/go-ethereum v1.8.27 | ||
github.com/fatih/color v1.7.0 | ||
github.com/fjl/memsize v0.0.0-20180929194037-2a09253e352a // indirect | ||
github.com/gizak/termui v2.2.0+incompatible | ||
github.com/go-stack/stack v1.8.0 // indirect | ||
github.com/golang/protobuf v1.3.1 // indirect | ||
github.com/golang/snappy v0.0.1 // indirect | ||
github.com/hashicorp/golang-lru v0.5.1 | ||
github.com/huin/goupnp v1.0.0 | ||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 // indirect | ||
github.com/influxdata/influxdb v1.7.6 // indirect | ||
github.com/jackpal/go-nat-pmp v1.0.1 | ||
github.com/karalabe/hid v0.0.0-20190507082517-9e0a1cda7275 // indirect | ||
github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983 | ||
github.com/maruel/panicparse v1.1.1 // indirect | ||
github.com/mattn/go-colorable v0.1.1 // indirect | ||
github.com/mattn/go-isatty v0.0.7 // indirect | ||
github.com/mitchellh/go-wordwrap v1.0.0 // indirect | ||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect | ||
github.com/naoina/go-stringutil v0.1.0 // indirect | ||
github.com/naoina/toml v0.1.1 // indirect | ||
github.com/nsf/termbox-go v0.0.0-20190325093121-288510b9734e // indirect | ||
github.com/pborman/uuid v1.2.0 // indirect | ||
github.com/peterh/liner v1.1.0 | ||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a | ||
github.com/rjeczalik/notify v0.9.1 | ||
|
@@ -29,11 +44,13 @@ require ( | |
github.com/syndtr/goleveldb v0.0.0-20171214120811-34011bf325bc | ||
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 | ||
golang.org/x/net v0.0.0-20190419010253-1f3472d942ba | ||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 // indirect | ||
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a | ||
golang.org/x/tools v0.0.0-20190418235243-4796d4bd3df0 | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 | ||
gopkg.in/fatih/set.v0 v0.1.0 | ||
gopkg.in/karalabe/cookiejar.v2 v2.0.0-20150724131613-8dcd6a7f4951 | ||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190213234257-ec84240a7772 // indirect | ||
gopkg.in/sourcemap.v1 v1.0.5 // indirect | ||
gopkg.in/urfave/cli.v1 v1.17.0 | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this needed? Can you either just make the previous line usable for both or make it so that error prints the max depth for staticcall? A side note you should probably follow casing standards and start with a lowercase for this variable if it is needed.