aboutsummaryrefslogtreecommitdiffstats
path: root/les
diff options
context:
space:
mode:
Diffstat (limited to 'les')
-rw-r--r--les/backend.go39
-rw-r--r--les/distributor.go4
-rw-r--r--les/handler.go34
-rw-r--r--les/helper_test.go6
-rw-r--r--les/odr.go18
-rw-r--r--les/odr_test.go3
-rw-r--r--les/request_test.go3
-rw-r--r--les/retrieve.go3
-rw-r--r--les/server.go4
9 files changed, 70 insertions, 44 deletions
diff --git a/les/backend.go b/les/backend.go
index 178bc1e0e..9b8cc1828 100644
--- a/les/backend.go
+++ b/les/backend.go
@@ -95,29 +95,35 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
quitSync := make(chan struct{})
leth := &LightEthereum{
- config: config,
- chainConfig: chainConfig,
- chainDb: chainDb,
- eventMux: ctx.EventMux,
- peers: peers,
- reqDist: newRequestDistributor(peers, quitSync),
- accountManager: ctx.AccountManager,
- engine: eth.CreateConsensusEngine(ctx, chainConfig, &config.Ethash, nil, chainDb),
- shutdownChan: make(chan bool),
- networkId: config.NetworkId,
- bloomRequests: make(chan chan *bloombits.Retrieval),
- bloomIndexer: eth.NewBloomIndexer(chainDb, light.BloomTrieFrequency),
- chtIndexer: light.NewChtIndexer(chainDb, true),
- bloomTrieIndexer: light.NewBloomTrieIndexer(chainDb, true),
+ config: config,
+ chainConfig: chainConfig,
+ chainDb: chainDb,
+ eventMux: ctx.EventMux,
+ peers: peers,
+ reqDist: newRequestDistributor(peers, quitSync),
+ accountManager: ctx.AccountManager,
+ engine: eth.CreateConsensusEngine(ctx, chainConfig, &config.Ethash, nil, chainDb),
+ shutdownChan: make(chan bool),
+ networkId: config.NetworkId,
+ bloomRequests: make(chan chan *bloombits.Retrieval),
+ bloomIndexer: eth.NewBloomIndexer(chainDb, light.BloomTrieFrequency, light.HelperTrieConfirmations),
}
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.bloomTrieIndexer, leth.bloomIndexer, leth.retriever)
+ leth.odr = NewLesOdr(chainDb, leth.retriever)
+ leth.chtIndexer = light.NewChtIndexer(chainDb, true, leth.odr)
+ leth.bloomTrieIndexer = light.NewBloomTrieIndexer(chainDb, true, leth.odr)
+ leth.odr.SetIndexers(leth.chtIndexer, leth.bloomTrieIndexer, leth.bloomIndexer)
+ // Note: NewLightChain adds the trusted checkpoint so it needs an ODR with
+ // indexers already set but not started yet
if leth.blockchain, err = light.NewLightChain(leth.odr, leth.chainConfig, leth.engine); err != nil {
return nil, err
}
+ // Note: AddChildIndexer starts the update process for the child
+ leth.bloomIndexer.AddChildIndexer(leth.bloomTrieIndexer)
+ leth.chtIndexer.Start(leth.blockchain)
leth.bloomIndexer.Start(leth.blockchain)
// Rewind the chain in case of an incompatible config upgrade.
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
@@ -242,9 +248,6 @@ func (s *LightEthereum) Stop() error {
if s.chtIndexer != nil {
s.chtIndexer.Close()
}
- if s.bloomTrieIndexer != nil {
- s.bloomTrieIndexer.Close()
- }
s.blockchain.Stop()
s.protocolManager.Stop()
s.txPool.Stop()
diff --git a/les/distributor.go b/les/distributor.go
index 159fa4c73..d3f6b21d1 100644
--- a/les/distributor.go
+++ b/les/distributor.go
@@ -20,14 +20,10 @@ package les
import (
"container/list"
- "errors"
"sync"
"time"
)
-// ErrNoPeers is returned if no peers capable of serving a queued request are available
-var ErrNoPeers = errors.New("no suitable peers available")
-
// requestDistributor implements a mechanism that distributes requests to
// suitable peers, obeying flow control rules and prioritizing them in creation
// order (even when a resend is necessary).
diff --git a/les/handler.go b/les/handler.go
index 91a235bf0..ccb4a8844 100644
--- a/les/handler.go
+++ b/les/handler.go
@@ -1206,11 +1206,12 @@ func (pm *ProtocolManager) txStatus(hashes []common.Hash) []txStatus {
// NodeInfo represents a short summary of the Ethereum sub-protocol metadata
// known about the host peer.
type NodeInfo struct {
- Network uint64 `json:"network"` // Ethereum network ID (1=Frontier, 2=Morden, Ropsten=3, Rinkeby=4)
- Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain
- Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block
- Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules
- Head common.Hash `json:"head"` // SHA3 hash of the host's best owned block
+ Network uint64 `json:"network"` // Ethereum network ID (1=Frontier, 2=Morden, Ropsten=3, Rinkeby=4)
+ Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain
+ Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block
+ Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules
+ Head common.Hash `json:"head"` // SHA3 hash of the host's best owned block
+ CHT light.TrustedCheckpoint `json:"cht"` // Trused CHT checkpoint for fast catchup
}
// NodeInfo retrieves some protocol metadata about the running host node.
@@ -1218,12 +1219,31 @@ func (self *ProtocolManager) NodeInfo() *NodeInfo {
head := self.blockchain.CurrentHeader()
hash := head.Hash()
+ var cht light.TrustedCheckpoint
+
+ sections, _, sectionHead := self.odr.ChtIndexer().Sections()
+ sections2, _, sectionHead2 := self.odr.BloomTrieIndexer().Sections()
+ if sections2 < sections {
+ sections = sections2
+ sectionHead = sectionHead2
+ }
+ if sections > 0 {
+ sectionIndex := sections - 1
+ cht = light.TrustedCheckpoint{
+ SectionIdx: sectionIndex,
+ SectionHead: sectionHead,
+ CHTRoot: light.GetChtRoot(self.chainDb, sectionIndex, sectionHead),
+ BloomRoot: light.GetBloomTrieRoot(self.chainDb, sectionIndex, sectionHead),
+ }
+ }
+
return &NodeInfo{
Network: self.networkId,
Difficulty: self.blockchain.GetTd(hash, head.Number.Uint64()),
Genesis: self.blockchain.Genesis().Hash(),
Config: self.blockchain.Config(),
Head: hash,
+ CHT: cht,
}
}
@@ -1258,7 +1278,7 @@ func (pc *peerConnection) RequestHeadersByHash(origin common.Hash, amount int, s
}
_, ok := <-pc.manager.reqDist.queue(rq)
if !ok {
- return ErrNoPeers
+ return light.ErrNoPeers
}
return nil
}
@@ -1282,7 +1302,7 @@ func (pc *peerConnection) RequestHeadersByNumber(origin uint64, amount int, skip
}
_, ok := <-pc.manager.reqDist.queue(rq)
if !ok {
- return ErrNoPeers
+ return light.ErrNoPeers
}
return nil
}
diff --git a/les/helper_test.go b/les/helper_test.go
index 8fd01a39e..50c97e06e 100644
--- a/les/helper_test.go
+++ b/les/helper_test.go
@@ -156,12 +156,12 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor
} else {
blockchain, _ := core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{})
- chtIndexer := light.NewChtIndexer(db, false)
+ chtIndexer := light.NewChtIndexer(db, false, nil)
chtIndexer.Start(blockchain)
- bbtIndexer := light.NewBloomTrieIndexer(db, false)
+ bbtIndexer := light.NewBloomTrieIndexer(db, false, nil)
- bloomIndexer := eth.NewBloomIndexer(db, params.BloomBitsBlocks)
+ bloomIndexer := eth.NewBloomIndexer(db, params.BloomBitsBlocks, light.HelperTrieProcessConfirmations)
bloomIndexer.AddChildIndexer(bbtIndexer)
bloomIndexer.Start(blockchain)
diff --git a/les/odr.go b/les/odr.go
index f8412aaad..2ad28d5d9 100644
--- a/les/odr.go
+++ b/les/odr.go
@@ -33,14 +33,11 @@ type LesOdr struct {
stop chan struct{}
}
-func NewLesOdr(db ethdb.Database, chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer, retriever *retrieveManager) *LesOdr {
+func NewLesOdr(db ethdb.Database, retriever *retrieveManager) *LesOdr {
return &LesOdr{
- db: db,
- chtIndexer: chtIndexer,
- bloomTrieIndexer: bloomTrieIndexer,
- bloomIndexer: bloomIndexer,
- retriever: retriever,
- stop: make(chan struct{}),
+ db: db,
+ retriever: retriever,
+ stop: make(chan struct{}),
}
}
@@ -54,6 +51,13 @@ func (odr *LesOdr) Database() ethdb.Database {
return odr.db
}
+// SetIndexers adds the necessary chain indexers to the ODR backend
+func (odr *LesOdr) SetIndexers(chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer) {
+ odr.chtIndexer = chtIndexer
+ odr.bloomTrieIndexer = bloomTrieIndexer
+ odr.bloomIndexer = bloomIndexer
+}
+
// ChtIndexer returns the CHT chain indexer
func (odr *LesOdr) ChtIndexer() *core.ChainIndexer {
return odr.chtIndexer
diff --git a/les/odr_test.go b/les/odr_test.go
index 983f7262b..c7c25cbe4 100644
--- a/les/odr_test.go
+++ b/les/odr_test.go
@@ -167,7 +167,8 @@ 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, light.NewChtIndexer(db, true), light.NewBloomTrieIndexer(db, true), eth.NewBloomIndexer(db, light.BloomTrieFrequency), rm)
+ odr := NewLesOdr(ldb, rm)
+ odr.SetIndexers(light.NewChtIndexer(db, true, nil), light.NewBloomTrieIndexer(db, true, nil), eth.NewBloomIndexer(db, light.BloomTrieFrequency, light.HelperTrieConfirmations))
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)
diff --git a/les/request_test.go b/les/request_test.go
index ba2f603d8..db576798b 100644
--- a/les/request_test.go
+++ b/les/request_test.go
@@ -89,7 +89,8 @@ func testAccess(t *testing.T, protocol int, fn accessTestFn) {
rm := newRetrieveManager(peers, dist, nil)
db := ethdb.NewMemDatabase()
ldb := ethdb.NewMemDatabase()
- odr := NewLesOdr(ldb, light.NewChtIndexer(db, true), light.NewBloomTrieIndexer(db, true), eth.NewBloomIndexer(db, light.BloomTrieFrequency), rm)
+ odr := NewLesOdr(ldb, rm)
+ odr.SetIndexers(light.NewChtIndexer(db, true, nil), light.NewBloomTrieIndexer(db, true, nil), eth.NewBloomIndexer(db, light.BloomTrieFrequency, light.HelperTrieConfirmations))
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
lpm := newTestProtocolManagerMust(t, true, 0, nil, peers, odr, ldb)
diff --git a/les/retrieve.go b/les/retrieve.go
index a9037a38e..8ae36d82c 100644
--- a/les/retrieve.go
+++ b/les/retrieve.go
@@ -27,6 +27,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/common/mclock"
+ "github.com/ethereum/go-ethereum/light"
)
var (
@@ -207,7 +208,7 @@ func (r *sentReq) stateRequesting() reqStateFn {
return r.stateNoMorePeers
}
// nothing to wait for, no more peers to ask, return with error
- r.stop(ErrNoPeers)
+ r.stop(light.ErrNoPeers)
// no need to go to stopped state because waiting() already returned false
return nil
}
diff --git a/les/server.go b/les/server.go
index fca6124c9..a934fbf26 100644
--- a/les/server.go
+++ b/les/server.go
@@ -67,8 +67,8 @@ func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) {
protocolManager: pm,
quitSync: quitSync,
lesTopics: lesTopics,
- chtIndexer: light.NewChtIndexer(eth.ChainDb(), false),
- bloomTrieIndexer: light.NewBloomTrieIndexer(eth.ChainDb(), false),
+ chtIndexer: light.NewChtIndexer(eth.ChainDb(), false, nil),
+ bloomTrieIndexer: light.NewBloomTrieIndexer(eth.ChainDb(), false, nil),
}
logger := log.New()