server.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. // Copyright 2016 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 implements the Light Ethereum Subprotocol.
  17. package les
  18. import (
  19. "encoding/binary"
  20. "math"
  21. "sync"
  22. "time"
  23. "github.com/ethereum/go-ethereum/common"
  24. "github.com/ethereum/go-ethereum/core"
  25. "github.com/ethereum/go-ethereum/core/types"
  26. "github.com/ethereum/go-ethereum/eth"
  27. "github.com/ethereum/go-ethereum/ethdb"
  28. "github.com/ethereum/go-ethereum/les/flowcontrol"
  29. "github.com/ethereum/go-ethereum/light"
  30. "github.com/ethereum/go-ethereum/logger"
  31. "github.com/ethereum/go-ethereum/logger/glog"
  32. "github.com/ethereum/go-ethereum/p2p"
  33. "github.com/ethereum/go-ethereum/rlp"
  34. "github.com/ethereum/go-ethereum/trie"
  35. )
  36. type LesServer struct {
  37. protocolManager *ProtocolManager
  38. fcManager *flowcontrol.ClientManager // nil if our node is client only
  39. fcCostStats *requestCostStats
  40. defParams *flowcontrol.ServerParams
  41. srvr *p2p.Server
  42. synced, stopped bool
  43. lock sync.Mutex
  44. }
  45. func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) {
  46. pm, err := NewProtocolManager(config.ChainConfig, false, config.NetworkId, eth.EventMux(), eth.Pow(), eth.BlockChain(), eth.TxPool(), eth.ChainDb(), nil, nil)
  47. if err != nil {
  48. return nil, err
  49. }
  50. pm.blockLoop()
  51. srv := &LesServer{protocolManager: pm}
  52. pm.server = srv
  53. srv.defParams = &flowcontrol.ServerParams{
  54. BufLimit: 300000000,
  55. MinRecharge: 50000,
  56. }
  57. srv.fcManager = flowcontrol.NewClientManager(uint64(config.LightServ), 10, 1000000000)
  58. srv.fcCostStats = newCostStats(eth.ChainDb())
  59. return srv, nil
  60. }
  61. func (s *LesServer) Protocols() []p2p.Protocol {
  62. return s.protocolManager.SubProtocols
  63. }
  64. // Start only starts the actual service if the ETH protocol has already been synced,
  65. // otherwise it will be started by Synced()
  66. func (s *LesServer) Start(srvr *p2p.Server) {
  67. s.lock.Lock()
  68. defer s.lock.Unlock()
  69. s.srvr = srvr
  70. if s.synced {
  71. s.protocolManager.Start(s.srvr)
  72. }
  73. }
  74. // Synced notifies the server that the ETH protocol has been synced and LES service can be started
  75. func (s *LesServer) Synced() {
  76. s.lock.Lock()
  77. defer s.lock.Unlock()
  78. s.synced = true
  79. if s.srvr != nil && !s.stopped {
  80. s.protocolManager.Start(s.srvr)
  81. }
  82. }
  83. // Stop stops the LES service
  84. func (s *LesServer) Stop() {
  85. s.lock.Lock()
  86. defer s.lock.Unlock()
  87. s.stopped = true
  88. s.fcCostStats.store()
  89. s.fcManager.Stop()
  90. go func() {
  91. <-s.protocolManager.noMorePeers
  92. }()
  93. s.protocolManager.Stop()
  94. }
  95. type requestCosts struct {
  96. baseCost, reqCost uint64
  97. }
  98. type requestCostTable map[uint64]*requestCosts
  99. type RequestCostList []struct {
  100. MsgCode, BaseCost, ReqCost uint64
  101. }
  102. func (list RequestCostList) decode() requestCostTable {
  103. table := make(requestCostTable)
  104. for _, e := range list {
  105. table[e.MsgCode] = &requestCosts{
  106. baseCost: e.BaseCost,
  107. reqCost: e.ReqCost,
  108. }
  109. }
  110. return table
  111. }
  112. func (table requestCostTable) encode() RequestCostList {
  113. list := make(RequestCostList, len(table))
  114. for idx, code := range reqList {
  115. list[idx].MsgCode = code
  116. list[idx].BaseCost = table[code].baseCost
  117. list[idx].ReqCost = table[code].reqCost
  118. }
  119. return list
  120. }
  121. type linReg struct {
  122. sumX, sumY, sumXX, sumXY float64
  123. cnt uint64
  124. }
  125. const linRegMaxCnt = 100000
  126. func (l *linReg) add(x, y float64) {
  127. if l.cnt >= linRegMaxCnt {
  128. sub := float64(l.cnt+1-linRegMaxCnt) / linRegMaxCnt
  129. l.sumX -= l.sumX * sub
  130. l.sumY -= l.sumY * sub
  131. l.sumXX -= l.sumXX * sub
  132. l.sumXY -= l.sumXY * sub
  133. l.cnt = linRegMaxCnt - 1
  134. }
  135. l.cnt++
  136. l.sumX += x
  137. l.sumY += y
  138. l.sumXX += x * x
  139. l.sumXY += x * y
  140. }
  141. func (l *linReg) calc() (b, m float64) {
  142. if l.cnt == 0 {
  143. return 0, 0
  144. }
  145. cnt := float64(l.cnt)
  146. d := cnt*l.sumXX - l.sumX*l.sumX
  147. if d < 0.001 {
  148. return l.sumY / cnt, 0
  149. }
  150. m = (cnt*l.sumXY - l.sumX*l.sumY) / d
  151. b = (l.sumY / cnt) - (m * l.sumX / cnt)
  152. return b, m
  153. }
  154. func (l *linReg) toBytes() []byte {
  155. var arr [40]byte
  156. binary.BigEndian.PutUint64(arr[0:8], math.Float64bits(l.sumX))
  157. binary.BigEndian.PutUint64(arr[8:16], math.Float64bits(l.sumY))
  158. binary.BigEndian.PutUint64(arr[16:24], math.Float64bits(l.sumXX))
  159. binary.BigEndian.PutUint64(arr[24:32], math.Float64bits(l.sumXY))
  160. binary.BigEndian.PutUint64(arr[32:40], l.cnt)
  161. return arr[:]
  162. }
  163. func linRegFromBytes(data []byte) *linReg {
  164. if len(data) != 40 {
  165. return nil
  166. }
  167. l := &linReg{}
  168. l.sumX = math.Float64frombits(binary.BigEndian.Uint64(data[0:8]))
  169. l.sumY = math.Float64frombits(binary.BigEndian.Uint64(data[8:16]))
  170. l.sumXX = math.Float64frombits(binary.BigEndian.Uint64(data[16:24]))
  171. l.sumXY = math.Float64frombits(binary.BigEndian.Uint64(data[24:32]))
  172. l.cnt = binary.BigEndian.Uint64(data[32:40])
  173. return l
  174. }
  175. type requestCostStats struct {
  176. lock sync.RWMutex
  177. db ethdb.Database
  178. stats map[uint64]*linReg
  179. }
  180. type requestCostStatsRlp []struct {
  181. MsgCode uint64
  182. Data []byte
  183. }
  184. var rcStatsKey = []byte("_requestCostStats")
  185. func newCostStats(db ethdb.Database) *requestCostStats {
  186. stats := make(map[uint64]*linReg)
  187. for _, code := range reqList {
  188. stats[code] = &linReg{cnt: 100}
  189. }
  190. if db != nil {
  191. data, err := db.Get(rcStatsKey)
  192. var statsRlp requestCostStatsRlp
  193. if err == nil {
  194. err = rlp.DecodeBytes(data, &statsRlp)
  195. }
  196. if err == nil {
  197. for _, r := range statsRlp {
  198. if stats[r.MsgCode] != nil {
  199. if l := linRegFromBytes(r.Data); l != nil {
  200. stats[r.MsgCode] = l
  201. }
  202. }
  203. }
  204. }
  205. }
  206. return &requestCostStats{
  207. db: db,
  208. stats: stats,
  209. }
  210. }
  211. func (s *requestCostStats) store() {
  212. s.lock.Lock()
  213. defer s.lock.Unlock()
  214. statsRlp := make(requestCostStatsRlp, len(reqList))
  215. for i, code := range reqList {
  216. statsRlp[i].MsgCode = code
  217. statsRlp[i].Data = s.stats[code].toBytes()
  218. }
  219. if data, err := rlp.EncodeToBytes(statsRlp); err == nil {
  220. s.db.Put(rcStatsKey, data)
  221. }
  222. }
  223. func (s *requestCostStats) getCurrentList() RequestCostList {
  224. s.lock.Lock()
  225. defer s.lock.Unlock()
  226. list := make(RequestCostList, len(reqList))
  227. //fmt.Println("RequestCostList")
  228. for idx, code := range reqList {
  229. b, m := s.stats[code].calc()
  230. //fmt.Println(code, s.stats[code].cnt, b/1000000, m/1000000)
  231. if m < 0 {
  232. b += m
  233. m = 0
  234. }
  235. if b < 0 {
  236. b = 0
  237. }
  238. list[idx].MsgCode = code
  239. list[idx].BaseCost = uint64(b * 2)
  240. list[idx].ReqCost = uint64(m * 2)
  241. }
  242. return list
  243. }
  244. func (s *requestCostStats) update(msgCode, reqCnt, cost uint64) {
  245. s.lock.Lock()
  246. defer s.lock.Unlock()
  247. c, ok := s.stats[msgCode]
  248. if !ok || reqCnt == 0 {
  249. return
  250. }
  251. c.add(float64(reqCnt), float64(cost))
  252. }
  253. func (pm *ProtocolManager) blockLoop() {
  254. pm.wg.Add(1)
  255. sub := pm.eventMux.Subscribe(core.ChainHeadEvent{})
  256. newCht := make(chan struct{}, 10)
  257. newCht <- struct{}{}
  258. go func() {
  259. var mu sync.Mutex
  260. var lastHead *types.Header
  261. lastBroadcastTd := common.Big0
  262. for {
  263. select {
  264. case ev := <-sub.Chan():
  265. peers := pm.peers.AllPeers()
  266. if len(peers) > 0 {
  267. header := ev.Data.(core.ChainHeadEvent).Block.Header()
  268. hash := header.Hash()
  269. number := header.Number.Uint64()
  270. td := core.GetTd(pm.chainDb, hash, number)
  271. if td != nil && td.Cmp(lastBroadcastTd) > 0 {
  272. var reorg uint64
  273. if lastHead != nil {
  274. reorg = lastHead.Number.Uint64() - core.FindCommonAncestor(pm.chainDb, header, lastHead).Number.Uint64()
  275. }
  276. lastHead = header
  277. lastBroadcastTd = td
  278. glog.V(logger.Debug).Infoln("===> ", number, hash, td, reorg)
  279. announce := announceData{Hash: hash, Number: number, Td: td, ReorgDepth: reorg}
  280. for _, p := range peers {
  281. select {
  282. case p.announceChn <- announce:
  283. default:
  284. pm.removePeer(p.id)
  285. }
  286. }
  287. }
  288. }
  289. newCht <- struct{}{}
  290. case <-newCht:
  291. go func() {
  292. mu.Lock()
  293. more := makeCht(pm.chainDb)
  294. mu.Unlock()
  295. if more {
  296. time.Sleep(time.Millisecond * 10)
  297. newCht <- struct{}{}
  298. }
  299. }()
  300. case <-pm.quitSync:
  301. sub.Unsubscribe()
  302. pm.wg.Done()
  303. return
  304. }
  305. }
  306. }()
  307. }
  308. var (
  309. lastChtKey = []byte("LastChtNumber") // chtNum (uint64 big endian)
  310. chtPrefix = []byte("cht") // chtPrefix + chtNum (uint64 big endian) -> trie root hash
  311. )
  312. func getChtRoot(db ethdb.Database, num uint64) common.Hash {
  313. var encNumber [8]byte
  314. binary.BigEndian.PutUint64(encNumber[:], num)
  315. data, _ := db.Get(append(chtPrefix, encNumber[:]...))
  316. return common.BytesToHash(data)
  317. }
  318. func storeChtRoot(db ethdb.Database, num uint64, root common.Hash) {
  319. var encNumber [8]byte
  320. binary.BigEndian.PutUint64(encNumber[:], num)
  321. db.Put(append(chtPrefix, encNumber[:]...), root[:])
  322. }
  323. func makeCht(db ethdb.Database) bool {
  324. headHash := core.GetHeadBlockHash(db)
  325. headNum := core.GetBlockNumber(db, headHash)
  326. var newChtNum uint64
  327. if headNum > light.ChtConfirmations {
  328. newChtNum = (headNum - light.ChtConfirmations) / light.ChtFrequency
  329. }
  330. var lastChtNum uint64
  331. data, _ := db.Get(lastChtKey)
  332. if len(data) == 8 {
  333. lastChtNum = binary.BigEndian.Uint64(data[:])
  334. }
  335. if newChtNum <= lastChtNum {
  336. return false
  337. }
  338. var t *trie.Trie
  339. if lastChtNum > 0 {
  340. var err error
  341. t, err = trie.New(getChtRoot(db, lastChtNum), db)
  342. if err != nil {
  343. lastChtNum = 0
  344. }
  345. }
  346. if lastChtNum == 0 {
  347. t, _ = trie.New(common.Hash{}, db)
  348. }
  349. for num := lastChtNum * light.ChtFrequency; num < (lastChtNum+1)*light.ChtFrequency; num++ {
  350. hash := core.GetCanonicalHash(db, num)
  351. if hash == (common.Hash{}) {
  352. panic("Canonical hash not found")
  353. }
  354. td := core.GetTd(db, hash, num)
  355. if td == nil {
  356. panic("TD not found")
  357. }
  358. var encNumber [8]byte
  359. binary.BigEndian.PutUint64(encNumber[:], num)
  360. var node light.ChtNode
  361. node.Hash = hash
  362. node.Td = td
  363. data, _ := rlp.EncodeToBytes(node)
  364. t.Update(encNumber[:], data)
  365. }
  366. root, err := t.Commit()
  367. if err != nil {
  368. lastChtNum = 0
  369. } else {
  370. lastChtNum++
  371. glog.V(logger.Detail).Infof("cht: %d %064x", lastChtNum, root)
  372. storeChtRoot(db, lastChtNum, root)
  373. var data [8]byte
  374. binary.BigEndian.PutUint64(data[:], lastChtNum)
  375. db.Put(lastChtKey, data[:])
  376. }
  377. return newChtNum > lastChtNum
  378. }