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