diff --git a/cmd/client/flags.go b/cmd/client/flags.go index a119927fb5..0562e15da4 100644 --- a/cmd/client/flags.go +++ b/cmd/client/flags.go @@ -13,6 +13,7 @@ import ( func RegisterAppFlag(cmd *cobra.Command) { cmd.Flags().Bool(watcher.FlagFastQuery, false, "Enable the fast query mode for rpc queries") + cmd.Flags().Int(watcher.FlagFastQueryLru, 1000, "Set the size of LRU cache under fast-query mode") cmd.Flags().Bool(rpc.FlagPersonalAPI, true, "Enable the personal_ prefixed set of APIs in the Web3 JSON-RPC spec") cmd.Flags().Bool(evmtypes.FlagEnableBloomFilter, true, "Enable bloom filter for event logs") cmd.Flags().Int64(filters.FlagGetLogsHeightSpan, -1, "config the block height span for get logs") diff --git a/go.mod b/go.mod index ee67ab0622..0089f4e82d 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/google/uuid v1.1.1 github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.4.2 + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d github.com/jinzhu/gorm v1.9.16 github.com/json-iterator/go v1.1.9 github.com/mattn/go-colorable v0.1.7 // indirect diff --git a/x/evm/watcher/db.go b/x/evm/watcher/db.go index eea04c51e3..3730f7c617 100644 --- a/x/evm/watcher/db.go +++ b/x/evm/watcher/db.go @@ -11,6 +11,7 @@ import ( ) const FlagFastQuery = "fast-query" +const FlagFastQueryLru = "fast-lru" type WatchStore struct { db *leveldb.DB diff --git a/x/evm/watcher/querier.go b/x/evm/watcher/querier.go index 4039124e6e..9ce5bc28aa 100644 --- a/x/evm/watcher/querier.go +++ b/x/evm/watcher/querier.go @@ -6,6 +6,8 @@ import ( "errors" "strconv" + "github.com/hashicorp/golang-lru/simplelru" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" @@ -20,6 +22,7 @@ const MsgFunctionDisable = "fast query function has been disabled" type Querier struct { store *WatchStore sw bool + lru *simplelru.LRU } func (q Querier) enabled() bool { @@ -31,7 +34,11 @@ func (q *Querier) Enable(sw bool) { } func NewQuerier() *Querier { - return &Querier{store: InstanceOfWatchStore(), sw: IsWatcherEnabled()} + lru, e := simplelru.NewLRU(GetWatchLruSize(), nil) + if e != nil { + panic(errors.New("Failed to init LRU Cause " + e.Error())) + } + return &Querier{store: InstanceOfWatchStore(), sw: IsWatcherEnabled(), lru: lru} } func (q Querier) GetTransactionReceipt(hash common.Hash) (*TransactionReceipt, error) { @@ -148,16 +155,19 @@ func (q Querier) GetCodeByHash(codeHash []byte) ([]byte, error) { if !q.enabled() { return nil, errors.New(MsgFunctionDisable) } - var codeInfo CodeInfo - info, e := q.store.Get(append(prefixCodeHash, codeHash...)) - if e != nil { - return nil, e + cacheCode, ok := q.lru.Get(common.BytesToHash(codeHash)) + if ok { + data, ok := cacheCode.([]byte) + if ok { + return data, nil + } } - e = json.Unmarshal(info, &codeInfo) + code, e := q.store.Get(append(prefixCodeHash, codeHash...)) if e != nil { return nil, e } - return hex.DecodeString(codeInfo.Code) + q.lru.Add(common.BytesToHash(codeHash), code) + return code, nil } func (q Querier) GetLatestBlockNumber() (uint64, error) { diff --git a/x/evm/watcher/types.go b/x/evm/watcher/types.go index 25cfde4441..63cadba64d 100644 --- a/x/evm/watcher/types.go +++ b/x/evm/watcher/types.go @@ -114,18 +114,10 @@ type MsgCodeByHash struct { Code string } -func NewMsgCodeByHash(hash []byte, code []byte, height uint64) *MsgCodeByHash { - codeInfo := CodeInfo{ - Height: height, - Code: hexutils.BytesToHex(code), - } - jsCode, e := json.Marshal(codeInfo) - if e != nil { - return nil - } +func NewMsgCodeByHash(hash []byte, code []byte) *MsgCodeByHash { return &MsgCodeByHash{ Key: hash, - Code: string(jsCode), + Code: string(code), } } diff --git a/x/evm/watcher/watcher.go b/x/evm/watcher/watcher.go index 5541f2e3e2..45a76904cb 100644 --- a/x/evm/watcher/watcher.go +++ b/x/evm/watcher/watcher.go @@ -31,6 +31,10 @@ func IsWatcherEnabled() bool { return viper.GetBool(FlagFastQuery) } +func GetWatchLruSize() int { + return viper.GetInt(FlagFastQueryLru) +} + func NewWatcher() *Watcher { return &Watcher{store: InstanceOfWatchStore(), sw: IsWatcherEnabled(), firstUse: true} } @@ -89,7 +93,7 @@ func (w *Watcher) SaveContractCodeByHash(hash []byte, code []byte) { if !w.Enabled() { return } - wMsg := NewMsgCodeByHash(hash, code, w.height) + wMsg := NewMsgCodeByHash(hash, code) if wMsg != nil { w.staleBatch = append(w.staleBatch, wMsg) } @@ -262,7 +266,7 @@ func (w *Watcher) CommitCodeHashToDb(hash []byte, code []byte) { if !w.Enabled() { return } - wMsg := NewMsgCodeByHash(hash, code, w.height) + wMsg := NewMsgCodeByHash(hash, code) if wMsg != nil { w.store.Set(wMsg.GetKey(), []byte(wMsg.GetValue())) }