handler_test.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  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
  17. import (
  18. "encoding/binary"
  19. "math/big"
  20. "math/rand"
  21. "testing"
  22. "time"
  23. "github.com/ethereum/go-ethereum/common"
  24. "github.com/ethereum/go-ethereum/common/mclock"
  25. "github.com/ethereum/go-ethereum/consensus/ethash"
  26. "github.com/ethereum/go-ethereum/core"
  27. "github.com/ethereum/go-ethereum/core/rawdb"
  28. "github.com/ethereum/go-ethereum/core/types"
  29. "github.com/ethereum/go-ethereum/crypto"
  30. "github.com/ethereum/go-ethereum/eth/downloader"
  31. "github.com/ethereum/go-ethereum/light"
  32. "github.com/ethereum/go-ethereum/p2p"
  33. "github.com/ethereum/go-ethereum/params"
  34. "github.com/ethereum/go-ethereum/rlp"
  35. "github.com/ethereum/go-ethereum/trie"
  36. )
  37. func expectResponse(r p2p.MsgReader, msgcode, reqID, bv uint64, data interface{}) error {
  38. type resp struct {
  39. ReqID, BV uint64
  40. Data interface{}
  41. }
  42. return p2p.ExpectMsg(r, msgcode, resp{reqID, bv, data})
  43. }
  44. // Tests that block headers can be retrieved from a remote chain based on user queries.
  45. func TestGetBlockHeadersLes2(t *testing.T) { testGetBlockHeaders(t, 2) }
  46. func TestGetBlockHeadersLes3(t *testing.T) { testGetBlockHeaders(t, 3) }
  47. func TestGetBlockHeadersLes4(t *testing.T) { testGetBlockHeaders(t, 4) }
  48. func testGetBlockHeaders(t *testing.T, protocol int) {
  49. netconfig := testnetConfig{
  50. blocks: downloader.MaxHeaderFetch + 15,
  51. protocol: protocol,
  52. nopruning: true,
  53. }
  54. server, _, tearDown := newClientServerEnv(t, netconfig)
  55. defer tearDown()
  56. rawPeer, closePeer, _ := server.newRawPeer(t, "peer", protocol)
  57. defer closePeer()
  58. bc := server.handler.blockchain
  59. // Create a "random" unknown hash for testing
  60. var unknown common.Hash
  61. for i := range unknown {
  62. unknown[i] = byte(i)
  63. }
  64. // Create a batch of tests for various scenarios
  65. limit := uint64(MaxHeaderFetch)
  66. tests := []struct {
  67. query *GetBlockHeadersData // The query to execute for header retrieval
  68. expect []common.Hash // The hashes of the block whose headers are expected
  69. }{
  70. // A single random block should be retrievable by hash and number too
  71. {
  72. &GetBlockHeadersData{Origin: hashOrNumber{Hash: bc.GetBlockByNumber(limit / 2).Hash()}, Amount: 1},
  73. []common.Hash{bc.GetBlockByNumber(limit / 2).Hash()},
  74. }, {
  75. &GetBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 1},
  76. []common.Hash{bc.GetBlockByNumber(limit / 2).Hash()},
  77. },
  78. // Multiple headers should be retrievable in both directions
  79. {
  80. &GetBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3},
  81. []common.Hash{
  82. bc.GetBlockByNumber(limit / 2).Hash(),
  83. bc.GetBlockByNumber(limit/2 + 1).Hash(),
  84. bc.GetBlockByNumber(limit/2 + 2).Hash(),
  85. },
  86. }, {
  87. &GetBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3, Reverse: true},
  88. []common.Hash{
  89. bc.GetBlockByNumber(limit / 2).Hash(),
  90. bc.GetBlockByNumber(limit/2 - 1).Hash(),
  91. bc.GetBlockByNumber(limit/2 - 2).Hash(),
  92. },
  93. },
  94. // Multiple headers with skip lists should be retrievable
  95. {
  96. &GetBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3},
  97. []common.Hash{
  98. bc.GetBlockByNumber(limit / 2).Hash(),
  99. bc.GetBlockByNumber(limit/2 + 4).Hash(),
  100. bc.GetBlockByNumber(limit/2 + 8).Hash(),
  101. },
  102. }, {
  103. &GetBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3, Reverse: true},
  104. []common.Hash{
  105. bc.GetBlockByNumber(limit / 2).Hash(),
  106. bc.GetBlockByNumber(limit/2 - 4).Hash(),
  107. bc.GetBlockByNumber(limit/2 - 8).Hash(),
  108. },
  109. },
  110. // The chain endpoints should be retrievable
  111. {
  112. &GetBlockHeadersData{Origin: hashOrNumber{Number: 0}, Amount: 1},
  113. []common.Hash{bc.GetBlockByNumber(0).Hash()},
  114. }, {
  115. &GetBlockHeadersData{Origin: hashOrNumber{Number: bc.CurrentBlock().NumberU64()}, Amount: 1},
  116. []common.Hash{bc.CurrentBlock().Hash()},
  117. },
  118. // Ensure protocol limits are honored
  119. //{
  120. // &GetBlockHeadersData{Origin: hashOrNumber{Number: bc.CurrentBlock().NumberU64() - 1}, Amount: limit + 10, Reverse: true},
  121. // []common.Hash{},
  122. //},
  123. // Check that requesting more than available is handled gracefully
  124. {
  125. &GetBlockHeadersData{Origin: hashOrNumber{Number: bc.CurrentBlock().NumberU64() - 4}, Skip: 3, Amount: 3},
  126. []common.Hash{
  127. bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - 4).Hash(),
  128. bc.GetBlockByNumber(bc.CurrentBlock().NumberU64()).Hash(),
  129. },
  130. }, {
  131. &GetBlockHeadersData{Origin: hashOrNumber{Number: 4}, Skip: 3, Amount: 3, Reverse: true},
  132. []common.Hash{
  133. bc.GetBlockByNumber(4).Hash(),
  134. bc.GetBlockByNumber(0).Hash(),
  135. },
  136. },
  137. // Check that requesting more than available is handled gracefully, even if mid skip
  138. {
  139. &GetBlockHeadersData{Origin: hashOrNumber{Number: bc.CurrentBlock().NumberU64() - 4}, Skip: 2, Amount: 3},
  140. []common.Hash{
  141. bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - 4).Hash(),
  142. bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - 1).Hash(),
  143. },
  144. }, {
  145. &GetBlockHeadersData{Origin: hashOrNumber{Number: 4}, Skip: 2, Amount: 3, Reverse: true},
  146. []common.Hash{
  147. bc.GetBlockByNumber(4).Hash(),
  148. bc.GetBlockByNumber(1).Hash(),
  149. },
  150. },
  151. // Check that non existing headers aren't returned
  152. {
  153. &GetBlockHeadersData{Origin: hashOrNumber{Hash: unknown}, Amount: 1},
  154. []common.Hash{},
  155. }, {
  156. &GetBlockHeadersData{Origin: hashOrNumber{Number: bc.CurrentBlock().NumberU64() + 1}, Amount: 1},
  157. []common.Hash{},
  158. },
  159. }
  160. // Run each of the tests and verify the results against the chain
  161. var reqID uint64
  162. for i, tt := range tests {
  163. // Collect the headers to expect in the response
  164. var headers []*types.Header
  165. for _, hash := range tt.expect {
  166. headers = append(headers, bc.GetHeaderByHash(hash))
  167. }
  168. // Send the hash request and verify the response
  169. reqID++
  170. sendRequest(rawPeer.app, GetBlockHeadersMsg, reqID, tt.query)
  171. if err := expectResponse(rawPeer.app, BlockHeadersMsg, reqID, testBufLimit, headers); err != nil {
  172. t.Errorf("test %d: headers mismatch: %v", i, err)
  173. }
  174. }
  175. }
  176. // Tests that block contents can be retrieved from a remote chain based on their hashes.
  177. func TestGetBlockBodiesLes2(t *testing.T) { testGetBlockBodies(t, 2) }
  178. func TestGetBlockBodiesLes3(t *testing.T) { testGetBlockBodies(t, 3) }
  179. func TestGetBlockBodiesLes4(t *testing.T) { testGetBlockBodies(t, 4) }
  180. func testGetBlockBodies(t *testing.T, protocol int) {
  181. netconfig := testnetConfig{
  182. blocks: downloader.MaxHeaderFetch + 15,
  183. protocol: protocol,
  184. nopruning: true,
  185. }
  186. server, _, tearDown := newClientServerEnv(t, netconfig)
  187. defer tearDown()
  188. rawPeer, closePeer, _ := server.newRawPeer(t, "peer", protocol)
  189. defer closePeer()
  190. bc := server.handler.blockchain
  191. // Create a batch of tests for various scenarios
  192. limit := MaxBodyFetch
  193. tests := []struct {
  194. random int // Number of blocks to fetch randomly from the chain
  195. explicit []common.Hash // Explicitly requested blocks
  196. available []bool // Availability of explicitly requested blocks
  197. expected int // Total number of existing blocks to expect
  198. }{
  199. {1, nil, nil, 1}, // A single random block should be retrievable
  200. {10, nil, nil, 10}, // Multiple random blocks should be retrievable
  201. {limit, nil, nil, limit}, // The maximum possible blocks should be retrievable
  202. //{limit + 1, nil, nil, limit}, // No more than the possible block count should be returned
  203. {0, []common.Hash{bc.Genesis().Hash()}, []bool{true}, 1}, // The genesis block should be retrievable
  204. {0, []common.Hash{bc.CurrentBlock().Hash()}, []bool{true}, 1}, // The chains head block should be retrievable
  205. {0, []common.Hash{{}}, []bool{false}, 0}, // A non existent block should not be returned
  206. // Existing and non-existing blocks interleaved should not cause problems
  207. {0, []common.Hash{
  208. {},
  209. bc.GetBlockByNumber(1).Hash(),
  210. {},
  211. bc.GetBlockByNumber(10).Hash(),
  212. {},
  213. bc.GetBlockByNumber(100).Hash(),
  214. {},
  215. }, []bool{false, true, false, true, false, true, false}, 3},
  216. }
  217. // Run each of the tests and verify the results against the chain
  218. var reqID uint64
  219. for i, tt := range tests {
  220. // Collect the hashes to request, and the response to expect
  221. var hashes []common.Hash
  222. seen := make(map[int64]bool)
  223. var bodies []*types.Body
  224. for j := 0; j < tt.random; j++ {
  225. for {
  226. num := rand.Int63n(int64(bc.CurrentBlock().NumberU64()))
  227. if !seen[num] {
  228. seen[num] = true
  229. block := bc.GetBlockByNumber(uint64(num))
  230. hashes = append(hashes, block.Hash())
  231. if len(bodies) < tt.expected {
  232. bodies = append(bodies, &types.Body{Transactions: block.Transactions(), Uncles: block.Uncles()})
  233. }
  234. break
  235. }
  236. }
  237. }
  238. for j, hash := range tt.explicit {
  239. hashes = append(hashes, hash)
  240. if tt.available[j] && len(bodies) < tt.expected {
  241. block := bc.GetBlockByHash(hash)
  242. bodies = append(bodies, &types.Body{Transactions: block.Transactions(), Uncles: block.Uncles()})
  243. }
  244. }
  245. reqID++
  246. // Send the hash request and verify the response
  247. sendRequest(rawPeer.app, GetBlockBodiesMsg, reqID, hashes)
  248. if err := expectResponse(rawPeer.app, BlockBodiesMsg, reqID, testBufLimit, bodies); err != nil {
  249. t.Errorf("test %d: bodies mismatch: %v", i, err)
  250. }
  251. }
  252. }
  253. // Tests that the contract codes can be retrieved based on account addresses.
  254. func TestGetCodeLes2(t *testing.T) { testGetCode(t, 2) }
  255. func TestGetCodeLes3(t *testing.T) { testGetCode(t, 3) }
  256. func TestGetCodeLes4(t *testing.T) { testGetCode(t, 4) }
  257. func testGetCode(t *testing.T, protocol int) {
  258. // Assemble the test environment
  259. netconfig := testnetConfig{
  260. blocks: 4,
  261. protocol: protocol,
  262. nopruning: true,
  263. }
  264. server, _, tearDown := newClientServerEnv(t, netconfig)
  265. defer tearDown()
  266. rawPeer, closePeer, _ := server.newRawPeer(t, "peer", protocol)
  267. defer closePeer()
  268. bc := server.handler.blockchain
  269. var codereqs []*CodeReq
  270. var codes [][]byte
  271. for i := uint64(0); i <= bc.CurrentBlock().NumberU64(); i++ {
  272. header := bc.GetHeaderByNumber(i)
  273. req := &CodeReq{
  274. BHash: header.Hash(),
  275. AccKey: crypto.Keccak256(testContractAddr[:]),
  276. }
  277. codereqs = append(codereqs, req)
  278. if i >= testContractDeployed {
  279. codes = append(codes, testContractCodeDeployed)
  280. }
  281. }
  282. sendRequest(rawPeer.app, GetCodeMsg, 42, codereqs)
  283. if err := expectResponse(rawPeer.app, CodeMsg, 42, testBufLimit, codes); err != nil {
  284. t.Errorf("codes mismatch: %v", err)
  285. }
  286. }
  287. // Tests that the stale contract codes can't be retrieved based on account addresses.
  288. func TestGetStaleCodeLes2(t *testing.T) { testGetStaleCode(t, 2) }
  289. func TestGetStaleCodeLes3(t *testing.T) { testGetStaleCode(t, 3) }
  290. func TestGetStaleCodeLes4(t *testing.T) { testGetStaleCode(t, 4) }
  291. func testGetStaleCode(t *testing.T, protocol int) {
  292. netconfig := testnetConfig{
  293. blocks: core.TriesInMemory + 4,
  294. protocol: protocol,
  295. nopruning: true,
  296. }
  297. server, _, tearDown := newClientServerEnv(t, netconfig)
  298. defer tearDown()
  299. rawPeer, closePeer, _ := server.newRawPeer(t, "peer", protocol)
  300. defer closePeer()
  301. bc := server.handler.blockchain
  302. check := func(number uint64, expected [][]byte) {
  303. req := &CodeReq{
  304. BHash: bc.GetHeaderByNumber(number).Hash(),
  305. AccKey: crypto.Keccak256(testContractAddr[:]),
  306. }
  307. sendRequest(rawPeer.app, GetCodeMsg, 42, []*CodeReq{req})
  308. if err := expectResponse(rawPeer.app, CodeMsg, 42, testBufLimit, expected); err != nil {
  309. t.Errorf("codes mismatch: %v", err)
  310. }
  311. }
  312. check(0, [][]byte{}) // Non-exist contract
  313. check(testContractDeployed, [][]byte{}) // Stale contract
  314. check(bc.CurrentHeader().Number.Uint64(), [][]byte{testContractCodeDeployed}) // Fresh contract
  315. }
  316. // Tests that the transaction receipts can be retrieved based on hashes.
  317. func TestGetReceiptLes2(t *testing.T) { testGetReceipt(t, 2) }
  318. func TestGetReceiptLes3(t *testing.T) { testGetReceipt(t, 3) }
  319. func TestGetReceiptLes4(t *testing.T) { testGetReceipt(t, 4) }
  320. func testGetReceipt(t *testing.T, protocol int) {
  321. // Assemble the test environment
  322. netconfig := testnetConfig{
  323. blocks: 4,
  324. protocol: protocol,
  325. nopruning: true,
  326. }
  327. server, _, tearDown := newClientServerEnv(t, netconfig)
  328. defer tearDown()
  329. rawPeer, closePeer, _ := server.newRawPeer(t, "peer", protocol)
  330. defer closePeer()
  331. bc := server.handler.blockchain
  332. // Collect the hashes to request, and the response to expect
  333. var receipts []types.Receipts
  334. var hashes []common.Hash
  335. for i := uint64(0); i <= bc.CurrentBlock().NumberU64(); i++ {
  336. block := bc.GetBlockByNumber(i)
  337. hashes = append(hashes, block.Hash())
  338. receipts = append(receipts, rawdb.ReadRawReceipts(server.db, block.Hash(), block.NumberU64()))
  339. }
  340. // Send the hash request and verify the response
  341. sendRequest(rawPeer.app, GetReceiptsMsg, 42, hashes)
  342. if err := expectResponse(rawPeer.app, ReceiptsMsg, 42, testBufLimit, receipts); err != nil {
  343. t.Errorf("receipts mismatch: %v", err)
  344. }
  345. }
  346. // Tests that trie merkle proofs can be retrieved
  347. func TestGetProofsLes2(t *testing.T) { testGetProofs(t, 2) }
  348. func TestGetProofsLes3(t *testing.T) { testGetProofs(t, 3) }
  349. func TestGetProofsLes4(t *testing.T) { testGetProofs(t, 4) }
  350. func testGetProofs(t *testing.T, protocol int) {
  351. // Assemble the test environment
  352. netconfig := testnetConfig{
  353. blocks: 4,
  354. protocol: protocol,
  355. nopruning: true,
  356. }
  357. server, _, tearDown := newClientServerEnv(t, netconfig)
  358. defer tearDown()
  359. rawPeer, closePeer, _ := server.newRawPeer(t, "peer", protocol)
  360. defer closePeer()
  361. bc := server.handler.blockchain
  362. var proofreqs []ProofReq
  363. proofsV2 := light.NewNodeSet()
  364. accounts := []common.Address{bankAddr, userAddr1, userAddr2, signerAddr, {}}
  365. for i := uint64(0); i <= bc.CurrentBlock().NumberU64(); i++ {
  366. header := bc.GetHeaderByNumber(i)
  367. trie, _ := trie.New(header.Root, trie.NewDatabase(server.db))
  368. for _, acc := range accounts {
  369. req := ProofReq{
  370. BHash: header.Hash(),
  371. Key: crypto.Keccak256(acc[:]),
  372. }
  373. proofreqs = append(proofreqs, req)
  374. trie.Prove(crypto.Keccak256(acc[:]), 0, proofsV2)
  375. }
  376. }
  377. // Send the proof request and verify the response
  378. sendRequest(rawPeer.app, GetProofsV2Msg, 42, proofreqs)
  379. if err := expectResponse(rawPeer.app, ProofsV2Msg, 42, testBufLimit, proofsV2.NodeList()); err != nil {
  380. t.Errorf("proofs mismatch: %v", err)
  381. }
  382. }
  383. // Tests that the stale contract codes can't be retrieved based on account addresses.
  384. func TestGetStaleProofLes2(t *testing.T) { testGetStaleProof(t, 2) }
  385. func TestGetStaleProofLes3(t *testing.T) { testGetStaleProof(t, 3) }
  386. func TestGetStaleProofLes4(t *testing.T) { testGetStaleProof(t, 4) }
  387. func testGetStaleProof(t *testing.T, protocol int) {
  388. netconfig := testnetConfig{
  389. blocks: core.TriesInMemory + 4,
  390. protocol: protocol,
  391. nopruning: true,
  392. }
  393. server, _, tearDown := newClientServerEnv(t, netconfig)
  394. defer tearDown()
  395. rawPeer, closePeer, _ := server.newRawPeer(t, "peer", protocol)
  396. defer closePeer()
  397. bc := server.handler.blockchain
  398. check := func(number uint64, wantOK bool) {
  399. var (
  400. header = bc.GetHeaderByNumber(number)
  401. account = crypto.Keccak256(userAddr1.Bytes())
  402. )
  403. req := &ProofReq{
  404. BHash: header.Hash(),
  405. Key: account,
  406. }
  407. sendRequest(rawPeer.app, GetProofsV2Msg, 42, []*ProofReq{req})
  408. var expected []rlp.RawValue
  409. if wantOK {
  410. proofsV2 := light.NewNodeSet()
  411. t, _ := trie.New(header.Root, trie.NewDatabase(server.db))
  412. t.Prove(account, 0, proofsV2)
  413. expected = proofsV2.NodeList()
  414. }
  415. if err := expectResponse(rawPeer.app, ProofsV2Msg, 42, testBufLimit, expected); err != nil {
  416. t.Errorf("codes mismatch: %v", err)
  417. }
  418. }
  419. check(0, false) // Non-exist proof
  420. check(2, false) // Stale proof
  421. check(bc.CurrentHeader().Number.Uint64(), true) // Fresh proof
  422. }
  423. // Tests that CHT proofs can be correctly retrieved.
  424. func TestGetCHTProofsLes2(t *testing.T) { testGetCHTProofs(t, 2) }
  425. func TestGetCHTProofsLes3(t *testing.T) { testGetCHTProofs(t, 3) }
  426. func TestGetCHTProofsLes4(t *testing.T) { testGetCHTProofs(t, 4) }
  427. func testGetCHTProofs(t *testing.T, protocol int) {
  428. var (
  429. config = light.TestServerIndexerConfig
  430. waitIndexers = func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) {
  431. for {
  432. cs, _, _ := cIndexer.Sections()
  433. if cs >= 1 {
  434. break
  435. }
  436. time.Sleep(10 * time.Millisecond)
  437. }
  438. }
  439. netconfig = testnetConfig{
  440. blocks: int(config.ChtSize + config.ChtConfirms),
  441. protocol: protocol,
  442. indexFn: waitIndexers,
  443. nopruning: true,
  444. }
  445. )
  446. server, _, tearDown := newClientServerEnv(t, netconfig)
  447. defer tearDown()
  448. rawPeer, closePeer, _ := server.newRawPeer(t, "peer", protocol)
  449. defer closePeer()
  450. bc := server.handler.blockchain
  451. // Assemble the proofs from the different protocols
  452. header := bc.GetHeaderByNumber(config.ChtSize - 1)
  453. rlp, _ := rlp.EncodeToBytes(header)
  454. key := make([]byte, 8)
  455. binary.BigEndian.PutUint64(key, config.ChtSize-1)
  456. proofsV2 := HelperTrieResps{
  457. AuxData: [][]byte{rlp},
  458. }
  459. root := light.GetChtRoot(server.db, 0, bc.GetHeaderByNumber(config.ChtSize-1).Hash())
  460. trie, _ := trie.New(root, trie.NewDatabase(rawdb.NewTable(server.db, light.ChtTablePrefix)))
  461. trie.Prove(key, 0, &proofsV2.Proofs)
  462. // Assemble the requests for the different protocols
  463. requestsV2 := []HelperTrieReq{{
  464. Type: htCanonical,
  465. TrieIdx: 0,
  466. Key: key,
  467. AuxReq: htAuxHeader,
  468. }}
  469. // Send the proof request and verify the response
  470. sendRequest(rawPeer.app, GetHelperTrieProofsMsg, 42, requestsV2)
  471. if err := expectResponse(rawPeer.app, HelperTrieProofsMsg, 42, testBufLimit, proofsV2); err != nil {
  472. t.Errorf("proofs mismatch: %v", err)
  473. }
  474. }
  475. func TestGetBloombitsProofsLes2(t *testing.T) { testGetBloombitsProofs(t, 2) }
  476. func TestGetBloombitsProofsLes3(t *testing.T) { testGetBloombitsProofs(t, 3) }
  477. func TestGetBloombitsProofsLes4(t *testing.T) { testGetBloombitsProofs(t, 4) }
  478. // Tests that bloombits proofs can be correctly retrieved.
  479. func testGetBloombitsProofs(t *testing.T, protocol int) {
  480. var (
  481. config = light.TestServerIndexerConfig
  482. waitIndexers = func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) {
  483. for {
  484. bts, _, _ := btIndexer.Sections()
  485. if bts >= 1 {
  486. break
  487. }
  488. time.Sleep(10 * time.Millisecond)
  489. }
  490. }
  491. netconfig = testnetConfig{
  492. blocks: int(config.BloomTrieSize + config.BloomTrieConfirms),
  493. protocol: protocol,
  494. indexFn: waitIndexers,
  495. nopruning: true,
  496. }
  497. )
  498. server, _, tearDown := newClientServerEnv(t, netconfig)
  499. defer tearDown()
  500. rawPeer, closePeer, _ := server.newRawPeer(t, "peer", protocol)
  501. defer closePeer()
  502. bc := server.handler.blockchain
  503. // Request and verify each bit of the bloom bits proofs
  504. for bit := 0; bit < 2048; bit++ {
  505. // Assemble the request and proofs for the bloombits
  506. key := make([]byte, 10)
  507. binary.BigEndian.PutUint16(key[:2], uint16(bit))
  508. // Only the first bloom section has data.
  509. binary.BigEndian.PutUint64(key[2:], 0)
  510. requests := []HelperTrieReq{{
  511. Type: htBloomBits,
  512. TrieIdx: 0,
  513. Key: key,
  514. }}
  515. var proofs HelperTrieResps
  516. root := light.GetBloomTrieRoot(server.db, 0, bc.GetHeaderByNumber(config.BloomTrieSize-1).Hash())
  517. trie, _ := trie.New(root, trie.NewDatabase(rawdb.NewTable(server.db, light.BloomTrieTablePrefix)))
  518. trie.Prove(key, 0, &proofs.Proofs)
  519. // Send the proof request and verify the response
  520. sendRequest(rawPeer.app, GetHelperTrieProofsMsg, 42, requests)
  521. if err := expectResponse(rawPeer.app, HelperTrieProofsMsg, 42, testBufLimit, proofs); err != nil {
  522. t.Errorf("bit %d: proofs mismatch: %v", bit, err)
  523. }
  524. }
  525. }
  526. func TestTransactionStatusLes2(t *testing.T) { testTransactionStatus(t, lpv2) }
  527. func TestTransactionStatusLes3(t *testing.T) { testTransactionStatus(t, lpv3) }
  528. func TestTransactionStatusLes4(t *testing.T) { testTransactionStatus(t, lpv4) }
  529. func testTransactionStatus(t *testing.T, protocol int) {
  530. netconfig := testnetConfig{
  531. protocol: protocol,
  532. nopruning: true,
  533. }
  534. server, _, tearDown := newClientServerEnv(t, netconfig)
  535. defer tearDown()
  536. rawPeer, closePeer, _ := server.newRawPeer(t, "peer", protocol)
  537. defer closePeer()
  538. server.handler.addTxsSync = true
  539. chain := server.handler.blockchain
  540. var reqID uint64
  541. test := func(tx *types.Transaction, send bool, expStatus light.TxStatus) {
  542. reqID++
  543. if send {
  544. sendRequest(rawPeer.app, SendTxV2Msg, reqID, types.Transactions{tx})
  545. } else {
  546. sendRequest(rawPeer.app, GetTxStatusMsg, reqID, []common.Hash{tx.Hash()})
  547. }
  548. if err := expectResponse(rawPeer.app, TxStatusMsg, reqID, testBufLimit, []light.TxStatus{expStatus}); err != nil {
  549. t.Errorf("transaction status mismatch")
  550. }
  551. }
  552. signer := types.HomesteadSigner{}
  553. // test error status by sending an underpriced transaction
  554. tx0, _ := types.SignTx(types.NewTransaction(0, userAddr1, big.NewInt(10000), params.TxGas, nil, nil), signer, bankKey)
  555. test(tx0, true, light.TxStatus{Status: core.TxStatusUnknown, Error: core.ErrUnderpriced.Error()})
  556. tx1, _ := types.SignTx(types.NewTransaction(0, userAddr1, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil), signer, bankKey)
  557. test(tx1, false, light.TxStatus{Status: core.TxStatusUnknown}) // query before sending, should be unknown
  558. test(tx1, true, light.TxStatus{Status: core.TxStatusPending}) // send valid processable tx, should return pending
  559. test(tx1, true, light.TxStatus{Status: core.TxStatusPending}) // adding it again should not return an error
  560. tx2, _ := types.SignTx(types.NewTransaction(1, userAddr1, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil), signer, bankKey)
  561. tx3, _ := types.SignTx(types.NewTransaction(2, userAddr1, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil), signer, bankKey)
  562. // send transactions in the wrong order, tx3 should be queued
  563. test(tx3, true, light.TxStatus{Status: core.TxStatusQueued})
  564. test(tx2, true, light.TxStatus{Status: core.TxStatusPending})
  565. // query again, now tx3 should be pending too
  566. test(tx3, false, light.TxStatus{Status: core.TxStatusPending})
  567. // generate and add a block with tx1 and tx2 included
  568. gchain, _ := core.GenerateChain(params.TestChainConfig, chain.GetBlockByNumber(0), ethash.NewFaker(), server.db, 1, func(i int, block *core.BlockGen) {
  569. block.AddTx(tx1)
  570. block.AddTx(tx2)
  571. })
  572. if _, err := chain.InsertChain(gchain); err != nil {
  573. panic(err)
  574. }
  575. // wait until TxPool processes the inserted block
  576. for i := 0; i < 10; i++ {
  577. if pending, _ := server.handler.txpool.Stats(); pending == 1 {
  578. break
  579. }
  580. time.Sleep(100 * time.Millisecond)
  581. }
  582. if pending, _ := server.handler.txpool.Stats(); pending != 1 {
  583. t.Fatalf("pending count mismatch: have %d, want 1", pending)
  584. }
  585. // Discard new block announcement
  586. msg, _ := rawPeer.app.ReadMsg()
  587. msg.Discard()
  588. // check if their status is included now
  589. block1hash := rawdb.ReadCanonicalHash(server.db, 1)
  590. test(tx1, false, light.TxStatus{Status: core.TxStatusIncluded, Lookup: &rawdb.LegacyTxLookupEntry{BlockHash: block1hash, BlockIndex: 1, Index: 0}})
  591. test(tx2, false, light.TxStatus{Status: core.TxStatusIncluded, Lookup: &rawdb.LegacyTxLookupEntry{BlockHash: block1hash, BlockIndex: 1, Index: 1}})
  592. // create a reorg that rolls them back
  593. gchain, _ = core.GenerateChain(params.TestChainConfig, chain.GetBlockByNumber(0), ethash.NewFaker(), server.db, 2, func(i int, block *core.BlockGen) {})
  594. if _, err := chain.InsertChain(gchain); err != nil {
  595. panic(err)
  596. }
  597. // wait until TxPool processes the reorg
  598. for i := 0; i < 10; i++ {
  599. if pending, _ := server.handler.txpool.Stats(); pending == 3 {
  600. break
  601. }
  602. time.Sleep(100 * time.Millisecond)
  603. }
  604. if pending, _ := server.handler.txpool.Stats(); pending != 3 {
  605. t.Fatalf("pending count mismatch: have %d, want 3", pending)
  606. }
  607. // Discard new block announcement
  608. msg, _ = rawPeer.app.ReadMsg()
  609. msg.Discard()
  610. // check if their status is pending again
  611. test(tx1, false, light.TxStatus{Status: core.TxStatusPending})
  612. test(tx2, false, light.TxStatus{Status: core.TxStatusPending})
  613. }
  614. func TestStopResumeLES3(t *testing.T) { testStopResume(t, lpv3) }
  615. func TestStopResumeLES4(t *testing.T) { testStopResume(t, lpv4) }
  616. func testStopResume(t *testing.T, protocol int) {
  617. netconfig := testnetConfig{
  618. protocol: protocol,
  619. simClock: true,
  620. nopruning: true,
  621. }
  622. server, _, tearDown := newClientServerEnv(t, netconfig)
  623. defer tearDown()
  624. server.handler.server.costTracker.testing = true
  625. server.handler.server.costTracker.testCostList = testCostList(testBufLimit / 10)
  626. rawPeer, closePeer, _ := server.newRawPeer(t, "peer", protocol)
  627. defer closePeer()
  628. var (
  629. reqID uint64
  630. expBuf = testBufLimit
  631. testCost = testBufLimit / 10
  632. )
  633. header := server.handler.blockchain.CurrentHeader()
  634. req := func() {
  635. reqID++
  636. sendRequest(rawPeer.app, GetBlockHeadersMsg, reqID, &GetBlockHeadersData{Origin: hashOrNumber{Hash: header.Hash()}, Amount: 1})
  637. }
  638. for i := 1; i <= 5; i++ {
  639. // send requests while we still have enough buffer and expect a response
  640. for expBuf >= testCost {
  641. req()
  642. expBuf -= testCost
  643. if err := expectResponse(rawPeer.app, BlockHeadersMsg, reqID, expBuf, []*types.Header{header}); err != nil {
  644. t.Errorf("expected response and failed: %v", err)
  645. }
  646. }
  647. // send some more requests in excess and expect a single StopMsg
  648. c := i
  649. for c > 0 {
  650. req()
  651. c--
  652. }
  653. if err := p2p.ExpectMsg(rawPeer.app, StopMsg, nil); err != nil {
  654. t.Errorf("expected StopMsg and failed: %v", err)
  655. }
  656. // wait until the buffer is recharged by half of the limit
  657. wait := testBufLimit / testBufRecharge / 2
  658. server.clock.(*mclock.Simulated).Run(time.Millisecond * time.Duration(wait))
  659. // expect a ResumeMsg with the partially recharged buffer value
  660. expBuf += testBufRecharge * wait
  661. if err := p2p.ExpectMsg(rawPeer.app, ResumeMsg, expBuf); err != nil {
  662. t.Errorf("expected ResumeMsg and failed: %v", err)
  663. }
  664. }
  665. }