github.com/nebulouslabs/sia@v1.3.7/modules/host/announce_test.go (about) 1 package host 2 3 import ( 4 "bytes" 5 "testing" 6 7 "github.com/NebulousLabs/Sia/modules" 8 "github.com/NebulousLabs/Sia/types" 9 ) 10 11 // announcementFinder is a quick module that parses the blockchain for host 12 // announcements, keeping a record of all the announcements that get found. 13 type announcementFinder struct { 14 cs modules.ConsensusSet 15 16 // Announcements that have been seen. The two slices are wedded. 17 netAddresses []modules.NetAddress 18 publicKeys []types.SiaPublicKey 19 } 20 21 // ProcessConsensusChange receives consensus changes from the consensus set and 22 // parses them for valid host announcements. 23 func (af *announcementFinder) ProcessConsensusChange(cc modules.ConsensusChange) { 24 for _, block := range cc.AppliedBlocks { 25 for _, txn := range block.Transactions { 26 for _, arb := range txn.ArbitraryData { 27 addr, pubKey, err := modules.DecodeAnnouncement(arb) 28 if err == nil { 29 af.netAddresses = append(af.netAddresses, addr) 30 af.publicKeys = append(af.publicKeys, pubKey) 31 } 32 } 33 } 34 } 35 } 36 37 // Close will shut down the announcement finder. 38 func (af *announcementFinder) Close() error { 39 af.cs.Unsubscribe(af) 40 return nil 41 } 42 43 // newAnnouncementFinder will create and return an announcement finder. 44 func newAnnouncementFinder(cs modules.ConsensusSet) (*announcementFinder, error) { 45 af := &announcementFinder{ 46 cs: cs, 47 } 48 err := cs.ConsensusSetSubscribe(af, modules.ConsensusChangeBeginning, nil) 49 if err != nil { 50 return nil, err 51 } 52 return af, nil 53 } 54 55 // TestHostAnnounce checks that the host announce function is operating 56 // correctly. 57 func TestHostAnnounce(t *testing.T) { 58 if testing.Short() { 59 t.SkipNow() 60 } 61 t.Parallel() 62 ht, err := newHostTester("TestHostAnnounce") 63 if err != nil { 64 t.Fatal(err) 65 } 66 defer ht.Close() 67 68 // Create an announcement finder to scan the blockchain for host 69 // announcements. 70 af, err := newAnnouncementFinder(ht.cs) 71 if err != nil { 72 t.Fatal(err) 73 } 74 defer af.Close() 75 76 // Create an announcement, then use the address finding module to scan the 77 // blockchain for the host's address. 78 err = ht.host.Announce() 79 if err != nil { 80 t.Fatal(err) 81 } 82 _, err = ht.miner.AddBlock() 83 if err != nil { 84 t.Fatal(err) 85 } 86 if len(af.publicKeys) != 1 { 87 t.Fatal("could not find host announcement in blockchain") 88 } 89 if af.netAddresses[0] != ht.host.autoAddress { 90 t.Error("announcement has wrong address") 91 } 92 if !bytes.Equal(af.publicKeys[0].Key, ht.host.publicKey.Key) { 93 t.Error("announcement has wrong host key") 94 } 95 } 96 97 // TestHostAnnounceAddress checks that the host announce address function is 98 // operating correctly. 99 func TestHostAnnounceAddress(t *testing.T) { 100 if testing.Short() { 101 t.SkipNow() 102 } 103 t.Parallel() 104 ht, err := newHostTester("TestHostAnnounceAddress") 105 if err != nil { 106 t.Fatal(err) 107 } 108 defer ht.Close() 109 110 // Create an announcement finder to scan the blockchain for host 111 // announcements. 112 af, err := newAnnouncementFinder(ht.cs) 113 if err != nil { 114 t.Fatal(err) 115 } 116 defer af.Close() 117 118 // Create an announcement, then use the address finding module to scan the 119 // blockchain for the host's address. 120 addr := modules.NetAddress("foo.com:1234") 121 err = ht.host.AnnounceAddress(addr) 122 if err != nil { 123 t.Fatal(err) 124 } 125 _, err = ht.miner.AddBlock() 126 if err != nil { 127 t.Fatal(err) 128 } 129 if len(af.netAddresses) != 1 { 130 t.Fatal("could not find host announcement in blockchain") 131 } 132 if af.netAddresses[0] != addr { 133 t.Error("announcement has wrong address") 134 } 135 if !bytes.Equal(af.publicKeys[0].Key, ht.host.publicKey.Key) { 136 t.Error("announcement has wrong host key") 137 } 138 } 139 140 // TestHostAnnounceCheckUnlockHash verifies that the host's unlock hash is 141 // checked when an announcement is performed. 142 func TestHostAnnounceCheckUnlockHash(t *testing.T) { 143 if testing.Short() { 144 t.SkipNow() 145 } 146 t.Parallel() 147 ht, err := newHostTester(t.Name()) 148 if err != nil { 149 t.Fatal(err) 150 } 151 defer ht.Close() 152 153 ht.host.mu.RLock() 154 oldUnlockHash := ht.host.unlockHash 155 ht.host.mu.RUnlock() 156 157 err = ht.wallet.Reset() 158 if err != nil { 159 t.Fatal(err) 160 } 161 err = ht.initWallet() 162 if err != nil { 163 t.Fatal(err) 164 } 165 for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { 166 _, err = ht.miner.AddBlock() 167 if err != nil { 168 t.Fatal(err) 169 } 170 } 171 err = ht.host.Announce() 172 if err != nil { 173 t.Fatal(err) 174 } 175 _, err = ht.miner.AddBlock() 176 if err != nil { 177 t.Fatal(err) 178 } 179 ht.host.mu.RLock() 180 newUnlockHash := ht.host.unlockHash 181 ht.host.mu.RUnlock() 182 if newUnlockHash == oldUnlockHash { 183 t.Fatal("host did not set a new unlock hash after announce with reset wallet") 184 } 185 hasAddr := false 186 addrs, err := ht.wallet.AllAddresses() 187 if err != nil { 188 t.Fatal(err) 189 } 190 for _, addr := range addrs { 191 if addr == newUnlockHash { 192 hasAddr = true 193 break 194 } 195 } 196 if !hasAddr { 197 t.Fatal("host unlock has did not exist in wallet") 198 } 199 }