github.com/codingfuture/orig-energi3@v0.8.4/core/vm/evm.go (about) 1 // Copyright 2018 The Energi Core Authors 2 // Copyright 2014 The go-ethereum Authors 3 // This file is part of the Energi Core library. 4 // 5 // The Energi Core library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The Energi Core library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the Energi Core library. If not, see <http://www.gnu.org/licenses/>. 17 18 package vm 19 20 import ( 21 "math/big" 22 "sync/atomic" 23 "time" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/crypto" 27 "github.com/ethereum/go-ethereum/params" 28 ) 29 30 // emptyCodeHash is used by create to ensure deployment is disallowed to already 31 // deployed contract addresses (relevant after the account abstraction). 32 var emptyCodeHash = crypto.Keccak256Hash(nil) 33 34 type ( 35 // CanTransferFunc is the signature of a transfer guard function 36 CanTransferFunc func(StateDB, common.Address, *big.Int) bool 37 // TransferFunc is the signature of a transfer function 38 TransferFunc func(StateDB, common.Address, common.Address, *big.Int) 39 // GetHashFunc returns the nth block hash in the blockchain 40 // and is used by the BLOCKHASH EVM op code. 41 GetHashFunc func(uint64) common.Hash 42 ) 43 44 // run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter. 45 func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, error) { 46 if contract.CodeAddr != nil { 47 precompiles := PrecompiledContractsHomestead 48 if evm.ChainConfig().IsByzantium(evm.BlockNumber) { 49 precompiles = PrecompiledContractsByzantium 50 } 51 if p := precompiles[*contract.CodeAddr]; p != nil { 52 return RunPrecompiledContract(p, input, contract) 53 } 54 } 55 for _, interpreter := range evm.interpreters { 56 if interpreter.CanRun(contract.Code) { 57 if evm.interpreter != interpreter { 58 // Ensure that the interpreter pointer is set back 59 // to its current value upon return. 60 defer func(i Interpreter) { 61 evm.interpreter = i 62 }(evm.interpreter) 63 evm.interpreter = interpreter 64 } 65 return interpreter.Run(contract, input, readOnly) 66 } 67 } 68 return nil, ErrNoCompatibleInterpreter 69 } 70 71 // Context provides the EVM with auxiliary information. Once provided 72 // it shouldn't be modified. 73 type Context struct { 74 // CanTransfer returns whether the account contains 75 // sufficient ether to transfer the value 76 CanTransfer CanTransferFunc 77 // Transfer transfers ether from one account to the other 78 Transfer TransferFunc 79 // GetHash returns the hash corresponding to n 80 GetHash GetHashFunc 81 82 // Message information 83 Origin common.Address // Provides information for ORIGIN 84 GasPrice *big.Int // Provides information for GASPRICE 85 86 // Block information 87 Coinbase common.Address // Provides information for COINBASE 88 GasLimit uint64 // Provides information for GASLIMIT 89 BlockNumber *big.Int // Provides information for NUMBER 90 Time *big.Int // Provides information for TIME 91 Difficulty *big.Int // Provides information for DIFFICULTY 92 } 93 94 // EVM is the Ethereum Virtual Machine base object and provides 95 // the necessary tools to run a contract on the given state with 96 // the provided context. It should be noted that any error 97 // generated through any of the calls should be considered a 98 // revert-state-and-consume-all-gas operation, no checks on 99 // specific errors should ever be performed. The interpreter makes 100 // sure that any errors generated are to be considered faulty code. 101 // 102 // The EVM should never be reused and is not thread safe. 103 type EVM struct { 104 // Context provides auxiliary blockchain related information 105 Context 106 // StateDB gives access to the underlying state 107 StateDB StateDB 108 // Depth is the current call stack 109 depth int 110 111 // chainConfig contains information about the current chain 112 chainConfig *params.ChainConfig 113 // chain rules contains the chain rules for the current epoch 114 chainRules params.Rules 115 // virtual machine configuration options used to initialise the 116 // evm. 117 vmConfig Config 118 // global (to this context) ethereum virtual machine 119 // used throughout the execution of the tx. 120 interpreters []Interpreter 121 interpreter Interpreter 122 // abort is used to abort the EVM calling operations 123 // NOTE: must be set atomically 124 abort int32 125 // callGasTemp holds the gas available for the current call. This is needed because the 126 // available gas is calculated in gasCall* according to the 63/64 rule and later 127 // applied in opCall*. 128 callGasTemp uint64 129 } 130 131 // NewEVM returns a new EVM. The returned EVM is not thread safe and should 132 // only ever be used *once*. 133 func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM { 134 evm := &EVM{ 135 Context: ctx, 136 StateDB: statedb, 137 vmConfig: vmConfig, 138 chainConfig: chainConfig, 139 chainRules: chainConfig.Rules(ctx.BlockNumber), 140 interpreters: make([]Interpreter, 0, 1), 141 } 142 143 if chainConfig.IsEWASM(ctx.BlockNumber) { 144 // to be implemented by EVM-C and Wagon PRs. 145 // if vmConfig.EWASMInterpreter != "" { 146 // extIntOpts := strings.Split(vmConfig.EWASMInterpreter, ":") 147 // path := extIntOpts[0] 148 // options := []string{} 149 // if len(extIntOpts) > 1 { 150 // options = extIntOpts[1..] 151 // } 152 // evm.interpreters = append(evm.interpreters, NewEVMVCInterpreter(evm, vmConfig, options)) 153 // } else { 154 // evm.interpreters = append(evm.interpreters, NewEWASMInterpreter(evm, vmConfig)) 155 // } 156 panic("No supported ewasm interpreter yet.") 157 } 158 159 // vmConfig.EVMInterpreter will be used by EVM-C, it won't be checked here 160 // as we always want to have the built-in EVM as the failover option. 161 evm.interpreters = append(evm.interpreters, NewEVMInterpreter(evm, vmConfig)) 162 evm.interpreter = evm.interpreters[0] 163 164 return evm 165 } 166 167 // Cancel cancels any running EVM operation. This may be called concurrently and 168 // it's safe to be called multiple times. 169 func (evm *EVM) Cancel() { 170 atomic.StoreInt32(&evm.abort, 1) 171 } 172 173 // Interpreter returns the current interpreter 174 func (evm *EVM) Interpreter() Interpreter { 175 return evm.interpreter 176 } 177 178 // Call executes the contract associated with the addr with the given input as 179 // parameters. It also handles any necessary value transfer required and takes 180 // the necessary steps to create accounts and reverses the state in case of an 181 // execution error or failed value transfer. 182 func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { 183 if evm.vmConfig.NoRecursion && evm.depth > 0 { 184 return nil, gas, nil 185 } 186 187 // Fail if we're trying to execute above the call depth limit 188 if evm.depth > int(params.CallCreateDepth) { 189 return nil, gas, ErrDepth 190 } 191 // Fail if we're trying to transfer more than the available balance 192 if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 193 return nil, gas, ErrInsufficientBalance 194 } 195 196 var ( 197 to = AccountRef(addr) 198 snapshot = evm.StateDB.Snapshot() 199 ) 200 if !evm.StateDB.Exist(addr) { 201 precompiles := PrecompiledContractsHomestead 202 if evm.ChainConfig().IsByzantium(evm.BlockNumber) { 203 precompiles = PrecompiledContractsByzantium 204 } 205 if precompiles[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.Sign() == 0 { 206 // Calling a non existing account, don't do anything, but ping the tracer 207 if evm.vmConfig.Debug && evm.depth == 0 { 208 evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) 209 evm.vmConfig.Tracer.CaptureEnd(ret, 0, 0, nil) 210 } 211 return nil, gas, nil 212 } 213 evm.StateDB.CreateAccount(addr) 214 } 215 evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value) 216 // Initialise a new contract and set the code that is to be used by the EVM. 217 // The contract is a scoped environment for this execution context only. 218 contract := NewContract(caller, to, value, gas) 219 contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) 220 221 // Even if the account has no code, we need to continue because it might be a precompile 222 start := time.Now() 223 224 // Capture the tracer start/end events in debug mode 225 if evm.vmConfig.Debug && evm.depth == 0 { 226 evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) 227 228 defer func() { // Lazy evaluation of the parameters 229 evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) 230 }() 231 } 232 ret, err = run(evm, contract, input, false) 233 234 // When an error was returned by the EVM or when setting the creation code 235 // above we revert to the snapshot and consume any gas remaining. Additionally 236 // when we're in homestead this also counts for code storage gas errors. 237 if err != nil { 238 evm.StateDB.RevertToSnapshot(snapshot) 239 if err != errExecutionReverted { 240 contract.UseGas(contract.Gas) 241 } 242 } 243 return ret, contract.Gas, err 244 } 245 246 // CallCode executes the contract associated with the addr with the given input 247 // as parameters. It also handles any necessary value transfer required and takes 248 // the necessary steps to create accounts and reverses the state in case of an 249 // execution error or failed value transfer. 250 // 251 // CallCode differs from Call in the sense that it executes the given address' 252 // code with the caller as context. 253 func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { 254 if evm.vmConfig.NoRecursion && evm.depth > 0 { 255 return nil, gas, nil 256 } 257 258 // Fail if we're trying to execute above the call depth limit 259 if evm.depth > int(params.CallCreateDepth) { 260 return nil, gas, ErrDepth 261 } 262 // Fail if we're trying to transfer more than the available balance 263 if !evm.CanTransfer(evm.StateDB, caller.Address(), value) { 264 return nil, gas, ErrInsufficientBalance 265 } 266 267 var ( 268 snapshot = evm.StateDB.Snapshot() 269 to = AccountRef(caller.Address()) 270 ) 271 // initialise a new contract and set the code that is to be used by the 272 // EVM. The contract is a scoped environment for this execution context 273 // only. 274 contract := NewContract(caller, to, value, gas) 275 contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) 276 277 ret, err = run(evm, contract, input, false) 278 if err != nil { 279 evm.StateDB.RevertToSnapshot(snapshot) 280 if err != errExecutionReverted { 281 contract.UseGas(contract.Gas) 282 } 283 } 284 return ret, contract.Gas, err 285 } 286 287 // DelegateCall executes the contract associated with the addr with the given input 288 // as parameters. It reverses the state in case of an execution error. 289 // 290 // DelegateCall differs from CallCode in the sense that it executes the given address' 291 // code with the caller as context and the caller is set to the caller of the caller. 292 func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { 293 if evm.vmConfig.NoRecursion && evm.depth > 0 { 294 return nil, gas, nil 295 } 296 // Fail if we're trying to execute above the call depth limit 297 if evm.depth > int(params.CallCreateDepth) { 298 return nil, gas, ErrDepth 299 } 300 301 var ( 302 snapshot = evm.StateDB.Snapshot() 303 to = AccountRef(caller.Address()) 304 ) 305 306 // Initialise a new contract and make initialise the delegate values 307 contract := NewContract(caller, to, nil, gas).AsDelegate() 308 contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) 309 310 ret, err = run(evm, contract, input, false) 311 if err != nil { 312 evm.StateDB.RevertToSnapshot(snapshot) 313 if err != errExecutionReverted { 314 contract.UseGas(contract.Gas) 315 } 316 } 317 return ret, contract.Gas, err 318 } 319 320 // StaticCall executes the contract associated with the addr with the given input 321 // as parameters while disallowing any modifications to the state during the call. 322 // Opcodes that attempt to perform such modifications will result in exceptions 323 // instead of performing the modifications. 324 func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { 325 if evm.vmConfig.NoRecursion && evm.depth > 0 { 326 return nil, gas, nil 327 } 328 // Fail if we're trying to execute above the call depth limit 329 if evm.depth > int(params.CallCreateDepth) { 330 return nil, gas, ErrDepth 331 } 332 333 var ( 334 to = AccountRef(addr) 335 snapshot = evm.StateDB.Snapshot() 336 ) 337 // Initialise a new contract and set the code that is to be used by the 338 // EVM. The contract is a scoped environment for this execution context 339 // only. 340 contract := NewContract(caller, to, new(big.Int), gas) 341 contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) 342 343 // We do an AddBalance of zero here, just in order to trigger a touch. 344 // This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium, 345 // but is the correct thing to do and matters on other networks, in tests, and potential 346 // future scenarios 347 evm.StateDB.AddBalance(addr, bigZero) 348 349 // When an error was returned by the EVM or when setting the creation code 350 // above we revert to the snapshot and consume any gas remaining. Additionally 351 // when we're in Homestead this also counts for code storage gas errors. 352 ret, err = run(evm, contract, input, true) 353 if err != nil { 354 evm.StateDB.RevertToSnapshot(snapshot) 355 if err != errExecutionReverted { 356 contract.UseGas(contract.Gas) 357 } 358 } 359 return ret, contract.Gas, err 360 } 361 362 type codeAndHash struct { 363 code []byte 364 hash common.Hash 365 } 366 367 func (c *codeAndHash) Hash() common.Hash { 368 if c.hash == (common.Hash{}) { 369 c.hash = crypto.Keccak256Hash(c.code) 370 } 371 return c.hash 372 } 373 374 // create creates a new contract using code as deployment code. 375 func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error) { 376 // Depth check execution. Fail if we're trying to execute above the 377 // limit. 378 if evm.depth > int(params.CallCreateDepth) { 379 return nil, common.Address{}, gas, ErrDepth 380 } 381 if !evm.CanTransfer(evm.StateDB, caller.Address(), value) { 382 return nil, common.Address{}, gas, ErrInsufficientBalance 383 } 384 nonce := evm.StateDB.GetNonce(caller.Address()) 385 evm.StateDB.SetNonce(caller.Address(), nonce+1) 386 387 // Ensure there's no existing contract already at the designated address 388 contractHash := evm.StateDB.GetCodeHash(address) 389 if evm.StateDB.GetNonce(address) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) { 390 return nil, common.Address{}, 0, ErrContractAddressCollision 391 } 392 // Create a new account on the state 393 snapshot := evm.StateDB.Snapshot() 394 evm.StateDB.CreateAccount(address) 395 if evm.ChainConfig().IsEIP158(evm.BlockNumber) { 396 evm.StateDB.SetNonce(address, 1) 397 } 398 evm.Transfer(evm.StateDB, caller.Address(), address, value) 399 400 // initialise a new contract and set the code that is to be used by the 401 // EVM. The contract is a scoped environment for this execution context 402 // only. 403 contract := NewContract(caller, AccountRef(address), value, gas) 404 contract.SetCodeOptionalHash(&address, codeAndHash) 405 406 if evm.vmConfig.NoRecursion && evm.depth > 0 { 407 return nil, address, gas, nil 408 } 409 410 if evm.vmConfig.Debug && evm.depth == 0 { 411 evm.vmConfig.Tracer.CaptureStart(caller.Address(), address, true, codeAndHash.code, gas, value) 412 } 413 start := time.Now() 414 415 ret, err := run(evm, contract, nil, false) 416 417 // check whether the max code size has been exceeded 418 maxCodeSizeExceeded := evm.ChainConfig().IsEIP158(evm.BlockNumber) && len(ret) > params.MaxCodeSize 419 // if the contract creation ran successfully and no errors were returned 420 // calculate the gas required to store the code. If the code could not 421 // be stored due to not enough gas set an error and let it be handled 422 // by the error checking condition below. 423 if err == nil && !maxCodeSizeExceeded { 424 createDataGas := uint64(len(ret)) * params.CreateDataGas 425 if contract.UseGas(createDataGas) { 426 evm.StateDB.SetCode(address, ret) 427 } else { 428 err = ErrCodeStoreOutOfGas 429 } 430 } 431 432 // When an error was returned by the EVM or when setting the creation code 433 // above we revert to the snapshot and consume any gas remaining. Additionally 434 // when we're in homestead this also counts for code storage gas errors. 435 if maxCodeSizeExceeded || (err != nil && (evm.ChainConfig().IsHomestead(evm.BlockNumber) || err != ErrCodeStoreOutOfGas)) { 436 evm.StateDB.RevertToSnapshot(snapshot) 437 if err != errExecutionReverted { 438 contract.UseGas(contract.Gas) 439 } 440 } 441 // Assign err if contract code size exceeds the max while the err is still empty. 442 if maxCodeSizeExceeded && err == nil { 443 err = errMaxCodeSizeExceeded 444 } 445 if evm.vmConfig.Debug && evm.depth == 0 { 446 evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) 447 } 448 return ret, address, contract.Gas, err 449 450 } 451 452 // Create creates a new contract using code as deployment code. 453 func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { 454 contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address())) 455 return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr) 456 } 457 458 // Create creates a new contract using code as deployment code. 459 func (evm *EVM) CreateGenesis(caller ContractRef, contractAddr common.Address, code []byte, gas uint64, value *big.Int) (ret []byte, _ common.Address, leftOverGas uint64, err error) { 460 return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr) 461 } 462 463 // Create2 creates a new contract using code as deployment code. 464 // 465 // The different between Create2 with Create is Create2 uses sha3(0xff ++ msg.sender ++ salt ++ sha3(init_code))[12:] 466 // instead of the usual sender-and-nonce-hash as the address where the contract is initialized at. 467 func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *big.Int, salt *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { 468 codeAndHash := &codeAndHash{code: code} 469 contractAddr = crypto.CreateAddress2(caller.Address(), common.BigToHash(salt), codeAndHash.Hash().Bytes()) 470 return evm.create(caller, codeAndHash, gas, endowment, contractAddr) 471 } 472 473 // ChainConfig returns the environment's chain configuration 474 func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }