github.com/klaytn/klaytn@v1.12.1/api/api_ethereum.go (about) 1 // Copyright 2021 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn 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 klaytn 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 klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package api 18 19 import ( 20 "context" 21 "encoding/binary" 22 "encoding/hex" 23 "errors" 24 "fmt" 25 "math/big" 26 "strconv" 27 "strings" 28 "time" 29 30 "github.com/klaytn/klaytn/rlp" 31 "github.com/klaytn/klaytn/storage/statedb" 32 33 "github.com/klaytn/klaytn/blockchain" 34 "github.com/klaytn/klaytn/blockchain/state" 35 "github.com/klaytn/klaytn/blockchain/types" 36 "github.com/klaytn/klaytn/blockchain/vm" 37 "github.com/klaytn/klaytn/common" 38 "github.com/klaytn/klaytn/common/hexutil" 39 "github.com/klaytn/klaytn/crypto" 40 "github.com/klaytn/klaytn/governance" 41 "github.com/klaytn/klaytn/networks/rpc" 42 "github.com/klaytn/klaytn/node/cn/filters" 43 "github.com/klaytn/klaytn/params" 44 ) 45 46 const ( 47 // EmptySha3Uncles always have value which is the result of 48 // `crypto.Keccak256Hash(rlp.EncodeToBytes([]*types.Header(nil)).String())` 49 // because there is no uncles in Klaytn. 50 // Just use const value because we don't have to calculate it everytime which always be same result. 51 EmptySha3Uncles = "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" 52 // ZeroHashrate exists for supporting Ethereum compatible data structure. 53 // There is no POW mining mechanism in Klaytn. 54 ZeroHashrate uint64 = 0 55 // ZeroUncleCount is always zero because there is no uncle blocks in Klaytn. 56 ZeroUncleCount uint = 0 57 ) 58 59 var ( 60 errNoMiningWork = errors.New("no mining work available yet") 61 errNotFoundBlock = errors.New("can't find a block in database") 62 ) 63 64 // EthereumAPI provides an API to access the Klaytn through the `eth` namespace. 65 // TODO-Klaytn: Removed unused variable 66 type EthereumAPI struct { 67 publicFilterAPI *filters.PublicFilterAPI 68 governanceKlayAPI *governance.GovernanceKlayAPI 69 70 publicKlayAPI *PublicKlayAPI 71 publicBlockChainAPI *PublicBlockChainAPI 72 publicTransactionPoolAPI *PublicTransactionPoolAPI 73 publicAccountAPI *PublicAccountAPI 74 governanceAPI *governance.GovernanceAPI 75 } 76 77 // NewEthereumAPI creates a new ethereum API. 78 // EthereumAPI operates using Klaytn's API internally without overriding. 79 // Therefore, it is necessary to use APIs defined in two different packages(cn and api), 80 // so those apis will be defined through a setter. 81 func NewEthereumAPI() *EthereumAPI { 82 return &EthereumAPI{nil, nil, nil, nil, nil, nil, nil} 83 } 84 85 // SetPublicFilterAPI sets publicFilterAPI 86 func (api *EthereumAPI) SetPublicFilterAPI(publicFilterAPI *filters.PublicFilterAPI) { 87 api.publicFilterAPI = publicFilterAPI 88 } 89 90 // SetGovernanceKlayAPI sets governanceKlayAPI 91 func (api *EthereumAPI) SetGovernanceKlayAPI(governanceKlayAPI *governance.GovernanceKlayAPI) { 92 api.governanceKlayAPI = governanceKlayAPI 93 } 94 95 // SetPublicKlayAPI sets publicKlayAPI 96 func (api *EthereumAPI) SetPublicKlayAPI(publicKlayAPI *PublicKlayAPI) { 97 api.publicKlayAPI = publicKlayAPI 98 } 99 100 // SetPublicBlockChainAPI sets publicBlockChainAPI 101 func (api *EthereumAPI) SetPublicBlockChainAPI(publicBlockChainAPI *PublicBlockChainAPI) { 102 api.publicBlockChainAPI = publicBlockChainAPI 103 } 104 105 // SetPublicTransactionPoolAPI sets publicTransactionPoolAPI 106 func (api *EthereumAPI) SetPublicTransactionPoolAPI(publicTransactionPoolAPI *PublicTransactionPoolAPI) { 107 api.publicTransactionPoolAPI = publicTransactionPoolAPI 108 } 109 110 // SetPublicAccountAPI sets publicAccountAPI 111 func (api *EthereumAPI) SetPublicAccountAPI(publicAccountAPI *PublicAccountAPI) { 112 api.publicAccountAPI = publicAccountAPI 113 } 114 115 // SetGovernanceAPI sets governanceAPI 116 func (api *EthereumAPI) SetGovernanceAPI(governanceAPI *governance.GovernanceAPI) { 117 api.governanceAPI = governanceAPI 118 } 119 120 // Etherbase is the address of operating node. 121 // Unlike Ethereum, it only returns the node address because Klaytn does not have a POW mechanism. 122 func (api *EthereumAPI) Etherbase() (common.Address, error) { 123 return api.governanceAPI.NodeAddress(), nil 124 } 125 126 // Coinbase is the address of operating node (alias for Etherbase). 127 func (api *EthereumAPI) Coinbase() (common.Address, error) { 128 return api.Etherbase() 129 } 130 131 // Hashrate returns the POW hashrate. 132 // Unlike Ethereum, it always returns ZeroHashrate because Klaytn does not have a POW mechanism. 133 func (api *EthereumAPI) Hashrate() hexutil.Uint64 { 134 return hexutil.Uint64(ZeroHashrate) 135 } 136 137 // Mining returns an indication if this node is currently mining. 138 // Unlike Ethereum, it always returns false because Klaytn does not have a POW mechanism, 139 func (api *EthereumAPI) Mining() bool { 140 return false 141 } 142 143 // GetWork returns an errNoMiningWork because klaytn does not have a POW mechanism. 144 func (api *EthereumAPI) GetWork() ([4]string, error) { 145 return [4]string{}, errNoMiningWork 146 } 147 148 // A BlockNonce is a 64-bit hash which proves (combined with the 149 // mix-hash) that a sufficient amount of computation has been carried 150 // out on a block. 151 type BlockNonce [8]byte 152 153 // EncodeNonce converts the given integer to a block nonce. 154 func EncodeNonce(i uint64) BlockNonce { 155 var n BlockNonce 156 binary.BigEndian.PutUint64(n[:], i) 157 return n 158 } 159 160 // Uint64 returns the integer value of a block nonce. 161 func (n BlockNonce) Uint64() uint64 { 162 return binary.BigEndian.Uint64(n[:]) 163 } 164 165 // MarshalText encodes n as a hex string with 0x prefix. 166 func (n BlockNonce) MarshalText() ([]byte, error) { 167 return hexutil.Bytes(n[:]).MarshalText() 168 } 169 170 // UnmarshalText implements encoding.TextUnmarshaler. 171 func (n *BlockNonce) UnmarshalText(input []byte) error { 172 return hexutil.UnmarshalFixedText("BlockNonce", input, n[:]) 173 } 174 175 // SubmitWork returns false because klaytn does not have a POW mechanism. 176 func (api *EthereumAPI) SubmitWork(nonce BlockNonce, hash, digest common.Hash) bool { 177 return false 178 } 179 180 // SubmitHashrate returns false because klaytn does not have a POW mechanism. 181 func (api *EthereumAPI) SubmitHashrate(rate hexutil.Uint64, id common.Hash) bool { 182 return false 183 } 184 185 // GetHashrate returns ZeroHashrate because klaytn does not have a POW mechanism. 186 func (api *EthereumAPI) GetHashrate() uint64 { 187 return ZeroHashrate 188 } 189 190 // NewPendingTransactionFilter creates a filter that fetches pending transaction hashes 191 // as transactions enter the pending state. 192 // 193 // It is part of the filter package because this filter can be used through the 194 // `eth_getFilterChanges` polling method that is also used for log filters. 195 // 196 // https://eth.wiki/json-rpc/API#eth_newpendingtransactionfilter 197 func (api *EthereumAPI) NewPendingTransactionFilter() rpc.ID { 198 return api.publicFilterAPI.NewPendingTransactionFilter() 199 } 200 201 // NewPendingTransactions creates a subscription that is triggered each time a transaction 202 // enters the transaction pool and was signed from one of the transactions this nodes manages. 203 func (api *EthereumAPI) NewPendingTransactions(ctx context.Context) (*rpc.Subscription, error) { 204 return api.publicFilterAPI.NewPendingTransactions(ctx) 205 } 206 207 // NewBlockFilter creates a filter that fetches blocks that are imported into the chain. 208 // It is part of the filter package since polling goes with eth_getFilterChanges. 209 // 210 // https://eth.wiki/json-rpc/API#eth_newblockfilter 211 func (api *EthereumAPI) NewBlockFilter() rpc.ID { 212 return api.publicFilterAPI.NewBlockFilter() 213 } 214 215 // NewHeads send a notification each time a new (header) block is appended to the chain. 216 func (api *EthereumAPI) NewHeads(ctx context.Context) (*rpc.Subscription, error) { 217 notifier, supported := rpc.NotifierFromContext(ctx) 218 if !supported { 219 return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported 220 } 221 222 rpcSub := notifier.CreateSubscription() 223 go func() { 224 headers := make(chan *types.Header) 225 headersSub := api.publicFilterAPI.Events().SubscribeNewHeads(headers) 226 227 for { 228 select { 229 case h := <-headers: 230 header, err := api.rpcMarshalHeader(h, true) 231 if err != nil { 232 logger.Error("Failed to marshal header during newHeads subscription", "err", err) 233 headersSub.Unsubscribe() 234 return 235 } 236 notifier.Notify(rpcSub.ID, header) 237 case <-rpcSub.Err(): 238 headersSub.Unsubscribe() 239 return 240 case <-notifier.Closed(): 241 headersSub.Unsubscribe() 242 return 243 } 244 } 245 }() 246 247 return rpcSub, nil 248 } 249 250 // Logs creates a subscription that fires for all new log that match the given filter criteria. 251 func (api *EthereumAPI) Logs(ctx context.Context, crit filters.FilterCriteria) (*rpc.Subscription, error) { 252 return api.publicFilterAPI.Logs(ctx, crit) 253 } 254 255 // NewFilter creates a new filter and returns the filter id. It can be 256 // used to retrieve logs when the state changes. This method cannot be 257 // used to fetch logs that are already stored in the state. 258 // 259 // Default criteria for the from and to block are "latest". 260 // Using "latest" as block number will return logs for mined blocks. 261 // Using "pending" as block number returns logs for not yet mined (pending) blocks. 262 // In case logs are removed (chain reorg) previously returned logs are returned 263 // again but with the removed property set to true. 264 // 265 // In case "fromBlock" > "toBlock" an error is returned. 266 // 267 // https://eth.wiki/json-rpc/API#eth_newfilter 268 func (api *EthereumAPI) NewFilter(crit filters.FilterCriteria) (rpc.ID, error) { 269 return api.publicFilterAPI.NewFilter(crit) 270 } 271 272 // GetLogs returns logs matching the given argument that are stored within the state. 273 // 274 // https://eth.wiki/json-rpc/API#eth_getlogs 275 func (api *EthereumAPI) GetLogs(ctx context.Context, crit filters.FilterCriteria) ([]*types.Log, error) { 276 return api.publicFilterAPI.GetLogs(ctx, crit) 277 } 278 279 // UninstallFilter removes the filter with the given filter id. 280 // 281 // https://eth.wiki/json-rpc/API#eth_uninstallfilter 282 func (api *EthereumAPI) UninstallFilter(id rpc.ID) bool { 283 return api.publicFilterAPI.UninstallFilter(id) 284 } 285 286 // GetFilterLogs returns the logs for the filter with the given id. 287 // If the filter could not be found an empty array of logs is returned. 288 // 289 // https://eth.wiki/json-rpc/API#eth_getfilterlogs 290 func (api *EthereumAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*types.Log, error) { 291 return api.publicFilterAPI.GetFilterLogs(ctx, id) 292 } 293 294 // GetFilterChanges returns the logs for the filter with the given id since 295 // last time it was called. This can be used for polling. 296 // 297 // For pending transaction and block filters the result is []common.Hash. 298 // (pending)Log filters return []Log. 299 // 300 // https://eth.wiki/json-rpc/API#eth_getfilterchanges 301 func (api *EthereumAPI) GetFilterChanges(id rpc.ID) (interface{}, error) { 302 return api.publicFilterAPI.GetFilterChanges(id) 303 } 304 305 // GasPrice returns a suggestion for a gas price. 306 func (api *EthereumAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { 307 return api.publicKlayAPI.GasPrice(ctx) 308 } 309 310 func (api *EthereumAPI) UpperBoundGasPrice(ctx context.Context) *hexutil.Big { 311 return (*hexutil.Big)(api.publicKlayAPI.UpperBoundGasPrice(ctx)) 312 } 313 314 func (api *EthereumAPI) LowerBoundGasPrice(ctx context.Context) *hexutil.Big { 315 return (*hexutil.Big)(api.publicKlayAPI.LowerBoundGasPrice(ctx)) 316 } 317 318 // MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions. 319 func (api *EthereumAPI) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, error) { 320 return api.publicKlayAPI.MaxPriorityFeePerGas(ctx) 321 } 322 323 // DecimalOrHex unmarshals a non-negative decimal or hex parameter into a uint64. 324 type DecimalOrHex uint64 325 326 // UnmarshalJSON implements json.Unmarshaler. 327 func (dh *DecimalOrHex) UnmarshalJSON(data []byte) error { 328 input := strings.TrimSpace(string(data)) 329 if len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' { 330 input = input[1 : len(input)-1] 331 } 332 333 value, err := strconv.ParseUint(input, 10, 64) 334 if err != nil { 335 value, err = hexutil.DecodeUint64(input) 336 } 337 if err != nil { 338 return err 339 } 340 *dh = DecimalOrHex(value) 341 return nil 342 } 343 344 func (api *EthereumAPI) FeeHistory(ctx context.Context, blockCount DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*FeeHistoryResult, error) { 345 return api.publicKlayAPI.FeeHistory(ctx, blockCount, lastBlock, rewardPercentiles) 346 } 347 348 // Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not 349 // yet received the latest block headers from its pears. In case it is synchronizing: 350 // - startingBlock: block number this node started to synchronise from 351 // - currentBlock: block number this node is currently importing 352 // - highestBlock: block number of the highest block header this node has received from peers 353 // - pulledStates: number of state entries processed until now 354 // - knownStates: number of known state entries that still need to be pulled 355 func (api *EthereumAPI) Syncing() (interface{}, error) { 356 return api.publicKlayAPI.Syncing() 357 } 358 359 // ChainId is the EIP-155 replay-protection chain id for the current ethereum chain config. 360 func (api *EthereumAPI) ChainId() (*hexutil.Big, error) { 361 return api.publicBlockChainAPI.ChainId(), nil 362 } 363 364 // BlockNumber returns the block number of the chain head. 365 func (api *EthereumAPI) BlockNumber() hexutil.Uint64 { 366 return api.publicBlockChainAPI.BlockNumber() 367 } 368 369 // GetBalance returns the amount of wei for the given address in the state of the 370 // given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta 371 // block numbers are also allowed. 372 func (api *EthereumAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { 373 return api.publicBlockChainAPI.GetBalance(ctx, address, blockNrOrHash) 374 } 375 376 // EthAccountResult structs for GetProof 377 // AccountResult in go-ethereum has been renamed to EthAccountResult. 378 // AccountResult is defined in go-ethereum's internal package, so AccountResult is redefined here as EthAccountResult. 379 type EthAccountResult struct { 380 Address common.Address `json:"address"` 381 AccountProof []string `json:"accountProof"` 382 Balance *hexutil.Big `json:"balance"` 383 CodeHash common.Hash `json:"codeHash"` 384 Nonce hexutil.Uint64 `json:"nonce"` 385 StorageHash common.Hash `json:"storageHash"` 386 StorageProof []EthStorageResult `json:"storageProof"` 387 } 388 389 // StorageResult in go-ethereum has been renamed to EthStorageResult. 390 // StorageResult is defined in go-ethereum's internal package, so StorageResult is redefined here as EthStorageResult. 391 type EthStorageResult struct { 392 Key string `json:"key"` 393 Value *hexutil.Big `json:"value"` 394 Proof []string `json:"proof"` 395 } 396 397 // proofList implements KeyValueWriter and collects the proofs as 398 // hex-strings for delivery to rpc-caller. 399 type proofList []string 400 401 func (n *proofList) Put(key []byte, value []byte) error { 402 *n = append(*n, hexutil.Encode(value)) 403 return nil 404 } 405 406 func (n *proofList) Delete(key []byte) error { 407 panic("not supported") 408 } 409 410 func (n *proofList) WriteMerkleProof(key, value []byte) { 411 n.Put(key, value) 412 } 413 414 // decodeHash parses a hex-encoded 32-byte hash. The input may optionally 415 // be prefixed by 0x and can have a byte length up to 32. 416 func decodeHash(s string) (h common.Hash, inputLength int, err error) { 417 if strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X") { 418 s = s[2:] 419 } 420 if (len(s) & 1) > 0 { 421 s = "0" + s 422 } 423 b, err := hex.DecodeString(s) 424 if err != nil { 425 return common.Hash{}, 0, errors.New("hex string invalid") 426 } 427 if len(b) > 32 { 428 return common.Hash{}, len(b), errors.New("hex string too long, want at most 32 bytes") 429 } 430 return common.BytesToHash(b), len(b), nil 431 } 432 433 func doGetProof(ctx context.Context, b Backend, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*EthAccountResult, error) { 434 var ( 435 keys = make([]common.Hash, len(storageKeys)) 436 keyLengths = make([]int, len(storageKeys)) 437 storageProof = make([]EthStorageResult, len(storageKeys)) 438 ) 439 // Deserialize all keys. This prevents state access on invalid input. 440 for i, hexKey := range storageKeys { 441 var err error 442 keys[i], keyLengths[i], err = decodeHash(hexKey) 443 if err != nil { 444 return nil, err 445 } 446 } 447 state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 448 if state == nil || err != nil { 449 return nil, err 450 } 451 codeHash := state.GetCodeHash(address) 452 453 contractStorageRootExt, err := state.GetContractStorageRoot(address) 454 if err != nil { 455 return nil, err 456 } 457 contractStorageRoot := contractStorageRootExt.Unextend() 458 459 // if we have a storageTrie, (which means the account exists), we can update the storagehash 460 if len(keys) > 0 { 461 storageTrie, err := statedb.NewTrie(contractStorageRoot, state.Database().TrieDB(), nil) 462 if err != nil { 463 return nil, err 464 } 465 // Create the proofs for the storageKeys. 466 for i, key := range keys { 467 // Output key encoding is a bit special: if the input was a 32-byte hash, it is 468 // returned as such. Otherwise, we apply the QUANTITY encoding mandated by the 469 // JSON-RPC spec for getProof. This behavior exists to preserve backwards 470 // compatibility with older client versions. 471 var outputKey string 472 if keyLengths[i] != 32 { 473 outputKey = hexutil.EncodeBig(key.Big()) 474 } else { 475 outputKey = hexutil.Encode(key[:]) 476 } 477 if storageTrie == nil { 478 storageProof[i] = EthStorageResult{outputKey, &hexutil.Big{}, []string{}} 479 continue 480 } 481 var proof proofList 482 if err := storageTrie.Prove(crypto.Keccak256(key.Bytes()), 0, &proof); err != nil { 483 return nil, err 484 } 485 value := (*hexutil.Big)(state.GetState(address, key).Big()) 486 storageProof[i] = EthStorageResult{outputKey, value, proof} 487 } 488 } 489 490 // Create the accountProof. 491 trie, err := statedb.NewTrie(header.Root, state.Database().TrieDB(), nil) 492 if err != nil { 493 return nil, err 494 } 495 var accountProof proofList 496 if err := trie.Prove(crypto.Keccak256(address.Bytes()), 0, &accountProof); err != nil { 497 return nil, err 498 } 499 500 return &EthAccountResult{ 501 Address: address, 502 AccountProof: accountProof, 503 Balance: (*hexutil.Big)(state.GetBalance(address)), 504 CodeHash: codeHash, 505 Nonce: hexutil.Uint64(state.GetNonce(address)), 506 StorageHash: contractStorageRoot, 507 StorageProof: storageProof, 508 }, state.Error() 509 } 510 511 // GetProof returns the Merkle-proof for a given account and optionally some storage keys 512 func (api *EthereumAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*EthAccountResult, error) { 513 return doGetProof(ctx, api.publicBlockChainAPI.b, address, storageKeys, blockNrOrHash) 514 } 515 516 // GetHeaderByNumber returns the requested canonical block header. 517 // * When blockNr is -1 the chain head is returned. 518 // * When blockNr is -2 the pending chain head is returned. 519 func (api *EthereumAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { 520 // In Ethereum, err is always nil because the backend of Ethereum always return nil. 521 klaytnHeader, err := api.publicBlockChainAPI.b.HeaderByNumber(ctx, number) 522 if err != nil { 523 if strings.Contains(err.Error(), "does not exist") { 524 return nil, nil 525 } 526 return nil, err 527 } 528 inclMiner := number != rpc.PendingBlockNumber 529 response, err := api.rpcMarshalHeader(klaytnHeader, inclMiner) 530 if err != nil { 531 return nil, err 532 } 533 if number == rpc.PendingBlockNumber { 534 // Pending header need to nil out a few fields 535 for _, field := range []string{"hash", "nonce", "miner"} { 536 response[field] = nil 537 } 538 } 539 return response, nil 540 } 541 542 // GetHeaderByHash returns the requested header by hash. 543 func (api *EthereumAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) map[string]interface{} { 544 // In Ethereum, err is always nil because the backend of Ethereum always return nil. 545 klaytnHeader, _ := api.publicBlockChainAPI.b.HeaderByHash(ctx, hash) 546 if klaytnHeader != nil { 547 response, err := api.rpcMarshalHeader(klaytnHeader, true) 548 if err != nil { 549 return nil 550 } 551 return response 552 } 553 return nil 554 } 555 556 // GetBlockByNumber returns the requested canonical block. 557 // - When blockNr is -1 the chain head is returned. 558 // - When blockNr is -2 the pending chain head is returned. 559 // - When fullTx is true all transactions in the block are returned, otherwise 560 // only the transaction hash is returned. 561 func (api *EthereumAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { 562 // Klaytn backend returns error when there is no matched block but 563 // Ethereum returns it as nil without error, so we should return is as nil when there is no matched block. 564 klaytnBlock, err := api.publicBlockChainAPI.b.BlockByNumber(ctx, number) 565 if err != nil { 566 if strings.Contains(err.Error(), "does not exist") { 567 return nil, nil 568 } 569 return nil, err 570 } 571 572 inclMiner := number != rpc.PendingBlockNumber 573 inclTx := true 574 response, err := api.rpcMarshalBlock(klaytnBlock, inclMiner, inclTx, fullTx) 575 if err == nil && number == rpc.PendingBlockNumber { 576 // Pending blocks need to nil out a few fields 577 for _, field := range []string{"hash", "nonce", "miner"} { 578 response[field] = nil 579 } 580 } 581 return response, err 582 } 583 584 // GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full 585 // detail, otherwise only the transaction hash is returned. 586 func (api *EthereumAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) { 587 // Klaytn backend returns error when there is no matched block but 588 // Ethereum returns it as nil without error, so we should return is as nil when there is no matched block. 589 klaytnBlock, err := api.publicBlockChainAPI.b.BlockByHash(ctx, hash) 590 if err != nil { 591 if strings.Contains(err.Error(), "does not exist") { 592 return nil, nil 593 } 594 return nil, err 595 } 596 return api.rpcMarshalBlock(klaytnBlock, true, true, fullTx) 597 } 598 599 // GetUncleByBlockNumberAndIndex returns nil because there is no uncle block in Klaytn. 600 func (api *EthereumAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (map[string]interface{}, error) { 601 return nil, nil 602 } 603 604 // GetUncleByBlockHashAndIndex returns nil because there is no uncle block in Klaytn. 605 func (api *EthereumAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (map[string]interface{}, error) { 606 return nil, nil 607 } 608 609 // GetUncleCountByBlockNumber returns 0 when given blockNr exists because there is no uncle block in Klaytn. 610 func (api *EthereumAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 611 if block, _ := api.publicBlockChainAPI.b.BlockByNumber(ctx, blockNr); block != nil { 612 n := hexutil.Uint(ZeroUncleCount) 613 return &n 614 } 615 return nil 616 } 617 618 // GetUncleCountByBlockHash returns 0 when given blockHash exists because there is no uncle block in Klaytn. 619 func (api *EthereumAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 620 if block, _ := api.publicBlockChainAPI.b.BlockByHash(ctx, blockHash); block != nil { 621 n := hexutil.Uint(ZeroUncleCount) 622 return &n 623 } 624 return nil 625 } 626 627 // GetCode returns the code stored at the given address in the state for the given block number. 628 func (api *EthereumAPI) GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { 629 return api.publicBlockChainAPI.GetCode(ctx, address, blockNrOrHash) 630 } 631 632 // GetStorageAt returns the storage from the state at the given address, key and 633 // block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block 634 // numbers are also allowed. 635 func (api *EthereumAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { 636 return api.publicBlockChainAPI.GetStorageAt(ctx, address, key, blockNrOrHash) 637 } 638 639 // EthOverrideAccount indicates the overriding fields of account during the execution 640 // of a message call. 641 // Note, state and stateDiff can't be specified at the same time. If state is 642 // set, message execution will only use the data in the given state. Otherwise 643 // if statDiff is set, all diff will be applied first and then execute the call 644 // message. 645 // OverrideAccount in go-ethereum has been renamed to EthOverrideAccount. 646 // OverrideAccount is defined in go-ethereum's internal package, so OverrideAccount is redefined here as EthOverrideAccount. 647 type EthOverrideAccount struct { 648 Nonce *hexutil.Uint64 `json:"nonce"` 649 Code *hexutil.Bytes `json:"code"` 650 Balance **hexutil.Big `json:"balance"` 651 State *map[common.Hash]common.Hash `json:"state"` 652 StateDiff *map[common.Hash]common.Hash `json:"stateDiff"` 653 } 654 655 // EthStateOverride is the collection of overridden accounts. 656 // StateOverride in go-ethereum has been renamed to EthStateOverride. 657 // StateOverride is defined in go-ethereum's internal package, so StateOverride is redefined here as EthStateOverride. 658 type EthStateOverride map[common.Address]EthOverrideAccount 659 660 func (diff *EthStateOverride) Apply(state *state.StateDB) error { 661 if diff == nil { 662 return nil 663 } 664 for addr, account := range *diff { 665 // Override account nonce. 666 if account.Nonce != nil { 667 state.SetNonce(addr, uint64(*account.Nonce)) 668 } 669 // Override account(contract) code. 670 if account.Code != nil { 671 state.SetCode(addr, *account.Code) 672 } 673 // Override account balance. 674 if account.Balance != nil { 675 state.SetBalance(addr, (*big.Int)(*account.Balance)) 676 } 677 if account.State != nil && account.StateDiff != nil { 678 return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex()) 679 } 680 // Replace entire state if caller requires. 681 if account.State != nil { 682 state.SetStorage(addr, *account.State) 683 } 684 // Apply state diff into specified accounts. 685 if account.StateDiff != nil { 686 for key, value := range *account.StateDiff { 687 state.SetState(addr, key, value) 688 } 689 } 690 } 691 return nil 692 } 693 694 // Call executes the given transaction on the state for the given block number. 695 // 696 // Additionally, the caller can specify a batch of contract for fields overriding. 697 // 698 // Note, this function doesn't make and changes in the state/blockchain and is 699 // useful to execute and retrieve values. 700 func (api *EthereumAPI) Call(ctx context.Context, args EthTransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *EthStateOverride) (hexutil.Bytes, error) { 701 bcAPI := api.publicBlockChainAPI.b 702 gasCap := uint64(0) 703 if rpcGasCap := bcAPI.RPCGasCap(); rpcGasCap != nil { 704 gasCap = rpcGasCap.Uint64() 705 } 706 result, err := EthDoCall(ctx, bcAPI, args, blockNrOrHash, overrides, bcAPI.RPCEVMTimeout(), gasCap) 707 if err != nil { 708 return nil, err 709 } 710 711 if len(result.Revert()) > 0 { 712 return nil, blockchain.NewRevertError(result) 713 } 714 return result.Return(), result.Unwrap() 715 } 716 717 // EstimateGas returns an estimate of the amount of gas needed to execute the 718 // given transaction against the current pending block. 719 func (api *EthereumAPI) EstimateGas(ctx context.Context, args EthTransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) { 720 bcAPI := api.publicBlockChainAPI.b 721 bNrOrHash := rpc.NewBlockNumberOrHashWithNumber(rpc.LatestBlockNumber) 722 if blockNrOrHash != nil { 723 bNrOrHash = *blockNrOrHash 724 } 725 gasCap := uint64(0) 726 if rpcGasCap := bcAPI.RPCGasCap(); rpcGasCap != nil { 727 gasCap = rpcGasCap.Uint64() 728 } 729 return EthDoEstimateGas(ctx, bcAPI, args, bNrOrHash, gasCap) 730 } 731 732 // GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number. 733 func (api *EthereumAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 734 transactionCount, _ := api.publicTransactionPoolAPI.GetBlockTransactionCountByNumber(ctx, blockNr) 735 return transactionCount 736 } 737 738 // GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash. 739 func (api *EthereumAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 740 transactionCount, _ := api.publicTransactionPoolAPI.GetBlockTransactionCountByHash(ctx, blockHash) 741 return transactionCount 742 } 743 744 // EthRPCTransaction represents a transaction that will serialize to the RPC representation of a transaction 745 // RPCTransaction in go-ethereum has been renamed to EthRPCTransaction. 746 // RPCTransaction is defined in go-ethereum's internal package, so RPCTransaction is redefined here as EthRPCTransaction. 747 type EthRPCTransaction struct { 748 BlockHash *common.Hash `json:"blockHash"` 749 BlockNumber *hexutil.Big `json:"blockNumber"` 750 From common.Address `json:"from"` 751 Gas hexutil.Uint64 `json:"gas"` 752 GasPrice *hexutil.Big `json:"gasPrice"` 753 GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` 754 GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` 755 Hash common.Hash `json:"hash"` 756 Input hexutil.Bytes `json:"input"` 757 Nonce hexutil.Uint64 `json:"nonce"` 758 To *common.Address `json:"to"` 759 TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` 760 Value *hexutil.Big `json:"value"` 761 Type hexutil.Uint64 `json:"type"` 762 Accesses *types.AccessList `json:"accessList,omitempty"` 763 ChainID *hexutil.Big `json:"chainId,omitempty"` 764 V *hexutil.Big `json:"v"` 765 R *hexutil.Big `json:"r"` 766 S *hexutil.Big `json:"s"` 767 } 768 769 // ethTxJSON is the JSON representation of Ethereum transaction. 770 // ethTxJSON is used by eth namespace APIs which returns Transaction object as it is. 771 // Because every transaction in Klaytn, implements json.Marshaler interface (MarshalJSON), but 772 // it is marshaled for Klaytn format only. 773 // e.g. Ethereum transaction have V, R, and S field for signature but, 774 // Klaytn transaction have types.TxSignaturesJSON which includes array of signatures which is not 775 // applicable for Ethereum transaction. 776 type ethTxJSON struct { 777 Type hexutil.Uint64 `json:"type"` 778 779 // Common transaction fields: 780 Nonce *hexutil.Uint64 `json:"nonce"` 781 GasPrice *hexutil.Big `json:"gasPrice"` 782 MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` 783 MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` 784 Gas *hexutil.Uint64 `json:"gas"` 785 Value *hexutil.Big `json:"value"` 786 Data *hexutil.Bytes `json:"input"` 787 V *hexutil.Big `json:"v"` 788 R *hexutil.Big `json:"r"` 789 S *hexutil.Big `json:"s"` 790 To *common.Address `json:"to"` 791 792 // Access list transaction fields: 793 ChainID *hexutil.Big `json:"chainId,omitempty"` 794 AccessList *types.AccessList `json:"accessList,omitempty"` 795 796 // Only used for encoding: 797 Hash common.Hash `json:"hash"` 798 } 799 800 // newEthRPCTransactionFromBlockIndex creates an EthRPCTransaction from block and index parameters. 801 func newEthRPCTransactionFromBlockIndex(b *types.Block, index uint64) *EthRPCTransaction { 802 txs := b.Transactions() 803 if index >= uint64(len(txs)) { 804 logger.Error("invalid transaction index", "given index", index, "length of txs", len(txs)) 805 return nil 806 } 807 return newEthRPCTransaction(b, txs[index], b.Hash(), b.NumberU64(), index) 808 } 809 810 // newEthRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation. 811 func newEthRPCTransactionFromBlockHash(b *types.Block, hash common.Hash) *EthRPCTransaction { 812 for idx, tx := range b.Transactions() { 813 if tx.Hash() == hash { 814 return newEthRPCTransactionFromBlockIndex(b, uint64(idx)) 815 } 816 } 817 return nil 818 } 819 820 // resolveToField returns value which fits to `to` field based on transaction types. 821 // This function is used when converting Klaytn transactions to Ethereum transaction types. 822 func resolveToField(tx *types.Transaction) *common.Address { 823 switch tx.Type() { 824 case types.TxTypeAccountUpdate, types.TxTypeFeeDelegatedAccountUpdate, types.TxTypeFeeDelegatedAccountUpdateWithRatio, 825 types.TxTypeCancel, types.TxTypeFeeDelegatedCancel, types.TxTypeFeeDelegatedCancelWithRatio, 826 types.TxTypeChainDataAnchoring, types.TxTypeFeeDelegatedChainDataAnchoring, types.TxTypeFeeDelegatedChainDataAnchoringWithRatio: 827 // These type of transactions actually do not have `to` address, but Ethereum always have `to` field, 828 // so we Klaytn developers decided to fill the `to` field with `from` address value in these case. 829 from := getFrom(tx) 830 return &from 831 } 832 return tx.To() 833 } 834 835 // newEthRPCTransaction creates an EthRPCTransaction from Klaytn transaction. 836 func newEthRPCTransaction(block *types.Block, tx *types.Transaction, blockHash common.Hash, blockNumber, index uint64) *EthRPCTransaction { 837 // When an unknown transaction is requested through rpc call, 838 // nil is returned by Klaytn API, and it is handled. 839 if tx == nil { 840 return nil 841 } 842 843 typeInt := tx.Type() 844 // If tx is not Ethereum transaction, the type is converted to TxTypeLegacyTransaction. 845 if !tx.IsEthereumTransaction() { 846 typeInt = types.TxTypeLegacyTransaction 847 } 848 849 signature := tx.GetTxInternalData().RawSignatureValues()[0] 850 851 result := &EthRPCTransaction{ 852 Type: hexutil.Uint64(byte(typeInt)), 853 From: getFrom(tx), 854 Gas: hexutil.Uint64(tx.Gas()), 855 GasPrice: (*hexutil.Big)(tx.GasPrice()), 856 Hash: tx.Hash(), 857 Input: tx.Data(), 858 Nonce: hexutil.Uint64(tx.Nonce()), 859 To: resolveToField(tx), 860 Value: (*hexutil.Big)(tx.Value()), 861 V: (*hexutil.Big)(signature.V), 862 R: (*hexutil.Big)(signature.R), 863 S: (*hexutil.Big)(signature.S), 864 } 865 866 if blockHash != (common.Hash{}) { 867 result.BlockHash = &blockHash 868 result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber)) 869 result.TransactionIndex = (*hexutil.Uint64)(&index) 870 } 871 872 switch typeInt { 873 case types.TxTypeEthereumAccessList: 874 al := tx.AccessList() 875 result.Accesses = &al 876 result.ChainID = (*hexutil.Big)(tx.ChainId()) 877 case types.TxTypeEthereumDynamicFee: 878 al := tx.AccessList() 879 result.Accesses = &al 880 result.ChainID = (*hexutil.Big)(tx.ChainId()) 881 result.GasFeeCap = (*hexutil.Big)(tx.GasFeeCap()) 882 result.GasTipCap = (*hexutil.Big)(tx.GasTipCap()) 883 if block != nil { 884 result.GasPrice = (*hexutil.Big)(tx.EffectiveGasPrice(block.Header())) 885 } else { 886 // transaction is not processed yet 887 result.GasPrice = (*hexutil.Big)(tx.EffectiveGasPrice(nil)) 888 } 889 } 890 return result 891 } 892 893 // newEthRPCPendingTransaction creates an EthRPCTransaction for pending tx. 894 func newEthRPCPendingTransaction(tx *types.Transaction) *EthRPCTransaction { 895 return newEthRPCTransaction(nil, tx, common.Hash{}, 0, 0) 896 } 897 898 // formatTxToEthTxJSON formats types.Transaction to ethTxJSON. 899 // Use this function for only Ethereum typed transaction. 900 func formatTxToEthTxJSON(tx *types.Transaction) *ethTxJSON { 901 var enc ethTxJSON 902 903 enc.Type = hexutil.Uint64(byte(tx.Type())) 904 // If tx is not Ethereum transaction, the type is converted to TxTypeLegacyTransaction. 905 if !tx.IsEthereumTransaction() { 906 enc.Type = hexutil.Uint64(types.TxTypeLegacyTransaction) 907 } 908 enc.Hash = tx.Hash() 909 signature := tx.GetTxInternalData().RawSignatureValues()[0] 910 // Initialize signature values when it is nil. 911 if signature.V == nil { 912 signature.V = new(big.Int) 913 } 914 if signature.R == nil { 915 signature.R = new(big.Int) 916 } 917 if signature.S == nil { 918 signature.S = new(big.Int) 919 } 920 nonce := tx.Nonce() 921 gas := tx.Gas() 922 enc.Nonce = (*hexutil.Uint64)(&nonce) 923 enc.Gas = (*hexutil.Uint64)(&gas) 924 enc.Value = (*hexutil.Big)(tx.Value()) 925 data := tx.Data() 926 enc.Data = (*hexutil.Bytes)(&data) 927 enc.To = tx.To() 928 enc.V = (*hexutil.Big)(signature.V) 929 enc.R = (*hexutil.Big)(signature.R) 930 enc.S = (*hexutil.Big)(signature.S) 931 932 switch tx.Type() { 933 case types.TxTypeEthereumAccessList: 934 al := tx.AccessList() 935 enc.AccessList = &al 936 enc.ChainID = (*hexutil.Big)(tx.ChainId()) 937 enc.GasPrice = (*hexutil.Big)(tx.GasPrice()) 938 case types.TxTypeEthereumDynamicFee: 939 al := tx.AccessList() 940 enc.AccessList = &al 941 enc.ChainID = (*hexutil.Big)(tx.ChainId()) 942 enc.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap()) 943 enc.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap()) 944 default: 945 enc.GasPrice = (*hexutil.Big)(tx.GasPrice()) 946 } 947 return &enc 948 } 949 950 // GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index. 951 func (api *EthereumAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *EthRPCTransaction { 952 block, err := api.publicTransactionPoolAPI.b.BlockByNumber(ctx, blockNr) 953 if err != nil { 954 return nil 955 } 956 957 return newEthRPCTransactionFromBlockIndex(block, uint64(index)) 958 } 959 960 // GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index. 961 func (api *EthereumAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *EthRPCTransaction { 962 block, err := api.publicTransactionPoolAPI.b.BlockByHash(ctx, blockHash) 963 if err != nil || block == nil { 964 return nil 965 } 966 return newEthRPCTransactionFromBlockIndex(block, uint64(index)) 967 } 968 969 // GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index. 970 func (api *EthereumAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) hexutil.Bytes { 971 rawTx, err := api.publicTransactionPoolAPI.GetRawTransactionByBlockNumberAndIndex(ctx, blockNr, index) 972 if rawTx == nil || err != nil { 973 return nil 974 } 975 if rawTx[0] == byte(types.EthereumTxTypeEnvelope) { 976 rawTx = rawTx[1:] 977 } 978 return rawTx 979 } 980 981 // GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index. 982 func (api *EthereumAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) hexutil.Bytes { 983 rawTx, err := api.publicTransactionPoolAPI.GetRawTransactionByBlockHashAndIndex(ctx, blockHash, index) 984 if rawTx == nil || err != nil { 985 return nil 986 } 987 if rawTx[0] == byte(types.EthereumTxTypeEnvelope) { 988 rawTx = rawTx[1:] 989 } 990 return rawTx 991 } 992 993 // GetTransactionCount returns the number of transactions the given address has sent for the given block number. 994 func (api *EthereumAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Uint64, error) { 995 return api.publicTransactionPoolAPI.GetTransactionCount(ctx, address, blockNrOrHash) 996 } 997 998 // GetTransactionByHash returns the transaction for the given hash. 999 func (api *EthereumAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*EthRPCTransaction, error) { 1000 txpoolAPI := api.publicTransactionPoolAPI.b 1001 1002 // Try to return an already finalized transaction 1003 if tx, blockHash, blockNumber, index := txpoolAPI.ChainDB().ReadTxAndLookupInfo(hash); tx != nil { 1004 block, err := txpoolAPI.BlockByHash(ctx, blockHash) 1005 if err != nil { 1006 return nil, err 1007 } 1008 if block == nil { 1009 return nil, errNotFoundBlock 1010 } 1011 return newEthRPCTransaction(block, tx, blockHash, blockNumber, index), nil 1012 } 1013 // No finalized transaction, try to retrieve it from the pool 1014 if tx := txpoolAPI.GetPoolTransaction(hash); tx != nil { 1015 return newEthRPCPendingTransaction(tx), nil 1016 } 1017 // Transaction unknown, return as such 1018 return nil, nil 1019 } 1020 1021 // GetRawTransactionByHash returns the bytes of the transaction for the given hash. 1022 func (api *EthereumAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { 1023 rawTx, err := api.publicTransactionPoolAPI.GetRawTransactionByHash(ctx, hash) 1024 if rawTx == nil || err != nil { 1025 return nil, err 1026 } 1027 if rawTx[0] == byte(types.EthereumTxTypeEnvelope) { 1028 return rawTx[1:], nil 1029 } 1030 return rawTx, nil 1031 } 1032 1033 // GetTransactionReceipt returns the transaction receipt for the given transaction hash. 1034 func (api *EthereumAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { 1035 txpoolAPI := api.publicTransactionPoolAPI.b 1036 1037 // Formats return Klaytn Transaction Receipt to the Ethereum Transaction Receipt. 1038 tx, blockHash, blockNumber, index, receipt := txpoolAPI.GetTxLookupInfoAndReceipt(ctx, hash) 1039 1040 if tx == nil { 1041 return nil, nil 1042 } 1043 receipts := txpoolAPI.GetBlockReceipts(ctx, blockHash) 1044 cumulativeGasUsed := uint64(0) 1045 for i := uint64(0); i <= index; i++ { 1046 cumulativeGasUsed += receipts[i].GasUsed 1047 } 1048 1049 // No error handling is required here. 1050 // Header is checked in the following newEthTransactionReceipt function 1051 header, _ := txpoolAPI.HeaderByHash(ctx, blockHash) 1052 1053 ethTx, err := newEthTransactionReceipt(header, tx, txpoolAPI, blockHash, blockNumber, index, cumulativeGasUsed, receipt) 1054 if err != nil { 1055 return nil, err 1056 } 1057 return ethTx, nil 1058 } 1059 1060 // GetBlockReceipts returns the receipts of all transactions in the block identified by number or hash. 1061 func (api *EthereumAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) { 1062 b := api.publicBlockChainAPI.b 1063 block, err := b.BlockByNumberOrHash(ctx, blockNrOrHash) 1064 if err != nil { 1065 return nil, err 1066 } 1067 1068 var ( 1069 header = block.Header() 1070 blockHash = block.Hash() 1071 blockNumber = block.NumberU64() 1072 txs = block.Transactions() 1073 receipts = b.GetBlockReceipts(ctx, block.Hash()) 1074 cumulativeGasUsed = uint64(0) 1075 outputList = make([]map[string]interface{}, 0, len(receipts)) 1076 ) 1077 if receipts.Len() != txs.Len() { 1078 return nil, fmt.Errorf("the size of transactions and receipts is different in the block (%s)", blockHash.String()) 1079 } 1080 for index, receipt := range receipts { 1081 tx := txs[index] 1082 cumulativeGasUsed += receipt.GasUsed 1083 output, err := newEthTransactionReceipt(header, tx, b, blockHash, blockNumber, uint64(index), cumulativeGasUsed, receipt) 1084 if err != nil { 1085 return nil, err 1086 } 1087 outputList = append(outputList, output) 1088 } 1089 return outputList, nil 1090 } 1091 1092 // newEthTransactionReceipt creates a transaction receipt in Ethereum format. 1093 func newEthTransactionReceipt(header *types.Header, tx *types.Transaction, b Backend, blockHash common.Hash, blockNumber, index, cumulativeGasUsed uint64, receipt *types.Receipt) (map[string]interface{}, error) { 1094 // When an unknown transaction receipt is requested through rpc call, 1095 // nil is returned by Klaytn API, and it is handled. 1096 if tx == nil || receipt == nil { 1097 return nil, nil 1098 } 1099 1100 typeInt := tx.Type() 1101 // If tx is not Ethereum transaction, the type is converted to TxTypeLegacyTransaction. 1102 if !tx.IsEthereumTransaction() { 1103 typeInt = types.TxTypeLegacyTransaction 1104 } 1105 1106 fields := map[string]interface{}{ 1107 "blockHash": blockHash, 1108 "blockNumber": hexutil.Uint64(blockNumber), 1109 "transactionHash": tx.Hash(), 1110 "transactionIndex": hexutil.Uint64(index), 1111 "from": getFrom(tx), 1112 "to": resolveToField(tx), 1113 "gasUsed": hexutil.Uint64(receipt.GasUsed), 1114 "cumulativeGasUsed": hexutil.Uint64(cumulativeGasUsed), 1115 "contractAddress": nil, 1116 "logs": receipt.Logs, 1117 "logsBloom": receipt.Bloom, 1118 "type": hexutil.Uint(byte(typeInt)), 1119 } 1120 1121 // After Magma hard fork : return header.baseFee 1122 // After EthTxType hard fork : use zero baseFee to calculate effective gas price for EthereumDynamicFeeTx : 1123 // return gas price of tx. 1124 // Before EthTxType hard fork : return gas price of tx. (typed ethereum txs are not available.) 1125 fields["effectiveGasPrice"] = hexutil.Uint64(tx.EffectiveGasPrice(header).Uint64()) 1126 1127 // Always use the "status" field and Ignore the "root" field. 1128 if receipt.Status != types.ReceiptStatusSuccessful { 1129 // In Ethereum, status field can have 0(=Failure) or 1(=Success) only. 1130 fields["status"] = hexutil.Uint(types.ReceiptStatusFailed) 1131 } else { 1132 fields["status"] = hexutil.Uint(receipt.Status) 1133 } 1134 1135 if receipt.Logs == nil { 1136 fields["logs"] = [][]*types.Log{} 1137 } 1138 // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation 1139 if receipt.ContractAddress != (common.Address{}) { 1140 fields["contractAddress"] = receipt.ContractAddress 1141 } 1142 1143 return fields, nil 1144 } 1145 1146 // SendTransaction creates a transaction for the given argument, sign it and submit it to the 1147 // transaction pool. 1148 func (api *EthereumAPI) SendTransaction(ctx context.Context, args EthTransactionArgs) (common.Hash, error) { 1149 if args.Nonce == nil { 1150 // Hold the addresses mutex around signing to prevent concurrent assignment of 1151 // the same nonce to multiple accounts. 1152 api.publicTransactionPoolAPI.nonceLock.LockAddr(args.from()) 1153 defer api.publicTransactionPoolAPI.nonceLock.UnlockAddr(args.from()) 1154 } 1155 if err := args.setDefaults(ctx, api.publicTransactionPoolAPI.b); err != nil { 1156 return common.Hash{}, err 1157 } 1158 tx, _ := args.toTransaction() 1159 signedTx, err := api.publicTransactionPoolAPI.sign(args.from(), tx) 1160 if err != nil { 1161 return common.Hash{}, err 1162 } 1163 // Check if signedTx is RLP-Encodable format. 1164 _, err = rlp.EncodeToBytes(signedTx) 1165 if err != nil { 1166 return common.Hash{}, err 1167 } 1168 return submitTransaction(ctx, api.publicTransactionPoolAPI.b, signedTx) 1169 } 1170 1171 // EthSignTransactionResult represents a RLP encoded signed transaction. 1172 // SignTransactionResult in go-ethereum has been renamed to EthSignTransactionResult. 1173 // SignTransactionResult is defined in go-ethereum's internal package, so SignTransactionResult is redefined here as EthSignTransactionResult. 1174 type EthSignTransactionResult struct { 1175 Raw hexutil.Bytes `json:"raw"` 1176 Tx *ethTxJSON `json:"tx"` 1177 } 1178 1179 // FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields) 1180 // on a given unsigned transaction, and returns it to the caller for further 1181 // processing (signing + broadcast). 1182 func (api *EthereumAPI) FillTransaction(ctx context.Context, args EthTransactionArgs) (*EthSignTransactionResult, error) { // Set some sanity defaults and terminate on failure 1183 if err := args.setDefaults(ctx, api.publicTransactionPoolAPI.b); err != nil { 1184 return nil, err 1185 } 1186 // Assemble the transaction and obtain rlp 1187 tx, _ := args.toTransaction() 1188 data, err := tx.MarshalBinary() 1189 if err != nil { 1190 return nil, err 1191 } 1192 1193 if tx.IsEthTypedTransaction() { 1194 // Return rawTx except types.TxTypeEthEnvelope: 0x78(= 1 byte) 1195 return &EthSignTransactionResult{data[1:], formatTxToEthTxJSON(tx)}, nil 1196 } 1197 return &EthSignTransactionResult{data, formatTxToEthTxJSON(tx)}, nil 1198 } 1199 1200 // SendRawTransaction will add the signed transaction to the transaction pool. 1201 // The sender is responsible for signing the transaction and using the correct nonce. 1202 func (api *EthereumAPI) SendRawTransaction(ctx context.Context, input hexutil.Bytes) (common.Hash, error) { 1203 if len(input) == 0 { 1204 return common.Hash{}, fmt.Errorf("Empty input") 1205 } 1206 if 0 < input[0] && input[0] < 0x7f { 1207 inputBytes := []byte{byte(types.EthereumTxTypeEnvelope)} 1208 inputBytes = append(inputBytes, input...) 1209 return api.publicTransactionPoolAPI.SendRawTransaction(ctx, inputBytes) 1210 } 1211 // legacy transaction 1212 return api.publicTransactionPoolAPI.SendRawTransaction(ctx, input) 1213 } 1214 1215 // Sign calculates an ECDSA signature for: 1216 // keccack256("\x19Klaytn Signed Message:\n" + len(message) + message). 1217 // 1218 // Note, the produced signature conforms to the secp256k1 curve R, S and V values, 1219 // where the V value will be 27 or 28 for legacy reasons. 1220 // 1221 // The account associated with addr must be unlocked. 1222 // 1223 // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign 1224 func (api *EthereumAPI) Sign(addr common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { 1225 return api.publicTransactionPoolAPI.Sign(addr, data) 1226 } 1227 1228 // SignTransaction will sign the given transaction with the from account. 1229 // The node needs to have the private key of the account corresponding with 1230 // the given from address and it needs to be unlocked. 1231 func (api *EthereumAPI) SignTransaction(ctx context.Context, args EthTransactionArgs) (*EthSignTransactionResult, error) { 1232 b := api.publicTransactionPoolAPI.b 1233 1234 if args.Gas == nil { 1235 return nil, fmt.Errorf("gas not specified") 1236 } 1237 if args.GasPrice == nil && (args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil) { 1238 return nil, fmt.Errorf("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas") 1239 } 1240 if args.Nonce == nil { 1241 return nil, fmt.Errorf("nonce not specified") 1242 } 1243 if err := args.setDefaults(ctx, b); err != nil { 1244 return nil, err 1245 } 1246 // Before actually sign the transaction, ensure the transaction fee is reasonable. 1247 tx, _ := args.toTransaction() 1248 if err := checkTxFee(tx.GasPrice(), tx.Gas(), b.RPCTxFeeCap()); err != nil { 1249 return nil, err 1250 } 1251 signed, err := api.publicTransactionPoolAPI.sign(args.from(), tx) 1252 if err != nil { 1253 return nil, err 1254 } 1255 data, err := signed.MarshalBinary() 1256 if err != nil { 1257 return nil, err 1258 } 1259 if tx.IsEthTypedTransaction() { 1260 // Return rawTx except types.TxTypeEthEnvelope: 0x78(= 1 byte) 1261 return &EthSignTransactionResult{data[1:], formatTxToEthTxJSON(tx)}, nil 1262 } 1263 return &EthSignTransactionResult{data, formatTxToEthTxJSON(tx)}, nil 1264 } 1265 1266 // PendingTransactions returns the transactions that are in the transaction pool 1267 // and have a from address that is one of the accounts this node manages. 1268 func (api *EthereumAPI) PendingTransactions() ([]*EthRPCTransaction, error) { 1269 b := api.publicTransactionPoolAPI.b 1270 pending, err := b.GetPoolTransactions() 1271 if err != nil { 1272 return nil, err 1273 } 1274 accounts := getAccountsFromWallets(b.AccountManager().Wallets()) 1275 transactions := make([]*EthRPCTransaction, 0, len(pending)) 1276 for _, tx := range pending { 1277 from := getFrom(tx) 1278 if _, exists := accounts[from]; exists { 1279 ethTx := newEthRPCPendingTransaction(tx) 1280 if ethTx == nil { 1281 return nil, nil 1282 } 1283 transactions = append(transactions, ethTx) 1284 } 1285 } 1286 return transactions, nil 1287 } 1288 1289 // Resend accepts an existing transaction and a new gas price and limit. It will remove 1290 // the given transaction from the pool and reinsert it with the new gas price and limit. 1291 func (api *EthereumAPI) Resend(ctx context.Context, sendArgs EthTransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) { 1292 return resend(api.publicTransactionPoolAPI, ctx, &sendArgs, gasPrice, gasLimit) 1293 } 1294 1295 // Accounts returns the collection of accounts this node manages. 1296 func (api *EthereumAPI) Accounts() []common.Address { 1297 return api.publicAccountAPI.Accounts() 1298 } 1299 1300 // rpcMarshalHeader marshal block header as Ethereum compatible format. 1301 // It returns error when fetching Author which is block proposer is failed. 1302 func (api *EthereumAPI) rpcMarshalHeader(head *types.Header, inclMiner bool) (map[string]interface{}, error) { 1303 var proposer common.Address 1304 var err error 1305 1306 b := api.publicKlayAPI.b 1307 if head.Number.Sign() != 0 && inclMiner { 1308 proposer, err = b.Engine().Author(head) 1309 if err != nil { 1310 // miner is the field Klaytn should provide the correct value. It's not the field dummy value is allowed. 1311 logger.Error("Failed to fetch author during marshaling header", "err", err.Error()) 1312 return nil, err 1313 } 1314 } 1315 result := map[string]interface{}{ 1316 "number": (*hexutil.Big)(head.Number), 1317 "hash": head.Hash(), 1318 "parentHash": head.ParentHash, 1319 "nonce": BlockNonce{}, // There is no block nonce concept in Klaytn, so it must be empty. 1320 "mixHash": common.Hash{}, // Klaytn does not use mixHash, so it must be empty. 1321 "sha3Uncles": common.HexToHash(EmptySha3Uncles), 1322 "logsBloom": head.Bloom, 1323 "stateRoot": head.Root, 1324 "miner": proposer, 1325 "difficulty": (*hexutil.Big)(head.BlockScore), 1326 "totalDifficulty": (*hexutil.Big)(b.GetTd(head.Hash())), 1327 // extraData always return empty Bytes because actual value of extraData in Klaytn header cannot be used as meaningful way because 1328 // we cannot provide original header of Klaytn and this field is used as consensus info which is encoded value of validators addresses, validators signatures, and proposer signature in Klaytn. 1329 "extraData": hexutil.Bytes{}, 1330 "size": hexutil.Uint64(head.Size()), 1331 // No block gas limit in Klaytn, instead there is computation cost limit per tx. 1332 "gasLimit": hexutil.Uint64(params.UpperGasLimit), 1333 "gasUsed": hexutil.Uint64(head.GasUsed), 1334 "timestamp": hexutil.Big(*head.Time), 1335 "transactionsRoot": head.TxHash, 1336 "receiptsRoot": head.ReceiptHash, 1337 } 1338 1339 if b.ChainConfig().IsEthTxTypeForkEnabled(head.Number) { 1340 if head.BaseFee == nil { 1341 result["baseFeePerGas"] = (*hexutil.Big)(new(big.Int).SetUint64(params.ZeroBaseFee)) 1342 } else { 1343 result["baseFeePerGas"] = (*hexutil.Big)(head.BaseFee) 1344 } 1345 } 1346 if b.ChainConfig().IsRandaoForkEnabled(head.Number) { 1347 result["randomReveal"] = hexutil.Bytes(head.RandomReveal) 1348 result["mixHash"] = hexutil.Bytes(head.MixHash) 1349 } 1350 return result, nil 1351 } 1352 1353 // rpcMarshalBlock marshal block as Ethereum compatible format 1354 func (api *EthereumAPI) rpcMarshalBlock(block *types.Block, inclMiner, inclTx, fullTx bool) (map[string]interface{}, error) { 1355 fields, err := api.rpcMarshalHeader(block.Header(), inclMiner) 1356 if err != nil { 1357 return nil, err 1358 } 1359 fields["size"] = hexutil.Uint64(block.Size()) 1360 1361 if inclTx { 1362 formatTx := func(tx *types.Transaction) (interface{}, error) { 1363 return tx.Hash(), nil 1364 } 1365 if fullTx { 1366 formatTx = func(tx *types.Transaction) (interface{}, error) { 1367 return newEthRPCTransactionFromBlockHash(block, tx.Hash()), nil 1368 } 1369 } 1370 txs := block.Transactions() 1371 transactions := make([]interface{}, len(txs)) 1372 var err error 1373 for i, tx := range txs { 1374 if transactions[i], err = formatTx(tx); err != nil { 1375 return nil, err 1376 } 1377 } 1378 fields["transactions"] = transactions 1379 } 1380 // There is no uncles in Klaytn 1381 fields["uncles"] = []common.Hash{} 1382 1383 return fields, nil 1384 } 1385 1386 func EthDoCall(ctx context.Context, b Backend, args EthTransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *EthStateOverride, timeout time.Duration, globalGasCap uint64) (*blockchain.ExecutionResult, error) { 1387 defer func(start time.Time) { logger.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) 1388 1389 state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 1390 if state == nil || err != nil { 1391 return nil, err 1392 } 1393 if err := overrides.Apply(state); err != nil { 1394 return nil, err 1395 } 1396 // Setup context so it may be cancelled the call has completed 1397 // or, in case of unmetered gas, setup a context with a timeout. 1398 var cancel context.CancelFunc 1399 if timeout > 0 { 1400 ctx, cancel = context.WithTimeout(ctx, timeout) 1401 } else { 1402 ctx, cancel = context.WithCancel(ctx) 1403 } 1404 // Make sure the context is cancelled when the call has completed 1405 // this makes sure resources are cleaned up. 1406 defer cancel() 1407 1408 // header.BaseFee != nil means magma hardforked 1409 var baseFee *big.Int 1410 if header.BaseFee != nil { 1411 baseFee = header.BaseFee 1412 } else { 1413 baseFee = new(big.Int).SetUint64(params.ZeroBaseFee) 1414 } 1415 intrinsicGas, err := types.IntrinsicGas(args.data(), nil, args.To == nil, b.ChainConfig().Rules(header.Number)) 1416 if err != nil { 1417 return nil, err 1418 } 1419 msg, err := args.ToMessage(globalGasCap, baseFee, intrinsicGas) 1420 if err != nil { 1421 return nil, err 1422 } 1423 var balanceBaseFee *big.Int 1424 if header.BaseFee != nil { 1425 balanceBaseFee = baseFee 1426 } else { 1427 balanceBaseFee = msg.GasPrice() 1428 } 1429 // Add gas fee to sender for estimating gasLimit/computing cost or calling a function by insufficient balance sender. 1430 state.AddBalance(msg.ValidatedSender(), new(big.Int).Mul(new(big.Int).SetUint64(msg.Gas()), balanceBaseFee)) 1431 1432 // The intrinsicGas is checked again later in the blockchain.ApplyMessage function, 1433 // but we check in advance here in order to keep StateTransition.TransactionDb method as unchanged as possible 1434 // and to clarify error reason correctly to serve eth namespace APIs. 1435 // This case is handled by EthDoEstimateGas function. 1436 if msg.Gas() < intrinsicGas { 1437 return nil, fmt.Errorf("%w: msg.gas %d, want %d", blockchain.ErrIntrinsicGas, msg.Gas(), intrinsicGas) 1438 } 1439 evm, vmError, err := b.GetEVM(ctx, msg, state, header, vm.Config{ComputationCostLimit: params.OpcodeComputationCostLimitInfinite}) 1440 if err != nil { 1441 return nil, err 1442 } 1443 // Wait for the context to be done and cancel the evm. Even if the 1444 // EVM has finished, cancelling may be done (repeatedly) 1445 go func() { 1446 <-ctx.Done() 1447 evm.Cancel(vm.CancelByCtxDone) 1448 }() 1449 1450 // Execute the message. 1451 result, err := blockchain.ApplyMessage(evm, msg) 1452 if err := vmError(); err != nil { 1453 return nil, err 1454 } 1455 // If the timer caused an abort, return an appropriate error message 1456 if evm.Cancelled() { 1457 return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout) 1458 } 1459 if err != nil { 1460 return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas()) 1461 } 1462 return result, nil 1463 } 1464 1465 func EthDoEstimateGas(ctx context.Context, b Backend, args EthTransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap uint64) (hexutil.Uint64, error) { 1466 // Use zero address if sender unspecified. 1467 if args.From == nil { 1468 args.From = new(common.Address) 1469 } 1470 1471 var gasLimit uint64 = 0 1472 if args.Gas != nil { 1473 gasLimit = uint64(*args.Gas) 1474 } 1475 1476 // Normalize the max fee per gas the call is willing to spend. 1477 var feeCap *big.Int = common.Big0 1478 if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) { 1479 return 0, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") 1480 } else if args.GasPrice != nil { 1481 feeCap = args.GasPrice.ToInt() 1482 } else if args.MaxFeePerGas != nil { 1483 feeCap = args.MaxFeePerGas.ToInt() 1484 } 1485 1486 state, _, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 1487 if err != nil { 1488 return 0, err 1489 } 1490 balance := state.GetBalance(*args.From) // from can't be nil 1491 1492 executable := func(gas uint64) (bool, *blockchain.ExecutionResult, error) { 1493 args.Gas = (*hexutil.Uint64)(&gas) 1494 result, err := EthDoCall(ctx, b, args, rpc.NewBlockNumberOrHashWithNumber(rpc.LatestBlockNumber), nil, b.RPCEVMTimeout(), gasCap) 1495 if err != nil { 1496 if errors.Is(err, blockchain.ErrIntrinsicGas) { 1497 return true, nil, nil // Special case, raise gas limit 1498 } 1499 // Returns error when it is not VM error (less balance or wrong nonce, etc...). 1500 return true, nil, err // Bail out 1501 } 1502 // If err is vmError, return vmError with returned data 1503 return result.Failed(), result, nil 1504 } 1505 1506 return blockchain.DoEstimateGas(ctx, gasLimit, gasCap, args.Value.ToInt(), feeCap, balance, executable) 1507 } 1508 1509 // checkTxFee is an internal function used to check whether the fee of 1510 // the given transaction is _reasonable_(under the cap). 1511 func checkTxFee(gasPrice *big.Int, gas uint64, cap float64) error { 1512 // Short circuit if there is no cap for transaction fee at all. 1513 if cap == 0 { 1514 return nil 1515 } 1516 feeEth := new(big.Float).Quo(new(big.Float).SetInt(new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(gas))), new(big.Float).SetInt(big.NewInt(params.KLAY))) 1517 feeFloat, _ := feeEth.Float64() 1518 if feeFloat > cap { 1519 return fmt.Errorf("tx fee (%.2f klay) exceeds the configured cap (%.2f klay)", feeFloat, cap) 1520 } 1521 return nil 1522 } 1523 1524 // accessListResult returns an optional accesslist 1525 // It's the result of the `debug_createAccessList` RPC call. 1526 // It contains an error if the transaction itself failed. 1527 type accessListResult struct { 1528 Accesslist *types.AccessList `json:"accessList"` 1529 Error string `json:"error,omitempty"` 1530 GasUsed hexutil.Uint64 `json:"gasUsed"` 1531 } 1532 1533 func doCreateAccessList(ctx context.Context, b Backend, args EthTransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (interface{}, error) { 1534 bNrOrHash := rpc.NewBlockNumberOrHashWithNumber(rpc.PendingBlockNumber) 1535 if blockNrOrHash != nil { 1536 bNrOrHash = *blockNrOrHash 1537 } 1538 acl, gasUsed, vmerr, err := AccessList(ctx, b, bNrOrHash, args) 1539 if err != nil { 1540 return nil, err 1541 } 1542 result := &accessListResult{Accesslist: &acl, GasUsed: hexutil.Uint64(gasUsed)} 1543 if vmerr != nil { 1544 result.Error = vmerr.Error() 1545 } 1546 return result, nil 1547 } 1548 1549 // CreateAccessList creates an EIP-2930 type AccessList for the given transaction. 1550 // Reexec and BlockNrOrHash can be specified to create the accessList on top of a certain state. 1551 func (api *EthereumAPI) CreateAccessList(ctx context.Context, args EthTransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (interface{}, error) { 1552 return doCreateAccessList(ctx, api.publicKlayAPI.b, args, blockNrOrHash) 1553 } 1554 1555 // AccessList creates an access list for the given transaction. 1556 // If the accesslist creation fails an error is returned. 1557 // If the transaction itself fails, an vmErr is returned. 1558 func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrHash, args EthTransactionArgs) (acl types.AccessList, gasUsed uint64, vmErr error, err error) { 1559 // Retrieve the execution context 1560 db, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 1561 if db == nil || err != nil { 1562 return nil, 0, nil, err 1563 } 1564 gasCap := uint64(0) 1565 if rpcGasCap := b.RPCGasCap(); rpcGasCap != nil { 1566 gasCap = rpcGasCap.Uint64() 1567 } 1568 1569 // Retrieve the precompiles since they don't need to be added to the access list 1570 rules := b.ChainConfig().Rules(header.Number) 1571 precompiles := vm.ActivePrecompiles(rules) 1572 1573 toMsg := func() (*types.Transaction, error) { 1574 intrinsicGas, err := types.IntrinsicGas(args.data(), nil, args.To == nil, rules) 1575 if err != nil { 1576 return nil, err 1577 } 1578 return args.ToMessage(gasCap, header.BaseFee, intrinsicGas) 1579 } 1580 1581 if args.Gas == nil { 1582 // Set gaslimit to maximum if the gas is not specified 1583 upperGasLimit := hexutil.Uint64(params.UpperGasLimit) 1584 args.Gas = &upperGasLimit 1585 } 1586 if msg, err := toMsg(); err == nil { 1587 baseFee := new(big.Int).SetUint64(params.ZeroBaseFee) 1588 if header.BaseFee != nil { 1589 baseFee = header.BaseFee 1590 } 1591 // Add gas fee to sender for estimating gasLimit/computing cost or calling a function by insufficient balance sender. 1592 db.AddBalance(msg.ValidatedSender(), new(big.Int).Mul(new(big.Int).SetUint64(msg.Gas()), baseFee)) 1593 } 1594 1595 // Ensure any missing fields are filled, extract the recipient and input data 1596 if err := args.setDefaults(ctx, b); err != nil { 1597 return nil, 0, nil, err 1598 } 1599 var to common.Address 1600 if args.To != nil { 1601 to = *args.To 1602 } else { 1603 to = crypto.CreateAddress(args.from(), uint64(*args.Nonce)) 1604 } 1605 1606 // Create an initial tracer 1607 prevTracer := vm.NewAccessListTracer(nil, args.from(), to, precompiles) 1608 if args.AccessList != nil { 1609 prevTracer = vm.NewAccessListTracer(*args.AccessList, args.from(), to, precompiles) 1610 } 1611 for { 1612 // Retrieve the current access list to expand 1613 accessList := prevTracer.AccessList() 1614 logger.Trace("Creating access list", "input", accessList) 1615 1616 // Copy the original db so we don't modify it 1617 statedb := db.Copy() 1618 // Set the accesslist to the last al 1619 args.AccessList = &accessList 1620 msg, err := toMsg() 1621 if err != nil { 1622 return nil, 0, nil, err 1623 } 1624 1625 // Apply the transaction with the access list tracer 1626 tracer := vm.NewAccessListTracer(accessList, args.from(), to, precompiles) 1627 config := vm.Config{Tracer: tracer, Debug: true} 1628 vmenv, _, err := b.GetEVM(ctx, msg, statedb, header, config) 1629 res, err := blockchain.ApplyMessage(vmenv, msg) 1630 if err != nil { 1631 tx, _ := args.toTransaction() 1632 return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", tx.Hash().Hex(), err) 1633 } 1634 if tracer.Equal(prevTracer) { 1635 return accessList, res.UsedGas, res.Unwrap(), nil 1636 } 1637 prevTracer = tracer 1638 } 1639 }