les, light: deterministic nodeset rlp, bloombits test skeleton

This commit is contained in:
Péter Szilágyi 2018-02-10 03:38:42 +02:00
parent ef58aaf253
commit 390d54c3e0
No known key found for this signature in database
GPG key ID: E9AE538CEDF8293D
5 changed files with 65 additions and 38 deletions

View file

@ -790,10 +790,9 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
break
}
}
proofs := nodes.NodeList()
bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
return p.SendProofsV2(req.ReqID, bv, proofs)
return p.SendProofsV2(req.ReqID, bv, nodes.NodeList())
case ProofsV1Msg:
if pm.odr == nil {

View file

@ -385,31 +385,13 @@ func testGetProofs(t *testing.T, protocol int) {
case 2:
cost := peer.GetRequestCost(GetProofsV2Msg, len(proofreqs))
sendRequest(peer.app, GetProofsV2Msg, 42, cost, proofreqs)
msg, err := peer.app.ReadMsg()
if err != nil {
t.Errorf("Message read error: %v", err)
if err := expectResponse(peer.app, ProofsV2Msg, 42, testBufLimit, proofsV2.NodeList()); err != nil {
t.Errorf("proofs mismatch: %v", err)
}
var resp struct {
ReqID, BV uint64
Data light.NodeList
}
if err := msg.Decode(&resp); err != nil {
t.Errorf("reply decode error: %v", err)
}
if msg.Code != ProofsV2Msg {
t.Errorf("Message code mismatch")
}
if resp.ReqID != 42 {
t.Errorf("ReqID mismatch")
}
if resp.BV != testBufLimit {
t.Errorf("BV mismatch")
}
testCheckProof(t, proofsV2, resp.Data)
}
}
// Tests that helper trie proofs can be correctly retrieved.
// Tests that CHT proofs can be correctly retrieved.
func TestGetCHTProofsLes1(t *testing.T) { testGetCHTProofs(t, 1) }
func TestGetCHTProofsLes2(t *testing.T) { testGetCHTProofs(t, 2) }
@ -485,6 +467,41 @@ func testGetCHTProofs(t *testing.T, protocol int) {
}
}
// Tests that bloombits proofs can be correctly retrieved.
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)
peer, _ := newTestPeer(t, "peer", 2, pm, true)
defer peer.close()
// Wait a while for the bloombits indexer to process the new headers
time.Sleep(100 * time.Millisecond * time.Duration(light.BloomTrieFrequency/4096)) // Chain indexer throttling
time.Sleep(250 * time.Millisecond) // CI tester slack
// Assemble therequest and proofs for the bloombits
bit := rand.Intn(2048)
key := make([]byte, 10)
binary.BigEndian.PutUint16(key[:2], uint16(bit))
binary.BigEndian.PutUint64(key[2:], 0)
requests := []HelperTrieReq{{
Type: htBloomBits,
TrieIdx: 0,
Key: key,
}}
var proofs HelperTrieResps
// Send the proof request and verify the response
cost := peer.GetRequestCost(GetHelperTrieProofsMsg, len(requests))
sendRequest(peer.app, GetHelperTrieProofsMsg, 42, cost, requests)
if err := expectResponse(peer.app, HelperTrieProofsMsg, 42, testBufLimit, proofs); err != nil {
t.Errorf("proofs mismatch: %v", err)
}
}
func TestTransactionStatusLes2(t *testing.T) {
db, _ := ethdb.NewMemDatabase()
pm := newTestProtocolManagerMust(t, false, 0, nil, nil, nil, db)

View file

@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/les/flowcontrol"
@ -151,7 +152,10 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor
chtIndexer := light.NewChtIndexer(db, false)
chtIndexer.Start(blockchain)
bloomIndexer := light.NewBloomTrieIndexer(db, false)
bbtIndexer := light.NewBloomTrieIndexer(db, false)
bloomIndexer := eth.NewBloomIndexer(db, params.BloomBitsBlocks)
bloomIndexer.AddChildIndexer(bbtIndexer)
bloomIndexer.Start(blockchain)
gchain, _ := core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, blocks, generator)

View file

@ -493,10 +493,10 @@ func (r *BloomRequest) Request(reqID uint64, peer *peer) error {
reqs := make([]HelperTrieReq, len(r.SectionIdxList))
var encNumber [10]byte
binary.BigEndian.PutUint16(encNumber[0:2], uint16(r.BitIdx))
binary.BigEndian.PutUint16(encNumber[:2], uint16(r.BitIdx))
for i, sectionIdx := range r.SectionIdxList {
binary.BigEndian.PutUint64(encNumber[2:10], sectionIdx)
binary.BigEndian.PutUint64(encNumber[2:], sectionIdx)
reqs[i] = HelperTrieReq{
Type: htBloomBits,
TrieIdx: r.BloomTrieNum,
@ -525,10 +525,10 @@ func (r *BloomRequest) Validate(db ethdb.Database, msg *Msg) error {
// Verify the proofs
var encNumber [10]byte
binary.BigEndian.PutUint16(encNumber[0:2], uint16(r.BitIdx))
binary.BigEndian.PutUint16(encNumber[:2], uint16(r.BitIdx))
for i, idx := range r.SectionIdxList {
binary.BigEndian.PutUint64(encNumber[2:10], idx)
binary.BigEndian.PutUint64(encNumber[2:], idx)
value, err, _ := trie.VerifyProof(r.BloomTrieRoot, encNumber[:], reads)
if err != nil {
return err

View file

@ -29,7 +29,9 @@ import (
// NodeSet stores a set of trie nodes. It implements trie.Database and can also
// act as a cache for another trie.Database.
type NodeSet struct {
db map[string][]byte
nodes map[string][]byte
order []string
dataSize int
lock sync.RWMutex
}
@ -37,7 +39,7 @@ type NodeSet struct {
// NewNodeSet creates an empty node set
func NewNodeSet() *NodeSet {
return &NodeSet{
db: make(map[string][]byte),
nodes: make(map[string][]byte),
}
}
@ -46,10 +48,15 @@ func (db *NodeSet) Put(key []byte, value []byte) error {
db.lock.Lock()
defer db.lock.Unlock()
if _, ok := db.db[string(key)]; !ok {
db.db[string(key)] = common.CopyBytes(value)
db.dataSize += len(value)
if _, ok := db.nodes[string(key)]; ok {
return nil
}
keystr := string(key)
db.nodes[keystr] = common.CopyBytes(value)
db.order = append(db.order, keystr)
db.dataSize += len(value)
return nil
}
@ -58,7 +65,7 @@ func (db *NodeSet) Get(key []byte) ([]byte, error) {
db.lock.RLock()
defer db.lock.RUnlock()
if entry, ok := db.db[string(key)]; ok {
if entry, ok := db.nodes[string(key)]; ok {
return entry, nil
}
return nil, errors.New("not found")
@ -75,7 +82,7 @@ func (db *NodeSet) KeyCount() int {
db.lock.RLock()
defer db.lock.RUnlock()
return len(db.db)
return len(db.nodes)
}
// DataSize returns the aggregated data size of nodes in the set
@ -92,8 +99,8 @@ func (db *NodeSet) NodeList() NodeList {
defer db.lock.RUnlock()
var values NodeList
for _, value := range db.db {
values = append(values, value)
for _, key := range db.order {
values = append(values, db.nodes[key])
}
return values
}
@ -103,7 +110,7 @@ func (db *NodeSet) Store(target ethdb.Putter) {
db.lock.RLock()
defer db.lock.RUnlock()
for key, value := range db.db {
for key, value := range db.nodes {
target.Put([]byte(key), value)
}
}