github.com/annchain/OG@v0.0.9/client/tx_client/client.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 tx_client
    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(timeOut time.Duration) *http.Transport {
    31  	transport := &http.Transport{
    32  		MaxIdleConnsPerHost: 15,
    33  		Proxy:               http.ProxyFromEnvironment,
    34  		DialContext: (&net.Dialer{
    35  			Timeout:   timeOut,
    36  			KeepAlive: timeOut * 3,
    37  		}).DialContext,
    38  		MaxIdleConns:          100,
    39  		IdleConnTimeout:       timeOut * 9,
    40  		TLSHandshakeTimeout:   timeOut,
    41  		ExpectContinueTimeout: timeOut / 10,
    42  	}
    43  	return transport
    44  }
    45  
    46  func NewTxClient(Host string, debug bool) TxClient {
    47  	a := TxClient{
    48  		httpClient: &http.Client{
    49  			Timeout:   time.Second * 10,
    50  			Transport: newTransport(time.Second * 10),
    51  		},
    52  		requestChan: make(chan *rpc.NewTxRequest, 100),
    53  		quit:        make(chan bool),
    54  		Host:        Host,
    55  		Debug:       debug,
    56  	}
    57  	return a
    58  }
    59  
    60  func NewTxClientWIthTimeOut(Host string, debug bool, timeOut time.Duration) TxClient {
    61  	a := TxClient{
    62  		httpClient: &http.Client{
    63  			Timeout:   timeOut,
    64  			Transport: newTransport(timeOut),
    65  		},
    66  		requestChan: make(chan *rpc.NewTxRequest, 100),
    67  		quit:        make(chan bool),
    68  		Host:        Host,
    69  		Debug:       debug,
    70  	}
    71  	return a
    72  }
    73  
    74  type TxClient struct {
    75  	httpClient  *http.Client
    76  	requestChan chan *rpc.NewTxRequest
    77  	quit        chan bool
    78  	Host        string
    79  	Debug       bool
    80  }
    81  
    82  func (a *TxClient) StartAsyncLoop() {
    83  	go a.ConsumeQueue()
    84  }
    85  
    86  func (a *TxClient) Stop() {
    87  	close(a.quit)
    88  }
    89  
    90  func (A *TxClient) SendAsyncTx(Req *rpc.NewTxRequest) {
    91  	A.requestChan <- Req
    92  }
    93  
    94  func (o *TxClient) ConsumeQueue() {
    95  	i := 0
    96  	for {
    97  		logrus.WithField("size", len(o.requestChan)).Debug("og queue size")
    98  		select {
    99  		case data := <-o.requestChan:
   100  			i++
   101  			if o.Debug {
   102  				fmt.Println(data)
   103  			}
   104  			resp, err := o.SendNormalTx(data)
   105  			if err != nil {
   106  				logrus.WithField("resp", resp).WithError(err).Warnf("failed to send to ledger")
   107  			}
   108  		case <-o.quit:
   109  			logrus.Info("OgProcessor stopped")
   110  			return
   111  		}
   112  	}
   113  
   114  }
   115  
   116  func (a *TxClient) SendNormalTx(request *rpc.NewTxRequest) (string, error) {
   117  	return a.sendTx(request, "new_transaction", "POST")
   118  }
   119  
   120  func (a *TxClient) SendNormalTxs(request *rpc.NewTxsRequests) (string, error) {
   121  	return a.sendTxs(request, "new_transactions", "POST")
   122  }
   123  
   124  func (a *TxClient) SendTokenIPO(request *rpc.NewPublicOfferingRequest) (string, error) {
   125  	return a.sendTx(request, "token/initial_offering", "POST")
   126  }
   127  
   128  func (a *TxClient) SendTokenSPO(request *rpc.NewPublicOfferingRequest) (string, error) {
   129  	return a.sendTx(request, "token/second_offering", "POST")
   130  }
   131  
   132  func (a *TxClient) SendTokenDestroy(request *rpc.NewPublicOfferingRequest) (string, error) {
   133  	return a.sendTx(request, "token/destroy", "POST")
   134  }
   135  
   136  func (a *TxClient) sendTx(request interface{}, uri string, methd string) (string, error) {
   137  	//req := httplib.NewBeegoRequest(url,"POST")
   138  	//req.SetTimeout(time.Second*10,time.Second*10)
   139  	data, err := json.Marshal(request)
   140  	if err != nil {
   141  		panic(err)
   142  	}
   143  	r := bytes.NewReader(data)
   144  	url := a.Host + "/" + uri
   145  	req, err := http.NewRequest(methd, url, r)
   146  
   147  	resp, err := a.httpClient.Do(req)
   148  	if err != nil {
   149  		//fmt.Println(err)
   150  		return "", err
   151  	}
   152  	//now := time.Now()
   153  	defer resp.Body.Close()
   154  	resDate, err := ioutil.ReadAll(resp.Body)
   155  	if err != nil {
   156  		return "", err
   157  	}
   158  
   159  	str := string(resDate)
   160  	if err != nil {
   161  		fmt.Println(str, err)
   162  		return "", err
   163  	}
   164  	if resp.StatusCode != 200 {
   165  		//panic( resp.StatusCode)
   166  		fmt.Println(resp.StatusCode)
   167  		return "", errors.New(resp.Status)
   168  	}
   169  	var respStruct struct {
   170  		Data string `json:"data"`
   171  	}
   172  	err = json.Unmarshal(resDate, &respStruct)
   173  	if err != nil {
   174  		//fmt.Println(str, err)
   175  		return "", err
   176  	}
   177  	if a.Debug {
   178  		fmt.Println(respStruct.Data)
   179  	}
   180  	return respStruct.Data, nil
   181  }
   182  
   183  func (a *TxClient) sendTxs(request interface{}, uri string, methd string) (string, error) {
   184  	//req := httplib.NewBeegoRequest(url,"POST")
   185  	//req.SetTimeout(time.Second*10,time.Second*10)
   186  	data, err := json.Marshal(request)
   187  	if err != nil {
   188  		panic(err)
   189  	}
   190  	r := bytes.NewReader(data)
   191  	url := a.Host + "/" + uri
   192  	req, err := http.NewRequest(methd, url, r)
   193  
   194  	resp, err := a.httpClient.Do(req)
   195  	if err != nil {
   196  		//fmt.Println(err)
   197  		return "", err
   198  	}
   199  	//now := time.Now()
   200  	defer resp.Body.Close()
   201  	resDate, err := ioutil.ReadAll(resp.Body)
   202  	if err != nil {
   203  		return "", err
   204  	}
   205  
   206  	str := string(resDate)
   207  	if err != nil {
   208  		fmt.Println(str, err)
   209  		return "", err
   210  	}
   211  	if resp.StatusCode != 200 {
   212  		//panic( resp.StatusCode)
   213  		fmt.Println(resp.StatusCode, str)
   214  		return "", errors.New(resp.Status)
   215  	}
   216  	//var respStruct struct{
   217  	//	Data common.Hashes  `json:"data"`
   218  	//}
   219  	if a.Debug {
   220  		fmt.Println(str)
   221  	}
   222  	return str, nil
   223  }
   224  
   225  func (a *TxClient) GetNonce(addr common.Address) (nonce uint64, err error) {
   226  	uri := fmt.Sprintf("query_nonce?address=%s", addr.Hex())
   227  	url := a.Host + "/" + uri
   228  	req, err := http.NewRequest("GET", url, nil)
   229  	resp, err := a.httpClient.Do(req)
   230  	if err != nil {
   231  		//fmt.Println(err)
   232  		return 0, err
   233  	}
   234  	//now := time.Now()
   235  	defer resp.Body.Close()
   236  	resDate, err := ioutil.ReadAll(resp.Body)
   237  	if err != nil {
   238  		panic(err)
   239  	}
   240  	str := string(resDate)
   241  	if err != nil {
   242  		fmt.Println(str, err)
   243  		return 0, err
   244  	}
   245  	if resp.StatusCode != 200 {
   246  		//panic( resp.StatusCode)
   247  		fmt.Println(resp.StatusCode)
   248  		return 0, err
   249  	}
   250  	var nonceResp struct {
   251  		Data uint64 `json:"data"`
   252  	}
   253  	err = json.Unmarshal(resDate, &nonceResp)
   254  	if err != nil {
   255  		//fmt.Println("encode nonce errror ", err)
   256  		return 0, err
   257  	}
   258  	return nonceResp.Data, nil
   259  }
   260  
   261  //type TokenList map[string]string
   262  
   263  func (a *TxClient) GetTokenList() (TokenList string, err error) {
   264  	url := a.Host + "/" + "token/list"
   265  	req, err := http.NewRequest("GET", url, nil)
   266  	if err != nil {
   267  		panic(err)
   268  	}
   269  	resp, err := a.httpClient.Do(req)
   270  	if err != nil {
   271  		//fmt.Println(err)
   272  		return "", err
   273  	}
   274  	//now := time.Now()
   275  	defer resp.Body.Close()
   276  	resDate, err := ioutil.ReadAll(resp.Body)
   277  	if err != nil {
   278  		panic(err)
   279  	}
   280  	str := string(resDate)
   281  	if err != nil {
   282  		fmt.Println(str, err)
   283  		return "", err
   284  	}
   285  	if resp.StatusCode != 200 {
   286  		//panic( resp.StatusCode)
   287  		fmt.Println(resp.StatusCode)
   288  		return "", errors.New(resp.Status)
   289  	}
   290  	return str, nil
   291  }