github.com/DxChainNetwork/dxc@v0.8.1-0.20220824085222-1162e304b6e7/core/vm/evm.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vm 18 19 import ( 20 "math/big" 21 "sync/atomic" 22 "time" 23 24 "github.com/DxChainNetwork/dxc/common" 25 "github.com/DxChainNetwork/dxc/core/types" 26 "github.com/DxChainNetwork/dxc/crypto" 27 "github.com/DxChainNetwork/dxc/params" 28 "github.com/holiman/uint256" 29 ) 30 31 // emptyCodeHash is used by create to ensure deployment is disallowed to already 32 // deployed contract addresses (relevant after the account abstraction). 33 var emptyCodeHash = crypto.Keccak256Hash(nil) 34 35 type ( 36 // CanTransferFunc is the signature of a transfer guard function 37 CanTransferFunc func(StateDB, common.Address, *big.Int) bool 38 // TransferFunc is the signature of a transfer function 39 TransferFunc func(StateDB, common.Address, common.Address, *big.Int) 40 // GetHashFunc returns the n'th block hash in the blockchain 41 // and is used by the BLOCKHASH EVM op code. 42 GetHashFunc func(uint64) common.Hash 43 // CanCreateFunc is the signature of a contract creation guard function 44 CanCreateFunc func(db StateDB, address common.Address, height *big.Int) bool 45 ) 46 47 func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { 48 var precompiles map[common.Address]PrecompiledContract 49 switch { 50 case evm.chainRules.IsBerlin: 51 precompiles = PrecompiledContractsBerlin 52 case evm.chainRules.IsIstanbul: 53 precompiles = PrecompiledContractsIstanbul 54 case evm.chainRules.IsByzantium: 55 precompiles = PrecompiledContractsByzantium 56 default: 57 precompiles = PrecompiledContractsHomestead 58 } 59 p, ok := precompiles[addr] 60 return p, ok 61 } 62 63 // BlockContext provides the EVM with auxiliary information. Once provided 64 // it shouldn't be modified. 65 type BlockContext struct { 66 // CanTransfer returns whether the account contains 67 // sufficient ether to transfer the value 68 CanTransfer CanTransferFunc 69 // Transfer transfers ether from one account to the other 70 Transfer TransferFunc 71 // GetHash returns the hash corresponding to n 72 GetHash GetHashFunc 73 // CanCreate returns whether a given address can create a new contract 74 CanCreate CanCreateFunc 75 // ExtraValidator do some extra validation to a message during it's execution 76 ExtraValidator types.EvmExtraValidator 77 78 // Block information 79 Coinbase common.Address // Provides information for COINBASE 80 GasLimit uint64 // Provides information for GASLIMIT 81 BlockNumber *big.Int // Provides information for NUMBER 82 Time *big.Int // Provides information for TIME 83 Difficulty *big.Int // Provides information for DIFFICULTY 84 BaseFee *big.Int // Provides information for BASEFEE 85 } 86 87 // TxContext provides the EVM with information about a transaction. 88 // All fields can change between transactions. 89 type TxContext struct { 90 // Message information 91 Origin common.Address // Provides information for ORIGIN 92 GasPrice *big.Int // Provides information for GASPRICE 93 } 94 95 // EVM is the Ethereum Virtual Machine base object and provides 96 // the necessary tools to run a contract on the given state with 97 // the provided context. It should be noted that any error 98 // generated through any of the calls should be considered a 99 // revert-state-and-consume-all-gas operation, no checks on 100 // specific errors should ever be performed. The interpreter makes 101 // sure that any errors generated are to be considered faulty code. 102 // 103 // The EVM should never be reused and is not thread safe. 104 type EVM struct { 105 // Context provides auxiliary blockchain related information 106 Context BlockContext 107 TxContext 108 // StateDB gives access to the underlying state 109 StateDB StateDB 110 // Depth is the current call stack 111 depth int 112 113 // chainConfig contains information about the current chain 114 chainConfig *params.ChainConfig 115 // chain rules contains the chain rules for the current epoch 116 chainRules params.Rules 117 // virtual machine configuration options used to initialise the 118 // evm. 119 Config Config 120 // global (to this context) ethereum virtual machine 121 // used throughout the execution of the tx. 122 interpreter *EVMInterpreter 123 // abort is used to abort the EVM calling operations 124 // NOTE: must be set atomically 125 abort int32 126 // callGasTemp holds the gas available for the current call. This is needed because the 127 // available gas is calculated in gasCall* according to the 63/64 rule and later 128 // applied in opCall*. 129 callGasTemp uint64 130 } 131 132 // NewEVM returns a new EVM. The returned EVM is not thread safe and should 133 // only ever be used *once*. 134 func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM { 135 evm := &EVM{ 136 Context: blockCtx, 137 TxContext: txCtx, 138 StateDB: statedb, 139 Config: config, 140 chainConfig: chainConfig, 141 chainRules: chainConfig.Rules(blockCtx.BlockNumber), 142 } 143 evm.interpreter = NewEVMInterpreter(evm, config) 144 return evm 145 } 146 147 // Reset resets the EVM with a new transaction context.Reset 148 // This is not threadsafe and should only be done very cautiously. 149 func (evm *EVM) Reset(txCtx TxContext, statedb StateDB) { 150 evm.TxContext = txCtx 151 evm.StateDB = statedb 152 } 153 154 // Cancel cancels any running EVM operation. This may be called concurrently and 155 // it's safe to be called multiple times. 156 func (evm *EVM) Cancel() { 157 atomic.StoreInt32(&evm.abort, 1) 158 } 159 160 // Cancelled returns true if Cancel has been called 161 func (evm *EVM) Cancelled() bool { 162 return atomic.LoadInt32(&evm.abort) == 1 163 } 164 165 // Interpreter returns the current interpreter 166 func (evm *EVM) Interpreter() *EVMInterpreter { 167 return evm.interpreter 168 } 169 170 // Call executes the contract associated with the addr with the given input as 171 // parameters. It also handles any necessary value transfer required and takes 172 // the necessary steps to create accounts and reverses the state in case of an 173 // execution error or failed value transfer. 174 func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { 175 if evm.Config.NoRecursion && evm.depth > 0 { 176 return nil, gas, nil 177 } 178 // Fail if we're trying to execute above the call depth limit 179 if evm.depth > int(params.CallCreateDepth) { 180 return nil, gas, ErrDepth 181 } 182 183 // Check whether the involved addresses are denied if needed 184 if evm.Context.ExtraValidator != nil && evm.depth > 0 { 185 if evm.Context.ExtraValidator.IsAddressDenied(caller.Address(), common.CheckFrom) || 186 evm.Context.ExtraValidator.IsAddressDenied(addr, common.CheckTo) { 187 return nil, gas, types.ErrAddressDenied 188 } 189 } 190 191 // Fail if we're trying to transfer more than the available balance 192 if value.Sign() != 0 && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 193 return nil, gas, ErrInsufficientBalance 194 } 195 snapshot := evm.StateDB.Snapshot() 196 p, isPrecompile := evm.precompile(addr) 197 198 if !evm.StateDB.Exist(addr) { 199 if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 { 200 // Calling a non existing account, don't do anything, but ping the tracer 201 if evm.Config.Debug && evm.depth == 0 { 202 evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value) 203 evm.Config.Tracer.CaptureEnd(ret, 0, 0, nil) 204 } 205 return nil, gas, nil 206 } 207 evm.StateDB.CreateAccount(addr) 208 } 209 evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value) 210 211 // Capture the tracer start/end events in debug mode 212 if evm.Config.Debug && evm.depth == 0 { 213 evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value) 214 defer func(startGas uint64, startTime time.Time) { // Lazy evaluation of the parameters 215 evm.Config.Tracer.CaptureEnd(ret, startGas-gas, time.Since(startTime), err) 216 }(gas, time.Now()) 217 } 218 219 if isPrecompile { 220 ret, gas, err = RunPrecompiledContract(p, input, gas) 221 } else { 222 // Initialise a new contract and set the code that is to be used by the EVM. 223 // The contract is a scoped environment for this execution context only. 224 code := evm.StateDB.GetCode(addr) 225 if len(code) == 0 { 226 ret, err = nil, nil // gas is unchanged 227 } else { 228 addrCopy := addr 229 // If the account has no code, we can abort here 230 // The depth-check is already done, and precompiles handled above 231 contract := NewContract(caller, AccountRef(addrCopy), value, gas) 232 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code) 233 ret, err = evm.interpreter.Run(contract, input, false) 234 gas = contract.Gas 235 } 236 } 237 // When an error was returned by the EVM or when setting the creation code 238 // above we revert to the snapshot and consume any gas remaining. Additionally 239 // when we're in homestead this also counts for code storage gas errors. 240 if err != nil { 241 evm.StateDB.RevertToSnapshot(snapshot) 242 if err != ErrExecutionReverted { 243 gas = 0 244 } 245 // TODO: consider clearing up unused snapshots: 246 //} else { 247 // evm.StateDB.DiscardSnapshot(snapshot) 248 } 249 return ret, gas, err 250 } 251 252 // CallCode executes the contract associated with the addr with the given input 253 // as parameters. It also handles any necessary value transfer required and takes 254 // the necessary steps to create accounts and reverses the state in case of an 255 // execution error or failed value transfer. 256 // 257 // CallCode differs from Call in the sense that it executes the given address' 258 // code with the caller as context. 259 func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { 260 if evm.Config.NoRecursion && evm.depth > 0 { 261 return nil, gas, nil 262 } 263 // Fail if we're trying to execute above the call depth limit 264 if evm.depth > int(params.CallCreateDepth) { 265 return nil, gas, ErrDepth 266 } 267 268 // Check whether the involved addresses are denied if needed 269 if evm.Context.ExtraValidator != nil { 270 if evm.Context.ExtraValidator.IsAddressDenied(caller.Address(), common.CheckFrom) || 271 evm.Context.ExtraValidator.IsAddressDenied(addr, common.CheckTo) { 272 return nil, gas, types.ErrAddressDenied 273 } 274 } 275 276 // Fail if we're trying to transfer more than the available balance 277 // Note although it's noop to transfer X ether to caller itself. But 278 // if caller doesn't have enough balance, it would be an error to allow 279 // over-charging itself. So the check here is necessary. 280 if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 281 return nil, gas, ErrInsufficientBalance 282 } 283 var snapshot = evm.StateDB.Snapshot() 284 285 // It is allowed to call precompiles, even via delegatecall 286 if p, isPrecompile := evm.precompile(addr); isPrecompile { 287 ret, gas, err = RunPrecompiledContract(p, input, gas) 288 } else { 289 addrCopy := addr 290 // Initialise a new contract and set the code that is to be used by the EVM. 291 // The contract is a scoped environment for this execution context only. 292 contract := NewContract(caller, AccountRef(caller.Address()), value, gas) 293 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) 294 ret, err = evm.interpreter.Run(contract, input, false) 295 gas = contract.Gas 296 } 297 if err != nil { 298 evm.StateDB.RevertToSnapshot(snapshot) 299 if err != ErrExecutionReverted { 300 gas = 0 301 } 302 } 303 return ret, gas, err 304 } 305 306 // DelegateCall executes the contract associated with the addr with the given input 307 // as parameters. It reverses the state in case of an execution error. 308 // 309 // DelegateCall differs from CallCode in the sense that it executes the given address' 310 // code with the caller as context and the caller is set to the caller of the caller. 311 func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { 312 if evm.Config.NoRecursion && evm.depth > 0 { 313 return nil, gas, nil 314 } 315 // Fail if we're trying to execute above the call depth limit 316 if evm.depth > int(params.CallCreateDepth) { 317 return nil, gas, ErrDepth 318 } 319 320 // Check whether the involved addresses are denied if needed 321 if evm.Context.ExtraValidator != nil { 322 if evm.Context.ExtraValidator.IsAddressDenied(caller.Address(), common.CheckFrom) || 323 evm.Context.ExtraValidator.IsAddressDenied(addr, common.CheckTo) { 324 return nil, gas, types.ErrAddressDenied 325 } 326 } 327 328 var snapshot = evm.StateDB.Snapshot() 329 330 // It is allowed to call precompiles, even via delegatecall 331 if p, isPrecompile := evm.precompile(addr); isPrecompile { 332 ret, gas, err = RunPrecompiledContract(p, input, gas) 333 } else { 334 addrCopy := addr 335 // Initialise a new contract and make initialise the delegate values 336 contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate() 337 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) 338 ret, err = evm.interpreter.Run(contract, input, false) 339 gas = contract.Gas 340 } 341 if err != nil { 342 evm.StateDB.RevertToSnapshot(snapshot) 343 if err != ErrExecutionReverted { 344 gas = 0 345 } 346 } 347 return ret, gas, err 348 } 349 350 // StaticCall executes the contract associated with the addr with the given input 351 // as parameters while disallowing any modifications to the state during the call. 352 // Opcodes that attempt to perform such modifications will result in exceptions 353 // instead of performing the modifications. 354 func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { 355 if evm.Config.NoRecursion && evm.depth > 0 { 356 return nil, gas, nil 357 } 358 // Fail if we're trying to execute above the call depth limit 359 if evm.depth > int(params.CallCreateDepth) { 360 return nil, gas, ErrDepth 361 } 362 363 // Check whether the involved addresses are denied if needed 364 if evm.Context.ExtraValidator != nil { 365 if evm.Context.ExtraValidator.IsAddressDenied(caller.Address(), common.CheckFrom) || 366 evm.Context.ExtraValidator.IsAddressDenied(addr, common.CheckTo) { 367 return nil, gas, types.ErrAddressDenied 368 } 369 } 370 371 // We take a snapshot here. This is a bit counter-intuitive, and could probably be skipped. 372 // However, even a staticcall is considered a 'touch'. On mainnet, static calls were introduced 373 // after all empty accounts were deleted, so this is not required. However, if we omit this, 374 // then certain tests start failing; stRevertTest/RevertPrecompiledTouchExactOOG.json. 375 // We could change this, but for now it's left for legacy reasons 376 var snapshot = evm.StateDB.Snapshot() 377 378 // We do an AddBalance of zero here, just in order to trigger a touch. 379 // This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium, 380 // but is the correct thing to do and matters on other networks, in tests, and potential 381 // future scenarios 382 evm.StateDB.AddBalance(addr, big0) 383 384 if p, isPrecompile := evm.precompile(addr); isPrecompile { 385 ret, gas, err = RunPrecompiledContract(p, input, gas) 386 } else { 387 // At this point, we use a copy of address. If we don't, the go compiler will 388 // leak the 'contract' to the outer scope, and make allocation for 'contract' 389 // even if the actual execution ends on RunPrecompiled above. 390 addrCopy := addr 391 // Initialise a new contract and set the code that is to be used by the EVM. 392 // The contract is a scoped environment for this execution context only. 393 contract := NewContract(caller, AccountRef(addrCopy), new(big.Int), gas) 394 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) 395 // When an error was returned by the EVM or when setting the creation code 396 // above we revert to the snapshot and consume any gas remaining. Additionally 397 // when we're in Homestead this also counts for code storage gas errors. 398 ret, err = evm.interpreter.Run(contract, input, true) 399 gas = contract.Gas 400 } 401 if err != nil { 402 evm.StateDB.RevertToSnapshot(snapshot) 403 if err != ErrExecutionReverted { 404 gas = 0 405 } 406 } 407 return ret, gas, err 408 } 409 410 type codeAndHash struct { 411 code []byte 412 hash common.Hash 413 } 414 415 func (c *codeAndHash) Hash() common.Hash { 416 if c.hash == (common.Hash{}) { 417 c.hash = crypto.Keccak256Hash(c.code) 418 } 419 return c.hash 420 } 421 422 // create creates a new contract using code as deployment code. 423 func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error) { 424 // Depth check execution. Fail if we're trying to execute above the 425 // limit. 426 if evm.depth > int(params.CallCreateDepth) { 427 return nil, common.Address{}, gas, ErrDepth 428 } 429 // check developer if needed 430 if evm.Context.CanCreate != nil { 431 if !evm.Context.CanCreate(evm.StateDB, caller.Address(), evm.Context.BlockNumber) { 432 return nil, common.Address{}, gas, ErrUnauthorizedDeveloper 433 } 434 } 435 436 if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 437 return nil, common.Address{}, gas, ErrInsufficientBalance 438 } 439 nonce := evm.StateDB.GetNonce(caller.Address()) 440 evm.StateDB.SetNonce(caller.Address(), nonce+1) 441 // We add this to the access list _before_ taking a snapshot. Even if the creation fails, 442 // the access-list change should not be rolled back 443 if evm.chainRules.IsBerlin { 444 evm.StateDB.AddAddressToAccessList(address) 445 } 446 // Ensure there's no existing contract already at the designated address 447 contractHash := evm.StateDB.GetCodeHash(address) 448 if evm.StateDB.GetNonce(address) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) { 449 return nil, common.Address{}, 0, ErrContractAddressCollision 450 } 451 // Create a new account on the state 452 snapshot := evm.StateDB.Snapshot() 453 evm.StateDB.CreateAccount(address) 454 if evm.chainRules.IsEIP158 { 455 evm.StateDB.SetNonce(address, 1) 456 } 457 evm.Context.Transfer(evm.StateDB, caller.Address(), address, value) 458 459 // Initialise a new contract and set the code that is to be used by the EVM. 460 // The contract is a scoped environment for this execution context only. 461 contract := NewContract(caller, AccountRef(address), value, gas) 462 contract.SetCodeOptionalHash(&address, codeAndHash) 463 464 if evm.Config.NoRecursion && evm.depth > 0 { 465 return nil, address, gas, nil 466 } 467 468 if evm.Config.Debug && evm.depth == 0 { 469 evm.Config.Tracer.CaptureStart(evm, caller.Address(), address, true, codeAndHash.code, gas, value) 470 } 471 start := time.Now() 472 473 ret, err := evm.interpreter.Run(contract, nil, false) 474 475 // Check whether the max code size has been exceeded, assign err if the case. 476 if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize { 477 err = ErrMaxCodeSizeExceeded 478 } 479 480 // Reject code starting with 0xEF if EIP-3541 is enabled. 481 if err == nil && len(ret) >= 1 && ret[0] == 0xEF && evm.chainRules.IsLondon { 482 err = ErrInvalidCode 483 } 484 485 // if the contract creation ran successfully and no errors were returned 486 // calculate the gas required to store the code. If the code could not 487 // be stored due to not enough gas set an error and let it be handled 488 // by the error checking condition below. 489 if err == nil { 490 createDataGas := uint64(len(ret)) * params.CreateDataGas 491 if contract.UseGas(createDataGas) { 492 evm.StateDB.SetCode(address, ret) 493 } else { 494 err = ErrCodeStoreOutOfGas 495 } 496 } 497 498 // When an error was returned by the EVM or when setting the creation code 499 // above we revert to the snapshot and consume any gas remaining. Additionally 500 // when we're in homestead this also counts for code storage gas errors. 501 if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) { 502 evm.StateDB.RevertToSnapshot(snapshot) 503 if err != ErrExecutionReverted { 504 contract.UseGas(contract.Gas) 505 } 506 } 507 508 if evm.Config.Debug && evm.depth == 0 { 509 evm.Config.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) 510 } 511 return ret, address, contract.Gas, err 512 } 513 514 // Create creates a new contract using code as deployment code. 515 func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { 516 contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address())) 517 return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr) 518 } 519 520 // Create2 creates a new contract using code as deployment code. 521 // 522 // The different between Create2 with Create is Create2 uses sha3(0xff ++ msg.sender ++ salt ++ sha3(init_code))[12:] 523 // instead of the usual sender-and-nonce-hash as the address where the contract is initialized at. 524 func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *big.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { 525 codeAndHash := &codeAndHash{code: code} 526 contractAddr = crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes()) 527 return evm.create(caller, codeAndHash, gas, endowment, contractAddr) 528 } 529 530 // ChainConfig returns the environment's chain configuration 531 func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }