les: fix a bit

This commit is contained in:
rjl493456442 2018-07-24 15:34:12 +08:00
parent 14e65b5d0e
commit 8ec6efcb88
3 changed files with 78 additions and 4 deletions

View file

@ -365,7 +365,6 @@ func (r *ChtRequest) GetCost(peer *peer) uint64 {
func (r *ChtRequest) CanSend(peer *peer, config *light.IndexerConfig) bool { func (r *ChtRequest) CanSend(peer *peer, config *light.IndexerConfig) bool {
peer.lock.RLock() peer.lock.RLock()
defer peer.lock.RUnlock() defer peer.lock.RUnlock()
return peer.headInfo.Number >= config.ChtConfirm && r.ChtNum <= (peer.headInfo.Number-config.ChtConfirm)/config.ChtSize return peer.headInfo.Number >= config.ChtConfirm && r.ChtNum <= (peer.headInfo.Number-config.ChtConfirm)/config.ChtSize
} }
@ -409,7 +408,6 @@ func (r *ChtRequest) Request(reqID uint64, peer *peer, config *light.IndexerConf
// to the request (implementation of LesOdrRequest) // to the request (implementation of LesOdrRequest)
func (r *ChtRequest) Validate(db ethdb.Database, msg *Msg) error { func (r *ChtRequest) Validate(db ethdb.Database, msg *Msg) error {
log.Debug("Validating CHT", "cht", r.ChtNum, "block", r.Numbers) log.Debug("Validating CHT", "cht", r.ChtNum, "block", r.Numbers)
switch msg.MsgType { switch msg.MsgType {
case MsgHeaderProofs: // LES/1 backwards compatibility case MsgHeaderProofs: // LES/1 backwards compatibility
resps := msg.Obj.([]ChtResp) resps := msg.Obj.([]ChtResp)
@ -428,6 +426,7 @@ func (r *ChtRequest) Validate(db ethdb.Database, msg *Msg) error {
binary.BigEndian.PutUint64(encNumber[:], num) binary.BigEndian.PutUint64(encNumber[:], num)
value, _, err := trie.VerifyProof(r.ChtRoot, encNumber[:], light.NodeList(resp.Proof).NodeSet()) value, _, err := trie.VerifyProof(r.ChtRoot, encNumber[:], light.NodeList(resp.Proof).NodeSet())
if err != nil { if err != nil {
fmt.Println(err)
return err return err
} }
var node light.ChtNode var node light.ChtNode

View file

@ -36,6 +36,26 @@ import (
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
) )
type chtTestFn func(ctx context.Context, bc *core.BlockChain, lc *light.LightChain, number uint64) []byte
func TestChtGetHeadersLes1(t *testing.T) { testCht(t, 1, chtGetHeader) }
func TestChtGetHeadersLes2(t *testing.T) { testCht(t, 2, chtGetHeader) }
func chtGetHeader(ctx context.Context, bc *core.BlockChain, lc *light.LightChain, number uint64) []byte {
var header *types.Header
if bc != nil {
header = bc.GetHeaderByNumber(number)
} else {
header, _ = lc.GetHeaderByNumberOdr(ctx, number)
}
if header == nil {
return nil
}
rlp, _ := rlp.EncodeToBytes(header)
return rlp
}
type odrTestFn func(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte type odrTestFn func(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte
func TestOdrGetBlockLes1(t *testing.T) { testOdr(t, 1, 1, odrGetBlock) } func TestOdrGetBlockLes1(t *testing.T) { testOdr(t, 1, 1, odrGetBlock) }
@ -159,6 +179,61 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
return res return res
} }
// testCht tests cht requests whose validation guaranteed by calculated cht root.
func testCht(t *testing.T, protocol int, fn chtTestFn) {
// Assemble the test environment
config := light.TestServerIndexerConfig
waitIndexers := func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) {
for {
cs, _, _ := cIndexer.Sections()
bs, _, _ := bIndexer.Sections()
bts, _, _ := btIndexer.Sections()
if cs >= 8 && bs >= 8 && bts >= 1 {
break
}
time.Sleep(10 * time.Millisecond)
}
}
server, client, tearDown := newClientServerEnv(t, int(config.ChtSize*8+config.ChtConfirm), protocol, waitIndexers, false)
defer func() {
if tearDown != nil {
tearDown()
}
}()
// Add trusted checkpoint for client side indexers.
cs, _, head := server.chtIndexer.Sections()
light.StoreChtRoot(client.db, cs/8-1, head, light.GetChtRoot(server.db, cs-1, head))
client.chtIndexer.AddKnownSectionHead(cs/8-1, head)
bts, _, head := server.bloomTrieIndexer.Sections()
light.StoreBloomTrieRoot(client.db, bts-1, head, light.GetBloomTrieRoot(server.db, bts-1, head))
client.bloomTrieIndexer.AddKnownSectionHead(bts-1, head)
// Create connected peer pair.
peer, err1, lPeer, err2 := newTestPeerPair("peer", protocol, server.pm, client.pm)
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)
}
server.rPeer, client.rPeer = peer, lPeer
test := func() {
for i := uint64(0); i <= config.ChtSize*8-1; i++ {
h1 := fn(light.NoOdr, server.pm.blockchain.(*core.BlockChain), nil, i)
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
h2 := fn(ctx, nil, client.pm.blockchain.(*light.LightChain), i)
if !bytes.Equal(h1, h2) {
t.Error("cht mismatch")
}
cancel()
}
}
test()
}
// testOdr tests odr requests whose validation guaranteed by block headers. // 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

View file

@ -298,6 +298,7 @@ func (p *peer) RequestHelperTrieProofs(reqID, cost uint64, data interface{}) err
if !ok { if !ok {
return errInvalidHelpTrieReq return errInvalidHelpTrieReq
} }
p.Log().Debug("Fetching batch of HelperTrie proofs", "count", len(reqs))
return sendRequest(p.rw, GetHelperTrieProofsMsg, reqID, cost, reqs) return sendRequest(p.rw, GetHelperTrieProofsMsg, reqID, cost, reqs)
default: default:
panic(nil) panic(nil)
@ -489,7 +490,6 @@ func (p *peer) Handshake(td *big.Int, head common.Hash, headNum uint64, genesis
p.fcServer = flowcontrol.NewServerNode(params) p.fcServer = flowcontrol.NewServerNode(params)
p.fcCosts = MRC.decode() p.fcCosts = MRC.decode()
} }
p.headInfo = &announceData{Td: rTd, Hash: rHash, Number: rNum} p.headInfo = &announceData{Td: rTd, Hash: rHash, Number: rNum}
return nil return nil
} }