The core protocol of WoopChain
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
woop/api/service/explorer/interface.go

153 lines
3.4 KiB

package explorer
import (
"github.com/ethereum/go-ethereum/common"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/filter"
"github.com/syndtr/goleveldb/leveldb/opt"
levelutil "github.com/syndtr/goleveldb/leveldb/util"
)
// database is an adapter for *leveldb.DB
type database interface {
databaseWriter
databaseReader
NewBatch() batch
}
type databaseWriter interface {
Put(key, val []byte) error
}
type databaseReader interface {
Get(key []byte) ([]byte, error)
Has(key []byte) (bool, error)
NewPrefixIterator(prefix []byte) iterator
NewSizedIterator(start []byte, size int) iterator
}
type batch interface {
databaseWriter
Write() error
ValueSize() int
}
// lvlDB is the adapter for leveldb.Database
type lvlDB struct {
db *leveldb.DB
}
func newLvlDB(dbPath string) (database, error) {
// https://github.com/ethereum/go-ethereum/blob/master/ethdb/leveldb/leveldb.go#L98 options.
// We had 0 for handles and cache params before, so set 0s for all of them. Filter opt is the same.
options := &opt.Options{
OpenFilesCacheCapacity: 500,
BlockCacheCapacity: 8 * 1024 * 1024, // 8 MiB
WriteBuffer: 4 * 1024 * 1024, // 4 MiB
Filter: filter.NewBloomFilter(10),
}
db, err := leveldb.OpenFile(dbPath, options)
if err != nil {
return nil, err
}
return &lvlDB{db}, nil
}
func (db *lvlDB) Put(key, val []byte) error {
return db.db.Put(key, val, nil)
}
func (db *lvlDB) Get(key []byte) ([]byte, error) {
return db.db.Get(key, nil)
}
func (db *lvlDB) Has(key []byte) (bool, error) {
return db.db.Has(key, nil)
}
func (db *lvlDB) NewBatch() batch {
batch := new(leveldb.Batch)
return &lvlBatch{
batch: batch,
db: db.db,
}
}
func (db *lvlDB) NewPrefixIterator(prefix []byte) iterator {
rng := levelutil.BytesPrefix(prefix)
it := db.db.NewIterator(rng, nil)
return it
}
func (db *lvlDB) NewSizedIterator(start []byte, size int) iterator {
return db.newSizedIterator(start, size)
}
type sizedIterator struct {
it iterator
curIndex int
sizeLimit int
}
func (db *lvlDB) newSizedIterator(start []byte, size int) *sizedIterator {
rng := &levelutil.Range{Start: start, Limit: nil}
it := db.db.NewIterator(rng, nil)
return &sizedIterator{
it: it,
curIndex: 0,
sizeLimit: size,
}
}
func (it *sizedIterator) Next() bool {
if it.curIndex >= it.sizeLimit-1 {
return false
}
it.curIndex++
return it.it.Next()
}
func (it *sizedIterator) Key() []byte { return it.it.Key() }
func (it *sizedIterator) Value() []byte { return it.it.Value() }
func (it *sizedIterator) Release() { it.it.Release() }
func (it *sizedIterator) Error() error { return it.it.Error() }
// Note: lvlBatch is not thread safe
type lvlBatch struct {
batch *leveldb.Batch
db *leveldb.DB
valueSize int
}
func (b *lvlBatch) Put(key, val []byte) error {
b.batch.Put(key, val)
b.valueSize += len(val)
return nil
}
func (b *lvlBatch) Write() error {
if err := b.db.Write(b.batch, nil); err != nil {
return err
}
b.valueSize = 0
return nil
}
func (b *lvlBatch) ValueSize() int {
return b.valueSize
}
type iterator interface {
Next() bool
Key() []byte
Value() []byte
Release()
Error() error
}
// blockChainTxIndexer is the interface to check the loop up entry for transaction.
// Implemented by core.BlockChain
type blockChainTxIndexer interface {
ReadTxLookupEntry(txID common.Hash) (common.Hash, uint64, uint64)
}