github.com/dominant-strategies/go-quai@v0.28.2/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 "encoding/binary" 21 "fmt" 22 "math/big" 23 "sync" 24 "sync/atomic" 25 "time" 26 27 "github.com/dominant-strategies/go-quai/common" 28 "github.com/dominant-strategies/go-quai/core/types" 29 "github.com/dominant-strategies/go-quai/crypto" 30 "github.com/dominant-strategies/go-quai/params" 31 "github.com/holiman/uint256" 32 ) 33 34 // emptyCodeHash is used by create to ensure deployment is disallowed to already 35 // deployed contract addresses (relevant after the account abstraction). 36 var emptyCodeHash = crypto.Keccak256Hash(nil) 37 38 type ( 39 // CanTransferFunc is the signature of a transfer guard function 40 CanTransferFunc func(StateDB, common.Address, *big.Int) bool 41 // TransferFunc is the signature of a transfer function 42 TransferFunc func(StateDB, common.Address, common.Address, *big.Int) error 43 // GetHashFunc returns the n'th block hash in the blockchain 44 // and is used by the BLOCKHASH EVM op code. 45 GetHashFunc func(uint64) common.Hash 46 ) 47 48 func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool, common.Address) { 49 if evm.Context.BlockNumber.Uint64() <= params.CarbonForkBlockNumber { // no precompiles before the fork 50 return nil, false, addr 51 } 52 if index, ok := TranslatedAddresses[addr.Bytes20()]; ok { 53 addr = PrecompiledAddresses[common.NodeLocation.Name()][index] 54 } 55 p, ok := PrecompiledContracts[addr.Bytes20()] 56 return p, ok, addr 57 } 58 59 // BlockContext provides the EVM with auxiliary information. Once provided 60 // it shouldn't be modified. 61 type BlockContext struct { 62 // CanTransfer returns whether the account contains 63 // sufficient ether to transfer the value 64 CanTransfer CanTransferFunc 65 // Transfer transfers ether from one account to the other 66 Transfer TransferFunc 67 // GetHash returns the hash corresponding to n 68 GetHash GetHashFunc 69 70 // Block information 71 Coinbase common.Address // Provides information for COINBASE 72 GasLimit uint64 // Provides information for GASLIMIT 73 BlockNumber *big.Int // Provides information for NUMBER 74 Time *big.Int // Provides information for TIME 75 Difficulty *big.Int // Provides information for DIFFICULTY 76 BaseFee *big.Int // Provides information for BASEFEE 77 } 78 79 // TxContext provides the EVM with information about a transaction. 80 // All fields can change between transactions. 81 type TxContext struct { 82 // Message information 83 Origin common.Address // Provides information for ORIGIN 84 GasPrice *big.Int // Provides information for GASPRICE 85 ETXSender common.Address // Original sender of the ETX 86 TxType byte 87 ETXGasLimit uint64 88 ETXGasPrice *big.Int 89 ETXGasTip *big.Int 90 TXGasTip *big.Int 91 ETXData []byte 92 ETXAccessList types.AccessList 93 } 94 95 // EVM is the Quai 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) quai 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 ETXCache []*types.Transaction 132 ETXCacheLock sync.RWMutex 133 } 134 135 // NewEVM returns a new EVM. The returned EVM is not thread safe and should 136 // only ever be used *once*. 137 func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM { 138 evm := &EVM{ 139 Context: blockCtx, 140 TxContext: txCtx, 141 StateDB: statedb, 142 Config: config, 143 chainConfig: chainConfig, 144 chainRules: chainConfig.Rules(blockCtx.BlockNumber), 145 ETXCache: make([]*types.Transaction, 0), 146 } 147 evm.interpreter = NewEVMInterpreter(evm, config) 148 return evm 149 } 150 151 // Reset resets the EVM with a new transaction context.Reset 152 // This is not threadsafe and should only be done very cautiously. 153 func (evm *EVM) Reset(txCtx TxContext, statedb StateDB) { 154 evm.TxContext = txCtx 155 evm.StateDB = statedb 156 } 157 158 // Cancel cancels any running EVM operation. This may be called concurrently and 159 // it's safe to be called multiple times. 160 func (evm *EVM) Cancel() { 161 atomic.StoreInt32(&evm.abort, 1) 162 } 163 164 // Cancelled returns true if Cancel has been called 165 func (evm *EVM) Cancelled() bool { 166 return atomic.LoadInt32(&evm.abort) == 1 167 } 168 169 // Interpreter returns the current interpreter 170 func (evm *EVM) Interpreter() *EVMInterpreter { 171 return evm.interpreter 172 } 173 174 // Call executes the contract associated with the addr with the given input as 175 // parameters. It also handles any necessary value transfer required and takes 176 // the necessary steps to create accounts and reverses the state in case of an 177 // execution error or failed value transfer. 178 func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { 179 if evm.Config.NoRecursion && evm.depth > 0 { 180 return nil, gas, nil 181 } 182 // Fail if we're trying to execute above the call depth limit 183 if evm.depth > int(params.CallCreateDepth) { 184 return nil, gas, ErrDepth 185 } 186 // Fail if we're trying to transfer more than the available balance 187 if value.Sign() != 0 && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 188 return nil, gas, ErrInsufficientBalance 189 } 190 snapshot := evm.StateDB.Snapshot() 191 p, isPrecompile, addr := evm.precompile(addr) 192 if evm.TxType == types.InternalToExternalTxType { 193 return evm.CreateETX(addr, caller.Address(), evm.ETXGasLimit, evm.ETXGasPrice, evm.ETXGasTip, evm.ETXData, evm.ETXAccessList, gas, value) 194 } 195 internalAddr, err := addr.InternalAddress() 196 if err != nil { 197 // We might want to return zero leftOverGas here, but we're being nice 198 return nil, gas, err 199 } 200 if !evm.StateDB.Exist(internalAddr) { 201 if !isPrecompile && value.Sign() == 0 { 202 // Calling a non existing account, don't do anything, but ping the tracer 203 if evm.Config.Debug && evm.depth == 0 { 204 evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value) 205 evm.Config.Tracer.CaptureEnd(ret, 0, 0, nil) 206 } 207 return nil, gas, nil 208 } 209 evm.StateDB.CreateAccount(internalAddr) 210 } 211 if err := evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value); err != nil { 212 return nil, gas, err 213 } 214 215 // Capture the tracer start/end events in debug mode 216 if evm.Config.Debug && evm.depth == 0 { 217 evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value) 218 defer func(startGas uint64, startTime time.Time) { // Lazy evaluation of the parameters 219 evm.Config.Tracer.CaptureEnd(ret, startGas-gas, time.Since(startTime), err) 220 }(gas, time.Now()) 221 } 222 223 if isPrecompile { 224 ret, gas, err = RunPrecompiledContract(p, input, gas) 225 } else { 226 // Initialise a new contract and set the code that is to be used by the EVM. 227 // The contract is a scoped environment for this execution context only. 228 code := evm.StateDB.GetCode(internalAddr) 229 if len(code) == 0 { 230 ret, err = nil, nil // gas is unchanged 231 } else { 232 addrCopy := addr 233 // If the account has no code, we can abort here 234 // The depth-check is already done, and precompiles handled above 235 contract := NewContract(caller, AccountRef(addrCopy), value, gas) 236 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(internalAddr), code) 237 ret, err = evm.interpreter.Run(contract, input, false) 238 gas = contract.Gas 239 } 240 } 241 // When an error was returned by the EVM or when setting the creation code 242 // above we revert to the snapshot and consume any gas remaining. Additionally 243 // when we're in this also counts for code storage gas errors. 244 if err != nil { 245 evm.StateDB.RevertToSnapshot(snapshot) 246 if err != ErrExecutionReverted { 247 gas = 0 248 } 249 // TODO: consider clearing up unused snapshots: 250 //} else { 251 // evm.StateDB.DiscardSnapshot(snapshot) 252 } 253 return ret, gas, err 254 } 255 256 // CallCode executes the contract associated with the addr with the given input 257 // as parameters. It also handles any necessary value transfer required and takes 258 // the necessary steps to create accounts and reverses the state in case of an 259 // execution error or failed value transfer. 260 // 261 // CallCode differs from Call in the sense that it executes the given address' 262 // code with the caller as context. 263 func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { 264 if evm.Config.NoRecursion && evm.depth > 0 { 265 return nil, gas, nil 266 } 267 // Fail if we're trying to execute above the call depth limit 268 if evm.depth > int(params.CallCreateDepth) { 269 return nil, gas, ErrDepth 270 } 271 // Fail if we're trying to transfer more than the available balance 272 // Note although it's noop to transfer X ether to caller itself. But 273 // if caller doesn't have enough balance, it would be an error to allow 274 // over-charging itself. So the check here is necessary. 275 if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 276 return nil, gas, ErrInsufficientBalance 277 } 278 var snapshot = evm.StateDB.Snapshot() 279 280 // It is allowed to call precompiles, even via delegatecall 281 if p, isPrecompile, addr := evm.precompile(addr); isPrecompile { 282 ret, gas, err = RunPrecompiledContract(p, input, gas) 283 } else { 284 addrCopy := addr 285 internalAddr, err := addrCopy.InternalAddress() 286 if err != nil { 287 return nil, gas, err 288 } 289 // Initialise a new contract and set the code that is to be used by the EVM. 290 // The contract is a scoped environment for this execution context only. 291 contract := NewContract(caller, AccountRef(caller.Address()), value, gas) 292 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(internalAddr), evm.StateDB.GetCode(internalAddr)) 293 ret, err = evm.interpreter.Run(contract, input, false) 294 gas = contract.Gas 295 } 296 if err != nil { 297 evm.StateDB.RevertToSnapshot(snapshot) 298 if err != ErrExecutionReverted { 299 gas = 0 300 } 301 } 302 return ret, gas, err 303 } 304 305 // DelegateCall executes the contract associated with the addr with the given input 306 // as parameters. It reverses the state in case of an execution error. 307 // 308 // DelegateCall differs from CallCode in the sense that it executes the given address' 309 // code with the caller as context and the caller is set to the caller of the caller. 310 func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { 311 if evm.Config.NoRecursion && evm.depth > 0 { 312 return nil, gas, nil 313 } 314 // Fail if we're trying to execute above the call depth limit 315 if evm.depth > int(params.CallCreateDepth) { 316 return nil, gas, ErrDepth 317 } 318 var snapshot = evm.StateDB.Snapshot() 319 320 // It is allowed to call precompiles, even via delegatecall 321 if p, isPrecompile, addr := evm.precompile(addr); isPrecompile { 322 ret, gas, err = RunPrecompiledContract(p, input, gas) 323 } else { 324 addrCopy := addr 325 internalAddr, err := addrCopy.InternalAddress() 326 if err != nil { 327 return nil, gas, err 328 } 329 // Initialise a new contract and make initialise the delegate values 330 contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate() 331 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(internalAddr), evm.StateDB.GetCode(internalAddr)) 332 ret, err = evm.interpreter.Run(contract, input, false) 333 gas = contract.Gas 334 } 335 if err != nil { 336 evm.StateDB.RevertToSnapshot(snapshot) 337 if err != ErrExecutionReverted { 338 gas = 0 339 } 340 } 341 return ret, gas, err 342 } 343 344 // StaticCall executes the contract associated with the addr with the given input 345 // as parameters while disallowing any modifications to the state during the call. 346 // Opcodes that attempt to perform such modifications will result in exceptions 347 // instead of performing the modifications. 348 func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { 349 if evm.Config.NoRecursion && evm.depth > 0 { 350 return nil, gas, nil 351 } 352 // Fail if we're trying to execute above the call depth limit 353 if evm.depth > int(params.CallCreateDepth) { 354 return nil, gas, ErrDepth 355 } 356 357 // We take a snapshot here. This is a bit counter-intuitive, and could probably be skipped. 358 // However, even a staticcall is considered a 'touch'. On mainnet, static calls were introduced 359 // after all empty accounts were deleted, so this is not required. However, if we omit this, 360 // then certain tests start failing; stRevertTest/RevertPrecompiledTouchExactOOG.json. 361 // We could change this, but for now it's left for legacy reasons 362 var snapshot = evm.StateDB.Snapshot() 363 364 if p, isPrecompile, addr := evm.precompile(addr); isPrecompile { 365 ret, gas, err = RunPrecompiledContract(p, input, gas) 366 } else { 367 internalAddr, err := addr.InternalAddress() 368 if err != nil { 369 return nil, gas, err 370 } 371 // At this point, we use a copy of address. If we don't, the go compiler will 372 // leak the 'contract' to the outer scope, and make allocation for 'contract' 373 // even if the actual execution ends on RunPrecompiled above. 374 addrCopy := addr 375 // Initialise a new contract and set the code that is to be used by the EVM. 376 // The contract is a scoped environment for this execution context only. 377 contract := NewContract(caller, AccountRef(addrCopy), new(big.Int), gas) 378 contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(internalAddr), evm.StateDB.GetCode(internalAddr)) 379 // When an error was returned by the EVM or when setting the creation code 380 // above we revert to the snapshot and consume any gas remaining. Additionally 381 // when we're in this also counts for code storage gas errors. 382 ret, err = evm.interpreter.Run(contract, input, true) 383 gas = contract.Gas 384 } 385 if err != nil { 386 evm.StateDB.RevertToSnapshot(snapshot) 387 if err != ErrExecutionReverted { 388 gas = 0 389 } 390 } 391 return ret, gas, err 392 } 393 394 type codeAndHash struct { 395 code []byte 396 hash common.Hash 397 } 398 399 func (c *codeAndHash) Hash() common.Hash { 400 if c.hash == (common.Hash{}) { 401 c.hash = crypto.Keccak256Hash(c.code) 402 } 403 return c.hash 404 } 405 406 // create creates a new contract using code as deployment code. 407 func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error) { 408 internalCallerAddr, err := caller.Address().InternalAddress() 409 if err != nil { 410 return nil, common.ZeroAddr, 0, err 411 } 412 nonce := evm.StateDB.GetNonce(internalCallerAddr) 413 evm.StateDB.SetNonce(internalCallerAddr, nonce+1) 414 415 // Depth check execution. Fail if we're trying to execute above the 416 // limit. 417 if evm.depth > int(params.CallCreateDepth) { 418 return nil, common.ZeroAddr, gas, ErrDepth 419 } 420 if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { 421 return nil, common.ZeroAddr, gas, ErrInsufficientBalance 422 } 423 424 internalContractAddr, err := address.InternalAddress() 425 if err != nil { 426 return nil, common.ZeroAddr, 0, err 427 } 428 429 // We add this to the access list _before_ taking a snapshot. Even if the creation fails, 430 // the access-list change should not be rolled back 431 evm.StateDB.AddAddressToAccessList(address) 432 433 // Ensure there's no existing contract already at the designated address 434 contractHash := evm.StateDB.GetCodeHash(internalContractAddr) 435 if evm.StateDB.GetNonce(internalContractAddr) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) { 436 return nil, common.ZeroAddr, 0, ErrContractAddressCollision 437 } 438 // Create a new account on the state 439 snapshot := evm.StateDB.Snapshot() 440 evm.StateDB.CreateAccount(internalContractAddr) 441 442 evm.StateDB.SetNonce(internalContractAddr, 1) 443 444 if err := evm.Context.Transfer(evm.StateDB, caller.Address(), address, value); err != nil { 445 return nil, common.ZeroAddr, 0, err 446 } 447 448 // Initialise a new contract and set the code that is to be used by the EVM. 449 // The contract is a scoped environment for this execution context only. 450 contract := NewContract(caller, AccountRef(address), value, gas) 451 contract.SetCodeOptionalHash(&address, codeAndHash) 452 453 if evm.Config.NoRecursion && evm.depth > 0 { 454 return nil, address, gas, nil 455 } 456 457 if evm.Config.Debug && evm.depth == 0 { 458 evm.Config.Tracer.CaptureStart(evm, caller.Address(), address, true, codeAndHash.code, gas, value) 459 } 460 start := time.Now() 461 462 ret, err := evm.interpreter.Run(contract, nil, false) 463 464 // Check whether the max code size has been exceeded, assign err if the case. 465 if err == nil && len(ret) > params.MaxCodeSize { 466 err = ErrMaxCodeSizeExceeded 467 } 468 469 // Reject code starting with 0xEF 470 if err == nil && len(ret) >= 1 && ret[0] == 0xEF { 471 err = ErrInvalidCode 472 } 473 474 // if the contract creation ran successfully and no errors were returned 475 // calculate the gas required to store the code. If the code could not 476 // be stored due to not enough gas set an error and let it be handled 477 // by the error checking condition below. 478 if err == nil { 479 createDataGas := uint64(len(ret)) * params.CreateDataGas 480 if contract.UseGas(createDataGas) { 481 evm.StateDB.SetCode(internalContractAddr, ret) 482 } else { 483 err = ErrCodeStoreOutOfGas 484 } 485 } 486 487 // When an error was returned by the EVM or when setting the creation code 488 // above we revert to the snapshot and consume any gas remaining. Additionally 489 // when we're in this also counts for code storage gas errors. 490 if err != nil && err != ErrCodeStoreOutOfGas { 491 evm.StateDB.RevertToSnapshot(snapshot) 492 if err != ErrExecutionReverted { 493 contract.UseGas(contract.Gas) 494 } 495 } 496 497 if evm.Config.Debug && evm.depth == 0 { 498 evm.Config.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) 499 } 500 return ret, address, contract.Gas, err 501 } 502 503 // Create creates a new contract using code as deployment code. 504 func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { 505 internalAddr, err := caller.Address().InternalAddress() 506 if err != nil { 507 return nil, common.ZeroAddr, 0, err 508 } 509 510 nonce := evm.StateDB.GetNonce(internalAddr) 511 512 contractAddr = crypto.CreateAddress(caller.Address(), nonce, code) 513 if _, err := contractAddr.InternalAddress(); err == nil { 514 return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr) 515 } else if evm.Context.BlockNumber.Uint64() <= params.CarbonForkBlockNumber { 516 return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr) 517 } 518 519 // Calculate the gas required for the keccak256 computation of the input data. 520 gasCost, err := calculateKeccakGas(code) 521 if err != nil { 522 return nil, common.ZeroAddr, 0, err 523 } 524 525 // attempt to grind the address 526 contractAddr, remainingGas, err := evm.attemptGrindContractCreation(caller, nonce, gas, gasCost, code) 527 if err != nil { 528 return nil, common.ZeroAddr, 0, err 529 } 530 531 gas = remainingGas 532 533 return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr) 534 } 535 536 // calculateKeccakGas calculates the gas required for performing a keccak256 hash on the given data. 537 // It returns the total gas cost and any error that may occur during the calculation. 538 func calculateKeccakGas(data []byte) (int64, error) { 539 // Base gas for keccak256 computation. 540 keccakBaseGas := int64(params.Sha3Gas) 541 // Calculate the number of words (rounded up) in the data for gas calculation. 542 wordCount := (len(data) + 31) / 32 // Round up to the nearest word 543 return keccakBaseGas + int64(wordCount)*int64(params.Sha3WordGas), nil 544 } 545 546 // attemptContractCreation tries to create a contract address by iterating through possible nonce values. 547 // It returns the modified data for contract creation and any error encountered. 548 func (evm *EVM) attemptGrindContractCreation(caller ContractRef, nonce uint64, gas uint64, gasCost int64, code []byte) (common.Address, uint64, error) { 549 senderAddress := caller.Address() 550 551 codeAndHash := &codeAndHash{code: code} 552 var salt [32]byte 553 binary.BigEndian.PutUint64(salt[24:], nonce) 554 555 // Iterate through possible nonce values to find a suitable contract address. 556 for i := 0; i < params.MaxAddressGrindAttempts; i++ { 557 558 // Check if there is enough gas left to continue. 559 if gas < uint64(gasCost) { 560 return common.ZeroAddr, 0, fmt.Errorf("out of gas grinding contract address for %v", caller.Address().Hex()) 561 } 562 563 // Subtract the gas cost for each attempt. 564 gas -= uint64(gasCost) 565 566 // Place i in the [32]byte array. 567 binary.BigEndian.PutUint64(salt[16:24], uint64(i)) 568 569 // Generate a potential contract address. 570 contractAddr := crypto.CreateAddress2(senderAddress, salt, codeAndHash.Hash().Bytes()) 571 572 // Check if the generated address is valid. 573 if _, err := contractAddr.InternalAddress(); err == nil { 574 return contractAddr, gas, nil 575 } 576 } 577 // Return an error if a valid address could not be found after the maximum number of attempts. 578 return common.ZeroAddr, 0, fmt.Errorf("exceeded number of attempts grinding address %v", caller.Address().Hex()) 579 } 580 581 // Create2 creates a new contract using code as deployment code. 582 // 583 // The different between Create2 with Create is Create2 uses sha3(0xff ++ msg.sender ++ salt ++ sha3(init_code))[12:] 584 // instead of the usual sender-and-nonce-hash as the address where the contract is initialized at. 585 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) { 586 codeAndHash := &codeAndHash{code: code} 587 contractAddr = crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes()) 588 return evm.create(caller, codeAndHash, gas, endowment, contractAddr) 589 } 590 591 func (evm *EVM) CreateETX(toAddr common.Address, fromAddr common.Address, etxGasLimit uint64, etxGasPrice *big.Int, etxGasTip *big.Int, etxData []byte, etxAccessList types.AccessList, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { 592 593 // Verify address is not in context 594 if common.IsInChainScope(toAddr.Bytes()) { 595 return []byte{}, 0, fmt.Errorf("%x is in chain scope, but CreateETX was called", toAddr) 596 } 597 if gas < params.ETXGas { 598 return []byte{}, 0, fmt.Errorf("CreateETX error: %d is not sufficient gas, required amount: %d", gas, params.ETXGas) 599 } 600 fromInternal, err := fromAddr.InternalAddress() 601 if err != nil { 602 return []byte{}, 0, fmt.Errorf("CreateETX error: %s", err.Error()) 603 } 604 605 if err := evm.ValidateETXGasPriceAndTip(fromAddr, toAddr, etxGasPrice, etxGasTip); err != nil { 606 return []byte{}, 0, err 607 } 608 609 fee := big.NewInt(0) 610 fee.Add(etxGasTip, etxGasPrice) 611 fee.Mul(fee, big.NewInt(int64(etxGasLimit))) 612 total := big.NewInt(0) 613 total.Add(value, fee) 614 // Fail if we're trying to transfer more than the available balance 615 if total.Sign() == 0 || !evm.Context.CanTransfer(evm.StateDB, fromAddr, total) { 616 return []byte{}, 0, fmt.Errorf("CreateETX: %x cannot transfer %d", fromAddr, total.Uint64()) 617 } 618 619 evm.StateDB.SubBalance(fromInternal, total) 620 621 nonce := evm.StateDB.GetNonce(fromInternal) 622 623 // create external transaction 624 etxInner := types.ExternalTx{Value: value, To: &toAddr, Sender: fromAddr, GasTipCap: etxGasTip, GasFeeCap: etxGasPrice, Gas: etxGasLimit, Data: etxData, AccessList: etxAccessList, Nonce: nonce, ChainID: evm.chainConfig.ChainID} 625 etx := types.NewTx(&etxInner) 626 627 evm.ETXCacheLock.Lock() 628 evm.ETXCache = append(evm.ETXCache, etx) 629 evm.ETXCacheLock.Unlock() 630 631 return []byte{}, gas - params.ETXGas, nil 632 } 633 634 // Emitted ETXs must include some multiple of BaseFee as miner tip, to 635 // encourage processing at the destination. 636 func calcEtxFeeMultiplier(fromAddr, toAddr common.Address) *big.Int { 637 confirmationCtx := fromAddr.Location().CommonDom(*toAddr.Location()).Context() 638 multiplier := big.NewInt(common.NumZonesInRegion) 639 if confirmationCtx == common.PRIME_CTX { 640 multiplier = big.NewInt(0).Mul(multiplier, big.NewInt(common.NumRegionsInPrime)) 641 } 642 return multiplier 643 } 644 645 // Validate ETX gas price and tip 646 func (evm *EVM) ValidateETXGasPriceAndTip(fromAddr, toAddr common.Address, etxGasPrice *big.Int, etxGasTip *big.Int) error { 647 if l := etxGasPrice.BitLen(); l > 256 { 648 return fmt.Errorf("max fee per gas higher than 2^256-1: address %v, etxGasPrice bit length: %d", 649 fromAddr, l) 650 } 651 if l := etxGasTip.BitLen(); l > 256 { 652 return fmt.Errorf("max priority fee per gas higher than 2^256-1: address %v, etxGasTip bit length: %d", 653 fromAddr, l) 654 } 655 if etxGasPrice.Cmp(etxGasTip) < 0 { 656 return fmt.Errorf("max priority fee per gas higher than max fee per gas: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", 657 fromAddr, etxGasTip, etxGasPrice) 658 } 659 // This will panic if baseFee is nil, but basefee presence is verified 660 // as part of header validation. 661 feeMul := calcEtxFeeMultiplier(fromAddr, toAddr) 662 mulBaseFee := new(big.Int).Mul(evm.Context.BaseFee, feeMul) 663 if etxGasPrice.Cmp(mulBaseFee) < 0 { 664 return fmt.Errorf("etx max fee per gas less than %dx block base fee: address %v, maxFeePerGas: %s baseFee: %s", 665 feeMul, fromAddr, etxGasPrice, evm.Context.BaseFee) 666 } 667 mulTip := new(big.Int).Mul(evm.TXGasTip, feeMul) 668 if etxGasTip.Cmp(mulTip) < 0 { 669 return fmt.Errorf("etx miner tip cap less than %dx tx miner tip cap: address %v, etxGasTip: %s txGasTip: %s", 670 feeMul, fromAddr, etxGasTip, evm.TXGasTip) 671 } 672 return nil 673 } 674 675 // ChainConfig returns the environment's chain configuration 676 func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }