Merge pull request #437: Code Size Lookup Cache

This commit is contained in:
Aleksandr Bezobchuk 2018-07-17 10:34:32 -04:00
parent 759c2292f4
commit 377b7f06c5
4 changed files with 42 additions and 36 deletions

46
Gopkg.lock generated
View File

@ -24,7 +24,7 @@
packages = [
"store",
"types",
"wire",
"wire"
]
revision = "1a1373cc220e402397ad536aee6b8f5b068914c6"
version = "v0.21.0"
@ -71,7 +71,7 @@
"params",
"rlp",
"rpc",
"trie",
"trie"
]
revision = "dea1ce052a10cd7d401a5c04f83f371a06fe293c"
version = "v1.8.11"
@ -81,7 +81,7 @@
packages = [
"log",
"log/level",
"log/term",
"log/term"
]
revision = "4dc7be5d2d12881735283bcab7352178e190fc71"
version = "v0.6.0"
@ -106,7 +106,7 @@
"proto",
"protoc-gen-gogo/descriptor",
"sortkeys",
"types",
"types"
]
revision = "1adfc126b41513cc696b209667c8656ea7aac67c"
version = "v1.0.0"
@ -118,7 +118,7 @@
"ptypes",
"ptypes/any",
"ptypes/duration",
"ptypes/timestamp",
"ptypes/timestamp"
]
revision = "925541529c1fa6821df4e44ce2723319eb2be768"
version = "v1.0.0"
@ -134,7 +134,7 @@
name = "github.com/hashicorp/golang-lru"
packages = [
".",
"simplelru",
"simplelru"
]
revision = "0fb14efe8c47ae851c0034ed7a448854d3d34cf3"
@ -177,7 +177,7 @@
"leveldb/opt",
"leveldb/storage",
"leveldb/table",
"leveldb/util",
"leveldb/util"
]
revision = "c4c61651e9e37fa117f53c5a906d3b63090d8445"
@ -187,7 +187,7 @@
packages = [
".",
"edwards25519",
"extra25519",
"extra25519"
]
revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057"
@ -216,7 +216,7 @@
"libs/log",
"libs/pubsub",
"libs/pubsub/query",
"types",
"types"
]
revision = "5ff65274b84ea905787a48512cc3124385bddf2f"
version = "v0.22.2"
@ -231,7 +231,7 @@
"openpgp/errors",
"poly1305",
"ripemd160",
"salsa20/salsa",
"salsa20/salsa"
]
revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602"
@ -246,7 +246,7 @@
"idna",
"internal/timeseries",
"trace",
"websocket",
"websocket"
]
revision = "d0887baf81f4598189d4e12a37c6da86f0bba4d0"
@ -266,7 +266,7 @@
"unicode/bidi",
"unicode/cldr",
"unicode/norm",
"unicode/rangetable",
"unicode/rangetable"
]
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
version = "v0.3.0"
@ -301,7 +301,7 @@
"stats",
"status",
"tap",
"transport",
"transport"
]
revision = "d11072e7ca9811b1100b80ca0269ac831f06d024"
version = "v1.11.3"
@ -327,24 +327,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
input-imports = [
"github.com/cosmos/cosmos-sdk/store",
"github.com/cosmos/cosmos-sdk/types",
"github.com/ethereum/go-ethereum/common",
"github.com/ethereum/go-ethereum/common/math",
"github.com/ethereum/go-ethereum/consensus",
"github.com/ethereum/go-ethereum/consensus/ethash",
"github.com/ethereum/go-ethereum/consensus/misc",
"github.com/ethereum/go-ethereum/core",
"github.com/ethereum/go-ethereum/core/state",
"github.com/ethereum/go-ethereum/core/types",
"github.com/ethereum/go-ethereum/core/vm",
"github.com/ethereum/go-ethereum/ethdb",
"github.com/ethereum/go-ethereum/params",
"github.com/ethereum/go-ethereum/rlp",
"github.com/ethereum/go-ethereum/rpc",
"github.com/ethereum/go-ethereum/trie",
"github.com/tendermint/tendermint/libs/db",
]
inputs-digest = "df6cfdfe013b00b662a5b9ebd45319d0c114859e865b3034b0e984f15e698b45"
solver-name = "gps-cdcl"
solver-version = 1

