gitlab.com/SiaPrime/SiaPrime@v1.4.1/node/api/hostdb.go (about) 1 package api 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 8 "gitlab.com/SiaPrime/SiaPrime/modules" 9 "gitlab.com/SiaPrime/SiaPrime/types" 10 11 "github.com/julienschmidt/httprouter" 12 ) 13 14 type ( 15 // ExtendedHostDBEntry is an extension to modules.HostDBEntry that includes 16 // the string representation of the public key, otherwise presented as two 17 // fields, a string and a base64 encoded byte slice. 18 ExtendedHostDBEntry struct { 19 modules.HostDBEntry 20 PublicKeyString string `json:"publickeystring"` 21 } 22 23 // HostdbActiveGET lists active hosts on the network. 24 HostdbActiveGET struct { 25 Hosts []ExtendedHostDBEntry `json:"hosts"` 26 } 27 28 // HostdbAllGET lists all hosts that the renter is aware of. 29 HostdbAllGET struct { 30 Hosts []ExtendedHostDBEntry `json:"hosts"` 31 } 32 33 // HostdbHostsGET lists detailed statistics for a particular host, selected 34 // by pubkey. 35 HostdbHostsGET struct { 36 Entry ExtendedHostDBEntry `json:"entry"` 37 ScoreBreakdown modules.HostScoreBreakdown `json:"scorebreakdown"` 38 } 39 40 // HostdbGet holds information about the hostdb. 41 HostdbGet struct { 42 InitialScanComplete bool `json:"initialscancomplete"` 43 } 44 45 // HostdbFilterModeGET contains the information about the HostDB's 46 // filtermode 47 HostdbFilterModeGET struct { 48 FilterMode string `json:"filtermode"` 49 Hosts []string `json:"hosts"` 50 } 51 52 // HostdbFilterModePOST contains the information needed to set the the 53 // FilterMode of the hostDB 54 HostdbFilterModePOST struct { 55 FilterMode string `json:"filtermode"` 56 Hosts []types.SiaPublicKey `json:"hosts"` 57 } 58 ) 59 60 // hostdbHandler handles the API call asking for the list of active 61 // hosts. 62 func (api *API) hostdbHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) { 63 isc, err := api.renter.InitialScanComplete() 64 if err != nil { 65 WriteError(w, Error{"Failed to get initial scan status" + err.Error()}, http.StatusInternalServerError) 66 return 67 } 68 WriteJSON(w, HostdbGet{ 69 InitialScanComplete: isc, 70 }) 71 } 72 73 // hostdbActiveHandler handles the API call asking for the list of active 74 // hosts. 75 func (api *API) hostdbActiveHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) { 76 var numHosts uint64 77 hosts := api.renter.ActiveHosts() 78 79 if req.FormValue("numhosts") == "" { 80 // Default value for 'numhosts' is all of them. 81 numHosts = uint64(len(hosts)) 82 } else { 83 // Parse the value for 'numhosts'. 84 _, err := fmt.Sscan(req.FormValue("numhosts"), &numHosts) 85 if err != nil { 86 WriteError(w, Error{err.Error()}, http.StatusBadRequest) 87 return 88 } 89 90 // Catch any boundary errors. 91 if numHosts > uint64(len(hosts)) { 92 numHosts = uint64(len(hosts)) 93 } 94 } 95 96 // Convert the entries into extended entries. 97 var extendedHosts []ExtendedHostDBEntry 98 for _, host := range hosts { 99 extendedHosts = append(extendedHosts, ExtendedHostDBEntry{ 100 HostDBEntry: host, 101 PublicKeyString: host.PublicKey.String(), 102 }) 103 } 104 105 WriteJSON(w, HostdbActiveGET{ 106 Hosts: extendedHosts[:numHosts], 107 }) 108 } 109 110 // hostdbAllHandler handles the API call asking for the list of all hosts. 111 func (api *API) hostdbAllHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) { 112 // Get the set of all hosts and convert them into extended hosts. 113 hosts := api.renter.AllHosts() 114 var extendedHosts []ExtendedHostDBEntry 115 for _, host := range hosts { 116 extendedHosts = append(extendedHosts, ExtendedHostDBEntry{ 117 HostDBEntry: host, 118 PublicKeyString: host.PublicKey.String(), 119 }) 120 } 121 122 WriteJSON(w, HostdbAllGET{ 123 Hosts: extendedHosts, 124 }) 125 } 126 127 // hostdbHostsHandler handles the API call asking for a specific host, 128 // returning detailed information about that host. 129 func (api *API) hostdbHostsHandler(w http.ResponseWriter, req *http.Request, ps httprouter.Params) { 130 var pk types.SiaPublicKey 131 pk.LoadString(ps.ByName("pubkey")) 132 133 entry, exists := api.renter.Host(pk) 134 if !exists { 135 WriteError(w, Error{"requested host does not exist"}, http.StatusBadRequest) 136 return 137 } 138 breakdown, err := api.renter.ScoreBreakdown(entry) 139 if err != nil { 140 WriteError(w, Error{"error calculating score breakdown: " + err.Error()}, http.StatusInternalServerError) 141 return 142 } 143 144 // Extend the hostdb entry to have the public key string. 145 extendedEntry := ExtendedHostDBEntry{ 146 HostDBEntry: entry, 147 PublicKeyString: entry.PublicKey.String(), 148 } 149 WriteJSON(w, HostdbHostsGET{ 150 Entry: extendedEntry, 151 ScoreBreakdown: breakdown, 152 }) 153 } 154 155 // hostdbFilterModeHandlerGET handles the API call to get the hostdb's filter 156 // mode 157 func (api *API) hostdbFilterModeHandlerGET(w http.ResponseWriter, _ *http.Request, _ httprouter.Params) { 158 // Get FilterMode 159 fm, hostMap, err := api.renter.Filter() 160 if err != nil { 161 WriteError(w, Error{"unable to get filter mode: " + err.Error()}, http.StatusBadRequest) 162 return 163 } 164 // Build Slice of PubKeys 165 var hosts []string 166 for key := range hostMap { 167 hosts = append(hosts, key) 168 } 169 WriteJSON(w, HostdbFilterModeGET{ 170 FilterMode: fm.String(), 171 Hosts: hosts, 172 }) 173 } 174 175 // hostdbFilterModeHandlerPOST handles the API call to set the hostdb's filter 176 // mode 177 func (api *API) hostdbFilterModeHandlerPOST(w http.ResponseWriter, req *http.Request, _ httprouter.Params) { 178 // Parse parameters 179 var params HostdbFilterModePOST 180 err := json.NewDecoder(req.Body).Decode(¶ms) 181 if err != nil { 182 WriteError(w, Error{"invalid parameters: " + err.Error()}, http.StatusBadRequest) 183 return 184 } 185 186 var fm modules.FilterMode 187 if err = fm.FromString(params.FilterMode); err != nil { 188 WriteError(w, Error{"unable to load filter mode from string: " + err.Error()}, http.StatusBadRequest) 189 return 190 } 191 192 // Set list mode 193 if err := api.renter.SetFilterMode(fm, params.Hosts); err != nil { 194 WriteError(w, Error{"failed to set the list mode: " + err.Error()}, http.StatusBadRequest) 195 return 196 } 197 WriteSuccess(w) 198 }