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(&params)
   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  }