github.com/dominant-strategies/go-quai@v0.28.2/internal/quaiapi/api.go (about) 1 // Copyright 2015 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 quaiapi 18 19 import ( 20 "context" 21 "errors" 22 "fmt" 23 "math/big" 24 "strings" 25 "time" 26 27 "github.com/davecgh/go-spew/spew" 28 "github.com/dominant-strategies/go-quai/common" 29 "github.com/dominant-strategies/go-quai/common/hexutil" 30 "github.com/dominant-strategies/go-quai/common/math" 31 "github.com/dominant-strategies/go-quai/consensus/misc" 32 "github.com/dominant-strategies/go-quai/consensus/progpow" 33 "github.com/dominant-strategies/go-quai/core" 34 "github.com/dominant-strategies/go-quai/core/state" 35 "github.com/dominant-strategies/go-quai/core/types" 36 "github.com/dominant-strategies/go-quai/core/vm" 37 "github.com/dominant-strategies/go-quai/crypto" 38 "github.com/dominant-strategies/go-quai/eth/abi" 39 "github.com/dominant-strategies/go-quai/log" 40 "github.com/dominant-strategies/go-quai/p2p" 41 "github.com/dominant-strategies/go-quai/params" 42 "github.com/dominant-strategies/go-quai/rlp" 43 "github.com/dominant-strategies/go-quai/rpc" 44 ) 45 46 // PublicQuaiAPI_Deprecated provides an API to access Quai related information. 47 // It offers only methods that operate on public data that is freely available to anyone. 48 type PublicQuaiAPI_Deprecated struct { 49 b Backend 50 } 51 52 // NewPublicQuaiAPI_Deprecated creates a new Quai protocol API. 53 func NewPublicQuaiAPI_Deprecated(b Backend) *PublicQuaiAPI_Deprecated { 54 return &PublicQuaiAPI_Deprecated{b} 55 } 56 57 // GasPrice returns a suggestion for a gas price for legacy transactions. 58 func (s *PublicQuaiAPI_Deprecated) GasPrice(ctx context.Context) (*hexutil.Big, error) { 59 tipcap, err := s.b.SuggestGasTipCap(ctx) 60 if err != nil { 61 return nil, err 62 } 63 if head := s.b.CurrentHeader(); head.BaseFee() != nil { 64 tipcap.Add(tipcap, head.BaseFee()) 65 } 66 return (*hexutil.Big)(tipcap), err 67 } 68 69 // MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions. 70 func (s *PublicQuaiAPI_Deprecated) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, error) { 71 tipcap, err := s.b.SuggestGasTipCap(ctx) 72 if err != nil { 73 return nil, err 74 } 75 return (*hexutil.Big)(tipcap), err 76 } 77 78 type feeHistoryResult struct { 79 OldestBlock *hexutil.Big `json:"oldestBlock"` 80 Reward [][]*hexutil.Big `json:"reward,omitempty"` 81 BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"` 82 GasUsedRatio []float64 `json:"gasUsedRatio"` 83 } 84 85 func (s *PublicQuaiAPI_Deprecated) FeeHistory(ctx context.Context, blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*feeHistoryResult, error) { 86 oldest, reward, baseFee, gasUsed, err := s.b.FeeHistory(ctx, int(blockCount), lastBlock, rewardPercentiles) 87 if err != nil { 88 return nil, err 89 } 90 results := &feeHistoryResult{ 91 OldestBlock: (*hexutil.Big)(oldest), 92 GasUsedRatio: gasUsed, 93 } 94 if reward != nil { 95 results.Reward = make([][]*hexutil.Big, len(reward)) 96 for i, w := range reward { 97 results.Reward[i] = make([]*hexutil.Big, len(w)) 98 for j, v := range w { 99 results.Reward[i][j] = (*hexutil.Big)(v) 100 } 101 } 102 } 103 if baseFee != nil { 104 results.BaseFee = make([]*hexutil.Big, len(baseFee)) 105 for i, v := range baseFee { 106 results.BaseFee[i] = (*hexutil.Big)(v) 107 } 108 } 109 return results, nil 110 } 111 112 // Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not 113 // yet received the latest block headers from its pears. In case it is synchronizing: 114 // - startingBlock: block number this node started to synchronise from 115 // - currentBlock: block number this node is currently importing 116 // - highestBlock: block number of the highest block header this node has received from peers 117 // - pulledStates: number of state entries processed until now 118 // - knownStates: number of known state entries that still need to be pulled 119 func (s *PublicQuaiAPI_Deprecated) Syncing() (interface{}, error) { 120 progress := s.b.Downloader().Progress() 121 122 // Return not syncing if the synchronisation already completed 123 if progress.CurrentBlock >= progress.HighestBlock { 124 return false, nil 125 } 126 // Otherwise gather the block sync stats 127 return map[string]interface{}{ 128 "startingBlock": hexutil.Uint64(progress.StartingBlock), 129 "currentBlock": hexutil.Uint64(progress.CurrentBlock), 130 "highestBlock": hexutil.Uint64(progress.HighestBlock), 131 "pulledStates": hexutil.Uint64(progress.PulledStates), 132 "knownStates": hexutil.Uint64(progress.KnownStates), 133 }, nil 134 } 135 136 // PublicTxPoolAPI offers and API for the transaction pool. It only operates on data that is non confidential. 137 type PublicTxPoolAPI struct { 138 b Backend 139 } 140 141 // NewPublicTxPoolAPI creates a new tx pool service that gives information about the transaction pool. 142 func NewPublicTxPoolAPI(b Backend) *PublicTxPoolAPI { 143 return &PublicTxPoolAPI{b} 144 } 145 146 // Content returns the transactions contained within the transaction pool. 147 func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { 148 content := map[string]map[string]map[string]*RPCTransaction{ 149 "pending": make(map[string]map[string]*RPCTransaction), 150 "queued": make(map[string]map[string]*RPCTransaction), 151 } 152 pending, queue := s.b.TxPoolContent() 153 curHeader := s.b.CurrentHeader() 154 // Flatten the pending transactions 155 for account, txs := range pending { 156 dump := make(map[string]*RPCTransaction) 157 for _, tx := range txs { 158 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()) 159 } 160 content["pending"][account.Hex()] = dump 161 } 162 // Flatten the queued transactions 163 for account, txs := range queue { 164 dump := make(map[string]*RPCTransaction) 165 for _, tx := range txs { 166 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()) 167 } 168 content["queued"][account.Hex()] = dump 169 } 170 return content 171 } 172 173 // ContentFrom returns the transactions contained within the transaction pool. 174 func (s *PublicTxPoolAPI) ContentFrom(addr common.Address) map[string]map[string]*RPCTransaction { 175 content := make(map[string]map[string]*RPCTransaction, 2) 176 pending, queue := s.b.TxPoolContentFrom(addr) 177 curHeader := s.b.CurrentHeader() 178 179 // Build the pending transactions 180 dump := make(map[string]*RPCTransaction, len(pending)) 181 for _, tx := range pending { 182 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()) 183 } 184 content["pending"] = dump 185 186 // Build the queued transactions 187 dump = make(map[string]*RPCTransaction, len(queue)) 188 for _, tx := range queue { 189 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, curHeader, s.b.ChainConfig()) 190 } 191 content["queued"] = dump 192 193 return content 194 } 195 196 // Status returns the number of pending and queued transaction in the pool. 197 func (s *PublicTxPoolAPI) Status() map[string]hexutil.Uint { 198 pending, queue := s.b.Stats() 199 return map[string]hexutil.Uint{ 200 "pending": hexutil.Uint(pending), 201 "queued": hexutil.Uint(queue), 202 } 203 } 204 205 // Inspect retrieves the content of the transaction pool and flattens it into an 206 // easily inspectable list. 207 func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string]string { 208 content := map[string]map[string]map[string]string{ 209 "pending": make(map[string]map[string]string), 210 "queued": make(map[string]map[string]string), 211 } 212 pending, queue := s.b.TxPoolContent() 213 214 // Define a formatter to flatten a transaction into a string 215 var format = func(tx *types.Transaction) string { 216 if to := tx.To(); to != nil { 217 return fmt.Sprintf("%s: %v wei + %v gas × %v wei", tx.To().Hex(), tx.Value(), tx.Gas(), tx.GasPrice()) 218 } 219 return fmt.Sprintf("contract creation: %v wei + %v gas × %v wei", tx.Value(), tx.Gas(), tx.GasPrice()) 220 } 221 // Flatten the pending transactions 222 for account, txs := range pending { 223 dump := make(map[string]string) 224 for _, tx := range txs { 225 dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) 226 } 227 content["pending"][account.Hex()] = dump 228 } 229 // Flatten the queued transactions 230 for account, txs := range queue { 231 dump := make(map[string]string) 232 for _, tx := range txs { 233 dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) 234 } 235 content["queued"][account.Hex()] = dump 236 } 237 return content 238 } 239 240 // PublicBlockChainAPI provides an API to access the Quai blockchain. 241 // It offers only methods that operate on public data that is freely available to anyone. 242 type PublicBlockChainAPI struct { 243 b Backend 244 } 245 246 // NewPublicBlockChainAPI creates a new Quai blockchain API. 247 func NewPublicBlockChainAPI(b Backend) *PublicBlockChainAPI { 248 return &PublicBlockChainAPI{b} 249 } 250 251 // ChainId is the replay-protection chain id for the current Quai chain config. 252 func (api *PublicBlockChainAPI) ChainId() (*hexutil.Big, error) { 253 return (*hexutil.Big)(api.b.ChainConfig().ChainID), nil 254 } 255 256 // BlockNumber returns the block number of the chain head. 257 func (s *PublicBlockChainAPI) BlockNumber() hexutil.Uint64 { 258 header, _ := s.b.HeaderByNumber(context.Background(), rpc.LatestBlockNumber) // latest header should always be available 259 return hexutil.Uint64(header.NumberU64()) 260 } 261 262 // GetBalance returns the amount of wei for the given address in the state of the 263 // given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta 264 // block numbers are also allowed. 265 func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { 266 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 267 if state == nil || err != nil { 268 return nil, err 269 } 270 internal, err := address.InternalAddress() 271 if err != nil { 272 return nil, err 273 } 274 return (*hexutil.Big)(state.GetBalance(internal)), state.Error() 275 } 276 277 // Result structs for GetProof 278 type AccountResult struct { 279 Address common.Address `json:"address"` 280 AccountProof []string `json:"accountProof"` 281 Balance *hexutil.Big `json:"balance"` 282 CodeHash common.Hash `json:"codeHash"` 283 Nonce hexutil.Uint64 `json:"nonce"` 284 StorageHash common.Hash `json:"storageHash"` 285 StorageProof []StorageResult `json:"storageProof"` 286 } 287 288 type StorageResult struct { 289 Key string `json:"key"` 290 Value *hexutil.Big `json:"value"` 291 Proof []string `json:"proof"` 292 } 293 294 // GetProof returns the Merkle-proof for a given account and optionally some storage keys. 295 func (s *PublicBlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) { 296 nodeCtx := common.NodeLocation.Context() 297 if nodeCtx != common.ZONE_CTX { 298 return nil, errors.New("getProof can only be called in zone chain") 299 } 300 if !s.b.ProcessingState() { 301 return nil, errors.New("getProof call can only be made on chain processing the state") 302 } 303 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 304 if state == nil || err != nil { 305 return nil, err 306 } 307 internal, err := address.InternalAddress() 308 if err != nil { 309 return nil, err 310 } 311 storageTrie := state.StorageTrie(internal) 312 storageHash := types.EmptyRootHash 313 codeHash := state.GetCodeHash(internal) 314 storageProof := make([]StorageResult, len(storageKeys)) 315 316 // if we have a storageTrie, (which means the account exists), we can update the storagehash 317 if storageTrie != nil { 318 storageHash = storageTrie.Hash() 319 } else { 320 // no storageTrie means the account does not exist, so the codeHash is the hash of an empty bytearray. 321 codeHash = crypto.Keccak256Hash(nil) 322 } 323 324 // create the proof for the storageKeys 325 for i, key := range storageKeys { 326 if storageTrie != nil { 327 proof, storageError := state.GetStorageProof(internal, common.HexToHash(key)) 328 if storageError != nil { 329 return nil, storageError 330 } 331 storageProof[i] = StorageResult{key, (*hexutil.Big)(state.GetState(internal, common.HexToHash(key)).Big()), toHexSlice(proof)} 332 } else { 333 storageProof[i] = StorageResult{key, &hexutil.Big{}, []string{}} 334 } 335 } 336 337 // create the accountProof 338 accountProof, proofErr := state.GetProof(internal) 339 if proofErr != nil { 340 return nil, proofErr 341 } 342 343 return &AccountResult{ 344 Address: address, 345 AccountProof: toHexSlice(accountProof), 346 Balance: (*hexutil.Big)(state.GetBalance(internal)), 347 CodeHash: codeHash, 348 Nonce: hexutil.Uint64(state.GetNonce(internal)), 349 StorageHash: storageHash, 350 StorageProof: storageProof, 351 }, state.Error() 352 } 353 354 // GetHeaderByNumber returns the requested canonical block header. 355 // * When blockNr is -1 the chain head is returned. 356 // * When blockNr is -2 the pending chain head is returned. 357 func (s *PublicBlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { 358 header, err := s.b.HeaderByNumber(ctx, number) 359 if header != nil && err == nil { 360 response := RPCMarshalETHHeader(header) 361 if number == rpc.PendingBlockNumber { 362 // Pending header need to nil out a few fields 363 for _, field := range []string{"hash", "nonce", "miner"} { 364 response[field] = nil 365 } 366 } 367 return response, err 368 } 369 return nil, err 370 } 371 372 // GetHeaderByHash returns the requested header by hash. 373 func (s *PublicBlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) map[string]interface{} { 374 header, _ := s.b.HeaderByHash(ctx, hash) 375 if header != nil { 376 return RPCMarshalETHHeader(header) 377 } 378 return nil 379 } 380 381 // GetBlockByNumber returns the requested canonical block. 382 // - When blockNr is -1 the chain head is returned. 383 // - When blockNr is -2 the pending chain head is returned. 384 // - When fullTx is true all transactions in the block are returned, otherwise 385 // only the transaction hash is returned. 386 func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { 387 block, err := s.b.BlockByNumber(ctx, number) 388 if block != nil && err == nil { 389 response, err := s.rpcMarshalBlock(ctx, block, true, fullTx) 390 if err == nil && number == rpc.PendingBlockNumber { 391 // Pending blocks need to nil out a few fields 392 for _, field := range []string{"hash", "nonce", "miner"} { 393 response[field] = nil 394 } 395 } 396 return response, err 397 } 398 return nil, err 399 } 400 401 // GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full 402 // detail, otherwise only the transaction hash is returned. 403 func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) { 404 block, err := s.b.BlockByHash(ctx, hash) 405 if block != nil { 406 return s.rpcMarshalBlock(ctx, block, true, fullTx) 407 } 408 return nil, err 409 } 410 411 // GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. When fullTx is true 412 // all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. 413 func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (map[string]interface{}, error) { 414 block, err := s.b.BlockByNumber(ctx, blockNr) 415 if block != nil { 416 uncles := block.Uncles() 417 if index >= hexutil.Uint(len(uncles)) { 418 log.Debug("Requested uncle not found", "number", blockNr, "hash", block.Hash(), "index", index) 419 return nil, nil 420 } 421 block = types.NewBlockWithHeader(uncles[index]) 422 return s.rpcMarshalBlock(ctx, block, false, false) 423 } 424 return nil, err 425 } 426 427 // GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. When fullTx is true 428 // all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. 429 func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (map[string]interface{}, error) { 430 block, err := s.b.BlockByHash(ctx, blockHash) 431 if block != nil { 432 uncles := block.Uncles() 433 if index >= hexutil.Uint(len(uncles)) { 434 log.Debug("Requested uncle not found", "number", block.Number(), "hash", blockHash, "index", index) 435 return nil, nil 436 } 437 block = types.NewBlockWithHeader(uncles[index]) 438 return s.rpcMarshalBlock(ctx, block, false, false) 439 } 440 return nil, err 441 } 442 443 // GetUncleCountByBlockNumber returns number of uncles in the block for the given block number 444 func (s *PublicBlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 445 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 446 n := hexutil.Uint(len(block.Uncles())) 447 return &n 448 } 449 return nil 450 } 451 452 // GetUncleCountByBlockHash returns number of uncles in the block for the given block hash 453 func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 454 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 455 n := hexutil.Uint(len(block.Uncles())) 456 return &n 457 } 458 return nil 459 } 460 461 // GetCode returns the code stored at the given address in the state for the given block number. 462 func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { 463 nodeCtx := common.NodeLocation.Context() 464 if nodeCtx != common.ZONE_CTX { 465 return nil, errors.New("getCode can only be called in zone chain") 466 } 467 if !s.b.ProcessingState() { 468 return nil, errors.New("getCode call can only be made on chain processing the state") 469 } 470 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 471 if state == nil || err != nil { 472 return nil, err 473 } 474 internal, err := address.InternalAddress() 475 if err != nil { 476 return nil, err 477 } 478 code := state.GetCode(internal) 479 return code, state.Error() 480 } 481 482 // GetStorageAt returns the storage from the state at the given address, key and 483 // block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block 484 // numbers are also allowed. 485 func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { 486 nodeCtx := common.NodeLocation.Context() 487 if nodeCtx != common.ZONE_CTX { 488 return nil, errors.New("getStorageAt can only be called in zone chain") 489 } 490 if !s.b.ProcessingState() { 491 return nil, errors.New("getStorageAt call can only be made on chain processing the state") 492 } 493 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 494 if state == nil || err != nil { 495 return nil, err 496 } 497 internal, err := address.InternalAddress() 498 if err != nil { 499 return nil, err 500 } 501 res := state.GetState(internal, common.HexToHash(key)) 502 return res[:], state.Error() 503 } 504 505 // OverrideAccount indicates the overriding fields of account during the execution 506 // of a message call. 507 // Note, state and stateDiff can't be specified at the same time. If state is 508 // set, message execution will only use the data in the given state. Otherwise 509 // if statDiff is set, all diff will be applied first and then execute the call 510 // message. 511 type OverrideAccount struct { 512 Nonce *hexutil.Uint64 `json:"nonce"` 513 Code *hexutil.Bytes `json:"code"` 514 Balance **hexutil.Big `json:"balance"` 515 State *map[common.Hash]common.Hash `json:"state"` 516 StateDiff *map[common.Hash]common.Hash `json:"stateDiff"` 517 } 518 519 // StateOverride is the collection of overridden accounts. 520 type StateOverride map[common.AddressBytes]OverrideAccount 521 522 // Apply overrides the fields of specified accounts into the given state. 523 func (diff *StateOverride) Apply(state *state.StateDB) error { 524 nodeCtx := common.NodeLocation.Context() 525 if nodeCtx != common.ZONE_CTX { 526 return errors.New("stateOverride Apply can only be called in zone chain") 527 } 528 if diff == nil { 529 return nil 530 } 531 for addr, account := range *diff { 532 internal, err := common.Bytes20ToAddress(addr).InternalAddress() 533 if err != nil { 534 return err 535 } 536 // Override account nonce. 537 if account.Nonce != nil { 538 state.SetNonce(internal, uint64(*account.Nonce)) 539 } 540 // Override account(contract) code. 541 if account.Code != nil { 542 state.SetCode(internal, *account.Code) 543 } 544 // Override account balance. 545 if account.Balance != nil { 546 state.SetBalance(internal, (*big.Int)(*account.Balance)) 547 } 548 if account.State != nil && account.StateDiff != nil { 549 return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex()) 550 } 551 // Replace entire state if caller requires. 552 if account.State != nil { 553 state.SetStorage(internal, *account.State) 554 } 555 // Apply state diff into specified accounts. 556 if account.StateDiff != nil { 557 for key, value := range *account.StateDiff { 558 state.SetState(internal, key, value) 559 } 560 } 561 } 562 return nil 563 } 564 565 func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { 566 defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) 567 nodeCtx := common.NodeLocation.Context() 568 if nodeCtx != common.ZONE_CTX { 569 return nil, errors.New("doCall can only be called in zone chain") 570 } 571 if !b.ProcessingState() { 572 return nil, errors.New("doCall call can only be made on chain processing the state") 573 } 574 state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 575 if state == nil || err != nil { 576 return nil, err 577 } 578 if err := overrides.Apply(state); err != nil { 579 return nil, err 580 } 581 // Setup context so it may be cancelled the call has completed 582 // or, in case of unmetered gas, setup a context with a timeout. 583 var cancel context.CancelFunc 584 if timeout > 0 { 585 ctx, cancel = context.WithTimeout(ctx, timeout) 586 } else { 587 ctx, cancel = context.WithCancel(ctx) 588 } 589 // Make sure the context is cancelled when the call has completed 590 // this makes sure resources are cleaned up. 591 defer cancel() 592 593 // Get a new instance of the EVM. 594 msg, err := args.ToMessage(globalGasCap, header.BaseFee()) 595 if err != nil { 596 return nil, err 597 } 598 evm, vmError, err := b.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true}) 599 if err != nil { 600 return nil, err 601 } 602 // Wait for the context to be done and cancel the evm. Even if the 603 // EVM has finished, cancelling may be done (repeatedly) 604 go func() { 605 <-ctx.Done() 606 evm.Cancel() 607 }() 608 609 // Execute the message. 610 gp := new(core.GasPool).AddGas(math.MaxUint64) 611 result, err := core.ApplyMessage(evm, msg, gp) 612 if err := vmError(); err != nil { 613 return nil, err 614 } 615 616 // If the timer caused an abort, return an appropriate error message 617 if evm.Cancelled() { 618 return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout) 619 } 620 if err != nil { 621 return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas()) 622 } 623 return result, nil 624 } 625 626 func newRevertError(result *core.ExecutionResult) *revertError { 627 reason, errUnpack := abi.UnpackRevert(result.Revert()) 628 err := errors.New("execution reverted") 629 if errUnpack == nil { 630 err = fmt.Errorf("execution reverted: %v", reason) 631 } 632 return &revertError{ 633 error: err, 634 reason: hexutil.Encode(result.Revert()), 635 } 636 } 637 638 // revertError is an API error that encompassas an EVM revertal with JSON error 639 // code and a binary data blob. 640 type revertError struct { 641 error 642 reason string // revert reason hex encoded 643 } 644 645 // ErrorCode returns the JSON error code for a revertal. 646 func (e *revertError) ErrorCode() int { 647 return 3 648 } 649 650 // ErrorData returns the hex encoded revert reason. 651 func (e *revertError) ErrorData() interface{} { 652 return e.reason 653 } 654 655 // Call executes the given transaction on the state for the given block number. 656 // 657 // Additionally, the caller can specify a batch of contract for fields overriding. 658 // 659 // Note, this function doesn't make and changes in the state/blockchain and is 660 // useful to execute and retrieve values. 661 func (s *PublicBlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Bytes, error) { 662 nodeCtx := common.NodeLocation.Context() 663 if nodeCtx != common.ZONE_CTX { 664 return nil, errors.New("call can only called in zone chain") 665 } 666 if !s.b.ProcessingState() { 667 return nil, errors.New("evm call can only be made on chain processing the state") 668 } 669 result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, 5*time.Second, s.b.RPCGasCap()) 670 if err != nil { 671 return nil, err 672 } 673 // If the result contains a revert reason, try to unpack and return it. 674 if len(result.Revert()) > 0 { 675 return nil, newRevertError(result) 676 } 677 return result.Return(), result.Err 678 } 679 680 func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap uint64) (hexutil.Uint64, error) { 681 nodeCtx := common.NodeLocation.Context() 682 if nodeCtx != common.ZONE_CTX { 683 return 0, errors.New("doEstimateGas can only be called in zone chain") 684 } 685 if !b.ProcessingState() { 686 return 0, errors.New("doEstimateGas call can only be made on chain processing the state") 687 } 688 // Binary search the gas requirement, as it may be higher than the amount used 689 var ( 690 lo uint64 = params.TxGas - 1 691 hi uint64 692 cap uint64 693 ) 694 // Use zero address if sender unspecified. 695 if args.From == nil { 696 args.From = new(common.Address) 697 } 698 // Determine the highest gas limit can be used during the estimation. 699 if args.Gas != nil && uint64(*args.Gas) >= params.TxGas { 700 hi = uint64(*args.Gas) 701 } else { 702 // Retrieve the block to act as the gas ceiling 703 block, err := b.BlockByNumberOrHash(ctx, blockNrOrHash) 704 if err != nil { 705 return 0, err 706 } 707 if block == nil { 708 return 0, errors.New("block not found") 709 } 710 hi = block.GasLimit() 711 } 712 // Normalize the max fee per gas the call is willing to spend. 713 var feeCap *big.Int 714 if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) { 715 return 0, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") 716 } else if args.GasPrice != nil { 717 feeCap = args.GasPrice.ToInt() 718 } else if args.MaxFeePerGas != nil { 719 feeCap = args.MaxFeePerGas.ToInt() 720 } else { 721 feeCap = common.Big0 722 } 723 // Recap the highest gas limit with account's available balance. 724 if feeCap.BitLen() != 0 { 725 state, _, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 726 if err != nil { 727 return 0, err 728 } 729 internal, err := args.From.InternalAddress() 730 if err != nil { 731 return 0, err 732 } 733 balance := state.GetBalance(internal) // from can't be nil 734 available := new(big.Int).Set(balance) 735 if args.Value != nil { 736 if args.Value.ToInt().Cmp(available) >= 0 { 737 return 0, errors.New("insufficient funds for transfer") 738 } 739 available.Sub(available, args.Value.ToInt()) 740 } 741 allowance := new(big.Int).Div(available, feeCap) 742 743 // If the allowance is larger than maximum uint64, skip checking 744 if allowance.IsUint64() && hi > allowance.Uint64() { 745 transfer := args.Value 746 if transfer == nil { 747 transfer = new(hexutil.Big) 748 } 749 log.Debug("Gas estimation capped by limited funds", "original", hi, "balance", balance, 750 "sent", transfer.ToInt(), "maxFeePerGas", feeCap, "fundable", allowance) 751 hi = allowance.Uint64() 752 } 753 } 754 // Recap the highest gas allowance with specified gascap. 755 if gasCap != 0 && hi > gasCap { 756 log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", gasCap) 757 hi = gasCap 758 } 759 cap = hi 760 761 // Create a helper to check if a gas allowance results in an executable transaction 762 executable := func(gas uint64) (bool, *core.ExecutionResult, error) { 763 args.Gas = (*hexutil.Uint64)(&gas) 764 765 result, err := DoCall(ctx, b, args, blockNrOrHash, nil, 0, gasCap) 766 if err != nil { 767 if errors.Is(err, core.ErrIntrinsicGas) { 768 return true, nil, nil // Special case, raise gas limit 769 } 770 return true, nil, err // Bail out 771 } 772 return result.Failed(), result, nil 773 } 774 // Execute the binary search and hone in on an executable gas limit 775 for lo+1 < hi { 776 mid := (hi + lo) / 2 777 failed, _, err := executable(mid) 778 779 // If the error is not nil(consensus error), it means the provided message 780 // call or transaction will never be accepted no matter how much gas it is 781 // assigned. Return the error directly, don't struggle any more. 782 if err != nil { 783 return 0, err 784 } 785 if failed { 786 lo = mid 787 } else { 788 hi = mid 789 } 790 } 791 // Reject the transaction as invalid if it still fails at the highest allowance 792 if hi == cap { 793 failed, result, err := executable(hi) 794 if err != nil { 795 return 0, err 796 } 797 if failed { 798 if result != nil && result.Err != vm.ErrOutOfGas { 799 if len(result.Revert()) > 0 { 800 return 0, newRevertError(result) 801 } 802 return 0, result.Err 803 } 804 // Otherwise, the specified gas cap is too low 805 return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) 806 } 807 } 808 return hexutil.Uint64(hi), nil 809 } 810 811 // EstimateGas returns an estimate of the amount of gas needed to execute the 812 // given transaction against the current pending block. 813 func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) { 814 nodeCtx := common.NodeLocation.Context() 815 if nodeCtx != common.ZONE_CTX { 816 return 0, errors.New("estimateGas can only be called in zone chain") 817 } 818 if !s.b.ProcessingState() { 819 return 0, errors.New("estimateGas call can only be made on chain processing the state") 820 } 821 bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) 822 if blockNrOrHash != nil { 823 bNrOrHash = *blockNrOrHash 824 } 825 return DoEstimateGas(ctx, s.b, args, bNrOrHash, s.b.RPCGasCap()) 826 } 827 828 // ExecutionResult groups all structured logs emitted by the EVM 829 // while replaying a transaction in debug mode as well as transaction 830 // execution status, the amount of gas used and the return value 831 type ExecutionResult struct { 832 Gas uint64 `json:"gas"` 833 Failed bool `json:"failed"` 834 ReturnValue string `json:"returnValue"` 835 StructLogs []StructLogRes `json:"structLogs"` 836 } 837 838 // StructLogRes stores a structured log emitted by the EVM while replaying a 839 // transaction in debug mode 840 type StructLogRes struct { 841 Pc uint64 `json:"pc"` 842 Op string `json:"op"` 843 Gas uint64 `json:"gas"` 844 GasCost uint64 `json:"gasCost"` 845 Depth int `json:"depth"` 846 Error string `json:"error,omitempty"` 847 Stack *[]string `json:"stack,omitempty"` 848 Memory *[]string `json:"memory,omitempty"` 849 Storage *map[string]string `json:"storage,omitempty"` 850 } 851 852 // FormatLogs formats EVM returned structured logs for json output 853 func FormatLogs(logs []vm.StructLog) []StructLogRes { 854 formatted := make([]StructLogRes, len(logs)) 855 for index, trace := range logs { 856 formatted[index] = StructLogRes{ 857 Pc: trace.Pc, 858 Op: trace.Op.String(), 859 Gas: trace.Gas, 860 GasCost: trace.GasCost, 861 Depth: trace.Depth, 862 Error: trace.ErrorString(), 863 } 864 if trace.Stack != nil { 865 stack := make([]string, len(trace.Stack)) 866 for i, stackValue := range trace.Stack { 867 stack[i] = stackValue.Hex() 868 } 869 formatted[index].Stack = &stack 870 } 871 if trace.Memory != nil { 872 memory := make([]string, 0, (len(trace.Memory)+31)/32) 873 for i := 0; i+32 <= len(trace.Memory); i += 32 { 874 memory = append(memory, fmt.Sprintf("%x", trace.Memory[i:i+32])) 875 } 876 formatted[index].Memory = &memory 877 } 878 if trace.Storage != nil { 879 storage := make(map[string]string) 880 for i, storageValue := range trace.Storage { 881 storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue) 882 } 883 formatted[index].Storage = &storage 884 } 885 } 886 return formatted 887 } 888 889 // RPCMarshalHeader converts the given header to the RPC output . 890 func RPCMarshalETHHeader(head *types.Header) map[string]interface{} { 891 result := map[string]interface{}{ 892 "number": (*hexutil.Big)(head.Number()), 893 "hash": head.Hash(), 894 "parentHash": head.ParentHash, 895 "nonce": head.Nonce, 896 "sha3Uncles": head.UncleHash, 897 "stateRoot": head.Root, 898 "miner": head.Coinbase, 899 "difficulty": (*hexutil.Big)(head.Difficulty()), 900 "extraData": hexutil.Bytes(head.Extra()), 901 "size": hexutil.Uint64(head.Size()), 902 "gasLimit": hexutil.Uint64(head.GasLimit()), 903 "gasUsed": hexutil.Uint64(head.GasUsed()), 904 "baseFee": hexutil.Big(*head.BaseFee()), 905 "location": head.Location(), 906 "timestamp": hexutil.Uint64(head.Time()), 907 "transactionsRoot": head.TxHash, 908 "receiptsRoot": head.ReceiptHash, 909 } 910 911 return result 912 } 913 914 // RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are 915 // returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain 916 // transaction hashes. 917 func RPCMarshalETHBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { 918 fields := RPCMarshalETHHeader(block.Header()) 919 fields["size"] = hexutil.Uint64(block.Size()) 920 921 if inclTx { 922 formatTx := func(tx *types.Transaction) (interface{}, error) { 923 return tx.Hash(), nil 924 } 925 if fullTx { 926 formatTx = func(tx *types.Transaction) (interface{}, error) { 927 return newRPCTransactionFromBlockHash(block, tx.Hash(), false), nil 928 } 929 } 930 txs := block.Transactions() 931 transactions := make([]interface{}, len(txs)) 932 var err error 933 for i, tx := range txs { 934 if transactions[i], err = formatTx(tx); err != nil { 935 return nil, err 936 } 937 } 938 fields["transactions"] = transactions 939 } 940 uncles := block.Uncles() 941 uncleHashes := make([]common.Hash, len(uncles)) 942 for i, uncle := range uncles { 943 uncleHashes[i] = uncle.Hash() 944 } 945 fields["uncles"] = uncleHashes 946 947 return fields, nil 948 } 949 950 // rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires 951 // a `PublicBlockchainAPI`. 952 func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *types.Header) map[string]interface{} { 953 fields := RPCMarshalETHHeader(header) 954 fields["totalEntropy"] = (*hexutil.Big)(s.b.TotalLogS(header)) 955 return fields 956 } 957 958 // rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires 959 // a `PublicBlockchainAPI`. 960 func (s *PublicBlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { 961 fields, err := RPCMarshalBlock(b, inclTx, fullTx) 962 if err != nil { 963 return nil, err 964 } 965 fields["totalEntropy"] = (*hexutil.Big)(s.b.TotalLogS(b.Header())) 966 return fields, err 967 } 968 969 // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction 970 type RPCTransaction struct { 971 BlockHash *common.Hash `json:"blockHash"` 972 BlockNumber *hexutil.Big `json:"blockNumber"` 973 From common.Address `json:"from"` 974 Gas hexutil.Uint64 `json:"gas"` 975 GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` 976 GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` 977 Hash common.Hash `json:"hash"` 978 Input hexutil.Bytes `json:"input"` 979 Nonce hexutil.Uint64 `json:"nonce"` 980 To *common.Address `json:"to"` 981 TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` 982 Value *hexutil.Big `json:"value"` 983 Type hexutil.Uint64 `json:"type"` 984 Accesses *types.AccessList `json:"accessList,omitempty"` 985 ChainID *hexutil.Big `json:"chainId,omitempty"` 986 V *hexutil.Big `json:"v"` 987 R *hexutil.Big `json:"r"` 988 S *hexutil.Big `json:"s"` 989 // Optional fields only present for external transactions 990 Sender *common.Address `json:"sender,omitempty"` 991 992 ETXGasLimit hexutil.Uint64 `json:"etxGasLimit,omitempty"` 993 ETXGasPrice *hexutil.Big `json:"etxGasPrice,omitempty"` 994 ETXGasTip *hexutil.Big `json:"etxGasTip,omitempty"` 995 ETXData *hexutil.Bytes `json:"etxData,omitempty"` 996 ETXAccessList *types.AccessList `json:"etxAccessList,omitempty"` 997 } 998 999 // newRPCTransaction returns a transaction that will serialize to the RPC 1000 // representation, with the given location metadata set (if available). 1001 func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64, baseFee *big.Int) *RPCTransaction { 1002 nodeCtx := common.NodeLocation.Context() 1003 if nodeCtx != common.ZONE_CTX { 1004 return nil 1005 } 1006 // Determine the signer. For replay-protected transactions, use the most permissive 1007 // signer, because we assume that signers are backwards-compatible with old 1008 // transactions. For non-protected transactions, the signer is used 1009 // because the return value of ChainId is zero for those transactions. 1010 var signer types.Signer 1011 signer = types.LatestSignerForChainID(tx.ChainId()) 1012 from, _ := types.Sender(signer, tx) 1013 var result *RPCTransaction 1014 switch tx.Type() { 1015 case types.InternalTxType: 1016 result = &RPCTransaction{ 1017 Type: hexutil.Uint64(tx.Type()), 1018 From: from, 1019 Gas: hexutil.Uint64(tx.Gas()), 1020 Hash: tx.Hash(), 1021 Input: hexutil.Bytes(tx.Data()), 1022 Nonce: hexutil.Uint64(tx.Nonce()), 1023 To: tx.To(), 1024 Value: (*hexutil.Big)(tx.Value()), 1025 ChainID: (*hexutil.Big)(tx.ChainId()), 1026 GasFeeCap: (*hexutil.Big)(tx.GasFeeCap()), 1027 GasTipCap: (*hexutil.Big)(tx.GasTipCap()), 1028 } 1029 case types.ExternalTxType: 1030 result = &RPCTransaction{ 1031 Type: hexutil.Uint64(tx.Type()), 1032 Gas: hexutil.Uint64(tx.Gas()), 1033 Hash: tx.Hash(), 1034 Input: hexutil.Bytes(tx.Data()), 1035 Nonce: hexutil.Uint64(tx.Nonce()), 1036 To: tx.To(), 1037 Value: (*hexutil.Big)(tx.Value()), 1038 ChainID: (*hexutil.Big)(tx.ChainId()), 1039 GasFeeCap: (*hexutil.Big)(tx.GasFeeCap()), 1040 GasTipCap: (*hexutil.Big)(tx.GasTipCap()), 1041 } 1042 sender := tx.ETXSender() 1043 result.Sender = &sender 1044 case types.InternalToExternalTxType: 1045 result = &RPCTransaction{ 1046 Type: hexutil.Uint64(tx.Type()), 1047 From: from, 1048 Gas: hexutil.Uint64(tx.Gas()), 1049 Hash: tx.Hash(), 1050 Input: hexutil.Bytes(tx.Data()), 1051 Nonce: hexutil.Uint64(tx.Nonce()), 1052 To: tx.To(), 1053 Value: (*hexutil.Big)(tx.Value()), 1054 ChainID: (*hexutil.Big)(tx.ChainId()), 1055 GasFeeCap: (*hexutil.Big)(tx.GasFeeCap()), 1056 GasTipCap: (*hexutil.Big)(tx.GasTipCap()), 1057 ETXGasLimit: (hexutil.Uint64)(tx.ETXGasLimit()), 1058 ETXGasPrice: (*hexutil.Big)(tx.ETXGasPrice()), 1059 ETXGasTip: (*hexutil.Big)(tx.ETXGasTip()), 1060 } 1061 data := tx.ETXData() 1062 result.ETXData = (*hexutil.Bytes)(&data) 1063 eal := tx.ETXAccessList() 1064 result.ETXAccessList = &eal 1065 } 1066 if blockHash != (common.Hash{}) { 1067 result.BlockHash = &blockHash 1068 result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber)) 1069 result.TransactionIndex = (*hexutil.Uint64)(&index) 1070 } 1071 if tx.Type() != types.ExternalTxType { 1072 v, r, s := tx.RawSignatureValues() 1073 result.V = (*hexutil.Big)(v) 1074 result.R = (*hexutil.Big)(r) 1075 result.S = (*hexutil.Big)(s) 1076 } 1077 al := tx.AccessList() 1078 result.Accesses = &al 1079 return result 1080 } 1081 1082 // newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation 1083 func newRPCPendingTransaction(tx *types.Transaction, current *types.Header, config *params.ChainConfig) *RPCTransaction { 1084 var baseFee *big.Int 1085 if current != nil { 1086 baseFee = misc.CalcBaseFee(config, current) 1087 } 1088 return newRPCTransaction(tx, common.Hash{}, 0, 0, baseFee) 1089 } 1090 1091 // newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation. 1092 func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, etxs bool) *RPCTransaction { 1093 var txs types.Transactions 1094 if etxs { 1095 txs = b.ExtTransactions() 1096 } else { 1097 txs = b.Transactions() 1098 } 1099 if index >= uint64(len(txs)) { 1100 return nil 1101 } 1102 return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index, b.BaseFee()) 1103 } 1104 1105 // newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index. 1106 func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) hexutil.Bytes { 1107 txs := b.Transactions() 1108 if index >= uint64(len(txs)) { 1109 return nil 1110 } 1111 blob, _ := txs[index].MarshalBinary() 1112 return blob 1113 } 1114 1115 // newRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation. 1116 func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash, etxs bool) *RPCTransaction { 1117 if etxs { 1118 for idx, tx := range b.ExtTransactions() { 1119 if tx.Hash() == hash { 1120 return newRPCTransactionFromBlockIndex(b, uint64(idx), true) 1121 } 1122 } 1123 } 1124 for idx, tx := range b.Transactions() { 1125 if tx.Hash() == hash { 1126 return newRPCTransactionFromBlockIndex(b, uint64(idx), false) 1127 } 1128 } 1129 return nil 1130 } 1131 1132 // accessListResult returns an optional accesslist 1133 // Its the result of the `debug_createAccessList` RPC call. 1134 // It contains an error if the transaction itself failed. 1135 type accessListResult struct { 1136 Accesslist *types.AccessList `json:"accessList"` 1137 Error string `json:"error,omitempty"` 1138 GasUsed hexutil.Uint64 `json:"gasUsed"` 1139 } 1140 1141 // CreateAccessList creates an AccessList for the given transaction. 1142 // Reexec and BlockNrOrHash can be specified to create the accessList on top of a certain state. 1143 func (s *PublicBlockChainAPI) CreateAccessList(ctx context.Context, args TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash) (*accessListResult, error) { 1144 nodeCtx := common.NodeLocation.Context() 1145 if nodeCtx != common.ZONE_CTX { 1146 return nil, errors.New("createAccessList can only be called in zone chain") 1147 } 1148 if !s.b.ProcessingState() { 1149 return nil, errors.New("createAccessList call can only be made on chain processing the state") 1150 } 1151 bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) 1152 if blockNrOrHash != nil { 1153 bNrOrHash = *blockNrOrHash 1154 } 1155 acl, gasUsed, vmerr, err := AccessList(ctx, s.b, bNrOrHash, args) 1156 if err != nil { 1157 return nil, err 1158 } 1159 result := &accessListResult{Accesslist: &acl, GasUsed: hexutil.Uint64(gasUsed)} 1160 if vmerr != nil { 1161 result.Error = vmerr.Error() 1162 } 1163 return result, nil 1164 } 1165 1166 // AccessList creates an access list for the given transaction. 1167 // If the accesslist creation fails an error is returned. 1168 // If the transaction itself fails, an vmErr is returned. 1169 func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrHash, args TransactionArgs) (acl types.AccessList, gasUsed uint64, vmErr error, err error) { 1170 nodeCtx := common.NodeLocation.Context() 1171 if nodeCtx != common.ZONE_CTX { 1172 return nil, 0, nil, errors.New("AccessList can only be called in zone chain") 1173 } 1174 if !b.ProcessingState() { 1175 return nil, 0, nil, errors.New("accessList call can only be made on chain processing the state") 1176 } 1177 // Retrieve the execution context 1178 db, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 1179 if db == nil || err != nil { 1180 return nil, 0, nil, err 1181 } 1182 // If the gas amount is not set, extract this as it will depend on access 1183 // lists and we'll need to reestimate every time 1184 nogas := args.Gas == nil 1185 1186 // Ensure any missing fields are filled, extract the recipient and input data 1187 if err := args.setDefaults(ctx, b); err != nil { 1188 return nil, 0, nil, err 1189 } 1190 var to common.Address 1191 if args.To != nil { 1192 to = *args.To 1193 } else { 1194 to = crypto.CreateAddress(args.from(), uint64(*args.Nonce), *args.Data) 1195 } 1196 // Retrieve the precompiles since they don't need to be added to the access list 1197 precompiles := vm.ActivePrecompiles(b.ChainConfig().Rules(header.Number())) 1198 1199 // Create an initial tracer 1200 prevTracer := vm.NewAccessListTracer(nil, args.from(), to, precompiles) 1201 if args.AccessList != nil { 1202 prevTracer = vm.NewAccessListTracer(*args.AccessList, args.from(), to, precompiles) 1203 } 1204 for { 1205 // Retrieve the current access list to expand 1206 accessList := prevTracer.AccessList() 1207 log.Trace("Creating access list", "input", accessList) 1208 1209 // If no gas amount was specified, each unique access list needs it's own 1210 // gas calculation. This is quite expensive, but we need to be accurate 1211 // and it's convered by the sender only anyway. 1212 if nogas { 1213 args.Gas = nil 1214 if err := args.setDefaults(ctx, b); err != nil { 1215 return nil, 0, nil, err // shouldn't happen, just in case 1216 } 1217 } 1218 // Copy the original db so we don't modify it 1219 statedb := db.Copy() 1220 // Set the accesslist to the last al 1221 args.AccessList = &accessList 1222 msg, err := args.ToMessage(b.RPCGasCap(), header.BaseFee()) 1223 if err != nil { 1224 return nil, 0, nil, err 1225 } 1226 1227 // Apply the transaction with the access list tracer 1228 tracer := vm.NewAccessListTracer(accessList, args.from(), to, precompiles) 1229 config := vm.Config{Tracer: tracer, Debug: true, NoBaseFee: true} 1230 vmenv, _, err := b.GetEVM(ctx, msg, statedb, header, &config) 1231 if err != nil { 1232 return nil, 0, nil, err 1233 } 1234 res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())) 1235 if err != nil { 1236 return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", msg, err) 1237 } 1238 if tracer.Equal(prevTracer) { 1239 return accessList, res.UsedGas, res.Err, nil 1240 } 1241 prevTracer = tracer 1242 } 1243 } 1244 1245 // PublicTransactionPoolAPI exposes methods for the RPC interface 1246 type PublicTransactionPoolAPI struct { 1247 b Backend 1248 nonceLock *AddrLocker 1249 signer types.Signer 1250 } 1251 1252 // NewPublicTransactionPoolAPI creates a new RPC service with methods specific for the transaction pool. 1253 func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransactionPoolAPI { 1254 // The signer used by the API should always be the 'latest' known one because we expect 1255 // signers to be backwards-compatible with old transactions. 1256 signer := types.LatestSigner(b.ChainConfig()) 1257 return &PublicTransactionPoolAPI{b, nonceLock, signer} 1258 } 1259 1260 // GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number. 1261 func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 1262 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 1263 n := hexutil.Uint(len(block.Transactions())) 1264 return &n 1265 } 1266 return nil 1267 } 1268 1269 // GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash. 1270 func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 1271 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 1272 n := hexutil.Uint(len(block.Transactions())) 1273 return &n 1274 } 1275 return nil 1276 } 1277 1278 // GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index. 1279 func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction { 1280 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 1281 return newRPCTransactionFromBlockIndex(block, uint64(index), false) 1282 } 1283 return nil 1284 } 1285 1286 // GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index. 1287 func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction { 1288 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 1289 return newRPCTransactionFromBlockIndex(block, uint64(index), false) 1290 } 1291 return nil 1292 } 1293 1294 // GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index. 1295 func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) hexutil.Bytes { 1296 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 1297 return newRPCRawTransactionFromBlockIndex(block, uint64(index)) 1298 } 1299 return nil 1300 } 1301 1302 // GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index. 1303 func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) hexutil.Bytes { 1304 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 1305 return newRPCRawTransactionFromBlockIndex(block, uint64(index)) 1306 } 1307 return nil 1308 } 1309 1310 // GetTransactionCount returns the number of transactions the given address has sent for the given block number 1311 func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Uint64, error) { 1312 // Ask transaction pool for the nonce which includes pending transactions 1313 if blockNr, ok := blockNrOrHash.Number(); ok && blockNr == rpc.PendingBlockNumber { 1314 nonce, err := s.b.GetPoolNonce(ctx, address) 1315 if err != nil { 1316 return nil, err 1317 } 1318 return (*hexutil.Uint64)(&nonce), nil 1319 } 1320 // Resolve block number and use its state to ask for the nonce 1321 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 1322 if state == nil || err != nil { 1323 return nil, err 1324 } 1325 internal, err := address.InternalAddress() 1326 if err != nil { 1327 return nil, err 1328 } 1329 nonce := state.GetNonce(internal) 1330 return (*hexutil.Uint64)(&nonce), state.Error() 1331 } 1332 1333 // GetTransactionByHash returns the transaction for the given hash 1334 func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) { 1335 // Try to return an already finalized transaction 1336 tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash) 1337 if err != nil { 1338 return nil, err 1339 } 1340 if tx != nil { 1341 header, err := s.b.HeaderByHash(ctx, blockHash) 1342 if err != nil { 1343 return nil, err 1344 } 1345 return newRPCTransaction(tx, blockHash, blockNumber, index, header.BaseFee()), nil 1346 } 1347 // No finalized transaction, try to retrieve it from the pool 1348 if tx := s.b.GetPoolTransaction(hash); tx != nil { 1349 return newRPCPendingTransaction(tx, s.b.CurrentHeader(), s.b.ChainConfig()), nil 1350 } 1351 1352 // Transaction unknown, return as such 1353 return nil, nil 1354 } 1355 1356 // GetRawTransactionByHash returns the bytes of the transaction for the given hash. 1357 func (s *PublicTransactionPoolAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { 1358 // Retrieve a finalized transaction, or a pooled otherwise 1359 tx, _, _, _, err := s.b.GetTransaction(ctx, hash) 1360 if err != nil { 1361 return nil, err 1362 } 1363 if tx == nil { 1364 if tx = s.b.GetPoolTransaction(hash); tx == nil { 1365 // Transaction not found anywhere, abort 1366 return nil, nil 1367 } 1368 } 1369 // Serialize to RLP and return 1370 return tx.MarshalBinary() 1371 } 1372 1373 // GetTransactionReceipt returns the transaction receipt for the given transaction hash. 1374 func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { 1375 tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash) 1376 if err != nil { 1377 return nil, nil 1378 } 1379 receipts, err := s.b.GetReceipts(ctx, blockHash) 1380 if err != nil { 1381 return nil, err 1382 } 1383 if len(receipts) <= int(index) { 1384 return nil, nil 1385 } 1386 receipt := receipts[index] 1387 1388 // Derive the sender. 1389 bigblock := new(big.Int).SetUint64(blockNumber) 1390 signer := types.MakeSigner(s.b.ChainConfig(), bigblock) 1391 from, _ := types.Sender(signer, tx) 1392 1393 fields := map[string]interface{}{ 1394 "blockHash": blockHash, 1395 "blockNumber": hexutil.Uint64(blockNumber), 1396 "transactionHash": hash, 1397 "transactionIndex": hexutil.Uint64(index), 1398 "from": from, 1399 "to": tx.To(), 1400 "gasUsed": hexutil.Uint64(receipt.GasUsed), 1401 "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), 1402 "contractAddress": nil, 1403 "logs": receipt.Logs, 1404 "etxs": receipt.Etxs, 1405 "logsBloom": receipt.Bloom, 1406 "type": hexutil.Uint(tx.Type()), 1407 } 1408 // Assign the effective gas price paid 1409 header, err := s.b.HeaderByHash(ctx, blockHash) 1410 if err != nil { 1411 return nil, err 1412 } 1413 gasPrice := new(big.Int).Add(header.BaseFee(), tx.EffectiveGasTipValue(header.BaseFee())) 1414 fields["effectiveGasPrice"] = hexutil.Uint64(gasPrice.Uint64()) 1415 1416 // Assign receipt status or post state. 1417 if len(receipt.PostState) > 0 { 1418 fields["root"] = hexutil.Bytes(receipt.PostState) 1419 } else { 1420 fields["status"] = hexutil.Uint(receipt.Status) 1421 } 1422 if receipt.Logs == nil { 1423 fields["logs"] = [][]*types.Log{} 1424 } 1425 // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation 1426 if !receipt.ContractAddress.Equal(common.ZeroAddr) { 1427 fields["contractAddress"] = receipt.ContractAddress 1428 } 1429 return fields, nil 1430 } 1431 1432 // SubmitTransaction is a helper function that submits tx to txPool and logs a message. 1433 func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) { 1434 nodeCtx := common.NodeLocation.Context() 1435 if nodeCtx != common.ZONE_CTX { 1436 return common.Hash{}, errors.New("submitTransaction can only be called in zone chain") 1437 } 1438 if !b.ProcessingState() { 1439 return common.Hash{}, errors.New("submitTransaction call can only be made on chain processing the state") 1440 } 1441 // If the transaction fee cap is already specified, ensure the 1442 // fee of the given transaction is _reasonable_. 1443 if err := checkTxFee(tx.GasPrice(), tx.Gas(), b.RPCTxFeeCap()); err != nil { 1444 return common.Hash{}, err 1445 } 1446 if err := b.SendTx(ctx, tx); err != nil { 1447 return common.Hash{}, err 1448 } 1449 // Print a log with full tx details for manual investigations and interventions 1450 signer := types.MakeSigner(b.ChainConfig(), b.CurrentHeader().Number()) 1451 from, err := types.Sender(signer, tx) 1452 if err != nil { 1453 return common.Hash{}, err 1454 } 1455 1456 if tx.To() == nil { 1457 addr := crypto.CreateAddress(from, tx.Nonce(), tx.Data()) 1458 log.Debug("Submitted contract creation", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "contract", addr.Hex(), "value", tx.Value()) 1459 } else { 1460 log.Debug("Submitted transaction", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "recipient", tx.To(), "value", tx.Value()) 1461 } 1462 return tx.Hash(), nil 1463 } 1464 1465 // SendRawTransaction will add the signed transaction to the transaction pool. 1466 // The sender is responsible for signing the transaction and using the correct nonce. 1467 func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, input hexutil.Bytes) (common.Hash, error) { 1468 tx := new(types.Transaction) 1469 if err := tx.UnmarshalBinary(input); err != nil { 1470 return common.Hash{}, err 1471 } 1472 return SubmitTransaction(ctx, s.b, tx) 1473 } 1474 1475 // PublicDebugAPI is the collection of Quai APIs exposed over the public 1476 // debugging endpoint. 1477 type PublicDebugAPI struct { 1478 b Backend 1479 } 1480 1481 // NewPublicDebugAPI creates a new API definition for the public debug methods 1482 // of the Quai service. 1483 func NewPublicDebugAPI(b Backend) *PublicDebugAPI { 1484 return &PublicDebugAPI{b: b} 1485 } 1486 1487 // GetBlockRlp retrieves the RLP encoded for of a single block. 1488 func (api *PublicDebugAPI) GetBlockRlp(ctx context.Context, number uint64) (string, error) { 1489 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 1490 if block == nil { 1491 return "", fmt.Errorf("block #%d not found", number) 1492 } 1493 encoded, err := rlp.EncodeToBytes(block) 1494 if err != nil { 1495 return "", err 1496 } 1497 return fmt.Sprintf("%x", encoded), nil 1498 } 1499 1500 // PrintBlock retrieves a block and returns its pretty printed form. 1501 func (api *PublicDebugAPI) PrintBlock(ctx context.Context, number uint64) (string, error) { 1502 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 1503 if block == nil { 1504 return "", fmt.Errorf("block #%d not found", number) 1505 } 1506 return spew.Sdump(block), nil 1507 } 1508 1509 // SeedHash retrieves the seed hash of a block. 1510 func (api *PublicDebugAPI) SeedHash(ctx context.Context, number uint64) (string, error) { 1511 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 1512 if block == nil { 1513 return "", fmt.Errorf("block #%d not found", number) 1514 } 1515 return fmt.Sprintf("0x%x", progpow.SeedHash(number)), nil 1516 } 1517 1518 // PrivateDebugAPI is the collection of Quai APIs exposed over the private 1519 // debugging endpoint. 1520 type PrivateDebugAPI struct { 1521 b Backend 1522 } 1523 1524 // NewPrivateDebugAPI creates a new API definition for the private debug methods 1525 // of the Quai service. 1526 func NewPrivateDebugAPI(b Backend) *PrivateDebugAPI { 1527 return &PrivateDebugAPI{b: b} 1528 } 1529 1530 // ChaindbProperty returns leveldb properties of the key-value database. 1531 func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) { 1532 if property == "" { 1533 property = "leveldb.stats" 1534 } else if !strings.HasPrefix(property, "leveldb.") { 1535 property = "leveldb." + property 1536 } 1537 return api.b.ChainDb().Stat(property) 1538 } 1539 1540 // ChaindbCompact flattens the entire key-value database into a single level, 1541 // removing all unused slots and merging all keys. 1542 func (api *PrivateDebugAPI) ChaindbCompact() error { 1543 for b := byte(0); b < 255; b++ { 1544 log.Info("Compacting chain database", "range", fmt.Sprintf("0x%0.2X-0x%0.2X", b, b+1)) 1545 if err := api.b.ChainDb().Compact([]byte{b}, []byte{b + 1}); err != nil { 1546 log.Error("Database compaction failed", "err", err) 1547 return err 1548 } 1549 } 1550 return nil 1551 } 1552 1553 // PublicNetAPI offers network related RPC methods 1554 type PublicNetAPI struct { 1555 net *p2p.Server 1556 networkVersion uint64 1557 } 1558 1559 // NewPublicNetAPI creates a new net API instance. 1560 func NewPublicNetAPI(net *p2p.Server, networkVersion uint64) *PublicNetAPI { 1561 return &PublicNetAPI{net, networkVersion} 1562 } 1563 1564 // Listening returns an indication if the node is listening for network connections. 1565 func (s *PublicNetAPI) Listening() bool { 1566 return true // always listening 1567 } 1568 1569 // PeerCount returns the number of connected peers 1570 func (s *PublicNetAPI) PeerCount() hexutil.Uint { 1571 return hexutil.Uint(s.net.PeerCount()) 1572 } 1573 1574 // Version returns the current Quai protocol version. 1575 func (s *PublicNetAPI) Version() string { 1576 return fmt.Sprintf("%d", s.networkVersion) 1577 } 1578 1579 // checkTxFee is an internal function used to check whether the fee of 1580 // the given transaction is _reasonable_(under the cap). 1581 func checkTxFee(gasPrice *big.Int, gas uint64, cap float64) error { 1582 // Short circuit if there is no cap for transaction fee at all. 1583 if cap == 0 { 1584 return nil 1585 } 1586 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.Ether))) 1587 feeFloat, _ := feeEth.Float64() 1588 if feeFloat > cap { 1589 return fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, cap) 1590 } 1591 return nil 1592 } 1593 1594 // toHexSlice creates a slice of hex-strings based on []byte. 1595 func toHexSlice(b [][]byte) []string { 1596 r := make([]string, len(b)) 1597 for i := range b { 1598 r[i] = hexutil.Encode(b[i]) 1599 } 1600 return r 1601 }