gitlab.com/SkynetLabs/skyd@v1.6.9/skymodules/renter/hostdb/persist_test.go (about) 1 package hostdb 2 3 import ( 4 "fmt" 5 "path/filepath" 6 "testing" 7 "time" 8 9 "gitlab.com/NebulousLabs/errors" 10 "gitlab.com/NebulousLabs/fastrand" 11 12 "gitlab.com/SkynetLabs/skyd/build" 13 "gitlab.com/SkynetLabs/skyd/skymodules" 14 "go.sia.tech/siad/modules" 15 "go.sia.tech/siad/types" 16 ) 17 18 // quitAfterLoadDeps will quit startup in newHostDB 19 type quitAfterLoadDeps struct { 20 modules.ProductionDependencies 21 } 22 23 // Send a disrupt signal to the quitAfterLoad codebreak. 24 func (*quitAfterLoadDeps) Disrupt(s string) bool { 25 if s == "quitAfterLoad" { 26 return true 27 } 28 return false 29 } 30 31 // TestSaveLoad tests that the hostdb can save and load itself. 32 func TestSaveLoad(t *testing.T) { 33 if testing.Short() { 34 t.SkipNow() 35 } 36 t.Parallel() 37 hdbt, err := newHDBTester(t.Name()) 38 if err != nil { 39 t.Fatal(err) 40 } 41 42 // Mine two blocks to put the hdb height at 2. 43 for i := 0; i < 2; i++ { 44 _, err := hdbt.miner.AddBlock() 45 if err != nil { 46 t.Fatal(err) 47 } 48 } 49 50 // Verify that the hdb height is 2. 51 if hdbt.hdb.blockHeight != 2 { 52 t.Fatal("test setup incorrect, hdb height needs to be 2 for remainder of test") 53 } 54 55 // Add fake hosts and a fake consensus change. The fake consensus change 56 // would normally be detected and routed around, but we stunt the loading 57 // process to only load the persistent fields. 58 var host1, host2, host3 skymodules.HostDBEntry 59 host1.FirstSeen = 1 60 host2.FirstSeen = 2 61 host3.FirstSeen = 3 62 host1.PublicKey.Key = fastrand.Bytes(32) 63 host2.PublicKey.Key = fastrand.Bytes(32) 64 host3.PublicKey.Key = []byte("baz") 65 hdbt.hdb.staticHostTree.Insert(host1) 66 hdbt.hdb.staticHostTree.Insert(host2) 67 hdbt.hdb.staticHostTree.Insert(host3) 68 69 // Manually set listed Hosts and filterMode 70 filteredHosts := make(map[string]types.SiaPublicKey) 71 filteredHosts[host1.PublicKey.String()] = host1.PublicKey 72 filteredHosts[host2.PublicKey.String()] = host2.PublicKey 73 filteredHosts[host3.PublicKey.String()] = host3.PublicKey 74 filterMode := skymodules.HostDBActiveWhitelist 75 76 // Manually set list of blocked domains 77 badDomain := "baddomain.com" 78 blockedDomains := []string{badDomain} 79 80 // Save, close, and reload. 81 hdbt.hdb.mu.Lock() 82 hdbt.hdb.lastChange = modules.ConsensusChangeID{1, 2, 3} 83 hdbt.hdb.disableIPViolationCheck = true 84 stashedLC := hdbt.hdb.lastChange 85 hdbt.hdb.filteredHosts = filteredHosts 86 hdbt.hdb.filterMode = filterMode 87 hdbt.hdb.staticBlockedDomains = newBlockedDomains(blockedDomains) 88 err = hdbt.hdb.saveSync() 89 hdbt.hdb.mu.Unlock() 90 if err != nil { 91 t.Fatal(err) 92 } 93 err = hdbt.hdb.Close() 94 if err != nil { 95 t.Fatal(err) 96 } 97 var errChan <-chan error 98 hdbt.hdb, errChan = NewCustomHostDB(hdbt.gateway, hdbt.cs, hdbt.tpool, hdbt.mux, filepath.Join(hdbt.persistDir, skymodules.RenterDir), &quitAfterLoadDeps{}) 99 if err := <-errChan; err != nil { 100 t.Fatal(err) 101 } 102 103 // Last change and disableIPViolationCheck should have been reloaded. 104 err = build.Retry(100, 100*time.Millisecond, func() error { 105 hdbt.hdb.mu.Lock() 106 lastChange := hdbt.hdb.lastChange 107 disableIPViolationCheck := hdbt.hdb.disableIPViolationCheck 108 hdbt.hdb.mu.Unlock() 109 if lastChange != stashedLC { 110 return fmt.Errorf("wrong consensus change ID was loaded: %v", hdbt.hdb.lastChange) 111 } 112 if disableIPViolationCheck != true { 113 return errors.New("disableIPViolationCheck should've been true but was false") 114 } 115 return nil 116 }) 117 if err != nil { 118 t.Error(err) 119 } 120 121 // Check that AllHosts was loaded. 122 h1, ok0 := hdbt.hdb.staticHostTree.Select(host1.PublicKey) 123 h2, ok1 := hdbt.hdb.staticHostTree.Select(host2.PublicKey) 124 h3, ok2 := hdbt.hdb.staticHostTree.Select(host3.PublicKey) 125 if !ok0 || !ok1 || !ok2 || len(hdbt.hdb.staticHostTree.All()) != 3 { 126 t.Error("allHosts was not restored properly", ok0, ok1, ok2, len(hdbt.hdb.staticHostTree.All())) 127 } 128 if h1.FirstSeen != 1 { 129 t.Error("h1 block height loaded incorrectly", h1.FirstSeen) 130 } 131 if h2.FirstSeen != 2 { 132 t.Error("h2 block height loaded incorrectly", h2.FirstSeen) 133 } 134 if h3.FirstSeen != 3 { 135 t.Error("h3 block height loaded incorrectly", h3.FirstSeen) 136 } 137 138 // Check that FilterMode was saved 139 if hdbt.hdb.filterMode != skymodules.HostDBActiveWhitelist { 140 t.Error("filter mode should be whitelist") 141 } 142 if _, ok := hdbt.hdb.filteredHosts[host1.PublicKey.String()]; !ok { 143 t.Error("host1 not found in filteredHosts") 144 } 145 if _, ok := hdbt.hdb.filteredHosts[host2.PublicKey.String()]; !ok { 146 t.Error("host2 not found in filteredHosts") 147 } 148 if _, ok := hdbt.hdb.filteredHosts[host3.PublicKey.String()]; !ok { 149 t.Error("host3 not found in filteredHosts") 150 } 151 152 // Check that the blocked domains were saved 153 bd := hdbt.hdb.staticBlockedDomains 154 bd.mu.Lock() 155 _, ok := bd.domains[badDomain] 156 bd.mu.Unlock() 157 if !ok { 158 t.Fatal("badDomain not found in blockedDomains", hdbt.hdb.staticBlockedDomains) 159 } 160 } 161 162 // TestRescan tests that the hostdb will rescan the blockchain properly, picking 163 // up new hosts which appear in an alternate past. 164 func TestRescan(t *testing.T) { 165 if testing.Short() { 166 t.SkipNow() 167 } 168 _, err := newHDBTester(t.Name()) 169 if err != nil { 170 t.Fatal(err) 171 } 172 173 t.Skip("create two consensus sets with blocks + announcements") 174 }