github.com/c4dt/go-ethereum@v1.9.2/les/helper_test.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // This file contains some shares testing functionality, common to  multiple
    18  // different files and modules being tested.
    19  
    20  package les
    21  
    22  import (
    23  	"context"
    24  	"crypto/rand"
    25  	"math/big"
    26  	"sync"
    27  	"testing"
    28  	"time"
    29  
    30  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    31  	"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
    32  	"github.com/ethereum/go-ethereum/common"
    33  	"github.com/ethereum/go-ethereum/common/mclock"
    34  	"github.com/ethereum/go-ethereum/consensus/ethash"
    35  	"github.com/ethereum/go-ethereum/contracts/checkpointoracle/contract"
    36  	"github.com/ethereum/go-ethereum/core"
    37  	"github.com/ethereum/go-ethereum/core/rawdb"
    38  	"github.com/ethereum/go-ethereum/core/types"
    39  	"github.com/ethereum/go-ethereum/crypto"
    40  	"github.com/ethereum/go-ethereum/eth"
    41  	"github.com/ethereum/go-ethereum/ethdb"
    42  	"github.com/ethereum/go-ethereum/event"
    43  	"github.com/ethereum/go-ethereum/les/flowcontrol"
    44  	"github.com/ethereum/go-ethereum/light"
    45  	"github.com/ethereum/go-ethereum/p2p"
    46  	"github.com/ethereum/go-ethereum/p2p/enode"
    47  	"github.com/ethereum/go-ethereum/params"
    48  )
    49  
    50  var (
    51  	bankKey, _ = crypto.GenerateKey()
    52  	bankAddr   = crypto.PubkeyToAddress(bankKey.PublicKey)
    53  	bankFunds  = big.NewInt(1000000000000000000)
    54  
    55  	userKey1, _ = crypto.GenerateKey()
    56  	userKey2, _ = crypto.GenerateKey()
    57  	userAddr1   = crypto.PubkeyToAddress(userKey1.PublicKey)
    58  	userAddr2   = crypto.PubkeyToAddress(userKey2.PublicKey)
    59  
    60  	testContractCode         = common.Hex2Bytes("606060405260cc8060106000396000f360606040526000357c01000000000000000000000000000000000000000000000000000000009004806360cd2685146041578063c16431b914606b57603f565b005b6055600480803590602001909190505060a9565b6040518082815260200191505060405180910390f35b60886004808035906020019091908035906020019091905050608a565b005b80600060005083606481101560025790900160005b50819055505b5050565b6000600060005082606481101560025790900160005b5054905060c7565b91905056")
    61  	testContractAddr         common.Address
    62  	testContractCodeDeployed = testContractCode[16:]
    63  	testContractDeployed     = uint64(2)
    64  
    65  	testEventEmitterCode = common.Hex2Bytes("60606040523415600e57600080fd5b7f57050ab73f6b9ebdd9f76b8d4997793f48cf956e965ee070551b9ca0bb71584e60405160405180910390a160358060476000396000f3006060604052600080fd00a165627a7a723058203f727efcad8b5811f8cb1fc2620ce5e8c63570d697aef968172de296ea3994140029")
    66  
    67  	// Checkpoint registrar relative
    68  	registrarAddr common.Address
    69  	signerKey, _  = crypto.GenerateKey()
    70  	signerAddr    = crypto.PubkeyToAddress(signerKey.PublicKey)
    71  )
    72  
    73  var (
    74  	// The block frequency for creating checkpoint(only used in test)
    75  	sectionSize = big.NewInt(512)
    76  
    77  	// The number of confirmations needed to generate a checkpoint(only used in test).
    78  	processConfirms = big.NewInt(4)
    79  
    80  	//
    81  	testBufLimit    = uint64(1000000)
    82  	testBufRecharge = uint64(1000)
    83  )
    84  
    85  /*
    86  contract test {
    87  
    88      uint256[100] data;
    89  
    90      function Put(uint256 addr, uint256 value) {
    91          data[addr] = value;
    92      }
    93  
    94      function Get(uint256 addr) constant returns (uint256 value) {
    95          return data[addr];
    96      }
    97  }
    98  */
    99  
   100  // prepareTestchain pre-commits specified number customized blocks into chain.
   101  func prepareTestchain(n int, backend *backends.SimulatedBackend) {
   102  	var (
   103  		ctx    = context.Background()
   104  		signer = types.HomesteadSigner{}
   105  	)
   106  	for i := 0; i < n; i++ {
   107  		switch i {
   108  		case 0:
   109  			// deploy checkpoint contract
   110  			registrarAddr, _, _, _ = contract.DeployCheckpointOracle(bind.NewKeyedTransactor(bankKey), backend, []common.Address{signerAddr}, sectionSize, processConfirms, big.NewInt(1))
   111  			// bankUser transfers some ether to user1
   112  			nonce, _ := backend.PendingNonceAt(ctx, bankAddr)
   113  			tx, _ := types.SignTx(types.NewTransaction(nonce, userAddr1, big.NewInt(10000), params.TxGas, nil, nil), signer, bankKey)
   114  			backend.SendTransaction(ctx, tx)
   115  		case 1:
   116  			bankNonce, _ := backend.PendingNonceAt(ctx, bankAddr)
   117  			userNonce1, _ := backend.PendingNonceAt(ctx, userAddr1)
   118  
   119  			// bankUser transfers more ether to user1
   120  			tx1, _ := types.SignTx(types.NewTransaction(bankNonce, userAddr1, big.NewInt(1000), params.TxGas, nil, nil), signer, bankKey)
   121  			backend.SendTransaction(ctx, tx1)
   122  
   123  			// user1 relays ether to user2
   124  			tx2, _ := types.SignTx(types.NewTransaction(userNonce1, userAddr2, big.NewInt(1000), params.TxGas, nil, nil), signer, userKey1)
   125  			backend.SendTransaction(ctx, tx2)
   126  
   127  			// user1 deploys a test contract
   128  			tx3, _ := types.SignTx(types.NewContractCreation(userNonce1+1, big.NewInt(0), 200000, big.NewInt(0), testContractCode), signer, userKey1)
   129  			backend.SendTransaction(ctx, tx3)
   130  			testContractAddr = crypto.CreateAddress(userAddr1, userNonce1+1)
   131  
   132  			// user1 deploys a event contract
   133  			tx4, _ := types.SignTx(types.NewContractCreation(userNonce1+2, big.NewInt(0), 200000, big.NewInt(0), testEventEmitterCode), signer, userKey1)
   134  			backend.SendTransaction(ctx, tx4)
   135  		case 2:
   136  			// bankUser transfer some ether to signer
   137  			bankNonce, _ := backend.PendingNonceAt(ctx, bankAddr)
   138  			tx1, _ := types.SignTx(types.NewTransaction(bankNonce, signerAddr, big.NewInt(1000000000), params.TxGas, nil, nil), signer, bankKey)
   139  			backend.SendTransaction(ctx, tx1)
   140  
   141  			// invoke test contract
   142  			data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001")
   143  			tx2, _ := types.SignTx(types.NewTransaction(bankNonce+1, testContractAddr, big.NewInt(0), 100000, nil, data), signer, bankKey)
   144  			backend.SendTransaction(ctx, tx2)
   145  		case 3:
   146  			// invoke test contract
   147  			bankNonce, _ := backend.PendingNonceAt(ctx, bankAddr)
   148  			data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002")
   149  			tx, _ := types.SignTx(types.NewTransaction(bankNonce, testContractAddr, big.NewInt(0), 100000, nil, data), signer, bankKey)
   150  			backend.SendTransaction(ctx, tx)
   151  		}
   152  		backend.Commit()
   153  	}
   154  }
   155  
   156  // testIndexers creates a set of indexers with specified params for testing purpose.
   157  func testIndexers(db ethdb.Database, odr light.OdrBackend, config *light.IndexerConfig) []*core.ChainIndexer {
   158  	var indexers [3]*core.ChainIndexer
   159  	indexers[0] = light.NewChtIndexer(db, odr, config.ChtSize, config.ChtConfirms)
   160  	indexers[1] = eth.NewBloomIndexer(db, config.BloomSize, config.BloomConfirms)
   161  	indexers[2] = light.NewBloomTrieIndexer(db, odr, config.BloomSize, config.BloomTrieSize)
   162  	// make bloomTrieIndexer as a child indexer of bloom indexer.
   163  	indexers[1].AddChildIndexer(indexers[2])
   164  	return indexers[:]
   165  }
   166  
   167  // newTestProtocolManager creates a new protocol manager for testing purposes,
   168  // with the given number of blocks already known, potential notification
   169  // channels for different events and relative chain indexers array.
   170  func newTestProtocolManager(lightSync bool, blocks int, odr *LesOdr, indexers []*core.ChainIndexer, peers *peerSet, db ethdb.Database, ulcServers []string, ulcFraction int, testCost uint64, clock mclock.Clock) (*ProtocolManager, *backends.SimulatedBackend, error) {
   171  	var (
   172  		evmux  = new(event.TypeMux)
   173  		engine = ethash.NewFaker()
   174  		gspec  = core.Genesis{
   175  			Config: params.AllEthashProtocolChanges,
   176  			Alloc:  core.GenesisAlloc{bankAddr: {Balance: bankFunds}},
   177  		}
   178  		pool   txPool
   179  		chain  BlockChain
   180  		exitCh = make(chan struct{})
   181  	)
   182  	gspec.MustCommit(db)
   183  	if peers == nil {
   184  		peers = newPeerSet()
   185  	}
   186  	// create a simulation backend and pre-commit several customized block to the database.
   187  	simulation := backends.NewSimulatedBackendWithDatabase(db, gspec.Alloc, 100000000)
   188  	prepareTestchain(blocks, simulation)
   189  
   190  	// initialize empty chain for light client or pre-committed chain for server.
   191  	if lightSync {
   192  		chain, _ = light.NewLightChain(odr, gspec.Config, engine, nil)
   193  	} else {
   194  		chain = simulation.Blockchain()
   195  		config := core.DefaultTxPoolConfig
   196  		config.Journal = ""
   197  		pool = core.NewTxPool(config, gspec.Config, simulation.Blockchain())
   198  	}
   199  
   200  	// Create contract registrar
   201  	indexConfig := light.TestServerIndexerConfig
   202  	if lightSync {
   203  		indexConfig = light.TestClientIndexerConfig
   204  	}
   205  	config := &params.CheckpointOracleConfig{
   206  		Address:   crypto.CreateAddress(bankAddr, 0),
   207  		Signers:   []common.Address{signerAddr},
   208  		Threshold: 1,
   209  	}
   210  	var reg *checkpointOracle
   211  	if indexers != nil {
   212  		getLocal := func(index uint64) params.TrustedCheckpoint {
   213  			chtIndexer := indexers[0]
   214  			sectionHead := chtIndexer.SectionHead(index)
   215  			return params.TrustedCheckpoint{
   216  				SectionIndex: index,
   217  				SectionHead:  sectionHead,
   218  				CHTRoot:      light.GetChtRoot(db, index, sectionHead),
   219  				BloomRoot:    light.GetBloomTrieRoot(db, index, sectionHead),
   220  			}
   221  		}
   222  		reg = newCheckpointOracle(config, getLocal)
   223  	}
   224  	pm, err := NewProtocolManager(gspec.Config, nil, indexConfig, ulcServers, ulcFraction, lightSync, NetworkId, evmux, peers, chain, pool, db, odr, nil, reg, exitCh, new(sync.WaitGroup), func() bool { return true })
   225  	if err != nil {
   226  		return nil, nil, err
   227  	}
   228  	// Registrar initialization could failed if checkpoint contract is not specified.
   229  	if pm.reg != nil {
   230  		pm.reg.start(simulation)
   231  	}
   232  	// Set up les server stuff.
   233  	if !lightSync {
   234  		srv := &LesServer{lesCommons: lesCommons{protocolManager: pm, chainDb: db}}
   235  		pm.server = srv
   236  		pm.servingQueue = newServingQueue(int64(time.Millisecond*10), 1)
   237  		pm.servingQueue.setThreads(4)
   238  
   239  		srv.defParams = flowcontrol.ServerParams{
   240  			BufLimit:    testBufLimit,
   241  			MinRecharge: testBufRecharge,
   242  		}
   243  		srv.testCost = testCost
   244  		srv.fcManager = flowcontrol.NewClientManager(nil, clock)
   245  	}
   246  	pm.Start(1000)
   247  	return pm, simulation, nil
   248  }
   249  
   250  // newTestProtocolManagerMust creates a new protocol manager for testing purposes,
   251  // with the given number of blocks already known, potential notification channels
   252  // for different events and relative chain indexers array. In case of an error, the
   253  // constructor force-fails the test.
   254  func newTestProtocolManagerMust(t *testing.T, lightSync bool, blocks int, odr *LesOdr, indexers []*core.ChainIndexer, peers *peerSet, db ethdb.Database, ulcServers []string, ulcFraction int) (*ProtocolManager, *backends.SimulatedBackend) {
   255  	pm, backend, err := newTestProtocolManager(lightSync, blocks, odr, indexers, peers, db, ulcServers, ulcFraction, 0, &mclock.System{})
   256  	if err != nil {
   257  		t.Fatalf("Failed to create protocol manager: %v", err)
   258  	}
   259  	return pm, backend
   260  }
   261  
   262  // testPeer is a simulated peer to allow testing direct network calls.
   263  type testPeer struct {
   264  	net p2p.MsgReadWriter // Network layer reader/writer to simulate remote messaging
   265  	app *p2p.MsgPipeRW    // Application layer reader/writer to simulate the local side
   266  	*peer
   267  }
   268  
   269  // newTestPeer creates a new peer registered at the given protocol manager.
   270  func newTestPeer(t *testing.T, name string, version int, pm *ProtocolManager, shake bool, testCost uint64) (*testPeer, <-chan error) {
   271  	// Create a message pipe to communicate through
   272  	app, net := p2p.MsgPipe()
   273  
   274  	// Generate a random id and create the peer
   275  	var id enode.ID
   276  	rand.Read(id[:])
   277  
   278  	peer := pm.newPeer(version, NetworkId, p2p.NewPeer(id, name, nil), net)
   279  
   280  	// Start the peer on a new thread
   281  	errc := make(chan error, 1)
   282  	go func() {
   283  		select {
   284  		case pm.newPeerCh <- peer:
   285  			errc <- pm.handle(peer)
   286  		case <-pm.quitSync:
   287  			errc <- p2p.DiscQuitting
   288  		}
   289  	}()
   290  	tp := &testPeer{
   291  		app:  app,
   292  		net:  net,
   293  		peer: peer,
   294  	}
   295  	// Execute any implicitly requested handshakes and return
   296  	if shake {
   297  		var (
   298  			genesis = pm.blockchain.Genesis()
   299  			head    = pm.blockchain.CurrentHeader()
   300  			td      = pm.blockchain.GetTd(head.Hash(), head.Number.Uint64())
   301  		)
   302  		tp.handshake(t, td, head.Hash(), head.Number.Uint64(), genesis.Hash(), testCost)
   303  	}
   304  	return tp, errc
   305  }
   306  
   307  func newTestPeerPair(name string, version int, pm, pm2 *ProtocolManager) (*peer, <-chan error, *peer, <-chan error) {
   308  	// Create a message pipe to communicate through
   309  	app, net := p2p.MsgPipe()
   310  
   311  	// Generate a random id and create the peer
   312  	var id enode.ID
   313  	rand.Read(id[:])
   314  
   315  	peer := pm.newPeer(version, NetworkId, p2p.NewPeer(id, name, nil), net)
   316  	peer2 := pm2.newPeer(version, NetworkId, p2p.NewPeer(id, name, nil), app)
   317  
   318  	// Start the peer on a new thread
   319  	errc := make(chan error, 1)
   320  	errc2 := make(chan error, 1)
   321  	go func() {
   322  		select {
   323  		case pm.newPeerCh <- peer:
   324  			errc <- pm.handle(peer)
   325  		case <-pm.quitSync:
   326  			errc <- p2p.DiscQuitting
   327  		}
   328  	}()
   329  	go func() {
   330  		select {
   331  		case pm2.newPeerCh <- peer2:
   332  			errc2 <- pm2.handle(peer2)
   333  		case <-pm2.quitSync:
   334  			errc2 <- p2p.DiscQuitting
   335  		}
   336  	}()
   337  	return peer, errc, peer2, errc2
   338  }
   339  
   340  // handshake simulates a trivial handshake that expects the same state from the
   341  // remote side as we are simulating locally.
   342  func (p *testPeer) handshake(t *testing.T, td *big.Int, head common.Hash, headNum uint64, genesis common.Hash, testCost uint64) {
   343  	var expList keyValueList
   344  	expList = expList.add("protocolVersion", uint64(p.version))
   345  	expList = expList.add("networkId", uint64(NetworkId))
   346  	expList = expList.add("headTd", td)
   347  	expList = expList.add("headHash", head)
   348  	expList = expList.add("headNum", headNum)
   349  	expList = expList.add("genesisHash", genesis)
   350  	sendList := make(keyValueList, len(expList))
   351  	copy(sendList, expList)
   352  	expList = expList.add("serveHeaders", nil)
   353  	expList = expList.add("serveChainSince", uint64(0))
   354  	expList = expList.add("serveStateSince", uint64(0))
   355  	expList = expList.add("serveRecentState", uint64(core.TriesInMemory-4))
   356  	expList = expList.add("txRelay", nil)
   357  	expList = expList.add("flowControl/BL", testBufLimit)
   358  	expList = expList.add("flowControl/MRR", testBufRecharge)
   359  	expList = expList.add("flowControl/MRC", testCostList(testCost))
   360  
   361  	if err := p2p.ExpectMsg(p.app, StatusMsg, expList); err != nil {
   362  		t.Fatalf("status recv: %v", err)
   363  	}
   364  	if err := p2p.Send(p.app, StatusMsg, sendList); err != nil {
   365  		t.Fatalf("status send: %v", err)
   366  	}
   367  
   368  	p.fcParams = flowcontrol.ServerParams{
   369  		BufLimit:    testBufLimit,
   370  		MinRecharge: testBufRecharge,
   371  	}
   372  }
   373  
   374  // close terminates the local side of the peer, notifying the remote protocol
   375  // manager of termination.
   376  func (p *testPeer) close() {
   377  	p.app.Close()
   378  }
   379  
   380  // TestEntity represents a network entity for testing with necessary auxiliary fields.
   381  type TestEntity struct {
   382  	db      ethdb.Database
   383  	rPeer   *peer
   384  	tPeer   *testPeer
   385  	peers   *peerSet
   386  	pm      *ProtocolManager
   387  	backend *backends.SimulatedBackend
   388  
   389  	// Indexers
   390  	chtIndexer       *core.ChainIndexer
   391  	bloomIndexer     *core.ChainIndexer
   392  	bloomTrieIndexer *core.ChainIndexer
   393  }
   394  
   395  // newServerEnv creates a server testing environment with a connected test peer for testing purpose.
   396  func newServerEnv(t *testing.T, blocks int, protocol int, waitIndexers func(*core.ChainIndexer, *core.ChainIndexer, *core.ChainIndexer)) (*TestEntity, func()) {
   397  	db := rawdb.NewMemoryDatabase()
   398  	indexers := testIndexers(db, nil, light.TestServerIndexerConfig)
   399  
   400  	pm, b := newTestProtocolManagerMust(t, false, blocks, nil, indexers, nil, db, nil, 0)
   401  	peer, _ := newTestPeer(t, "peer", protocol, pm, true, 0)
   402  
   403  	cIndexer, bIndexer, btIndexer := indexers[0], indexers[1], indexers[2]
   404  	cIndexer.Start(pm.blockchain.(*core.BlockChain))
   405  	bIndexer.Start(pm.blockchain.(*core.BlockChain))
   406  
   407  	// Wait until indexers generate enough index data.
   408  	if waitIndexers != nil {
   409  		waitIndexers(cIndexer, bIndexer, btIndexer)
   410  	}
   411  
   412  	return &TestEntity{
   413  			db:               db,
   414  			tPeer:            peer,
   415  			pm:               pm,
   416  			backend:          b,
   417  			chtIndexer:       cIndexer,
   418  			bloomIndexer:     bIndexer,
   419  			bloomTrieIndexer: btIndexer,
   420  		}, func() {
   421  			peer.close()
   422  			// Note bloom trie indexer will be closed by it parent recursively.
   423  			cIndexer.Close()
   424  			bIndexer.Close()
   425  			b.Close()
   426  		}
   427  }
   428  
   429  // newClientServerEnv creates a client/server arch environment with a connected les server and light client pair
   430  // for testing purpose.
   431  func newClientServerEnv(t *testing.T, blocks int, protocol int, waitIndexers func(*core.ChainIndexer, *core.ChainIndexer, *core.ChainIndexer), newPeer bool) (*TestEntity, *TestEntity, func()) {
   432  	db, ldb := rawdb.NewMemoryDatabase(), rawdb.NewMemoryDatabase()
   433  	peers, lPeers := newPeerSet(), newPeerSet()
   434  
   435  	dist := newRequestDistributor(lPeers, make(chan struct{}), &mclock.System{})
   436  	rm := newRetrieveManager(lPeers, dist, nil)
   437  	odr := NewLesOdr(ldb, light.TestClientIndexerConfig, rm)
   438  
   439  	indexers := testIndexers(db, nil, light.TestServerIndexerConfig)
   440  	lIndexers := testIndexers(ldb, odr, light.TestClientIndexerConfig)
   441  
   442  	cIndexer, bIndexer, btIndexer := indexers[0], indexers[1], indexers[2]
   443  	lcIndexer, lbIndexer, lbtIndexer := lIndexers[0], lIndexers[1], lIndexers[2]
   444  
   445  	odr.SetIndexers(lcIndexer, lbtIndexer, lbIndexer)
   446  
   447  	pm, b := newTestProtocolManagerMust(t, false, blocks, nil, indexers, peers, db, nil, 0)
   448  	lpm, lb := newTestProtocolManagerMust(t, true, 0, odr, lIndexers, lPeers, ldb, nil, 0)
   449  
   450  	startIndexers := func(clientMode bool, pm *ProtocolManager) {
   451  		if clientMode {
   452  			lcIndexer.Start(pm.blockchain.(*light.LightChain))
   453  			lbIndexer.Start(pm.blockchain.(*light.LightChain))
   454  		} else {
   455  			cIndexer.Start(pm.blockchain.(*core.BlockChain))
   456  			bIndexer.Start(pm.blockchain.(*core.BlockChain))
   457  		}
   458  	}
   459  
   460  	startIndexers(false, pm)
   461  	startIndexers(true, lpm)
   462  
   463  	// Execute wait until function if it is specified.
   464  	if waitIndexers != nil {
   465  		waitIndexers(cIndexer, bIndexer, btIndexer)
   466  	}
   467  
   468  	var (
   469  		peer, lPeer *peer
   470  		err1, err2  <-chan error
   471  	)
   472  	if newPeer {
   473  		peer, err1, lPeer, err2 = newTestPeerPair("peer", protocol, pm, lpm)
   474  		select {
   475  		case <-time.After(time.Millisecond * 100):
   476  		case err := <-err1:
   477  			t.Fatalf("peer 1 handshake error: %v", err)
   478  		case err := <-err2:
   479  			t.Fatalf("peer 2 handshake error: %v", err)
   480  		}
   481  	}
   482  
   483  	return &TestEntity{
   484  			db:               db,
   485  			pm:               pm,
   486  			rPeer:            peer,
   487  			peers:            peers,
   488  			backend:          b,
   489  			chtIndexer:       cIndexer,
   490  			bloomIndexer:     bIndexer,
   491  			bloomTrieIndexer: btIndexer,
   492  		}, &TestEntity{
   493  			db:               ldb,
   494  			pm:               lpm,
   495  			rPeer:            lPeer,
   496  			peers:            lPeers,
   497  			backend:          lb,
   498  			chtIndexer:       lcIndexer,
   499  			bloomIndexer:     lbIndexer,
   500  			bloomTrieIndexer: lbtIndexer,
   501  		}, func() {
   502  			// Note bloom trie indexers will be closed by their parents recursively.
   503  			cIndexer.Close()
   504  			bIndexer.Close()
   505  			lcIndexer.Close()
   506  			lbIndexer.Close()
   507  			b.Close()
   508  			lb.Close()
   509  		}
   510  }