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 }