gitlab.com/SiaPrime/SiaPrime@v1.4.1/node/api/transactionpool.go (about) 1 package api 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "net/http" 7 8 "github.com/julienschmidt/httprouter" 9 10 "gitlab.com/SiaPrime/SiaPrime/crypto" 11 "gitlab.com/SiaPrime/SiaPrime/encoding" 12 "gitlab.com/SiaPrime/SiaPrime/modules" 13 "gitlab.com/SiaPrime/SiaPrime/types" 14 ) 15 16 type ( 17 // TpoolFeeGET contains the current estimated fee 18 TpoolFeeGET struct { 19 Minimum types.Currency `json:"minimum"` 20 Maximum types.Currency `json:"maximum"` 21 } 22 23 // TpoolRawGET contains the requested transaction encoded to the raw 24 // format, along with the id of that transaction. 25 TpoolRawGET struct { 26 ID types.TransactionID `json:"id"` 27 Parents []byte `json:"parents"` 28 Transaction []byte `json:"transaction"` 29 } 30 31 // TpoolConfirmedGET contains information about whether or not 32 // the transaction has been seen on the blockhain 33 TpoolConfirmedGET struct { 34 Confirmed bool `json:"confirmed"` 35 } 36 ) 37 38 // decodeTransactionID will decode a transaction id from a string. 39 func decodeTransactionID(txidStr string) (types.TransactionID, error) { 40 txid := new(crypto.Hash) 41 err := txid.LoadString(txidStr) 42 if err != nil { 43 return types.TransactionID{}, err 44 } 45 return types.TransactionID(*txid), nil 46 } 47 48 // tpoolFeeHandlerGET returns the current estimated fee. Transactions with 49 // fees are lower than the estimated fee may take longer to confirm. 50 func (api *API) tpoolFeeHandlerGET(w http.ResponseWriter, req *http.Request, ps httprouter.Params) { 51 min, max := api.tpool.FeeEstimation() 52 WriteJSON(w, TpoolFeeGET{ 53 Minimum: min, 54 Maximum: max, 55 }) 56 } 57 58 // tpoolRawHandlerGET will provide the raw byte representation of a 59 // transaction that matches the input id. 60 func (api *API) tpoolRawHandlerGET(w http.ResponseWriter, req *http.Request, ps httprouter.Params) { 61 txid, err := decodeTransactionID(ps.ByName("id")) 62 if err != nil { 63 WriteError(w, Error{"error decoding transaction id:" + err.Error()}, http.StatusBadRequest) 64 return 65 } 66 txn, parents, exists := api.tpool.Transaction(txid) 67 if !exists { 68 WriteError(w, Error{"transaction not found in transaction pool"}, http.StatusBadRequest) 69 return 70 } 71 72 WriteJSON(w, TpoolRawGET{ 73 ID: txid, 74 Parents: encoding.Marshal(parents), 75 Transaction: encoding.Marshal(txn), 76 }) 77 } 78 79 // tpoolRawHandlerPOST takes a raw encoded transaction set and posts 80 // it to the transaction pool, relaying it to the transaction pool's peers 81 // regardless of if the set is accepted. 82 func (api *API) tpoolRawHandlerPOST(w http.ResponseWriter, req *http.Request, _ httprouter.Params) { 83 var parents []types.Transaction 84 var txn types.Transaction 85 86 // JSON, base64, and raw binary are accepted 87 if err := json.Unmarshal([]byte(req.FormValue("parents")), &parents); err != nil { 88 rawParents, err := base64.StdEncoding.DecodeString(req.FormValue("parents")) 89 if err != nil { 90 rawParents = []byte(req.FormValue("parents")) 91 } 92 if err := encoding.Unmarshal(rawParents, &parents); err != nil { 93 WriteError(w, Error{"error decoding parents:" + err.Error()}, http.StatusBadRequest) 94 return 95 } 96 } 97 if err := json.Unmarshal([]byte(req.FormValue("transaction")), &txn); err != nil { 98 rawTransaction, err := base64.StdEncoding.DecodeString(req.FormValue("transaction")) 99 if err != nil { 100 rawTransaction = []byte(req.FormValue("transaction")) 101 } 102 if err := encoding.Unmarshal(rawTransaction, &txn); err != nil { 103 WriteError(w, Error{"error decoding transaction:" + err.Error()}, http.StatusBadRequest) 104 return 105 } 106 } 107 // Broadcast the transaction set, so that they are passed to any peers that 108 // may have rejected them earlier. 109 txnSet := append(parents, txn) 110 api.tpool.Broadcast(txnSet) 111 err := api.tpool.AcceptTransactionSet(txnSet) 112 if err != nil && err != modules.ErrDuplicateTransactionSet { 113 WriteError(w, Error{"error accepting transaction set:" + err.Error()}, http.StatusBadRequest) 114 return 115 } 116 WriteSuccess(w) 117 } 118 119 // tpoolConfirmedGET returns whether the specified transaction has 120 // been seen on the blockchain. 121 func (api *API) tpoolConfirmedGET(w http.ResponseWriter, req *http.Request, ps httprouter.Params) { 122 txid, err := decodeTransactionID(ps.ByName("id")) 123 if err != nil { 124 WriteError(w, Error{"error decoding transaction id:" + err.Error()}, http.StatusBadRequest) 125 return 126 } 127 confirmed, err := api.tpool.TransactionConfirmed(txid) 128 if err != nil { 129 WriteError(w, Error{"error fetching transaction status:" + err.Error()}, http.StatusBadRequest) 130 return 131 } 132 WriteJSON(w, TpoolConfirmedGET{ 133 Confirmed: confirmed, 134 }) 135 }