mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
les: refactor test a bit
This commit is contained in:
parent
3ededf0edd
commit
da8abaf8cb
12 changed files with 323 additions and 205 deletions
|
|
@ -309,7 +309,6 @@ func (c *ChainIndexer) updateLoop() {
|
||||||
updating = false
|
updating = false
|
||||||
c.log.Info("Finished upgrading chain index")
|
c.log.Info("Finished upgrading chain index")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.cascadedHead = c.storedSections*c.sectionSize - 1
|
c.cascadedHead = c.storedSections*c.sectionSize - 1
|
||||||
for _, child := range c.children {
|
for _, child := range c.children {
|
||||||
c.log.Trace("Cascading chain index update", "head", c.cascadedHead)
|
c.log.Trace("Cascading chain index update", "head", c.cascadedHead)
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
|
||||||
leth.serverPool = newServerPool(chainDb, quitSync, &leth.wg)
|
leth.serverPool = newServerPool(chainDb, quitSync, &leth.wg)
|
||||||
leth.retriever = newRetrieveManager(peers, leth.reqDist, leth.serverPool)
|
leth.retriever = newRetrieveManager(peers, leth.reqDist, leth.serverPool)
|
||||||
leth.odr = NewLesOdr(chainDb, light.DefaultClientIndexerConfig, leth.chtIndexer, leth.bloomTrieIndexer, leth.bloomIndexer, leth.retriever)
|
leth.odr = NewLesOdr(chainDb, light.DefaultClientIndexerConfig, leth.chtIndexer, leth.bloomTrieIndexer, leth.bloomIndexer, leth.retriever)
|
||||||
if leth.blockchain, err = light.NewLightChain(leth.odr, leth.chainConfig, light.DefaultClientIndexerConfig, leth.engine); err != nil {
|
if leth.blockchain, err = light.NewLightChain(leth.odr, leth.chainConfig, leth.engine); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
leth.bloomIndexer.Start(leth.blockchain)
|
leth.bloomIndexer.Start(leth.blockchain)
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,13 @@ func TestGetBlockHeadersLes1(t *testing.T) { testGetBlockHeaders(t, 1) }
|
||||||
func TestGetBlockHeadersLes2(t *testing.T) { testGetBlockHeaders(t, 2) }
|
func TestGetBlockHeadersLes2(t *testing.T) { testGetBlockHeaders(t, 2) }
|
||||||
|
|
||||||
func testGetBlockHeaders(t *testing.T, protocol int) {
|
func testGetBlockHeaders(t *testing.T, protocol int) {
|
||||||
pm := newTestProtocolManagerMust(t, false, downloader.MaxHashFetch+15, nil, nil, nil, ethdb.NewMemDatabase())
|
server, tearDown := newServerEnv(t, downloader.MaxHashFetch+15, protocol, 0)
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
defer func() {
|
||||||
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
if tearDown != nil {
|
||||||
defer peer.close()
|
tearDown()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
bc := server.pm.blockchain.(*core.BlockChain)
|
||||||
|
|
||||||
// Create a "random" unknown hash for testing
|
// Create a "random" unknown hash for testing
|
||||||
var unknown common.Hash
|
var unknown common.Hash
|
||||||
|
|
@ -167,9 +170,9 @@ func testGetBlockHeaders(t *testing.T, protocol int) {
|
||||||
}
|
}
|
||||||
// Send the hash request and verify the response
|
// Send the hash request and verify the response
|
||||||
reqID++
|
reqID++
|
||||||
cost := peer.GetRequestCost(GetBlockHeadersMsg, int(tt.query.Amount))
|
cost := server.tPeer.GetRequestCost(GetBlockHeadersMsg, int(tt.query.Amount))
|
||||||
sendRequest(peer.app, GetBlockHeadersMsg, reqID, cost, tt.query)
|
sendRequest(server.tPeer.app, GetBlockHeadersMsg, reqID, cost, tt.query)
|
||||||
if err := expectResponse(peer.app, BlockHeadersMsg, reqID, testBufLimit, headers); err != nil {
|
if err := expectResponse(server.tPeer.app, BlockHeadersMsg, reqID, testBufLimit, headers); err != nil {
|
||||||
t.Errorf("test %d: headers mismatch: %v", i, err)
|
t.Errorf("test %d: headers mismatch: %v", i, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -180,10 +183,13 @@ func TestGetBlockBodiesLes1(t *testing.T) { testGetBlockBodies(t, 1) }
|
||||||
func TestGetBlockBodiesLes2(t *testing.T) { testGetBlockBodies(t, 2) }
|
func TestGetBlockBodiesLes2(t *testing.T) { testGetBlockBodies(t, 2) }
|
||||||
|
|
||||||
func testGetBlockBodies(t *testing.T, protocol int) {
|
func testGetBlockBodies(t *testing.T, protocol int) {
|
||||||
pm := newTestProtocolManagerMust(t, false, downloader.MaxBlockFetch+15, nil, nil, nil, ethdb.NewMemDatabase())
|
server, tearDown := newServerEnv(t, downloader.MaxBlockFetch+15, protocol, 0)
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
defer func() {
|
||||||
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
if tearDown != nil {
|
||||||
defer peer.close()
|
tearDown()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
bc := server.pm.blockchain.(*core.BlockChain)
|
||||||
|
|
||||||
// Create a batch of tests for various scenarios
|
// Create a batch of tests for various scenarios
|
||||||
limit := MaxBodyFetch
|
limit := MaxBodyFetch
|
||||||
|
|
@ -243,9 +249,9 @@ func testGetBlockBodies(t *testing.T, protocol int) {
|
||||||
}
|
}
|
||||||
reqID++
|
reqID++
|
||||||
// Send the hash request and verify the response
|
// Send the hash request and verify the response
|
||||||
cost := peer.GetRequestCost(GetBlockBodiesMsg, len(hashes))
|
cost := server.tPeer.GetRequestCost(GetBlockBodiesMsg, len(hashes))
|
||||||
sendRequest(peer.app, GetBlockBodiesMsg, reqID, cost, hashes)
|
sendRequest(server.tPeer.app, GetBlockBodiesMsg, reqID, cost, hashes)
|
||||||
if err := expectResponse(peer.app, BlockBodiesMsg, reqID, testBufLimit, bodies); err != nil {
|
if err := expectResponse(server.tPeer.app, BlockBodiesMsg, reqID, testBufLimit, bodies); err != nil {
|
||||||
t.Errorf("test %d: bodies mismatch: %v", i, err)
|
t.Errorf("test %d: bodies mismatch: %v", i, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -257,10 +263,13 @@ func TestGetCodeLes2(t *testing.T) { testGetCode(t, 2) }
|
||||||
|
|
||||||
func testGetCode(t *testing.T, protocol int) {
|
func testGetCode(t *testing.T, protocol int) {
|
||||||
// Assemble the test environment
|
// Assemble the test environment
|
||||||
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, ethdb.NewMemDatabase())
|
server, tearDown := newServerEnv(t, 4, protocol, 0)
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
defer func() {
|
||||||
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
if tearDown != nil {
|
||||||
defer peer.close()
|
tearDown()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
bc := server.pm.blockchain.(*core.BlockChain)
|
||||||
|
|
||||||
var codereqs []*CodeReq
|
var codereqs []*CodeReq
|
||||||
var codes [][]byte
|
var codes [][]byte
|
||||||
|
|
@ -277,9 +286,9 @@ func testGetCode(t *testing.T, protocol int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cost := peer.GetRequestCost(GetCodeMsg, len(codereqs))
|
cost := server.tPeer.GetRequestCost(GetCodeMsg, len(codereqs))
|
||||||
sendRequest(peer.app, GetCodeMsg, 42, cost, codereqs)
|
sendRequest(server.tPeer.app, GetCodeMsg, 42, cost, codereqs)
|
||||||
if err := expectResponse(peer.app, CodeMsg, 42, testBufLimit, codes); err != nil {
|
if err := expectResponse(server.tPeer.app, CodeMsg, 42, testBufLimit, codes); err != nil {
|
||||||
t.Errorf("codes mismatch: %v", err)
|
t.Errorf("codes mismatch: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -290,11 +299,13 @@ func TestGetReceiptLes2(t *testing.T) { testGetReceipt(t, 2) }
|
||||||
|
|
||||||
func testGetReceipt(t *testing.T, protocol int) {
|
func testGetReceipt(t *testing.T, protocol int) {
|
||||||
// Assemble the test environment
|
// Assemble the test environment
|
||||||
db := ethdb.NewMemDatabase()
|
server, tearDown := newServerEnv(t, 4, protocol, 0)
|
||||||
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
|
defer func() {
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
if tearDown != nil {
|
||||||
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
tearDown()
|
||||||
defer peer.close()
|
}
|
||||||
|
}()
|
||||||
|
bc := server.pm.blockchain.(*core.BlockChain)
|
||||||
|
|
||||||
// Collect the hashes to request, and the response to expect
|
// Collect the hashes to request, and the response to expect
|
||||||
hashes, receipts := []common.Hash{}, []types.Receipts{}
|
hashes, receipts := []common.Hash{}, []types.Receipts{}
|
||||||
|
|
@ -302,12 +313,12 @@ func testGetReceipt(t *testing.T, protocol int) {
|
||||||
block := bc.GetBlockByNumber(i)
|
block := bc.GetBlockByNumber(i)
|
||||||
|
|
||||||
hashes = append(hashes, block.Hash())
|
hashes = append(hashes, block.Hash())
|
||||||
receipts = append(receipts, rawdb.ReadReceipts(db, block.Hash(), block.NumberU64()))
|
receipts = append(receipts, rawdb.ReadReceipts(server.db, block.Hash(), block.NumberU64()))
|
||||||
}
|
}
|
||||||
// Send the hash request and verify the response
|
// Send the hash request and verify the response
|
||||||
cost := peer.GetRequestCost(GetReceiptsMsg, len(hashes))
|
cost := server.tPeer.GetRequestCost(GetReceiptsMsg, len(hashes))
|
||||||
sendRequest(peer.app, GetReceiptsMsg, 42, cost, hashes)
|
sendRequest(server.tPeer.app, GetReceiptsMsg, 42, cost, hashes)
|
||||||
if err := expectResponse(peer.app, ReceiptsMsg, 42, testBufLimit, receipts); err != nil {
|
if err := expectResponse(server.tPeer.app, ReceiptsMsg, 42, testBufLimit, receipts); err != nil {
|
||||||
t.Errorf("receipts mismatch: %v", err)
|
t.Errorf("receipts mismatch: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -318,11 +329,13 @@ func TestGetProofsLes2(t *testing.T) { testGetProofs(t, 2) }
|
||||||
|
|
||||||
func testGetProofs(t *testing.T, protocol int) {
|
func testGetProofs(t *testing.T, protocol int) {
|
||||||
// Assemble the test environment
|
// Assemble the test environment
|
||||||
db := ethdb.NewMemDatabase()
|
server, tearDown := newServerEnv(t, 4, protocol, 0)
|
||||||
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)
|
defer func() {
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
if tearDown != nil {
|
||||||
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
tearDown()
|
||||||
defer peer.close()
|
}
|
||||||
|
}()
|
||||||
|
bc := server.pm.blockchain.(*core.BlockChain)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
proofreqs []ProofReq
|
proofreqs []ProofReq
|
||||||
|
|
@ -334,7 +347,7 @@ func testGetProofs(t *testing.T, protocol int) {
|
||||||
for i := uint64(0); i <= bc.CurrentBlock().NumberU64(); i++ {
|
for i := uint64(0); i <= bc.CurrentBlock().NumberU64(); i++ {
|
||||||
header := bc.GetHeaderByNumber(i)
|
header := bc.GetHeaderByNumber(i)
|
||||||
root := header.Root
|
root := header.Root
|
||||||
trie, _ := trie.New(root, trie.NewDatabase(db))
|
trie, _ := trie.New(root, trie.NewDatabase(server.db))
|
||||||
|
|
||||||
for _, acc := range accounts {
|
for _, acc := range accounts {
|
||||||
req := ProofReq{
|
req := ProofReq{
|
||||||
|
|
@ -356,15 +369,15 @@ func testGetProofs(t *testing.T, protocol int) {
|
||||||
// Send the proof request and verify the response
|
// Send the proof request and verify the response
|
||||||
switch protocol {
|
switch protocol {
|
||||||
case 1:
|
case 1:
|
||||||
cost := peer.GetRequestCost(GetProofsV1Msg, len(proofreqs))
|
cost := server.tPeer.GetRequestCost(GetProofsV1Msg, len(proofreqs))
|
||||||
sendRequest(peer.app, GetProofsV1Msg, 42, cost, proofreqs)
|
sendRequest(server.tPeer.app, GetProofsV1Msg, 42, cost, proofreqs)
|
||||||
if err := expectResponse(peer.app, ProofsV1Msg, 42, testBufLimit, proofsV1); err != nil {
|
if err := expectResponse(server.tPeer.app, ProofsV1Msg, 42, testBufLimit, proofsV1); err != nil {
|
||||||
t.Errorf("proofs mismatch: %v", err)
|
t.Errorf("proofs mismatch: %v", err)
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
cost := peer.GetRequestCost(GetProofsV2Msg, len(proofreqs))
|
cost := server.tPeer.GetRequestCost(GetProofsV2Msg, len(proofreqs))
|
||||||
sendRequest(peer.app, GetProofsV2Msg, 42, cost, proofreqs)
|
sendRequest(server.tPeer.app, GetProofsV2Msg, 42, cost, proofreqs)
|
||||||
if err := expectResponse(peer.app, ProofsV2Msg, 42, testBufLimit, proofsV2.NodeList()); err != nil {
|
if err := expectResponse(server.tPeer.app, ProofsV2Msg, 42, testBufLimit, proofsV2.NodeList()); err != nil {
|
||||||
t.Errorf("proofs mismatch: %v", err)
|
t.Errorf("proofs mismatch: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -375,28 +388,26 @@ func TestGetCHTProofsLes1(t *testing.T) { testGetCHTProofs(t, 1) }
|
||||||
func TestGetCHTProofsLes2(t *testing.T) { testGetCHTProofs(t, 2) }
|
func TestGetCHTProofsLes2(t *testing.T) { testGetCHTProofs(t, 2) }
|
||||||
|
|
||||||
func testGetCHTProofs(t *testing.T, protocol int) {
|
func testGetCHTProofs(t *testing.T, protocol int) {
|
||||||
// Figure out the client's CHT frequency
|
config := light.TestServerIndexerConfig
|
||||||
frequency := uint64(params.CHTFrequencyClient)
|
frequency := config.ChtSize
|
||||||
if protocol == 1 {
|
if protocol == 2 {
|
||||||
frequency = uint64(params.CHTFrequencyServer)
|
frequency = config.ChtSize * 8
|
||||||
}
|
}
|
||||||
// Assemble the test environment
|
|
||||||
db := ethdb.NewMemDatabase()
|
|
||||||
pm := newTestProtocolManagerMust(t, false, int(frequency)+params.HelperTrieProcessConfirmations, testChainGen, nil, nil, db)
|
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
|
||||||
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
|
||||||
defer peer.close()
|
|
||||||
|
|
||||||
// Wait a while for the CHT indexer to process the new headers
|
server, tearDown := newServerEnv(t, int(frequency+config.ChtConfirm), protocol, 1)
|
||||||
time.Sleep(100 * time.Millisecond * time.Duration(frequency/params.CHTFrequencyServer)) // Chain indexer throttling
|
defer func() {
|
||||||
time.Sleep(250 * time.Millisecond) // CI tester slack
|
if tearDown != nil {
|
||||||
|
tearDown()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
bc := server.pm.blockchain.(*core.BlockChain)
|
||||||
|
|
||||||
// Assemble the proofs from the different protocols
|
// Assemble the proofs from the different protocols
|
||||||
header := bc.GetHeaderByNumber(frequency)
|
header := bc.GetHeaderByNumber(config.ChtSize - 1)
|
||||||
rlp, _ := rlp.EncodeToBytes(header)
|
rlp, _ := rlp.EncodeToBytes(header)
|
||||||
|
|
||||||
key := make([]byte, 8)
|
key := make([]byte, 8)
|
||||||
binary.BigEndian.PutUint64(key, frequency)
|
binary.BigEndian.PutUint64(key, config.ChtSize-1)
|
||||||
|
|
||||||
proofsV1 := []ChtResp{{
|
proofsV1 := []ChtResp{{
|
||||||
Header: header,
|
Header: header,
|
||||||
|
|
@ -406,22 +417,22 @@ func testGetCHTProofs(t *testing.T, protocol int) {
|
||||||
}
|
}
|
||||||
switch protocol {
|
switch protocol {
|
||||||
case 1:
|
case 1:
|
||||||
root := light.GetChtRoot(db, 0, bc.GetHeaderByNumber(frequency-1).Hash())
|
root := light.GetChtRoot(server.db, 0, bc.GetHeaderByNumber(config.ChtSize-1).Hash())
|
||||||
trie, _ := trie.New(root, trie.NewDatabase(ethdb.NewTable(db, light.ChtTablePrefix)))
|
trie, _ := trie.New(root, trie.NewDatabase(ethdb.NewTable(server.db, light.ChtTablePrefix)))
|
||||||
|
|
||||||
var proof light.NodeList
|
var proof light.NodeList
|
||||||
trie.Prove(key, 0, &proof)
|
trie.Prove(key, 0, &proof)
|
||||||
proofsV1[0].Proof = proof
|
proofsV1[0].Proof = proof
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
root := light.GetChtRoot(db, (params.CHTFrequencyClient/params.CHTFrequencyServer)-1, bc.GetHeaderByNumber(frequency-1).Hash())
|
root := light.GetChtRoot(server.db, (config.ChtSize/config.PairChtSize)-1, bc.GetHeaderByNumber(config.ChtSize-1).Hash())
|
||||||
trie, _ := trie.New(root, trie.NewDatabase(ethdb.NewTable(db, light.ChtTablePrefix)))
|
trie, _ := trie.New(root, trie.NewDatabase(ethdb.NewTable(server.db, light.ChtTablePrefix)))
|
||||||
trie.Prove(key, 0, &proofsV2.Proofs)
|
trie.Prove(key, 0, &proofsV2.Proofs)
|
||||||
}
|
}
|
||||||
// Assemble the requests for the different protocols
|
// Assemble the requests for the different protocols
|
||||||
requestsV1 := []ChtReq{{
|
requestsV1 := []ChtReq{{
|
||||||
ChtNum: 1,
|
ChtNum: 1,
|
||||||
BlockNum: frequency,
|
BlockNum: config.ChtSize - 1,
|
||||||
}}
|
}}
|
||||||
requestsV2 := []HelperTrieReq{{
|
requestsV2 := []HelperTrieReq{{
|
||||||
Type: htCanonical,
|
Type: htCanonical,
|
||||||
|
|
@ -432,15 +443,15 @@ func testGetCHTProofs(t *testing.T, protocol int) {
|
||||||
// Send the proof request and verify the response
|
// Send the proof request and verify the response
|
||||||
switch protocol {
|
switch protocol {
|
||||||
case 1:
|
case 1:
|
||||||
cost := peer.GetRequestCost(GetHeaderProofsMsg, len(requestsV1))
|
cost := server.tPeer.GetRequestCost(GetHeaderProofsMsg, len(requestsV1))
|
||||||
sendRequest(peer.app, GetHeaderProofsMsg, 42, cost, requestsV1)
|
sendRequest(server.tPeer.app, GetHeaderProofsMsg, 42, cost, requestsV1)
|
||||||
if err := expectResponse(peer.app, HeaderProofsMsg, 42, testBufLimit, proofsV1); err != nil {
|
if err := expectResponse(server.tPeer.app, HeaderProofsMsg, 42, testBufLimit, proofsV1); err != nil {
|
||||||
t.Errorf("proofs mismatch: %v", err)
|
t.Errorf("proofs mismatch: %v", err)
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
cost := peer.GetRequestCost(GetHelperTrieProofsMsg, len(requestsV2))
|
cost := server.tPeer.GetRequestCost(GetHelperTrieProofsMsg, len(requestsV2))
|
||||||
sendRequest(peer.app, GetHelperTrieProofsMsg, 42, cost, requestsV2)
|
sendRequest(server.tPeer.app, GetHelperTrieProofsMsg, 42, cost, requestsV2)
|
||||||
if err := expectResponse(peer.app, HelperTrieProofsMsg, 42, testBufLimit, proofsV2); err != nil {
|
if err := expectResponse(server.tPeer.app, HelperTrieProofsMsg, 42, testBufLimit, proofsV2); err != nil {
|
||||||
t.Errorf("proofs mismatch: %v", err)
|
t.Errorf("proofs mismatch: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -448,24 +459,22 @@ func testGetCHTProofs(t *testing.T, protocol int) {
|
||||||
|
|
||||||
// Tests that bloombits proofs can be correctly retrieved.
|
// Tests that bloombits proofs can be correctly retrieved.
|
||||||
func TestGetBloombitsProofs(t *testing.T) {
|
func TestGetBloombitsProofs(t *testing.T) {
|
||||||
// Assemble the test environment
|
config := light.TestServerIndexerConfig
|
||||||
db := ethdb.NewMemDatabase()
|
server, tearDown := newServerEnv(t, int(config.BloomSize+config.BloomConfirm), 2, 1)
|
||||||
pm := newTestProtocolManagerMust(t, false, int(params.BloomBitsBlocksClient)+256, testChainGen, nil, nil, db)
|
defer func() {
|
||||||
bc := pm.blockchain.(*core.BlockChain)
|
if tearDown != nil {
|
||||||
peer, _ := newTestPeer(t, "peer", 2, pm, true)
|
tearDown()
|
||||||
defer peer.close()
|
}
|
||||||
|
}()
|
||||||
// Wait a while for the bloombits indexer to process the new headers
|
bc := server.pm.blockchain.(*core.BlockChain)
|
||||||
time.Sleep(100 * time.Millisecond * time.Duration(params.BloomBitsBlocksClient/4096)) // Chain indexer throttling
|
|
||||||
time.Sleep(250 * time.Millisecond) // CI tester slack
|
|
||||||
|
|
||||||
// Request and verify each bit of the bloom bits proofs
|
// Request and verify each bit of the bloom bits proofs
|
||||||
for bit := 0; bit < 2048; bit++ {
|
for bit := 0; bit < 2048; bit++ {
|
||||||
// Assemble therequest and proofs for the bloombits
|
// Assemble the request and proofs for the bloombits
|
||||||
key := make([]byte, 10)
|
key := make([]byte, 10)
|
||||||
|
|
||||||
binary.BigEndian.PutUint16(key[:2], uint16(bit))
|
binary.BigEndian.PutUint16(key[:2], uint16(bit))
|
||||||
binary.BigEndian.PutUint64(key[2:], params.BloomBitsBlocksClient)
|
binary.BigEndian.PutUint64(key[2:], config.BloomSize-1)
|
||||||
|
|
||||||
requests := []HelperTrieReq{{
|
requests := []HelperTrieReq{{
|
||||||
Type: htBloomBits,
|
Type: htBloomBits,
|
||||||
|
|
@ -474,14 +483,14 @@ func TestGetBloombitsProofs(t *testing.T) {
|
||||||
}}
|
}}
|
||||||
var proofs HelperTrieResps
|
var proofs HelperTrieResps
|
||||||
|
|
||||||
root := light.GetBloomTrieRoot(db, 0, bc.GetHeaderByNumber(params.BloomBitsBlocksClient-1).Hash())
|
root := light.GetBloomTrieRoot(server.db, 0, bc.GetHeaderByNumber(config.BloomSize-1).Hash())
|
||||||
trie, _ := trie.New(root, trie.NewDatabase(ethdb.NewTable(db, light.BloomTrieTablePrefix)))
|
trie, _ := trie.New(root, trie.NewDatabase(ethdb.NewTable(server.db, light.BloomTrieTablePrefix)))
|
||||||
trie.Prove(key, 0, &proofs.Proofs)
|
trie.Prove(key, 0, &proofs.Proofs)
|
||||||
|
|
||||||
// Send the proof request and verify the response
|
// Send the proof request and verify the response
|
||||||
cost := peer.GetRequestCost(GetHelperTrieProofsMsg, len(requests))
|
cost := server.tPeer.GetRequestCost(GetHelperTrieProofsMsg, len(requests))
|
||||||
sendRequest(peer.app, GetHelperTrieProofsMsg, 42, cost, requests)
|
sendRequest(server.tPeer.app, GetHelperTrieProofsMsg, 42, cost, requests)
|
||||||
if err := expectResponse(peer.app, HelperTrieProofsMsg, 42, testBufLimit, proofs); err != nil {
|
if err := expectResponse(server.tPeer.app, HelperTrieProofsMsg, 42, testBufLimit, proofs); err != nil {
|
||||||
t.Errorf("bit %d: proofs mismatch: %v", bit, err)
|
t.Errorf("bit %d: proofs mismatch: %v", bit, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||||
|
|
@ -123,6 +124,16 @@ func testChainGen(i int, block *core.BlockGen) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// testIndexers creates a set of indexers with specified params for testing purpose.
|
||||||
|
func testIndexers(db ethdb.Database, indexerConfig *light.IndexerConfig) (*core.ChainIndexer, *core.ChainIndexer, *core.ChainIndexer) {
|
||||||
|
chtIndexer := light.NewChtIndexer(db, indexerConfig.ChtSize, indexerConfig.ChtConfirm)
|
||||||
|
bloomIndexer := eth.NewBloomIndexer(db, indexerConfig.BloomSize, indexerConfig.BloomConfirm)
|
||||||
|
bloomTrieIndexer := light.NewBloomTrieIndexer(db, indexerConfig.BloomSize, indexerConfig.BloomConfirm,
|
||||||
|
indexerConfig.BloomTrieSize, indexerConfig.BloomTrieConfirm)
|
||||||
|
bloomIndexer.AddChildIndexer(bloomTrieIndexer)
|
||||||
|
return chtIndexer, bloomIndexer, bloomTrieIndexer
|
||||||
|
}
|
||||||
|
|
||||||
func testRCL() RequestCostList {
|
func testRCL() RequestCostList {
|
||||||
cl := make(RequestCostList, len(reqList))
|
cl := make(RequestCostList, len(reqList))
|
||||||
for i, code := range reqList {
|
for i, code := range reqList {
|
||||||
|
|
@ -134,9 +145,9 @@ func testRCL() RequestCostList {
|
||||||
}
|
}
|
||||||
|
|
||||||
// newTestProtocolManager creates a new protocol manager for testing purposes,
|
// newTestProtocolManager creates a new protocol manager for testing purposes,
|
||||||
// with the given number of blocks already known, and potential notification
|
// with the given number of blocks already known, potential notification
|
||||||
// channels for different events.
|
// channels for different events and relative chain indexers array.
|
||||||
func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *core.BlockGen), peers *peerSet, odr *LesOdr, db ethdb.Database) (*ProtocolManager, error) {
|
func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *core.BlockGen), odr *LesOdr, peers *peerSet, db ethdb.Database) (*ProtocolManager, error) {
|
||||||
var (
|
var (
|
||||||
evmux = new(event.TypeMux)
|
evmux = new(event.TypeMux)
|
||||||
engine = ethash.NewFaker()
|
engine = ethash.NewFaker()
|
||||||
|
|
@ -152,20 +163,9 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor
|
||||||
}
|
}
|
||||||
|
|
||||||
if lightSync {
|
if lightSync {
|
||||||
chain, _ = light.NewLightChain(odr, gspec.Config, light.DefaultClientIndexerConfig, engine)
|
chain, _ = light.NewLightChain(odr, gspec.Config, engine)
|
||||||
} else {
|
} else {
|
||||||
blockchain, _ := core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{})
|
blockchain, _ := core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{})
|
||||||
|
|
||||||
chtIndexer := light.NewChtIndexer(db, params.CHTFrequencyServer, params.HelperTrieProcessConfirmations)
|
|
||||||
chtIndexer.Start(blockchain)
|
|
||||||
|
|
||||||
bbtIndexer := light.NewBloomTrieIndexer(db, params.BloomBitsBlocks, params.BloomConfirms,
|
|
||||||
params.BloomTrieFrequency, params.HelperTrieProcessConfirmations)
|
|
||||||
|
|
||||||
bloomIndexer := eth.NewBloomIndexer(db, params.BloomBitsBlocks, params.BloomConfirms)
|
|
||||||
bloomIndexer.AddChildIndexer(bbtIndexer)
|
|
||||||
bloomIndexer.Start(blockchain)
|
|
||||||
|
|
||||||
gchain, _ := core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, blocks, generator)
|
gchain, _ := core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, blocks, generator)
|
||||||
if _, err := blockchain.InsertChain(gchain); err != nil {
|
if _, err := blockchain.InsertChain(gchain); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
@ -180,10 +180,10 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor
|
||||||
|
|
||||||
if lightSync {
|
if lightSync {
|
||||||
protocolVersions = ClientProtocolVersions
|
protocolVersions = ClientProtocolVersions
|
||||||
indexConfig = light.DefaultClientIndexerConfig
|
indexConfig = light.TestClientIndexerConfig
|
||||||
} else {
|
} else {
|
||||||
protocolVersions = ServerProtocolVersions
|
protocolVersions = ServerProtocolVersions
|
||||||
indexConfig = light.DefaultServerIndexerConfig
|
indexConfig = light.TestServerIndexerConfig
|
||||||
}
|
}
|
||||||
pm, err := NewProtocolManager(gspec.Config, indexConfig, lightSync, protocolVersions, NetworkId, evmux, engine, peers, chain, nil, db, odr, nil, nil, make(chan struct{}), new(sync.WaitGroup))
|
pm, err := NewProtocolManager(gspec.Config, indexConfig, lightSync, protocolVersions, NetworkId, evmux, engine, peers, chain, nil, db, odr, nil, nil, make(chan struct{}), new(sync.WaitGroup))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -206,11 +206,11 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor
|
||||||
}
|
}
|
||||||
|
|
||||||
// newTestProtocolManagerMust creates a new protocol manager for testing purposes,
|
// newTestProtocolManagerMust creates a new protocol manager for testing purposes,
|
||||||
// with the given number of blocks already known, and potential notification
|
// with the given number of blocks already known, potential notification
|
||||||
// channels for different events. In case of an error, the constructor force-
|
// channels for different events and relative chain indexers array. In case of an error, the constructor force-
|
||||||
// fails the test.
|
// fails the test.
|
||||||
func newTestProtocolManagerMust(t *testing.T, lightSync bool, blocks int, generator func(int, *core.BlockGen), peers *peerSet, odr *LesOdr, db ethdb.Database) *ProtocolManager {
|
func newTestProtocolManagerMust(t *testing.T, lightSync bool, blocks int, generator func(int, *core.BlockGen), odr *LesOdr, peers *peerSet, db ethdb.Database) *ProtocolManager {
|
||||||
pm, err := newTestProtocolManager(lightSync, blocks, generator, peers, odr, db)
|
pm, err := newTestProtocolManager(lightSync, blocks, generator, odr, peers, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create protocol manager: %v", err)
|
t.Fatalf("Failed to create protocol manager: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -333,3 +333,114 @@ func (p *testPeer) handshake(t *testing.T, td *big.Int, head common.Hash, headNu
|
||||||
func (p *testPeer) close() {
|
func (p *testPeer) close() {
|
||||||
p.app.Close()
|
p.app.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestEntity represents a network entity for testing with necessary auxiliary fields.
|
||||||
|
type TestEntity struct {
|
||||||
|
db ethdb.Database
|
||||||
|
rPeer *peer
|
||||||
|
tPeer *testPeer
|
||||||
|
peers *peerSet
|
||||||
|
pm *ProtocolManager
|
||||||
|
// Indexers
|
||||||
|
chtIndexer *core.ChainIndexer
|
||||||
|
bloomIndexer *core.ChainIndexer
|
||||||
|
bloomTrieIndexer *core.ChainIndexer
|
||||||
|
}
|
||||||
|
|
||||||
|
// newServerEnv creates a server testing environment with a connected test peer for testing purpose.
|
||||||
|
func newServerEnv(t *testing.T, blocks int, protocol int, processSections uint64) (*TestEntity, func()) {
|
||||||
|
db := ethdb.NewMemDatabase()
|
||||||
|
cIndexer, bIndexer, btIndexer := testIndexers(db, light.TestServerIndexerConfig)
|
||||||
|
|
||||||
|
pm := newTestProtocolManagerMust(t, false, blocks, testChainGen, nil, nil, db)
|
||||||
|
peer, _ := newTestPeer(t, "peer", protocol, pm, true)
|
||||||
|
|
||||||
|
cIndexer.Start(pm.blockchain.(*core.BlockChain))
|
||||||
|
bIndexer.Start(pm.blockchain.(*core.BlockChain))
|
||||||
|
|
||||||
|
// Wait until indexers generate enough index data.
|
||||||
|
if processSections > 0 {
|
||||||
|
for {
|
||||||
|
cs, _, _ := cIndexer.Sections()
|
||||||
|
bs, _, _ := bIndexer.Sections()
|
||||||
|
if cs >= processSections && bs >= processSections {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &TestEntity{
|
||||||
|
db: db,
|
||||||
|
tPeer: peer,
|
||||||
|
pm: pm,
|
||||||
|
chtIndexer: cIndexer,
|
||||||
|
bloomIndexer: bIndexer,
|
||||||
|
bloomTrieIndexer: btIndexer,
|
||||||
|
}, func() {
|
||||||
|
peer.close()
|
||||||
|
// Note bloom trie indexer will be closed by it parent recursively.
|
||||||
|
cIndexer.Close()
|
||||||
|
bIndexer.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// newClientServerEnv creates a client/server arch environment with a connected les server and light client pair
|
||||||
|
// for testing purpose.
|
||||||
|
func newClientServerEnv(t *testing.T, blocks int, protocol int) (*TestEntity, *TestEntity, func()) {
|
||||||
|
db, ldb := ethdb.NewMemDatabase(), ethdb.NewMemDatabase()
|
||||||
|
peers, lPeers := newPeerSet(), newPeerSet()
|
||||||
|
|
||||||
|
cIndexer, bIndexer, btIndexer := testIndexers(db, light.TestServerIndexerConfig)
|
||||||
|
lcIndexer, lbIndexer, lbtIndexer := testIndexers(ldb, light.TestClientIndexerConfig)
|
||||||
|
|
||||||
|
startIndexers := func(clientMode bool, pm *ProtocolManager) {
|
||||||
|
if clientMode {
|
||||||
|
lcIndexer.Start(pm.blockchain.(*light.LightChain))
|
||||||
|
lbIndexer.Start(pm.blockchain.(*light.LightChain))
|
||||||
|
} else {
|
||||||
|
cIndexer.Start(pm.blockchain.(*core.BlockChain))
|
||||||
|
bIndexer.Start(pm.blockchain.(*core.BlockChain))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pm := newTestProtocolManagerMust(t, false, blocks, testChainGen, nil, peers, db)
|
||||||
|
dist := newRequestDistributor(lPeers, make(chan struct{}))
|
||||||
|
rm := newRetrieveManager(lPeers, dist, nil)
|
||||||
|
lpm := newTestProtocolManagerMust(t, true, 0, nil, NewLesOdr(ldb, light.TestClientIndexerConfig, lcIndexer, lbtIndexer, lbIndexer, rm), lPeers, ldb)
|
||||||
|
|
||||||
|
startIndexers(false, pm)
|
||||||
|
startIndexers(true, lpm)
|
||||||
|
|
||||||
|
peer, err1, lPeer, err2 := newTestPeerPair("peer", protocol, pm, lpm)
|
||||||
|
select {
|
||||||
|
case <-time.After(time.Millisecond * 100):
|
||||||
|
case err := <-err1:
|
||||||
|
t.Fatalf("peer 1 handshake error: %v", err)
|
||||||
|
case err := <-err2:
|
||||||
|
t.Fatalf("peer 2 handshake error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &TestEntity{
|
||||||
|
db: db,
|
||||||
|
pm: pm,
|
||||||
|
rPeer: peer,
|
||||||
|
peers: peers,
|
||||||
|
chtIndexer: cIndexer,
|
||||||
|
bloomIndexer: bIndexer,
|
||||||
|
bloomTrieIndexer: btIndexer,
|
||||||
|
}, &TestEntity{
|
||||||
|
db: ldb,
|
||||||
|
pm: lpm,
|
||||||
|
rPeer: lPeer,
|
||||||
|
peers: lPeers,
|
||||||
|
chtIndexer: lcIndexer,
|
||||||
|
bloomIndexer: lbIndexer,
|
||||||
|
bloomTrieIndexer: lbtIndexer,
|
||||||
|
}, func() {
|
||||||
|
// Note bloom trie indexers will be closed by their parents recursively.
|
||||||
|
cIndexer.Close()
|
||||||
|
bIndexer.Close()
|
||||||
|
lcIndexer.Close()
|
||||||
|
lbIndexer.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/light"
|
"github.com/ethereum/go-ethereum/light"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
@ -160,37 +159,25 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// testOdr tests odr requests whose validation guaranteed by block headers.
|
||||||
func testOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
|
func testOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
|
||||||
// Assemble the test environment
|
// Assemble the test environment
|
||||||
peers := newPeerSet()
|
server, client, tearDown := newClientServerEnv(t, 4, protocol)
|
||||||
dist := newRequestDistributor(peers, make(chan struct{}))
|
defer func() {
|
||||||
rm := newRetrieveManager(peers, dist, nil)
|
if tearDown != nil {
|
||||||
db := ethdb.NewMemDatabase()
|
tearDown()
|
||||||
ldb := ethdb.NewMemDatabase()
|
|
||||||
odr := NewLesOdr(ldb, light.DefaultClientIndexerConfig, light.NewChtIndexer(db, params.CHTFrequencyClient, params.HelperTrieConfirmations),
|
|
||||||
light.NewBloomTrieIndexer(db, params.BloomBitsBlocksClient, params.HelperTrieConfirmations, params.BloomTrieFrequency, params.HelperTrieConfirmations),
|
|
||||||
eth.NewBloomIndexer(db, params.BloomBitsBlocksClient, params.HelperTrieConfirmations), 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)
|
|
||||||
select {
|
|
||||||
case <-time.After(time.Millisecond * 100):
|
|
||||||
case err := <-err1:
|
|
||||||
t.Fatalf("peer 1 handshake error: %v", err)
|
|
||||||
case err := <-err2:
|
|
||||||
t.Fatalf("peer 1 handshake error: %v", err)
|
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
lpm.synchronise(lpeer)
|
client.pm.synchronise(client.rPeer)
|
||||||
|
|
||||||
test := func(expFail uint64) {
|
test := func(expFail uint64) {
|
||||||
for i := uint64(0); i <= pm.blockchain.CurrentHeader().Number.Uint64(); i++ {
|
for i := uint64(0); i <= server.pm.blockchain.CurrentHeader().Number.Uint64(); i++ {
|
||||||
bhash := rawdb.ReadCanonicalHash(db, i)
|
bhash := rawdb.ReadCanonicalHash(server.db, i)
|
||||||
b1 := fn(light.NoOdr, db, pm.chainConfig, pm.blockchain.(*core.BlockChain), nil, bhash)
|
b1 := fn(light.NoOdr, server.db, server.pm.chainConfig, server.pm.blockchain.(*core.BlockChain), nil, bhash)
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
|
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
b2 := fn(ctx, ldb, lpm.chainConfig, nil, lpm.blockchain.(*light.LightChain), bhash)
|
b2 := fn(ctx, client.db, client.pm.chainConfig, nil, client.pm.blockchain.(*light.LightChain), bhash)
|
||||||
|
|
||||||
eq := bytes.Equal(b1, b2)
|
eq := bytes.Equal(b1, b2)
|
||||||
exp := i < expFail
|
exp := i < expFail
|
||||||
|
|
@ -202,21 +189,20 @@ func testOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// temporarily remove peer to test odr fails
|
// temporarily remove peer to test odr fails
|
||||||
// expect retrievals to fail (except genesis block) without a les peer
|
// expect retrievals to fail (except genesis block) without a les peer
|
||||||
peers.Unregister(lpeer.id)
|
client.peers.Unregister(client.rPeer.id)
|
||||||
time.Sleep(time.Millisecond * 10) // ensure that all peerSetNotify callbacks are executed
|
time.Sleep(time.Millisecond * 10) // ensure that all peerSetNotify callbacks are executed
|
||||||
test(expFail)
|
test(expFail)
|
||||||
// expect all retrievals to pass
|
// expect all retrievals to pass
|
||||||
peers.Register(lpeer)
|
client.peers.Register(client.rPeer)
|
||||||
time.Sleep(time.Millisecond * 10) // ensure that all peerSetNotify callbacks are executed
|
time.Sleep(time.Millisecond * 10) // ensure that all peerSetNotify callbacks are executed
|
||||||
lpeer.lock.Lock()
|
client.peers.lock.Lock()
|
||||||
lpeer.hasBlock = func(common.Hash, uint64) bool { return true }
|
client.rPeer.hasBlock = func(common.Hash, uint64) bool { return true }
|
||||||
lpeer.lock.Unlock()
|
client.peers.lock.Unlock()
|
||||||
test(5)
|
test(5)
|
||||||
// still expect all retrievals to pass, now data should be cached locally
|
// still expect all retrievals to pass, now data should be cached locally
|
||||||
peers.Unregister(lpeer.id)
|
client.peers.Unregister(client.rPeer.id)
|
||||||
time.Sleep(time.Millisecond * 10) // ensure that all peerSetNotify callbacks are executed
|
time.Sleep(time.Millisecond * 10) // ensure that all peerSetNotify callbacks are executed
|
||||||
test(5)
|
test(5)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,8 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/light"
|
"github.com/ethereum/go-ethereum/light"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var testBankSecureTrieKey = secAddr(testBankAddress)
|
var testBankSecureTrieKey = secAddr(testBankAddress)
|
||||||
|
|
@ -85,36 +83,21 @@ func tfCodeAccess(db ethdb.Database, bhash common.Hash, num uint64) light.OdrReq
|
||||||
|
|
||||||
func testAccess(t *testing.T, protocol int, fn accessTestFn) {
|
func testAccess(t *testing.T, protocol int, fn accessTestFn) {
|
||||||
// Assemble the test environment
|
// Assemble the test environment
|
||||||
peers := newPeerSet()
|
server, client, tearDown := newClientServerEnv(t, 4, protocol)
|
||||||
dist := newRequestDistributor(peers, make(chan struct{}))
|
defer func() {
|
||||||
rm := newRetrieveManager(peers, dist, nil)
|
if tearDown != nil {
|
||||||
db := ethdb.NewMemDatabase()
|
tearDown()
|
||||||
ldb := ethdb.NewMemDatabase()
|
|
||||||
odr := NewLesOdr(ldb, light.DefaultClientIndexerConfig, light.NewChtIndexer(db, params.CHTFrequencyClient, params.HelperTrieConfirmations),
|
|
||||||
light.NewBloomTrieIndexer(db, params.BloomBitsBlocksClient, params.HelperTrieConfirmations, params.BloomTrieFrequency, params.HelperTrieConfirmations),
|
|
||||||
eth.NewBloomIndexer(db, params.BloomBitsBlocksClient, params.HelperTrieConfirmations), 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)
|
|
||||||
select {
|
|
||||||
case <-time.After(time.Millisecond * 100):
|
|
||||||
case err := <-err1:
|
|
||||||
t.Fatalf("peer 1 handshake error: %v", err)
|
|
||||||
case err := <-err2:
|
|
||||||
t.Fatalf("peer 1 handshake error: %v", err)
|
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
lpm.synchronise(lpeer)
|
client.pm.synchronise(client.rPeer)
|
||||||
|
|
||||||
test := func(expFail uint64) {
|
test := func(expFail uint64) {
|
||||||
for i := uint64(0); i <= pm.blockchain.CurrentHeader().Number.Uint64(); i++ {
|
for i := uint64(0); i <= server.pm.blockchain.CurrentHeader().Number.Uint64(); i++ {
|
||||||
bhash := rawdb.ReadCanonicalHash(db, i)
|
bhash := rawdb.ReadCanonicalHash(server.db, i)
|
||||||
if req := fn(ldb, bhash, i); req != nil {
|
if req := fn(client.db, bhash, i); req != nil {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
|
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
err := client.pm.odr.Retrieve(ctx, req)
|
||||||
err := odr.Retrieve(ctx, req)
|
|
||||||
got := err == nil
|
got := err == nil
|
||||||
exp := i < expFail
|
exp := i < expFail
|
||||||
if exp && !got {
|
if exp && !got {
|
||||||
|
|
@ -128,16 +111,16 @@ func testAccess(t *testing.T, protocol int, fn accessTestFn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// temporarily remove peer to test odr fails
|
// temporarily remove peer to test odr fails
|
||||||
peers.Unregister(lpeer.id)
|
client.peers.Unregister(client.rPeer.id)
|
||||||
time.Sleep(time.Millisecond * 10) // ensure that all peerSetNotify callbacks are executed
|
time.Sleep(time.Millisecond * 10) // ensure that all peerSetNotify callbacks are executed
|
||||||
// expect retrievals to fail (except genesis block) without a les peer
|
// expect retrievals to fail (except genesis block) without a les peer
|
||||||
test(0)
|
test(0)
|
||||||
|
|
||||||
peers.Register(lpeer)
|
client.peers.Register(client.rPeer)
|
||||||
time.Sleep(time.Millisecond * 10) // ensure that all peerSetNotify callbacks are executed
|
time.Sleep(time.Millisecond * 10) // ensure that all peerSetNotify callbacks are executed
|
||||||
lpeer.lock.Lock()
|
client.rPeer.lock.Lock()
|
||||||
lpeer.hasBlock = func(common.Hash, uint64) bool { return true }
|
client.rPeer.hasBlock = func(common.Hash, uint64) bool { return true }
|
||||||
lpeer.lock.Unlock()
|
client.rPeer.lock.Unlock()
|
||||||
// expect all retrievals to pass
|
// expect all retrievals to pass
|
||||||
test(5)
|
test(5)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,14 +76,14 @@ type LightChain struct {
|
||||||
// NewLightChain returns a fully initialised light chain using information
|
// NewLightChain returns a fully initialised light chain using information
|
||||||
// available in the database. It initialises the default Ethereum header
|
// available in the database. It initialises the default Ethereum header
|
||||||
// validator.
|
// validator.
|
||||||
func NewLightChain(odr OdrBackend, config *params.ChainConfig, indexerConfig *IndexerConfig, engine consensus.Engine) (*LightChain, error) {
|
func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.Engine) (*LightChain, error) {
|
||||||
bodyCache, _ := lru.New(bodyCacheLimit)
|
bodyCache, _ := lru.New(bodyCacheLimit)
|
||||||
bodyRLPCache, _ := lru.New(bodyCacheLimit)
|
bodyRLPCache, _ := lru.New(bodyCacheLimit)
|
||||||
blockCache, _ := lru.New(blockCacheLimit)
|
blockCache, _ := lru.New(blockCacheLimit)
|
||||||
|
|
||||||
bc := &LightChain{
|
bc := &LightChain{
|
||||||
chainDb: odr.Database(),
|
chainDb: odr.Database(),
|
||||||
indexerConfig: indexerConfig,
|
indexerConfig: odr.IndexerConfig(),
|
||||||
odr: odr,
|
odr: odr,
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
bodyCache: bodyCache,
|
bodyCache: bodyCache,
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ func newCanonical(n int) (ethdb.Database, *LightChain, error) {
|
||||||
db := ethdb.NewMemDatabase()
|
db := ethdb.NewMemDatabase()
|
||||||
gspec := core.Genesis{Config: params.TestChainConfig}
|
gspec := core.Genesis{Config: params.TestChainConfig}
|
||||||
genesis := gspec.MustCommit(db)
|
genesis := gspec.MustCommit(db)
|
||||||
blockchain, _ := NewLightChain(&dummyOdr{db: db}, gspec.Config, DefaultClientIndexerConfig, ethash.NewFaker())
|
blockchain, _ := NewLightChain(&dummyOdr{db: db, indexerConfig: TestClientIndexerConfig}, gspec.Config, ethash.NewFaker())
|
||||||
|
|
||||||
// Create and inject the requested chain
|
// Create and inject the requested chain
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
|
|
@ -75,7 +75,7 @@ func newTestLightChain() *LightChain {
|
||||||
Config: params.TestChainConfig,
|
Config: params.TestChainConfig,
|
||||||
}
|
}
|
||||||
gspec.MustCommit(db)
|
gspec.MustCommit(db)
|
||||||
lc, err := NewLightChain(&dummyOdr{db: db}, gspec.Config, DefaultClientIndexerConfig, ethash.NewFullFaker())
|
lc, err := NewLightChain(&dummyOdr{db: db}, gspec.Config, ethash.NewFullFaker())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
@ -266,6 +266,7 @@ func makeHeaderChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.
|
||||||
type dummyOdr struct {
|
type dummyOdr struct {
|
||||||
OdrBackend
|
OdrBackend
|
||||||
db ethdb.Database
|
db ethdb.Database
|
||||||
|
indexerConfig *IndexerConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (odr *dummyOdr) Database() ethdb.Database {
|
func (odr *dummyOdr) Database() ethdb.Database {
|
||||||
|
|
@ -276,6 +277,10 @@ func (odr *dummyOdr) Retrieve(ctx context.Context, req OdrRequest) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (odr *dummyOdr) IndexerConfig() *IndexerConfig {
|
||||||
|
return odr.indexerConfig
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that reorganizing a long difficult chain after a short easy one
|
// Tests that reorganizing a long difficult chain after a short easy one
|
||||||
// overwrites the canonical numbers and links in the database.
|
// overwrites the canonical numbers and links in the database.
|
||||||
func TestReorgLongHeaders(t *testing.T) {
|
func TestReorgLongHeaders(t *testing.T) {
|
||||||
|
|
@ -339,7 +344,7 @@ func TestReorgBadHeaderHashes(t *testing.T) {
|
||||||
defer func() { delete(core.BadHashes, headers[3].Hash()) }()
|
defer func() { delete(core.BadHashes, headers[3].Hash()) }()
|
||||||
|
|
||||||
// Create a new LightChain and check that it rolled back the state.
|
// Create a new LightChain and check that it rolled back the state.
|
||||||
ncm, err := NewLightChain(&dummyOdr{db: bc.chainDb}, params.TestChainConfig, DefaultClientIndexerConfig, ethash.NewFaker())
|
ncm, err := NewLightChain(&dummyOdr{db: bc.chainDb}, params.TestChainConfig, ethash.NewFaker())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create new chain manager: %v", err)
|
t.Fatalf("failed to create new chain manager: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,10 @@ func (odr *testOdr) Retrieve(ctx context.Context, req OdrRequest) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (odr *testOdr) IndexerConfig() *IndexerConfig {
|
||||||
|
return odr.indexerConfig
|
||||||
|
}
|
||||||
|
|
||||||
type odrTestFn func(ctx context.Context, db ethdb.Database, bc *core.BlockChain, lc *LightChain, bhash common.Hash) ([]byte, error)
|
type odrTestFn func(ctx context.Context, db ethdb.Database, bc *core.BlockChain, lc *LightChain, bhash common.Hash) ([]byte, error)
|
||||||
|
|
||||||
func TestOdrGetBlockLes1(t *testing.T) { testChainOdr(t, 1, odrGetBlock) }
|
func TestOdrGetBlockLes1(t *testing.T) { testChainOdr(t, 1, odrGetBlock) }
|
||||||
|
|
@ -259,8 +263,8 @@ func testChainOdr(t *testing.T, protocol int, fn odrTestFn) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
odr := &testOdr{sdb: sdb, ldb: ldb, indexerConfig: DefaultClientIndexerConfig}
|
odr := &testOdr{sdb: sdb, ldb: ldb, indexerConfig: TestClientIndexerConfig}
|
||||||
lightchain, err := NewLightChain(odr, params.TestChainConfig, DefaultClientIndexerConfig, ethash.NewFullFaker())
|
lightchain, err := NewLightChain(odr, params.TestChainConfig, ethash.NewFullFaker())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,9 @@ type IndexerConfig struct {
|
||||||
BloomTrieConfirm uint64
|
BloomTrieConfirm uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultServerIndexerConfig wraps a set of configs as a default indexer config for server side.
|
var (
|
||||||
var DefaultServerIndexerConfig = &IndexerConfig{
|
// DefaultServerIndexerConfig wraps a set of configs as a default indexer config for server side.
|
||||||
|
DefaultServerIndexerConfig = &IndexerConfig{
|
||||||
ChtSize: params.CHTFrequencyServer,
|
ChtSize: params.CHTFrequencyServer,
|
||||||
PairChtSize: params.CHTFrequencyClient,
|
PairChtSize: params.CHTFrequencyClient,
|
||||||
ChtConfirm: params.HelperTrieProcessConfirmations,
|
ChtConfirm: params.HelperTrieProcessConfirmations,
|
||||||
|
|
@ -68,10 +69,9 @@ var DefaultServerIndexerConfig = &IndexerConfig{
|
||||||
BloomConfirm: params.BloomConfirms,
|
BloomConfirm: params.BloomConfirms,
|
||||||
BloomTrieSize: params.BloomTrieFrequency,
|
BloomTrieSize: params.BloomTrieFrequency,
|
||||||
BloomTrieConfirm: params.HelperTrieProcessConfirmations,
|
BloomTrieConfirm: params.HelperTrieProcessConfirmations,
|
||||||
}
|
}
|
||||||
|
// DefaultClientIndexerConfig wraps a set of configs as a default indexer config for client side.
|
||||||
// DefaultClientIndexerConfig wraps a set of configs as a default indexer config for client side.
|
DefaultClientIndexerConfig = &IndexerConfig{
|
||||||
var DefaultClientIndexerConfig = &IndexerConfig{
|
|
||||||
ChtSize: params.CHTFrequencyClient,
|
ChtSize: params.CHTFrequencyClient,
|
||||||
PairChtSize: params.CHTFrequencyServer,
|
PairChtSize: params.CHTFrequencyServer,
|
||||||
ChtConfirm: params.HelperTrieConfirmations,
|
ChtConfirm: params.HelperTrieConfirmations,
|
||||||
|
|
@ -79,7 +79,28 @@ var DefaultClientIndexerConfig = &IndexerConfig{
|
||||||
BloomConfirm: params.HelperTrieConfirmations,
|
BloomConfirm: params.HelperTrieConfirmations,
|
||||||
BloomTrieSize: params.BloomTrieFrequency,
|
BloomTrieSize: params.BloomTrieFrequency,
|
||||||
BloomTrieConfirm: params.HelperTrieConfirmations,
|
BloomTrieConfirm: params.HelperTrieConfirmations,
|
||||||
}
|
}
|
||||||
|
// TestServerIndexerConfig wraps a set of configs as a test indexer config for server side.
|
||||||
|
TestServerIndexerConfig = &IndexerConfig{
|
||||||
|
ChtSize: 256,
|
||||||
|
PairChtSize: 2048,
|
||||||
|
ChtConfirm: 16,
|
||||||
|
BloomSize: 256,
|
||||||
|
BloomConfirm: 16,
|
||||||
|
BloomTrieSize: 2048,
|
||||||
|
BloomTrieConfirm: 16,
|
||||||
|
}
|
||||||
|
// TestClientIndexerConfig wraps a set of configs as a test indexer config for client side.
|
||||||
|
TestClientIndexerConfig = &IndexerConfig{
|
||||||
|
ChtSize: 2048,
|
||||||
|
PairChtSize: 256,
|
||||||
|
ChtConfirm: 128,
|
||||||
|
BloomSize: 2048,
|
||||||
|
BloomConfirm: 128,
|
||||||
|
BloomTrieSize: 2048,
|
||||||
|
BloomTrieConfirm: 128,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// trustedCheckpoint represents a set of post-processed trie roots (CHT and BloomTrie) associated with
|
// trustedCheckpoint represents a set of post-processed trie roots (CHT and BloomTrie) associated with
|
||||||
// the appropriate section index and head hash. It is used to start light syncing from this checkpoint
|
// the appropriate section index and head hash. It is used to start light syncing from this checkpoint
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ func TestNodeIterator(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
odr := &testOdr{sdb: fulldb, ldb: lightdb, indexerConfig: DefaultClientIndexerConfig}
|
odr := &testOdr{sdb: fulldb, ldb: lightdb, indexerConfig: TestClientIndexerConfig}
|
||||||
head := blockchain.CurrentHeader()
|
head := blockchain.CurrentHeader()
|
||||||
lightTrie, _ := NewStateDatabase(ctx, head, odr).OpenTrie(head.Root)
|
lightTrie, _ := NewStateDatabase(ctx, head, odr).OpenTrie(head.Root)
|
||||||
fullTrie, _ := state.NewDatabase(fulldb).OpenTrie(head.Root)
|
fullTrie, _ := state.NewDatabase(fulldb).OpenTrie(head.Root)
|
||||||
|
|
|
||||||
|
|
@ -94,13 +94,13 @@ func TestTxPool(t *testing.T) {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
odr := &testOdr{sdb: sdb, ldb: ldb, indexerConfig: DefaultClientIndexerConfig}
|
odr := &testOdr{sdb: sdb, ldb: ldb, indexerConfig: TestClientIndexerConfig}
|
||||||
relay := &testTxRelay{
|
relay := &testTxRelay{
|
||||||
send: make(chan int, 1),
|
send: make(chan int, 1),
|
||||||
discard: make(chan int, 1),
|
discard: make(chan int, 1),
|
||||||
mined: make(chan int, 1),
|
mined: make(chan int, 1),
|
||||||
}
|
}
|
||||||
lightchain, _ := NewLightChain(odr, params.TestChainConfig, DefaultClientIndexerConfig, ethash.NewFullFaker())
|
lightchain, _ := NewLightChain(odr, params.TestChainConfig, ethash.NewFullFaker())
|
||||||
txPermanent = 50
|
txPermanent = 50
|
||||||
pool := NewTxPool(params.TestChainConfig, lightchain, relay)
|
pool := NewTxPool(params.TestChainConfig, lightchain, relay)
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue