|
1 | 1 | package les |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "crypto/rand" |
| 5 | + "fmt" |
| 6 | + "github.com/ethereum/go-ethereum/core" |
4 | 7 | "github.com/ethereum/go-ethereum/eth" |
5 | 8 | "github.com/ethereum/go-ethereum/ethdb" |
6 | 9 | "github.com/ethereum/go-ethereum/light" |
| 10 | + "github.com/ethereum/go-ethereum/p2p" |
| 11 | + "github.com/ethereum/go-ethereum/p2p/discover" |
| 12 | + "reflect" |
7 | 13 | "testing" |
8 | 14 | "time" |
9 | 15 | ) |
10 | 16 |
|
11 | | -func TestUlc(t *testing.T) { |
12 | | - testULC(t, 2) |
| 17 | +func TestULCSyncWithOnePeer(t *testing.T) { |
| 18 | + f := newFullPeerPair(t, 1, 4, testChainGen) |
| 19 | + ulcConfig := ð.ULCConfig{ |
| 20 | + MinTrustedFraction: 100, |
| 21 | + TrustedNodes: []string{f.ID.String()}, |
| 22 | + } |
| 23 | + |
| 24 | + l := newLightPeer(t, ulcConfig) |
| 25 | + |
| 26 | + if reflect.DeepEqual(f.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Hash()) { |
| 27 | + t.Fatal("blocks are equal") |
| 28 | + } |
| 29 | + |
| 30 | + fPeer, _, err := connectPeers(f, l, 2) |
| 31 | + if err != nil { |
| 32 | + t.Fatal(err) |
| 33 | + } |
| 34 | + |
| 35 | + l.PM.synchronise(fPeer) |
| 36 | + |
| 37 | + if !reflect.DeepEqual(f.PM.blockchain.CurrentHeader().Hash(), l.PM.blockchain.CurrentHeader().Hash()) { |
| 38 | + t.Fatal("sync don't work") |
| 39 | + } |
13 | 40 | } |
14 | 41 |
|
15 | | -func testULC(t *testing.T, protocol int) { |
16 | | - // Assemble the test environment |
17 | | - peers := newPeerSet() |
18 | | - dist := newRequestDistributor(peers, make(chan struct{})) |
19 | | - rm := newRetrieveManager(peers, dist, nil) |
| 42 | +func TestULCShouldNotSyncWithTwoPeersOneHaveEmptyChain(t *testing.T) { |
| 43 | + f1 := newFullPeerPair(t, 1, 4, testChainGen) |
| 44 | + f2 := newFullPeerPair(t, 3, 0, nil) |
| 45 | + ulcConf := &ulc{minTrustedFraction: 100, trustedKeys: make(map[string]struct{})} |
| 46 | + ulcConf.trustedKeys[f1.ID.String()] = struct{}{} |
| 47 | + ulcConf.trustedKeys[f2.ID.String()] = struct{}{} |
| 48 | + ulcConfig := ð.ULCConfig{ |
| 49 | + MinTrustedFraction: 100, |
| 50 | + TrustedNodes: []string{f1.ID.String(), f2.ID.String()}, |
| 51 | + } |
| 52 | + l := newLightPeer(t, ulcConfig) |
| 53 | + l.PM.ulc.minTrustedFraction = 100 |
20 | 54 |
|
21 | | - db, _ := ethdb.NewMemDatabase() |
22 | | - ldb, _ := ethdb.NewMemDatabase() |
| 55 | + fPeer1, lPeer1, err := connectPeers(f1, l, 2) |
| 56 | + fPeer2, lPeer2, err := connectPeers(f2, l, 2) |
| 57 | + if err != nil { |
| 58 | + t.Fatal(err) |
| 59 | + } |
| 60 | + |
| 61 | + _, _ = lPeer1, lPeer2 |
| 62 | + |
| 63 | + l.PM.synchronise(fPeer1) |
| 64 | + l.PM.synchronise(fPeer2) |
| 65 | + |
| 66 | + time.Sleep(time.Second) |
| 67 | + if l.PM.blockchain.CurrentHeader() != nil { |
| 68 | + t.Fatal("Should be empty") |
| 69 | + } |
| 70 | +} |
| 71 | + |
| 72 | +type pairPeer struct { |
| 73 | + Name string |
| 74 | + ID discover.NodeID |
| 75 | + PM *ProtocolManager |
| 76 | +} |
23 | 77 |
|
24 | | - odr := NewLesOdr(ldb, light.NewChtIndexer(db, true), light.NewBloomTrieIndexer(db, true), eth.NewBloomIndexer(db, light.BloomTrieFrequency), rm) |
| 78 | +func connectPeers(full, light pairPeer, version int) (*peer, *peer, error) { |
| 79 | + // Create a message pipe to communicate through |
| 80 | + app, net := p2p.MsgPipe() |
25 | 81 |
|
26 | | - pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db, nil) |
27 | | - lpm := newTestProtocolManagerMust(t, true, 0, nil, peers, odr, ldb, nil) |
| 82 | + peerLight := full.PM.newPeer(version, NetworkId, p2p.NewPeer(light.ID, light.Name, nil), net) |
| 83 | + peerFull := light.PM.newPeer(version, NetworkId, p2p.NewPeer(full.ID, full.Name, nil), app) |
| 84 | + |
| 85 | + // Start the peerLight on a new thread |
| 86 | + errc1 := make(chan error, 1) |
| 87 | + errc2 := make(chan error, 1) |
| 88 | + go func() { |
| 89 | + select { |
| 90 | + case light.PM.newPeerCh <- peerFull: |
| 91 | + errc1 <- light.PM.handle(peerFull) |
| 92 | + case <-light.PM.quitSync: |
| 93 | + errc1 <- p2p.DiscQuitting |
| 94 | + } |
| 95 | + }() |
| 96 | + go func() { |
| 97 | + select { |
| 98 | + case full.PM.newPeerCh <- peerLight: |
| 99 | + errc2 <- full.PM.handle(peerLight) |
| 100 | + case <-full.PM.quitSync: |
| 101 | + errc2 <- p2p.DiscQuitting |
| 102 | + } |
| 103 | + }() |
28 | 104 |
|
29 | | - _, err1, lpeer, err2 := newTestPeerPair("peer", protocol, pm, lpm) |
30 | 105 | select { |
31 | 106 | case <-time.After(time.Millisecond * 100): |
32 | | - case err := <-err1: |
33 | | - t.Fatalf("peer 1 handshake error: %v", err) |
34 | | - case err := <-err2: |
35 | | - t.Fatalf("peer 1 handshake error: %v", err) |
| 107 | + case err := <-errc1: |
| 108 | + return nil, nil, fmt.Errorf("peerLight handshake error: %v", err) |
| 109 | + case err := <-errc2: |
| 110 | + return nil, nil, fmt.Errorf("peerFull handshake error: %v", err) |
| 111 | + } |
| 112 | + |
| 113 | + return peerFull, peerLight, nil |
| 114 | +} |
| 115 | + |
| 116 | +func newFullPeerPair(t *testing.T, index int, numberOfblocks int, chainGen func(int, *core.BlockGen)) pairPeer { |
| 117 | + db, _ := ethdb.NewMemDatabase() |
| 118 | + |
| 119 | + pmFull := newTestProtocolManagerMust(t, false, numberOfblocks, chainGen, nil, nil, db, nil) |
| 120 | + |
| 121 | + peerPairFull := pairPeer{ |
| 122 | + Name: "full node", |
| 123 | + PM: pmFull, |
| 124 | + } |
| 125 | + rand.Read(peerPairFull.ID[:]) |
| 126 | + return peerPairFull |
| 127 | +} |
| 128 | + |
| 129 | +func newLightPeer(t *testing.T, ulcConfig *eth.ULCConfig) pairPeer { |
| 130 | + peers := newPeerSet() |
| 131 | + dist := newRequestDistributor(peers, make(chan struct{})) |
| 132 | + rm := newRetrieveManager(peers, dist, nil) |
| 133 | + ldb, _ := ethdb.NewMemDatabase() |
| 134 | + |
| 135 | + odr := NewLesOdr(ldb, light.NewChtIndexer(ldb, true), light.NewBloomTrieIndexer(ldb, true), eth.NewBloomIndexer(ldb, light.BloomTrieFrequency), rm) |
| 136 | + |
| 137 | + pmLight := newTestProtocolManagerMust(t, true, 0, nil, peers, odr, ldb, ulcConfig) |
| 138 | + peerPairLight := pairPeer{ |
| 139 | + Name: "ulc node", |
| 140 | + PM: pmLight, |
36 | 141 | } |
| 142 | + rand.Read(peerPairLight.ID[:]) |
37 | 143 |
|
38 | | - lpm.synchronise(lpeer) |
| 144 | + return peerPairLight |
39 | 145 | } |
0 commit comments