github.com/c4dt/go-ethereum@v1.9.2/les/fetcher_test.go (about) 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 17 package les 18 19 import ( 20 "math/big" 21 "testing" 22 23 "net" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/core/types" 27 "github.com/ethereum/go-ethereum/crypto" 28 "github.com/ethereum/go-ethereum/p2p" 29 "github.com/ethereum/go-ethereum/p2p/enode" 30 ) 31 32 func TestFetcherULCPeerSelector(t *testing.T) { 33 id1 := newNodeID(t).ID() 34 id2 := newNodeID(t).ID() 35 id3 := newNodeID(t).ID() 36 id4 := newNodeID(t).ID() 37 38 ftn1 := &fetcherTreeNode{ 39 hash: common.HexToHash("1"), 40 td: big.NewInt(1), 41 } 42 ftn2 := &fetcherTreeNode{ 43 hash: common.HexToHash("2"), 44 td: big.NewInt(2), 45 parent: ftn1, 46 } 47 ftn3 := &fetcherTreeNode{ 48 hash: common.HexToHash("3"), 49 td: big.NewInt(3), 50 parent: ftn2, 51 } 52 lf := lightFetcher{ 53 pm: &ProtocolManager{ 54 ulc: &ulc{ 55 keys: map[string]bool{ 56 id1.String(): true, 57 id2.String(): true, 58 id3.String(): true, 59 id4.String(): true, 60 }, 61 fraction: 70, 62 }, 63 }, 64 maxConfirmedTd: ftn1.td, 65 66 peers: map[*peer]*fetcherPeerInfo{ 67 { 68 id: "peer1", 69 Peer: p2p.NewPeer(id1, "peer1", []p2p.Cap{}), 70 trusted: true, 71 }: { 72 nodeByHash: map[common.Hash]*fetcherTreeNode{ 73 ftn1.hash: ftn1, 74 ftn2.hash: ftn2, 75 }, 76 }, 77 { 78 Peer: p2p.NewPeer(id2, "peer2", []p2p.Cap{}), 79 id: "peer2", 80 trusted: true, 81 }: { 82 nodeByHash: map[common.Hash]*fetcherTreeNode{ 83 ftn1.hash: ftn1, 84 ftn2.hash: ftn2, 85 }, 86 }, 87 { 88 id: "peer3", 89 Peer: p2p.NewPeer(id3, "peer3", []p2p.Cap{}), 90 trusted: true, 91 }: { 92 nodeByHash: map[common.Hash]*fetcherTreeNode{ 93 ftn1.hash: ftn1, 94 ftn2.hash: ftn2, 95 ftn3.hash: ftn3, 96 }, 97 }, 98 { 99 id: "peer4", 100 Peer: p2p.NewPeer(id4, "peer4", []p2p.Cap{}), 101 trusted: true, 102 }: { 103 nodeByHash: map[common.Hash]*fetcherTreeNode{ 104 ftn1.hash: ftn1, 105 }, 106 }, 107 }, 108 chain: &lightChainStub{ 109 tds: map[common.Hash]*big.Int{}, 110 headers: map[common.Hash]*types.Header{ 111 ftn1.hash: {}, 112 ftn2.hash: {}, 113 ftn3.hash: {}, 114 }, 115 }, 116 } 117 bestHash, bestAmount, bestTD, sync := lf.findBestRequest() 118 119 if bestTD == nil { 120 t.Fatal("Empty result") 121 } 122 123 if bestTD.Cmp(ftn2.td) != 0 { 124 t.Fatal("bad td", bestTD) 125 } 126 if bestHash != ftn2.hash { 127 t.Fatal("bad hash", bestTD) 128 } 129 130 _, _ = bestAmount, sync 131 } 132 133 type lightChainStub struct { 134 BlockChain 135 tds map[common.Hash]*big.Int 136 headers map[common.Hash]*types.Header 137 insertHeaderChainAssertFunc func(chain []*types.Header, checkFreq int) (int, error) 138 } 139 140 func (l *lightChainStub) GetHeader(hash common.Hash, number uint64) *types.Header { 141 if h, ok := l.headers[hash]; ok { 142 return h 143 } 144 145 return nil 146 } 147 148 func (l *lightChainStub) LockChain() {} 149 func (l *lightChainStub) UnlockChain() {} 150 151 func (l *lightChainStub) GetTd(hash common.Hash, number uint64) *big.Int { 152 if td, ok := l.tds[hash]; ok { 153 return td 154 } 155 return nil 156 } 157 158 func (l *lightChainStub) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { 159 return l.insertHeaderChainAssertFunc(chain, checkFreq) 160 } 161 162 func newNodeID(t *testing.T) *enode.Node { 163 key, err := crypto.GenerateKey() 164 if err != nil { 165 t.Fatal("generate key err:", err) 166 } 167 return enode.NewV4(&key.PublicKey, net.IP{}, 35000, 35000) 168 }