Skip to content

Commit

Permalink
Merge pull request #29 from wangdayong228/cache-for-contractInfo
Browse files Browse the repository at this point in the history
cache for contract info
  • Loading branch information
wangdayong228 authored Mar 17, 2021
2 parents ef4fded + eb76464 commit 02fdd5e
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 66 deletions.
4 changes: 2 additions & 2 deletions example/context/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ ContractManagerAddress = "testnet.confluxscan.io"
ERC20Address = "CFXTEST:TYPE.CONTRACT:ACDDTMBZ2ZTGAD5KY4P62K0J51RDMZV6Z6HXF0FNSR"
ERC777Address = "CFXTEST:TYPE.CONTRACT:ACBG83W3HYZC90U5SH6MNRR85X70KVS6SPZN3ZHX84"
NormalTransactions = ["0xc765d5039ec398c12ba78a8fa6f59f2a0b93324ec0e7db4fa5f9f8aec9aaff87"]
ERC20Transactions = ["0x587cdb85b1f6b65d2e198b2c908da3b12a2fd3c286ab89628cd168dc8503e89d", "0x9cc78cf06c42abfa6c246fc0dd62f1cc0a2511eb5e53c4342876547bc4c1f5bc", "0x018fb70250123ba3eb5b492ff5fdd76a7360b539031953bd2fcc91ee71c15604", "0x2a9c8417dca16f7026fa465f7bb2cd6d7e845ea0dd773cfd961647381da0c5d8", "0x3b0be1aea1b8b3dcfece16cb57e7fc4aa407f83c59a275323149aac85e163e8b"]
ERC777Transactions = ["0x4ddef98703d376e87db02337f94ee6bd0406ccfc11bf221ff8d9683513c53967", "0xb460976f3838d73067d949ba9a32635423d72e3b6a40cffb25e813ddee6ee1a8", "0xbe2bb6152f614f2a0258c9b16725039599f1740526a2c848e765ef0921c6a02d", "0x96bb6802d2d1da87555565b1e368c9042c6ebd9dd872a818ec876bdd8411d5a4", "0x6e08c5f80f527a1f7508c798d8eab08e103bc9591044149c70143b1a8f8270e7"]
ERC20Transactions = ["0x45f2d5adf0e968b789d96dcec77ec097be84c30d73ba116fd8d0d361dfa0a597", "0x162182ce72764c021fe2042bdd037f4d0cfbaf248acd0b16e83a9bc60ade3623", "0xb9c2beac5baedf4b17a0c6f00df0f2b67fd24b423e1462b7cdda1fadc8147d4d", "0x2a9c8417dca16f7026fa465f7bb2cd6d7e845ea0dd773cfd961647381da0c5d8", "0x3b0be1aea1b8b3dcfece16cb57e7fc4aa407f83c59a275323149aac85e163e8b"]
ERC777Transactions = ["0x4990024c40c01d05863cf272961c77ebfb07f0b7ab075937ca77d815db133c8a", "0x10a13c3b9a3275b8ad7f2ab419b99ad39f6e2a3f0bdefe55b4d5696141956b29", "0x78a5e1b7736b7e4a6d3fedd1110c420d7c8421a99cf3214e79e4ba8a9e9938c1", "0x96bb6802d2d1da87555565b1e368c9042c6ebd9dd872a818ec876bdd8411d5a4", "0x6e08c5f80f527a1f7508c798d8eab08e103bc9591044149c70143b1a8f8270e7"]
75 changes: 11 additions & 64 deletions rich_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ package walletsdk
import (
"encoding/json"
"fmt"
"io/ioutil"
"math/big"
"net/http"
"net/url"
"strings"
"sync"

Expand All @@ -33,13 +31,6 @@ type RichClient struct {
client sdk.ClientOperator
}

// scanServer represents a centralized server
type scanServer struct {
Scheme string
Address string
HTTPRequester sdk.HTTPRequester
}

// ServerConfig represents cfx-scan-backend and contract-manager configurations, because centralized servers maybe changed.
type ServerConfig struct {
CfxScanBackendSchema string
Expand Down Expand Up @@ -138,61 +129,6 @@ func (rc *RichClient) setHTTPRequester(requester sdk.HTTPRequester) {
rc.contractManager.HTTPRequester = requester
}

// URL returns url build by schema, host, path and params
func (s *scanServer) URL(path string, params map[string]interface{}) string {
q := url.Values{}
for key, val := range params {
q.Add(key, fmt.Sprintf("%+v", val))
}
encodedParams := q.Encode()
result := fmt.Sprintf("%+v://%+v%+v?%+v", s.Scheme, s.Address, path, encodedParams)
return result
}

// Get sends a "Get" request and fill the unmarshaled value of field "Result" in response to unmarshaledResult
func (s *scanServer) Get(path string, params map[string]interface{}, unmarshaledResult interface{}) error {
client := s.HTTPRequester
// fmt.Println("request url:", s.URL(path, params))
rspBytes, err := client.Get(s.URL(path, params))
if err != nil {
return err
}

defer func() {
err := rspBytes.Body.Close()
if err != nil {
//fmt.Println("close rsp error", err)
}
}()

body, err := ioutil.ReadAll(rspBytes.Body)
if err != nil {
return err
}
// fmt.Printf("body:%+v\n\n", string(body))

// check if error response
var rsp richtypes.ErrorResponse
err = json.Unmarshal(body, &rsp)
if err != nil {
return fmt.Errorf("failed to unmarshal '%v' to richtypes.ErrorResponse, error:%v", string(body), err.Error())
}
// fmt.Printf("unmarshaled body: %+v\n\n", rsp)

if rsp.Code != 0 {
msg := fmt.Sprintf("code:%+v, message:%+v", rsp.Code, rsp.Message)
return errors.New(msg)
}

// unmarshl to result
err = json.Unmarshal(body, unmarshaledResult)
if err != nil {
return fmt.Errorf("failed to unmarshal '%v' to unmarshaledResult, error:%v", string(body), err.Error())
}
// fmt.Printf("unmarshaled result: %+v\n\n", unmarshaledResult)
return nil
}

// GetAccountTokenTransfers returns address releated transactions,
// the tokenIdentifier represnets the token contract address and it is optional,
// when tokenIdentifier is specicied it returns token transfer events related the address,
Expand Down Expand Up @@ -367,11 +303,20 @@ func (rc *RichClient) getDataForTransToken(contractType richtypes.ContractType,
return nil, err
}

var contractInfoCaches map[string]*richtypes.Contract = make(map[string]*richtypes.Contract)

// GetContractInfo returns contract detail infomation, it will contains token info if it is token contract,
// it will contains abi if set needABI to be true.
func (rc *RichClient) GetContractInfo(contractAddress types.Address, needABI, needIcon bool) (*richtypes.Contract, error) {
params := make(map[string]interface{})

cInfoCache := contractInfoCaches[contractAddress.String()]
if cInfoCache != nil {
if (!needIcon || (needIcon && cInfoCache.TokenIcon != "")) && (!needABI || (needABI && cInfoCache.ABI != "")) {
return cInfoCache, nil
}
}

fields := []string{}
if needIcon {
fields = append(fields, "icon")
Expand All @@ -394,6 +339,8 @@ func (rc *RichClient) GetContractInfo(contractAddress types.Address, needABI, ne
var tokenQueryFullPath = fmt.Sprintf("%v/%v", tokenQueryBasePath, contractAddress)
rc.contractManager.Get(tokenQueryFullPath, params, &contract.Token)

contractInfoCaches[contractAddress.String()] = &contract

return &contract, nil
}

Expand Down
75 changes: 75 additions & 0 deletions scan_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2019 Conflux Foundation. All rights reserved.
// Conflux is free software and distributed under GNU General Public License.
// See http://www.gnu.org/licenses/

package walletsdk

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/url"

sdk "github.com/Conflux-Chain/go-conflux-sdk"
richtypes "github.com/Conflux-Chain/go-conflux-sdk-for-wallet/types"
"github.com/pkg/errors"
)

// scanServer represents a centralized server
type scanServer struct {
Scheme string
Address string
HTTPRequester sdk.HTTPRequester
}

// URL returns url build by schema, host, path and params
func (s *scanServer) URL(path string, params map[string]interface{}) string {
q := url.Values{}
for key, val := range params {
q.Add(key, fmt.Sprintf("%+v", val))
}
encodedParams := q.Encode()
result := fmt.Sprintf("%+v://%+v%+v?%+v", s.Scheme, s.Address, path, encodedParams)
return result
}

// Get sends a "Get" request and fill the unmarshaled value of field "Result" in response to unmarshaledResult
func (s *scanServer) Get(path string, params map[string]interface{}, unmarshaledResult interface{}) error {
client := s.HTTPRequester
// fmt.Println("request url:", s.URL(path, params))
rspBytes, err := client.Get(s.URL(path, params))
if err != nil {
return err
}

defer func() {
rspBytes.Body.Close()
}()

body, err := ioutil.ReadAll(rspBytes.Body)
if err != nil {
return err
}
// fmt.Printf("body:%+v\n\n", string(body))

// check if error response
var rsp richtypes.ErrorResponse
err = json.Unmarshal(body, &rsp)
if err != nil {
return fmt.Errorf("failed to unmarshal '%v' to richtypes.ErrorResponse, error:%v", string(body), err.Error())
}
// fmt.Printf("unmarshaled body: %+v\n\n", rsp)

if rsp.Code != 0 {
msg := fmt.Sprintf("code:%+v, message:%+v", rsp.Code, rsp.Message)
return errors.New(msg)
}

// unmarshl to result
err = json.Unmarshal(body, unmarshaledResult)
if err != nil {
return fmt.Errorf("failed to unmarshal '%v' to unmarshaledResult, error:%v", string(body), err.Error())
}
// fmt.Printf("unmarshaled result: %+v\n\n", unmarshaledResult)
return nil
}

0 comments on commit 02fdd5e

Please sign in to comment.