diff --git a/les/api_backend.go b/les/api_backend.go index dea33c4702..780f9e5259 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -48,7 +48,7 @@ func (b *LesApiBackend) ChainConfig() *params.ChainConfig { } func (b *LesApiBackend) CurrentBlock() *types.Block { - return types.NewBlockWithHeader(b.eth.BlockChain().CurrentHeader()) + return types.NewBlockWithHeader(b.eth.blockchain.CurrentHeader()) } func (b *LesApiBackend) SetHead(number uint64) { diff --git a/les/fetcher.go b/les/fetcher.go index 59d3a2aa3c..18fc07df01 100644 --- a/les/fetcher.go +++ b/les/fetcher.go @@ -108,7 +108,7 @@ type fetchResponse struct { func newLightFetcher(pm *ProtocolManager) *lightFetcher { f := &lightFetcher{ pm: pm, - chain: pm.blockchain.(*light.LightChain), + chain: pm.lightchain, odr: pm.odr, peers: make(map[*peer]*fetcherPeerInfo), deliverChn: make(chan fetchResponse, 100), diff --git a/les/handler.go b/les/handler.go index caf76e851e..1f034faa33 100644 --- a/les/handler.go +++ b/les/handler.go @@ -72,20 +72,12 @@ func errResp(code errCode, format string, v ...interface{}) error { return fmt.Errorf("%v - %v", code, fmt.Sprintf(format, v...)) } +// BlockChain interface is used by code shared between LES client and server mode type BlockChain interface { Config() *params.ChainConfig - HasHeader(hash common.Hash, number uint64) bool - GetHeader(hash common.Hash, number uint64) *types.Header - GetHeaderByHash(hash common.Hash) *types.Header CurrentHeader() *types.Header GetTd(hash common.Hash, number uint64) *big.Int - State() (*state.StateDB, error) - InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) - Rollback(chain []common.Hash) - GetHeaderByNumber(number uint64) *types.Header - GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) Genesis() *types.Block - SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription } type txPool interface { @@ -99,7 +91,9 @@ type ProtocolManager struct { txrelay *LesTxRelay networkId uint64 chainConfig *params.ChainConfig - blockchain BlockChain + chain BlockChain + blockchain *core.BlockChain + lightchain *light.LightChain chainDb ethdb.Database odr *LesOdr server *LesServer @@ -129,12 +123,12 @@ type ProtocolManager struct { // NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable // with the ethereum network. -func NewProtocolManager(chainConfig *params.ChainConfig, lightSync bool, protocolVersions []uint, networkId uint64, mux *event.TypeMux, engine consensus.Engine, peers *peerSet, blockchain BlockChain, txpool txPool, chainDb ethdb.Database, odr *LesOdr, txrelay *LesTxRelay, serverPool *serverPool, quitSync chan struct{}, wg *sync.WaitGroup) (*ProtocolManager, error) { +func NewProtocolManager(chainConfig *params.ChainConfig, lightSync bool, protocolVersions []uint, networkId uint64, mux *event.TypeMux, engine consensus.Engine, peers *peerSet, chain BlockChain, txpool txPool, chainDb ethdb.Database, odr *LesOdr, txrelay *LesTxRelay, serverPool *serverPool, quitSync chan struct{}, wg *sync.WaitGroup) (*ProtocolManager, error) { // Create the protocol manager with the base fields manager := &ProtocolManager{ lightSync: lightSync, eventMux: mux, - blockchain: blockchain, + chain: chain, chainConfig: chainConfig, chainDb: chainDb, odr: odr, @@ -148,6 +142,11 @@ func NewProtocolManager(chainConfig *params.ChainConfig, lightSync bool, protoco wg: wg, noMorePeers: make(chan struct{}), } + if lightSync { + manager.lightchain = chain.(*light.LightChain) + } else { + manager.blockchain = chain.(*core.BlockChain) + } if odr != nil { manager.retriever = odr.retriever manager.reqDist = odr.retriever.dist @@ -207,7 +206,7 @@ func NewProtocolManager(chainConfig *params.ChainConfig, lightSync bool, protoco } if lightSync { - manager.downloader = downloader.New(downloader.LightSync, chainDb, manager.eventMux, nil, blockchain, removePeer) + manager.downloader = downloader.New(downloader.LightSync, chainDb, manager.eventMux, nil, manager.lightchain, removePeer) manager.peers.notify((*downloaderPeerNotify)(manager)) manager.fetcher = newLightFetcher(manager) } @@ -272,11 +271,11 @@ func (pm *ProtocolManager) handle(p *peer) error { // Execute the LES handshake var ( - genesis = pm.blockchain.Genesis() - head = pm.blockchain.CurrentHeader() + genesis = pm.chain.Genesis() + head = pm.chain.CurrentHeader() hash = head.Hash() number = head.Number.Uint64() - td = pm.blockchain.GetTd(hash, number) + td = pm.chain.GetTd(hash, number) ) if err := p.Handshake(td, hash, number, genesis.Hash(), pm.server); err != nil { p.Log().Debug("Light Ethereum handshake failed", "err", err) @@ -416,7 +415,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { if reject(query.Amount, MaxHeaderFetch) { return errResp(ErrRequestRejected, "") } - headers := eth.ServeBlockHeaders(pm.blockchain.(*core.BlockChain), p.Peer, query.Origin.Hash, query.Origin.Number, query.Amount, query.Skip, query.Reverse) + headers := eth.ServeBlockHeaders(pm.blockchain, p.Peer, query.Origin.Hash, query.Origin.Number, query.Amount, query.Skip, query.Reverse) bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + query.Amount*costs.reqCost) pm.server.fcCostStats.update(msg.Code, query.Amount, rcost) return p.SendBlockHeaders(req.ReqID, bv, headers) @@ -469,7 +468,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { break } // Retrieve the requested block body, stopping if enough was found - if data := pm.blockchain.(*core.BlockChain).GetBodyRLP(hash); len(data) != 0 { + if data := pm.blockchain.GetBodyRLP(hash); len(data) != 0 { bodies = append(bodies, data) bytes += len(data) } @@ -588,7 +587,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { break } - if encoded := eth.ServeBlockReceipts(pm.blockchain.(*core.BlockChain), hash); encoded != nil { + if encoded := eth.ServeBlockReceipts(pm.blockchain, hash); encoded != nil { receipts = append(receipts, encoded) bytes += len(encoded) } @@ -1101,14 +1100,14 @@ type NodeInfo struct { // NodeInfo retrieves some protocol metadata about the running host node. func (self *ProtocolManager) NodeInfo() *NodeInfo { - head := self.blockchain.CurrentHeader() + head := self.chain.CurrentHeader() hash := head.Hash() return &NodeInfo{ Network: self.networkId, - Difficulty: self.blockchain.GetTd(hash, head.Number.Uint64()), - Genesis: self.blockchain.Genesis().Hash(), - Config: self.blockchain.Config(), + Difficulty: self.chain.GetTd(hash, head.Number.Uint64()), + Genesis: self.chain.Genesis().Hash(), + Config: self.chain.Config(), Head: hash, } } diff --git a/les/handler_test.go b/les/handler_test.go index 31aad3ed45..94f1ddc202 100644 --- a/les/handler_test.go +++ b/les/handler_test.go @@ -52,7 +52,7 @@ func TestGetBlockHeadersLes2(t *testing.T) { testGetBlockHeaders(t, 2) } func testGetBlockHeaders(t *testing.T, protocol int) { pm := newTestProtocolManagerMust(t, false, downloader.MaxHashFetch+15, nil, nil, nil, ethdb.NewMemDatabase()) - bc := pm.blockchain.(*core.BlockChain) + bc := pm.blockchain peer, _ := newTestPeer(t, "peer", protocol, pm, true) defer peer.close() @@ -181,7 +181,7 @@ func TestGetBlockBodiesLes2(t *testing.T) { testGetBlockBodies(t, 2) } func testGetBlockBodies(t *testing.T, protocol int) { pm := newTestProtocolManagerMust(t, false, downloader.MaxBlockFetch+15, nil, nil, nil, ethdb.NewMemDatabase()) - bc := pm.blockchain.(*core.BlockChain) + bc := pm.blockchain peer, _ := newTestPeer(t, "peer", protocol, pm, true) defer peer.close() @@ -258,7 +258,7 @@ func TestGetCodeLes2(t *testing.T) { testGetCode(t, 2) } func testGetCode(t *testing.T, protocol int) { // Assemble the test environment pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, ethdb.NewMemDatabase()) - bc := pm.blockchain.(*core.BlockChain) + bc := pm.blockchain peer, _ := newTestPeer(t, "peer", protocol, pm, true) defer peer.close() @@ -292,7 +292,7 @@ func testGetReceipt(t *testing.T, protocol int) { // Assemble the test environment db := ethdb.NewMemDatabase() pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db) - bc := pm.blockchain.(*core.BlockChain) + bc := pm.blockchain peer, _ := newTestPeer(t, "peer", protocol, pm, true) defer peer.close() @@ -320,7 +320,7 @@ func testGetProofs(t *testing.T, protocol int) { // Assemble the test environment db := ethdb.NewMemDatabase() pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db) - bc := pm.blockchain.(*core.BlockChain) + bc := pm.blockchain peer, _ := newTestPeer(t, "peer", protocol, pm, true) defer peer.close() @@ -383,7 +383,7 @@ func testGetCHTProofs(t *testing.T, protocol int) { // Assemble the test environment db := ethdb.NewMemDatabase() pm := newTestProtocolManagerMust(t, false, int(frequency)+light.HelperTrieProcessConfirmations, testChainGen, nil, nil, db) - bc := pm.blockchain.(*core.BlockChain) + bc := pm.blockchain peer, _ := newTestPeer(t, "peer", protocol, pm, true) defer peer.close() @@ -451,7 +451,7 @@ func TestGetBloombitsProofs(t *testing.T) { // Assemble the test environment db := ethdb.NewMemDatabase() pm := newTestProtocolManagerMust(t, false, light.BloomTrieFrequency+256, testChainGen, nil, nil, db) - bc := pm.blockchain.(*core.BlockChain) + bc := pm.blockchain peer, _ := newTestPeer(t, "peer", 2, pm, true) defer peer.close() @@ -490,7 +490,7 @@ func TestGetBloombitsProofs(t *testing.T) { func TestTransactionStatusLes2(t *testing.T) { db := ethdb.NewMemDatabase() pm := newTestProtocolManagerMust(t, false, 0, nil, nil, nil, db) - chain := pm.blockchain.(*core.BlockChain) + chain := pm.blockchain config := core.DefaultTxPoolConfig config.Journal = "" txpool := core.NewTxPool(config, params.TestChainConfig, chain) diff --git a/les/helper_test.go b/les/helper_test.go index 8fd01a39e0..1f3c238be1 100644 --- a/les/helper_test.go +++ b/les/helper_test.go @@ -246,9 +246,9 @@ func newTestPeer(t *testing.T, name string, version int, pm *ProtocolManager, sh // Execute any implicitly requested handshakes and return if shake { var ( - genesis = pm.blockchain.Genesis() - head = pm.blockchain.CurrentHeader() - td = pm.blockchain.GetTd(head.Hash(), head.Number.Uint64()) + genesis = pm.chain.Genesis() + head = pm.chain.CurrentHeader() + td = pm.chain.GetTd(head.Hash(), head.Number.Uint64()) ) tp.handshake(t, td, head.Hash(), head.Number.Uint64(), genesis.Hash()) } diff --git a/les/odr_test.go b/les/odr_test.go index 983f7262b0..3b71158ff4 100644 --- a/les/odr_test.go +++ b/les/odr_test.go @@ -184,11 +184,11 @@ func testOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) { test := func(expFail uint64) { for i := uint64(0); i <= pm.blockchain.CurrentHeader().Number.Uint64(); i++ { bhash := rawdb.ReadCanonicalHash(db, i) - b1 := fn(light.NoOdr, db, pm.chainConfig, pm.blockchain.(*core.BlockChain), nil, bhash) + b1 := fn(light.NoOdr, db, pm.chainConfig, pm.blockchain, nil, bhash) ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond) defer cancel() - b2 := fn(ctx, ldb, lpm.chainConfig, nil, lpm.blockchain.(*light.LightChain), bhash) + b2 := fn(ctx, ldb, lpm.chainConfig, nil, lpm.lightchain, bhash) eq := bytes.Equal(b1, b2) exp := i < expFail diff --git a/les/sync.go b/les/sync.go index 1ac6455852..510d9323bc 100644 --- a/les/sync.go +++ b/les/sync.go @@ -22,7 +22,6 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/eth/downloader" - "github.com/ethereum/go-ethereum/light" ) // syncer is responsible for periodically synchronising with the network, both @@ -55,7 +54,7 @@ func (pm *ProtocolManager) syncer() { } func (pm *ProtocolManager) needToSync(peerHead blockInfo) bool { - head := pm.blockchain.CurrentHeader() + head := pm.lightchain.CurrentHeader() currentTd := rawdb.ReadTd(pm.chainDb, head.Hash(), head.Number.Uint64()) return currentTd != nil && peerHead.Td.Cmp(currentTd) > 0 } @@ -74,6 +73,6 @@ func (pm *ProtocolManager) synchronise(peer *peer) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() - pm.blockchain.(*light.LightChain).SyncCht(ctx) + pm.lightchain.SyncCht(ctx) pm.downloader.Synchronise(peer.id, peer.Head(), peer.Td(), downloader.LightSync) }