github.com/core-coin/go-core/v2@v2.1.9/internal/xcbapi/api.go (about) 1 // Copyright 2015 by the Authors 2 // This file is part of the go-core library. 3 // 4 // The go-core 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-core 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-core library. If not, see <http://www.gnu.org/licenses/>. 16 17 package xcbapi 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 "github.com/tyler-smith/go-bip39" 30 31 "github.com/core-coin/go-core/v2/consensus/cryptore" 32 33 "github.com/core-coin/go-core/v2/accounts" 34 "github.com/core-coin/go-core/v2/accounts/abi" 35 "github.com/core-coin/go-core/v2/accounts/keystore" 36 "github.com/core-coin/go-core/v2/common" 37 "github.com/core-coin/go-core/v2/common/hexutil" 38 "github.com/core-coin/go-core/v2/common/math" 39 "github.com/core-coin/go-core/v2/consensus/clique" 40 "github.com/core-coin/go-core/v2/core" 41 "github.com/core-coin/go-core/v2/core/types" 42 "github.com/core-coin/go-core/v2/core/vm" 43 "github.com/core-coin/go-core/v2/crypto" 44 "github.com/core-coin/go-core/v2/log" 45 "github.com/core-coin/go-core/v2/p2p" 46 "github.com/core-coin/go-core/v2/params" 47 "github.com/core-coin/go-core/v2/rlp" 48 "github.com/core-coin/go-core/v2/rpc" 49 ) 50 51 // PublicCoreAPI provides an API to access Core related information. 52 // It offers only methods that operate on public data that is freely available to anyone. 53 type PublicCoreAPI struct { 54 b Backend 55 } 56 57 // NewPublicCoreAPI creates a new Core protocol API. 58 func NewPublicCoreAPI(b Backend) *PublicCoreAPI { 59 return &PublicCoreAPI{b} 60 } 61 62 // EnergyPrice returns a suggestion for a energy price. 63 func (s *PublicCoreAPI) EnergyPrice(ctx context.Context) (*hexutil.Big, error) { 64 price, err := s.b.SuggestPrice(ctx) 65 return (*hexutil.Big)(price), err 66 } 67 68 // ProtocolVersion returns the current Core protocol version this node supports 69 func (s *PublicCoreAPI) ProtocolVersion() hexutil.Uint { 70 return hexutil.Uint(s.b.ProtocolVersion()) 71 } 72 73 // Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not 74 // yet received the latest block headers from its pears. In case it is synchronizing: 75 // - startingBlock: block number this node started to synchronise from 76 // - currentBlock: block number this node is currently importing 77 // - highestBlock: block number of the highest block header this node has received from peers 78 // - pulledStates: number of state entries processed until now 79 // - knownStates: number of known state entries that still need to be pulled 80 func (s *PublicCoreAPI) Syncing() (interface{}, error) { 81 progress := s.b.Downloader().Progress() 82 83 // Return not syncing if the synchronisation already completed 84 if progress.CurrentBlock >= progress.HighestBlock { 85 return false, nil 86 } 87 // Otherwise gather the block sync stats 88 return map[string]interface{}{ 89 "startingBlock": hexutil.Uint64(progress.StartingBlock), 90 "currentBlock": hexutil.Uint64(progress.CurrentBlock), 91 "highestBlock": hexutil.Uint64(progress.HighestBlock), 92 "pulledStates": hexutil.Uint64(progress.PulledStates), 93 "knownStates": hexutil.Uint64(progress.KnownStates), 94 }, nil 95 } 96 97 // PublicTxPoolAPI offers and API for the transaction pool. It only operates on data that is non confidential. 98 type PublicTxPoolAPI struct { 99 b Backend 100 } 101 102 // NewPublicTxPoolAPI creates a new tx pool service that gives information about the transaction pool. 103 func NewPublicTxPoolAPI(b Backend) *PublicTxPoolAPI { 104 return &PublicTxPoolAPI{b} 105 } 106 107 // Content returns the transactions contained within the transaction pool. 108 func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { 109 content := map[string]map[string]map[string]*RPCTransaction{ 110 "pending": make(map[string]map[string]*RPCTransaction), 111 "queued": make(map[string]map[string]*RPCTransaction), 112 } 113 pending, queue := s.b.TxPoolContent() 114 115 // Flatten the pending transactions 116 for account, txs := range pending { 117 dump := make(map[string]*RPCTransaction) 118 for _, tx := range txs { 119 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, s.b.ChainConfig().NetworkID) 120 } 121 content["pending"][account.Hex()] = dump 122 } 123 // Flatten the queued transactions 124 for account, txs := range queue { 125 dump := make(map[string]*RPCTransaction) 126 for _, tx := range txs { 127 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx, s.b.ChainConfig().NetworkID) 128 } 129 content["queued"][account.Hex()] = dump 130 } 131 return content 132 } 133 134 // Status returns the number of pending and queued transaction in the pool. 135 func (s *PublicTxPoolAPI) Status() map[string]hexutil.Uint { 136 pending, queue := s.b.Stats() 137 return map[string]hexutil.Uint{ 138 "pending": hexutil.Uint(pending), 139 "queued": hexutil.Uint(queue), 140 } 141 } 142 143 // Inspect retrieves the content of the transaction pool and flattens it into an 144 // easily inspectable list. 145 func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string]string { 146 content := map[string]map[string]map[string]string{ 147 "pending": make(map[string]map[string]string), 148 "queued": make(map[string]map[string]string), 149 } 150 pending, queue := s.b.TxPoolContent() 151 152 // Define a formatter to flatten a transaction into a string 153 var format = func(tx *types.Transaction) string { 154 if to := tx.To(); to != nil { 155 return fmt.Sprintf("%s: %v ore + %v energy × %v ore", tx.To().Hex(), tx.Value(), tx.Energy(), tx.EnergyPrice()) 156 } 157 return fmt.Sprintf("contract creation: %v ore + %v energy × %v ore", tx.Value(), tx.Energy(), tx.EnergyPrice()) 158 } 159 // Flatten the pending transactions 160 for account, txs := range pending { 161 dump := make(map[string]string) 162 for _, tx := range txs { 163 dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) 164 } 165 content["pending"][account.Hex()] = dump 166 } 167 // Flatten the queued transactions 168 for account, txs := range queue { 169 dump := make(map[string]string) 170 for _, tx := range txs { 171 dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) 172 } 173 content["queued"][account.Hex()] = dump 174 } 175 return content 176 } 177 178 // PublicAccountAPI provides an API to access accounts managed by this node. 179 // It offers only methods that can retrieve accounts. 180 type PublicAccountAPI struct { 181 am *accounts.Manager 182 } 183 184 // NewPublicAccountAPI creates a new PublicAccountAPI. 185 func NewPublicAccountAPI(am *accounts.Manager) *PublicAccountAPI { 186 return &PublicAccountAPI{am: am} 187 } 188 189 // Accounts returns the collection of accounts this node manages 190 func (s *PublicAccountAPI) Accounts() []common.Address { 191 return s.am.Accounts() 192 } 193 194 // PrivateAccountAPI provides an API to access accounts managed by this node. 195 // It offers methods to create, (un)lock en list accounts. Some methods accept 196 // passwords and are therefore considered private by default. 197 type PrivateAccountAPI struct { 198 am *accounts.Manager 199 nonceLock *AddrLocker 200 b Backend 201 } 202 203 // NewPrivateAccountAPI create a new PrivateAccountAPI. 204 func NewPrivateAccountAPI(b Backend, nonceLock *AddrLocker) *PrivateAccountAPI { 205 return &PrivateAccountAPI{ 206 am: b.AccountManager(), 207 nonceLock: nonceLock, 208 b: b, 209 } 210 } 211 212 // listAccounts will return a list of addresses for accounts this node manages. 213 func (s *PrivateAccountAPI) ListAccounts() []common.Address { 214 return s.am.Accounts() 215 } 216 217 // rawWallet is a JSON representation of an accounts.Wallet interface, with its 218 // data contents extracted into plain fields. 219 type rawWallet struct { 220 URL string `json:"url"` 221 Status string `json:"status"` 222 Failure string `json:"failure,omitempty"` 223 Accounts []accounts.Account `json:"accounts,omitempty"` 224 } 225 226 // ListWallets will return a list of wallets this node manages. 227 func (s *PrivateAccountAPI) ListWallets() []rawWallet { 228 wallets := make([]rawWallet, 0) // return [] instead of nil if empty 229 for _, wallet := range s.am.Wallets() { 230 status, failure := wallet.Status() 231 232 raw := rawWallet{ 233 URL: wallet.URL().String(), 234 Status: status, 235 Accounts: wallet.Accounts(), 236 } 237 if failure != nil { 238 raw.Failure = failure.Error() 239 } 240 wallets = append(wallets, raw) 241 } 242 return wallets 243 } 244 245 // OpenWallet initiates a hardware wallet opening procedure, establishing a USB 246 // connection and attempting to authenticate via the provided passphrase. Note, 247 // the method may return an extra challenge requiring a second open. 248 func (s *PrivateAccountAPI) OpenWallet(url string, passphrase *string) error { 249 wallet, err := s.am.Wallet(url) 250 if err != nil { 251 return err 252 } 253 pass := "" 254 if passphrase != nil { 255 pass = *passphrase 256 } 257 return wallet.Open(pass) 258 } 259 260 // DeriveAccount requests a HD wallet to derive a new account, optionally pinning 261 // it for later reuse. 262 func (s *PrivateAccountAPI) DeriveAccount(url string, path string, pin *bool) (accounts.Account, error) { 263 wallet, err := s.am.Wallet(url) 264 if err != nil { 265 return accounts.Account{}, err 266 } 267 derivPath, err := accounts.ParseDerivationPath(path) 268 if err != nil { 269 return accounts.Account{}, err 270 } 271 if pin == nil { 272 pin = new(bool) 273 } 274 return wallet.Derive(derivPath, *pin) 275 } 276 277 // NewAccount will create a new account and returns the address for the new account. 278 func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) { 279 ks, err := fetchKeystore(s.am) 280 if err != nil { 281 return common.Address{}, err 282 } 283 acc, err := ks.NewAccount(password) 284 if err == nil { 285 log.Info("Your new key was generated", "address", acc.Address) 286 log.Warn("Please backup your key file!", "path", acc.URL.Path) 287 log.Warn("Please remember your password!") 288 return acc.Address, nil 289 } 290 return common.Address{}, err 291 } 292 293 // fetchKeystore retrives the encrypted keystore from the account manager. 294 func fetchKeystore(am *accounts.Manager) (*keystore.KeyStore, error) { 295 if ks := am.Backends(keystore.KeyStoreType); len(ks) > 0 { 296 return ks[0].(*keystore.KeyStore), nil 297 } 298 return nil, errors.New("local keystore not used") 299 } 300 301 // ImportRawKey stores the given hex encoded EDDSA key into the key directory, 302 // encrypting it with the passphrase. 303 func (s *PrivateAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) { 304 key, err := crypto.UnmarshalPrivateKeyHex(privkey) 305 if err != nil { 306 return common.Address{}, err 307 } 308 ks, err := fetchKeystore(s.am) 309 if err != nil { 310 return common.Address{}, err 311 } 312 acc, err := ks.ImportEDDSA(key, password) 313 return acc.Address, err 314 } 315 316 // UnlockAccount will unlock the account associated with the given address with 317 // the given password for duration seconds. If duration is nil it will use a 318 // default of 300 seconds. It returns an indication if the account was unlocked. 319 func (s *PrivateAccountAPI) UnlockAccount(ctx context.Context, addr common.Address, password string, duration *uint64) (bool, error) { 320 // When the API is exposed by external RPC(http, ws etc), unless the user 321 // explicitly specifies to allow the insecure account unlocking, otherwise 322 // it is disabled. 323 if s.b.ExtRPCEnabled() && !s.b.AccountManager().Config().InsecureUnlockAllowed { 324 return false, errors.New("account unlock with HTTP access is forbidden") 325 } 326 327 const max = uint64(time.Duration(math.MaxInt64) / time.Second) 328 var d time.Duration 329 if duration == nil { 330 d = 300 * time.Second 331 } else if *duration > max { 332 return false, errors.New("unlock duration too large") 333 } else { 334 d = time.Duration(*duration) * time.Second 335 } 336 ks, err := fetchKeystore(s.am) 337 if err != nil { 338 return false, err 339 } 340 err = ks.TimedUnlock(accounts.Account{Address: addr}, password, d) 341 if err != nil { 342 log.Warn("Failed account unlock attempt", "address", addr, "err", err) 343 } 344 return err == nil, err 345 } 346 347 // LockAccount will lock the account associated with the given address when it's unlocked. 348 func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool { 349 if ks, err := fetchKeystore(s.am); err == nil { 350 return ks.Lock(addr) == nil 351 } 352 return false 353 } 354 355 // signTransaction sets defaults and signs the given transaction 356 // NOTE: the caller needs to ensure that the nonceLock is held, if applicable, 357 // and release it after the transaction has been submitted to the tx pool 358 func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args *SendTxArgs, passwd string) (*types.Transaction, error) { 359 // Look up the wallet containing the requested signer 360 account := accounts.Account{Address: args.From} 361 wallet, err := s.am.Find(account) 362 if err != nil { 363 return nil, err 364 } 365 // Set some sanity defaults and terminate on failure 366 if err := args.setDefaults(ctx, s.b); err != nil { 367 return nil, err 368 } 369 // Assemble the transaction and sign with the wallet 370 tx := args.toTransaction() 371 372 return wallet.SignTxWithPassphrase(account, passwd, tx, s.b.ChainConfig().NetworkID) 373 } 374 375 // SendTransaction will create a transaction from the given arguments and 376 // tries to sign it with the key associated with args.To. If the given passwd isn't 377 // able to decrypt the key it fails. 378 func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) { 379 if args.Nonce == nil { 380 // Hold the addresse's mutex around signing to prevent concurrent assignment of 381 // the same nonce to multiple accounts. 382 s.nonceLock.LockAddr(args.From) 383 defer s.nonceLock.UnlockAddr(args.From) 384 } 385 signed, err := s.signTransaction(ctx, &args, passwd) 386 if err != nil { 387 log.Warn("Failed transaction send attempt", "from", args.From, "to", args.To, "value", args.Value.ToInt(), "err", err) 388 return common.Hash{}, err 389 } 390 return SubmitTransaction(ctx, s.b, signed) 391 } 392 393 // SignTransaction will create a transaction from the given arguments and 394 // tries to sign it with the key associated with args.To. If the given passwd isn't 395 // able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast 396 // to other nodes 397 func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs, passwd string) (*SignTransactionResult, error) { 398 // No need to obtain the noncelock mutex, since we won't be sending this 399 // tx into the transaction pool, but right back to the user 400 if args.Energy == nil { 401 return nil, fmt.Errorf("energy not specified") 402 } 403 if args.EnergyPrice == nil { 404 return nil, fmt.Errorf("energyPrice not specified") 405 } 406 if args.Nonce == nil { 407 return nil, fmt.Errorf("nonce not specified") 408 } 409 // Before actually sign the transaction, ensure the transaction fee is reasonable. 410 if err := checkTxFee(args.EnergyPrice.ToInt(), uint64(*args.Energy), s.b.RPCTxFeeCap()); err != nil { 411 return nil, err 412 } 413 signed, err := s.signTransaction(ctx, &args, passwd) 414 if err != nil { 415 log.Warn("Failed transaction sign attempt", "from", args.From, "to", args.To, "value", args.Value.ToInt(), "err", err) 416 return nil, err 417 } 418 data, err := rlp.EncodeToBytes(signed) 419 if err != nil { 420 return nil, err 421 } 422 return &SignTransactionResult{data, signed}, nil 423 } 424 425 // Sign calculates an Core EDDSA signature for: 426 // keccack256("\x19Core Signed Message:\n" + len(message) + message)) 427 // 428 // The key used to calculate the signature is decrypted with the given password. 429 // 430 // https://developer.coreblockchain.cc/Management-APIs#personal_sign 431 func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) { 432 // Look up the wallet containing the requested signer 433 account := accounts.Account{Address: addr} 434 435 wallet, err := s.b.AccountManager().Find(account) 436 if err != nil { 437 return nil, err 438 } 439 // Assemble sign the data with the wallet 440 signature, err := wallet.SignTextWithPassphrase(account, passwd, data) 441 if err != nil { 442 log.Warn("Failed data sign attempt", "address", addr, "err", err) 443 return nil, err 444 } 445 return signature, nil 446 } 447 448 // EcRecover returns the address for the account that was used to create the signature. 449 // Note, this function is compatible with xcb_sign and personal_sign. As such it recovers 450 // the address of: 451 // hash = keccak256("\x19Core Signed Message:\n"${message length}${message}) 452 // addr = ecrecover(hash, signature) 453 // 454 // https://developer.coreblockchain.cc/Management-APIs#personal_ecRecover 455 func (s *PrivateAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) { 456 rpk, err := crypto.SigToPub(accounts.TextHash(data), sig) 457 if err != nil { 458 return common.Address{}, err 459 } 460 return crypto.PubkeyToAddress(rpk), nil 461 } 462 463 // SignAndSendTransaction was renamed to SendTransaction. This method is deprecated 464 // and will be removed in the future. It primary goal is to give clients time to update. 465 func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) { 466 return s.SendTransaction(ctx, args, passwd) 467 } 468 469 // InitializeWallet initializes a new wallet at the provided URL, by generating and returning a new private key. 470 func (s *PrivateAccountAPI) InitializeWallet(ctx context.Context, url string) (string, error) { 471 _, err := s.am.Wallet(url) 472 if err != nil { 473 return "", err 474 } 475 476 entropy, err := bip39.NewEntropy(256) 477 if err != nil { 478 return "", err 479 } 480 481 mnemonic, err := bip39.NewMnemonic(entropy) 482 if err != nil { 483 return "", err 484 } 485 486 _ = bip39.NewSeed(mnemonic, "") 487 488 return "", fmt.Errorf("specified wallet does not support initialization") 489 } 490 491 // Unpair deletes a pairing between wallet and gocore. 492 func (s *PrivateAccountAPI) Unpair(ctx context.Context, url string, pin string) error { 493 _, err := s.am.Wallet(url) 494 if err != nil { 495 return err 496 } 497 498 return fmt.Errorf("specified wallet does not support pairing") 499 } 500 501 // PublicBlockChainAPI provides an API to access the Core blockchain. 502 // It offers only methods that operate on public data that is freely available to anyone. 503 type PublicBlockChainAPI struct { 504 b Backend 505 } 506 507 // NewPublicBlockChainAPI creates a new Core blockchain API. 508 func NewPublicBlockChainAPI(b Backend) *PublicBlockChainAPI { 509 return &PublicBlockChainAPI{b} 510 } 511 512 // NetworkId returns the networkID value for transaction replay protection. 513 func (s *PublicBlockChainAPI) NetworkId() *hexutil.Big { 514 return (*hexutil.Big)(s.b.ChainConfig().NetworkID) 515 } 516 517 // BlockNumber returns the block number of the chain head. 518 func (s *PublicBlockChainAPI) BlockNumber() hexutil.Uint64 { 519 header, _ := s.b.HeaderByNumber(context.Background(), rpc.LatestBlockNumber) // latest header should always be available 520 return hexutil.Uint64(header.Number.Uint64()) 521 } 522 523 // GetBalance returns the amount of ore for the given address in the state of the 524 // given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta 525 // block numbers are also allowed. 526 func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { 527 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 528 if state == nil || err != nil { 529 return nil, err 530 } 531 return (*hexutil.Big)(state.GetBalance(address)), state.Error() 532 } 533 534 // Result structs for GetProof 535 type AccountResult struct { 536 Address common.Address `json:"address"` 537 AccountProof []string `json:"accountProof"` 538 Balance *hexutil.Big `json:"balance"` 539 CodeHash common.Hash `json:"codeHash"` 540 Nonce hexutil.Uint64 `json:"nonce"` 541 StorageHash common.Hash `json:"storageHash"` 542 StorageProof []StorageResult `json:"storageProof"` 543 } 544 type StorageResult struct { 545 Key string `json:"key"` 546 Value *hexutil.Big `json:"value"` 547 Proof []string `json:"proof"` 548 } 549 550 // GetProof returns the Merkle-proof for a given account and optionally some storage keys. 551 func (s *PublicBlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) { 552 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 553 if state == nil || err != nil { 554 return nil, err 555 } 556 557 storageTrie := state.StorageTrie(address) 558 storageHash := types.EmptyRootHash 559 codeHash := state.GetCodeHash(address) 560 storageProof := make([]StorageResult, len(storageKeys)) 561 562 // if we have a storageTrie, (which means the account exists), we can update the storagehash 563 if storageTrie != nil { 564 storageHash = storageTrie.Hash() 565 } else { 566 // no storageTrie means the account does not exist, so the codeHash is the hash of an empty bytearray. 567 codeHash = crypto.SHA3Hash(nil) 568 } 569 570 // create the proof for the storageKeys 571 for i, key := range storageKeys { 572 if storageTrie != nil { 573 proof, storageError := state.GetStorageProof(address, common.HexToHash(key)) 574 if storageError != nil { 575 return nil, storageError 576 } 577 storageProof[i] = StorageResult{key, (*hexutil.Big)(state.GetState(address, common.HexToHash(key)).Big()), toHexSlice(proof)} 578 } else { 579 storageProof[i] = StorageResult{key, &hexutil.Big{}, []string{}} 580 } 581 } 582 583 // create the accountProof 584 accountProof, proofErr := state.GetProof(address) 585 if proofErr != nil { 586 return nil, proofErr 587 } 588 589 return &AccountResult{ 590 Address: address, 591 AccountProof: toHexSlice(accountProof), 592 Balance: (*hexutil.Big)(state.GetBalance(address)), 593 CodeHash: codeHash, 594 Nonce: hexutil.Uint64(state.GetNonce(address)), 595 StorageHash: storageHash, 596 StorageProof: storageProof, 597 }, state.Error() 598 } 599 600 // GetHeaderByNumber returns the requested canonical block header. 601 // * When blockNr is -1 the chain head is returned. 602 // * When blockNr is -2 the pending chain head is returned. 603 func (s *PublicBlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { 604 header, err := s.b.HeaderByNumber(ctx, number) 605 if header != nil && err == nil { 606 response := s.rpcMarshalHeader(ctx, header) 607 if number == rpc.PendingBlockNumber { 608 // Pending header need to nil out a few fields 609 for _, field := range []string{"hash", "nonce", "miner"} { 610 response[field] = nil 611 } 612 } 613 return response, err 614 } 615 return nil, err 616 } 617 618 // GetHeaderByHash returns the requested header by hash. 619 func (s *PublicBlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) map[string]interface{} { 620 header, _ := s.b.HeaderByHash(ctx, hash) 621 if header != nil { 622 return s.rpcMarshalHeader(ctx, header) 623 } 624 return nil 625 } 626 627 // GetBlockByNumber returns the requested canonical block. 628 // - When blockNr is -1 the chain head is returned. 629 // - When blockNr is -2 the pending chain head is returned. 630 // - When fullTx is true all transactions in the block are returned, otherwise 631 // only the transaction hash is returned. 632 func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { 633 block, err := s.b.BlockByNumber(ctx, number) 634 if block != nil && err == nil { 635 response, err := s.rpcMarshalBlock(ctx, block, true, fullTx) 636 if err == nil && number == rpc.PendingBlockNumber { 637 // Pending blocks need to nil out a few fields 638 for _, field := range []string{"hash", "nonce", "miner"} { 639 response[field] = nil 640 } 641 } 642 return response, err 643 } 644 return nil, err 645 } 646 647 // GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full 648 // detail, otherwise only the transaction hash is returned. 649 func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) { 650 block, err := s.b.BlockByHash(ctx, hash) 651 if block != nil { 652 return s.rpcMarshalBlock(ctx, block, true, fullTx) 653 } 654 return nil, err 655 } 656 657 // GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. When fullTx is true 658 // all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. 659 func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (map[string]interface{}, error) { 660 block, err := s.b.BlockByNumber(ctx, blockNr) 661 if block != nil { 662 uncles := block.Uncles() 663 if index >= hexutil.Uint(len(uncles)) { 664 log.Debug("Requested uncle not found", "number", blockNr, "hash", block.Hash(), "index", index) 665 return nil, nil 666 } 667 block = types.NewBlockWithHeader(uncles[index]) 668 return s.rpcMarshalBlock(ctx, block, false, false) 669 } 670 return nil, err 671 } 672 673 // GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. When fullTx is true 674 // all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. 675 func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (map[string]interface{}, error) { 676 block, err := s.b.BlockByHash(ctx, blockHash) 677 if block != nil { 678 uncles := block.Uncles() 679 if index >= hexutil.Uint(len(uncles)) { 680 log.Debug("Requested uncle not found", "number", block.Number(), "hash", blockHash, "index", index) 681 return nil, nil 682 } 683 block = types.NewBlockWithHeader(uncles[index]) 684 return s.rpcMarshalBlock(ctx, block, false, false) 685 } 686 return nil, err 687 } 688 689 // GetUncleCountByBlockNumber returns number of uncles in the block for the given block number 690 func (s *PublicBlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 691 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 692 n := hexutil.Uint(len(block.Uncles())) 693 return &n 694 } 695 return nil 696 } 697 698 // GetUncleCountByBlockHash returns number of uncles in the block for the given block hash 699 func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 700 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 701 n := hexutil.Uint(len(block.Uncles())) 702 return &n 703 } 704 return nil 705 } 706 707 // GetCode returns the code stored at the given address in the state for the given block number. 708 func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { 709 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 710 if state == nil || err != nil { 711 return nil, err 712 } 713 code := state.GetCode(address) 714 return code, state.Error() 715 } 716 717 // GetStorageAt returns the storage from the state at the given address, key and 718 // block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block 719 // numbers are also allowed. 720 func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { 721 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 722 if state == nil || err != nil { 723 return nil, err 724 } 725 res := state.GetState(address, common.HexToHash(key)) 726 return res[:], state.Error() 727 } 728 729 // CallArgs represents the arguments for a call. 730 type CallArgs struct { 731 From *common.Address `json:"from"` 732 To *common.Address `json:"to"` 733 Energy *hexutil.Uint64 `json:"energy"` 734 EnergyPrice *hexutil.Big `json:"energyPrice"` 735 Value *hexutil.Big `json:"value"` 736 Data *hexutil.Bytes `json:"data"` 737 } 738 739 // ToMessage converts CallArgs to the Message type used by the core cvm 740 func (args *CallArgs) ToMessage(globalEnergyCap uint64) types.Message { 741 // Set sender address or use zero address if none specified. 742 var addr common.Address 743 if args.From != nil { 744 addr = *args.From 745 } 746 747 // Set default energy & energy price if none were set 748 energy := globalEnergyCap 749 if energy == 0 { 750 energy = uint64(math.MaxUint64 / 2) 751 } 752 if args.Energy != nil { 753 energy = uint64(*args.Energy) 754 } 755 if globalEnergyCap != 0 && globalEnergyCap < energy { 756 log.Warn("Caller energy above allowance, capping", "requested", energy, "cap", globalEnergyCap) 757 energy = globalEnergyCap 758 } 759 energyPrice := new(big.Int) 760 if args.EnergyPrice != nil { 761 energyPrice = args.EnergyPrice.ToInt() 762 } 763 764 value := new(big.Int) 765 if args.Value != nil { 766 value = args.Value.ToInt() 767 } 768 769 var data []byte 770 if args.Data != nil { 771 data = *args.Data 772 } 773 774 msg := types.NewMessage(addr, args.To, 0, value, energy, energyPrice, data, false) 775 return msg 776 } 777 778 // account indicates the overriding fields of account during the execution of 779 // a message call. 780 // Note, state and stateDiff can't be specified at the same time. If state is 781 // set, message execution will only use the data in the given state. Otherwise 782 // if statDiff is set, all diff will be applied first and then execute the call 783 // message. 784 type account struct { 785 Nonce *hexutil.Uint64 `json:"nonce"` 786 Code *hexutil.Bytes `json:"code"` 787 Balance **hexutil.Big `json:"balance"` 788 State *map[common.Hash]common.Hash `json:"state"` 789 StateDiff *map[common.Hash]common.Hash `json:"stateDiff"` 790 } 791 792 func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides map[common.Address]account, vmCfg vm.Config, timeout time.Duration, globalEnergyCap uint64) (*core.ExecutionResult, error) { 793 defer func(start time.Time) { log.Debug("Executing CVM call finished", "runtime", time.Since(start)) }(time.Now()) 794 795 state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 796 if state == nil || err != nil { 797 return nil, err 798 } 799 // Override the fields of specified contracts before execution. 800 for addr, account := range overrides { 801 // Override account nonce. 802 if account.Nonce != nil { 803 state.SetNonce(addr, uint64(*account.Nonce)) 804 } 805 // Override account(contract) code. 806 if account.Code != nil { 807 state.SetCode(addr, *account.Code) 808 } 809 // Override account balance. 810 if account.Balance != nil { 811 state.SetBalance(addr, (*big.Int)(*account.Balance)) 812 } 813 if account.State != nil && account.StateDiff != nil { 814 return nil, fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex()) 815 } 816 // Replace entire state if caller requires. 817 if account.State != nil { 818 state.SetStorage(addr, *account.State) 819 } 820 // Apply state diff into specified accounts. 821 if account.StateDiff != nil { 822 for key, value := range *account.StateDiff { 823 state.SetState(addr, key, value) 824 } 825 } 826 } 827 // Setup context so it may be cancelled the call has completed 828 // or, in case of unmetered energy, setup a context with a timeout. 829 var cancel context.CancelFunc 830 if timeout > 0 { 831 ctx, cancel = context.WithTimeout(ctx, timeout) 832 } else { 833 ctx, cancel = context.WithCancel(ctx) 834 } 835 // Make sure the context is cancelled when the call has completed 836 // this makes sure resources are cleaned up. 837 defer cancel() 838 839 // Get a new instance of the CVM. 840 msg := args.ToMessage(globalEnergyCap) 841 cvm, vmError, err := b.GetCVM(ctx, msg, state, header) 842 if err != nil { 843 return nil, err 844 } 845 // Wait for the context to be done and cancel the cvm. Even if the 846 // CVM has finished, cancelling may be done (repeatedly) 847 go func() { 848 <-ctx.Done() 849 cvm.Cancel() 850 }() 851 852 // Setup the energy pool (also for unmetered requests) 853 // and apply the message. 854 gp := new(core.EnergyPool).AddEnergy(math.MaxUint64) 855 result, err := core.ApplyMessage(cvm, msg, gp) 856 if err := vmError(); err != nil { 857 return nil, err 858 } 859 // If the timer caused an abort, return an appropriate error message 860 if cvm.Cancelled() { 861 return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout) 862 } 863 if err != nil { 864 return result, fmt.Errorf("err: %w (supplied energy %d)", err, msg.Energy()) 865 } 866 return result, nil 867 } 868 869 func newRevertError(result *core.ExecutionResult) *revertError { 870 reason, errUnpack := abi.UnpackRevert(result.Revert()) 871 err := errors.New("execution reverted") 872 if errUnpack == nil { 873 err = fmt.Errorf("execution reverted: %v", reason) 874 } 875 return &revertError{ 876 error: err, 877 reason: hexutil.Encode(result.Revert()), 878 } 879 } 880 881 // revertError is an API error that encompassas an CVM revertal with JSON error 882 // code and a binary data blob. 883 type revertError struct { 884 error 885 reason string // revert reason hex encoded 886 } 887 888 // ErrorCode returns the JSON error code for a revertal. 889 // See: https://github.com/core/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal 890 func (e *revertError) ErrorCode() int { 891 return 3 892 } 893 894 // ErrorData returns the hex encoded revert reason. 895 func (e *revertError) ErrorData() interface{} { 896 return e.reason 897 } 898 899 // Call executes the given transaction on the state for the given block number. 900 // 901 // Additionally, the caller can specify a batch of contract for fields overriding. 902 // 903 // Note, this function doesn't make and changes in the state/blockchain and is 904 // useful to execute and retrieve values. 905 func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *map[common.Address]account) (hexutil.Bytes, error) { 906 var accounts map[common.Address]account 907 if overrides != nil { 908 accounts = *overrides 909 } 910 result, err := DoCall(ctx, s.b, args, blockNrOrHash, accounts, vm.Config{}, 5*time.Second, s.b.RPCEnergyCap()) 911 if err != nil { 912 return nil, err 913 } 914 // If the result contains a revert reason, try to unpack and return it. 915 if len(result.Revert()) > 0 { 916 return nil, newRevertError(result) 917 } 918 return result.Return(), result.Err 919 } 920 921 func DoEstimateEnergy(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, energyCap uint64) (hexutil.Uint64, error) { 922 // Binary search the energy requirement, as it may be higher than the amount used 923 var ( 924 lo uint64 = params.TxEnergy - 1 925 hi uint64 926 cap uint64 927 ) 928 // Use zero address if sender unspecified. 929 if args.From == nil { 930 args.From = new(common.Address) 931 } 932 // Determine the highest energy limit can be used during the estimation. 933 if args.Energy != nil && uint64(*args.Energy) >= params.TxEnergy { 934 hi = uint64(*args.Energy) 935 } else { 936 // Retrieve the block to act as the energy ceiling 937 block, err := b.BlockByNumberOrHash(ctx, blockNrOrHash) 938 if err != nil { 939 return 0, err 940 } 941 if block == nil { 942 return 0, errors.New("block not found") 943 } 944 hi = block.EnergyLimit() 945 } 946 // Recap the highest energy limit with account's available balance. 947 if args.EnergyPrice != nil && args.EnergyPrice.ToInt().BitLen() != 0 { 948 state, _, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 949 if err != nil { 950 return 0, err 951 } 952 balance := state.GetBalance(*args.From) // from can't be nil 953 available := new(big.Int).Set(balance) 954 if args.Value != nil { 955 if args.Value.ToInt().Cmp(available) >= 0 { 956 return 0, errors.New("insufficient funds for transfer") 957 } 958 available.Sub(available, args.Value.ToInt()) 959 } 960 allowance := new(big.Int).Div(available, args.EnergyPrice.ToInt()) 961 962 // If the allowance is larger than maximum uint64, skip checking 963 if allowance.IsUint64() && hi > allowance.Uint64() { 964 transfer := args.Value 965 if transfer == nil { 966 transfer = new(hexutil.Big) 967 } 968 log.Warn("Energy estimation capped by limited funds", "original", hi, "balance", balance, 969 "sent", transfer.ToInt(), "energyprice", args.EnergyPrice.ToInt(), "fundable", allowance) 970 hi = allowance.Uint64() 971 } 972 } 973 // Recap the highest energy allowance with specified energycap. 974 if energyCap != 0 && hi > energyCap { 975 log.Warn("Caller energy above allowance, capping", "requested", hi, "cap", energyCap) 976 hi = energyCap 977 } 978 cap = hi 979 980 // Create a helper to check if a energy allowance results in an executable transaction 981 executable := func(energy uint64) (bool, *core.ExecutionResult, error) { 982 args.Energy = (*hexutil.Uint64)(&energy) 983 984 result, err := DoCall(ctx, b, args, blockNrOrHash, nil, vm.Config{}, 0, energyCap) 985 if err != nil { 986 if errors.Is(err, core.ErrIntrinsicEnergy) { 987 return true, nil, nil // Special case, raise energy limit 988 } 989 return true, nil, err // Bail out 990 } 991 return result.Failed(), result, nil 992 } 993 // Execute the binary search and hone in on an executable energy limit 994 for lo+1 < hi { 995 mid := (hi + lo) / 2 996 failed, _, err := executable(mid) 997 998 // If the error is not nil(consensus error), it means the provided message 999 // call or transaction will never be accepted no matter how much energy it is 1000 // assigened. Return the error directly, don't struggle any more. 1001 if err != nil { 1002 return 0, err 1003 } 1004 if failed { 1005 lo = mid 1006 } else { 1007 hi = mid 1008 } 1009 } 1010 // Reject the transaction as invalid if it still fails at the highest allowance 1011 if hi == cap { 1012 failed, result, err := executable(hi) 1013 if err != nil { 1014 return 0, err 1015 } 1016 if failed { 1017 if result != nil && result.Err != vm.ErrOutOfEnergy { 1018 if len(result.Revert()) > 0 { 1019 return 0, newRevertError(result) 1020 } 1021 return 0, result.Err 1022 } 1023 // Otherwise, the specified energy cap is too low 1024 return 0, fmt.Errorf("energy required exceeds allowance (%d)", cap) 1025 } 1026 } 1027 return hexutil.Uint64(hi), nil 1028 } 1029 1030 // EstimateEnergy returns an estimate of the amount of energy needed to execute the 1031 // given transaction against the current pending block. 1032 func (s *PublicBlockChainAPI) EstimateEnergy(ctx context.Context, args CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) { 1033 bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) 1034 if blockNrOrHash != nil { 1035 bNrOrHash = *blockNrOrHash 1036 } 1037 return DoEstimateEnergy(ctx, s.b, args, bNrOrHash, s.b.RPCEnergyCap()) 1038 } 1039 1040 // ExecutionResult groups all structured logs emitted by the CVM 1041 // while replaying a transaction in debug mode as well as transaction 1042 // execution status, the amount of energy used and the return value 1043 type ExecutionResult struct { 1044 Energy uint64 `json:"energy"` 1045 Failed bool `json:"failed"` 1046 ReturnValue string `json:"returnValue"` 1047 StructLogs []StructLogRes `json:"structLogs"` 1048 } 1049 1050 // StructLogRes stores a structured log emitted by the CVM while replaying a 1051 // transaction in debug mode 1052 type StructLogRes struct { 1053 Pc uint64 `json:"pc"` 1054 Op string `json:"op"` 1055 Energy uint64 `json:"energy"` 1056 EnergyCost uint64 `json:"energyCost"` 1057 Depth int `json:"depth"` 1058 Error error `json:"error,omitempty"` 1059 Stack *[]string `json:"stack,omitempty"` 1060 Memory *[]string `json:"memory,omitempty"` 1061 Storage *map[string]string `json:"storage,omitempty"` 1062 } 1063 1064 // FormatLogs formats CVM returned structured logs for json output 1065 func FormatLogs(logs []vm.StructLog) []StructLogRes { 1066 formatted := make([]StructLogRes, len(logs)) 1067 for index, trace := range logs { 1068 formatted[index] = StructLogRes{ 1069 Pc: trace.Pc, 1070 Op: trace.Op.String(), 1071 Energy: trace.Energy, 1072 EnergyCost: trace.EnergyCost, 1073 Depth: trace.Depth, 1074 Error: trace.Err, 1075 } 1076 if trace.Stack != nil { 1077 stack := make([]string, len(trace.Stack)) 1078 for i, stackValue := range trace.Stack { 1079 stack[i] = fmt.Sprintf("%x", math.PaddedBigBytes(stackValue, 32)) 1080 } 1081 formatted[index].Stack = &stack 1082 } 1083 if trace.Memory != nil { 1084 memory := make([]string, 0, (len(trace.Memory)+31)/32) 1085 for i := 0; i+32 <= len(trace.Memory); i += 32 { 1086 memory = append(memory, fmt.Sprintf("%x", trace.Memory[i:i+32])) 1087 } 1088 formatted[index].Memory = &memory 1089 } 1090 if trace.Storage != nil { 1091 storage := make(map[string]string) 1092 for i, storageValue := range trace.Storage { 1093 storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue) 1094 } 1095 formatted[index].Storage = &storage 1096 } 1097 } 1098 return formatted 1099 } 1100 1101 // RPCMarshalHeader converts the given header to the RPC output . 1102 func RPCMarshalHeader(head *types.Header) map[string]interface{} { 1103 return map[string]interface{}{ 1104 "number": (*hexutil.Big)(head.Number), 1105 "hash": head.Hash(), 1106 "parentHash": head.ParentHash, 1107 "nonce": head.Nonce, 1108 "sha3Uncles": head.UncleHash, 1109 "logsBloom": head.Bloom, 1110 "stateRoot": head.Root, 1111 "miner": head.Coinbase, 1112 "difficulty": (*hexutil.Big)(head.Difficulty), 1113 "extraData": hexutil.Bytes(head.Extra), 1114 "size": hexutil.Uint64(head.Size()), 1115 "energyLimit": hexutil.Uint64(head.EnergyLimit), 1116 "energyUsed": hexutil.Uint64(head.EnergyUsed), 1117 "timestamp": hexutil.Uint64(head.Time), 1118 "transactionsRoot": head.TxHash, 1119 "receiptsRoot": head.ReceiptHash, 1120 } 1121 } 1122 1123 // RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are 1124 // returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain 1125 // transaction hashes. 1126 func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, networkID *big.Int) (map[string]interface{}, error) { 1127 fields := RPCMarshalHeader(block.Header()) 1128 fields["size"] = hexutil.Uint64(block.Size()) 1129 1130 if inclTx { 1131 formatTx := func(tx *types.Transaction) (interface{}, error) { 1132 return tx.Hash(), nil 1133 } 1134 if fullTx { 1135 formatTx = func(tx *types.Transaction) (interface{}, error) { 1136 return newRPCTransactionFromBlockHash(block, tx.Hash(), networkID), nil 1137 } 1138 } 1139 txs := block.Transactions() 1140 transactions := make([]interface{}, len(txs)) 1141 var err error 1142 for i, tx := range txs { 1143 if transactions[i], err = formatTx(tx); err != nil { 1144 return nil, err 1145 } 1146 } 1147 fields["transactions"] = transactions 1148 } 1149 uncles := block.Uncles() 1150 uncleHashes := make([]common.Hash, len(uncles)) 1151 for i, uncle := range uncles { 1152 uncleHashes[i] = uncle.Hash() 1153 } 1154 fields["uncles"] = uncleHashes 1155 1156 return fields, nil 1157 } 1158 1159 // rpcMarshalHeader uses the generalized output filler, then adds the total difficulty field, which requires 1160 // a `PublicBlockchainAPI`. 1161 func (s *PublicBlockChainAPI) rpcMarshalHeader(ctx context.Context, header *types.Header) map[string]interface{} { 1162 fields := RPCMarshalHeader(header) 1163 fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, header.Hash())) 1164 return fields 1165 } 1166 1167 // rpcMarshalBlock uses the generalized output filler, then adds the total difficulty field, which requires 1168 // a `PublicBlockchainAPI`. 1169 func (s *PublicBlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { 1170 fields, err := RPCMarshalBlock(b, inclTx, fullTx, s.b.ChainConfig().NetworkID) 1171 if err != nil { 1172 return nil, err 1173 } 1174 if inclTx { 1175 fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(ctx, b.Hash())) 1176 } 1177 return fields, err 1178 } 1179 1180 // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction 1181 type RPCTransaction struct { 1182 BlockHash *common.Hash `json:"blockHash"` 1183 BlockNumber *hexutil.Big `json:"blockNumber"` 1184 From common.Address `json:"from"` 1185 Energy hexutil.Uint64 `json:"energy"` 1186 EnergyPrice *hexutil.Big `json:"energyPrice"` 1187 Hash common.Hash `json:"hash"` 1188 Input hexutil.Bytes `json:"input"` 1189 Nonce hexutil.Uint64 `json:"nonce"` 1190 To *common.Address `json:"to"` 1191 NetworkID hexutil.Uint64 `json:"network_id"` 1192 Signature hexutil.Bytes `json:"signature"` 1193 TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` 1194 Value *hexutil.Big `json:"value"` 1195 } 1196 1197 // newRPCTransaction returns a transaction that will serialize to the RPC 1198 // representation, with the given location metadata set (if available). 1199 func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64, networkID *big.Int) *RPCTransaction { 1200 signer := types.NewNucleusSigner(networkID) 1201 from, err := types.Sender(signer, tx) 1202 if err != nil { 1203 log.Error("newRPCTransaction signature or recipient error", "err", err) 1204 } 1205 result := &RPCTransaction{ 1206 From: from, 1207 Energy: hexutil.Uint64(tx.Energy()), 1208 EnergyPrice: (*hexutil.Big)(tx.EnergyPrice()), 1209 Hash: tx.Hash(), 1210 Input: hexutil.Bytes(tx.Data()), 1211 Nonce: hexutil.Uint64(tx.Nonce()), 1212 To: tx.To(), 1213 NetworkID: hexutil.Uint64(tx.NetworkID()), 1214 Signature: hexutil.Bytes(tx.Signature()), 1215 Value: (*hexutil.Big)(tx.Value()), 1216 } 1217 if blockHash != (common.Hash{}) { 1218 result.BlockHash = &blockHash 1219 result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber)) 1220 result.TransactionIndex = (*hexutil.Uint64)(&index) 1221 } 1222 return result 1223 } 1224 1225 // newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation 1226 func newRPCPendingTransaction(tx *types.Transaction, networkID *big.Int) *RPCTransaction { 1227 return newRPCTransaction(tx, common.Hash{}, 0, 0, networkID) 1228 } 1229 1230 // newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation. 1231 func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, networkID *big.Int) *RPCTransaction { 1232 txs := b.Transactions() 1233 if index >= uint64(len(txs)) { 1234 return nil 1235 } 1236 return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index, networkID) 1237 } 1238 1239 // newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index. 1240 func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) hexutil.Bytes { 1241 txs := b.Transactions() 1242 if index >= uint64(len(txs)) { 1243 return nil 1244 } 1245 blob, _ := rlp.EncodeToBytes(txs[index]) 1246 return blob 1247 } 1248 1249 // newRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation. 1250 func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash, networkID *big.Int) *RPCTransaction { 1251 for idx, tx := range b.Transactions() { 1252 if tx.Hash() == hash { 1253 return newRPCTransactionFromBlockIndex(b, uint64(idx), networkID) 1254 } 1255 } 1256 return nil 1257 } 1258 1259 // PublicTransactionPoolAPI exposes methods for the RPC interface 1260 type PublicTransactionPoolAPI struct { 1261 b Backend 1262 nonceLock *AddrLocker 1263 } 1264 1265 // NewPublicTransactionPoolAPI creates a new RPC service with methods specific for the transaction pool. 1266 func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransactionPoolAPI { 1267 return &PublicTransactionPoolAPI{b, nonceLock} 1268 } 1269 1270 // GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number. 1271 func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 1272 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 1273 n := hexutil.Uint(len(block.Transactions())) 1274 return &n 1275 } 1276 return nil 1277 } 1278 1279 // GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash. 1280 func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 1281 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 1282 n := hexutil.Uint(len(block.Transactions())) 1283 return &n 1284 } 1285 return nil 1286 } 1287 1288 // GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index. 1289 func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction { 1290 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 1291 return newRPCTransactionFromBlockIndex(block, uint64(index), s.b.ChainConfig().NetworkID) 1292 } 1293 return nil 1294 } 1295 1296 // GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index. 1297 func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction { 1298 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 1299 return newRPCTransactionFromBlockIndex(block, uint64(index), s.b.ChainConfig().NetworkID) 1300 } 1301 return nil 1302 } 1303 1304 // GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index. 1305 func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) hexutil.Bytes { 1306 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 1307 return newRPCRawTransactionFromBlockIndex(block, uint64(index)) 1308 } 1309 return nil 1310 } 1311 1312 // GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index. 1313 func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) hexutil.Bytes { 1314 if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { 1315 return newRPCRawTransactionFromBlockIndex(block, uint64(index)) 1316 } 1317 return nil 1318 } 1319 1320 // GetTransactionCount returns the number of transactions the given address has sent for the given block number 1321 func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Uint64, error) { 1322 // Ask transaction pool for the nonce which includes pending transactions 1323 if blockNr, ok := blockNrOrHash.Number(); ok && blockNr == rpc.PendingBlockNumber { 1324 nonce, err := s.b.GetPoolNonce(ctx, address) 1325 if err != nil { 1326 return nil, err 1327 } 1328 return (*hexutil.Uint64)(&nonce), nil 1329 } 1330 // Resolve block number and use its state to ask for the nonce 1331 state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) 1332 if state == nil || err != nil { 1333 return nil, err 1334 } 1335 nonce := state.GetNonce(address) 1336 return (*hexutil.Uint64)(&nonce), state.Error() 1337 } 1338 1339 // GetTransactionByHash returns the transaction for the given hash 1340 func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) { 1341 // Try to return an already finalized transaction 1342 tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash) 1343 if err != nil { 1344 return nil, err 1345 } 1346 if tx != nil { 1347 return newRPCTransaction(tx, blockHash, blockNumber, index, s.b.ChainConfig().NetworkID), nil 1348 } 1349 // No finalized transaction, try to retrieve it from the pool 1350 if tx := s.b.GetPoolTransaction(hash); tx != nil { 1351 return newRPCPendingTransaction(tx, s.b.ChainConfig().NetworkID), nil 1352 } 1353 1354 // Transaction unknown, return as such 1355 return nil, nil 1356 } 1357 1358 // GetRawTransactionByHash returns the bytes of the transaction for the given hash. 1359 func (s *PublicTransactionPoolAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { 1360 // Retrieve a finalized transaction, or a pooled otherwise 1361 tx, _, _, _, err := s.b.GetTransaction(ctx, hash) 1362 if err != nil { 1363 return nil, err 1364 } 1365 if tx == nil { 1366 if tx = s.b.GetPoolTransaction(hash); tx == nil { 1367 // Transaction not found anywhere, abort 1368 return nil, nil 1369 } 1370 } 1371 // Serialize to RLP and return 1372 return rlp.EncodeToBytes(tx) 1373 } 1374 1375 // GetTransactionReceipt returns the transaction receipt for the given transaction hash. 1376 func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { 1377 tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash) 1378 if err != nil { 1379 return nil, nil 1380 } 1381 receipts, err := s.b.GetReceipts(ctx, blockHash) 1382 if err != nil { 1383 return nil, err 1384 } 1385 if len(receipts) <= int(index) { 1386 return nil, nil 1387 } 1388 receipt := receipts[index] 1389 1390 var signer types.Signer = types.NewNucleusSigner(s.b.ChainConfig().NetworkID) 1391 from, err := types.Sender(signer, tx) 1392 if err != nil { 1393 return nil, err 1394 } 1395 fields := map[string]interface{}{ 1396 "blockHash": blockHash, 1397 "blockNumber": hexutil.Uint64(blockNumber), 1398 "transactionHash": hash, 1399 "transactionIndex": hexutil.Uint64(index), 1400 "from": from, 1401 "to": tx.To(), 1402 "energyUsed": hexutil.Uint64(receipt.EnergyUsed), 1403 "cumulativeEnergyUsed": hexutil.Uint64(receipt.CumulativeEnergyUsed), 1404 "contractAddress": nil, 1405 "logs": receipt.Logs, 1406 "logsBloom": receipt.Bloom, 1407 } 1408 1409 // Assign receipt status or post state. 1410 if len(receipt.PostState) > 0 { 1411 fields["root"] = hexutil.Bytes(receipt.PostState) 1412 } else { 1413 fields["status"] = hexutil.Uint(receipt.Status) 1414 } 1415 if receipt.Logs == nil { 1416 fields["logs"] = [][]*types.Log{} 1417 } 1418 // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation 1419 if receipt.ContractAddress != (common.Address{}) { 1420 fields["contractAddress"] = receipt.ContractAddress 1421 } 1422 return fields, nil 1423 } 1424 1425 // sign is a helper function that signs a transaction with the private key of the given address. 1426 func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { 1427 // Look up the wallet containing the requested signer 1428 account := accounts.Account{Address: addr} 1429 1430 wallet, err := s.b.AccountManager().Find(account) 1431 if err != nil { 1432 return nil, err 1433 } 1434 // Request the wallet to sign the transaction 1435 return wallet.SignTx(account, tx, s.b.ChainConfig().NetworkID) 1436 } 1437 1438 // SendTxArgs represents the arguments to sumbit a new transaction into the transaction pool. 1439 type SendTxArgs struct { 1440 From common.Address `json:"from"` 1441 To *common.Address `json:"to"` 1442 Energy *hexutil.Uint64 `json:"energy"` 1443 EnergyPrice *hexutil.Big `json:"energyPrice"` 1444 Value *hexutil.Big `json:"value"` 1445 Nonce *hexutil.Uint64 `json:"nonce"` 1446 NetworkID int64 `json:"network_id"` 1447 // We accept "data" and "input" for backwards-compatibility reasons. "input" is the 1448 // newer name and should be preferred by clients. 1449 Data *hexutil.Bytes `json:"data"` 1450 Input *hexutil.Bytes `json:"input"` 1451 } 1452 1453 // setDefaults is a helper function that fills in default values for unspecified tx fields. 1454 func (args *SendTxArgs) setDefaults(ctx context.Context, b Backend) error { 1455 if args.EnergyPrice == nil { 1456 price, err := b.SuggestPrice(ctx) 1457 if err != nil { 1458 return err 1459 } 1460 args.EnergyPrice = (*hexutil.Big)(price) 1461 } 1462 if args.Value == nil { 1463 args.Value = new(hexutil.Big) 1464 } 1465 if args.Nonce == nil { 1466 nonce, err := b.GetPoolNonce(ctx, args.From) 1467 if err != nil { 1468 return err 1469 } 1470 args.Nonce = (*hexutil.Uint64)(&nonce) 1471 } 1472 if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) { 1473 return errors.New(`both "data" and "input" are set and not equal. Please use "input" to pass transaction call data`) 1474 } 1475 if args.To == nil { 1476 // Contract creation 1477 var input []byte 1478 if args.Data != nil { 1479 input = *args.Data 1480 } else if args.Input != nil { 1481 input = *args.Input 1482 } 1483 if len(input) == 0 { 1484 return errors.New(`contract creation without any data provided`) 1485 } 1486 } 1487 // Estimate the energy usage if necessary. 1488 if args.Energy == nil { 1489 // For backwards-compatibility reason, we try both input and data 1490 // but input is preferred. 1491 input := args.Input 1492 if input == nil { 1493 input = args.Data 1494 } 1495 callArgs := CallArgs{ 1496 From: &args.From, // From shouldn't be nil 1497 To: args.To, 1498 EnergyPrice: args.EnergyPrice, 1499 Value: args.Value, 1500 Data: input, 1501 } 1502 pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) 1503 estimated, err := DoEstimateEnergy(ctx, b, callArgs, pendingBlockNr, b.RPCEnergyCap()) 1504 if err != nil { 1505 return err 1506 } 1507 args.Energy = &estimated 1508 log.Trace("Estimate energy usage automatically", "energy", args.Energy) 1509 } 1510 args.NetworkID = b.ChainConfig().NetworkID.Int64() 1511 return nil 1512 } 1513 1514 func (args *SendTxArgs) toTransaction() *types.Transaction { 1515 var input []byte 1516 if args.Input != nil { 1517 input = *args.Input 1518 } else if args.Data != nil { 1519 input = *args.Data 1520 } 1521 var tx *types.Transaction 1522 if args.To == nil { 1523 tx = types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), uint64(*args.Energy), (*big.Int)(args.EnergyPrice), input) 1524 } else { 1525 tx = types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), uint64(*args.Energy), (*big.Int)(args.EnergyPrice), input) 1526 } 1527 tx.SetNetworkID(uint(args.NetworkID)) 1528 return tx 1529 } 1530 1531 // SubmitTransaction is a helper function that submits tx to txPool and logs a message. 1532 func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) { 1533 // If the transaction fee cap is already specified, ensure the 1534 // fee of the given transaction is _reasonable_. 1535 if err := checkTxFee(tx.EnergyPrice(), tx.Energy(), b.RPCTxFeeCap()); err != nil { 1536 return common.Hash{}, err 1537 } 1538 if err := b.SendTx(ctx, tx); err != nil { 1539 return common.Hash{}, err 1540 } 1541 if tx.To() == nil { 1542 signer := types.MakeSigner(b.ChainConfig().NetworkID) 1543 from, err := types.Sender(signer, tx) 1544 if err != nil { 1545 return common.Hash{}, err 1546 } 1547 addr := crypto.CreateAddress(from, tx.Nonce()) 1548 log.Info("Submitted contract creation", "fullhash", tx.Hash().Hex(), "contract", addr.Hex()) 1549 } else { 1550 log.Info("Submitted transaction", "fullhash", tx.Hash().Hex(), "recipient", tx.To()) 1551 } 1552 return tx.Hash(), nil 1553 } 1554 1555 // SendTransaction creates a transaction for the given argument, sign it and submit it to the 1556 // transaction pool. 1557 func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) { 1558 // Look up the wallet containing the requested signer 1559 account := accounts.Account{Address: args.From} 1560 1561 wallet, err := s.b.AccountManager().Find(account) 1562 if err != nil { 1563 return common.Hash{}, err 1564 } 1565 1566 if args.Nonce == nil { 1567 // Hold the addresse's mutex around signing to prevent concurrent assignment of 1568 // the same nonce to multiple accounts. 1569 s.nonceLock.LockAddr(args.From) 1570 defer s.nonceLock.UnlockAddr(args.From) 1571 } 1572 1573 // Set some sanity defaults and terminate on failure 1574 if err := args.setDefaults(ctx, s.b); err != nil { 1575 return common.Hash{}, err 1576 } 1577 // Assemble the transaction and sign with the wallet 1578 tx := args.toTransaction() 1579 1580 signed, err := wallet.SignTx(account, tx, s.b.ChainConfig().NetworkID) 1581 if err != nil { 1582 return common.Hash{}, err 1583 } 1584 return SubmitTransaction(ctx, s.b, signed) 1585 } 1586 1587 // FillTransaction fills the defaults (nonce, energy, energyPrice) on a given unsigned transaction, 1588 // and returns it to the caller for further processing (signing + broadcast) 1589 func (s *PublicTransactionPoolAPI) FillTransaction(ctx context.Context, args SendTxArgs) (*SignTransactionResult, error) { 1590 // Set some sanity defaults and terminate on failure 1591 if err := args.setDefaults(ctx, s.b); err != nil { 1592 return nil, err 1593 } 1594 // Assemble the transaction and obtain rlp 1595 tx := args.toTransaction() 1596 data, err := rlp.EncodeToBytes(tx) 1597 if err != nil { 1598 return nil, err 1599 } 1600 return &SignTransactionResult{data, tx}, nil 1601 } 1602 1603 // SendRawTransaction will add the signed transaction to the transaction pool. 1604 // The sender is responsible for signing the transaction and using the correct nonce. 1605 func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) { 1606 tx := new(types.Transaction) 1607 if err := rlp.DecodeBytes(encodedTx, tx); err != nil { 1608 return common.Hash{}, err 1609 } 1610 return SubmitTransaction(ctx, s.b, tx) 1611 } 1612 1613 // Sign calculates an EDDSA signature for: 1614 // keccack256("\x19Core Signed Message:\n" + len(message) + message). 1615 // 1616 // The account associated with addr must be unlocked. 1617 // 1618 // https://github.com/core/wiki/wiki/JSON-RPC#xcb_sign 1619 func (s *PublicTransactionPoolAPI) Sign(addr common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { 1620 // Look up the wallet containing the requested signer 1621 account := accounts.Account{Address: addr} 1622 1623 wallet, err := s.b.AccountManager().Find(account) 1624 if err != nil { 1625 return nil, err 1626 } 1627 // Sign the requested hash with the wallet 1628 signature, err := wallet.SignText(account, data) 1629 if err != nil { 1630 return nil, err 1631 } 1632 return signature, nil 1633 } 1634 1635 // SignTransactionResult represents a RLP encoded signed transaction. 1636 type SignTransactionResult struct { 1637 Raw hexutil.Bytes `json:"raw"` 1638 Tx *types.Transaction `json:"tx"` 1639 } 1640 1641 // SignTransaction will sign the given transaction with the from account. 1642 // The node needs to have the private key of the account corresponding with 1643 // the given from address and it needs to be unlocked. 1644 func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args SendTxArgs) (*SignTransactionResult, error) { 1645 if args.Energy == nil { 1646 return nil, fmt.Errorf("energy not specified") 1647 } 1648 if args.EnergyPrice == nil { 1649 return nil, fmt.Errorf("energyPrice not specified") 1650 } 1651 if args.Nonce == nil { 1652 return nil, fmt.Errorf("nonce not specified") 1653 } 1654 if err := args.setDefaults(ctx, s.b); err != nil { 1655 return nil, err 1656 } 1657 // Before actually sign the transaction, ensure the transaction fee is reasonable. 1658 if err := checkTxFee(args.EnergyPrice.ToInt(), uint64(*args.Energy), s.b.RPCTxFeeCap()); err != nil { 1659 return nil, err 1660 } 1661 tx, err := s.sign(args.From, args.toTransaction()) 1662 if err != nil { 1663 return nil, err 1664 } 1665 data, err := rlp.EncodeToBytes(tx) 1666 if err != nil { 1667 return nil, err 1668 } 1669 return &SignTransactionResult{data, tx}, nil 1670 } 1671 1672 // PendingTransactions returns the transactions that are in the transaction pool 1673 // and have a from address that is one of the accounts this node manages. 1674 func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, error) { 1675 pending, err := s.b.GetPoolTransactions() 1676 if err != nil { 1677 return nil, err 1678 } 1679 accounts := make(map[common.Address]struct{}) 1680 for _, wallet := range s.b.AccountManager().Wallets() { 1681 for _, account := range wallet.Accounts() { 1682 accounts[account.Address] = struct{}{} 1683 } 1684 } 1685 transactions := make([]*RPCTransaction, 0, len(pending)) 1686 for _, tx := range pending { 1687 var signer types.Signer = types.NewNucleusSigner(s.b.ChainConfig().NetworkID) 1688 from, err := types.Sender(signer, tx) 1689 if err != nil { 1690 return nil, err 1691 } 1692 if _, exists := accounts[from]; exists { 1693 transactions = append(transactions, newRPCPendingTransaction(tx, s.b.ChainConfig().NetworkID)) 1694 } 1695 } 1696 return transactions, nil 1697 } 1698 1699 // Resend accepts an existing transaction and a new energy price and limit. It will remove 1700 // the given transaction from the pool and reinsert it with the new energy price and limit. 1701 func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxArgs, energyPrice *hexutil.Big, energyLimit *hexutil.Uint64) (common.Hash, error) { 1702 if sendArgs.Nonce == nil { 1703 return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec") 1704 } 1705 if err := sendArgs.setDefaults(ctx, s.b); err != nil { 1706 return common.Hash{}, err 1707 } 1708 matchTx := sendArgs.toTransaction() 1709 1710 // Before replacing the old transaction, ensure the _new_ transaction fee is reasonable. 1711 var price = matchTx.EnergyPrice() 1712 if energyPrice != nil { 1713 price = energyPrice.ToInt() 1714 } 1715 var energy = matchTx.Energy() 1716 if energyLimit != nil { 1717 energy = uint64(*energyLimit) 1718 } 1719 if err := checkTxFee(price, energy, s.b.RPCTxFeeCap()); err != nil { 1720 return common.Hash{}, err 1721 } 1722 // Iterate the pending list for replacement 1723 pending, err := s.b.GetPoolTransactions() 1724 if err != nil { 1725 return common.Hash{}, err 1726 } 1727 for _, p := range pending { 1728 var signer types.Signer = types.NewNucleusSigner(s.b.ChainConfig().NetworkID) 1729 wantSigHash := signer.Hash(matchTx) 1730 1731 if pFrom, err := types.Sender(signer, p); err == nil && pFrom == sendArgs.From && signer.Hash(p) == wantSigHash { 1732 // Match. Re-sign and send the transaction. 1733 if energyPrice != nil && (*big.Int)(energyPrice).Sign() != 0 { 1734 sendArgs.EnergyPrice = energyPrice 1735 } 1736 if energyLimit != nil && *energyLimit != 0 { 1737 sendArgs.Energy = energyLimit 1738 } 1739 signedTx, err := s.sign(sendArgs.From, sendArgs.toTransaction()) 1740 if err != nil { 1741 return common.Hash{}, err 1742 } 1743 if err = s.b.SendTx(ctx, signedTx); err != nil { 1744 return common.Hash{}, err 1745 } 1746 return signedTx.Hash(), nil 1747 } 1748 } 1749 1750 return common.Hash{}, fmt.Errorf("transaction %#x not found", matchTx.Hash()) 1751 } 1752 1753 // PublicDebugAPI is the collection of Core APIs exposed over the public 1754 // debugging endpoint. 1755 type PublicDebugAPI struct { 1756 b Backend 1757 } 1758 1759 // NewPublicDebugAPI creates a new API definition for the public debug methods 1760 // of the Core service. 1761 func NewPublicDebugAPI(b Backend) *PublicDebugAPI { 1762 return &PublicDebugAPI{b: b} 1763 } 1764 1765 // GetBlockRlp retrieves the RLP encoded for of a single block. 1766 func (api *PublicDebugAPI) GetBlockRlp(ctx context.Context, number uint64) (string, error) { 1767 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 1768 if block == nil { 1769 return "", fmt.Errorf("block #%d not found", number) 1770 } 1771 encoded, err := rlp.EncodeToBytes(block) 1772 if err != nil { 1773 return "", err 1774 } 1775 return fmt.Sprintf("%x", encoded), nil 1776 } 1777 1778 // TestSignCliqueBlock fetches the given block number, and attempts to sign it as a clique header with the 1779 // given address, returning the address of the recovered signature 1780 // 1781 // This is a temporary method to debug the externalsigner integration, 1782 // TODO: Remove this method when the integration is mature 1783 func (api *PublicDebugAPI) TestSignCliqueBlock(ctx context.Context, address common.Address, number uint64) (common.Address, error) { 1784 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 1785 if block == nil { 1786 return common.Address{}, fmt.Errorf("block #%d not found", number) 1787 } 1788 header := block.Header() 1789 header.Extra = make([]byte, 32+crypto.ExtendedSignatureLength) 1790 encoded := clique.CliqueRLP(header) 1791 1792 // Look up the wallet containing the requested signer 1793 account := accounts.Account{Address: address} 1794 wallet, err := api.b.AccountManager().Find(account) 1795 if err != nil { 1796 return common.Address{}, err 1797 } 1798 1799 signature, err := wallet.SignData(account, accounts.MimetypeClique, encoded) 1800 if err != nil { 1801 return common.Address{}, err 1802 } 1803 sealHash := clique.SealHash(header).Bytes() 1804 log.Info("test signing of clique block", 1805 "Sealhash", fmt.Sprintf("%x", sealHash), 1806 "signature", fmt.Sprintf("%x", signature)) 1807 pubkey, err := crypto.Ecrecover(sealHash, signature) 1808 if err != nil { 1809 return common.Address{}, err 1810 } 1811 var signer common.Address 1812 copy(signer[:], crypto.SHA3(pubkey)[12:]) 1813 1814 return signer, nil 1815 } 1816 1817 // PrintBlock retrieves a block and returns its pretty printed form. 1818 func (api *PublicDebugAPI) PrintBlock(ctx context.Context, number uint64) (string, error) { 1819 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 1820 if block == nil { 1821 return "", fmt.Errorf("block #%d not found", number) 1822 } 1823 return spew.Sdump(block), nil 1824 } 1825 1826 // SeedHash retrieves the seed hash of a block. 1827 func (api *PublicDebugAPI) SeedHash(ctx context.Context, number uint64) (string, error) { 1828 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 1829 if block == nil { 1830 return "", fmt.Errorf("block #%d not found", number) 1831 } 1832 return fmt.Sprintf("0x%x", cryptore.SeedHash(number)), nil 1833 } 1834 1835 // PrivateDebugAPI is the collection of Core APIs exposed over the private 1836 // debugging endpoint. 1837 type PrivateDebugAPI struct { 1838 b Backend 1839 } 1840 1841 // NewPrivateDebugAPI creates a new API definition for the private debug methods 1842 // of the Core service. 1843 func NewPrivateDebugAPI(b Backend) *PrivateDebugAPI { 1844 return &PrivateDebugAPI{b: b} 1845 } 1846 1847 // ChaindbProperty returns leveldb properties of the key-value database. 1848 func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) { 1849 if property == "" { 1850 property = "leveldb.stats" 1851 } else if !strings.HasPrefix(property, "leveldb.") { 1852 property = "leveldb." + property 1853 } 1854 return api.b.ChainDb().Stat(property) 1855 } 1856 1857 // ChaindbCompact flattens the entire key-value database into a single level, 1858 // removing all unused slots and merging all keys. 1859 func (api *PrivateDebugAPI) ChaindbCompact() error { 1860 for b := byte(0); b < 255; b++ { 1861 log.Info("Compacting chain database", "range", fmt.Sprintf("0x%0.2X-0x%0.2X", b, b+1)) 1862 if err := api.b.ChainDb().Compact([]byte{b}, []byte{b + 1}); err != nil { 1863 log.Error("Database compaction failed", "err", err) 1864 return err 1865 } 1866 } 1867 return nil 1868 } 1869 1870 // SetHead rewinds the head of the blockchain to a previous block. 1871 func (api *PrivateDebugAPI) SetHead(number hexutil.Uint64) { 1872 api.b.SetHead(uint64(number)) 1873 } 1874 1875 // PublicNetAPI offers network related RPC methods 1876 type PublicNetAPI struct { 1877 net *p2p.Server 1878 networkVersion uint64 1879 } 1880 1881 // NewPublicNetAPI creates a new net API instance. 1882 func NewPublicNetAPI(net *p2p.Server, networkVersion uint64) *PublicNetAPI { 1883 return &PublicNetAPI{net, networkVersion} 1884 } 1885 1886 // Listening returns an indication if the node is listening for network connections. 1887 func (s *PublicNetAPI) Listening() bool { 1888 return true // always listening 1889 } 1890 1891 // PeerCount returns the number of connected peers 1892 func (s *PublicNetAPI) PeerCount() hexutil.Uint { 1893 return hexutil.Uint(s.net.PeerCount()) 1894 } 1895 1896 // Version returns the current core protocol version. 1897 func (s *PublicNetAPI) Version() string { 1898 return fmt.Sprintf("%d", s.networkVersion) 1899 } 1900 1901 // checkTxFee is an internal function used to check whether the fee of 1902 // the given transaction is _reasonable_(under the cap). 1903 func checkTxFee(energyPrice *big.Int, energy uint64, cap float64) error { 1904 // Short circuit if there is no cap for transaction fee at all. 1905 if cap == 0 { 1906 return nil 1907 } 1908 feeXcb := new(big.Float).Quo(new(big.Float).SetInt(new(big.Int).Mul(energyPrice, new(big.Int).SetUint64(energy))), new(big.Float).SetInt(big.NewInt(params.Core))) 1909 feeFloat, _ := feeXcb.Float64() 1910 if feeFloat > cap { 1911 return fmt.Errorf("tx fee (%.2f core) exceeds the configured cap (%.2f core)", feeFloat, cap) 1912 } 1913 return nil 1914 } 1915 1916 // toHexSlice creates a slice of hex-strings based on []byte. 1917 func toHexSlice(b [][]byte) []string { 1918 r := make([]string, len(b)) 1919 for i := range b { 1920 r[i] = hexutil.Encode(b[i]) 1921 } 1922 return r 1923 }