github.com/phillinzzz/newBsc@v1.1.6/internal/ethapi/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 ethapi 18 19 import ( 20 "bytes" 21 "context" 22 "errors" 23 "fmt" 24 "math/big" 25 "strings" 26 "time" 27 28 "github.com/davecgh/go-spew/spew" 29 30 "github.com/phillinzzz/newBsc/accounts" 31 "github.com/phillinzzz/newBsc/accounts/abi" 32 "github.com/phillinzzz/newBsc/accounts/keystore" 33 "github.com/phillinzzz/newBsc/accounts/scwallet" 34 "github.com/phillinzzz/newBsc/common" 35 "github.com/phillinzzz/newBsc/common/gopool" 36 "github.com/phillinzzz/newBsc/common/hexutil" 37 "github.com/phillinzzz/newBsc/common/math" 38 "github.com/phillinzzz/newBsc/consensus" 39 "github.com/phillinzzz/newBsc/consensus/clique" 40 "github.com/phillinzzz/newBsc/consensus/ethash" 41 "github.com/phillinzzz/newBsc/core" 42 "github.com/phillinzzz/newBsc/core/rawdb" 43 "github.com/phillinzzz/newBsc/core/state" 44 "github.com/phillinzzz/newBsc/core/types" 45 "github.com/phillinzzz/newBsc/core/vm" 46 "github.com/phillinzzz/newBsc/crypto" 47 "github.com/phillinzzz/newBsc/log" 48 "github.com/phillinzzz/newBsc/p2p" 49 "github.com/phillinzzz/newBsc/params" 50 "github.com/phillinzzz/newBsc/rlp" 51 "github.com/phillinzzz/newBsc/rpc" 52 "github.com/tyler-smith/go-bip39" 53 ) 54 55 const UnHealthyTimeout = 5 * time.Second 56 57 // PublicEthereumAPI provides an API to access Ethereum related information. 58 // It offers only methods that operate on public data that is freely available to anyone. 59 type PublicEthereumAPI struct { 60 b Backend 61 } 62 63 // NewPublicEthereumAPI creates a new Ethereum protocol API. 64 func NewPublicEthereumAPI(b Backend) *PublicEthereumAPI { 65 return &PublicEthereumAPI{b} 66 } 67 68 // GasPrice returns a suggestion for a gas price. 69 func (s *PublicEthereumAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { 70 price, err := s.b.SuggestPrice(ctx) 71 return (*hexutil.Big)(price), err 72 } 73 74 // Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not 75 // yet received the latest block headers from its pears. In case it is synchronizing: 76 // - startingBlock: block number this node started to synchronise from 77 // - currentBlock: block number this node is currently importing 78 // - highestBlock: block number of the highest block header this node has received from peers 79 // - pulledStates: number of state entries processed until now 80 // - knownStates: number of known state entries that still need to be pulled 81 func (s *PublicEthereumAPI) Syncing() (interface{}, error) { 82 progress := s.b.Downloader().Progress() 83 84 // Return not syncing if the synchronisation already completed 85 if progress.CurrentBlock >= progress.HighestBlock { 86 return false, nil 87 } 88 // Otherwise gather the block sync stats 89 return map[string]interface{}{ 90 "startingBlock": hexutil.Uint64(progress.StartingBlock), 91 "currentBlock": hexutil.Uint64(progress.CurrentBlock), 92 "highestBlock": hexutil.Uint64(progress.HighestBlock), 93 "pulledStates": hexutil.Uint64(progress.PulledStates), 94 "knownStates": hexutil.Uint64(progress.KnownStates), 95 }, nil 96 } 97 98 // PublicTxPoolAPI offers and API for the transaction pool. It only operates on data that is non confidential. 99 type PublicTxPoolAPI struct { 100 b Backend 101 } 102 103 // NewPublicTxPoolAPI creates a new tx pool service that gives information about the transaction pool. 104 func NewPublicTxPoolAPI(b Backend) *PublicTxPoolAPI { 105 return &PublicTxPoolAPI{b} 106 } 107 108 // Content returns the transactions contained within the transaction pool. 109 func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { 110 content := map[string]map[string]map[string]*RPCTransaction{ 111 "pending": make(map[string]map[string]*RPCTransaction), 112 "queued": make(map[string]map[string]*RPCTransaction), 113 } 114 pending, queue := s.b.TxPoolContent() 115 116 // Flatten the pending transactions 117 for account, txs := range pending { 118 dump := make(map[string]*RPCTransaction) 119 for _, tx := range txs { 120 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx) 121 } 122 content["pending"][account.Hex()] = dump 123 } 124 // Flatten the queued transactions 125 for account, txs := range queue { 126 dump := make(map[string]*RPCTransaction) 127 for _, tx := range txs { 128 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx) 129 } 130 content["queued"][account.Hex()] = dump 131 } 132 return content 133 } 134 135 // Status returns the number of pending and queued transaction in the pool. 136 func (s *PublicTxPoolAPI) Status() map[string]hexutil.Uint { 137 pending, queue := s.b.Stats() 138 return map[string]hexutil.Uint{ 139 "pending": hexutil.Uint(pending), 140 "queued": hexutil.Uint(queue), 141 } 142 } 143 144 // Inspect retrieves the content of the transaction pool and flattens it into an 145 // easily inspectable list. 146 func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string]string { 147 content := map[string]map[string]map[string]string{ 148 "pending": make(map[string]map[string]string), 149 "queued": make(map[string]map[string]string), 150 } 151 pending, queue := s.b.TxPoolContent() 152 153 // Define a formatter to flatten a transaction into a string 154 var format = func(tx *types.Transaction) string { 155 if to := tx.To(); to != nil { 156 return fmt.Sprintf("%s: %v wei + %v gas × %v wei", tx.To().Hex(), tx.Value(), tx.Gas(), tx.GasPrice()) 157 } 158 return fmt.Sprintf("contract creation: %v wei + %v gas × %v wei", tx.Value(), tx.Gas(), tx.GasPrice()) 159 } 160 // Flatten the pending transactions 161 for account, txs := range pending { 162 dump := make(map[string]string) 163 for _, tx := range txs { 164 dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) 165 } 166 content["pending"][account.Hex()] = dump 167 } 168 // Flatten the queued transactions 169 for account, txs := range queue { 170 dump := make(map[string]string) 171 for _, tx := range txs { 172 dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) 173 } 174 content["queued"][account.Hex()] = dump 175 } 176 return content 177 } 178 179 // PublicAccountAPI provides an API to access accounts managed by this node. 180 // It offers only methods that can retrieve accounts. 181 type PublicAccountAPI struct { 182 am *accounts.Manager 183 } 184 185 // NewPublicAccountAPI creates a new PublicAccountAPI. 186 func NewPublicAccountAPI(am *accounts.Manager) *PublicAccountAPI { 187 return &PublicAccountAPI{am: am} 188 } 189 190 // Accounts returns the collection of accounts this node manages 191 func (s *PublicAccountAPI) Accounts() []common.Address { 192 return s.am.Accounts() 193 } 194 195 // PrivateAccountAPI provides an API to access accounts managed by this node. 196 // It offers methods to create, (un)lock en list accounts. Some methods accept 197 // passwords and are therefore considered private by default. 198 type PrivateAccountAPI struct { 199 am *accounts.Manager 200 nonceLock *AddrLocker 201 b Backend 202 } 203 204 // NewPrivateAccountAPI create a new PrivateAccountAPI. 205 func NewPrivateAccountAPI(b Backend, nonceLock *AddrLocker) *PrivateAccountAPI { 206 return &PrivateAccountAPI{ 207 am: b.AccountManager(), 208 nonceLock: nonceLock, 209 b: b, 210 } 211 } 212 213 // listAccounts will return a list of addresses for accounts this node manages. 214 func (s *PrivateAccountAPI) ListAccounts() []common.Address { 215 return s.am.Accounts() 216 } 217 218 // rawWallet is a JSON representation of an accounts.Wallet interface, with its 219 // data contents extracted into plain fields. 220 type rawWallet struct { 221 URL string `json:"url"` 222 Status string `json:"status"` 223 Failure string `json:"failure,omitempty"` 224 Accounts []accounts.Account `json:"accounts,omitempty"` 225 } 226 227 // ListWallets will return a list of wallets this node manages. 228 func (s *PrivateAccountAPI) ListWallets() []rawWallet { 229 wallets := make([]rawWallet, 0) // return [] instead of nil if empty 230 for _, wallet := range s.am.Wallets() { 231 status, failure := wallet.Status() 232 233 raw := rawWallet{ 234 URL: wallet.URL().String(), 235 Status: status, 236 Accounts: wallet.Accounts(), 237 } 238 if failure != nil { 239 raw.Failure = failure.Error() 240 } 241 wallets = append(wallets, raw) 242 } 243 return wallets 244 } 245 246 // OpenWallet initiates a hardware wallet opening procedure, establishing a USB 247 // connection and attempting to authenticate via the provided passphrase. Note, 248 // the method may return an extra challenge requiring a second open (e.g. the 249 // Trezor PIN matrix challenge). 250 func (s *PrivateAccountAPI) OpenWallet(url string, passphrase *string) error { 251 wallet, err := s.am.Wallet(url) 252 if err != nil { 253 return err 254 } 255 pass := "" 256 if passphrase != nil { 257 pass = *passphrase 258 } 259 return wallet.Open(pass) 260 } 261 262 // DeriveAccount requests a HD wallet to derive a new account, optionally pinning 263 // it for later reuse. 264 func (s *PrivateAccountAPI) DeriveAccount(url string, path string, pin *bool) (accounts.Account, error) { 265 wallet, err := s.am.Wallet(url) 266 if err != nil { 267 return accounts.Account{}, err 268 } 269 derivPath, err := accounts.ParseDerivationPath(path) 270 if err != nil { 271 return accounts.Account{}, err 272 } 273 if pin == nil { 274 pin = new(bool) 275 } 276 return wallet.Derive(derivPath, *pin) 277 } 278 279 // NewAccount will create a new account and returns the address for the new account. 280 func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) { 281 ks, err := fetchKeystore(s.am) 282 if err != nil { 283 return common.Address{}, err 284 } 285 acc, err := ks.NewAccount(password) 286 if err == nil { 287 log.Info("Your new key was generated", "address", acc.Address) 288 log.Warn("Please backup your key file!", "path", acc.URL.Path) 289 log.Warn("Please remember your password!") 290 return acc.Address, nil 291 } 292 return common.Address{}, err 293 } 294 295 // fetchKeystore retrieves the encrypted keystore from the account manager. 296 func fetchKeystore(am *accounts.Manager) (*keystore.KeyStore, error) { 297 if ks := am.Backends(keystore.KeyStoreType); len(ks) > 0 { 298 return ks[0].(*keystore.KeyStore), nil 299 } 300 return nil, errors.New("local keystore not used") 301 } 302 303 // ImportRawKey stores the given hex encoded ECDSA key into the key directory, 304 // encrypting it with the passphrase. 305 func (s *PrivateAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) { 306 key, err := crypto.HexToECDSA(privkey) 307 if err != nil { 308 return common.Address{}, err 309 } 310 ks, err := fetchKeystore(s.am) 311 if err != nil { 312 return common.Address{}, err 313 } 314 acc, err := ks.ImportECDSA(key, password) 315 return acc.Address, err 316 } 317 318 // UnlockAccount will unlock the account associated with the given address with 319 // the given password for duration seconds. If duration is nil it will use a 320 // default of 300 seconds. It returns an indication if the account was unlocked. 321 func (s *PrivateAccountAPI) UnlockAccount(ctx context.Context, addr common.Address, password string, duration *uint64) (bool, error) { 322 // When the API is exposed by external RPC(http, ws etc), unless the user 323 // explicitly specifies to allow the insecure account unlocking, otherwise 324 // it is disabled. 325 if s.b.ExtRPCEnabled() && !s.b.AccountManager().Config().InsecureUnlockAllowed { 326 return false, errors.New("account unlock with HTTP access is forbidden") 327 } 328 329 const max = uint64(time.Duration(math.MaxInt64) / time.Second) 330 var d time.Duration 331 if duration == nil { 332 d = 300 * time.Second 333 } else if *duration > max { 334 return false, errors.New("unlock duration too large") 335 } else { 336 d = time.Duration(*duration) * time.Second 337 } 338 ks, err := fetchKeystore(s.am) 339 if err != nil { 340 return false, err 341 } 342 err = ks.TimedUnlock(accounts.Account{Address: addr}, password, d) 343 if err != nil { 344 log.Warn("Failed account unlock attempt", "address", addr, "err", err) 345 } 346 return err == nil, err 347 } 348 349 // LockAccount will lock the account associated with the given address when it's unlocked. 350 func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool { 351 if ks, err := fetchKeystore(s.am); err == nil { 352 return ks.Lock(addr) == nil 353 } 354 return false 355 } 356 357 // signTransaction sets defaults and signs the given transaction 358 // NOTE: the caller needs to ensure that the nonceLock is held, if applicable, 359 // and release it after the transaction has been submitted to the tx pool 360 func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args *SendTxArgs, passwd string) (*types.Transaction, error) { 361 // Look up the wallet containing the requested signer 362 account := accounts.Account{Address: args.From} 363 wallet, err := s.am.Find(account) 364 if err != nil { 365 return nil, err 366 } 367 // Set some sanity defaults and terminate on failure 368 if err := args.setDefaults(ctx, s.b); err != nil { 369 return nil, err 370 } 371 // Assemble the transaction and sign with the wallet 372 tx := args.toTransaction() 373 374 return wallet.SignTxWithPassphrase(account, passwd, tx, s.b.ChainConfig().ChainID) 375 } 376 377 // SendTransaction will create a transaction from the given arguments and 378 // tries to sign it with the key associated with args.From. If the given passwd isn't 379 // able to decrypt the key it fails. 380 func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) { 381 if args.Nonce == nil { 382 // Hold the addresse's mutex around signing to prevent concurrent assignment of 383 // the same nonce to multiple accounts. 384 s.nonceLock.LockAddr(args.From) 385 defer s.nonceLock.UnlockAddr(args.From) 386 } 387 signed, err := s.signTransaction(ctx, &args, passwd) 388 if err != nil { 389 log.Warn("Failed transaction send attempt", "from", args.From, "to", args.To, "value", args.Value.ToInt(), "err", err) 390 return common.Hash{}, err 391 } 392 return SubmitTransaction(ctx, s.b, signed) 393 } 394 395 // SignTransaction will create a transaction from the given arguments and 396 // tries to sign it with the key associated with args.From. If the given passwd isn't 397 // able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast 398 // to other nodes 399 func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs, passwd string) (*SignTransactionResult, error) { 400 // No need to obtain the noncelock mutex, since we won't be sending this 401 // tx into the transaction pool, but right back to the user 402 if args.Gas == nil { 403 return nil, fmt.Errorf("gas not specified") 404 } 405 if args.GasPrice == nil { 406 return nil, fmt.Errorf("gasPrice not specified") 407 } 408 if args.Nonce == nil { 409 return nil, fmt.Errorf("nonce not specified") 410 } 411 // Before actually sign the transaction, ensure the transaction fee is reasonable. 412 if err := checkTxFee(args.GasPrice.ToInt(), uint64(*args.Gas), s.b.RPCTxFeeCap()); err != nil { 413 return nil, err 414 } 415 signed, err := s.signTransaction(ctx, &args, passwd) 416 if err != nil { 417 log.Warn("Failed transaction sign attempt", "from", args.From, "to", args.To, "value", args.Value.ToInt(), "err", err) 418 return nil, err 419 } 420 data, err := signed.MarshalBinary() 421 if err != nil { 422 return nil, err 423 } 424 return &SignTransactionResult{data, signed}, nil 425 } 426 427 // Sign calculates an Ethereum ECDSA signature for: 428 // keccack256("\x19Ethereum Signed Message:\n" + len(message) + message)) 429 // 430 // Note, the produced signature conforms to the secp256k1 curve R, S and V values, 431 // where the V value will be 27 or 28 for legacy reasons. 432 // 433 // The key used to calculate the signature is decrypted with the given password. 434 // 435 // https://github.com/phillinzzz/newBsc/wiki/Management-APIs#personal_sign 436 func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) { 437 // Look up the wallet containing the requested signer 438 account := accounts.Account{Address: addr} 439 440 wallet, err := s.b.AccountManager().Find(account) 441 if err != nil { 442 return nil, err 443 } 444 // Assemble sign the data with the wallet 445 signature, err := wallet.SignTextWithPassphrase(account, passwd, data) 446 if err != nil { 447 log.Warn("Failed data sign attempt", "address", addr, "err", err) 448 return nil, err 449 } 450 signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper 451 return signature, nil 452 } 453 454 // EcRecover returns the address for the account that was used to create the signature. 455 // Note, this function is compatible with eth_sign and personal_sign. As such it recovers 456 // the address of: 457 // hash = keccak256("\x19Ethereum Signed Message:\n"${message length}${message}) 458 // addr = ecrecover(hash, signature) 459 // 460 // Note, the signature must conform to the secp256k1 curve R, S and V values, where 461 // the V value must be 27 or 28 for legacy reasons. 462 // 463 // https://github.com/phillinzzz/newBsc/wiki/Management-APIs#personal_ecRecover 464 func (s *PrivateAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) { 465 if len(sig) != crypto.SignatureLength { 466 return common.Address{}, fmt.Errorf("signature must be %d bytes long", crypto.SignatureLength) 467 } 468 if sig[crypto.RecoveryIDOffset] != 27 && sig[crypto.RecoveryIDOffset] != 28 { 469 return common.Address{}, fmt.Errorf("invalid Ethereum signature (V is not 27 or 28)") 470 } 471 sig[crypto.RecoveryIDOffset] -= 27 // Transform yellow paper V from 27/28 to 0/1 472 473 rpk, err := crypto.SigToPub(accounts.TextHash(data), sig) 474 if err != nil { 475 return common.Address{}, err 476 } 477 return crypto.PubkeyToAddress(*rpk), nil 478 } 479 480 // SignAndSendTransaction was renamed to SendTransaction. This method is deprecated 481 // and will be removed in the future. It primary goal is to give clients time to update. 482 func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) { 483 return s.SendTransaction(ctx, args, passwd) 484 } 485 486 // InitializeWallet initializes a new wallet at the provided URL, by generating and returning a new private key. 487 func (s *PrivateAccountAPI) InitializeWallet(ctx context.Context, url string) (string, error) { 488 wallet, err := s.am.Wallet(url) 489 if err != nil { 490 return "", err 491 } 492 493 entropy, err := bip39.NewEntropy(256) 494 if err != nil { 495 return "", err 496 } 497 498 mnemonic, err := bip39.NewMnemonic(entropy) 499 if err != nil { 500 return "", err 501 } 502 503 seed := bip39.NewSeed(mnemonic, "") 504 505 switch wallet := wallet.(type) { 506 case *scwallet.Wallet: 507 return mnemonic, wallet.Initialize(seed) 508 default: 509 return "", fmt.Errorf("specified wallet does not support initialization") 510 } 511 } 512 513 // Unpair deletes a pairing between wallet and geth. 514 func (s *PrivateAccountAPI) Unpair(ctx context.Context, url string, pin string) error { 515 wallet, err := s.am.Wallet(url) 516 if err != nil { 517 return err 518 } 519 520 switch wallet := wallet.(type) { 521 case *scwallet.Wallet: 522 return wallet.Unpair([]byte(pin)) 523 default: 524 return fmt.Errorf("specified wallet does not support pairing") 525 } 526 } 527 528 // PublicBlockChainAPI provides an API to access the Ethereum blockchain. 529 // It offers only methods that operate on public data that is freely available to anyone. 530 type PublicBlockChainAPI struct { 531 b Backend 532 } 533 534 // NewPublicBlockChainAPI creates a new Ethereum blockchain API. 535 func NewPublicBlockChainAPI(b Backend) *PublicBlockChainAPI { 536 return &PublicBlockChainAPI{b} 537 } 538 539 // ChainId is the EIP-155 replay-protection chain id for the current ethereum chain config. 540 func (api *PublicBlockChainAPI) ChainId() (*hexutil.Big, error) { 541 // if current block is at or past the EIP-155 replay-protection fork block, return chainID from config 542 if config := api.b.ChainConfig(); config.IsEIP155(api.b.CurrentBlock().Number()) { 543 return (*hexutil.Big)(config.ChainID), nil 544 } 545 return nil, fmt.Errorf("chain not synced beyond EIP-155 replay-protection fork block") 546 } 547 548 // BlockNumber returns the block number of the chain head. 549 func (s *PublicBlockChainAPI) BlockNumber() hexutil.Uint64 { 550 header, _ := s.b.HeaderByNumber(context.Background(), rpc.LatestBlockNumber) // latest header should always be available 551 return hexutil.Uint64(header.Number.Uint64()) 552 } 553 554 // GetBalance returns the amount of wei for the given address in the state of the 555 // given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta 556 // block numbers are also allowed. 557 func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { 558 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 559 if state == nil || err != nil { 560 return nil, err 561 } 562 return (*hexutil.Big)(state.GetBalance(address)), state.Error() 563 } 564 565 // Result structs for GetProof 566 type AccountResult struct { 567 Address common.Address `json:"address"` 568 AccountProof []string `json:"accountProof"` 569 Balance *hexutil.Big `json:"balance"` 570 CodeHash common.Hash `json:"codeHash"` 571 Nonce hexutil.Uint64 `json:"nonce"` 572 StorageHash common.Hash `json:"storageHash"` 573 StorageProof []StorageResult `json:"storageProof"` 574 } 575 type StorageResult struct { 576 Key string `json:"key"` 577 Value *hexutil.Big `json:"value"` 578 Proof []string `json:"proof"` 579 } 580 581 // GetProof returns the Merkle-proof for a given account and optionally some storage keys. 582 func (s *PublicBlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) { 583 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 584 if state == nil || err != nil { 585 return nil, err 586 } 587 588 storageTrie := state.StorageTrie(address) 589 storageHash := types.EmptyRootHash 590 codeHash := state.GetCodeHash(address) 591 storageProof := make([]StorageResult, len(storageKeys)) 592 593 // if we have a storageTrie, (which means the account exists), we can update the storagehash 594 if storageTrie != nil { 595 storageHash = storageTrie.Hash() 596 } else { 597 // no storageTrie means the account does not exist, so the codeHash is the hash of an empty bytearray. 598 codeHash = crypto.Keccak256Hash(nil) 599 } 600 601 // create the proof for the storageKeys 602 for i, key := range storageKeys { 603 if storageTrie != nil { 604 proof, storageError := state.GetStorageProof(address, common.HexToHash(key)) 605 if storageError != nil { 606 return nil, storageError 607 } 608 storageProof[i] = StorageResult{key, (*hexutil.Big)(state.GetState(address, common.HexToHash(key)).Big()), toHexSlice(proof)} 609 } else { 610 storageProof[i] = StorageResult{key, &hexutil.Big{}, []string{}} 611 } 612 } 613 614 // create the accountProof 615 accountProof, proofErr := state.GetProof(address) 616 if proofErr != nil { 617 return nil, proofErr 618 } 619 620 return &AccountResult{ 621 Address: address, 622 AccountProof: toHexSlice(accountProof), 623 Balance: (*hexutil.Big)(state.GetBalance(address)), 624 CodeHash: codeHash, 625 Nonce: hexutil.Uint64(state.GetNonce(address)), 626 StorageHash: storageHash, 627 StorageProof: storageProof, 628 }, state.Error() 629 } 630 631 // GetHeaderByNumber returns the requested canonical block header. 632 // * When blockNr is -1 the chain head is returned. 633 // * When blockNr is -2 the pending chain head is returned. 634 func (s *PublicBlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { 635 header, err := s.b.HeaderByNumber(ctx, number) 636 if header != nil && err == nil { 637 response := s.rpcMarshalHeader(ctx, header) 638 if number == rpc.PendingBlockNumber { 639 // Pending header need to nil out a few fields 640 for _, field := range []string{"hash", "nonce", "miner"} { 641 response[field] = nil 642 } 643 } 644 return response, err 645 } 646 return nil, err 647 } 648 649 // GetHeaderByHash returns the requested header by hash. 650 func (s *PublicBlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) map[string]interface{} { 651 header, _ := s.b.HeaderByHash(ctx, hash) 652 if header != nil { 653 return s.rpcMarshalHeader(ctx, header) 654 } 655 return nil 656 } 657 658 // GetBlockByNumber returns the requested canonical block. 659 // * When blockNr is -1 the chain head is returned. 660 // * When blockNr is -2 the pending chain head is returned. 661 // * When fullTx is true all transactions in the block are returned, otherwise 662 // only the transaction hash is returned. 663 func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { 664 block, err := s.b.BlockByNumber(ctx, number) 665 if block != nil && err == nil { 666 response, err := s.rpcMarshalBlock(ctx, block, true, fullTx) 667 if err == nil && number == rpc.PendingBlockNumber { 668 // Pending blocks need to nil out a few fields 669 for _, field := range []string{"hash", "nonce", "miner"} { 670 response[field] = nil 671 } 672 } 673 return response, err 674 } 675 return nil, err 676 } 677 678 // GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full 679 // detail, otherwise only the transaction hash is returned. 680 func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) { 681 block, err := s.b.BlockByHash(ctx, hash) 682 if block != nil { 683 return s.rpcMarshalBlock(ctx, block, true, fullTx) 684 } 685 return nil, err 686 } 687 688 func (s *PublicBlockChainAPI) Health() bool { 689 if rpc.RpcServingTimer != nil { 690 return rpc.RpcServingTimer.Percentile(0.75) < float64(UnHealthyTimeout) 691 } 692 return true 693 } 694 695 // GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. When fullTx is true 696 // all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. 697 func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (map[string]interface{}, error) { 698 block, err := s.b.BlockByNumber(ctx, blockNr) 699 if block != nil { 700 uncles := block.Uncles() 701 if index >= hexutil.Uint(len(uncles)) { 702 log.Debug("Requested uncle not found", "number", blockNr, "hash", block.Hash(), "index", index) 703 return nil, nil 704 } 705 block = types.NewBlockWithHeader(uncles[index]) 706 return s.rpcMarshalBlock(ctx, block, false, false) 707 } 708 return nil, err 709 } 710 711 // GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. When fullTx is true 712 // all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. 713 func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (map[string]interface{}, error) { 714 block, err := s.b.BlockByHash(ctx, blockHash) 715 if block != nil { 716 uncles := block.Uncles() 717 if index >= hexutil.Uint(len(uncles)) { 718 log.Debug("Requested uncle not found", "number", block.Number(), "hash", blockHash, "index", index) 719 return nil, nil 720 } 721 block = types.NewBlockWithHeader(uncles[index]) 722 return s.rpcMarshalBlock(ctx, block, false, false) 723 } 724 return nil, err 725 } 726 727 // GetUncleCountByBlockNumber returns number of uncles in the block for the given block number 728 func (s *PublicBlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 729 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 730 n := hexutil.Uint(len(block.Uncles())) 731 return &n 732 } 733 return nil 734 } 735 736 // GetUncleCountByBlockHash returns number of uncles in the block for the given block hash 737 func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 738 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 739 n := hexutil.Uint(len(block.Uncles())) 740 return &n 741 } 742 return nil 743 } 744 745 // GetCode returns the code stored at the given address in the state for the given block number. 746 func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { 747 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 748 if state == nil || err != nil { 749 return nil, err 750 } 751 code := state.GetCode(address) 752 return code, state.Error() 753 } 754 755 // GetStorageAt returns the storage from the state at the given address, key and 756 // block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block 757 // numbers are also allowed. 758 func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { 759 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 760 if state == nil || err != nil { 761 return nil, err 762 } 763 res := state.GetState(address, common.HexToHash(key)) 764 return res[:], state.Error() 765 } 766 767 // CallArgs represents the arguments for a call. 768 type CallArgs struct { 769 From *common.Address `json:"from"` 770 To *common.Address `json:"to"` 771 Gas *hexutil.Uint64 `json:"gas"` 772 GasPrice *hexutil.Big `json:"gasPrice"` 773 Value *hexutil.Big `json:"value"` 774 Data *hexutil.Bytes `json:"data"` 775 AccessList *types.AccessList `json:"accessList"` 776 } 777 778 // ToMessage converts CallArgs to the Message type used by the core evm 779 func (args *CallArgs) ToMessage(globalGasCap uint64) types.Message { 780 // Set sender address or use zero address if none specified. 781 var addr common.Address 782 if args.From != nil { 783 addr = *args.From 784 } 785 786 // Set default gas & gas price if none were set 787 gas := globalGasCap 788 if gas == 0 { 789 gas = uint64(math.MaxUint64 / 2) 790 } 791 if args.Gas != nil { 792 gas = uint64(*args.Gas) 793 } 794 if globalGasCap != 0 && globalGasCap < gas { 795 log.Debug("Caller gas above allowance, capping", "requested", gas, "cap", globalGasCap) 796 gas = globalGasCap 797 } 798 gasPrice := new(big.Int) 799 if args.GasPrice != nil { 800 gasPrice = args.GasPrice.ToInt() 801 } 802 value := new(big.Int) 803 if args.Value != nil { 804 value = args.Value.ToInt() 805 } 806 var data []byte 807 if args.Data != nil { 808 data = *args.Data 809 } 810 var accessList types.AccessList 811 if args.AccessList != nil { 812 accessList = *args.AccessList 813 } 814 815 msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, data, accessList, false) 816 return msg 817 } 818 819 // OverrideAccount indicates the overriding fields of account during the execution 820 // of a message call. 821 // Note, state and stateDiff can't be specified at the same time. If state is 822 // set, message execution will only use the data in the given state. Otherwise 823 // if statDiff is set, all diff will be applied first and then execute the call 824 // message. 825 type OverrideAccount struct { 826 Nonce *hexutil.Uint64 `json:"nonce"` 827 Code *hexutil.Bytes `json:"code"` 828 Balance **hexutil.Big `json:"balance"` 829 State *map[common.Hash]common.Hash `json:"state"` 830 StateDiff *map[common.Hash]common.Hash `json:"stateDiff"` 831 } 832 833 // StateOverride is the collection of overridden accounts. 834 type StateOverride map[common.Address]OverrideAccount 835 836 // Apply overrides the fields of specified accounts into the given state. 837 func (diff *StateOverride) Apply(state *state.StateDB) error { 838 if diff == nil { 839 return nil 840 } 841 for addr, account := range *diff { 842 // Override account nonce. 843 if account.Nonce != nil { 844 state.SetNonce(addr, uint64(*account.Nonce)) 845 } 846 // Override account(contract) code. 847 if account.Code != nil { 848 state.SetCode(addr, *account.Code) 849 } 850 // Override account balance. 851 if account.Balance != nil { 852 state.SetBalance(addr, (*big.Int)(*account.Balance)) 853 } 854 if account.State != nil && account.StateDiff != nil { 855 return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex()) 856 } 857 // Replace entire state if caller requires. 858 if account.State != nil { 859 state.SetStorage(addr, *account.State) 860 } 861 // Apply state diff into specified accounts. 862 if account.StateDiff != nil { 863 for key, value := range *account.StateDiff { 864 state.SetState(addr, key, value) 865 } 866 } 867 } 868 return nil 869 } 870 871 func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, vmCfg vm.Config, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { 872 defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) 873 874 state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 875 if state == nil || err != nil { 876 return nil, err 877 } 878 if err := overrides.Apply(state); err != nil { 879 return nil, err 880 } 881 // Setup context so it may be cancelled the call has completed 882 // or, in case of unmetered gas, setup a context with a timeout. 883 var cancel context.CancelFunc 884 if timeout > 0 { 885 ctx, cancel = context.WithTimeout(ctx, timeout) 886 } else { 887 ctx, cancel = context.WithCancel(ctx) 888 } 889 // Make sure the context is cancelled when the call has completed 890 // this makes sure resources are cleaned up. 891 defer cancel() 892 893 // Get a new instance of the EVM. 894 msg := args.ToMessage(globalGasCap) 895 evm, vmError, err := b.GetEVM(ctx, msg, state, header, nil) 896 if err != nil { 897 return nil, err 898 } 899 // Wait for the context to be done and cancel the evm. Even if the 900 // EVM has finished, cancelling may be done (repeatedly) 901 gopool.Submit(func() { 902 <-ctx.Done() 903 evm.Cancel() 904 }) 905 906 // Execute the message. 907 gp := new(core.GasPool).AddGas(math.MaxUint64) 908 result, err := core.ApplyMessage(evm, msg, gp) 909 if err := vmError(); err != nil { 910 return nil, err 911 } 912 913 // If the timer caused an abort, return an appropriate error message 914 if evm.Cancelled() { 915 return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout) 916 } 917 if err != nil { 918 return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas()) 919 } 920 return result, nil 921 } 922 923 func newRevertError(result *core.ExecutionResult) *revertError { 924 reason, errUnpack := abi.UnpackRevert(result.Revert()) 925 err := errors.New("execution reverted") 926 if errUnpack == nil { 927 err = fmt.Errorf("execution reverted: %v", reason) 928 } 929 return &revertError{ 930 error: err, 931 reason: hexutil.Encode(result.Revert()), 932 } 933 } 934 935 // revertError is an API error that encompassas an EVM revertal with JSON error 936 // code and a binary data blob. 937 type revertError struct { 938 error 939 reason string // revert reason hex encoded 940 } 941 942 // ErrorCode returns the JSON error code for a revertal. 943 // See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal 944 func (e *revertError) ErrorCode() int { 945 return 3 946 } 947 948 // ErrorData returns the hex encoded revert reason. 949 func (e *revertError) ErrorData() interface{} { 950 return e.reason 951 } 952 953 // Call executes the given transaction on the state for the given block number. 954 // 955 // Additionally, the caller can specify a batch of contract for fields overriding. 956 // 957 // Note, this function doesn't make and changes in the state/blockchain and is 958 // useful to execute and retrieve values. 959 func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Bytes, error) { 960 result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, vm.Config{}, 5*time.Second, s.b.RPCGasCap()) 961 if err != nil { 962 return nil, err 963 } 964 // If the result contains a revert reason, try to unpack and return it. 965 if len(result.Revert()) > 0 { 966 return nil, newRevertError(result) 967 } 968 return result.Return(), result.Err 969 } 970 971 func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap uint64) (hexutil.Uint64, error) { 972 // Binary search the gas requirement, as it may be higher than the amount used 973 var ( 974 lo uint64 = params.TxGas - 1 975 hi uint64 976 cap uint64 977 ) 978 // Use zero address if sender unspecified. 979 if args.From == nil { 980 args.From = new(common.Address) 981 } 982 // Determine the highest gas limit can be used during the estimation. 983 if args.Gas != nil && uint64(*args.Gas) >= params.TxGas { 984 hi = uint64(*args.Gas) 985 } else { 986 // Retrieve the block to act as the gas ceiling 987 block, err := b.BlockByNumberOrHash(ctx, blockNrOrHash) 988 if err != nil { 989 return 0, err 990 } 991 if block == nil { 992 return 0, errors.New("block not found") 993 } 994 hi = block.GasLimit() 995 } 996 // Recap the highest gas limit with account's available balance. 997 if args.GasPrice != nil && args.GasPrice.ToInt().BitLen() != 0 { 998 state, _, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 999 if err != nil { 1000 return 0, err 1001 } 1002 balance := state.GetBalance(*args.From) // from can't be nil 1003 available := new(big.Int).Set(balance) 1004 if args.Value != nil { 1005 if args.Value.ToInt().Cmp(available) >= 0 { 1006 return 0, errors.New("insufficient funds for transfer") 1007 } 1008 available.Sub(available, args.Value.ToInt()) 1009 } 1010 allowance := new(big.Int).Div(available, args.GasPrice.ToInt()) 1011 1012 // If the allowance is larger than maximum uint64, skip checking 1013 if allowance.IsUint64() && hi > allowance.Uint64() { 1014 transfer := args.Value 1015 if transfer == nil { 1016 transfer = new(hexutil.Big) 1017 } 1018 log.Warn("Gas estimation capped by limited funds", "original", hi, "balance", balance, 1019 "sent", transfer.ToInt(), "gasprice", args.GasPrice.ToInt(), "fundable", allowance) 1020 hi = allowance.Uint64() 1021 } 1022 } 1023 // Recap the highest gas allowance with specified gascap. 1024 if gasCap != 0 && hi > gasCap { 1025 log.Debug("Caller gas above allowance, capping", "requested", hi, "cap", gasCap) 1026 hi = gasCap 1027 } 1028 cap = hi 1029 1030 // Create a helper to check if a gas allowance results in an executable transaction 1031 executable := func(gas uint64) (bool, *core.ExecutionResult, error) { 1032 args.Gas = (*hexutil.Uint64)(&gas) 1033 1034 result, err := DoCall(ctx, b, args, blockNrOrHash, nil, vm.Config{}, 0, gasCap) 1035 if err != nil { 1036 if errors.Is(err, core.ErrIntrinsicGas) { 1037 return true, nil, nil // Special case, raise gas limit 1038 } 1039 return true, nil, err // Bail out 1040 } 1041 return result.Failed(), result, nil 1042 } 1043 // Execute the binary search and hone in on an executable gas limit 1044 for lo+1 < hi { 1045 mid := (hi + lo) / 2 1046 failed, _, err := executable(mid) 1047 1048 // If the error is not nil(consensus error), it means the provided message 1049 // call or transaction will never be accepted no matter how much gas it is 1050 // assigned. Return the error directly, don't struggle any more. 1051 if err != nil { 1052 return 0, err 1053 } 1054 if failed { 1055 lo = mid 1056 } else { 1057 hi = mid 1058 } 1059 } 1060 // Reject the transaction as invalid if it still fails at the highest allowance 1061 if hi == cap { 1062 failed, result, err := executable(hi) 1063 if err != nil { 1064 return 0, err 1065 } 1066 if failed { 1067 if result != nil && result.Err != vm.ErrOutOfGas { 1068 if len(result.Revert()) > 0 { 1069 return 0, newRevertError(result) 1070 } 1071 return 0, result.Err 1072 } 1073 // Otherwise, the specified gas cap is too low 1074 return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) 1075 } 1076 } 1077 return hexutil.Uint64(hi), nil 1078 } 1079 1080 // EstimateGas returns an estimate of the amount of gas needed to execute the 1081 // given transaction against the current pending block. 1082 func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) { 1083 bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) 1084 if blockNrOrHash != nil { 1085 bNrOrHash = *blockNrOrHash 1086 } 1087 return DoEstimateGas(ctx, s.b, args, bNrOrHash, s.b.RPCGasCap()) 1088 } 1089 1090 // GetDiffAccounts returns changed accounts in a specific block number. 1091 func (s *PublicBlockChainAPI) GetDiffAccounts(ctx context.Context, blockNr rpc.BlockNumber) ([]common.Address, error) { 1092 if s.b.Chain() == nil { 1093 return nil, fmt.Errorf("blockchain not support get diff accounts") 1094 } 1095 1096 header, err := s.b.HeaderByNumber(ctx, blockNr) 1097 if err != nil { 1098 return nil, fmt.Errorf("block not found for block number (%d): %v", blockNr, err) 1099 } 1100 1101 return s.b.Chain().GetDiffAccounts(header.Hash()) 1102 } 1103 1104 // GetDiffAccountsWithScope returns detailed changes of some interested accounts in a specific block number. 1105 func (s *PublicBlockChainAPI) GetDiffAccountsWithScope(ctx context.Context, blockNr rpc.BlockNumber, accounts []common.Address) (*types.DiffAccountsInBlock, error) { 1106 if s.b.Chain() == nil { 1107 return nil, fmt.Errorf("blockchain not support get diff accounts") 1108 } 1109 1110 block, err := s.b.BlockByNumber(ctx, blockNr) 1111 if err != nil { 1112 return nil, fmt.Errorf("block not found for block number (%d): %v", blockNr, err) 1113 } 1114 parent, err := s.b.BlockByHash(ctx, block.ParentHash()) 1115 if err != nil { 1116 return nil, fmt.Errorf("block not found for block number (%d): %v", blockNr-1, err) 1117 } 1118 statedb, err := s.b.Chain().StateAt(parent.Root()) 1119 if err != nil { 1120 return nil, fmt.Errorf("state not found for block number (%d): %v", blockNr-1, err) 1121 } 1122 1123 result := &types.DiffAccountsInBlock{ 1124 Number: uint64(blockNr), 1125 BlockHash: block.Hash(), 1126 Transactions: make([]types.DiffAccountsInTx, 0), 1127 } 1128 1129 accountSet := make(map[common.Address]struct{}, len(accounts)) 1130 for _, account := range accounts { 1131 accountSet[account] = struct{}{} 1132 } 1133 1134 // Recompute transactions. 1135 signer := types.MakeSigner(s.b.ChainConfig(), block.Number()) 1136 for _, tx := range block.Transactions() { 1137 // Skip data empty tx and to is one of the interested accounts tx. 1138 skip := false 1139 if len(tx.Data()) == 0 { 1140 skip = true 1141 } else if to := tx.To(); to != nil { 1142 if _, exists := accountSet[*to]; exists { 1143 skip = true 1144 } 1145 } 1146 1147 diffTx := types.DiffAccountsInTx{ 1148 TxHash: tx.Hash(), 1149 Accounts: make(map[common.Address]*big.Int, len(accounts)), 1150 } 1151 1152 if !skip { 1153 // Record account balance 1154 for _, account := range accounts { 1155 diffTx.Accounts[account] = statedb.GetBalance(account) 1156 } 1157 } 1158 1159 // Apply transaction 1160 msg, _ := tx.AsMessage(signer) 1161 txContext := core.NewEVMTxContext(msg) 1162 context := core.NewEVMBlockContext(block.Header(), s.b.Chain(), nil) 1163 vmenv := vm.NewEVM(context, txContext, statedb, s.b.ChainConfig(), vm.Config{}) 1164 1165 if posa, ok := s.b.Engine().(consensus.PoSA); ok { 1166 if isSystem, _ := posa.IsSystemTransaction(tx, block.Header()); isSystem { 1167 balance := statedb.GetBalance(consensus.SystemAddress) 1168 if balance.Cmp(common.Big0) > 0 { 1169 statedb.SetBalance(consensus.SystemAddress, big.NewInt(0)) 1170 statedb.AddBalance(block.Header().Coinbase, balance) 1171 } 1172 } 1173 } 1174 1175 if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil { 1176 return nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err) 1177 } 1178 statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number())) 1179 1180 if !skip { 1181 // Compute account balance diff. 1182 for _, account := range accounts { 1183 diffTx.Accounts[account] = new(big.Int).Sub(statedb.GetBalance(account), diffTx.Accounts[account]) 1184 if diffTx.Accounts[account].Cmp(big.NewInt(0)) == 0 { 1185 delete(diffTx.Accounts, account) 1186 } 1187 } 1188 1189 if len(diffTx.Accounts) != 0 { 1190 result.Transactions = append(result.Transactions, diffTx) 1191 } 1192 } 1193 } 1194 1195 return result, nil 1196 } 1197 1198 // ExecutionResult groups all structured logs emitted by the EVM 1199 // while replaying a transaction in debug mode as well as transaction 1200 // execution status, the amount of gas used and the return value 1201 type ExecutionResult struct { 1202 Gas uint64 `json:"gas"` 1203 Failed bool `json:"failed"` 1204 ReturnValue string `json:"returnValue"` 1205 StructLogs []StructLogRes `json:"structLogs"` 1206 } 1207 1208 // StructLogRes stores a structured log emitted by the EVM while replaying a 1209 // transaction in debug mode 1210 type StructLogRes struct { 1211 Pc uint64 `json:"pc"` 1212 Op string `json:"op"` 1213 Gas uint64 `json:"gas"` 1214 GasCost uint64 `json:"gasCost"` 1215 Depth int `json:"depth"` 1216 Error error `json:"error,omitempty"` 1217 Stack *[]string `json:"stack,omitempty"` 1218 Memory *[]string `json:"memory,omitempty"` 1219 Storage *map[string]string `json:"storage,omitempty"` 1220 } 1221 1222 // FormatLogs formats EVM returned structured logs for json output 1223 func FormatLogs(logs []vm.StructLog) []StructLogRes { 1224 formatted := make([]StructLogRes, len(logs)) 1225 for index, trace := range logs { 1226 formatted[index] = StructLogRes{ 1227 Pc: trace.Pc, 1228 Op: trace.Op.String(), 1229 Gas: trace.Gas, 1230 GasCost: trace.GasCost, 1231 Depth: trace.Depth, 1232 Error: trace.Err, 1233 } 1234 if trace.Stack != nil { 1235 stack := make([]string, len(trace.Stack)) 1236 for i, stackValue := range trace.Stack { 1237 stack[i] = stackValue.Hex() 1238 } 1239 formatted[index].Stack = &stack 1240 } 1241 if trace.Memory != nil { 1242 memory := make([]string, 0, (len(trace.Memory)+31)/32) 1243 for i := 0; i+32 <= len(trace.Memory); i += 32 { 1244 memory = append(memory, fmt.Sprintf("%x", trace.Memory[i:i+32])) 1245 } 1246 formatted[index].Memory = &memory 1247 } 1248 if trace.Storage != nil { 1249 storage := make(map[string]string) 1250 for i, storageValue := range trace.Storage { 1251 storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue) 1252 } 1253 formatted[index].Storage = &storage 1254 } 1255 } 1256 return formatted 1257 } 1258 1259 // RPCMarshalHeader converts the given header to the RPC output . 1260 func RPCMarshalHeader(head *types.Header) map[string]interface{} { 1261 return map[string]interface{}{ 1262 "number": (*hexutil.Big)(head.Number), 1263 "hash": head.Hash(), 1264 "parentHash": head.ParentHash, 1265 "nonce": head.Nonce, 1266 "mixHash": head.MixDigest, 1267 "sha3Uncles": head.UncleHash, 1268 "logsBloom": head.Bloom, 1269 "stateRoot": head.Root, 1270 "miner": head.Coinbase, 1271 "difficulty": (*hexutil.Big)(head.Difficulty), 1272 "extraData": hexutil.Bytes(head.Extra), 1273 "size": hexutil.Uint64(head.Size()), 1274 "gasLimit": hexutil.Uint64(head.GasLimit), 1275 "gasUsed": hexutil.Uint64(head.GasUsed), 1276 "timestamp": hexutil.Uint64(head.Time), 1277 "transactionsRoot": head.TxHash, 1278 "receiptsRoot": head.ReceiptHash, 1279 } 1280 } 1281 1282 // RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are 1283 // returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain 1284 // transaction hashes. 1285 func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { 1286 fields := RPCMarshalHeader(block.Header()) 1287 fields["size"] = hexutil.Uint64(block.Size()) 1288 1289 if inclTx { 1290 formatTx := func(tx *types.Transaction) (interface{}, error) { 1291 return tx.Hash(), nil 1292 } 1293 if fullTx { 1294 formatTx = func(tx *types.Transaction) (interface{}, error) { 1295 return newRPCTransactionFromBlockHash(block, tx.Hash()), nil 1296 } 1297 } 1298 txs := block.Transactions() 1299 transactions := make([]interface{}, len(txs)) 1300 var err error 1301 for i, tx := range txs { 1302 if transactions[i], err = formatTx(tx); err != nil { 1303 return nil, err 1304 } 1305 } 1306 fields["transactions"] = transactions 1307 } 1308 uncles := block.Uncles() 1309 uncleHashes := make([]common.Hash, len(uncles)) 1310 for i, uncle := range uncles { 1311 uncleHashes[i] = uncle.Hash() 1312 } 1313 fields["uncles"] = uncleHashes 1314 1315 return fields, nil 1316 } 1317 1318 // rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires 1319 // a `PublicBlockchainAPI`. 1320 func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *types.Header) map[string]interface{} { 1321 fields := RPCMarshalHeader(header) 1322 fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, header.Hash())) 1323 return fields 1324 } 1325 1326 // rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires 1327 // a `PublicBlockchainAPI`. 1328 func (s *PublicBlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { 1329 fields, err := RPCMarshalBlock(b, inclTx, fullTx) 1330 if err != nil { 1331 return nil, err 1332 } 1333 if inclTx { 1334 fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, b.Hash())) 1335 } 1336 return fields, err 1337 } 1338 1339 // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction 1340 type RPCTransaction struct { 1341 BlockHash *common.Hash `json:"blockHash"` 1342 BlockNumber *hexutil.Big `json:"blockNumber"` 1343 From common.Address `json:"from"` 1344 Gas hexutil.Uint64 `json:"gas"` 1345 GasPrice *hexutil.Big `json:"gasPrice"` 1346 Hash common.Hash `json:"hash"` 1347 Input hexutil.Bytes `json:"input"` 1348 Nonce hexutil.Uint64 `json:"nonce"` 1349 To *common.Address `json:"to"` 1350 TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` 1351 Value *hexutil.Big `json:"value"` 1352 Type hexutil.Uint64 `json:"type"` 1353 Accesses *types.AccessList `json:"accessList,omitempty"` 1354 ChainID *hexutil.Big `json:"chainId,omitempty"` 1355 V *hexutil.Big `json:"v"` 1356 R *hexutil.Big `json:"r"` 1357 S *hexutil.Big `json:"s"` 1358 } 1359 1360 // newRPCTransaction returns a transaction that will serialize to the RPC 1361 // representation, with the given location metadata set (if available). 1362 func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) *RPCTransaction { 1363 // Determine the signer. For replay-protected transactions, use the most permissive 1364 // signer, because we assume that signers are backwards-compatible with old 1365 // transactions. For non-protected transactions, the homestead signer signer is used 1366 // because the return value of ChainId is zero for those transactions. 1367 var signer types.Signer 1368 if tx.Protected() { 1369 signer = types.LatestSignerForChainID(tx.ChainId()) 1370 } else { 1371 signer = types.HomesteadSigner{} 1372 } 1373 1374 from, _ := types.Sender(signer, tx) 1375 v, r, s := tx.RawSignatureValues() 1376 result := &RPCTransaction{ 1377 Type: hexutil.Uint64(tx.Type()), 1378 From: from, 1379 Gas: hexutil.Uint64(tx.Gas()), 1380 GasPrice: (*hexutil.Big)(tx.GasPrice()), 1381 Hash: tx.Hash(), 1382 Input: hexutil.Bytes(tx.Data()), 1383 Nonce: hexutil.Uint64(tx.Nonce()), 1384 To: tx.To(), 1385 Value: (*hexutil.Big)(tx.Value()), 1386 V: (*hexutil.Big)(v), 1387 R: (*hexutil.Big)(r), 1388 S: (*hexutil.Big)(s), 1389 } 1390 if blockHash != (common.Hash{}) { 1391 result.BlockHash = &blockHash 1392 result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber)) 1393 result.TransactionIndex = (*hexutil.Uint64)(&index) 1394 } 1395 if tx.Type() == types.AccessListTxType { 1396 al := tx.AccessList() 1397 result.Accesses = &al 1398 result.ChainID = (*hexutil.Big)(tx.ChainId()) 1399 } 1400 return result 1401 } 1402 1403 // newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation 1404 func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction { 1405 return newRPCTransaction(tx, common.Hash{}, 0, 0) 1406 } 1407 1408 // newRPCTransactionsFromBlockIndex returns transactions that will serialize to the RPC representation. 1409 func newRPCTransactionsFromBlockIndex(b *types.Block) []*RPCTransaction { 1410 txs := b.Transactions() 1411 result := make([]*RPCTransaction, 0, len(txs)) 1412 1413 for idx, tx := range txs { 1414 result = append(result, newRPCTransaction(tx, b.Hash(), b.NumberU64(), uint64(idx))) 1415 } 1416 return result 1417 } 1418 1419 // newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation. 1420 func newRPCTransactionFromBlockIndex(b *types.Block, index uint64) *RPCTransaction { 1421 txs := b.Transactions() 1422 if index >= uint64(len(txs)) { 1423 return nil 1424 } 1425 return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index) 1426 } 1427 1428 // newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index. 1429 func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) hexutil.Bytes { 1430 txs := b.Transactions() 1431 if index >= uint64(len(txs)) { 1432 return nil 1433 } 1434 blob, _ := txs[index].MarshalBinary() 1435 return blob 1436 } 1437 1438 // newRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation. 1439 func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCTransaction { 1440 for idx, tx := range b.Transactions() { 1441 if tx.Hash() == hash { 1442 return newRPCTransactionFromBlockIndex(b, uint64(idx)) 1443 } 1444 } 1445 return nil 1446 } 1447 1448 // accessListResult returns an optional accesslist 1449 // Its the result of the `debug_createAccessList` RPC call. 1450 // It contains an error if the transaction itself failed. 1451 type accessListResult struct { 1452 Accesslist *types.AccessList `json:"accessList"` 1453 Error string `json:"error,omitempty"` 1454 GasUsed hexutil.Uint64 `json:"gasUsed"` 1455 } 1456 1457 // CreateAccessList creates a EIP-2930 type AccessList for the given transaction. 1458 // Reexec and BlockNrOrHash can be specified to create the accessList on top of a certain state. 1459 func (s *PublicBlockChainAPI) CreateAccessList(ctx context.Context, args SendTxArgs, blockNrOrHash *rpc.BlockNumberOrHash) (*accessListResult, error) { 1460 bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) 1461 if blockNrOrHash != nil { 1462 bNrOrHash = *blockNrOrHash 1463 } 1464 acl, gasUsed, vmerr, err := AccessList(ctx, s.b, bNrOrHash, args) 1465 if err != nil { 1466 return nil, err 1467 } 1468 result := &accessListResult{Accesslist: &acl, GasUsed: hexutil.Uint64(gasUsed)} 1469 if vmerr != nil { 1470 result.Error = vmerr.Error() 1471 } 1472 return result, nil 1473 } 1474 1475 // AccessList creates an access list for the given transaction. 1476 // If the accesslist creation fails an error is returned. 1477 // If the transaction itself fails, an vmErr is returned. 1478 func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrHash, args SendTxArgs) (acl types.AccessList, gasUsed uint64, vmErr error, err error) { 1479 // Retrieve the execution context 1480 db, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 1481 if db == nil || err != nil { 1482 return nil, 0, nil, err 1483 } 1484 // If the gas amount is not set, extract this as it will depend on access 1485 // lists and we'll need to reestimate every time 1486 nogas := args.Gas == nil 1487 1488 // Ensure any missing fields are filled, extract the recipient and input data 1489 if err := args.setDefaults(ctx, b); err != nil { 1490 return nil, 0, nil, err 1491 } 1492 var to common.Address 1493 if args.To != nil { 1494 to = *args.To 1495 } else { 1496 to = crypto.CreateAddress(args.From, uint64(*args.Nonce)) 1497 } 1498 var input []byte 1499 if args.Input != nil { 1500 input = *args.Input 1501 } else if args.Data != nil { 1502 input = *args.Data 1503 } 1504 // Retrieve the precompiles since they don't need to be added to the access list 1505 precompiles := vm.ActivePrecompiles(b.ChainConfig().Rules(header.Number)) 1506 1507 // Create an initial tracer 1508 prevTracer := vm.NewAccessListTracer(nil, args.From, to, precompiles) 1509 if args.AccessList != nil { 1510 prevTracer = vm.NewAccessListTracer(*args.AccessList, args.From, to, precompiles) 1511 } 1512 for { 1513 // Retrieve the current access list to expand 1514 accessList := prevTracer.AccessList() 1515 log.Trace("Creating access list", "input", accessList) 1516 1517 // If no gas amount was specified, each unique access list needs it's own 1518 // gas calculation. This is quite expensive, but we need to be accurate 1519 // and it's convered by the sender only anyway. 1520 if nogas { 1521 args.Gas = nil 1522 if err := args.setDefaults(ctx, b); err != nil { 1523 return nil, 0, nil, err // shouldn't happen, just in case 1524 } 1525 } 1526 // Copy the original db so we don't modify it 1527 statedb := db.Copy() 1528 msg := types.NewMessage(args.From, args.To, uint64(*args.Nonce), args.Value.ToInt(), uint64(*args.Gas), args.GasPrice.ToInt(), input, accessList, false) 1529 1530 // Apply the transaction with the access list tracer 1531 tracer := vm.NewAccessListTracer(accessList, args.From, to, precompiles) 1532 config := vm.Config{Tracer: tracer, Debug: true} 1533 vmenv, _, err := b.GetEVM(ctx, msg, statedb, header, &config) 1534 if err != nil { 1535 return nil, 0, nil, err 1536 } 1537 res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())) 1538 if err != nil { 1539 return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction().Hash(), err) 1540 } 1541 if tracer.Equal(prevTracer) { 1542 return accessList, res.UsedGas, res.Err, nil 1543 } 1544 prevTracer = tracer 1545 } 1546 } 1547 1548 // PublicTransactionPoolAPI exposes methods for the RPC interface 1549 type PublicTransactionPoolAPI struct { 1550 b Backend 1551 nonceLock *AddrLocker 1552 signer types.Signer 1553 } 1554 1555 // NewPublicTransactionPoolAPI creates a new RPC service with methods specific for the transaction pool. 1556 func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransactionPoolAPI { 1557 // The signer used by the API should always be the 'latest' known one because we expect 1558 // signers to be backwards-compatible with old transactions. 1559 signer := types.LatestSigner(b.ChainConfig()) 1560 return &PublicTransactionPoolAPI{b, nonceLock, signer} 1561 } 1562 1563 // GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number. 1564 func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 1565 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 1566 n := hexutil.Uint(len(block.Transactions())) 1567 return &n 1568 } 1569 return nil 1570 } 1571 1572 // GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash. 1573 func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 1574 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 1575 n := hexutil.Uint(len(block.Transactions())) 1576 return &n 1577 } 1578 return nil 1579 } 1580 1581 // GetTransactionsByBlockNumber returns all the transactions for the given block number. 1582 func (s *PublicTransactionPoolAPI) GetTransactionsByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) []*RPCTransaction { 1583 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 1584 return newRPCTransactionsFromBlockIndex(block) 1585 } 1586 return nil 1587 } 1588 1589 // GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index. 1590 func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction { 1591 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 1592 return newRPCTransactionFromBlockIndex(block, uint64(index)) 1593 } 1594 return nil 1595 } 1596 1597 // GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index. 1598 func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction { 1599 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 1600 return newRPCTransactionFromBlockIndex(block, uint64(index)) 1601 } 1602 return nil 1603 } 1604 1605 // GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index. 1606 func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) hexutil.Bytes { 1607 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 1608 return newRPCRawTransactionFromBlockIndex(block, uint64(index)) 1609 } 1610 return nil 1611 } 1612 1613 // GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index. 1614 func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) hexutil.Bytes { 1615 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 1616 return newRPCRawTransactionFromBlockIndex(block, uint64(index)) 1617 } 1618 return nil 1619 } 1620 1621 // GetTransactionCount returns the number of transactions the given address has sent for the given block number 1622 func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Uint64, error) { 1623 // Ask transaction pool for the nonce which includes pending transactions 1624 if blockNr, ok := blockNrOrHash.Number(); ok && blockNr == rpc.PendingBlockNumber { 1625 nonce, err := s.b.GetPoolNonce(ctx, address) 1626 if err != nil { 1627 return nil, err 1628 } 1629 return (*hexutil.Uint64)(&nonce), nil 1630 } 1631 // Resolve block number and use its state to ask for the nonce 1632 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 1633 if state == nil || err != nil { 1634 return nil, err 1635 } 1636 nonce := state.GetNonce(address) 1637 return (*hexutil.Uint64)(&nonce), state.Error() 1638 } 1639 1640 // GetTransactionByHash returns the transaction for the given hash 1641 func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) { 1642 // Try to return an already finalized transaction 1643 tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash) 1644 if err != nil { 1645 return nil, err 1646 } 1647 if tx != nil { 1648 return newRPCTransaction(tx, blockHash, blockNumber, index), nil 1649 } 1650 // No finalized transaction, try to retrieve it from the pool 1651 if tx := s.b.GetPoolTransaction(hash); tx != nil { 1652 return newRPCPendingTransaction(tx), nil 1653 } 1654 1655 // Transaction unknown, return as such 1656 return nil, nil 1657 } 1658 1659 // GetRawTransactionByHash returns the bytes of the transaction for the given hash. 1660 func (s *PublicTransactionPoolAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { 1661 // Retrieve a finalized transaction, or a pooled otherwise 1662 tx, _, _, _, err := s.b.GetTransaction(ctx, hash) 1663 if err != nil { 1664 return nil, err 1665 } 1666 if tx == nil { 1667 if tx = s.b.GetPoolTransaction(hash); tx == nil { 1668 // Transaction not found anywhere, abort 1669 return nil, nil 1670 } 1671 } 1672 // Serialize to RLP and return 1673 return tx.MarshalBinary() 1674 } 1675 1676 // GetTransactionReceipt returns the transaction receipt for the given transaction hash. 1677 func (s *PublicTransactionPoolAPI) GetTransactionReceiptsByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) ([]map[string]interface{}, error) { 1678 blockNumber := uint64(blockNr.Int64()) 1679 blockHash := rawdb.ReadCanonicalHash(s.b.ChainDb(), blockNumber) 1680 1681 receipts, err := s.b.GetReceipts(ctx, blockHash) 1682 if err != nil { 1683 return nil, err 1684 } 1685 block, err := s.b.BlockByHash(ctx, blockHash) 1686 if err != nil { 1687 return nil, err 1688 } 1689 txs := block.Transactions() 1690 if len(txs) != len(receipts) { 1691 return nil, fmt.Errorf("txs length doesn't equal to receipts' length") 1692 } 1693 1694 txReceipts := make([]map[string]interface{}, 0, len(txs)) 1695 for idx, receipt := range receipts { 1696 tx := txs[idx] 1697 var signer types.Signer = types.FrontierSigner{} 1698 if tx.Protected() { 1699 signer = types.NewEIP155Signer(tx.ChainId()) 1700 } 1701 from, _ := types.Sender(signer, tx) 1702 1703 fields := map[string]interface{}{ 1704 "blockHash": blockHash, 1705 "blockNumber": hexutil.Uint64(blockNumber), 1706 "transactionHash": tx.Hash(), 1707 "transactionIndex": hexutil.Uint64(idx), 1708 "from": from, 1709 "to": tx.To(), 1710 "gasUsed": hexutil.Uint64(receipt.GasUsed), 1711 "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), 1712 "contractAddress": nil, 1713 "logs": receipt.Logs, 1714 "logsBloom": receipt.Bloom, 1715 } 1716 1717 // Assign receipt status or post state. 1718 if len(receipt.PostState) > 0 { 1719 fields["root"] = hexutil.Bytes(receipt.PostState) 1720 } else { 1721 fields["status"] = hexutil.Uint(receipt.Status) 1722 } 1723 if receipt.Logs == nil { 1724 fields["logs"] = [][]*types.Log{} 1725 } 1726 // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation 1727 if receipt.ContractAddress != (common.Address{}) { 1728 fields["contractAddress"] = receipt.ContractAddress 1729 } 1730 1731 txReceipts = append(txReceipts, fields) 1732 } 1733 1734 return txReceipts, nil 1735 } 1736 1737 // GetTransactionDataAndReceipt returns the original transaction data and transaction receipt for the given transaction hash. 1738 func (s *PublicTransactionPoolAPI) GetTransactionDataAndReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { 1739 tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash) 1740 if tx == nil { 1741 return nil, nil 1742 } 1743 receipts, err := s.b.GetReceipts(ctx, blockHash) 1744 if err != nil { 1745 return nil, err 1746 } 1747 if len(receipts) <= int(index) { 1748 return nil, nil 1749 } 1750 receipt := receipts[index] 1751 1752 var signer types.Signer = types.FrontierSigner{} 1753 if tx.Protected() { 1754 signer = types.NewEIP155Signer(tx.ChainId()) 1755 } 1756 from, _ := types.Sender(signer, tx) 1757 1758 rpcTransaction := newRPCTransaction(tx, blockHash, blockNumber, index) 1759 1760 txData := map[string]interface{}{ 1761 "blockHash": rpcTransaction.BlockHash.String(), 1762 "blockNumber": rpcTransaction.BlockNumber.String(), 1763 "from": rpcTransaction.From.String(), 1764 "gas": rpcTransaction.Gas.String(), 1765 "gasPrice": rpcTransaction.GasPrice.String(), 1766 "hash": rpcTransaction.Hash.String(), 1767 "input": rpcTransaction.Input.String(), 1768 "nonce": rpcTransaction.Nonce.String(), 1769 "to": rpcTransaction.To.String(), 1770 "transactionIndex": rpcTransaction.TransactionIndex.String(), 1771 "value": rpcTransaction.Value.String(), 1772 "v": rpcTransaction.V.String(), 1773 "r": rpcTransaction.R.String(), 1774 "s": rpcTransaction.S.String(), 1775 } 1776 1777 fields := map[string]interface{}{ 1778 "blockHash": blockHash, 1779 "blockNumber": hexutil.Uint64(blockNumber), 1780 "transactionHash": hash, 1781 "transactionIndex": hexutil.Uint64(index), 1782 "from": from, 1783 "to": tx.To(), 1784 "gasUsed": hexutil.Uint64(receipt.GasUsed), 1785 "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), 1786 "contractAddress": nil, 1787 "logs": receipt.Logs, 1788 "logsBloom": receipt.Bloom, 1789 } 1790 1791 // Assign receipt status or post state. 1792 if len(receipt.PostState) > 0 { 1793 fields["root"] = hexutil.Bytes(receipt.PostState) 1794 } else { 1795 fields["status"] = hexutil.Uint(receipt.Status) 1796 } 1797 if receipt.Logs == nil { 1798 fields["logs"] = [][]*types.Log{} 1799 } 1800 // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation 1801 if receipt.ContractAddress != (common.Address{}) { 1802 fields["contractAddress"] = receipt.ContractAddress 1803 } 1804 result := map[string]interface{}{ 1805 "txData": txData, 1806 "receipt": fields, 1807 } 1808 return result, nil 1809 } 1810 1811 // GetTransactionReceipt returns the transaction receipt for the given transaction hash. 1812 func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { 1813 tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash) 1814 if err != nil { 1815 return nil, nil 1816 } 1817 receipts, err := s.b.GetReceipts(ctx, blockHash) 1818 if err != nil { 1819 return nil, err 1820 } 1821 if len(receipts) <= int(index) { 1822 return nil, nil 1823 } 1824 receipt := receipts[index] 1825 1826 // Derive the sender. 1827 bigblock := new(big.Int).SetUint64(blockNumber) 1828 signer := types.MakeSigner(s.b.ChainConfig(), bigblock) 1829 from, _ := types.Sender(signer, tx) 1830 1831 fields := map[string]interface{}{ 1832 "blockHash": blockHash, 1833 "blockNumber": hexutil.Uint64(blockNumber), 1834 "transactionHash": hash, 1835 "transactionIndex": hexutil.Uint64(index), 1836 "from": from, 1837 "to": tx.To(), 1838 "gasUsed": hexutil.Uint64(receipt.GasUsed), 1839 "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), 1840 "contractAddress": nil, 1841 "logs": receipt.Logs, 1842 "logsBloom": receipt.Bloom, 1843 "type": hexutil.Uint(tx.Type()), 1844 } 1845 1846 // Assign receipt status or post state. 1847 if len(receipt.PostState) > 0 { 1848 fields["root"] = hexutil.Bytes(receipt.PostState) 1849 } else { 1850 fields["status"] = hexutil.Uint(receipt.Status) 1851 } 1852 if receipt.Logs == nil { 1853 fields["logs"] = [][]*types.Log{} 1854 } 1855 // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation 1856 if receipt.ContractAddress != (common.Address{}) { 1857 fields["contractAddress"] = receipt.ContractAddress 1858 } 1859 return fields, nil 1860 } 1861 1862 // sign is a helper function that signs a transaction with the private key of the given address. 1863 func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { 1864 // Look up the wallet containing the requested signer 1865 account := accounts.Account{Address: addr} 1866 1867 wallet, err := s.b.AccountManager().Find(account) 1868 if err != nil { 1869 return nil, err 1870 } 1871 // Request the wallet to sign the transaction 1872 return wallet.SignTx(account, tx, s.b.ChainConfig().ChainID) 1873 } 1874 1875 // SendTxArgs represents the arguments to sumbit a new transaction into the transaction pool. 1876 type SendTxArgs struct { 1877 From common.Address `json:"from"` 1878 To *common.Address `json:"to"` 1879 Gas *hexutil.Uint64 `json:"gas"` 1880 GasPrice *hexutil.Big `json:"gasPrice"` 1881 Value *hexutil.Big `json:"value"` 1882 Nonce *hexutil.Uint64 `json:"nonce"` 1883 // We accept "data" and "input" for backwards-compatibility reasons. "input" is the 1884 // newer name and should be preferred by clients. 1885 Data *hexutil.Bytes `json:"data"` 1886 Input *hexutil.Bytes `json:"input"` 1887 1888 // For non-legacy transactions 1889 AccessList *types.AccessList `json:"accessList,omitempty"` 1890 ChainID *hexutil.Big `json:"chainId,omitempty"` 1891 } 1892 1893 // setDefaults fills in default values for unspecified tx fields. 1894 func (args *SendTxArgs) setDefaults(ctx context.Context, b Backend) error { 1895 if args.GasPrice == nil { 1896 price, err := b.SuggestPrice(ctx) 1897 if err != nil { 1898 return err 1899 } 1900 args.GasPrice = (*hexutil.Big)(price) 1901 } 1902 if args.Value == nil { 1903 args.Value = new(hexutil.Big) 1904 } 1905 if args.Nonce == nil { 1906 nonce, err := b.GetPoolNonce(ctx, args.From) 1907 if err != nil { 1908 return err 1909 } 1910 args.Nonce = (*hexutil.Uint64)(&nonce) 1911 } 1912 if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) { 1913 return errors.New(`both "data" and "input" are set and not equal. Please use "input" to pass transaction call data`) 1914 } 1915 if args.To == nil { 1916 // Contract creation 1917 var input []byte 1918 if args.Data != nil { 1919 input = *args.Data 1920 } else if args.Input != nil { 1921 input = *args.Input 1922 } 1923 if len(input) == 0 { 1924 return errors.New(`contract creation without any data provided`) 1925 } 1926 } 1927 // Estimate the gas usage if necessary. 1928 if args.Gas == nil { 1929 // For backwards-compatibility reason, we try both input and data 1930 // but input is preferred. 1931 input := args.Input 1932 if input == nil { 1933 input = args.Data 1934 } 1935 callArgs := CallArgs{ 1936 From: &args.From, // From shouldn't be nil 1937 To: args.To, 1938 GasPrice: args.GasPrice, 1939 Value: args.Value, 1940 Data: input, 1941 AccessList: args.AccessList, 1942 } 1943 pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) 1944 estimated, err := DoEstimateGas(ctx, b, callArgs, pendingBlockNr, b.RPCGasCap()) 1945 if err != nil { 1946 return err 1947 } 1948 args.Gas = &estimated 1949 log.Trace("Estimate gas usage automatically", "gas", args.Gas) 1950 } 1951 if args.ChainID == nil { 1952 id := (*hexutil.Big)(b.ChainConfig().ChainID) 1953 args.ChainID = id 1954 } 1955 return nil 1956 } 1957 1958 // toTransaction converts the arguments to a transaction. 1959 // This assumes that setDefaults has been called. 1960 func (args *SendTxArgs) toTransaction() *types.Transaction { 1961 var input []byte 1962 if args.Input != nil { 1963 input = *args.Input 1964 } else if args.Data != nil { 1965 input = *args.Data 1966 } 1967 var data types.TxData 1968 if args.AccessList == nil { 1969 data = &types.LegacyTx{ 1970 To: args.To, 1971 Nonce: uint64(*args.Nonce), 1972 Gas: uint64(*args.Gas), 1973 GasPrice: (*big.Int)(args.GasPrice), 1974 Value: (*big.Int)(args.Value), 1975 Data: input, 1976 } 1977 } else { 1978 data = &types.AccessListTx{ 1979 To: args.To, 1980 ChainID: (*big.Int)(args.ChainID), 1981 Nonce: uint64(*args.Nonce), 1982 Gas: uint64(*args.Gas), 1983 GasPrice: (*big.Int)(args.GasPrice), 1984 Value: (*big.Int)(args.Value), 1985 Data: input, 1986 AccessList: *args.AccessList, 1987 } 1988 } 1989 return types.NewTx(data) 1990 } 1991 1992 // SubmitTransaction is a helper function that submits tx to txPool and logs a message. 1993 func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) { 1994 // If the transaction fee cap is already specified, ensure the 1995 // fee of the given transaction is _reasonable_. 1996 if err := checkTxFee(tx.GasPrice(), tx.Gas(), b.RPCTxFeeCap()); err != nil { 1997 return common.Hash{}, err 1998 } 1999 if !b.UnprotectedAllowed() && !tx.Protected() { 2000 // Ensure only eip155 signed transactions are submitted if EIP155Required is set. 2001 return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC") 2002 } 2003 if err := b.SendTx(ctx, tx); err != nil { 2004 return common.Hash{}, err 2005 } 2006 // Print a log with full tx details for manual investigations and interventions 2007 signer := types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number()) 2008 from, err := types.Sender(signer, tx) 2009 if err != nil { 2010 return common.Hash{}, err 2011 } 2012 2013 if tx.To() == nil { 2014 addr := crypto.CreateAddress(from, tx.Nonce()) 2015 log.Info("Submitted contract creation", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "contract", addr.Hex(), "value", tx.Value()) 2016 } else { 2017 log.Info("Submitted transaction", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "recipient", tx.To(), "value", tx.Value()) 2018 } 2019 return tx.Hash(), nil 2020 } 2021 2022 // SendTransaction creates a transaction for the given argument, sign it and submit it to the 2023 // transaction pool. 2024 func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) { 2025 // Look up the wallet containing the requested signer 2026 account := accounts.Account{Address: args.From} 2027 2028 wallet, err := s.b.AccountManager().Find(account) 2029 if err != nil { 2030 return common.Hash{}, err 2031 } 2032 2033 if args.Nonce == nil { 2034 // Hold the addresse's mutex around signing to prevent concurrent assignment of 2035 // the same nonce to multiple accounts. 2036 s.nonceLock.LockAddr(args.From) 2037 defer s.nonceLock.UnlockAddr(args.From) 2038 } 2039 2040 // Set some sanity defaults and terminate on failure 2041 if err := args.setDefaults(ctx, s.b); err != nil { 2042 return common.Hash{}, err 2043 } 2044 // Assemble the transaction and sign with the wallet 2045 tx := args.toTransaction() 2046 2047 signed, err := wallet.SignTx(account, tx, s.b.ChainConfig().ChainID) 2048 if err != nil { 2049 return common.Hash{}, err 2050 } 2051 return SubmitTransaction(ctx, s.b, signed) 2052 } 2053 2054 // FillTransaction fills the defaults (nonce, gas, gasPrice) on a given unsigned transaction, 2055 // and returns it to the caller for further processing (signing + broadcast) 2056 func (s *PublicTransactionPoolAPI) FillTransaction(ctx context.Context, args SendTxArgs) (*SignTransactionResult, error) { 2057 // Set some sanity defaults and terminate on failure 2058 if err := args.setDefaults(ctx, s.b); err != nil { 2059 return nil, err 2060 } 2061 // Assemble the transaction and obtain rlp 2062 tx := args.toTransaction() 2063 data, err := tx.MarshalBinary() 2064 if err != nil { 2065 return nil, err 2066 } 2067 return &SignTransactionResult{data, tx}, nil 2068 } 2069 2070 // SendRawTransaction will add the signed transaction to the transaction pool. 2071 // The sender is responsible for signing the transaction and using the correct nonce. 2072 func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, input hexutil.Bytes) (common.Hash, error) { 2073 tx := new(types.Transaction) 2074 if err := tx.UnmarshalBinary(input); err != nil { 2075 return common.Hash{}, err 2076 } 2077 return SubmitTransaction(ctx, s.b, tx) 2078 } 2079 2080 // Sign calculates an ECDSA signature for: 2081 // keccack256("\x19Ethereum Signed Message:\n" + len(message) + message). 2082 // 2083 // Note, the produced signature conforms to the secp256k1 curve R, S and V values, 2084 // where the V value will be 27 or 28 for legacy reasons. 2085 // 2086 // The account associated with addr must be unlocked. 2087 // 2088 // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign 2089 func (s *PublicTransactionPoolAPI) Sign(addr common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { 2090 // Look up the wallet containing the requested signer 2091 account := accounts.Account{Address: addr} 2092 2093 wallet, err := s.b.AccountManager().Find(account) 2094 if err != nil { 2095 return nil, err 2096 } 2097 // Sign the requested hash with the wallet 2098 signature, err := wallet.SignText(account, data) 2099 if err == nil { 2100 signature[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper 2101 } 2102 return signature, err 2103 } 2104 2105 // SignTransactionResult represents a RLP encoded signed transaction. 2106 type SignTransactionResult struct { 2107 Raw hexutil.Bytes `json:"raw"` 2108 Tx *types.Transaction `json:"tx"` 2109 } 2110 2111 // SignTransaction will sign the given transaction with the from account. 2112 // The node needs to have the private key of the account corresponding with 2113 // the given from address and it needs to be unlocked. 2114 func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args SendTxArgs) (*SignTransactionResult, error) { 2115 if args.Gas == nil { 2116 return nil, fmt.Errorf("gas not specified") 2117 } 2118 if args.GasPrice == nil { 2119 return nil, fmt.Errorf("gasPrice not specified") 2120 } 2121 if args.Nonce == nil { 2122 return nil, fmt.Errorf("nonce not specified") 2123 } 2124 if err := args.setDefaults(ctx, s.b); err != nil { 2125 return nil, err 2126 } 2127 // Before actually sign the transaction, ensure the transaction fee is reasonable. 2128 if err := checkTxFee(args.GasPrice.ToInt(), uint64(*args.Gas), s.b.RPCTxFeeCap()); err != nil { 2129 return nil, err 2130 } 2131 tx, err := s.sign(args.From, args.toTransaction()) 2132 if err != nil { 2133 return nil, err 2134 } 2135 data, err := tx.MarshalBinary() 2136 if err != nil { 2137 return nil, err 2138 } 2139 return &SignTransactionResult{data, tx}, nil 2140 } 2141 2142 // PendingTransactions returns the transactions that are in the transaction pool 2143 // and have a from address that is one of the accounts this node manages. 2144 func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, error) { 2145 pending, err := s.b.GetPoolTransactions() 2146 if err != nil { 2147 return nil, err 2148 } 2149 accounts := make(map[common.Address]struct{}) 2150 for _, wallet := range s.b.AccountManager().Wallets() { 2151 for _, account := range wallet.Accounts() { 2152 accounts[account.Address] = struct{}{} 2153 } 2154 } 2155 transactions := make([]*RPCTransaction, 0, len(pending)) 2156 for _, tx := range pending { 2157 from, _ := types.Sender(s.signer, tx) 2158 if _, exists := accounts[from]; exists { 2159 transactions = append(transactions, newRPCPendingTransaction(tx)) 2160 } 2161 } 2162 return transactions, nil 2163 } 2164 2165 // Resend accepts an existing transaction and a new gas price and limit. It will remove 2166 // the given transaction from the pool and reinsert it with the new gas price and limit. 2167 func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) { 2168 if sendArgs.Nonce == nil { 2169 return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec") 2170 } 2171 if err := sendArgs.setDefaults(ctx, s.b); err != nil { 2172 return common.Hash{}, err 2173 } 2174 matchTx := sendArgs.toTransaction() 2175 2176 // Before replacing the old transaction, ensure the _new_ transaction fee is reasonable. 2177 var price = matchTx.GasPrice() 2178 if gasPrice != nil { 2179 price = gasPrice.ToInt() 2180 } 2181 var gas = matchTx.Gas() 2182 if gasLimit != nil { 2183 gas = uint64(*gasLimit) 2184 } 2185 if err := checkTxFee(price, gas, s.b.RPCTxFeeCap()); err != nil { 2186 return common.Hash{}, err 2187 } 2188 // Iterate the pending list for replacement 2189 pending, err := s.b.GetPoolTransactions() 2190 if err != nil { 2191 return common.Hash{}, err 2192 } 2193 for _, p := range pending { 2194 wantSigHash := s.signer.Hash(matchTx) 2195 pFrom, err := types.Sender(s.signer, p) 2196 if err == nil && pFrom == sendArgs.From && s.signer.Hash(p) == wantSigHash { 2197 // Match. Re-sign and send the transaction. 2198 if gasPrice != nil && (*big.Int)(gasPrice).Sign() != 0 { 2199 sendArgs.GasPrice = gasPrice 2200 } 2201 if gasLimit != nil && *gasLimit != 0 { 2202 sendArgs.Gas = gasLimit 2203 } 2204 signedTx, err := s.sign(sendArgs.From, sendArgs.toTransaction()) 2205 if err != nil { 2206 return common.Hash{}, err 2207 } 2208 if err = s.b.SendTx(ctx, signedTx); err != nil { 2209 return common.Hash{}, err 2210 } 2211 return signedTx.Hash(), nil 2212 } 2213 } 2214 return common.Hash{}, fmt.Errorf("transaction %#x not found", matchTx.Hash()) 2215 } 2216 2217 // PublicDebugAPI is the collection of Ethereum APIs exposed over the public 2218 // debugging endpoint. 2219 type PublicDebugAPI struct { 2220 b Backend 2221 } 2222 2223 // NewPublicDebugAPI creates a new API definition for the public debug methods 2224 // of the Ethereum service. 2225 func NewPublicDebugAPI(b Backend) *PublicDebugAPI { 2226 return &PublicDebugAPI{b: b} 2227 } 2228 2229 // GetBlockRlp retrieves the RLP encoded for of a single block. 2230 func (api *PublicDebugAPI) GetBlockRlp(ctx context.Context, number uint64) (string, error) { 2231 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 2232 if block == nil { 2233 return "", fmt.Errorf("block #%d not found", number) 2234 } 2235 encoded, err := rlp.EncodeToBytes(block) 2236 if err != nil { 2237 return "", err 2238 } 2239 return fmt.Sprintf("%x", encoded), nil 2240 } 2241 2242 // TestSignCliqueBlock fetches the given block number, and attempts to sign it as a clique header with the 2243 // given address, returning the address of the recovered signature 2244 // 2245 // This is a temporary method to debug the externalsigner integration, 2246 // TODO: Remove this method when the integration is mature 2247 func (api *PublicDebugAPI) TestSignCliqueBlock(ctx context.Context, address common.Address, number uint64) (common.Address, error) { 2248 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 2249 if block == nil { 2250 return common.Address{}, fmt.Errorf("block #%d not found", number) 2251 } 2252 header := block.Header() 2253 header.Extra = make([]byte, 32+65) 2254 encoded := clique.CliqueRLP(header) 2255 2256 // Look up the wallet containing the requested signer 2257 account := accounts.Account{Address: address} 2258 wallet, err := api.b.AccountManager().Find(account) 2259 if err != nil { 2260 return common.Address{}, err 2261 } 2262 2263 signature, err := wallet.SignData(account, accounts.MimetypeClique, encoded) 2264 if err != nil { 2265 return common.Address{}, err 2266 } 2267 sealHash := clique.SealHash(header).Bytes() 2268 log.Info("test signing of clique block", 2269 "Sealhash", fmt.Sprintf("%x", sealHash), 2270 "signature", fmt.Sprintf("%x", signature)) 2271 pubkey, err := crypto.Ecrecover(sealHash, signature) 2272 if err != nil { 2273 return common.Address{}, err 2274 } 2275 var signer common.Address 2276 copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) 2277 2278 return signer, nil 2279 } 2280 2281 // PrintBlock retrieves a block and returns its pretty printed form. 2282 func (api *PublicDebugAPI) PrintBlock(ctx context.Context, number uint64) (string, error) { 2283 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 2284 if block == nil { 2285 return "", fmt.Errorf("block #%d not found", number) 2286 } 2287 return spew.Sdump(block), nil 2288 } 2289 2290 // SeedHash retrieves the seed hash of a block. 2291 func (api *PublicDebugAPI) SeedHash(ctx context.Context, number uint64) (string, error) { 2292 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 2293 if block == nil { 2294 return "", fmt.Errorf("block #%d not found", number) 2295 } 2296 return fmt.Sprintf("0x%x", ethash.SeedHash(number)), nil 2297 } 2298 2299 // PrivateDebugAPI is the collection of Ethereum APIs exposed over the private 2300 // debugging endpoint. 2301 type PrivateDebugAPI struct { 2302 b Backend 2303 } 2304 2305 // NewPrivateDebugAPI creates a new API definition for the private debug methods 2306 // of the Ethereum service. 2307 func NewPrivateDebugAPI(b Backend) *PrivateDebugAPI { 2308 return &PrivateDebugAPI{b: b} 2309 } 2310 2311 // ChaindbProperty returns leveldb properties of the key-value database. 2312 func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) { 2313 if property == "" { 2314 property = "leveldb.stats" 2315 } else if !strings.HasPrefix(property, "leveldb.") { 2316 property = "leveldb." + property 2317 } 2318 return api.b.ChainDb().Stat(property) 2319 } 2320 2321 // ChaindbCompact flattens the entire key-value database into a single level, 2322 // removing all unused slots and merging all keys. 2323 func (api *PrivateDebugAPI) ChaindbCompact() error { 2324 for b := byte(0); b < 255; b++ { 2325 log.Info("Compacting chain database", "range", fmt.Sprintf("0x%0.2X-0x%0.2X", b, b+1)) 2326 if err := api.b.ChainDb().Compact([]byte{b}, []byte{b + 1}); err != nil { 2327 log.Error("Database compaction failed", "err", err) 2328 return err 2329 } 2330 } 2331 return nil 2332 } 2333 2334 // SetHead rewinds the head of the blockchain to a previous block. 2335 func (api *PrivateDebugAPI) SetHead(number hexutil.Uint64) { 2336 api.b.SetHead(uint64(number)) 2337 } 2338 2339 // PublicNetAPI offers network related RPC methods 2340 type PublicNetAPI struct { 2341 net *p2p.Server 2342 networkVersion uint64 2343 } 2344 2345 // NewPublicNetAPI creates a new net API instance. 2346 func NewPublicNetAPI(net *p2p.Server, networkVersion uint64) *PublicNetAPI { 2347 return &PublicNetAPI{net, networkVersion} 2348 } 2349 2350 // Listening returns an indication if the node is listening for network connections. 2351 func (s *PublicNetAPI) Listening() bool { 2352 return true // always listening 2353 } 2354 2355 // PeerCount returns the number of connected peers 2356 func (s *PublicNetAPI) PeerCount() hexutil.Uint { 2357 return hexutil.Uint(s.net.PeerCount()) 2358 } 2359 2360 // Version returns the current ethereum protocol version. 2361 func (s *PublicNetAPI) Version() string { 2362 return fmt.Sprintf("%d", s.networkVersion) 2363 } 2364 2365 // checkTxFee is an internal function used to check whether the fee of 2366 // the given transaction is _reasonable_(under the cap). 2367 func checkTxFee(gasPrice *big.Int, gas uint64, cap float64) error { 2368 // Short circuit if there is no cap for transaction fee at all. 2369 if cap == 0 { 2370 return nil 2371 } 2372 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))) 2373 feeFloat, _ := feeEth.Float64() 2374 if feeFloat > cap { 2375 return fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, cap) 2376 } 2377 return nil 2378 } 2379 2380 // toHexSlice creates a slice of hex-strings based on []byte. 2381 func toHexSlice(b [][]byte) []string { 2382 r := make([]string, len(b)) 2383 for i := range b { 2384 r[i] = hexutil.Encode(b[i]) 2385 } 2386 return r 2387 }