github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/eth/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 eth 18 19 import ( 20 "bytes" 21 "context" 22 "encoding/hex" 23 "encoding/json" 24 "errors" 25 "fmt" 26 "io" 27 "math" 28 "math/big" 29 "os" 30 "runtime" 31 "sync" 32 "time" 33 34 "github.com/ethereumproject/ethash" 35 "github.com/ethereumproject/go-ethereum/accounts" 36 "github.com/ethereumproject/go-ethereum/common" 37 "github.com/ethereumproject/go-ethereum/common/compiler" 38 "github.com/ethereumproject/go-ethereum/common/hexutil" 39 "github.com/ethereumproject/go-ethereum/core" 40 "github.com/ethereumproject/go-ethereum/core/state" 41 "github.com/ethereumproject/go-ethereum/core/types" 42 "github.com/ethereumproject/go-ethereum/core/vm" 43 "github.com/ethereumproject/go-ethereum/crypto" 44 "github.com/ethereumproject/go-ethereum/ethdb" 45 "github.com/ethereumproject/go-ethereum/event" 46 "github.com/ethereumproject/go-ethereum/logger" 47 "github.com/ethereumproject/go-ethereum/logger/glog" 48 ethMetrics "github.com/ethereumproject/go-ethereum/metrics" 49 "github.com/ethereumproject/go-ethereum/miner" 50 "github.com/ethereumproject/go-ethereum/p2p" 51 "github.com/ethereumproject/go-ethereum/rlp" 52 "github.com/ethereumproject/go-ethereum/rpc" 53 ) 54 55 const defaultGas = uint64(90000) 56 57 // blockByNumber is a commonly used helper function which retrieves and returns 58 // the block for the given block number, capable of handling two special blocks: 59 // rpc.LatestBlockNumber and rpc.PendingBlockNumber. It returns nil when no block 60 // could be found. 61 func blockByNumber(m *miner.Miner, bc *core.BlockChain, blockNr rpc.BlockNumber) *types.Block { 62 // Pending block is only known by the miner 63 if blockNr == rpc.PendingBlockNumber { 64 block, _ := m.Pending() 65 return block 66 } 67 // Otherwise resolve and return the block 68 if blockNr == rpc.LatestBlockNumber { 69 return bc.CurrentBlock() 70 } 71 return bc.GetBlockByNumber(uint64(blockNr)) 72 } 73 74 // stateAndBlockByNumber is a commonly used helper function which retrieves and 75 // returns the state and containing block for the given block number, capable of 76 // handling two special states: rpc.LatestBlockNumber and rpc.PendingBlockNumber. 77 // It returns nil when no block or state could be found. 78 func stateAndBlockByNumber(m *miner.Miner, bc *core.BlockChain, blockNr rpc.BlockNumber, chainDb ethdb.Database) (*state.StateDB, *types.Block, error) { 79 // Pending state is only known by the miner 80 if blockNr == rpc.PendingBlockNumber { 81 block, state := m.Pending() 82 return state, block, nil 83 } 84 // Otherwise resolve the block number and return its state 85 block := blockByNumber(m, bc, blockNr) 86 if block == nil { 87 return nil, nil, nil 88 } 89 stateDb, err := state.New(block.Root(), state.NewDatabase(chainDb)) 90 return stateDb, block, err 91 } 92 93 // PublicEthereumAPI provides an API to access Ethereum related information. 94 // It offers only methods that operate on public data that is freely available to anyone. 95 type PublicEthereumAPI struct { 96 e *Ethereum 97 gpo *GasPriceOracle 98 } 99 100 // NewPublicEthereumAPI creates a new Ethereum protocol API. 101 func NewPublicEthereumAPI(e *Ethereum) *PublicEthereumAPI { 102 return &PublicEthereumAPI{ 103 e: e, 104 gpo: e.gpo, 105 } 106 } 107 108 // GasPrice returns a suggestion for a gas price. 109 func (s *PublicEthereumAPI) GasPrice() *big.Int { 110 return s.gpo.SuggestPrice() 111 } 112 113 // GetCompilers returns the collection of available smart contract compilers 114 func (s *PublicEthereumAPI) GetCompilers() ([]string, error) { 115 solc, err := s.e.Solc() 116 if err == nil && solc != nil { 117 return []string{"Solidity"}, nil 118 } 119 120 return []string{}, nil 121 } 122 123 // CompileSolidity compiles the given solidity source 124 func (s *PublicEthereumAPI) CompileSolidity(source string) (map[string]*compiler.Contract, error) { 125 solc, err := s.e.Solc() 126 if err != nil { 127 return nil, err 128 } 129 130 if solc == nil { 131 return nil, errors.New("solc (solidity compiler) not found") 132 } 133 134 return solc.Compile(source) 135 } 136 137 // Etherbase is the address that mining rewards will be send to 138 func (s *PublicEthereumAPI) Etherbase() (common.Address, error) { 139 return s.e.Etherbase() 140 } 141 142 // Coinbase is the address that mining rewards will be send to (alias for Etherbase) 143 func (s *PublicEthereumAPI) Coinbase() (common.Address, error) { 144 return s.Etherbase() 145 } 146 147 // ProtocolVersion returns the current Ethereum protocol version this node supports 148 func (s *PublicEthereumAPI) ProtocolVersion() *rpc.HexNumber { 149 return rpc.NewHexNumber(s.e.EthVersion()) 150 } 151 152 // Hashrate returns the POW hashrate 153 func (s *PublicEthereumAPI) Hashrate() *rpc.HexNumber { 154 return rpc.NewHexNumber(s.e.Miner().HashRate()) 155 } 156 157 // Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not 158 // yet received the latest block headers from its pears. In case it is synchronizing: 159 // - startingBlock: block number this node started to synchronise from 160 // - currentBlock: block number this node is currently importing 161 // - highestBlock: block number of the highest block header this node has received from peers 162 // - pulledStates: number of state entries processed until now 163 // - knownStates: number of known state entries that still need to be pulled 164 func (s *PublicEthereumAPI) Syncing() (interface{}, error) { 165 origin, current, height, pulled, known := s.e.Downloader().Progress() 166 167 // Return not syncing if the synchronisation already completed 168 if current >= height { 169 return false, nil 170 } 171 // Otherwise gather the block sync stats 172 return map[string]interface{}{ 173 "startingBlock": rpc.NewHexNumber(origin), 174 "currentBlock": rpc.NewHexNumber(current), 175 "highestBlock": rpc.NewHexNumber(height), 176 "pulledStates": rpc.NewHexNumber(pulled), 177 "knownStates": rpc.NewHexNumber(known), 178 }, nil 179 } 180 181 // ChainId returns the chain-configured value for EIP-155 chain id, used in signing protected txs. 182 // If EIP-155 is not configured it will return 0. 183 // Number will be returned as a string in hexadecimal format. 184 // 61 - Mainnet $((0x3d)) 185 // 62 - Morden $((0x3e)) 186 func (s *PublicEthereumAPI) ChainId() *big.Int { 187 return s.e.chainConfig.GetChainID() 188 } 189 190 // PublicMinerAPI provides an API to control the miner. 191 // It offers only methods that operate on data that pose no security risk when it is publicly accessible. 192 type PublicMinerAPI struct { 193 e *Ethereum 194 agent *miner.RemoteAgent 195 } 196 197 // NewPublicMinerAPI create a new PublicMinerAPI instance. 198 func NewPublicMinerAPI(e *Ethereum) *PublicMinerAPI { 199 agent := miner.NewRemoteAgent() 200 e.Miner().Register(agent) 201 202 return &PublicMinerAPI{e, agent} 203 } 204 205 // Mining returns an indication if this node is currently mining. 206 func (s *PublicMinerAPI) Mining() bool { 207 return s.e.IsMining() 208 } 209 210 // SubmitWork can be used by external miner to submit their POW solution. It returns an indication if the work was 211 // accepted. Note, this is not an indication if the provided work was valid! 212 func (s *PublicMinerAPI) SubmitWork(nonce rpc.HexNumber, solution, digest common.Hash) bool { 213 return s.agent.SubmitWork(nonce.Uint64(), digest, solution) 214 } 215 216 // GetWork returns a work package for external miner. The work package consists of 3 strings 217 // result[0], 32 bytes hex encoded current block header pow-hash 218 // result[1], 32 bytes hex encoded seed hash used for DAG 219 // result[2], 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty 220 func (s *PublicMinerAPI) GetWork() (work [3]string, err error) { 221 if !s.e.IsMining() { 222 if err := s.e.StartMining(0, ""); err != nil { 223 return work, err 224 } 225 } 226 if work, err = s.agent.GetWork(); err == nil { 227 return 228 } 229 glog.V(logger.Debug).Infof("%v", err) 230 return work, fmt.Errorf("mining not ready") 231 } 232 233 // SubmitHashrate can be used for remote miners to submit their hash rate. This enables the node to report the combined 234 // hash rate of all miners which submit work through this node. It accepts the miner hash rate and an identifier which 235 // must be unique between nodes. 236 func (s *PublicMinerAPI) SubmitHashrate(hashrate rpc.HexNumber, id common.Hash) bool { 237 s.agent.SubmitHashrate(id, hashrate.Uint64()) 238 return true 239 } 240 241 // PrivateMinerAPI provides private RPC methods to control the miner. 242 // These methods can be abused by external users and must be considered insecure for use by untrusted users. 243 type PrivateMinerAPI struct { 244 e *Ethereum 245 } 246 247 // NewPrivateMinerAPI create a new RPC service which controls the miner of this node. 248 func NewPrivateMinerAPI(e *Ethereum) *PrivateMinerAPI { 249 return &PrivateMinerAPI{e: e} 250 } 251 252 // Start the miner with the given number of threads. If threads is nil the number of 253 // workers started is equal to the number of logical CPU's that are usable by this process. 254 func (s *PrivateMinerAPI) Start(threads *rpc.HexNumber) (bool, error) { 255 s.e.StartAutoDAG() 256 257 if threads == nil { 258 threads = rpc.NewHexNumber(runtime.NumCPU()) 259 } 260 261 err := s.e.StartMining(threads.Int(), "") 262 if err == nil { 263 return true, nil 264 } 265 return false, err 266 } 267 268 // Stop the miner 269 func (s *PrivateMinerAPI) Stop() bool { 270 s.e.StopMining() 271 return true 272 } 273 274 // SetGasPrice sets the minimum accepted gas price for the miner. 275 func (s *PrivateMinerAPI) SetGasPrice(gasPrice rpc.HexNumber) bool { 276 s.e.Miner().SetGasPrice(gasPrice.BigInt()) 277 return true 278 } 279 280 // SetEtherbase sets the etherbase of the miner 281 func (s *PrivateMinerAPI) SetEtherbase(etherbase common.Address) bool { 282 s.e.SetEtherbase(etherbase) 283 return true 284 } 285 286 // StartAutoDAG starts auto DAG generation. This will prevent the DAG generating on epoch change 287 // which will cause the node to stop mining during the generation process. 288 func (s *PrivateMinerAPI) StartAutoDAG() bool { 289 s.e.StartAutoDAG() 290 return true 291 } 292 293 // StopAutoDAG stops auto DAG generation 294 func (s *PrivateMinerAPI) StopAutoDAG() bool { 295 s.e.StopAutoDAG() 296 return true 297 } 298 299 // StopAutoDAG stops auto DAG generation 300 func (s *PrivateMinerAPI) SetExtra(b hexutil.Bytes) bool { 301 // types.HeaderExtraMax is the size limit for Header.Extra 302 if len(b) > types.HeaderExtraMax { 303 return false 304 } 305 miner.HeaderExtra = b 306 return true 307 } 308 309 // MakeDAG creates the new DAG for the given block number 310 func (s *PrivateMinerAPI) MakeDAG(blockNr rpc.BlockNumber) (bool, error) { 311 if err := ethash.MakeDAG(uint64(blockNr.Int64()), ""); err != nil { 312 return false, err 313 } 314 return true, nil 315 } 316 317 // PublicTxPoolAPI offers and API for the transaction pool. It only operates on data that is non confidential. 318 type PublicTxPoolAPI struct { 319 e *Ethereum 320 } 321 322 // NewPublicTxPoolAPI creates a new tx pool service that gives information about the transaction pool. 323 func NewPublicTxPoolAPI(e *Ethereum) *PublicTxPoolAPI { 324 return &PublicTxPoolAPI{e} 325 } 326 327 // Content returns the transactions contained within the transaction pool. 328 func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string][]*RPCTransaction { 329 content := map[string]map[string]map[string][]*RPCTransaction{ 330 "pending": make(map[string]map[string][]*RPCTransaction), 331 "queued": make(map[string]map[string][]*RPCTransaction), 332 } 333 pending, queue := s.e.TxPool().Content() 334 335 // Flatten the pending transactions 336 for account, batches := range pending { 337 dump := make(map[string][]*RPCTransaction) 338 for nonce, txs := range batches { 339 nonce := fmt.Sprintf("%d", nonce) 340 for _, tx := range txs { 341 dump[nonce] = append(dump[nonce], newRPCPendingTransaction(tx)) 342 } 343 } 344 content["pending"][account.Hex()] = dump 345 } 346 // Flatten the queued transactions 347 for account, batches := range queue { 348 dump := make(map[string][]*RPCTransaction) 349 for nonce, txs := range batches { 350 nonce := fmt.Sprintf("%d", nonce) 351 for _, tx := range txs { 352 dump[nonce] = append(dump[nonce], newRPCPendingTransaction(tx)) 353 } 354 } 355 content["queued"][account.Hex()] = dump 356 } 357 return content 358 } 359 360 // Status returns the number of pending and queued transaction in the pool. 361 func (s *PublicTxPoolAPI) Status() map[string]*rpc.HexNumber { 362 pending, queue := s.e.TxPool().Stats() 363 return map[string]*rpc.HexNumber{ 364 "pending": rpc.NewHexNumber(pending), 365 "queued": rpc.NewHexNumber(queue), 366 } 367 } 368 369 // Inspect retrieves the content of the transaction pool and flattens it into an 370 // easily inspectable list. 371 func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string][]string { 372 content := map[string]map[string]map[string][]string{ 373 "pending": make(map[string]map[string][]string), 374 "queued": make(map[string]map[string][]string), 375 } 376 pending, queue := s.e.TxPool().Content() 377 378 // Define a formatter to flatten a transaction into a string 379 var format = func(tx *types.Transaction) string { 380 if to := tx.To(); to != nil { 381 return fmt.Sprintf("%s: %v wei + %v × %v gas", tx.To().Hex(), tx.Value(), tx.Gas(), tx.GasPrice()) 382 } 383 return fmt.Sprintf("contract creation: %v wei + %v × %v gas", tx.Value(), tx.Gas(), tx.GasPrice()) 384 } 385 // Flatten the pending transactions 386 for account, batches := range pending { 387 dump := make(map[string][]string) 388 for nonce, txs := range batches { 389 nonce := fmt.Sprintf("%d", nonce) 390 for _, tx := range txs { 391 dump[nonce] = append(dump[nonce], format(tx)) 392 } 393 } 394 content["pending"][account.Hex()] = dump 395 } 396 // Flatten the queued transactions 397 for account, batches := range queue { 398 dump := make(map[string][]string) 399 for nonce, txs := range batches { 400 nonce := fmt.Sprintf("%d", nonce) 401 for _, tx := range txs { 402 dump[nonce] = append(dump[nonce], format(tx)) 403 } 404 } 405 content["queued"][account.Hex()] = dump 406 } 407 return content 408 } 409 410 // PublicAccountAPI provides an API to access accounts managed by this node. 411 // It offers only methods that can retrieve accounts. 412 type PublicAccountAPI struct { 413 am *accounts.Manager 414 } 415 416 // NewPublicAccountAPI creates a new PublicAccountAPI. 417 func NewPublicAccountAPI(am *accounts.Manager) *PublicAccountAPI { 418 return &PublicAccountAPI{am: am} 419 } 420 421 // Accounts returns the collection of accounts this node manages 422 func (s *PublicAccountAPI) Accounts() []accounts.Account { 423 return s.am.Accounts() 424 } 425 426 // PrivateAccountAPI provides an API to access accounts managed by this node. 427 // It offers methods to create, (un)lock en list accounts. Some methods accept 428 // passwords and are therefore considered private by default. 429 type PrivateAccountAPI struct { 430 bc *core.BlockChain 431 am *accounts.Manager 432 txPool *core.TxPool 433 txMu *sync.Mutex 434 gpo *GasPriceOracle 435 } 436 437 // NewPrivateAccountAPI create a new PrivateAccountAPI. 438 func NewPrivateAccountAPI(e *Ethereum) *PrivateAccountAPI { 439 return &PrivateAccountAPI{ 440 bc: e.blockchain, 441 am: e.accountManager, 442 txPool: e.txPool, 443 txMu: &e.txMu, 444 gpo: e.gpo, 445 } 446 } 447 448 // ListAccounts will return a list of addresses for accounts this node manages. 449 func (s *PrivateAccountAPI) ListAccounts() []common.Address { 450 accounts := s.am.Accounts() 451 addresses := make([]common.Address, len(accounts)) 452 for i, acc := range accounts { 453 addresses[i] = acc.Address 454 } 455 return addresses 456 } 457 458 // NewAccount will create a new account and returns the address for the new account. 459 func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) { 460 acc, err := s.am.NewAccount(password) 461 if err == nil { 462 return acc.Address, nil 463 } 464 return common.Address{}, err 465 } 466 467 // ImportRawKey stores the given hex encoded ECDSA key into the key directory, 468 // encrypting it with the passphrase. 469 func (s *PrivateAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) { 470 hexkey, err := hex.DecodeString(privkey) 471 if err != nil { 472 return common.Address{}, err 473 } 474 475 acc, err := s.am.ImportECDSA(crypto.ToECDSA(hexkey), password) 476 return acc.Address, err 477 } 478 479 // UnlockAccount will unlock the account associated with the given address with 480 // the given password for duration seconds. If duration is nil it will use a 481 // default of 300 seconds. It returns an indication if the account was unlocked. 482 func (s *PrivateAccountAPI) UnlockAccount(addr common.Address, password string, duration *rpc.HexNumber) (bool, error) { 483 if duration == nil { 484 duration = rpc.NewHexNumber(300) 485 } 486 a := accounts.Account{Address: addr} 487 d := time.Duration(duration.Int64()) * time.Second 488 if err := s.am.TimedUnlock(a, password, d); err != nil { 489 return false, err 490 } 491 return true, nil 492 } 493 494 // LockAccount will lock the account associated with the given address when it's unlocked. 495 func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool { 496 return s.am.Lock(addr) == nil 497 } 498 499 // Sign calculates an Ethereum ECDSA signature for: 500 // keccack256("\x19Ethereum Signed Message:\n" + len(message) + message)) 501 // 502 // Note, the produced signature conforms to the secp256k1 curve R, S and V values, 503 // where the V value will be 27 or 28 for legacy reasons. 504 // 505 // The key used to calculate the signature is decrypted with the given password. 506 // 507 // https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign 508 func (s *PrivateAccountAPI) Sign(data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) { 509 signature, err := s.am.SignWithPassphrase(addr, passwd, signHash(data)) 510 if err != nil { 511 return nil, err 512 } 513 signature[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper 514 return signature, nil 515 } 516 517 // SendTransaction will create a transaction from the given arguments and 518 // tries to sign it with the key associated with args.To. If the given passwd isn't 519 // able to decrypt the key it fails. 520 func (s *PrivateAccountAPI) SendTransaction(args SendTxArgs, passwd string) (common.Hash, error) { 521 args = prepareSendTxArgs(args, s.gpo) 522 523 s.txMu.Lock() 524 defer s.txMu.Unlock() 525 526 if args.Nonce == nil { 527 args.Nonce = rpc.NewHexNumber(s.txPool.State().GetNonce(args.From)) 528 } 529 530 var tx *types.Transaction 531 if args.To == nil { 532 tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) 533 } else { 534 tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) 535 } 536 537 tx.SetSigner(s.bc.Config().GetSigner(s.bc.CurrentBlock().Number())) 538 539 signature, err := s.am.SignWithPassphrase(args.From, passwd, tx.SigHash().Bytes()) 540 if err != nil { 541 return common.Hash{}, err 542 } 543 544 return submitTransaction(s.bc, s.txPool, tx, signature) 545 } 546 547 // SignAndSendTransaction was renamed to SendTransaction. This method is deprecated 548 // and will be removed in the future. It primary goal is to give clients time to update. 549 func (s *PrivateAccountAPI) SignAndSendTransaction(args SendTxArgs, passwd string) (common.Hash, error) { 550 return s.SendTransaction(args, passwd) 551 } 552 553 // PublicBlockChainAPI provides an API to access the Ethereum blockchain. 554 // It offers only methods that operate on public data that is freely available to anyone. 555 type PublicBlockChainAPI struct { 556 config *core.ChainConfig 557 bc *core.BlockChain 558 chainDb ethdb.Database 559 indexesDb ethdb.Database 560 eventMux *event.TypeMux 561 muNewBlockSubscriptions sync.Mutex // protects newBlocksSubscriptions 562 newBlockSubscriptions map[string]func(core.ChainEvent) error // callbacks for new block subscriptions 563 am *accounts.Manager 564 miner *miner.Miner 565 gpo *GasPriceOracle 566 } 567 568 // NewPublicBlockChainAPI creates a new Etheruem blockchain API. 569 func NewPublicBlockChainAPI(config *core.ChainConfig, bc *core.BlockChain, m *miner.Miner, chainDb ethdb.Database, gpo *GasPriceOracle, eventMux *event.TypeMux, am *accounts.Manager) *PublicBlockChainAPI { 570 api := &PublicBlockChainAPI{ 571 config: config, 572 bc: bc, 573 miner: m, 574 chainDb: chainDb, 575 eventMux: eventMux, 576 am: am, 577 newBlockSubscriptions: make(map[string]func(core.ChainEvent) error), 578 gpo: gpo, 579 } 580 581 go api.subscriptionLoop() 582 583 return api 584 } 585 586 // subscriptionLoop reads events from the global event mux and creates notifications for the matched subscriptions. 587 func (s *PublicBlockChainAPI) subscriptionLoop() { 588 sub := s.eventMux.Subscribe(core.ChainEvent{}) 589 for event := range sub.Chan() { 590 if chainEvent, ok := event.Data.(core.ChainEvent); ok { 591 s.muNewBlockSubscriptions.Lock() 592 for id, notifyOf := range s.newBlockSubscriptions { 593 if notifyOf(chainEvent) == rpc.ErrNotificationNotFound { 594 delete(s.newBlockSubscriptions, id) 595 } 596 } 597 s.muNewBlockSubscriptions.Unlock() 598 } 599 } 600 } 601 602 // BlockNumber returns the block number of the chain head. 603 func (s *PublicBlockChainAPI) BlockNumber() *big.Int { 604 return s.bc.CurrentHeader().Number 605 } 606 607 // GetBalance returns the amount of wei for the given address in the state of the 608 // given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta 609 // block numbers are also allowed. 610 func (s *PublicBlockChainAPI) GetBalance(address common.Address, blockNr rpc.BlockNumber) (*big.Int, error) { 611 state, _, err := stateAndBlockByNumber(s.miner, s.bc, blockNr, s.chainDb) 612 if state == nil || err != nil { 613 return nil, err 614 } 615 return state.GetBalance(address), nil 616 } 617 618 // GetBlockByNumber returns the requested block. When blockNr is -1 the chain head is returned. When fullTx is true all 619 // transactions in the block are returned in full detail, otherwise only the transaction hash is returned. 620 func (s *PublicBlockChainAPI) GetBlockByNumber(blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { 621 if block := blockByNumber(s.miner, s.bc, blockNr); block != nil { 622 response, err := s.rpcOutputBlock(block, true, fullTx) 623 if err == nil && blockNr == rpc.PendingBlockNumber { 624 // Pending blocks need to nil out a few fields 625 for _, field := range []string{"hash", "nonce", "miner"} { 626 response[field] = nil 627 } 628 } 629 return response, err 630 } 631 return nil, nil 632 } 633 634 // GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full 635 // detail, otherwise only the transaction hash is returned. 636 func (s *PublicBlockChainAPI) GetBlockByHash(blockHash common.Hash, fullTx bool) (map[string]interface{}, error) { 637 if block := s.bc.GetBlock(blockHash); block != nil { 638 return s.rpcOutputBlock(block, true, fullTx) 639 } 640 return nil, nil 641 } 642 643 // GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. When fullTx is true 644 // all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. 645 func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(blockNr rpc.BlockNumber, index rpc.HexNumber) (map[string]interface{}, error) { 646 if block := blockByNumber(s.miner, s.bc, blockNr); block != nil { 647 uncles := block.Uncles() 648 if index.Int() < 0 || index.Int() >= len(uncles) { 649 glog.V(logger.Debug).Infof("uncle block on index %d not found for block #%d", index.Int(), blockNr) 650 return nil, nil 651 } 652 block = types.NewBlockWithHeader(uncles[index.Int()]) 653 return s.rpcOutputBlock(block, false, false) 654 } 655 return nil, nil 656 } 657 658 // GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. When fullTx is true 659 // all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. 660 func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(blockHash common.Hash, index rpc.HexNumber) (map[string]interface{}, error) { 661 if block := s.bc.GetBlock(blockHash); block != nil { 662 uncles := block.Uncles() 663 if index.Int() < 0 || index.Int() >= len(uncles) { 664 glog.V(logger.Debug).Infof("uncle block on index %d not found for block %s", index.Int(), blockHash.Hex()) 665 return nil, nil 666 } 667 block = types.NewBlockWithHeader(uncles[index.Int()]) 668 return s.rpcOutputBlock(block, false, false) 669 } 670 return nil, nil 671 } 672 673 // GetUncleCountByBlockNumber returns number of uncles in the block for the given block number 674 func (s *PublicBlockChainAPI) GetUncleCountByBlockNumber(blockNr rpc.BlockNumber) *rpc.HexNumber { 675 if block := blockByNumber(s.miner, s.bc, blockNr); block != nil { 676 return rpc.NewHexNumber(len(block.Uncles())) 677 } 678 return nil 679 } 680 681 // GetUncleCountByBlockHash returns number of uncles in the block for the given block hash 682 func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(blockHash common.Hash) *rpc.HexNumber { 683 if block := s.bc.GetBlock(blockHash); block != nil { 684 return rpc.NewHexNumber(len(block.Uncles())) 685 } 686 return nil 687 } 688 689 // NewBlocksArgs allows the user to specify if the returned block should include transactions and in which format. 690 type NewBlocksArgs struct { 691 IncludeTransactions bool `json:"includeTransactions"` 692 TransactionDetails bool `json:"transactionDetails"` 693 } 694 695 // NewBlocks triggers a new block event each time a block is appended to the chain. It accepts an argument which allows 696 // the caller to specify whether the output should contain transactions and in what format. 697 func (s *PublicBlockChainAPI) NewBlocks(ctx context.Context, args NewBlocksArgs) (rpc.Subscription, error) { 698 notifier, supported := rpc.NotifierFromContext(ctx) 699 if !supported { 700 return nil, rpc.ErrNotificationsUnsupported 701 } 702 703 // create a subscription that will remove itself when unsubscribed/cancelled 704 subscription, err := notifier.NewSubscription(func(subId string) { 705 s.muNewBlockSubscriptions.Lock() 706 delete(s.newBlockSubscriptions, subId) 707 s.muNewBlockSubscriptions.Unlock() 708 }) 709 710 if err != nil { 711 return nil, err 712 } 713 714 // add a callback that is called on chain events which will format the block and notify the client 715 s.muNewBlockSubscriptions.Lock() 716 s.newBlockSubscriptions[subscription.ID()] = func(e core.ChainEvent) error { 717 notification, err := s.rpcOutputBlock(e.Block, args.IncludeTransactions, args.TransactionDetails) 718 if err == nil { 719 return subscription.Notify(notification) 720 } 721 glog.V(logger.Warn).Infof("unable to format block %v\n", err) 722 return nil 723 } 724 s.muNewBlockSubscriptions.Unlock() 725 return subscription, nil 726 } 727 728 // GetCode returns the code stored at the given address in the state for the given block number. 729 func (s *PublicBlockChainAPI) GetCode(address common.Address, blockNr rpc.BlockNumber) (string, error) { 730 state, _, err := stateAndBlockByNumber(s.miner, s.bc, blockNr, s.chainDb) 731 if state == nil || err != nil { 732 return "", err 733 } 734 res := state.GetCode(address) 735 if len(res) == 0 { // backwards compatibility 736 return "0x", nil 737 } 738 return common.ToHex(res), nil 739 } 740 741 // GetStorageAt returns the storage from the state at the given address, key and 742 // block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block 743 // numbers are also allowed. 744 func (s *PublicBlockChainAPI) GetStorageAt(address common.Address, key string, blockNr rpc.BlockNumber) (string, error) { 745 state, _, err := stateAndBlockByNumber(s.miner, s.bc, blockNr, s.chainDb) 746 if state == nil || err != nil { 747 return "0x", err 748 } 749 return state.GetState(address, common.HexToHash(key)).Hex(), nil 750 } 751 752 // callmsg is the message type used for call transactions. 753 type callmsg struct { 754 from *state.StateObject 755 to *common.Address 756 gas, gasPrice *big.Int 757 value *big.Int 758 data []byte 759 } 760 761 // accessor boilerplate to implement core.Message 762 func (m callmsg) From() (common.Address, error) { return m.from.Address(), nil } 763 func (m callmsg) FromFrontier() (common.Address, error) { return m.from.Address(), nil } 764 func (m callmsg) Nonce() uint64 { return m.from.Nonce() } 765 func (m callmsg) To() *common.Address { return m.to } 766 func (m callmsg) GasPrice() *big.Int { return m.gasPrice } 767 func (m callmsg) Gas() *big.Int { return m.gas } 768 func (m callmsg) Value() *big.Int { return m.value } 769 func (m callmsg) Data() []byte { return m.data } 770 771 // CallArgs represents the arguments for a call. 772 type CallArgs struct { 773 From common.Address `json:"from"` 774 To *common.Address `json:"to"` 775 Gas *rpc.HexNumber `json:"gas"` 776 GasPrice *rpc.HexNumber `json:"gasPrice"` 777 Value rpc.HexNumber `json:"value"` 778 Data string `json:"data"` 779 } 780 781 func (s *PublicBlockChainAPI) doCall(args CallArgs, blockNr rpc.BlockNumber) (string, *big.Int, error) { 782 // Fetch the state associated with the block number 783 stateDb, block, err := stateAndBlockByNumber(s.miner, s.bc, blockNr, s.chainDb) 784 if stateDb == nil || err != nil { 785 return "0x", nil, err 786 } 787 stateDb = stateDb.Copy() 788 789 // Retrieve the account state object to interact with 790 var from *state.StateObject 791 if args.From == (common.Address{}) { 792 accounts := s.am.Accounts() 793 if len(accounts) == 0 { 794 from = stateDb.GetOrNewStateObject(common.Address{}) 795 } else { 796 from = stateDb.GetOrNewStateObject(accounts[0].Address) 797 } 798 } else { 799 from = stateDb.GetOrNewStateObject(args.From) 800 } 801 from.SetBalance(common.MaxBig) 802 803 // Assemble the CALL invocation 804 msg := callmsg{ 805 from: from, 806 to: args.To, 807 gas: args.Gas.BigInt(), 808 gasPrice: args.GasPrice.BigInt(), 809 value: args.Value.BigInt(), 810 data: common.FromHex(args.Data), 811 } 812 if msg.gas == nil { 813 msg.gas = big.NewInt(50000000) 814 } 815 if msg.gasPrice == nil { 816 msg.gasPrice = s.gpo.SuggestPrice() 817 } 818 819 // Execute the call and return 820 vmenv := core.NewEnv(stateDb, s.config, s.bc, msg, block.Header()) 821 gp := new(core.GasPool).AddGas(common.MaxBig) 822 823 res, requiredGas, _, err := core.NewStateTransition(vmenv, msg, gp).TransitionDb() 824 if len(res) == 0 { // backwards compatibility 825 return "0x", requiredGas, err 826 } 827 return common.ToHex(res), requiredGas, err 828 } 829 830 // Call executes the given transaction on the state for the given block number. 831 // It doesn't make and changes in the state/blockchain and is useful to execute and retrieve values. 832 func (s *PublicBlockChainAPI) Call(args CallArgs, blockNr rpc.BlockNumber) (string, error) { 833 result, _, err := s.doCall(args, blockNr) 834 return result, err 835 } 836 837 // EstimateGas returns an estimate of the amount of gas needed to execute the given transaction. 838 func (s *PublicBlockChainAPI) EstimateGas(args CallArgs) (*rpc.HexNumber, error) { 839 _, gas, err := s.doCall(args, rpc.PendingBlockNumber) 840 return rpc.NewHexNumber(gas), err 841 } 842 843 // rpcOutputBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are 844 // returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain 845 // transaction hashes. 846 func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { 847 fields := map[string]interface{}{ 848 "number": rpc.NewHexNumber(b.Number()), 849 "hash": b.Hash(), 850 "parentHash": b.ParentHash(), 851 "nonce": b.Header().Nonce, 852 "mixHash": b.Header().MixDigest, 853 "sha3Uncles": b.UncleHash(), 854 "logsBloom": b.Bloom(), 855 "stateRoot": b.Root(), 856 "miner": b.Coinbase(), 857 "difficulty": rpc.NewHexNumber(b.Difficulty()), 858 "totalDifficulty": rpc.NewHexNumber(s.bc.GetTd(b.Hash())), 859 "extraData": fmt.Sprintf("0x%x", b.Extra()), 860 "size": rpc.NewHexNumber(b.Size().Int64()), 861 "gasLimit": rpc.NewHexNumber(b.GasLimit()), 862 "gasUsed": rpc.NewHexNumber(b.GasUsed()), 863 "timestamp": rpc.NewHexNumber(b.Time()), 864 "transactionsRoot": b.TxHash(), 865 "receiptsRoot": b.ReceiptHash(), 866 } 867 868 if inclTx { 869 formatTx := func(tx *types.Transaction) (interface{}, error) { 870 return tx.Hash(), nil 871 } 872 873 if fullTx { 874 formatTx = func(tx *types.Transaction) (interface{}, error) { 875 if tx.Protected() { 876 tx.SetSigner(types.NewChainIdSigner(s.bc.Config().GetChainID())) 877 } 878 return newRPCTransaction(b, tx.Hash()) 879 } 880 } 881 882 txs := b.Transactions() 883 transactions := make([]interface{}, len(txs)) 884 var err error 885 for i, tx := range b.Transactions() { 886 if transactions[i], err = formatTx(tx); err != nil { 887 return nil, err 888 } 889 } 890 fields["transactions"] = transactions 891 } 892 893 uncles := b.Uncles() 894 uncleHashes := make([]common.Hash, len(uncles)) 895 for i, uncle := range uncles { 896 uncleHashes[i] = uncle.Hash() 897 } 898 fields["uncles"] = uncleHashes 899 900 return fields, nil 901 } 902 903 // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction 904 type RPCTransaction struct { 905 BlockHash common.Hash `json:"blockHash"` 906 BlockNumber *rpc.HexNumber `json:"blockNumber"` 907 From common.Address `json:"from"` 908 Gas *rpc.HexNumber `json:"gas"` 909 GasPrice *rpc.HexNumber `json:"gasPrice"` 910 Hash common.Hash `json:"hash"` 911 Input string `json:"input"` 912 Nonce *rpc.HexNumber `json:"nonce"` 913 To *common.Address `json:"to"` 914 TransactionIndex *rpc.HexNumber `json:"transactionIndex"` 915 Value *rpc.HexNumber `json:"value"` 916 ReplayProtected bool `json:"replayProtected"` 917 ChainId *big.Int `json:"chainId,omitempty"` 918 V *rpc.HexNumber `json:"v"` 919 R *rpc.HexNumber `json:"r"` 920 S *rpc.HexNumber `json:"s"` 921 } 922 923 // newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation 924 func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction { 925 from, _ := tx.From() 926 927 var protected bool 928 var chainId *big.Int 929 if tx.Protected() { 930 protected = true 931 chainId = tx.ChainId() 932 } 933 934 return &RPCTransaction{ 935 From: from, 936 Gas: rpc.NewHexNumber(tx.Gas()), 937 GasPrice: rpc.NewHexNumber(tx.GasPrice()), 938 Hash: tx.Hash(), 939 Input: fmt.Sprintf("0x%x", tx.Data()), 940 Nonce: rpc.NewHexNumber(tx.Nonce()), 941 To: tx.To(), 942 Value: rpc.NewHexNumber(tx.Value()), 943 ReplayProtected: protected, 944 ChainId: chainId, 945 } 946 } 947 948 // newRPCTransaction returns a transaction that will serialize to the RPC representation. 949 func newRPCTransactionFromBlockIndex(b *types.Block, txIndex int) (*RPCTransaction, error) { 950 if txIndex >= 0 && txIndex < len(b.Transactions()) { 951 tx := b.Transactions()[txIndex] 952 var signer types.Signer = types.BasicSigner{} 953 var protected bool 954 var chainId *big.Int 955 if tx.Protected() { 956 signer = types.NewChainIdSigner(tx.ChainId()) 957 protected = true 958 chainId = tx.ChainId() 959 } 960 from, _ := types.Sender(signer, tx) 961 962 v, r, s := tx.RawSignatureValues() 963 964 return &RPCTransaction{ 965 BlockHash: b.Hash(), 966 BlockNumber: rpc.NewHexNumber(b.Number()), 967 From: from, 968 Gas: rpc.NewHexNumber(tx.Gas()), 969 GasPrice: rpc.NewHexNumber(tx.GasPrice()), 970 Hash: tx.Hash(), 971 Input: fmt.Sprintf("0x%x", tx.Data()), 972 Nonce: rpc.NewHexNumber(tx.Nonce()), 973 To: tx.To(), 974 TransactionIndex: rpc.NewHexNumber(txIndex), 975 Value: rpc.NewHexNumber(tx.Value()), 976 ReplayProtected: protected, 977 ChainId: chainId, 978 V: rpc.NewHexNumber(v), 979 R: rpc.NewHexNumber(r), 980 S: rpc.NewHexNumber(s), 981 }, nil 982 } 983 984 return nil, nil 985 } 986 987 // newRPCTransaction returns a transaction that will serialize to the RPC representation. 988 func newRPCTransaction(b *types.Block, txHash common.Hash) (*RPCTransaction, error) { 989 for idx, tx := range b.Transactions() { 990 if tx.Hash() == txHash { 991 return newRPCTransactionFromBlockIndex(b, idx) 992 } 993 } 994 995 return nil, nil 996 } 997 998 // PublicTransactionPoolAPI exposes methods for the RPC interface 999 type PublicTransactionPoolAPI struct { 1000 eventMux *event.TypeMux 1001 chainDb ethdb.Database 1002 gpo *GasPriceOracle 1003 bc *core.BlockChain 1004 miner *miner.Miner 1005 am *accounts.Manager 1006 txPool *core.TxPool 1007 txMu *sync.Mutex 1008 muPendingTxSubs sync.Mutex 1009 pendingTxSubs map[string]rpc.Subscription 1010 } 1011 1012 // NewPublicTransactionPoolAPI creates a new RPC service with methods specific for the transaction pool. 1013 func NewPublicTransactionPoolAPI(e *Ethereum) *PublicTransactionPoolAPI { 1014 api := &PublicTransactionPoolAPI{ 1015 eventMux: e.eventMux, 1016 gpo: e.gpo, 1017 chainDb: e.chainDb, 1018 bc: e.blockchain, 1019 am: e.accountManager, 1020 txPool: e.txPool, 1021 txMu: &e.txMu, 1022 miner: e.miner, 1023 pendingTxSubs: make(map[string]rpc.Subscription), 1024 } 1025 go api.subscriptionLoop() 1026 1027 return api 1028 } 1029 1030 // subscriptionLoop listens for events on the global event mux and creates notifications for subscriptions. 1031 func (s *PublicTransactionPoolAPI) subscriptionLoop() { 1032 sub := s.eventMux.Subscribe(core.TxPreEvent{}) 1033 for event := range sub.Chan() { 1034 tx := event.Data.(core.TxPreEvent) 1035 if from, err := tx.Tx.From(); err == nil { 1036 if s.am.HasAddress(from) { 1037 s.muPendingTxSubs.Lock() 1038 for id, sub := range s.pendingTxSubs { 1039 if sub.Notify(tx.Tx.Hash()) == rpc.ErrNotificationNotFound { 1040 delete(s.pendingTxSubs, id) 1041 } 1042 } 1043 s.muPendingTxSubs.Unlock() 1044 } 1045 } 1046 } 1047 } 1048 1049 func getTransaction(chainDb ethdb.Database, txPool *core.TxPool, txHash common.Hash) (*types.Transaction, bool, error) { 1050 txData, err := chainDb.Get(txHash.Bytes()) 1051 isPending := false 1052 tx := new(types.Transaction) 1053 1054 if err == nil && len(txData) > 0 { 1055 if err := rlp.DecodeBytes(txData, tx); err != nil { 1056 return nil, isPending, err 1057 } 1058 } else { 1059 // pending transaction? 1060 tx = txPool.GetTransaction(txHash) 1061 isPending = true 1062 } 1063 1064 return tx, isPending, nil 1065 } 1066 1067 // GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number. 1068 func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(blockNr rpc.BlockNumber) *rpc.HexNumber { 1069 if block := blockByNumber(s.miner, s.bc, blockNr); block != nil { 1070 return rpc.NewHexNumber(len(block.Transactions())) 1071 } 1072 return nil 1073 } 1074 1075 // GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash. 1076 func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(blockHash common.Hash) *rpc.HexNumber { 1077 if block := s.bc.GetBlock(blockHash); block != nil { 1078 return rpc.NewHexNumber(len(block.Transactions())) 1079 } 1080 return nil 1081 } 1082 1083 // GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index. 1084 func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(blockNr rpc.BlockNumber, index rpc.HexNumber) (*RPCTransaction, error) { 1085 if block := blockByNumber(s.miner, s.bc, blockNr); block != nil { 1086 return newRPCTransactionFromBlockIndex(block, index.Int()) 1087 } 1088 return nil, nil 1089 } 1090 1091 // GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index. 1092 func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(blockHash common.Hash, index rpc.HexNumber) (*RPCTransaction, error) { 1093 if block := s.bc.GetBlock(blockHash); block != nil { 1094 return newRPCTransactionFromBlockIndex(block, index.Int()) 1095 } 1096 return nil, nil 1097 } 1098 1099 // GetTransactionCount returns the number of transactions the given address has sent for the given block number 1100 func (s *PublicTransactionPoolAPI) GetTransactionCount(address common.Address, blockNr rpc.BlockNumber) (*rpc.HexNumber, error) { 1101 state, _, err := stateAndBlockByNumber(s.miner, s.bc, blockNr, s.chainDb) 1102 if state == nil || err != nil { 1103 return nil, err 1104 } 1105 return rpc.NewHexNumber(state.GetNonce(address)), nil 1106 } 1107 1108 // getTransactionBlockData fetches the meta data for the given transaction from the chain database. This is useful to 1109 // retrieve block information for a hash. It returns the block hash, block index and transaction index. 1110 func getTransactionBlockData(chainDb ethdb.Database, txHash common.Hash) (common.Hash, uint64, uint64, error) { 1111 var txBlock struct { 1112 BlockHash common.Hash 1113 BlockIndex uint64 1114 Index uint64 1115 } 1116 1117 blockData, err := chainDb.Get(append(txHash.Bytes(), 0x0001)) 1118 if err != nil { 1119 return common.Hash{}, uint64(0), uint64(0), err 1120 } 1121 1122 reader := bytes.NewReader(blockData) 1123 if err = rlp.Decode(reader, &txBlock); err != nil { 1124 return common.Hash{}, uint64(0), uint64(0), err 1125 } 1126 1127 return txBlock.BlockHash, txBlock.BlockIndex, txBlock.Index, nil 1128 } 1129 1130 // GetTransactionByHash returns the transaction for the given hash 1131 func (s *PublicTransactionPoolAPI) GetTransactionByHash(txHash common.Hash) (*RPCTransaction, error) { 1132 var tx *types.Transaction 1133 var isPending bool 1134 var err error 1135 1136 if tx, isPending, err = getTransaction(s.chainDb, s.txPool, txHash); err != nil { 1137 glog.V(logger.Debug).Infof("%v\n", err) 1138 return nil, nil 1139 } else if tx == nil { 1140 return nil, nil 1141 } 1142 1143 if isPending { 1144 return newRPCPendingTransaction(tx), nil 1145 } 1146 1147 blockHash, _, _, err := getTransactionBlockData(s.chainDb, txHash) 1148 if err != nil { 1149 glog.V(logger.Debug).Infof("%v\n", err) 1150 return nil, nil 1151 } 1152 1153 if block := s.bc.GetBlock(blockHash); block != nil { 1154 return newRPCTransaction(block, txHash) 1155 } 1156 1157 return nil, nil 1158 } 1159 1160 // GetTransactionReceipt returns the transaction receipt for the given transaction hash. 1161 func (s *PublicTransactionPoolAPI) GetTransactionReceipt(txHash common.Hash) (map[string]interface{}, error) { 1162 receipt := core.GetReceipt(s.chainDb, txHash) 1163 if receipt == nil { 1164 glog.V(logger.Debug).Infof("receipt not found for transaction %s", txHash.Hex()) 1165 return nil, nil 1166 } 1167 1168 tx, _, err := getTransaction(s.chainDb, s.txPool, txHash) 1169 if err != nil { 1170 return nil, err 1171 } 1172 1173 txBlock, blockIndex, index, err := getTransactionBlockData(s.chainDb, txHash) 1174 if err != nil { 1175 return nil, err 1176 } 1177 1178 if receipt.Status == types.TxStatusUnknown { 1179 // To be able to get the proper state for n-th transaction in a block, 1180 // all previous transactions has to be executed. Because of that, it is 1181 // reasonable to reprocess entire block and update all receipts from 1182 // given block. 1183 proc := s.bc.Processor() 1184 block := s.bc.GetBlock(txBlock) 1185 parent := s.bc.GetBlock(block.ParentHash()) 1186 statedb, err := s.bc.StateAt(parent.Root()) 1187 if err != nil { 1188 return nil, fmt.Errorf("state not found - transaction status is not available for fast synced block: %v", err) 1189 } 1190 1191 receipts, _, _, err := proc.Process(block, statedb) 1192 if err != nil { 1193 return nil, err 1194 } 1195 1196 if err := core.WriteReceipts(s.chainDb, receipts); err != nil { 1197 glog.V(logger.Warn).Infof("cannot save updated receipts: %v", err) 1198 } 1199 if err := core.WriteBlockReceipts(s.chainDb, block.Hash(), receipts); err != nil { 1200 glog.V(logger.Warn).Infof("cannot save updated block receipts: %v", err) 1201 } 1202 receipt = receipts[index] 1203 } 1204 1205 var signer types.Signer = types.BasicSigner{} 1206 if tx.Protected() { 1207 signer = types.NewChainIdSigner(tx.ChainId()) 1208 } 1209 from, _ := types.Sender(signer, tx) 1210 1211 fields := map[string]interface{}{ 1212 "root": common.Bytes2Hex(receipt.PostState), 1213 "blockHash": txBlock, 1214 "blockNumber": rpc.NewHexNumber(blockIndex), 1215 "transactionHash": txHash, 1216 "transactionIndex": rpc.NewHexNumber(index), 1217 "from": from, 1218 "to": tx.To(), 1219 "gasUsed": rpc.NewHexNumber(receipt.GasUsed), 1220 "cumulativeGasUsed": rpc.NewHexNumber(receipt.CumulativeGasUsed), 1221 "contractAddress": nil, 1222 "logs": receipt.Logs, 1223 } 1224 1225 if receipt.Logs == nil { 1226 fields["logs"] = []vm.Logs{} 1227 } 1228 1229 // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation 1230 if bytes.Compare(receipt.ContractAddress.Bytes(), bytes.Repeat([]byte{0}, 20)) != 0 { 1231 fields["contractAddress"] = receipt.ContractAddress 1232 } 1233 1234 // We're not fully compatible with EIP-609 - just return status for all blocks. 1235 fields["status"] = nil 1236 if receipt.Status != types.TxStatusUnknown { 1237 fields["status"] = rpc.NewHexNumber(receipt.Status) 1238 } 1239 1240 return fields, nil 1241 } 1242 1243 // sign is a helper function that signs a transaction with the private key of the given address. 1244 func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { 1245 signer := s.bc.Config().GetSigner(s.bc.CurrentBlock().Number()) 1246 1247 signature, err := s.am.Sign(addr, signer.Hash(tx).Bytes()) 1248 if err != nil { 1249 return nil, err 1250 } 1251 return tx.WithSigner(signer).WithSignature(signature) 1252 } 1253 1254 // SendTxArgs represents the arguments to sumbit a new transaction into the transaction pool. 1255 type SendTxArgs struct { 1256 From common.Address `json:"from"` 1257 To *common.Address `json:"to"` 1258 Gas *rpc.HexNumber `json:"gas"` 1259 GasPrice *rpc.HexNumber `json:"gasPrice"` 1260 Value *rpc.HexNumber `json:"value"` 1261 Data string `json:"data"` 1262 Nonce *rpc.HexNumber `json:"nonce"` 1263 } 1264 1265 // prepareSendTxArgs is a helper function that fills in default values for unspecified tx fields. 1266 func prepareSendTxArgs(args SendTxArgs, gpo *GasPriceOracle) SendTxArgs { 1267 if args.Gas == nil { 1268 args.Gas = rpc.NewHexNumber(defaultGas) 1269 } 1270 if args.GasPrice == nil { 1271 args.GasPrice = rpc.NewHexNumber(gpo.SuggestPrice()) 1272 } 1273 if args.Value == nil { 1274 args.Value = rpc.NewHexNumber(0) 1275 } 1276 return args 1277 } 1278 1279 // submitTransaction is a helper function that submits tx to txPool and creates a log entry. 1280 func submitTransaction(bc *core.BlockChain, txPool *core.TxPool, tx *types.Transaction, signature []byte) (common.Hash, error) { 1281 signer := bc.Config().GetSigner(bc.CurrentBlock().Number()) 1282 1283 signedTx, err := tx.WithSigner(signer).WithSignature(signature) 1284 if err != nil { 1285 return common.Hash{}, err 1286 } 1287 1288 txPool.SetLocal(signedTx) 1289 if err := txPool.Add(signedTx); err != nil { 1290 return common.Hash{}, err 1291 } 1292 1293 if signedTx.To() == nil { 1294 from, _ := signedTx.From() 1295 addr := crypto.CreateAddress(from, signedTx.Nonce()) 1296 glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signedTx.Hash().Hex(), addr.Hex()) 1297 } else { 1298 glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signedTx.Hash().Hex(), tx.To().Hex()) 1299 } 1300 1301 return signedTx.Hash(), nil 1302 } 1303 1304 // SendTransaction creates a transaction for the given argument, sign it and submit it to the 1305 // transaction pool. 1306 func (s *PublicTransactionPoolAPI) SendTransaction(args SendTxArgs) (common.Hash, error) { 1307 args = prepareSendTxArgs(args, s.gpo) 1308 1309 s.txMu.Lock() 1310 defer s.txMu.Unlock() 1311 1312 if args.Nonce == nil { 1313 args.Nonce = rpc.NewHexNumber(s.txPool.State().GetNonce(args.From)) 1314 } 1315 1316 var tx *types.Transaction 1317 if args.To == nil { 1318 tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) 1319 } else { 1320 tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) 1321 } 1322 1323 signer := s.bc.Config().GetSigner(s.bc.CurrentBlock().Number()) 1324 tx.SetSigner(signer) 1325 1326 signature, err := s.am.Sign(args.From, signer.Hash(tx).Bytes()) 1327 if err != nil { 1328 return common.Hash{}, err 1329 } 1330 1331 return submitTransaction(s.bc, s.txPool, tx, signature) 1332 } 1333 1334 // SendRawTransaction will add the signed transaction to the transaction pool. 1335 // The sender is responsible for signing the transaction and using the correct nonce. 1336 func (s *PublicTransactionPoolAPI) SendRawTransaction(encodedTx string) (string, error) { 1337 tx := new(types.Transaction) 1338 if err := rlp.DecodeBytes(common.FromHex(encodedTx), tx); err != nil { 1339 return "", err 1340 } 1341 1342 s.txPool.SetLocal(tx) 1343 if err := s.txPool.Add(tx); err != nil { 1344 return "", err 1345 } 1346 1347 if tx.To() == nil { 1348 from, err := tx.From() 1349 if err != nil { 1350 return "", err 1351 } 1352 addr := crypto.CreateAddress(from, tx.Nonce()) 1353 glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr) 1354 } else { 1355 glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To()) 1356 } 1357 1358 return tx.Hash().Hex(), nil 1359 } 1360 1361 // signHash is a helper function that calculates a hash for the given message that can be 1362 // safely used to calculate a signature from. 1363 // 1364 // The hash is calculated as 1365 // keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). 1366 // 1367 // This gives context to the signed message and prevents signing of transactions. 1368 func signHash(data []byte) []byte { 1369 msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data) 1370 return crypto.Keccak256([]byte(msg)) 1371 } 1372 1373 // EcRecover returns the address for the account that was used to create the signature. 1374 // Note, this function is compatible with eth_sign and personal_sign. As such it recovers 1375 // the address of: 1376 // hash = keccak256("\x19Ethereum Signed Message:\n"${message length}${message}) 1377 // addr = ecrecover(hash, signature) 1378 // 1379 // Note, the signature must conform to the secp256k1 curve R, S and V values, where 1380 // the V value must be be 27 or 28 for legacy reasons. 1381 // 1382 // https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_ecRecover 1383 func (s *PrivateAccountAPI) EcRecover(data, sig hexutil.Bytes) (common.Address, error) { 1384 if len(sig) != 65 { 1385 return common.Address{}, fmt.Errorf("signature must be 65 bytes long") 1386 } 1387 if sig[64] != 27 && sig[64] != 28 { 1388 return common.Address{}, fmt.Errorf("invalid Ethereum signature (V is not 27 or 28)") 1389 } 1390 sig[64] -= 27 // Transform yellow paper V from 27/28 to 0/1 1391 1392 rpk, err := crypto.Ecrecover(signHash(data), sig) 1393 if err != nil { 1394 return common.Address{}, err 1395 } 1396 pubKey := crypto.ToECDSAPub(rpk) 1397 recoveredAddr := crypto.PubkeyToAddress(*pubKey) 1398 return recoveredAddr, nil 1399 } 1400 1401 // Sign signs the given hash using the key that matches the address. The key must be 1402 // unlocked in order to sign the hash. 1403 func (s *PublicBlockChainAPI) Sign(addr common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { 1404 signed := signHash(data) 1405 signature, err := s.am.Sign(addr, signed) 1406 if err != nil { 1407 return nil, err 1408 } 1409 signature[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper 1410 return signature, err 1411 } 1412 1413 // SignTransactionArgs represents the arguments to sign a transaction. 1414 type SignTransactionArgs struct { 1415 From common.Address 1416 To *common.Address 1417 Nonce *rpc.HexNumber 1418 Value *rpc.HexNumber 1419 Gas *rpc.HexNumber 1420 GasPrice *rpc.HexNumber 1421 Data string 1422 1423 BlockNumber int64 1424 } 1425 1426 // Tx is a helper object for argument and return values 1427 type Tx struct { 1428 tx *types.Transaction 1429 1430 To *common.Address `json:"to"` 1431 From common.Address `json:"from"` 1432 Nonce *rpc.HexNumber `json:"nonce"` 1433 Value *rpc.HexNumber `json:"value"` 1434 Data string `json:"data"` 1435 GasLimit *rpc.HexNumber `json:"gas"` 1436 GasPrice *rpc.HexNumber `json:"gasPrice"` 1437 Hash common.Hash `json:"hash"` 1438 } 1439 1440 // UnmarshalJSON parses JSON data into tx. 1441 func (tx *Tx) UnmarshalJSON(b []byte) (err error) { 1442 req := struct { 1443 To *common.Address `json:"to"` 1444 From common.Address `json:"from"` 1445 Nonce *rpc.HexNumber `json:"nonce"` 1446 Value *rpc.HexNumber `json:"value"` 1447 Data string `json:"data"` 1448 GasLimit *rpc.HexNumber `json:"gas"` 1449 GasPrice *rpc.HexNumber `json:"gasPrice"` 1450 Hash common.Hash `json:"hash"` 1451 }{} 1452 1453 if err := json.Unmarshal(b, &req); err != nil { 1454 return err 1455 } 1456 1457 tx.To = req.To 1458 tx.From = req.From 1459 tx.Nonce = req.Nonce 1460 tx.Value = req.Value 1461 tx.Data = req.Data 1462 tx.GasLimit = req.GasLimit 1463 tx.GasPrice = req.GasPrice 1464 tx.Hash = req.Hash 1465 1466 data := common.Hex2Bytes(tx.Data) 1467 1468 if tx.Nonce == nil { 1469 return fmt.Errorf("need nonce") 1470 } 1471 if tx.Value == nil { 1472 tx.Value = rpc.NewHexNumber(0) 1473 } 1474 if tx.GasLimit == nil { 1475 tx.GasLimit = rpc.NewHexNumber(0) 1476 } 1477 if tx.GasPrice == nil { 1478 tx.GasPrice = rpc.NewHexNumber(int64(50000000000)) 1479 } 1480 1481 if req.To == nil { 1482 tx.tx = types.NewContractCreation(tx.Nonce.Uint64(), tx.Value.BigInt(), tx.GasLimit.BigInt(), tx.GasPrice.BigInt(), data) 1483 } else { 1484 tx.tx = types.NewTransaction(tx.Nonce.Uint64(), *tx.To, tx.Value.BigInt(), tx.GasLimit.BigInt(), tx.GasPrice.BigInt(), data) 1485 } 1486 1487 return nil 1488 } 1489 1490 // SignTransactionResult represents a RLP encoded signed transaction. 1491 type SignTransactionResult struct { 1492 Raw string `json:"raw"` 1493 Tx *Tx `json:"tx"` 1494 } 1495 1496 func newTx(t *types.Transaction) *Tx { 1497 var signer types.Signer = types.BasicSigner{} 1498 if t.Protected() { 1499 signer = types.NewChainIdSigner(t.ChainId()) 1500 } 1501 from, _ := types.Sender(signer, t) 1502 return &Tx{ 1503 tx: t, 1504 To: t.To(), 1505 From: from, 1506 Value: rpc.NewHexNumber(t.Value()), 1507 Nonce: rpc.NewHexNumber(t.Nonce()), 1508 Data: "0x" + common.Bytes2Hex(t.Data()), 1509 GasLimit: rpc.NewHexNumber(t.Gas()), 1510 GasPrice: rpc.NewHexNumber(t.GasPrice()), 1511 Hash: t.Hash(), 1512 } 1513 } 1514 1515 // SignTransaction will sign the given transaction with the from account. 1516 // The node needs to have the private key of the account corresponding with 1517 // the given from address and it needs to be unlocked. 1518 func (s *PublicTransactionPoolAPI) SignTransaction(args SignTransactionArgs) (*SignTransactionResult, error) { 1519 if args.Gas == nil { 1520 args.Gas = rpc.NewHexNumber(defaultGas) 1521 } 1522 if args.GasPrice == nil { 1523 args.GasPrice = rpc.NewHexNumber(s.gpo.SuggestPrice()) 1524 } 1525 if args.Value == nil { 1526 args.Value = rpc.NewHexNumber(0) 1527 } 1528 1529 s.txMu.Lock() 1530 defer s.txMu.Unlock() 1531 1532 if args.Nonce == nil { 1533 args.Nonce = rpc.NewHexNumber(s.txPool.State().GetNonce(args.From)) 1534 } 1535 1536 var tx *types.Transaction 1537 if args.To == nil { 1538 tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) 1539 } else { 1540 tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) 1541 } 1542 1543 signedTx, err := s.sign(args.From, tx) 1544 if err != nil { 1545 return nil, err 1546 } 1547 1548 data, err := rlp.EncodeToBytes(signedTx) 1549 if err != nil { 1550 return nil, err 1551 } 1552 1553 return &SignTransactionResult{"0x" + common.Bytes2Hex(data), newTx(signedTx)}, nil 1554 } 1555 1556 // PendingTransactions returns the transactions that are in the transaction pool and have a from address that is one of 1557 // the accounts this node manages. 1558 func (s *PublicTransactionPoolAPI) PendingTransactions() []*RPCTransaction { 1559 pending := s.txPool.GetTransactions() 1560 transactions := make([]*RPCTransaction, 0, len(pending)) 1561 for _, tx := range pending { 1562 var signer types.Signer = types.BasicSigner{} 1563 if tx.Protected() { 1564 signer = types.NewChainIdSigner(tx.ChainId()) 1565 } 1566 from, _ := types.Sender(signer, tx) 1567 if s.am.HasAddress(from) { 1568 transactions = append(transactions, newRPCPendingTransaction(tx)) 1569 } 1570 } 1571 return transactions 1572 } 1573 1574 // NewPendingTransactions creates a subscription that is triggered each time a transaction enters the transaction pool 1575 // and is send from one of the transactions this nodes manages. 1576 func (s *PublicTransactionPoolAPI) NewPendingTransactions(ctx context.Context) (rpc.Subscription, error) { 1577 notifier, supported := rpc.NotifierFromContext(ctx) 1578 if !supported { 1579 return nil, rpc.ErrNotificationsUnsupported 1580 } 1581 1582 subscription, err := notifier.NewSubscription(func(id string) { 1583 s.muPendingTxSubs.Lock() 1584 delete(s.pendingTxSubs, id) 1585 s.muPendingTxSubs.Unlock() 1586 }) 1587 1588 if err != nil { 1589 return nil, err 1590 } 1591 1592 s.muPendingTxSubs.Lock() 1593 s.pendingTxSubs[subscription.ID()] = subscription 1594 s.muPendingTxSubs.Unlock() 1595 1596 return subscription, nil 1597 } 1598 1599 // Resend accepts an existing transaction and a new gas price and limit. It will remove the given transaction from the 1600 // pool and reinsert it with the new gas price and limit. 1601 func (s *PublicTransactionPoolAPI) Resend(tx Tx, gasPrice, gasLimit *rpc.HexNumber) (common.Hash, error) { 1602 1603 pending := s.txPool.GetTransactions() 1604 for _, p := range pending { 1605 var signer types.Signer = types.BasicSigner{} 1606 if p.Protected() { 1607 signer = types.NewChainIdSigner(p.ChainId()) 1608 } 1609 1610 if pFrom, err := types.Sender(signer, p); err == nil && pFrom == tx.From && signer.Hash(p) == signer.Hash(tx.tx) { 1611 if gasPrice == nil { 1612 gasPrice = rpc.NewHexNumber(tx.tx.GasPrice()) 1613 } 1614 if gasLimit == nil { 1615 gasLimit = rpc.NewHexNumber(tx.tx.Gas()) 1616 } 1617 1618 var newTx *types.Transaction 1619 if tx.tx.To() == nil { 1620 newTx = types.NewContractCreation(tx.tx.Nonce(), tx.tx.Value(), gasPrice.BigInt(), gasLimit.BigInt(), tx.tx.Data()) 1621 } else { 1622 newTx = types.NewTransaction(tx.tx.Nonce(), *tx.tx.To(), tx.tx.Value(), gasPrice.BigInt(), gasLimit.BigInt(), tx.tx.Data()) 1623 } 1624 1625 signedTx, err := s.sign(tx.From, newTx) 1626 if err != nil { 1627 return common.Hash{}, err 1628 } 1629 1630 s.txPool.RemoveTx(tx.Hash) 1631 if err = s.txPool.Add(signedTx); err != nil { 1632 return common.Hash{}, err 1633 } 1634 1635 return signedTx.Hash(), nil 1636 } 1637 } 1638 1639 return common.Hash{}, fmt.Errorf("Transaction %#x not found", tx.Hash) 1640 } 1641 1642 // PrivateAdminAPI is the collection of Etheruem APIs exposed over the private 1643 // admin endpoint. 1644 type PrivateAdminAPI struct { 1645 eth *Ethereum 1646 } 1647 1648 // NewPrivateAdminAPI creates a new API definition for the private admin methods 1649 // of the Ethereum service. 1650 func NewPrivateAdminAPI(eth *Ethereum) *PrivateAdminAPI { 1651 return &PrivateAdminAPI{eth: eth} 1652 } 1653 1654 // SetSolc sets the Solidity compiler path to be used by the node. 1655 func (api *PrivateAdminAPI) SetSolc(path string) (string, error) { 1656 solc, err := api.eth.SetSolc(path) 1657 if err != nil { 1658 return "", err 1659 } 1660 return solc.Info(), nil 1661 } 1662 1663 // ExportChain exports the current blockchain into a local file. 1664 func (api *PrivateAdminAPI) ExportChain(file string) (bool, error) { 1665 // Make sure we can create the file to export into 1666 out, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) 1667 if err != nil { 1668 return false, err 1669 } 1670 defer out.Close() 1671 1672 // Export the blockchain 1673 if err := api.eth.BlockChain().Export(out); err != nil { 1674 return false, err 1675 } 1676 return true, nil 1677 } 1678 1679 func hasAllBlocks(chain *core.BlockChain, bs []*types.Block) bool { 1680 for _, b := range bs { 1681 if !chain.HasBlock(b.Hash()) { 1682 return false 1683 } 1684 } 1685 1686 return true 1687 } 1688 1689 // ImportChain imports a blockchain from a local file. 1690 func (api *PrivateAdminAPI) ImportChain(file string) (bool, error) { 1691 // Make sure the can access the file to import 1692 in, err := os.Open(file) 1693 if err != nil { 1694 return false, err 1695 } 1696 defer in.Close() 1697 1698 // Run actual the import in pre-configured batches 1699 stream := rlp.NewStream(in, 0) 1700 1701 blocks, index := make([]*types.Block, 0, 2500), 0 1702 for batch := 0; ; batch++ { 1703 // Load a batch of blocks from the input file 1704 for len(blocks) < cap(blocks) { 1705 block := new(types.Block) 1706 if err := stream.Decode(block); err == io.EOF { 1707 break 1708 } else if err != nil { 1709 return false, fmt.Errorf("block %d: failed to parse: %v", index, err) 1710 } 1711 blocks = append(blocks, block) 1712 index++ 1713 } 1714 if len(blocks) == 0 { 1715 break 1716 } 1717 1718 if hasAllBlocks(api.eth.BlockChain(), blocks) { 1719 blocks = blocks[:0] 1720 continue 1721 } 1722 // Import the batch and reset the buffer 1723 if res := api.eth.BlockChain().InsertChain(blocks); res.Error != nil { 1724 return false, fmt.Errorf("batch %d: failed to insert: %v", batch, res.Error) 1725 } 1726 blocks = blocks[:0] 1727 } 1728 return true, nil 1729 } 1730 1731 // PublicDebugAPI is the collection of Etheruem APIs exposed over the public 1732 // debugging endpoint. 1733 type PublicGethAPI struct { 1734 eth *Ethereum 1735 } 1736 1737 // NewPublicDebugAPI creates a new API definition for the public debug methods 1738 // of the Ethereum service. 1739 func NewPublicGethAPI(eth *Ethereum) *PublicGethAPI { 1740 return &PublicGethAPI{eth: eth} 1741 } 1742 1743 // GetTransactionsByAddress is an alias for GetAddressTransactions which aligns more closely 1744 // with established eth_transaction api namespace 1745 func (api *PublicGethAPI) GetTransactionsByAddress(address common.Address, blockStartN uint64, blockEndN rpc.BlockNumber, toOrFrom string, txKindOf string, pagStart, pagEnd int, reverse bool) (list []string, err error) { 1746 return api.GetAddressTransactions(address, blockStartN, blockEndN, toOrFrom, txKindOf, pagStart, pagEnd, reverse) 1747 } 1748 1749 // AddressTransactions gets transactions for a given address. 1750 // Optional values include start and stop block numbers, and to/from/both value for tx/address relation. 1751 // Returns a slice of strings of transactions hashes. 1752 func (api *PublicGethAPI) GetAddressTransactions(address common.Address, blockStartN uint64, blockEndN rpc.BlockNumber, toOrFrom string, txKindOf string, pagStart, pagEnd int, reverse bool) (list []string, err error) { 1753 glog.V(logger.Debug).Infof("RPC call: debug_getAddressTransactions %s %d %d %s %s", address, blockStartN, blockEndN, toOrFrom, txKindOf) 1754 1755 atxi := api.eth.BlockChain().GetAtxi() 1756 if atxi == nil { 1757 return nil, errors.New("addr-tx indexing not enabled") 1758 } 1759 // Use human-friendly abbreviations, per https://github.com/ethereumproject/go-ethereum/pull/475#issuecomment-366065122 1760 // so 't' => to, 'f' => from, 'tf|ft' => either/both. Same pattern for txKindOf. 1761 // _t_o OR _f_rom 1762 if toOrFrom == "tf" || toOrFrom == "ft" { 1763 toOrFrom = "b" 1764 } 1765 // _s_tandard OR _c_ontract 1766 if txKindOf == "sc" || txKindOf == "cs" { 1767 txKindOf = "b" 1768 } 1769 1770 if blockEndN == rpc.LatestBlockNumber || blockEndN == rpc.PendingBlockNumber { 1771 blockEndN = 0 1772 } 1773 1774 list, err = core.GetAddrTxs(atxi.Db, address, blockStartN, uint64(blockEndN.Int64()), toOrFrom, txKindOf, pagStart, pagEnd, reverse) 1775 if err != nil { 1776 return 1777 } 1778 1779 // Since list is a slice, it can be nil, which returns 'null'. 1780 // Should return empty 'array' if no txs found. 1781 if list == nil { 1782 list = []string{} 1783 } 1784 return list, nil 1785 } 1786 1787 func (api *PublicGethAPI) BuildATXI(start, stop, step rpc.BlockNumber) (bool, error) { 1788 glog.V(logger.Debug).Infof("RPC call: geth_buildATXI %v %v %v", start, stop, step) 1789 1790 convert := func(number rpc.BlockNumber) uint64 { 1791 switch number { 1792 case rpc.LatestBlockNumber, rpc.PendingBlockNumber: 1793 return math.MaxUint64 1794 default: 1795 return uint64(number.Int64()) 1796 } 1797 } 1798 1799 atxi := api.eth.BlockChain().GetAtxi() 1800 if atxi == nil { 1801 return false, errors.New("addr-tx indexing not enabled") 1802 } 1803 if atxi.AutoMode { 1804 return false, errors.New("addr-tx indexing already running via the auto build mode") 1805 } 1806 1807 progress, err := api.eth.BlockChain().GetATXIBuildProgress() 1808 if err != nil { 1809 return false, err 1810 } 1811 if progress != nil && progress.Start != uint64(math.MaxUint64) && progress.Current < progress.Stop && progress.LastError == nil { 1812 return false, fmt.Errorf("ATXI build process is already running (first block: %d, last block: %d, current block: %d\n)", progress.Start, progress.Stop, progress.Current) 1813 } 1814 1815 go core.BuildAddrTxIndex(api.eth.BlockChain(), api.eth.ChainDb(), atxi.Db, convert(start), convert(stop), convert(step)) 1816 1817 return true, nil 1818 } 1819 1820 func (api *PublicGethAPI) GetATXIBuildStatus() (*core.AtxiProgressT, error) { 1821 atxi := api.eth.BlockChain().GetAtxi() 1822 if atxi == nil { 1823 return nil, errors.New("addr-tx indexing not enabled") 1824 } 1825 if atxi.Progress == nil { 1826 return nil, errors.New("no progress available for unstarted atxi indexing process") 1827 } 1828 1829 progress, err := api.eth.BlockChain().GetATXIBuildProgress() 1830 if err != nil { 1831 return nil, err 1832 } 1833 if progress.Start == progress.Current { 1834 return nil, nil 1835 } 1836 return progress, nil 1837 } 1838 1839 // PublicDebugAPI is the collection of Etheruem APIs exposed over the public 1840 // debugging endpoint. 1841 type PublicDebugAPI struct { 1842 eth *Ethereum 1843 } 1844 1845 // NewPublicDebugAPI creates a new API definition for the public debug methods 1846 // of the Ethereum service. 1847 func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI { 1848 return &PublicDebugAPI{eth: eth} 1849 } 1850 1851 // DumpBlock retrieves the entire state of the database at a given block. 1852 // TODO: update to be able to dump for specific addresses? 1853 func (api *PublicDebugAPI) DumpBlock(number uint64) (state.Dump, error) { 1854 block := api.eth.BlockChain().GetBlockByNumber(number) 1855 if block == nil { 1856 return state.Dump{}, fmt.Errorf("block #%d not found", number) 1857 } 1858 stateDb, err := api.eth.BlockChain().StateAt(block.Root()) 1859 if err != nil { 1860 return state.Dump{}, err 1861 } 1862 return stateDb.RawDump([]common.Address{}), nil 1863 } 1864 1865 // AccountExist checks whether an address is considered exists at a given block. 1866 func (api *PublicDebugAPI) AccountExist(address common.Address, number uint64) (bool, error) { 1867 block := api.eth.BlockChain().GetBlockByNumber(number) 1868 if block == nil { 1869 return false, fmt.Errorf("block #%d not found", number) 1870 } 1871 stateDb, err := api.eth.BlockChain().StateAt(block.Root()) 1872 if err != nil { 1873 return false, err 1874 } 1875 return stateDb.Exist(address), nil 1876 } 1877 1878 // GetBlockRlp retrieves the RLP encoded for of a single block. 1879 func (api *PublicDebugAPI) GetBlockRlp(number uint64) (string, error) { 1880 block := api.eth.BlockChain().GetBlockByNumber(number) 1881 if block == nil { 1882 return "", fmt.Errorf("block #%d not found", number) 1883 } 1884 encoded, err := rlp.EncodeToBytes(block) 1885 if err != nil { 1886 return "", err 1887 } 1888 return fmt.Sprintf("%x", encoded), nil 1889 } 1890 1891 // PrintBlock retrieves a block and returns its pretty printed form. 1892 func (api *PublicDebugAPI) PrintBlock(number uint64) (string, error) { 1893 block := api.eth.BlockChain().GetBlockByNumber(number) 1894 if block == nil { 1895 return "", fmt.Errorf("block #%d not found", number) 1896 } 1897 return fmt.Sprintf("%s", block), nil 1898 } 1899 1900 // SeedHash retrieves the seed hash of a block. 1901 func (api *PublicDebugAPI) SeedHash(number uint64) (string, error) { 1902 block := api.eth.BlockChain().GetBlockByNumber(number) 1903 if block == nil { 1904 return "", fmt.Errorf("block #%d not found", number) 1905 } 1906 hash, err := ethash.GetSeedHash(number) 1907 if err != nil { 1908 return "", err 1909 } 1910 return fmt.Sprintf("0x%x", hash), nil 1911 } 1912 1913 func (api *PublicDebugAPI) SetHead(number uint64) (bool, error) { 1914 if e := api.eth.BlockChain().SetHead(number); e != nil { 1915 return false, e 1916 } 1917 return true, nil 1918 } 1919 1920 // Metrics return all available registered metrics for the client. 1921 // See https://github.com/ethereumproject/go-ethereum/wiki/Metrics-and-Monitoring for prophetic documentation. 1922 func (api *PublicDebugAPI) Metrics(raw bool) (map[string]interface{}, error) { 1923 1924 // Create a rate formatter 1925 units := []string{"", "K", "M", "G", "T", "E", "P"} 1926 round := func(value float64, prec int) string { 1927 unit := 0 1928 for value >= 1000 { 1929 unit, value, prec = unit+1, value/1000, 2 1930 } 1931 return fmt.Sprintf(fmt.Sprintf("%%.%df%s", prec, units[unit]), value) 1932 } 1933 format := func(total float64, rate float64) string { 1934 return fmt.Sprintf("%s (%s/s)", round(total, 0), round(rate, 2)) 1935 } 1936 1937 var b []byte 1938 var err error 1939 1940 b, err = ethMetrics.CollectToJSON() 1941 if err != nil { 1942 return nil, err 1943 } 1944 1945 out := make(map[string]interface{}) 1946 err = json.Unmarshal(b, &out) 1947 if err != nil { 1948 return nil, err 1949 } 1950 1951 // human friendly if specified 1952 if !raw { 1953 rout := out 1954 for k, v := range out { 1955 if m, ok := v.(map[string]interface{}); ok { 1956 // This is one way of differentiating Meters, Timers, and Gauges. 1957 // whilei: (having some trouble with *metrics.StandardTimer(etc) type switches) 1958 // If new types metrics are introduced, they should have their relevant values added here. 1959 if _, ok := m["mean.rate"]; ok { 1960 h1m := format(m["1m.rate"].(float64)*60, m["1m.rate"].(float64)) 1961 h5m := format(m["5m.rate"].(float64)*300, m["5m.rate"].(float64)) 1962 h15m := format(m["15m.rate"].(float64)*900, m["15m.rate"].(float64)) 1963 hmr := format(m["mean.rate"].(float64), m["mean.rate"].(float64)) 1964 rout[k] = map[string]interface{}{ 1965 "1m.rate": h1m, 1966 "5m.rate": h5m, 1967 "15m.rate": h15m, 1968 "mean.rate": hmr, 1969 "count": fmt.Sprintf("%v", m["count"]), 1970 } 1971 } else if _, ok := m["value"]; ok { 1972 rout[k] = map[string]interface{}{ 1973 "value": fmt.Sprintf("%v", m["value"]), 1974 } 1975 } 1976 } 1977 } 1978 return rout, nil 1979 } 1980 1981 return out, nil 1982 } 1983 1984 // Verbosity implements api method debug_verbosity, enabling setting 1985 // global logging verbosity on the fly. 1986 // Note that it will NOT allow setting verbosity '0', which is effectively 'off'. 1987 // In place of ability to receive 0 as a functional parameter, debug.verbosity() -> debug.verbosity(0) -> glog.GetVerbosity(). 1988 // creates a shorthand/convenience method as a "getter" function returning the current value 1989 // of the verbosity setting. 1990 func (api *PublicDebugAPI) Verbosity(n uint64) (int, error) { 1991 nint := int(n) 1992 if nint == 0 { 1993 return int(*glog.GetVerbosity()), nil 1994 } 1995 if nint <= logger.Detail || nint == logger.Ridiculousness { 1996 glog.SetV(nint) 1997 i := int(*glog.GetVerbosity()) 1998 glog.V(logger.Warn).Infof("Set verbosity: %d", i) 1999 glog.D(logger.Warn).Warnf("Set verbosity: %d", i) 2000 return i, nil 2001 } 2002 e := errors.New("invalid logging level") 2003 glog.V(logger.Warn).Errorf("Set verbosity failed: %d (%v)", nint, e) 2004 glog.D(logger.Error).Errorf("Set verbosity failed: %d (%v)", nint, e) 2005 return -1, e 2006 } 2007 2008 // Vmodule implements api method debug_vmodule, enabling setting 2009 // glog per-module verbosity settings on the fly. 2010 func (api *PublicDebugAPI) Vmodule(s string) (string, error) { 2011 if s == "" { 2012 return glog.GetVModule().String(), nil 2013 } 2014 err := glog.GetVModule().Set(s) 2015 ns := glog.GetVModule().String() 2016 if err != nil { 2017 glog.V(logger.Warn).Infof("Set vmodule: '%s'", ns) 2018 glog.D(logger.Warn).Warnf("Set vmodule: '%s'", ns) 2019 } else { 2020 glog.V(logger.Warn).Infof("Set vmodule failed: '%s' (%v)", ns, err) 2021 glog.D(logger.Warn).Warnf("Set vmodule: '%s' (%v)", ns, err) 2022 } 2023 return ns, err 2024 } 2025 2026 // ExecutionResult groups all structured logs emitted by the EVM 2027 // while replaying a transaction in debug mode as well as the amount of 2028 // gas used and the return value 2029 type ExecutionResult struct { 2030 Gas *big.Int `json:"gas"` 2031 ReturnValue string `json:"returnValue"` 2032 } 2033 2034 // TraceCall executes a call and returns the amount of gas and optionally returned values. 2035 func (s *PublicBlockChainAPI) TraceCall(args CallArgs, blockNr rpc.BlockNumber) (*ExecutionResult, error) { 2036 // Fetch the state associated with the block number 2037 stateDb, block, err := stateAndBlockByNumber(s.miner, s.bc, blockNr, s.chainDb) 2038 if stateDb == nil || err != nil { 2039 return nil, err 2040 } 2041 stateDb = stateDb.Copy() 2042 2043 // Retrieve the account state object to interact with 2044 var from *state.StateObject 2045 if args.From == (common.Address{}) { 2046 accounts := s.am.Accounts() 2047 if len(accounts) == 0 { 2048 from = stateDb.GetOrNewStateObject(common.Address{}) 2049 } else { 2050 from = stateDb.GetOrNewStateObject(accounts[0].Address) 2051 } 2052 } else { 2053 from = stateDb.GetOrNewStateObject(args.From) 2054 } 2055 from.SetBalance(common.MaxBig) 2056 2057 // Assemble the CALL invocation 2058 msg := callmsg{ 2059 from: from, 2060 to: args.To, 2061 gas: args.Gas.BigInt(), 2062 gasPrice: args.GasPrice.BigInt(), 2063 value: args.Value.BigInt(), 2064 data: common.FromHex(args.Data), 2065 } 2066 if msg.gas.Sign() == 0 { 2067 msg.gas = big.NewInt(50000000) 2068 } 2069 if msg.gasPrice.Sign() == 0 { 2070 msg.gasPrice = new(big.Int).Mul(big.NewInt(50), common.Shannon) 2071 } 2072 2073 // Execute the call and return 2074 vmenv := core.NewEnv(stateDb, s.config, s.bc, msg, block.Header()) 2075 gp := new(core.GasPool).AddGas(common.MaxBig) 2076 2077 ret, gas, _, err := core.ApplyMessage(vmenv, msg, gp) 2078 return &ExecutionResult{ 2079 Gas: gas, 2080 ReturnValue: fmt.Sprintf("%x", ret), 2081 }, nil 2082 } 2083 2084 // TraceTransaction returns the amount of gas and execution result of the given transaction. 2085 func (s *PublicDebugAPI) TraceTransaction(txHash common.Hash) (*ExecutionResult, error) { 2086 var result *ExecutionResult 2087 tx, blockHash, _, txIndex := core.GetTransaction(s.eth.ChainDb(), txHash) 2088 if tx == nil { 2089 return result, fmt.Errorf("tx '%x' not found", txHash) 2090 } 2091 2092 msg, vmenv, err := s.computeTxEnv(blockHash, int(txIndex)) 2093 if err != nil { 2094 return nil, err 2095 } 2096 2097 gp := new(core.GasPool).AddGas(tx.Gas()) 2098 ret, gas, _, err := core.ApplyMessage(vmenv, msg, gp) 2099 return &ExecutionResult{ 2100 Gas: gas, 2101 ReturnValue: fmt.Sprintf("%x", ret), 2102 }, nil 2103 } 2104 2105 // computeTxEnv returns the execution environment of a certain transaction. 2106 func (s *PublicDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int) (core.Message, *core.VMEnv, error) { 2107 2108 // Create the parent state. 2109 block := s.eth.BlockChain().GetBlock(blockHash) 2110 if block == nil { 2111 return nil, nil, fmt.Errorf("block %x not found", blockHash) 2112 } 2113 parent := s.eth.BlockChain().GetBlock(block.ParentHash()) 2114 if parent == nil { 2115 return nil, nil, fmt.Errorf("block parent %x not found", block.ParentHash()) 2116 } 2117 statedb, err := s.eth.BlockChain().StateAt(parent.Root()) 2118 if err != nil { 2119 return nil, nil, err 2120 } 2121 txs := block.Transactions() 2122 2123 // Recompute transactions up to the target index. 2124 for idx, tx := range txs { 2125 // Assemble the transaction call message 2126 // Retrieve the account state object to interact with 2127 var from *state.StateObject 2128 fromAddress, e := tx.From() 2129 if e != nil { 2130 return nil, nil, e 2131 } 2132 if fromAddress == (common.Address{}) { 2133 from = statedb.GetOrNewStateObject(common.Address{}) 2134 } else { 2135 from = statedb.GetOrNewStateObject(fromAddress) 2136 } 2137 2138 msg := callmsg{ 2139 from: from, 2140 to: tx.To(), 2141 gas: tx.Gas(), 2142 gasPrice: tx.GasPrice(), 2143 value: tx.Value(), 2144 data: tx.Data(), 2145 } 2146 2147 vmenv := core.NewEnv(statedb, s.eth.chainConfig, s.eth.BlockChain(), msg, block.Header()) 2148 if idx == txIndex { 2149 return msg, vmenv, nil 2150 } 2151 2152 gp := new(core.GasPool).AddGas(tx.Gas()) 2153 _, _, _, err := core.ApplyMessage(vmenv, msg, gp) 2154 if err != nil { 2155 return nil, nil, fmt.Errorf("tx %x failed: %v", tx.Hash(), err) 2156 } 2157 statedb.DeleteSuicides() 2158 } 2159 return nil, nil, fmt.Errorf("tx index %d out of range for block %x", txIndex, blockHash) 2160 } 2161 2162 // PublicNetAPI offers network related RPC methods 2163 type PublicNetAPI struct { 2164 net *p2p.Server 2165 networkVersion int 2166 } 2167 2168 // NewPublicNetAPI creates a new net API instance. 2169 func NewPublicNetAPI(net *p2p.Server, networkVersion int) *PublicNetAPI { 2170 return &PublicNetAPI{net, networkVersion} 2171 } 2172 2173 // Listening returns an indication if the node is listening for network connections. 2174 func (s *PublicNetAPI) Listening() bool { 2175 return true // always listening 2176 } 2177 2178 // PeerCount returns the number of connected peers 2179 func (s *PublicNetAPI) PeerCount() *rpc.HexNumber { 2180 return rpc.NewHexNumber(s.net.PeerCount()) 2181 } 2182 2183 // Version returns the current ethereum protocol version. 2184 func (s *PublicNetAPI) Version() string { 2185 return fmt.Sprintf("%d", s.networkVersion) 2186 }