Implement basic blockpool
This commit is contained in:
parent
7f85330953
commit
2cd62d0079
1
go.mod
1
go.mod
@ -33,6 +33,7 @@ require (
|
||||
github.com/jmoiron/sqlx v1.2.0
|
||||
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.6 // indirect
|
||||
github.com/ledgerwatch/lmdb-go v1.17.8 // indirect
|
||||
github.com/libp2p/go-libp2p v0.12.0
|
||||
github.com/libp2p/go-libp2p-core v0.7.0
|
||||
github.com/libp2p/go-libp2p-pubsub v0.4.2-0.20210212194758-6c1addf493eb
|
||||
|
2
go.sum
2
go.sum
@ -909,6 +909,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/ledgerwatch/lmdb-go v1.17.8 h1:IQUVJ2MYIfSsrhz+o+QbugUqRQuqTXodt8pE6cuvQVg=
|
||||
github.com/ledgerwatch/lmdb-go v1.17.8/go.mod h1:NKRpCxksoTQPyxsUcBiVOe0135uqnJsnf6cElxmOL0o=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
|
137
pool/blockpool.go
Normal file
137
pool/blockpool.go
Normal file
@ -0,0 +1,137 @@
|
||||
package pool
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
|
||||
"github.com/Secured-Finance/dione/types"
|
||||
"github.com/fxamacker/cbor/v2"
|
||||
"github.com/ledgerwatch/lmdb-go/lmdb"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultBlockPrefix = "block_"
|
||||
DefaultBlockHeaderPrefix = "header_"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrBlockNotFound = errors.New("block isn't found")
|
||||
)
|
||||
|
||||
type BlockPool struct {
|
||||
dbEnv *lmdb.Env
|
||||
db lmdb.DBI
|
||||
}
|
||||
|
||||
func NewBlockPool(path string) (*BlockPool, error) {
|
||||
pool := &BlockPool{}
|
||||
|
||||
// configure lmdb env
|
||||
env, err := lmdb.NewEnv()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = env.SetMapSize(100 * 1024 * 1024 * 1024) // 100 GB
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = env.Open(path, 0, 0664)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pool.dbEnv = env
|
||||
|
||||
var dbi lmdb.DBI
|
||||
err = env.Update(func(txn *lmdb.Txn) error {
|
||||
dbi, err = txn.OpenDBI("blocks", lmdb.Create)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pool.db = dbi
|
||||
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
func (bp *BlockPool) StoreBlock(block *types.Block) error {
|
||||
return bp.dbEnv.Update(func(txn *lmdb.Txn) error {
|
||||
data, err := cbor.Marshal(block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
headerData, err := cbor.Marshal(block.Header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
blockHash := hex.EncodeToString(block.Header.Hash)
|
||||
err = txn.Put(bp.db, []byte(DefaultBlockPrefix+blockHash), data, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = txn.Put(bp.db, []byte(DefaultBlockHeaderPrefix+blockHash), headerData, 0) // store header separately for easy fetching
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func (bp *BlockPool) HasBlock(blockHash string) (bool, error) {
|
||||
var blockExists bool
|
||||
err := bp.dbEnv.View(func(txn *lmdb.Txn) error {
|
||||
_, err := txn.Get(bp.db, []byte(DefaultBlockPrefix+blockHash)) // try to fetch block header
|
||||
if err != nil {
|
||||
if lmdb.IsNotFound(err) {
|
||||
blockExists = false
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
blockExists = true
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return blockExists, nil
|
||||
}
|
||||
|
||||
func (bp *BlockPool) FetchBlock(blockHash string) (*types.Block, error) {
|
||||
var block types.Block
|
||||
err := bp.dbEnv.View(func(txn *lmdb.Txn) error {
|
||||
data, err := txn.Get(bp.db, []byte(DefaultBlockPrefix+blockHash))
|
||||
if err != nil {
|
||||
if lmdb.IsNotFound(err) {
|
||||
return ErrBlockNotFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
err = cbor.Unmarshal(data, &block)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &block, nil
|
||||
}
|
||||
|
||||
func (bp *BlockPool) FetchBlockHeader(blockHash string) (*types.BlockHeader, error) {
|
||||
var blockHeader types.BlockHeader
|
||||
err := bp.dbEnv.View(func(txn *lmdb.Txn) error {
|
||||
data, err := txn.Get(bp.db, []byte(DefaultBlockHeaderPrefix+blockHash))
|
||||
if err != nil {
|
||||
if lmdb.IsNotFound(err) {
|
||||
return ErrBlockNotFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
err = cbor.Unmarshal(data, &blockHeader)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &blockHeader, nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user