github.com/nitinawathare/ethereumassignment3@v0.0.0-20211021213010-f07344c2b868/go-ethereum/les/ulc_test.go (about) 1 package les 2 3 import ( 4 "crypto/ecdsa" 5 "fmt" 6 "math/big" 7 "net" 8 "reflect" 9 "testing" 10 "time" 11 12 "github.com/ethereum/go-ethereum/common/mclock" 13 "github.com/ethereum/go-ethereum/core" 14 "github.com/ethereum/go-ethereum/core/rawdb" 15 "github.com/ethereum/go-ethereum/crypto" 16 "github.com/ethereum/go-ethereum/eth" 17 "github.com/ethereum/go-ethereum/light" 18 "github.com/ethereum/go-ethereum/p2p" 19 "github.com/ethereum/go-ethereum/p2p/enode" 20 ) 21 22 func TestULCSyncWithOnePeer(t *testing.T) { 23 f := newFullPeerPair(t, 1, 4, testChainGen) 24 ulcConfig := ð.ULCConfig{ 25 MinTrustedFraction: 100, 26 TrustedServers: []string{f.Node.String()}, 27 } 28 29 l := newLightPeer(t, ulcConfig) 30 31 if reflect.DeepEqual(f.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Hash()) { 32 t.Fatal("blocks are equal") 33 } 34 35 _, _, err := connectPeers(f, l, 2) 36 if err != nil { 37 t.Fatal(err) 38 } 39 40 l.PM.fetcher.lock.Lock() 41 l.PM.fetcher.nextRequest() 42 l.PM.fetcher.lock.Unlock() 43 44 if !reflect.DeepEqual(f.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Hash()) { 45 t.Fatal("sync doesn't work") 46 } 47 } 48 49 func TestULCReceiveAnnounce(t *testing.T) { 50 f := newFullPeerPair(t, 1, 4, testChainGen) 51 ulcConfig := ð.ULCConfig{ 52 MinTrustedFraction: 100, 53 TrustedServers: []string{f.Node.String()}, 54 } 55 56 l := newLightPeer(t, ulcConfig) 57 fPeer, lPeer, err := connectPeers(f, l, 2) 58 if err != nil { 59 t.Fatal(err) 60 } 61 62 l.PM.synchronise(fPeer) 63 64 //check that the sync is finished correctly 65 if !reflect.DeepEqual(f.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Hash()) { 66 t.Fatal("sync doesn't work") 67 } 68 69 l.PM.peers.lock.Lock() 70 if len(l.PM.peers.peers) == 0 { 71 t.Fatal("peer list should not be empty") 72 } 73 l.PM.peers.lock.Unlock() 74 75 time.Sleep(time.Second) 76 //send a signed announce message(payload doesn't matter) 77 td := f.PM.blockchain.GetTd(l.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Number.Uint64()) 78 announce := announceData{ 79 Number: l.PM.blockchain.CurrentHeader().Number.Uint64() + 1, 80 Td: td.Add(td, big.NewInt(1)), 81 } 82 announce.sign(f.Key) 83 lPeer.SendAnnounce(announce) 84 } 85 86 func TestULCShouldNotSyncWithTwoPeersOneHaveEmptyChain(t *testing.T) { 87 f1 := newFullPeerPair(t, 1, 4, testChainGen) 88 f2 := newFullPeerPair(t, 2, 0, nil) 89 ulcConf := &ulc{minTrustedFraction: 100, trustedKeys: make(map[string]struct{})} 90 ulcConf.trustedKeys[f1.Node.ID().String()] = struct{}{} 91 ulcConf.trustedKeys[f2.Node.ID().String()] = struct{}{} 92 ulcConfig := ð.ULCConfig{ 93 MinTrustedFraction: 100, 94 TrustedServers: []string{f1.Node.String(), f2.Node.String()}, 95 } 96 l := newLightPeer(t, ulcConfig) 97 l.PM.ulc.minTrustedFraction = 100 98 99 _, _, err := connectPeers(f1, l, 2) 100 if err != nil { 101 t.Fatal(err) 102 } 103 _, _, err = connectPeers(f2, l, 2) 104 if err != nil { 105 t.Fatal(err) 106 } 107 108 l.PM.fetcher.lock.Lock() 109 l.PM.fetcher.nextRequest() 110 l.PM.fetcher.lock.Unlock() 111 112 if reflect.DeepEqual(f2.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Hash()) { 113 t.Fatal("Incorrect hash: second peer has empty chain") 114 } 115 } 116 117 func TestULCShouldNotSyncWithThreePeersOneHaveEmptyChain(t *testing.T) { 118 f1 := newFullPeerPair(t, 1, 3, testChainGen) 119 f2 := newFullPeerPair(t, 2, 4, testChainGen) 120 f3 := newFullPeerPair(t, 3, 0, nil) 121 122 ulcConfig := ð.ULCConfig{ 123 MinTrustedFraction: 60, 124 TrustedServers: []string{f1.Node.String(), f2.Node.String(), f3.Node.String()}, 125 } 126 127 l := newLightPeer(t, ulcConfig) 128 _, _, err := connectPeers(f1, l, 2) 129 if err != nil { 130 t.Fatal(err) 131 } 132 133 _, _, err = connectPeers(f2, l, 2) 134 if err != nil { 135 t.Fatal(err) 136 } 137 138 _, _, err = connectPeers(f3, l, 2) 139 if err != nil { 140 t.Fatal(err) 141 } 142 143 l.PM.fetcher.lock.Lock() 144 l.PM.fetcher.nextRequest() 145 l.PM.fetcher.lock.Unlock() 146 147 if !reflect.DeepEqual(f1.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Hash()) { 148 t.Fatal("Incorrect hash") 149 } 150 } 151 152 type pairPeer struct { 153 Name string 154 Node *enode.Node 155 PM *ProtocolManager 156 Key *ecdsa.PrivateKey 157 } 158 159 func connectPeers(full, light pairPeer, version int) (*peer, *peer, error) { 160 // Create a message pipe to communicate through 161 app, net := p2p.MsgPipe() 162 163 peerLight := full.PM.newPeer(version, NetworkId, p2p.NewPeer(light.Node.ID(), light.Name, nil), net) 164 peerFull := light.PM.newPeer(version, NetworkId, p2p.NewPeer(full.Node.ID(), full.Name, nil), app) 165 166 // Start the peerLight on a new thread 167 errc1 := make(chan error, 1) 168 errc2 := make(chan error, 1) 169 go func() { 170 select { 171 case light.PM.newPeerCh <- peerFull: 172 errc1 <- light.PM.handle(peerFull) 173 case <-light.PM.quitSync: 174 errc1 <- p2p.DiscQuitting 175 } 176 }() 177 go func() { 178 select { 179 case full.PM.newPeerCh <- peerLight: 180 errc2 <- full.PM.handle(peerLight) 181 case <-full.PM.quitSync: 182 errc2 <- p2p.DiscQuitting 183 } 184 }() 185 186 select { 187 case <-time.After(time.Millisecond * 100): 188 case err := <-errc1: 189 return nil, nil, fmt.Errorf("peerLight handshake error: %v", err) 190 case err := <-errc2: 191 return nil, nil, fmt.Errorf("peerFull handshake error: %v", err) 192 } 193 194 return peerFull, peerLight, nil 195 } 196 197 // newFullPeerPair creates node with full sync mode 198 func newFullPeerPair(t *testing.T, index int, numberOfblocks int, chainGen func(int, *core.BlockGen)) pairPeer { 199 db := rawdb.NewMemoryDatabase() 200 201 pmFull := newTestProtocolManagerMust(t, false, numberOfblocks, chainGen, nil, nil, db, nil) 202 203 peerPairFull := pairPeer{ 204 Name: "full node", 205 PM: pmFull, 206 } 207 key, err := crypto.GenerateKey() 208 if err != nil { 209 t.Fatal("generate key err:", err) 210 } 211 peerPairFull.Key = key 212 peerPairFull.Node = enode.NewV4(&key.PublicKey, net.ParseIP("127.0.0.1"), 35000, 35000) 213 return peerPairFull 214 } 215 216 // newLightPeer creates node with light sync mode 217 func newLightPeer(t *testing.T, ulcConfig *eth.ULCConfig) pairPeer { 218 peers := newPeerSet() 219 dist := newRequestDistributor(peers, make(chan struct{}), &mclock.System{}) 220 rm := newRetrieveManager(peers, dist, nil) 221 ldb := rawdb.NewMemoryDatabase() 222 223 odr := NewLesOdr(ldb, light.DefaultClientIndexerConfig, rm) 224 225 pmLight := newTestProtocolManagerMust(t, true, 0, nil, odr, peers, ldb, ulcConfig) 226 peerPairLight := pairPeer{ 227 Name: "ulc node", 228 PM: pmLight, 229 } 230 231 key, err := crypto.GenerateKey() 232 if err != nil { 233 t.Fatal("generate key err:", err) 234 } 235 peerPairLight.Key = key 236 peerPairLight.Node = enode.NewV4(&key.PublicKey, net.IP{}, 35000, 35000) 237 return peerPairLight 238 }