diff --git a/les/api.go b/les/api.go index b58cf0fc82..27d3e3975f 100644 --- a/les/api.go +++ b/les/api.go @@ -25,51 +25,50 @@ import ( ) var ( - errNoStableCheckpoint = errors.New("no stable checkpoint provided") + errNoCheckpoint = errors.New("no local checkpoint provided") ) -// PublicLesServerAPI provides an API to access the les server. -// It offers only methods that operate on public data that is freely available to anyone. -type PublicLesServerAPI struct { +// PrivateLesServerAPI provides a private API to access the les server. +type PrivateLesServerAPI struct { server *LesServer } -// NewPublicLesServerAPI creates a new les server API. -func NewPublicLesServerAPI(server *LesServer) *PublicLesServerAPI { - return &PublicLesServerAPI{ +// NewPrivateLesServerAPI creates a new les server API. +func NewPrivateLesServerAPI(server *LesServer) *PrivateLesServerAPI { + return &PrivateLesServerAPI{ server: server, } } -// Checkpoint returns the latest checkpoint package. +// Checkpoint returns the latest local checkpoint package. // // The checkpoint package consists of 4 strings: // result[0], hex encoded latest section index // result[1], 32 bytes hex encoded latest section head hash // result[2], 32 bytes hex encoded latest section canonical hash trie root hash // result[3], 32 bytes hex encoded latest section bloom trie root hash -func (api *PublicLesServerAPI) LatestCheckpoint() ([4]string, error) { +func (api *PrivateLesServerAPI) LatestCheckpoint() ([4]string, error) { var res [4]string sectionIdx, sectionHead, chtRoot, bloomTrieRoot := api.server.latestCheckpoint() if sectionHead == (common.Hash{}) || chtRoot == (common.Hash{}) || bloomTrieRoot == (common.Hash{}) { - return res, errNoStableCheckpoint + return res, errNoCheckpoint } res[0] = hexutil.Encode(big.NewInt(int64(sectionIdx)).Bytes()) res[1], res[2], res[3] = sectionHead.Hex(), chtRoot.Hex(), bloomTrieRoot.Hex() return res, nil } -// GetCheckpoint returns the specific checkpoint package. +// GetCheckpoint returns the specific local checkpoint package. // // The checkpoint package consists of 3 strings: // result[0], 32 bytes hex encoded latest section head hash // result[1], 32 bytes hex encoded latest section canonical hash trie root hash // result[2], 32 bytes hex encoded latest section bloom trie root hash -func (api *PublicLesServerAPI) GetCheckpoint(index uint64) ([3]string, error) { +func (api *PrivateLesServerAPI) GetCheckpoint(index uint64) ([3]string, error) { var res [3]string sectionHead, chtRoot, bloomTrieRoot := api.server.getCheckpoint(index) if sectionHead == (common.Hash{}) || chtRoot == (common.Hash{}) || bloomTrieRoot == (common.Hash{}) { - return res, errNoStableCheckpoint + return res, errNoCheckpoint } res[0], res[1], res[2] = sectionHead.Hex(), chtRoot.Hex(), bloomTrieRoot.Hex() return res, nil diff --git a/les/server.go b/les/server.go index 617212166c..3f30b85aa8 100644 --- a/les/server.go +++ b/les/server.go @@ -188,15 +188,15 @@ func (s *LesServer) APIs() []rpc.API { { Namespace: "les", Version: "1.0", - Service: NewPublicLesServerAPI(s), - Public: true, + Service: NewPrivateLesServerAPI(s), + Public: false, }, } } // latestCheckpoint finds the common stored section index and returns a set of // post-processed trie roots (CHT and BloomTrie) associated with -// the appropriate section index and head hash as a checkpoint package. +// the appropriate section index and head hash as a local checkpoint package. // // Note for cht, the section size in LES1 is 4K, so indexer still uses LES/1 // 4k section size for backwards server compatibility. For bloomTrie, the size @@ -219,6 +219,9 @@ func (s *LesServer) latestCheckpoint() (uint64, common.Hash, common.Hash, common // getCheckpoint returns a set of post-processed trie roots (CHT and BloomTrie) // associated with the appropriate head hash by specific section index. +// +// The returned checkpoint is only the checkpoint generated by the local indexers, +// not the stable checkpoint registered in the registrar contract. func (s *LesServer) getCheckpoint(index uint64) (common.Hash, common.Hash, common.Hash) { // convert last LES/2 section index back to LES/1 index for chtIndexer.SectionHead latest := (index+1)*(light.CHTFrequencyClient/light.CHTFrequencyServer) - 1 @@ -315,6 +318,7 @@ func (s *LesServer) recoverCheckpoint() *light.TrustedCheckpoint { headHash = rawdb.ReadHeadHeaderHash(s.chaindb) headNumber = rawdb.ReadHeaderNumber(s.chaindb, headHash) ) + // Short circuit if there is no local checkpoint generated. if headNumber == nil || sectionCnt == 0 { return nil } @@ -322,24 +326,25 @@ func (s *LesServer) recoverCheckpoint() *light.TrustedCheckpoint { for stable == nil || stable.SectionIdx < unstableIdx { if (unstableIdx+1)*light.CheckpointFrequency+light.CheckpointConfirmations <= *headNumber { iter, err := s.registrar.FilterNewCheckpointEvent(*headNumber, unstableIdx, light.CheckpointFrequency, light.CheckpointProcessConfirmations) - if err == nil { - for iter.Next() { - sectionHead := s.bloomTrieIndexer.SectionHead(unstableIdx) - checkpoint := &light.TrustedCheckpoint{ - SectionIdx: unstableIdx, - SectionHead: sectionHead, - ChtRoot: light.GetChtV2Root(s.chaindb, unstableIdx, sectionHead), - BloomTrieRoot: light.GetBloomTrieRoot(s.chaindb, unstableIdx, sectionHead), - } - if checkpoint.HashEqual(common.Hash(iter.Event.CheckpointHash)) { - light.WriteTrustedCheckpoint(s.chaindb, checkpoint) - iter.Close() - log.Info("Recover checkpoint", "index", checkpoint.SectionIdx, "hash", checkpoint.Hash().Hex()) - return checkpoint - } - } - iter.Close() + if err != nil { + continue } + for iter.Next() { + sectionHead := s.bloomTrieIndexer.SectionHead(unstableIdx) + checkpoint := &light.TrustedCheckpoint{ + SectionIdx: unstableIdx, + SectionHead: sectionHead, + ChtRoot: light.GetChtV2Root(s.chaindb, unstableIdx, sectionHead), + BloomTrieRoot: light.GetBloomTrieRoot(s.chaindb, unstableIdx, sectionHead), + } + if checkpoint.HashEqual(common.Hash(iter.Event.CheckpointHash)) { + light.WriteTrustedCheckpoint(s.chaindb, checkpoint) + iter.Close() + log.Info("Recover stable checkpoint", "index", checkpoint.SectionIdx, "hash", checkpoint.Hash().Hex()) + return checkpoint + } + } + iter.Close() } if unstableIdx == 0 { break @@ -349,7 +354,7 @@ func (s *LesServer) recoverCheckpoint() *light.TrustedCheckpoint { if stable == nil { log.Info("No stable checkpoint") } else { - log.Info("Recover checkpoint", "index", stable.SectionIdx, "hash", stable.Hash().Hex()) + log.Info("Recover stable checkpoint", "index", stable.SectionIdx, "hash", stable.Hash().Hex()) } return stable }