View File

@ -6,6 +6,9 @@
name = "github.com/cosmos/cosmos-sdk"
version = "=0.21.0"
[[constraint]]
name = "github.com/hashicorp/golang-lru"
[[override]]
name = "google.golang.org/genproto"
revision = "7fd901a49ba6a7f87732eb344f6e3c5b19d1b200"

View File

@ -29,6 +29,7 @@ import (
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile `file`")
var blockchain = flag.String("blockchain", "data/blockchain", "file containing blocks to load")
var datadir = flag.String("datadir", "", "directory for ethermint data")
var (
// TODO: Document...
@ -52,8 +53,8 @@ func main() {
defer pprof.StopCPUProfile()
}
stateDB := dbm.NewDB("state", dbm.LevelDBBackend, "")
codeDB := dbm.NewDB("code", dbm.LevelDBBackend, "")
stateDB := dbm.NewDB("state", dbm.LevelDBBackend, *datadir)
codeDB := dbm.NewDB("code", dbm.LevelDBBackend, *datadir)
ethermintDB, err := state.NewDatabase(stateDB, codeDB)
if err != nil {

View File

@ -7,6 +7,7 @@ import (
ethcommon "github.com/ethereum/go-ethereum/common"
ethstate "github.com/ethereum/go-ethereum/core/state"
ethtrie "github.com/ethereum/go-ethereum/trie"
lru "github.com/hashicorp/golang-lru"
dbm "github.com/tendermint/tendermint/libs/db"
)
@ -24,6 +25,13 @@ var (
CodeKey = types.NewKVStoreKey("code")
)
const (
// codeSizeCacheSize is the number of codehash to size associations to
// keep in cached memory. This is to address any DoS attempts on
// EXTCODESIZE calls.
codeSizeCacheSize = 100000
)
// Database implements the Ethereum state.Database interface.
type Database struct {
// stateStore will be used for the history of accounts (balance, nonce,
@ -43,7 +51,10 @@ type Database struct {
codeDB dbm.DB
ethTrieDB *ethtrie.Database
// TODO: Do we need this/document?
// codeSizeCache contains an LRU cache of a specified capacity to cache
// EXTCODESIZE calls.
codeSizeCache *lru.Cache
Tracing bool
}
@ -75,6 +86,8 @@ func NewDatabase(stateDB, codeDB dbm.DB) (*Database, error) {
db.codeDB = codeDB
db.ethTrieDB = ethtrie.NewDatabase(&core.EthereumDB{CodeDB: codeDB})
db.codeSizeCache, _ = lru.New(codeSizeCacheSize)
return db, nil
}
@ -151,13 +164,20 @@ func (db *Database) CopyTrie(ethstate.Trie) ethstate.Trie {
// ContractCode implements Ethereum's state.Database interface. It will return
// the contract byte code for a given code hash. It will not return an error.
func (db *Database) ContractCode(addrHash, codeHash ethcommon.Hash) ([]byte, error) {
return db.codeDB.Get(codeHash[:]), nil
code := db.codeDB.Get(codeHash[:])
db.codeSizeCache.Add(codeHash, code)
return code, nil
}
// ContractCodeSize implements Ethereum's state.Database interface. It will
// return the contract byte code size for a given code hash. It will not return
// an error.
func (db *Database) ContractCodeSize(addrHash, codeHash ethcommon.Hash) (int, error) {
if cached, ok := db.codeSizeCache.Get(codeHash); ok {
return cached.(int), nil
}
return len(db.codeDB.Get(codeHash[:])), nil
}