Skip to content

Commit

Permalink
light, les: CHT and bloom trie post processors
Browse files Browse the repository at this point in the history
  • Loading branch information
zsfelfoldi committed Aug 19, 2017
1 parent 0d0c3ae commit 46f1b87
Show file tree
Hide file tree
Showing 13 changed files with 443 additions and 184 deletions.
2 changes: 2 additions & 0 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type LesServer interface {
Start(srvr *p2p.Server)
Stop()
Protocols() []p2p.Protocol
SetBloomBitsIndexer(bbIndexer *core.ChainIndexer)
}

// Ethereum implements the Ethereum full node service.
Expand Down Expand Up @@ -89,6 +90,7 @@ type Ethereum struct {

func (s *Ethereum) AddLesServer(ls LesServer) {
s.lesServer = ls
ls.SetBloomBitsIndexer(s.bbIndexer)
}

// New creates a new Ethereum object (including the
Expand Down
7 changes: 4 additions & 3 deletions les/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,16 +175,17 @@ func (b *LesApiBackend) AccountManager() *accounts.Manager {
}

func (b *LesApiBackend) GetBloomBits(ctx context.Context, bitIdx uint64, sectionIdxList []uint64) ([][]byte, error) {
return nil, nil // implemented in a subsequent PR
return light.GetBloomBits(ctx, b.eth.odr, bitIdx, sectionIdxList)
}

func (b *LesApiBackend) BloomBitsSections() uint64 {
return 0
sections, _, _ := b.eth.bbIndexer.Sections()
return sections
}

func (b *LesApiBackend) BloomBitsConfig() filters.BloomConfig {
return filters.BloomConfig{
SectionSize: 32768,
SectionSize: light.BloomTrieFrequency,
MaxRequestLen: 16,
MaxRequestWait: time.Microsecond * 100,
}
Expand Down
35 changes: 22 additions & 13 deletions les/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ type LightEthereum struct {
// DB interfaces
chainDb ethdb.Database // Block chain database

bbIndexer, chtIndexer, bltIndexer *core.ChainIndexer

ApiBackend *LesApiBackend

eventMux *event.TypeMux
Expand All @@ -87,7 +89,7 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
peers := newPeerSet()
quitSync := make(chan struct{})

eth := &LightEthereum{
leth := &LightEthereum{
chainConfig: chainConfig,
chainDb: chainDb,
eventMux: ctx.EventMux,
Expand All @@ -97,33 +99,38 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
engine: eth.CreateConsensusEngine(ctx, config, chainConfig, chainDb),
shutdownChan: make(chan bool),
networkId: config.NetworkId,
bbIndexer: eth.NewBloomBitsProcessor(chainDb, light.BloomTrieFrequency),
chtIndexer: light.NewChtIndexer(chainDb, true),
bltIndexer: light.NewBloomTrieIndexer(chainDb, true),
}

eth.relay = NewLesTxRelay(peers, eth.reqDist)
eth.serverPool = newServerPool(chainDb, quitSync, &eth.wg)
eth.retriever = newRetrieveManager(peers, eth.reqDist, eth.serverPool)
eth.odr = NewLesOdr(chainDb, eth.retriever)
if eth.blockchain, err = light.NewLightChain(eth.odr, eth.chainConfig, eth.engine); err != nil {
leth.relay = NewLesTxRelay(peers, leth.reqDist)
leth.serverPool = newServerPool(chainDb, quitSync, &leth.wg)
leth.retriever = newRetrieveManager(peers, leth.reqDist, leth.serverPool)
leth.odr = NewLesOdr(chainDb, leth.chtIndexer, leth.bltIndexer, leth.bbIndexer, leth.retriever)
if leth.blockchain, err = light.NewLightChain(leth.odr, leth.chainConfig, leth.engine); err != nil {
return nil, err
}
// Rewind the chain in case of an incompatible config upgrade.
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
eth.blockchain.SetHead(compat.RewindTo)
leth.blockchain.SetHead(compat.RewindTo)
core.WriteChainConfig(chainDb, genesisHash, chainConfig)
}

eth.txPool = light.NewTxPool(eth.chainConfig, eth.blockchain, eth.relay)
if eth.protocolManager, err = NewProtocolManager(eth.chainConfig, true, config.NetworkId, eth.eventMux, eth.engine, eth.peers, eth.blockchain, nil, chainDb, eth.odr, eth.relay, quitSync, &eth.wg); err != nil {
leth.bbIndexer.Start(leth.blockchain)

leth.txPool = light.NewTxPool(leth.chainConfig, leth.blockchain, leth.relay)
if leth.protocolManager, err = NewProtocolManager(leth.chainConfig, true, config.NetworkId, leth.eventMux, leth.engine, leth.peers, leth.blockchain, nil, chainDb, leth.odr, leth.relay, quitSync, &leth.wg); err != nil {
return nil, err
}
eth.ApiBackend = &LesApiBackend{eth, nil}
leth.ApiBackend = &LesApiBackend{leth, nil}
gpoParams := config.GPO
if gpoParams.Default == nil {
gpoParams.Default = config.GasPrice
}
eth.ApiBackend.gpo = gasprice.NewOracle(eth.ApiBackend, gpoParams)
return eth, nil
leth.ApiBackend.gpo = gasprice.NewOracle(leth.ApiBackend, gpoParams)
return leth, nil
}

func lesTopic(genesisHash common.Hash) discv5.Topic {
Expand Down Expand Up @@ -210,7 +217,9 @@ func (s *LightEthereum) Start(srvr *p2p.Server) error {
// Stop implements node.Service, terminating all internal goroutines used by the
// Ethereum protocol.
func (s *LightEthereum) Stop() error {
s.odr.Stop()
s.bbIndexer.Close()
s.chtIndexer.Close()
s.bltIndexer.Close()
s.blockchain.Stop()
s.protocolManager.Stop()
s.txPool.Stop()
Expand Down
10 changes: 7 additions & 3 deletions les/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}

if header := pm.blockchain.GetHeaderByNumber(req.BlockNum); header != nil {
if root := getChtRoot(pm.chainDb, req.ChtNum); root != (common.Hash{}) {
sectionHead := core.GetCanonicalHash(pm.chainDb, (req.ChtNum+1)*light.ChtV1Frequency-1)
if root := light.GetChtRoot(pm.chainDb, req.ChtNum, sectionHead); root != (common.Hash{}) {
if tr, _ := trie.New(root, pm.chainDb); tr != nil {
var encNumber [8]byte
binary.BigEndian.PutUint64(encNumber[:], req.BlockNum)
Expand Down Expand Up @@ -956,9 +957,12 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
func (pm *ProtocolManager) getPPT(id uint, idx uint64) (common.Hash, string) {
switch id {
case PPTChain:
return light.GetChtRoot(pm.chainDb, idx), light.ChtTablePrefix
idx = (idx+1)*(light.ChtFrequency/light.ChtV1Frequency) - 1
sectionHead := core.GetCanonicalHash(pm.chainDb, (idx+1)*light.ChtV1Frequency-1)
return light.GetChtRoot(pm.chainDb, idx, sectionHead), light.ChtTablePrefix
case PPTBloomBits:
return light.GetBloomTrieRoot(pm.chainDb, idx), light.BloomTrieTablePrefix
sectionHead := core.GetCanonicalHash(pm.chainDb, (idx+1)*light.BloomTrieFrequency-1)
return light.GetBloomTrieRoot(pm.chainDb, idx, sectionHead), light.BloomTrieTablePrefix
}
return common.Hash{}, ""
}
Expand Down
37 changes: 26 additions & 11 deletions les/odr.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,49 @@ package les
import (
"context"

"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/light"
"github.com/ethereum/go-ethereum/log"
)

// LesOdr implements light.OdrBackend
type LesOdr struct {
db ethdb.Database
stop chan struct{}
retriever *retrieveManager
db ethdb.Database
chtIndexer, bltIndexer, bloomIndexer *core.ChainIndexer
retriever *retrieveManager
}

func NewLesOdr(db ethdb.Database, retriever *retrieveManager) *LesOdr {
func NewLesOdr(db ethdb.Database, chtIndexer, bltIndexer, bloomIndexer *core.ChainIndexer, retriever *retrieveManager) *LesOdr {
return &LesOdr{
db: db,
retriever: retriever,
stop: make(chan struct{}),
db: db,
chtIndexer: chtIndexer,
bltIndexer: bltIndexer,
bloomIndexer: bloomIndexer,
retriever: retriever,
}
}

func (odr *LesOdr) Stop() {
close(odr.stop)
}

// Database returns the backing database
func (odr *LesOdr) Database() ethdb.Database {
return odr.db
}

// ChtIndexer returns the CHT chain indexer
func (odr *LesOdr) ChtIndexer() *core.ChainIndexer {
return odr.chtIndexer
}

// BltIndexer returns the bloom trie chain indexer
func (odr *LesOdr) BltIndexer() *core.ChainIndexer {
return odr.bltIndexer
}

// BloomIndexer returns the bloombits chain indexer
func (odr *LesOdr) BloomIndexer() *core.ChainIndexer {
return odr.bloomIndexer
}

const (
MsgBlockBodies = iota
MsgCode
Expand Down
4 changes: 2 additions & 2 deletions les/odr_requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ func (r *ChtRequest) CanSend(peer *peer) bool {
peer.lock.RLock()
defer peer.lock.RUnlock()

return peer.headInfo.Number >= light.ChtConfirmations && r.ChtNum <= (peer.headInfo.Number-light.ChtConfirmations)/light.ChtFrequency
return peer.headInfo.Number >= light.PPTConfirmations && r.ChtNum <= (peer.headInfo.Number-light.PPTConfirmations)/light.ChtFrequency
}

// Request sends an ODR request to the LES network (implementation of LesOdrRequest)
Expand Down Expand Up @@ -423,7 +423,7 @@ func (r *BloomRequest) CanSend(peer *peer) bool {
peer.lock.RLock()
defer peer.lock.RUnlock()

return peer.headInfo.Number >= light.BloomTrieConfirmations && r.BltNum <= (peer.headInfo.Number-light.BloomTrieConfirmations)/light.BloomTrieFrequency
return peer.headInfo.Number >= light.PPTConfirmations && r.BltNum <= (peer.headInfo.Number-light.PPTConfirmations)/light.BloomTrieFrequency
}

// Request sends an ODR request to the LES network (implementation of LesOdrRequest)
Expand Down
3 changes: 2 additions & 1 deletion les/odr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"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/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/light"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -154,7 +155,7 @@ func testOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
rm := newRetrieveManager(peers, dist, nil)
db, _ := ethdb.NewMemDatabase()
ldb, _ := ethdb.NewMemDatabase()
odr := NewLesOdr(ldb, rm)
odr := NewLesOdr(ldb, light.NewChtIndexer(db, true), light.NewBloomTrieIndexer(db, true), eth.NewBloomBitsProcessor(db, light.BloomTrieFrequency), rm)
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
lpm := newTestProtocolManagerMust(t, true, 0, nil, peers, odr, ldb)
_, err1, lpeer, err2 := newTestPeerPair("peer", protocol, pm, lpm)
Expand Down
3 changes: 2 additions & 1 deletion les/request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/light"
)
Expand Down Expand Up @@ -73,7 +74,7 @@ func testAccess(t *testing.T, protocol int, fn accessTestFn) {
rm := newRetrieveManager(peers, dist, nil)
db, _ := ethdb.NewMemDatabase()
ldb, _ := ethdb.NewMemDatabase()
odr := NewLesOdr(ldb, rm)
odr := NewLesOdr(ldb, light.NewChtIndexer(db, true), light.NewBloomTrieIndexer(db, true), eth.NewBloomBitsProcessor(db, light.BloomTrieFrequency), rm)

pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
lpm := newTestProtocolManagerMust(t, true, 0, nil, peers, odr, ldb)
Expand Down
Loading

0 comments on commit 46f1b87

Please sign in to comment.