github.com/tdcblockchain/tdcblockchain@v0.0.0-20191111034745-805c65ade158/les/sync_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 "fmt" 21 "math/big" 22 "testing" 23 "time" 24 25 "github.com/ethereum/go-ethereum/accounts/abi/bind" 26 "github.com/ethereum/go-ethereum/core" 27 "github.com/ethereum/go-ethereum/crypto" 28 "github.com/ethereum/go-ethereum/light" 29 "github.com/ethereum/go-ethereum/params" 30 ) 31 32 // Test light syncing which will download all headers from genesis. 33 func TestLightSyncingLes2(t *testing.T) { testCheckpointSyncing(t, 2, 0) } 34 func TestLightSyncingLes3(t *testing.T) { testCheckpointSyncing(t, 3, 0) } 35 36 // Test legacy checkpoint syncing which will download tail headers 37 // based on a hardcoded checkpoint. 38 func TestLegacyCheckpointSyncingLes2(t *testing.T) { testCheckpointSyncing(t, 2, 1) } 39 func TestLegacyCheckpointSyncingLes3(t *testing.T) { testCheckpointSyncing(t, 3, 1) } 40 41 // Test checkpoint syncing which will download tail headers based 42 // on a verified checkpoint. 43 func TestCheckpointSyncingLes2(t *testing.T) { testCheckpointSyncing(t, 2, 2) } 44 func TestCheckpointSyncingLes3(t *testing.T) { testCheckpointSyncing(t, 3, 2) } 45 46 func testCheckpointSyncing(t *testing.T, protocol int, syncMode int) { 47 config := light.TestServerIndexerConfig 48 49 waitIndexers := func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) { 50 for { 51 cs, _, _ := cIndexer.Sections() 52 bts, _, _ := btIndexer.Sections() 53 if cs >= 1 && bts >= 1 { 54 break 55 } 56 time.Sleep(10 * time.Millisecond) 57 } 58 } 59 // Generate 512+4 blocks (totally 1 CHT sections) 60 server, client, tearDown := newClientServerEnv(t, int(config.ChtSize+config.ChtConfirms), protocol, waitIndexers, nil, 0, false, false) 61 defer tearDown() 62 63 expected := config.ChtSize + config.ChtConfirms 64 65 // Checkpoint syncing or legacy checkpoint syncing. 66 if syncMode == 1 || syncMode == 2 { 67 // Assemble checkpoint 0 68 s, _, head := server.chtIndexer.Sections() 69 cp := ¶ms.TrustedCheckpoint{ 70 SectionIndex: 0, 71 SectionHead: head, 72 CHTRoot: light.GetChtRoot(server.db, s-1, head), 73 BloomRoot: light.GetBloomTrieRoot(server.db, s-1, head), 74 } 75 if syncMode == 1 { 76 // Register the assembled checkpoint as hardcoded one. 77 client.handler.checkpoint = cp 78 client.handler.backend.blockchain.AddTrustedCheckpoint(cp) 79 } else { 80 // Register the assembled checkpoint into oracle. 81 header := server.backend.Blockchain().CurrentHeader() 82 83 data := append([]byte{0x19, 0x00}, append(registrarAddr.Bytes(), append([]byte{0, 0, 0, 0, 0, 0, 0, 0}, cp.Hash().Bytes()...)...)...) 84 sig, _ := crypto.Sign(crypto.Keccak256(data), signerKey) 85 sig[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper 86 if _, err := server.handler.server.oracle.contract.RegisterCheckpoint(bind.NewKeyedTransactor(signerKey), cp.SectionIndex, cp.Hash().Bytes(), new(big.Int).Sub(header.Number, big.NewInt(1)), header.ParentHash, [][]byte{sig}); err != nil { 87 t.Error("register checkpoint failed", err) 88 } 89 server.backend.Commit() 90 91 // Wait for the checkpoint registration 92 for { 93 _, hash, _, err := server.handler.server.oracle.contract.Contract().GetLatestCheckpoint(nil) 94 if err != nil || hash == [32]byte{} { 95 time.Sleep(100 * time.Millisecond) 96 continue 97 } 98 break 99 } 100 expected += 1 101 } 102 } 103 104 done := make(chan error) 105 client.handler.backend.oracle.syncDoneHook = func() { 106 header := client.handler.backend.blockchain.CurrentHeader() 107 if header.Number.Uint64() == expected { 108 done <- nil 109 } else { 110 done <- fmt.Errorf("blockchain length mismatch, want %d, got %d", expected, header.Number) 111 } 112 } 113 114 // Create connected peer pair. 115 _, err1, _, err2 := newTestPeerPair("peer", protocol, server.handler, client.handler) 116 select { 117 case <-time.After(time.Millisecond * 100): 118 case err := <-err1: 119 t.Fatalf("peer 1 handshake error: %v", err) 120 case err := <-err2: 121 t.Fatalf("peer 2 handshake error: %v", err) 122 } 123 124 select { 125 case err := <-done: 126 if err != nil { 127 t.Error("sync failed", err) 128 } 129 return 130 case <-time.NewTimer(10 * time.Second).C: 131 t.Error("checkpoint syncing timeout") 132 } 133 }