server_handler.go 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034
  1. // Copyright 2019 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. package les
  17. import (
  18. "crypto/ecdsa"
  19. "encoding/binary"
  20. "encoding/json"
  21. "errors"
  22. "sync"
  23. "sync/atomic"
  24. "time"
  25. "github.com/ethereum/go-ethereum/common"
  26. "github.com/ethereum/go-ethereum/common/mclock"
  27. "github.com/ethereum/go-ethereum/core"
  28. "github.com/ethereum/go-ethereum/core/rawdb"
  29. "github.com/ethereum/go-ethereum/core/state"
  30. "github.com/ethereum/go-ethereum/core/types"
  31. "github.com/ethereum/go-ethereum/ethdb"
  32. lps "github.com/ethereum/go-ethereum/les/lespay/server"
  33. "github.com/ethereum/go-ethereum/light"
  34. "github.com/ethereum/go-ethereum/log"
  35. "github.com/ethereum/go-ethereum/metrics"
  36. "github.com/ethereum/go-ethereum/p2p"
  37. "github.com/ethereum/go-ethereum/p2p/enode"
  38. "github.com/ethereum/go-ethereum/p2p/nodestate"
  39. "github.com/ethereum/go-ethereum/rlp"
  40. "github.com/ethereum/go-ethereum/trie"
  41. )
  42. const (
  43. softResponseLimit = 2 * 1024 * 1024 // Target maximum size of returned blocks, headers or node data.
  44. estHeaderRlpSize = 500 // Approximate size of an RLP encoded block header
  45. ethVersion = 63 // equivalent eth version for the downloader
  46. MaxHeaderFetch = 192 // Amount of block headers to be fetched per retrieval request
  47. MaxBodyFetch = 32 // Amount of block bodies to be fetched per retrieval request
  48. MaxReceiptFetch = 128 // Amount of transaction receipts to allow fetching per request
  49. MaxCodeFetch = 64 // Amount of contract codes to allow fetching per request
  50. MaxProofsFetch = 64 // Amount of merkle proofs to be fetched per retrieval request
  51. MaxHelperTrieProofsFetch = 64 // Amount of helper tries to be fetched per retrieval request
  52. MaxTxSend = 64 // Amount of transactions to be send per request
  53. MaxTxStatus = 256 // Amount of transactions to queried per request
  54. )
  55. var (
  56. errTooManyInvalidRequest = errors.New("too many invalid requests made")
  57. errFullClientPool = errors.New("client pool is full")
  58. )
  59. // serverHandler is responsible for serving light client and process
  60. // all incoming light requests.
  61. type serverHandler struct {
  62. blockchain *core.BlockChain
  63. chainDb ethdb.Database
  64. txpool *core.TxPool
  65. server *LesServer
  66. closeCh chan struct{} // Channel used to exit all background routines of handler.
  67. wg sync.WaitGroup // WaitGroup used to track all background routines of handler.
  68. synced func() bool // Callback function used to determine whether local node is synced.
  69. // Testing fields
  70. addTxsSync bool
  71. }
  72. func newServerHandler(server *LesServer, blockchain *core.BlockChain, chainDb ethdb.Database, txpool *core.TxPool, synced func() bool) *serverHandler {
  73. handler := &serverHandler{
  74. server: server,
  75. blockchain: blockchain,
  76. chainDb: chainDb,
  77. txpool: txpool,
  78. closeCh: make(chan struct{}),
  79. synced: synced,
  80. }
  81. return handler
  82. }
  83. // start starts the server handler.
  84. func (h *serverHandler) start() {
  85. h.wg.Add(1)
  86. go h.broadcastLoop()
  87. }
  88. // stop stops the server handler.
  89. func (h *serverHandler) stop() {
  90. close(h.closeCh)
  91. h.wg.Wait()
  92. }
  93. // runPeer is the p2p protocol run function for the given version.
  94. func (h *serverHandler) runPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter) error {
  95. peer := newClientPeer(int(version), h.server.config.NetworkId, p, newMeteredMsgWriter(rw, int(version)))
  96. defer peer.close()
  97. h.wg.Add(1)
  98. defer h.wg.Done()
  99. return h.handle(peer)
  100. }
  101. func (h *serverHandler) handle(p *clientPeer) error {
  102. p.Log().Debug("Light Ethereum peer connected", "name", p.Name())
  103. // Execute the LES handshake
  104. var (
  105. head = h.blockchain.CurrentHeader()
  106. hash = head.Hash()
  107. number = head.Number.Uint64()
  108. td = h.blockchain.GetTd(hash, number)
  109. )
  110. if err := p.Handshake(td, hash, number, h.blockchain.Genesis().Hash(), h.server); err != nil {
  111. p.Log().Debug("Light Ethereum handshake failed", "err", err)
  112. return err
  113. }
  114. // Reject the duplicated peer, otherwise register it to peerset.
  115. var registered bool
  116. if err := h.server.ns.Operation(func() {
  117. if h.server.ns.GetField(p.Node(), clientPeerField) != nil {
  118. registered = true
  119. } else {
  120. h.server.ns.SetFieldSub(p.Node(), clientPeerField, p)
  121. }
  122. }); err != nil {
  123. return err
  124. }
  125. if registered {
  126. return errAlreadyRegistered
  127. }
  128. defer func() {
  129. h.server.ns.SetField(p.Node(), clientPeerField, nil)
  130. if p.fcClient != nil { // is nil when connecting another server
  131. p.fcClient.Disconnect()
  132. }
  133. }()
  134. if p.server {
  135. // connected to another server, no messages expected, just wait for disconnection
  136. _, err := p.rw.ReadMsg()
  137. return err
  138. }
  139. // Reject light clients if server is not synced.
  140. //
  141. // Put this checking here, so that "non-synced" les-server peers are still allowed
  142. // to keep the connection.
  143. if !h.synced() {
  144. p.Log().Debug("Light server not synced, rejecting peer")
  145. return p2p.DiscRequested
  146. }
  147. // Disconnect the inbound peer if it's rejected by clientPool
  148. if cap, err := h.server.clientPool.connect(p); cap != p.fcParams.MinRecharge || err != nil {
  149. p.Log().Debug("Light Ethereum peer rejected", "err", errFullClientPool)
  150. return errFullClientPool
  151. }
  152. p.balance, _ = h.server.ns.GetField(p.Node(), h.server.clientPool.BalanceField).(*lps.NodeBalance)
  153. if p.balance == nil {
  154. return p2p.DiscRequested
  155. }
  156. activeCount, _ := h.server.clientPool.pp.Active()
  157. clientConnectionGauge.Update(int64(activeCount))
  158. var wg sync.WaitGroup // Wait group used to track all in-flight task routines.
  159. connectedAt := mclock.Now()
  160. defer func() {
  161. wg.Wait() // Ensure all background task routines have exited.
  162. h.server.clientPool.disconnect(p)
  163. p.balance = nil
  164. activeCount, _ := h.server.clientPool.pp.Active()
  165. clientConnectionGauge.Update(int64(activeCount))
  166. connectionTimer.Update(time.Duration(mclock.Now() - connectedAt))
  167. }()
  168. // Mark the peer starts to be served.
  169. atomic.StoreUint32(&p.serving, 1)
  170. defer atomic.StoreUint32(&p.serving, 0)
  171. // Spawn a main loop to handle all incoming messages.
  172. for {
  173. select {
  174. case err := <-p.errCh:
  175. p.Log().Debug("Failed to send light ethereum response", "err", err)
  176. return err
  177. default:
  178. }
  179. if err := h.handleMsg(p, &wg); err != nil {
  180. p.Log().Debug("Light Ethereum message handling failed", "err", err)
  181. return err
  182. }
  183. }
  184. }
  185. // handleMsg is invoked whenever an inbound message is received from a remote
  186. // peer. The remote connection is torn down upon returning any error.
  187. func (h *serverHandler) handleMsg(p *clientPeer, wg *sync.WaitGroup) error {
  188. // Read the next message from the remote peer, and ensure it's fully consumed
  189. msg, err := p.rw.ReadMsg()
  190. if err != nil {
  191. return err
  192. }
  193. p.Log().Trace("Light Ethereum message arrived", "code", msg.Code, "bytes", msg.Size)
  194. // Discard large message which exceeds the limitation.
  195. if msg.Size > ProtocolMaxMsgSize {
  196. clientErrorMeter.Mark(1)
  197. return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize)
  198. }
  199. defer msg.Discard()
  200. var (
  201. maxCost uint64
  202. task *servingTask
  203. )
  204. p.responseCount++
  205. responseCount := p.responseCount
  206. // accept returns an indicator whether the request can be served.
  207. // If so, deduct the max cost from the flow control buffer.
  208. accept := func(reqID, reqCnt, maxCnt uint64) bool {
  209. // Short circuit if the peer is already frozen or the request is invalid.
  210. inSizeCost := h.server.costTracker.realCost(0, msg.Size, 0)
  211. if p.isFrozen() || reqCnt == 0 || reqCnt > maxCnt {
  212. p.fcClient.OneTimeCost(inSizeCost)
  213. return false
  214. }
  215. // Prepaid max cost units before request been serving.
  216. maxCost = p.fcCosts.getMaxCost(msg.Code, reqCnt)
  217. accepted, bufShort, priority := p.fcClient.AcceptRequest(reqID, responseCount, maxCost)
  218. if !accepted {
  219. p.freeze()
  220. p.Log().Error("Request came too early", "remaining", common.PrettyDuration(time.Duration(bufShort*1000000/p.fcParams.MinRecharge)))
  221. p.fcClient.OneTimeCost(inSizeCost)
  222. return false
  223. }
  224. // Create a multi-stage task, estimate the time it takes for the task to
  225. // execute, and cache it in the request service queue.
  226. factor := h.server.costTracker.globalFactor()
  227. if factor < 0.001 {
  228. factor = 1
  229. p.Log().Error("Invalid global cost factor", "factor", factor)
  230. }
  231. maxTime := uint64(float64(maxCost) / factor)
  232. task = h.server.servingQueue.newTask(p, maxTime, priority)
  233. if task.start() {
  234. return true
  235. }
  236. p.fcClient.RequestProcessed(reqID, responseCount, maxCost, inSizeCost)
  237. return false
  238. }
  239. // sendResponse sends back the response and updates the flow control statistic.
  240. sendResponse := func(reqID, amount uint64, reply *reply, servingTime uint64) {
  241. p.responseLock.Lock()
  242. defer p.responseLock.Unlock()
  243. // Short circuit if the client is already frozen.
  244. if p.isFrozen() {
  245. realCost := h.server.costTracker.realCost(servingTime, msg.Size, 0)
  246. p.fcClient.RequestProcessed(reqID, responseCount, maxCost, realCost)
  247. return
  248. }
  249. // Positive correction buffer value with real cost.
  250. var replySize uint32
  251. if reply != nil {
  252. replySize = reply.size()
  253. }
  254. var realCost uint64
  255. if h.server.costTracker.testing {
  256. realCost = maxCost // Assign a fake cost for testing purpose
  257. } else {
  258. realCost = h.server.costTracker.realCost(servingTime, msg.Size, replySize)
  259. if realCost > maxCost {
  260. realCost = maxCost
  261. }
  262. }
  263. bv := p.fcClient.RequestProcessed(reqID, responseCount, maxCost, realCost)
  264. if amount != 0 {
  265. // Feed cost tracker request serving statistic.
  266. h.server.costTracker.updateStats(msg.Code, amount, servingTime, realCost)
  267. // Reduce priority "balance" for the specific peer.
  268. p.balance.RequestServed(realCost)
  269. }
  270. if reply != nil {
  271. p.queueSend(func() {
  272. if err := reply.send(bv); err != nil {
  273. select {
  274. case p.errCh <- err:
  275. default:
  276. }
  277. }
  278. })
  279. }
  280. }
  281. switch msg.Code {
  282. case GetBlockHeadersMsg:
  283. p.Log().Trace("Received block header request")
  284. if metrics.EnabledExpensive {
  285. miscInHeaderPacketsMeter.Mark(1)
  286. miscInHeaderTrafficMeter.Mark(int64(msg.Size))
  287. }
  288. var req struct {
  289. ReqID uint64
  290. Query getBlockHeadersData
  291. }
  292. if err := msg.Decode(&req); err != nil {
  293. clientErrorMeter.Mark(1)
  294. return errResp(ErrDecode, "%v: %v", msg, err)
  295. }
  296. query := req.Query
  297. if accept(req.ReqID, query.Amount, MaxHeaderFetch) {
  298. wg.Add(1)
  299. go func() {
  300. defer wg.Done()
  301. hashMode := query.Origin.Hash != (common.Hash{})
  302. first := true
  303. maxNonCanonical := uint64(100)
  304. // Gather headers until the fetch or network limits is reached
  305. var (
  306. bytes common.StorageSize
  307. headers []*types.Header
  308. unknown bool
  309. )
  310. for !unknown && len(headers) < int(query.Amount) && bytes < softResponseLimit {
  311. if !first && !task.waitOrStop() {
  312. sendResponse(req.ReqID, 0, nil, task.servingTime)
  313. return
  314. }
  315. // Retrieve the next header satisfying the query
  316. var origin *types.Header
  317. if hashMode {
  318. if first {
  319. origin = h.blockchain.GetHeaderByHash(query.Origin.Hash)
  320. if origin != nil {
  321. query.Origin.Number = origin.Number.Uint64()
  322. }
  323. } else {
  324. origin = h.blockchain.GetHeader(query.Origin.Hash, query.Origin.Number)
  325. }
  326. } else {
  327. origin = h.blockchain.GetHeaderByNumber(query.Origin.Number)
  328. }
  329. if origin == nil {
  330. break
  331. }
  332. headers = append(headers, origin)
  333. bytes += estHeaderRlpSize
  334. // Advance to the next header of the query
  335. switch {
  336. case hashMode && query.Reverse:
  337. // Hash based traversal towards the genesis block
  338. ancestor := query.Skip + 1
  339. if ancestor == 0 {
  340. unknown = true
  341. } else {
  342. query.Origin.Hash, query.Origin.Number = h.blockchain.GetAncestor(query.Origin.Hash, query.Origin.Number, ancestor, &maxNonCanonical)
  343. unknown = query.Origin.Hash == common.Hash{}
  344. }
  345. case hashMode && !query.Reverse:
  346. // Hash based traversal towards the leaf block
  347. var (
  348. current = origin.Number.Uint64()
  349. next = current + query.Skip + 1
  350. )
  351. if next <= current {
  352. infos, _ := json.MarshalIndent(p.Peer.Info(), "", " ")
  353. p.Log().Warn("GetBlockHeaders skip overflow attack", "current", current, "skip", query.Skip, "next", next, "attacker", infos)
  354. unknown = true
  355. } else {
  356. if header := h.blockchain.GetHeaderByNumber(next); header != nil {
  357. nextHash := header.Hash()
  358. expOldHash, _ := h.blockchain.GetAncestor(nextHash, next, query.Skip+1, &maxNonCanonical)
  359. if expOldHash == query.Origin.Hash {
  360. query.Origin.Hash, query.Origin.Number = nextHash, next
  361. } else {
  362. unknown = true
  363. }
  364. } else {
  365. unknown = true
  366. }
  367. }
  368. case query.Reverse:
  369. // Number based traversal towards the genesis block
  370. if query.Origin.Number >= query.Skip+1 {
  371. query.Origin.Number -= query.Skip + 1
  372. } else {
  373. unknown = true
  374. }
  375. case !query.Reverse:
  376. // Number based traversal towards the leaf block
  377. query.Origin.Number += query.Skip + 1
  378. }
  379. first = false
  380. }
  381. reply := p.replyBlockHeaders(req.ReqID, headers)
  382. sendResponse(req.ReqID, query.Amount, reply, task.done())
  383. if metrics.EnabledExpensive {
  384. miscOutHeaderPacketsMeter.Mark(1)
  385. miscOutHeaderTrafficMeter.Mark(int64(reply.size()))
  386. miscServingTimeHeaderTimer.Update(time.Duration(task.servingTime))
  387. }
  388. }()
  389. }
  390. case GetBlockBodiesMsg:
  391. p.Log().Trace("Received block bodies request")
  392. if metrics.EnabledExpensive {
  393. miscInBodyPacketsMeter.Mark(1)
  394. miscInBodyTrafficMeter.Mark(int64(msg.Size))
  395. }
  396. var req struct {
  397. ReqID uint64
  398. Hashes []common.Hash
  399. }
  400. if err := msg.Decode(&req); err != nil {
  401. clientErrorMeter.Mark(1)
  402. return errResp(ErrDecode, "msg %v: %v", msg, err)
  403. }
  404. var (
  405. bytes int
  406. bodies []rlp.RawValue
  407. )
  408. reqCnt := len(req.Hashes)
  409. if accept(req.ReqID, uint64(reqCnt), MaxBodyFetch) {
  410. wg.Add(1)
  411. go func() {
  412. defer wg.Done()
  413. for i, hash := range req.Hashes {
  414. if i != 0 && !task.waitOrStop() {
  415. sendResponse(req.ReqID, 0, nil, task.servingTime)
  416. return
  417. }
  418. if bytes >= softResponseLimit {
  419. break
  420. }
  421. body := h.blockchain.GetBodyRLP(hash)
  422. if body == nil {
  423. p.bumpInvalid()
  424. continue
  425. }
  426. bodies = append(bodies, body)
  427. bytes += len(body)
  428. }
  429. reply := p.replyBlockBodiesRLP(req.ReqID, bodies)
  430. sendResponse(req.ReqID, uint64(reqCnt), reply, task.done())
  431. if metrics.EnabledExpensive {
  432. miscOutBodyPacketsMeter.Mark(1)
  433. miscOutBodyTrafficMeter.Mark(int64(reply.size()))
  434. miscServingTimeBodyTimer.Update(time.Duration(task.servingTime))
  435. }
  436. }()
  437. }
  438. case GetCodeMsg:
  439. p.Log().Trace("Received code request")
  440. if metrics.EnabledExpensive {
  441. miscInCodePacketsMeter.Mark(1)
  442. miscInCodeTrafficMeter.Mark(int64(msg.Size))
  443. }
  444. var req struct {
  445. ReqID uint64
  446. Reqs []CodeReq
  447. }
  448. if err := msg.Decode(&req); err != nil {
  449. clientErrorMeter.Mark(1)
  450. return errResp(ErrDecode, "msg %v: %v", msg, err)
  451. }
  452. var (
  453. bytes int
  454. data [][]byte
  455. )
  456. reqCnt := len(req.Reqs)
  457. if accept(req.ReqID, uint64(reqCnt), MaxCodeFetch) {
  458. wg.Add(1)
  459. go func() {
  460. defer wg.Done()
  461. for i, request := range req.Reqs {
  462. if i != 0 && !task.waitOrStop() {
  463. sendResponse(req.ReqID, 0, nil, task.servingTime)
  464. return
  465. }
  466. // Look up the root hash belonging to the request
  467. header := h.blockchain.GetHeaderByHash(request.BHash)
  468. if header == nil {
  469. p.Log().Warn("Failed to retrieve associate header for code", "hash", request.BHash)
  470. p.bumpInvalid()
  471. continue
  472. }
  473. // Refuse to search stale state data in the database since looking for
  474. // a non-exist key is kind of expensive.
  475. local := h.blockchain.CurrentHeader().Number.Uint64()
  476. if !h.server.archiveMode && header.Number.Uint64()+core.TriesInMemory <= local {
  477. p.Log().Debug("Reject stale code request", "number", header.Number.Uint64(), "head", local)
  478. p.bumpInvalid()
  479. continue
  480. }
  481. triedb := h.blockchain.StateCache().TrieDB()
  482. account, err := h.getAccount(triedb, header.Root, common.BytesToHash(request.AccKey))
  483. if err != nil {
  484. p.Log().Warn("Failed to retrieve account for code", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(request.AccKey), "err", err)
  485. p.bumpInvalid()
  486. continue
  487. }
  488. code, err := h.blockchain.StateCache().ContractCode(common.BytesToHash(request.AccKey), common.BytesToHash(account.CodeHash))
  489. if err != nil {
  490. p.Log().Warn("Failed to retrieve account code", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(request.AccKey), "codehash", common.BytesToHash(account.CodeHash), "err", err)
  491. continue
  492. }
  493. // Accumulate the code and abort if enough data was retrieved
  494. data = append(data, code)
  495. if bytes += len(code); bytes >= softResponseLimit {
  496. break
  497. }
  498. }
  499. reply := p.replyCode(req.ReqID, data)
  500. sendResponse(req.ReqID, uint64(reqCnt), reply, task.done())
  501. if metrics.EnabledExpensive {
  502. miscOutCodePacketsMeter.Mark(1)
  503. miscOutCodeTrafficMeter.Mark(int64(reply.size()))
  504. miscServingTimeCodeTimer.Update(time.Duration(task.servingTime))
  505. }
  506. }()
  507. }
  508. case GetReceiptsMsg:
  509. p.Log().Trace("Received receipts request")
  510. if metrics.EnabledExpensive {
  511. miscInReceiptPacketsMeter.Mark(1)
  512. miscInReceiptTrafficMeter.Mark(int64(msg.Size))
  513. }
  514. var req struct {
  515. ReqID uint64
  516. Hashes []common.Hash
  517. }
  518. if err := msg.Decode(&req); err != nil {
  519. clientErrorMeter.Mark(1)
  520. return errResp(ErrDecode, "msg %v: %v", msg, err)
  521. }
  522. var (
  523. bytes int
  524. receipts []rlp.RawValue
  525. )
  526. reqCnt := len(req.Hashes)
  527. if accept(req.ReqID, uint64(reqCnt), MaxReceiptFetch) {
  528. wg.Add(1)
  529. go func() {
  530. defer wg.Done()
  531. for i, hash := range req.Hashes {
  532. if i != 0 && !task.waitOrStop() {
  533. sendResponse(req.ReqID, 0, nil, task.servingTime)
  534. return
  535. }
  536. if bytes >= softResponseLimit {
  537. break
  538. }
  539. // Retrieve the requested block's receipts, skipping if unknown to us
  540. results := h.blockchain.GetReceiptsByHash(hash)
  541. if results == nil {
  542. if header := h.blockchain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash {
  543. p.bumpInvalid()
  544. continue
  545. }
  546. }
  547. // If known, encode and queue for response packet
  548. if encoded, err := rlp.EncodeToBytes(results); err != nil {
  549. log.Error("Failed to encode receipt", "err", err)
  550. } else {
  551. receipts = append(receipts, encoded)
  552. bytes += len(encoded)
  553. }
  554. }
  555. reply := p.replyReceiptsRLP(req.ReqID, receipts)
  556. sendResponse(req.ReqID, uint64(reqCnt), reply, task.done())
  557. if metrics.EnabledExpensive {
  558. miscOutReceiptPacketsMeter.Mark(1)
  559. miscOutReceiptTrafficMeter.Mark(int64(reply.size()))
  560. miscServingTimeReceiptTimer.Update(time.Duration(task.servingTime))
  561. }
  562. }()
  563. }
  564. case GetProofsV2Msg:
  565. p.Log().Trace("Received les/2 proofs request")
  566. if metrics.EnabledExpensive {
  567. miscInTrieProofPacketsMeter.Mark(1)
  568. miscInTrieProofTrafficMeter.Mark(int64(msg.Size))
  569. }
  570. var req struct {
  571. ReqID uint64
  572. Reqs []ProofReq
  573. }
  574. if err := msg.Decode(&req); err != nil {
  575. clientErrorMeter.Mark(1)
  576. return errResp(ErrDecode, "msg %v: %v", msg, err)
  577. }
  578. // Gather state data until the fetch or network limits is reached
  579. var (
  580. lastBHash common.Hash
  581. root common.Hash
  582. )
  583. reqCnt := len(req.Reqs)
  584. if accept(req.ReqID, uint64(reqCnt), MaxProofsFetch) {
  585. wg.Add(1)
  586. go func() {
  587. defer wg.Done()
  588. nodes := light.NewNodeSet()
  589. for i, request := range req.Reqs {
  590. if i != 0 && !task.waitOrStop() {
  591. sendResponse(req.ReqID, 0, nil, task.servingTime)
  592. return
  593. }
  594. // Look up the root hash belonging to the request
  595. var (
  596. header *types.Header
  597. trie state.Trie
  598. )
  599. if request.BHash != lastBHash {
  600. root, lastBHash = common.Hash{}, request.BHash
  601. if header = h.blockchain.GetHeaderByHash(request.BHash); header == nil {
  602. p.Log().Warn("Failed to retrieve header for proof", "hash", request.BHash)
  603. p.bumpInvalid()
  604. continue
  605. }
  606. // Refuse to search stale state data in the database since looking for
  607. // a non-exist key is kind of expensive.
  608. local := h.blockchain.CurrentHeader().Number.Uint64()
  609. if !h.server.archiveMode && header.Number.Uint64()+core.TriesInMemory <= local {
  610. p.Log().Debug("Reject stale trie request", "number", header.Number.Uint64(), "head", local)
  611. p.bumpInvalid()
  612. continue
  613. }
  614. root = header.Root
  615. }
  616. // If a header lookup failed (non existent), ignore subsequent requests for the same header
  617. if root == (common.Hash{}) {
  618. p.bumpInvalid()
  619. continue
  620. }
  621. // Open the account or storage trie for the request
  622. statedb := h.blockchain.StateCache()
  623. switch len(request.AccKey) {
  624. case 0:
  625. // No account key specified, open an account trie
  626. trie, err = statedb.OpenTrie(root)
  627. if trie == nil || err != nil {
  628. p.Log().Warn("Failed to open storage trie for proof", "block", header.Number, "hash", header.Hash(), "root", root, "err", err)
  629. continue
  630. }
  631. default:
  632. // Account key specified, open a storage trie
  633. account, err := h.getAccount(statedb.TrieDB(), root, common.BytesToHash(request.AccKey))
  634. if err != nil {
  635. p.Log().Warn("Failed to retrieve account for proof", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(request.AccKey), "err", err)
  636. p.bumpInvalid()
  637. continue
  638. }
  639. trie, err = statedb.OpenStorageTrie(common.BytesToHash(request.AccKey), account.Root)
  640. if trie == nil || err != nil {
  641. p.Log().Warn("Failed to open storage trie for proof", "block", header.Number, "hash", header.Hash(), "account", common.BytesToHash(request.AccKey), "root", account.Root, "err", err)
  642. continue
  643. }
  644. }
  645. // Prove the user's request from the account or stroage trie
  646. if err := trie.Prove(request.Key, request.FromLevel, nodes); err != nil {
  647. p.Log().Warn("Failed to prove state request", "block", header.Number, "hash", header.Hash(), "err", err)
  648. continue
  649. }
  650. if nodes.DataSize() >= softResponseLimit {
  651. break
  652. }
  653. }
  654. reply := p.replyProofsV2(req.ReqID, nodes.NodeList())
  655. sendResponse(req.ReqID, uint64(reqCnt), reply, task.done())
  656. if metrics.EnabledExpensive {
  657. miscOutTrieProofPacketsMeter.Mark(1)
  658. miscOutTrieProofTrafficMeter.Mark(int64(reply.size()))
  659. miscServingTimeTrieProofTimer.Update(time.Duration(task.servingTime))
  660. }
  661. }()
  662. }
  663. case GetHelperTrieProofsMsg:
  664. p.Log().Trace("Received helper trie proof request")
  665. if metrics.EnabledExpensive {
  666. miscInHelperTriePacketsMeter.Mark(1)
  667. miscInHelperTrieTrafficMeter.Mark(int64(msg.Size))
  668. }
  669. var req struct {
  670. ReqID uint64
  671. Reqs []HelperTrieReq
  672. }
  673. if err := msg.Decode(&req); err != nil {
  674. clientErrorMeter.Mark(1)
  675. return errResp(ErrDecode, "msg %v: %v", msg, err)
  676. }
  677. // Gather state data until the fetch or network limits is reached
  678. var (
  679. auxBytes int
  680. auxData [][]byte
  681. )
  682. reqCnt := len(req.Reqs)
  683. if accept(req.ReqID, uint64(reqCnt), MaxHelperTrieProofsFetch) {
  684. wg.Add(1)
  685. go func() {
  686. defer wg.Done()
  687. var (
  688. lastIdx uint64
  689. lastType uint
  690. root common.Hash
  691. auxTrie *trie.Trie
  692. )
  693. nodes := light.NewNodeSet()
  694. for i, request := range req.Reqs {
  695. if i != 0 && !task.waitOrStop() {
  696. sendResponse(req.ReqID, 0, nil, task.servingTime)
  697. return
  698. }
  699. if auxTrie == nil || request.Type != lastType || request.TrieIdx != lastIdx {
  700. auxTrie, lastType, lastIdx = nil, request.Type, request.TrieIdx
  701. var prefix string
  702. if root, prefix = h.getHelperTrie(request.Type, request.TrieIdx); root != (common.Hash{}) {
  703. auxTrie, _ = trie.New(root, trie.NewDatabase(rawdb.NewTable(h.chainDb, prefix)))
  704. }
  705. }
  706. if request.AuxReq == auxRoot {
  707. var data []byte
  708. if root != (common.Hash{}) {
  709. data = root[:]
  710. }
  711. auxData = append(auxData, data)
  712. auxBytes += len(data)
  713. } else {
  714. if auxTrie != nil {
  715. auxTrie.Prove(request.Key, request.FromLevel, nodes)
  716. }
  717. if request.AuxReq != 0 {
  718. data := h.getAuxiliaryHeaders(request)
  719. auxData = append(auxData, data)
  720. auxBytes += len(data)
  721. }
  722. }
  723. if nodes.DataSize()+auxBytes >= softResponseLimit {
  724. break
  725. }
  726. }
  727. reply := p.replyHelperTrieProofs(req.ReqID, HelperTrieResps{Proofs: nodes.NodeList(), AuxData: auxData})
  728. sendResponse(req.ReqID, uint64(reqCnt), reply, task.done())
  729. if metrics.EnabledExpensive {
  730. miscOutHelperTriePacketsMeter.Mark(1)
  731. miscOutHelperTrieTrafficMeter.Mark(int64(reply.size()))
  732. miscServingTimeHelperTrieTimer.Update(time.Duration(task.servingTime))
  733. }
  734. }()
  735. }
  736. case SendTxV2Msg:
  737. p.Log().Trace("Received new transactions")
  738. if metrics.EnabledExpensive {
  739. miscInTxsPacketsMeter.Mark(1)
  740. miscInTxsTrafficMeter.Mark(int64(msg.Size))
  741. }
  742. var req struct {
  743. ReqID uint64
  744. Txs []*types.Transaction
  745. }
  746. if err := msg.Decode(&req); err != nil {
  747. clientErrorMeter.Mark(1)
  748. return errResp(ErrDecode, "msg %v: %v", msg, err)
  749. }
  750. reqCnt := len(req.Txs)
  751. if accept(req.ReqID, uint64(reqCnt), MaxTxSend) {
  752. wg.Add(1)
  753. go func() {
  754. defer wg.Done()
  755. stats := make([]light.TxStatus, len(req.Txs))
  756. for i, tx := range req.Txs {
  757. if i != 0 && !task.waitOrStop() {
  758. return
  759. }
  760. hash := tx.Hash()
  761. stats[i] = h.txStatus(hash)
  762. if stats[i].Status == core.TxStatusUnknown {
  763. addFn := h.txpool.AddRemotes
  764. // Add txs synchronously for testing purpose
  765. if h.addTxsSync {
  766. addFn = h.txpool.AddRemotesSync
  767. }
  768. if errs := addFn([]*types.Transaction{tx}); errs[0] != nil {
  769. stats[i].Error = errs[0].Error()
  770. continue
  771. }
  772. stats[i] = h.txStatus(hash)
  773. }
  774. }
  775. reply := p.replyTxStatus(req.ReqID, stats)
  776. sendResponse(req.ReqID, uint64(reqCnt), reply, task.done())
  777. if metrics.EnabledExpensive {
  778. miscOutTxsPacketsMeter.Mark(1)
  779. miscOutTxsTrafficMeter.Mark(int64(reply.size()))
  780. miscServingTimeTxTimer.Update(time.Duration(task.servingTime))
  781. }
  782. }()
  783. }
  784. case GetTxStatusMsg:
  785. p.Log().Trace("Received transaction status query request")
  786. if metrics.EnabledExpensive {
  787. miscInTxStatusPacketsMeter.Mark(1)
  788. miscInTxStatusTrafficMeter.Mark(int64(msg.Size))
  789. }
  790. var req struct {
  791. ReqID uint64
  792. Hashes []common.Hash
  793. }
  794. if err := msg.Decode(&req); err != nil {
  795. clientErrorMeter.Mark(1)
  796. return errResp(ErrDecode, "msg %v: %v", msg, err)
  797. }
  798. reqCnt := len(req.Hashes)
  799. if accept(req.ReqID, uint64(reqCnt), MaxTxStatus) {
  800. wg.Add(1)
  801. go func() {
  802. defer wg.Done()
  803. stats := make([]light.TxStatus, len(req.Hashes))
  804. for i, hash := range req.Hashes {
  805. if i != 0 && !task.waitOrStop() {
  806. sendResponse(req.ReqID, 0, nil, task.servingTime)
  807. return
  808. }
  809. stats[i] = h.txStatus(hash)
  810. }
  811. reply := p.replyTxStatus(req.ReqID, stats)
  812. sendResponse(req.ReqID, uint64(reqCnt), reply, task.done())
  813. if metrics.EnabledExpensive {
  814. miscOutTxStatusPacketsMeter.Mark(1)
  815. miscOutTxStatusTrafficMeter.Mark(int64(reply.size()))
  816. miscServingTimeTxStatusTimer.Update(time.Duration(task.servingTime))
  817. }
  818. }()
  819. }
  820. default:
  821. p.Log().Trace("Received invalid message", "code", msg.Code)
  822. clientErrorMeter.Mark(1)
  823. return errResp(ErrInvalidMsgCode, "%v", msg.Code)
  824. }
  825. // If the client has made too much invalid request(e.g. request a non-existent data),
  826. // reject them to prevent SPAM attack.
  827. if p.getInvalid() > maxRequestErrors {
  828. clientErrorMeter.Mark(1)
  829. return errTooManyInvalidRequest
  830. }
  831. return nil
  832. }
  833. // getAccount retrieves an account from the state based on root.
  834. func (h *serverHandler) getAccount(triedb *trie.Database, root, hash common.Hash) (state.Account, error) {
  835. trie, err := trie.New(root, triedb)
  836. if err != nil {
  837. return state.Account{}, err
  838. }
  839. blob, err := trie.TryGet(hash[:])
  840. if err != nil {
  841. return state.Account{}, err
  842. }
  843. var account state.Account
  844. if err = rlp.DecodeBytes(blob, &account); err != nil {
  845. return state.Account{}, err
  846. }
  847. return account, nil
  848. }
  849. // getHelperTrie returns the post-processed trie root for the given trie ID and section index
  850. func (h *serverHandler) getHelperTrie(typ uint, index uint64) (common.Hash, string) {
  851. switch typ {
  852. case htCanonical:
  853. sectionHead := rawdb.ReadCanonicalHash(h.chainDb, (index+1)*h.server.iConfig.ChtSize-1)
  854. return light.GetChtRoot(h.chainDb, index, sectionHead), light.ChtTablePrefix
  855. case htBloomBits:
  856. sectionHead := rawdb.ReadCanonicalHash(h.chainDb, (index+1)*h.server.iConfig.BloomTrieSize-1)
  857. return light.GetBloomTrieRoot(h.chainDb, index, sectionHead), light.BloomTrieTablePrefix
  858. }
  859. return common.Hash{}, ""
  860. }
  861. // getAuxiliaryHeaders returns requested auxiliary headers for the CHT request.
  862. func (h *serverHandler) getAuxiliaryHeaders(req HelperTrieReq) []byte {
  863. if req.Type == htCanonical && req.AuxReq == auxHeader && len(req.Key) == 8 {
  864. blockNum := binary.BigEndian.Uint64(req.Key)
  865. hash := rawdb.ReadCanonicalHash(h.chainDb, blockNum)
  866. return rawdb.ReadHeaderRLP(h.chainDb, hash, blockNum)
  867. }
  868. return nil
  869. }
  870. // txStatus returns the status of a specified transaction.
  871. func (h *serverHandler) txStatus(hash common.Hash) light.TxStatus {
  872. var stat light.TxStatus
  873. // Looking the transaction in txpool first.
  874. stat.Status = h.txpool.Status([]common.Hash{hash})[0]
  875. // If the transaction is unknown to the pool, try looking it up locally.
  876. if stat.Status == core.TxStatusUnknown {
  877. lookup := h.blockchain.GetTransactionLookup(hash)
  878. if lookup != nil {
  879. stat.Status = core.TxStatusIncluded
  880. stat.Lookup = lookup
  881. }
  882. }
  883. return stat
  884. }
  885. // broadcastLoop broadcasts new block information to all connected light
  886. // clients. According to the agreement between client and server, server should
  887. // only broadcast new announcement if the total difficulty is higher than the
  888. // last one. Besides server will add the signature if client requires.
  889. func (h *serverHandler) broadcastLoop() {
  890. defer h.wg.Done()
  891. headCh := make(chan core.ChainHeadEvent, 10)
  892. headSub := h.blockchain.SubscribeChainHeadEvent(headCh)
  893. defer headSub.Unsubscribe()
  894. var (
  895. lastHead *types.Header
  896. lastTd = common.Big0
  897. )
  898. for {
  899. select {
  900. case ev := <-headCh:
  901. header := ev.Block.Header()
  902. hash, number := header.Hash(), header.Number.Uint64()
  903. td := h.blockchain.GetTd(hash, number)
  904. if td == nil || td.Cmp(lastTd) <= 0 {
  905. continue
  906. }
  907. var reorg uint64
  908. if lastHead != nil {
  909. reorg = lastHead.Number.Uint64() - rawdb.FindCommonAncestor(h.chainDb, header, lastHead).Number.Uint64()
  910. }
  911. lastHead, lastTd = header, td
  912. log.Debug("Announcing block to peers", "number", number, "hash", hash, "td", td, "reorg", reorg)
  913. h.server.broadcaster.broadcast(announceData{Hash: hash, Number: number, Td: td, ReorgDepth: reorg})
  914. case <-h.closeCh:
  915. return
  916. }
  917. }
  918. }
  919. // broadcaster sends new header announcements to active client peers
  920. type broadcaster struct {
  921. ns *nodestate.NodeStateMachine
  922. privateKey *ecdsa.PrivateKey
  923. lastAnnounce, signedAnnounce announceData
  924. }
  925. // newBroadcaster creates a new broadcaster
  926. func newBroadcaster(ns *nodestate.NodeStateMachine) *broadcaster {
  927. b := &broadcaster{ns: ns}
  928. ns.SubscribeState(priorityPoolSetup.ActiveFlag, func(node *enode.Node, oldState, newState nodestate.Flags) {
  929. if newState.Equals(priorityPoolSetup.ActiveFlag) {
  930. // send last announcement to activated peers
  931. b.sendTo(node)
  932. }
  933. })
  934. return b
  935. }
  936. // setSignerKey sets the signer key for signed announcements. Should be called before
  937. // starting the protocol handler.
  938. func (b *broadcaster) setSignerKey(privateKey *ecdsa.PrivateKey) {
  939. b.privateKey = privateKey
  940. }
  941. // broadcast sends the given announcements to all active peers
  942. func (b *broadcaster) broadcast(announce announceData) {
  943. b.ns.Operation(func() {
  944. // iterate in an Operation to ensure that the active set does not change while iterating
  945. b.lastAnnounce = announce
  946. b.ns.ForEach(priorityPoolSetup.ActiveFlag, nodestate.Flags{}, func(node *enode.Node, state nodestate.Flags) {
  947. b.sendTo(node)
  948. })
  949. })
  950. }
  951. // sendTo sends the most recent announcement to the given node unless the same or higher Td
  952. // announcement has already been sent.
  953. func (b *broadcaster) sendTo(node *enode.Node) {
  954. if b.lastAnnounce.Td == nil {
  955. return
  956. }
  957. if p, _ := b.ns.GetField(node, clientPeerField).(*clientPeer); p != nil {
  958. if p.headInfo.Td == nil || b.lastAnnounce.Td.Cmp(p.headInfo.Td) > 0 {
  959. announce := b.lastAnnounce
  960. switch p.announceType {
  961. case announceTypeSimple:
  962. if !p.queueSend(func() { p.sendAnnounce(announce) }) {
  963. log.Debug("Drop announcement because queue is full", "number", announce.Number, "hash", announce.Hash)
  964. } else {
  965. log.Debug("Sent announcement", "number", announce.Number, "hash", announce.Hash)
  966. }
  967. case announceTypeSigned:
  968. if b.signedAnnounce.Hash != b.lastAnnounce.Hash {
  969. b.signedAnnounce = b.lastAnnounce
  970. b.signedAnnounce.sign(b.privateKey)
  971. }
  972. announce := b.signedAnnounce
  973. if !p.queueSend(func() { p.sendAnnounce(announce) }) {
  974. log.Debug("Drop announcement because queue is full", "number", announce.Number, "hash", announce.Hash)
  975. } else {
  976. log.Debug("Sent announcement", "number", announce.Number, "hash", announce.Hash)
  977. }
  978. }
  979. p.headInfo = blockInfo{b.lastAnnounce.Hash, b.lastAnnounce.Number, b.lastAnnounce.Td}
  980. }
  981. }
  982. }