github.com/annchain/OG@v0.0.9/tests/test_tps/httpclient.go (about)

     1  // Copyright © 2019 Annchain Authors <EMAIL ADDRESS>
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by TxClientlicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package main
    15  
    16  import (
    17  	"bytes"
    18  	"encoding/json"
    19  	"errors"
    20  	"fmt"
    21  	"github.com/annchain/OG/common"
    22  	"github.com/annchain/OG/rpc"
    23  	"github.com/sirupsen/logrus"
    24  	"io/ioutil"
    25  	"net"
    26  	"net/http"
    27  	"time"
    28  )
    29  
    30  func newTransport() *http.Transport {
    31  	transport := &http.Transport{
    32  		MaxIdleConnsPerHost: 15,
    33  		Proxy:               http.ProxyFromEnvironment,
    34  		DialContext: (&net.Dialer{
    35  			Timeout:   10 * time.Second,
    36  			KeepAlive: 30 * time.Second,
    37  		}).DialContext,
    38  		MaxIdleConns:          100,
    39  		IdleConnTimeout:       90 * time.Second,
    40  		TLSHandshakeTimeout:   10 * time.Second,
    41  		ExpectContinueTimeout: 1 * time.Second,
    42  	}
    43  	return transport
    44  }
    45  
    46  func NewTxClient(Host string) TxClient {
    47  	a := TxClient{
    48  		httpClient: &http.Client{
    49  			Timeout:   time.Second * 10,
    50  			Transport: newTransport(),
    51  		},
    52  		requestChan: make(chan *rpc.NewTxRequest, 100),
    53  		quit:        make(chan bool),
    54  	}
    55  	a.Host = Host
    56  	return a
    57  }
    58  
    59  type TxClient struct {
    60  	httpClient  *http.Client
    61  	requestChan chan *rpc.NewTxRequest
    62  	quit        chan bool
    63  	Host        string
    64  }
    65  
    66  func (a *TxClient) StartAsyncLoop() {
    67  	go a.ConsumeQueue()
    68  }
    69  
    70  func (a *TxClient) Stop() {
    71  	close(a.quit)
    72  }
    73  
    74  func (A *TxClient) SendAsyncTx(Req *rpc.NewTxRequest) {
    75  	A.requestChan <- Req
    76  }
    77  
    78  func (o *TxClient) ConsumeQueue() {
    79  	i := 0
    80  	for {
    81  		logrus.WithField("size", len(o.requestChan)).Debug("og queue size")
    82  		select {
    83  		case data := <-o.requestChan:
    84  			i++
    85  			if debug {
    86  				fmt.Println(data)
    87  			}
    88  			resp, err := o.SendNormalTx(data)
    89  			if err != nil {
    90  				logrus.WithField("resp", resp).WithError(err).Warnf("failed to send to ledger")
    91  			}
    92  		case <-o.quit:
    93  			logrus.Info("OgProcessor stopped")
    94  			return
    95  		}
    96  	}
    97  
    98  }
    99  
   100  func (a *TxClient) SendNormalTx(request *rpc.NewTxRequest) (string, error) {
   101  	return a.sendTx(request, "new_transaction", "POST")
   102  }
   103  
   104  func (a *TxClient) SendTokenIPO(request *rpc.NewPublicOfferingRequest) (string, error) {
   105  	return a.sendTx(request, "token", "POST")
   106  }
   107  
   108  func (a *TxClient) SendTokenSPO(request *rpc.NewPublicOfferingRequest) (string, error) {
   109  	return a.sendTx(request, "token", "PUT")
   110  }
   111  
   112  func (a *TxClient) SendTokenDestroy(request *rpc.NewPublicOfferingRequest) (string, error) {
   113  	return a.sendTx(request, "token", "DELETE")
   114  }
   115  
   116  func (a *TxClient) sendTx(request interface{}, uri string, methd string) (string, error) {
   117  	//req := httplib.NewBeegoRequest(url,"POST")
   118  	//req.SetTimeout(time.Second*10,time.Second*10)
   119  	data, err := json.Marshal(request)
   120  	if err != nil {
   121  		panic(err)
   122  	}
   123  	r := bytes.NewReader(data)
   124  	url := a.Host + "/" + "uri"
   125  	req, err := http.NewRequest(methd, url, r)
   126  
   127  	resp, err := a.httpClient.Do(req)
   128  	if err != nil {
   129  		fmt.Println(err)
   130  		return "", err
   131  	}
   132  	//now := time.Now()
   133  	defer resp.Body.Close()
   134  	resDate, err := ioutil.ReadAll(resp.Body)
   135  	if err != nil {
   136  		panic(err)
   137  	}
   138  
   139  	str := string(resDate)
   140  	if err != nil {
   141  		fmt.Println(str, err)
   142  		return "", err
   143  	}
   144  	if resp.StatusCode != 200 {
   145  		//panic( resp.StatusCode)
   146  		fmt.Println(resp.StatusCode)
   147  		return "", errors.New(resp.Status)
   148  	}
   149  	var respStruct struct {
   150  		Data string `json:"data"`
   151  	}
   152  	err = json.Unmarshal(resDate, &respStruct)
   153  	if err != nil {
   154  		fmt.Println(str, err)
   155  		return "", err
   156  	}
   157  	if debug {
   158  		fmt.Println(respStruct.Data)
   159  	}
   160  	return respStruct.Data, nil
   161  }
   162  
   163  func (a *TxClient) getNonce(addr common.Address) (nonce uint64) {
   164  	uri := fmt.Sprintf("query_nonce?address=%s", addr.Hex())
   165  	url := a.Host + "/" + uri
   166  	req, err := http.NewRequest("GET", url, nil)
   167  	resp, err := a.httpClient.Do(req)
   168  	if err != nil {
   169  		fmt.Println(err)
   170  		return 0
   171  	}
   172  	//now := time.Now()
   173  	defer resp.Body.Close()
   174  	resDate, err := ioutil.ReadAll(resp.Body)
   175  	if err != nil {
   176  		panic(err)
   177  	}
   178  	str := string(resDate)
   179  	if err != nil {
   180  		fmt.Println(str, err)
   181  		return 0
   182  	}
   183  	if resp.StatusCode != 200 {
   184  		//panic( resp.StatusCode)
   185  		fmt.Println(resp.StatusCode)
   186  		return 0
   187  	}
   188  	var nonceResp struct {
   189  		Nonce uint64 `json:"nonce"`
   190  	}
   191  	err = json.Unmarshal(resDate, &nonceResp)
   192  	if err != nil {
   193  		fmt.Println("encode nonce errror ", err)
   194  		return 0
   195  	}
   196  	return nonceResp.Nonce
   197  }