mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
les, light: redef cht request
This commit is contained in:
parent
dfe765f3f5
commit
14e65b5d0e
3 changed files with 34 additions and 29 deletions
|
|
@ -353,9 +353,9 @@ type ChtRequest light.ChtRequest
|
||||||
func (r *ChtRequest) GetCost(peer *peer) uint64 {
|
func (r *ChtRequest) GetCost(peer *peer) uint64 {
|
||||||
switch peer.version {
|
switch peer.version {
|
||||||
case lpv1:
|
case lpv1:
|
||||||
return peer.GetRequestCost(GetHeaderProofsMsg, len(r.BlockNum))
|
return peer.GetRequestCost(GetHeaderProofsMsg, len(r.Numbers))
|
||||||
case lpv2:
|
case lpv2:
|
||||||
return peer.GetRequestCost(GetHelperTrieProofsMsg, len(r.BlockNum))
|
return peer.GetRequestCost(GetHelperTrieProofsMsg, len(r.Numbers))
|
||||||
default:
|
default:
|
||||||
panic(nil)
|
panic(nil)
|
||||||
}
|
}
|
||||||
|
|
@ -371,17 +371,17 @@ func (r *ChtRequest) CanSend(peer *peer, config *light.IndexerConfig) bool {
|
||||||
|
|
||||||
// Request sends an ODR request to the LES network (implementation of LesOdrRequest)
|
// Request sends an ODR request to the LES network (implementation of LesOdrRequest)
|
||||||
func (r *ChtRequest) Request(reqID uint64, peer *peer, config *light.IndexerConfig) error {
|
func (r *ChtRequest) Request(reqID uint64, peer *peer, config *light.IndexerConfig) error {
|
||||||
peer.Log().Debug("Requesting CHT", "cht", r.ChtNum, "block", r.BlockNum)
|
peer.Log().Debug("Requesting CHT", "cht", r.ChtNum, "block", r.Numbers)
|
||||||
var (
|
var (
|
||||||
encNum [8]byte
|
encNum [8]byte
|
||||||
reqs []HelperTrieReq
|
reqs = make([]HelperTrieReq, 0, len(r.Numbers))
|
||||||
)
|
)
|
||||||
for _, num := range r.BlockNum {
|
for _, num := range r.Numbers {
|
||||||
binary.BigEndian.PutUint64(encNum[:], num)
|
binary.BigEndian.PutUint64(encNum[:], num)
|
||||||
reqs = append(reqs, HelperTrieReq{
|
reqs = append(reqs, HelperTrieReq{
|
||||||
Type: htCanonical,
|
Type: htCanonical,
|
||||||
TrieIdx: r.ChtNum,
|
TrieIdx: r.ChtNum,
|
||||||
Key: encNum[:],
|
Key: common.CopyBytes(encNum[:]),
|
||||||
AuxReq: auxHeader,
|
AuxReq: auxHeader,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -408,22 +408,21 @@ func (r *ChtRequest) Request(reqID uint64, peer *peer, config *light.IndexerConf
|
||||||
// returns true and stores results in memory if the message was a valid reply
|
// returns true and stores results in memory if the message was a valid reply
|
||||||
// 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.BlockNum)
|
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)
|
||||||
if len(resps) != len(r.BlockNum) {
|
if len(resps) != len(r.Numbers) {
|
||||||
return errInvalidEntryCount
|
return errInvalidEntryCount
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
headers []*types.Header
|
headers []*types.Header
|
||||||
tds []*big.Int
|
tds []*big.Int
|
||||||
encNumber [8]byte
|
encNumber [8]byte
|
||||||
node light.ChtNode
|
|
||||||
nodeset = light.NewNodeSet()
|
nodeset = light.NewNodeSet()
|
||||||
)
|
)
|
||||||
for i, num := range r.BlockNum {
|
for i, num := range r.Numbers {
|
||||||
resp := resps[i]
|
resp := resps[i]
|
||||||
// Verify the CHT
|
// Verify the CHT
|
||||||
binary.BigEndian.PutUint64(encNumber[:], num)
|
binary.BigEndian.PutUint64(encNumber[:], num)
|
||||||
|
|
@ -431,6 +430,7 @@ func (r *ChtRequest) Validate(db ethdb.Database, msg *Msg) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
var node light.ChtNode
|
||||||
if err := rlp.DecodeBytes(value, &node); err != nil {
|
if err := rlp.DecodeBytes(value, &node); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -445,24 +445,24 @@ func (r *ChtRequest) Validate(db ethdb.Database, msg *Msg) error {
|
||||||
tds = append(tds, node.Td)
|
tds = append(tds, node.Td)
|
||||||
light.NodeList(resp.Proof).Store(nodeset)
|
light.NodeList(resp.Proof).Store(nodeset)
|
||||||
}
|
}
|
||||||
r.Header = headers
|
r.Headers = headers
|
||||||
r.Td = tds
|
r.Tds = tds
|
||||||
r.Proof = nodeset
|
r.Proof = nodeset
|
||||||
|
|
||||||
case MsgHelperTrieProofs:
|
case MsgHelperTrieProofs:
|
||||||
// Check if the number of items in the response is the same as we requested.
|
// Check if the number of items in the response is the same as we requested.
|
||||||
resp := msg.Obj.(HelperTrieResps)
|
resp := msg.Obj.(HelperTrieResps)
|
||||||
if len(resp.AuxData) != len(r.BlockNum) {
|
if len(resp.AuxData) != len(r.Numbers) {
|
||||||
return errInvalidEntryCount
|
return errInvalidEntryCount
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
headers []*types.Header
|
headers []*types.Header
|
||||||
tds []*big.Int
|
tds []*big.Int
|
||||||
encNumber [8]byte
|
encNumber [8]byte
|
||||||
node light.ChtNode
|
|
||||||
nodeSet = resp.Proofs.NodeSet()
|
nodeSet = resp.Proofs.NodeSet()
|
||||||
|
reads = &readTraceDB{db: nodeSet}
|
||||||
)
|
)
|
||||||
for i, num := range r.BlockNum {
|
for i, num := range r.Numbers {
|
||||||
enc := resp.AuxData[i]
|
enc := resp.AuxData[i]
|
||||||
if len(enc) == 0 {
|
if len(enc) == 0 {
|
||||||
return errHeaderUnavailable
|
return errHeaderUnavailable
|
||||||
|
|
@ -473,10 +473,11 @@ func (r *ChtRequest) Validate(db ethdb.Database, msg *Msg) error {
|
||||||
}
|
}
|
||||||
// Verify the CHT
|
// Verify the CHT
|
||||||
binary.BigEndian.PutUint64(encNumber[:], num)
|
binary.BigEndian.PutUint64(encNumber[:], num)
|
||||||
value, _, err := trie.VerifyProof(r.ChtRoot, encNumber[:], nodeSet)
|
value, _, err := trie.VerifyProof(r.ChtRoot, encNumber[:], reads)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("merkle proof verification failed: %v", err)
|
return fmt.Errorf("merkle proof verification failed: %v", err)
|
||||||
}
|
}
|
||||||
|
var node light.ChtNode
|
||||||
if err := rlp.DecodeBytes(value, &node); err != nil {
|
if err := rlp.DecodeBytes(value, &node); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -490,8 +491,12 @@ func (r *ChtRequest) Validate(db ethdb.Database, msg *Msg) error {
|
||||||
headers = append(headers, header)
|
headers = append(headers, header)
|
||||||
tds = append(tds, node.Td)
|
tds = append(tds, node.Td)
|
||||||
}
|
}
|
||||||
r.Header = headers
|
if len(reads.reads) != nodeSet.KeyCount() {
|
||||||
r.Td = tds
|
return errUselessNodes
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Headers = headers
|
||||||
|
r.Tds = tds
|
||||||
r.Proof = nodeSet
|
r.Proof = nodeSet
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
12
light/odr.go
12
light/odr.go
|
|
@ -135,9 +135,9 @@ type ChtRequest struct {
|
||||||
OdrRequest
|
OdrRequest
|
||||||
ChtNum uint64
|
ChtNum uint64
|
||||||
ChtRoot common.Hash
|
ChtRoot common.Hash
|
||||||
BlockNum []uint64
|
Numbers []uint64
|
||||||
Header []*types.Header
|
Headers []*types.Header
|
||||||
Td []*big.Int
|
Tds []*big.Int
|
||||||
Proof *NodeSet
|
Proof *NodeSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,12 +145,12 @@ type ChtRequest struct {
|
||||||
func (req *ChtRequest) StoreResult(db ethdb.Database, config *IndexerConfig) {
|
func (req *ChtRequest) StoreResult(db ethdb.Database, config *IndexerConfig) {
|
||||||
// The block number, header, td, proof length consistency has been verified
|
// The block number, header, td, proof length consistency has been verified
|
||||||
// in the validation phase.
|
// in the validation phase.
|
||||||
for index := range req.BlockNum {
|
for index := range req.Numbers {
|
||||||
header := req.Header[index]
|
header := req.Headers[index]
|
||||||
hash, num := header.Hash(), header.Number.Uint64()
|
hash, num := header.Hash(), header.Number.Uint64()
|
||||||
|
|
||||||
rawdb.WriteHeader(db, header)
|
rawdb.WriteHeader(db, header)
|
||||||
rawdb.WriteTd(db, hash, num, req.Td[index])
|
rawdb.WriteTd(db, hash, num, req.Tds[index])
|
||||||
rawdb.WriteCanonicalHash(db, hash, num)
|
rawdb.WriteCanonicalHash(db, hash, num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,12 +62,12 @@ func GetHeaderByNumber(ctx context.Context, odr OdrBackend, number uint64) (*typ
|
||||||
if number >= chtCount*odr.IndexerConfig().ChtSize {
|
if number >= chtCount*odr.IndexerConfig().ChtSize {
|
||||||
return nil, ErrNoTrustedCht
|
return nil, ErrNoTrustedCht
|
||||||
}
|
}
|
||||||
r := &ChtRequest{ChtRoot: GetChtRoot(db, chtCount-1, sectionHead), ChtNum: chtCount - 1, BlockNum: []uint64{number}}
|
r := &ChtRequest{ChtRoot: GetChtRoot(db, chtCount-1, sectionHead), ChtNum: chtCount - 1, Numbers: []uint64{number}}
|
||||||
if err := odr.Retrieve(ctx, r); err != nil {
|
if err := odr.Retrieve(ctx, r); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Response item number has been checked in validation stage, no extra checking needed.
|
// Response item number has been checked in validation stage, no extra checking needed.
|
||||||
return r.Header[0], nil
|
return r.Headers[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCanonicalHash(ctx context.Context, odr OdrBackend, number uint64) (common.Hash, error) {
|
func GetCanonicalHash(ctx context.Context, odr OdrBackend, number uint64) (common.Hash, error) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue