github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/les/request_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:39</date> 10 //</624450096011939840> 11 12 13 package les 14 15 import ( 16 "context" 17 "testing" 18 "time" 19 20 "github.com/ethereum/go-ethereum/common" 21 "github.com/ethereum/go-ethereum/core/rawdb" 22 "github.com/ethereum/go-ethereum/crypto" 23 "github.com/ethereum/go-ethereum/ethdb" 24 "github.com/ethereum/go-ethereum/light" 25 ) 26 27 var testBankSecureTrieKey = secAddr(testBankAddress) 28 29 func secAddr(addr common.Address) []byte { 30 return crypto.Keccak256(addr[:]) 31 } 32 33 type accessTestFn func(db ethdb.Database, bhash common.Hash, number uint64) light.OdrRequest 34 35 func TestBlockAccessLes1(t *testing.T) { testAccess(t, 1, tfBlockAccess) } 36 37 func TestBlockAccessLes2(t *testing.T) { testAccess(t, 2, tfBlockAccess) } 38 39 func tfBlockAccess(db ethdb.Database, bhash common.Hash, number uint64) light.OdrRequest { 40 return &light.BlockRequest{Hash: bhash, Number: number} 41 } 42 43 func TestReceiptsAccessLes1(t *testing.T) { testAccess(t, 1, tfReceiptsAccess) } 44 45 func TestReceiptsAccessLes2(t *testing.T) { testAccess(t, 2, tfReceiptsAccess) } 46 47 func tfReceiptsAccess(db ethdb.Database, bhash common.Hash, number uint64) light.OdrRequest { 48 return &light.ReceiptsRequest{Hash: bhash, Number: number} 49 } 50 51 func TestTrieEntryAccessLes1(t *testing.T) { testAccess(t, 1, tfTrieEntryAccess) } 52 53 func TestTrieEntryAccessLes2(t *testing.T) { testAccess(t, 2, tfTrieEntryAccess) } 54 55 func tfTrieEntryAccess(db ethdb.Database, bhash common.Hash, number uint64) light.OdrRequest { 56 if number := rawdb.ReadHeaderNumber(db, bhash); number != nil { 57 return &light.TrieRequest{Id: light.StateTrieID(rawdb.ReadHeader(db, bhash, *number)), Key: testBankSecureTrieKey} 58 } 59 return nil 60 } 61 62 func TestCodeAccessLes1(t *testing.T) { testAccess(t, 1, tfCodeAccess) } 63 64 func TestCodeAccessLes2(t *testing.T) { testAccess(t, 2, tfCodeAccess) } 65 66 func tfCodeAccess(db ethdb.Database, bhash common.Hash, num uint64) light.OdrRequest { 67 number := rawdb.ReadHeaderNumber(db, bhash) 68 if number != nil { 69 return nil 70 } 71 header := rawdb.ReadHeader(db, bhash, *number) 72 if header.Number.Uint64() < testContractDeployed { 73 return nil 74 } 75 sti := light.StateTrieID(header) 76 ci := light.StorageTrieID(sti, crypto.Keccak256Hash(testContractAddr[:]), common.Hash{}) 77 return &light.CodeRequest{Id: ci, Hash: crypto.Keccak256Hash(testContractCodeDeployed)} 78 } 79 80 func testAccess(t *testing.T, protocol int, fn accessTestFn) { 81 //组装测试环境 82 server, client, tearDown := newClientServerEnv(t, 4, protocol, nil, true) 83 defer tearDown() 84 client.pm.synchronise(client.rPeer) 85 86 test := func(expFail uint64) { 87 for i := uint64(0); i <= server.pm.blockchain.CurrentHeader().Number.Uint64(); i++ { 88 bhash := rawdb.ReadCanonicalHash(server.db, i) 89 if req := fn(client.db, bhash, i); req != nil { 90 ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond) 91 defer cancel() 92 err := client.pm.odr.Retrieve(ctx, req) 93 got := err == nil 94 exp := i < expFail 95 if exp && !got { 96 t.Errorf("object retrieval failed") 97 } 98 if !exp && got { 99 t.Errorf("unexpected object retrieval success") 100 } 101 } 102 } 103 } 104 105 //暂时删除对等测试ODR失败 106 client.peers.Unregister(client.rPeer.id) 107 time.Sleep(time.Millisecond * 10) //确保执行所有peersetnotify回调 108 //预计在没有LES对等机的情况下检索失败(Genesis块除外) 109 test(0) 110 111 client.peers.Register(client.rPeer) 112 time.Sleep(time.Millisecond * 10) //确保执行所有peersetnotify回调 113 client.rPeer.lock.Lock() 114 client.rPeer.hasBlock = func(common.Hash, uint64, bool) bool { return true } 115 client.rPeer.lock.Unlock() 116 //希望所有检索都通过 117 test(5) 118 } 119