github.com/Synthesix/Sia@v1.3.3-0.20180413141344-f863baeed3ca/node/api/consensus.go (about)

     1  package api
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  
     8  	"github.com/Synthesix/Sia/types"
     9  
    10  	"github.com/julienschmidt/httprouter"
    11  )
    12  
    13  // ConsensusGET contains general information about the consensus set, with tags
    14  // to support idiomatic json encodings.
    15  type ConsensusGET struct {
    16  	Synced       bool              `json:"synced"`
    17  	Height       types.BlockHeight `json:"height"`
    18  	CurrentBlock types.BlockID     `json:"currentblock"`
    19  	Target       types.Target      `json:"target"`
    20  	Difficulty   types.Currency    `json:"difficulty"`
    21  }
    22  
    23  // ConsensusHeadersGET contains information from a blocks header.
    24  type ConsensusHeadersGET struct {
    25  	BlockID types.BlockID `json:"blockid"`
    26  }
    27  
    28  // consensusHandler handles the API calls to /consensus.
    29  func (api *API) consensusHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
    30  	cbid := api.cs.CurrentBlock().ID()
    31  	currentTarget, _ := api.cs.ChildTarget(cbid)
    32  	WriteJSON(w, ConsensusGET{
    33  		Synced:       api.cs.Synced(),
    34  		Height:       api.cs.Height(),
    35  		CurrentBlock: cbid,
    36  		Target:       currentTarget,
    37  		Difficulty:   currentTarget.Difficulty(),
    38  	})
    39  }
    40  
    41  // consensusBlocksIDHandler handles the API calls to /consensus/blocks
    42  // endpoint.
    43  func (api *API) consensusBlocksHandler(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
    44  	// Get query params and check them.
    45  	id, height := req.FormValue("id"), req.FormValue("height")
    46  	if id != "" && height != "" {
    47  		WriteError(w, Error{"can't specify both id and height"}, http.StatusBadRequest)
    48  	}
    49  	if id == "" && height == "" {
    50  		WriteError(w, Error{"either id or height has to be provided"}, http.StatusBadRequest)
    51  	}
    52  
    53  	var b types.Block
    54  	var exists bool
    55  
    56  	// Handle request by id
    57  	if id != "" {
    58  		var bid types.BlockID
    59  		if err := bid.LoadString(id); err != nil {
    60  			WriteError(w, Error{"failed to unmarshal blockid"}, http.StatusBadRequest)
    61  			return
    62  		}
    63  		b, exists = api.cs.BlockByID(bid)
    64  	}
    65  	// Handle request by height
    66  	if height != "" {
    67  		var h uint64
    68  		if _, err := fmt.Sscan(height, &h); err != nil {
    69  			WriteError(w, Error{"failed to parse block height"}, http.StatusBadRequest)
    70  			return
    71  		}
    72  		b, exists = api.cs.BlockAtHeight(types.BlockHeight(h))
    73  	}
    74  	// Check if block was found
    75  	if !exists {
    76  		WriteError(w, Error{"block doesn't exist"}, http.StatusBadRequest)
    77  		return
    78  	}
    79  	// Write response
    80  	WriteJSON(w, b)
    81  }
    82  
    83  // consensusValidateTransactionsetHandler handles the API calls to
    84  // /consensus/validate/transactionset.
    85  func (api *API) consensusValidateTransactionsetHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
    86  	var txnset []types.Transaction
    87  	err := json.NewDecoder(req.Body).Decode(&txnset)
    88  	if err != nil {
    89  		WriteError(w, Error{"could not decode transaction set: " + err.Error()}, http.StatusBadRequest)
    90  		return
    91  	}
    92  	_, err = api.cs.TryTransactionSet(txnset)
    93  	if err != nil {
    94  		WriteError(w, Error{"transaction set validation failed: " + err.Error()}, http.StatusBadRequest)
    95  		return
    96  	}
    97  	WriteSuccess(w)
    98  }