mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 17:33:47 +00:00
les, light: deterministic nodeset rlp, bloombits test skeleton
This commit is contained in:
parent
ef58aaf253
commit
390d54c3e0
5 changed files with 65 additions and 38 deletions
|
|
@ -790,10 +790,9 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
proofs := nodes.NodeList()
|
|
||||||
bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
|
bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
|
||||||
pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
|
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:
|
case ProofsV1Msg:
|
||||||
if pm.odr == nil {
|
if pm.odr == nil {
|
||||||
|
|
|
||||||
|
|
@ -385,31 +385,13 @@ func testGetProofs(t *testing.T, protocol int) {
|
||||||
case 2:
|
case 2:
|
||||||
cost := peer.GetRequestCost(GetProofsV2Msg, len(proofreqs))
|
cost := peer.GetRequestCost(GetProofsV2Msg, len(proofreqs))
|
||||||
sendRequest(peer.app, GetProofsV2Msg, 42, cost, proofreqs)
|
sendRequest(peer.app, GetProofsV2Msg, 42, cost, proofreqs)
|
||||||
msg, err := peer.app.ReadMsg()
|
if err := expectResponse(peer.app, ProofsV2Msg, 42, testBufLimit, proofsV2.NodeList()); err != nil {
|
||||||
if err != nil {
|
t.Errorf("proofs mismatch: %v", err)
|
||||||
t.Errorf("Message read error: %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 TestGetCHTProofsLes1(t *testing.T) { testGetCHTProofs(t, 1) }
|
||||||
func TestGetCHTProofsLes2(t *testing.T) { testGetCHTProofs(t, 2) }
|
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) {
|
func TestTransactionStatusLes2(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
pm := newTestProtocolManagerMust(t, false, 0, nil, nil, nil, db)
|
pm := newTestProtocolManagerMust(t, false, 0, nil, nil, nil, db)
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import (
|
||||||
"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/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/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/les/flowcontrol"
|
"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 := light.NewChtIndexer(db, false)
|
||||||
chtIndexer.Start(blockchain)
|
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)
|
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)
|
||||||
|
|
|
||||||
|
|
@ -493,10 +493,10 @@ func (r *BloomRequest) Request(reqID uint64, peer *peer) error {
|
||||||
reqs := make([]HelperTrieReq, len(r.SectionIdxList))
|
reqs := make([]HelperTrieReq, len(r.SectionIdxList))
|
||||||
|
|
||||||
var encNumber [10]byte
|
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 {
|
for i, sectionIdx := range r.SectionIdxList {
|
||||||
binary.BigEndian.PutUint64(encNumber[2:10], sectionIdx)
|
binary.BigEndian.PutUint64(encNumber[2:], sectionIdx)
|
||||||
reqs[i] = HelperTrieReq{
|
reqs[i] = HelperTrieReq{
|
||||||
Type: htBloomBits,
|
Type: htBloomBits,
|
||||||
TrieIdx: r.BloomTrieNum,
|
TrieIdx: r.BloomTrieNum,
|
||||||
|
|
@ -525,10 +525,10 @@ func (r *BloomRequest) Validate(db ethdb.Database, msg *Msg) error {
|
||||||
|
|
||||||
// Verify the proofs
|
// Verify the proofs
|
||||||
var encNumber [10]byte
|
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 {
|
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)
|
value, err, _ := trie.VerifyProof(r.BloomTrieRoot, encNumber[:], reads)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,9 @@ import (
|
||||||
// NodeSet stores a set of trie nodes. It implements trie.Database and can also
|
// NodeSet stores a set of trie nodes. It implements trie.Database and can also
|
||||||
// act as a cache for another trie.Database.
|
// act as a cache for another trie.Database.
|
||||||
type NodeSet struct {
|
type NodeSet struct {
|
||||||
db map[string][]byte
|
nodes map[string][]byte
|
||||||
|
order []string
|
||||||
|
|
||||||
dataSize int
|
dataSize int
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
@ -37,7 +39,7 @@ type NodeSet struct {
|
||||||
// NewNodeSet creates an empty node set
|
// NewNodeSet creates an empty node set
|
||||||
func NewNodeSet() *NodeSet {
|
func NewNodeSet() *NodeSet {
|
||||||
return &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()
|
db.lock.Lock()
|
||||||
defer db.lock.Unlock()
|
defer db.lock.Unlock()
|
||||||
|
|
||||||
if _, ok := db.db[string(key)]; !ok {
|
if _, ok := db.nodes[string(key)]; ok {
|
||||||
db.db[string(key)] = common.CopyBytes(value)
|
return nil
|
||||||
db.dataSize += len(value)
|
|
||||||
}
|
}
|
||||||
|
keystr := string(key)
|
||||||
|
|
||||||
|
db.nodes[keystr] = common.CopyBytes(value)
|
||||||
|
db.order = append(db.order, keystr)
|
||||||
|
db.dataSize += len(value)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,7 +65,7 @@ func (db *NodeSet) Get(key []byte) ([]byte, error) {
|
||||||
db.lock.RLock()
|
db.lock.RLock()
|
||||||
defer db.lock.RUnlock()
|
defer db.lock.RUnlock()
|
||||||
|
|
||||||
if entry, ok := db.db[string(key)]; ok {
|
if entry, ok := db.nodes[string(key)]; ok {
|
||||||
return entry, nil
|
return entry, nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("not found")
|
return nil, errors.New("not found")
|
||||||
|
|
@ -75,7 +82,7 @@ func (db *NodeSet) KeyCount() int {
|
||||||
db.lock.RLock()
|
db.lock.RLock()
|
||||||
defer db.lock.RUnlock()
|
defer db.lock.RUnlock()
|
||||||
|
|
||||||
return len(db.db)
|
return len(db.nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DataSize returns the aggregated data size of nodes in the set
|
// DataSize returns the aggregated data size of nodes in the set
|
||||||
|
|
@ -92,8 +99,8 @@ func (db *NodeSet) NodeList() NodeList {
|
||||||
defer db.lock.RUnlock()
|
defer db.lock.RUnlock()
|
||||||
|
|
||||||
var values NodeList
|
var values NodeList
|
||||||
for _, value := range db.db {
|
for _, key := range db.order {
|
||||||
values = append(values, value)
|
values = append(values, db.nodes[key])
|
||||||
}
|
}
|
||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
|
|
@ -103,7 +110,7 @@ func (db *NodeSet) Store(target ethdb.Putter) {
|
||||||
db.lock.RLock()
|
db.lock.RLock()
|
||||||
defer db.lock.RUnlock()
|
defer db.lock.RUnlock()
|
||||||
|
|
||||||
for key, value := range db.db {
|
for key, value := range db.nodes {
|
||||||
target.Put([]byte(key), value)
|
target.Put([]byte(key), value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue