@@ -19,20 +19,23 @@ package light
19
19
import (
20
20
"bytes"
21
21
"context"
22
+ "errors"
22
23
"math/big"
23
24
24
25
"github.com/ethereum/go-ethereum/common"
25
26
"github.com/ethereum/go-ethereum/core"
26
27
"github.com/ethereum/go-ethereum/core/rawdb"
27
28
"github.com/ethereum/go-ethereum/core/types"
28
- "github.com/ethereum/go-ethereum/crypto"
29
29
"github.com/ethereum/go-ethereum/rlp"
30
30
)
31
31
32
- var sha3Nil = crypto .Keccak256Hash (nil )
32
+ // errNonCanonicalHash is returned if the requested chain data doesn't belong
33
+ // to the canonical chain. ODR can only retrieve the canonical chain data covered
34
+ // by the CHT or Bloom trie for verification.
35
+ var errNonCanonicalHash = errors .New ("hash is not currently canonical" )
33
36
34
37
// GetHeaderByNumber retrieves the canonical block header corresponding to the
35
- // given number.
38
+ // given number. The returned header is proven by local CHT.
36
39
func GetHeaderByNumber (ctx context.Context , odr OdrBackend , number uint64 ) (* types.Header , error ) {
37
40
// Try to find it in the local database first.
38
41
db := odr .Database ()
@@ -63,25 +66,6 @@ func GetHeaderByNumber(ctx context.Context, odr OdrBackend, number uint64) (*typ
63
66
return r .Header , nil
64
67
}
65
68
66
- // GetUntrustedHeaderByNumber retrieves specified block header without
67
- // correctness checking. Note this function should only be used in light
68
- // client checkpoint syncing.
69
- func GetUntrustedHeaderByNumber (ctx context.Context , odr OdrBackend , number uint64 , peerId string ) (* types.Header , error ) {
70
- // todo(rjl493456442) it's a hack to retrieve headers which is not covered
71
- // by CHT. Fix it in LES4
72
- r := & ChtRequest {
73
- BlockNum : number ,
74
- ChtNum : number / odr .IndexerConfig ().ChtSize ,
75
- Untrusted : true ,
76
- PeerId : peerId ,
77
- Config : odr .IndexerConfig (),
78
- }
79
- if err := odr .Retrieve (ctx , r ); err != nil {
80
- return nil , err
81
- }
82
- return r .Header , nil
83
- }
84
-
85
69
// GetCanonicalHash retrieves the canonical block hash corresponding to the number.
86
70
func GetCanonicalHash (ctx context.Context , odr OdrBackend , number uint64 ) (common.Hash , error ) {
87
71
hash := rawdb .ReadCanonicalHash (odr .Database (), number )
@@ -102,10 +86,13 @@ func GetTd(ctx context.Context, odr OdrBackend, hash common.Hash, number uint64)
102
86
if td != nil {
103
87
return td , nil
104
88
}
105
- _ , err := GetHeaderByNumber (ctx , odr , number )
89
+ header , err := GetHeaderByNumber (ctx , odr , number )
106
90
if err != nil {
107
91
return nil , err
108
92
}
93
+ if header .Hash () != hash {
94
+ return nil , errNonCanonicalHash
95
+ }
109
96
// <hash, number> -> td mapping already be stored in db, get it.
110
97
return rawdb .ReadTd (odr .Database (), hash , number ), nil
111
98
}
@@ -120,6 +107,9 @@ func GetBodyRLP(ctx context.Context, odr OdrBackend, hash common.Hash, number ui
120
107
if err != nil {
121
108
return nil , errNoHeader
122
109
}
110
+ if header .Hash () != hash {
111
+ return nil , errNonCanonicalHash
112
+ }
123
113
r := & BlockRequest {Hash : hash , Number : number , Header : header }
124
114
if err := odr .Retrieve (ctx , r ); err != nil {
125
115
return nil , err
@@ -167,6 +157,9 @@ func GetBlockReceipts(ctx context.Context, odr OdrBackend, hash common.Hash, num
167
157
if err != nil {
168
158
return nil , errNoHeader
169
159
}
160
+ if header .Hash () != hash {
161
+ return nil , errNonCanonicalHash
162
+ }
170
163
r := & ReceiptsRequest {Hash : hash , Number : number , Header : header }
171
164
if err := odr .Retrieve (ctx , r ); err != nil {
172
165
return nil , err
0 commit comments