github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/rawdb/accessors_chain.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:35</date> 10 //</624450079255695360> 11 12 13 package rawdb 14 15 import ( 16 "bytes" 17 "encoding/binary" 18 "math/big" 19 20 "github.com/ethereum/go-ethereum/common" 21 "github.com/ethereum/go-ethereum/core/types" 22 "github.com/ethereum/go-ethereum/log" 23 "github.com/ethereum/go-ethereum/rlp" 24 ) 25 26 //readCanonicalHash检索分配给规范块号的哈希。 27 func ReadCanonicalHash(db DatabaseReader, number uint64) common.Hash { 28 data, _ := db.Get(headerHashKey(number)) 29 if len(data) == 0 { 30 return common.Hash{} 31 } 32 return common.BytesToHash(data) 33 } 34 35 //WriteCanonicalHash存储分配给规范块号的哈希。 36 func WriteCanonicalHash(db DatabaseWriter, hash common.Hash, number uint64) { 37 if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil { 38 log.Crit("Failed to store number to hash mapping", "err", err) 39 } 40 } 41 42 //DeleteConnicalHash删除到哈希规范映射的数字。 43 func DeleteCanonicalHash(db DatabaseDeleter, number uint64) { 44 if err := db.Delete(headerHashKey(number)); err != nil { 45 log.Crit("Failed to delete number to hash mapping", "err", err) 46 } 47 } 48 49 //readheadernumber返回分配给哈希的头编号。 50 func ReadHeaderNumber(db DatabaseReader, hash common.Hash) *uint64 { 51 data, _ := db.Get(headerNumberKey(hash)) 52 if len(data) != 8 { 53 return nil 54 } 55 number := binary.BigEndian.Uint64(data) 56 return &number 57 } 58 59 //readHeaderHash检索当前规范头的哈希。 60 func ReadHeadHeaderHash(db DatabaseReader) common.Hash { 61 data, _ := db.Get(headHeaderKey) 62 if len(data) == 0 { 63 return common.Hash{} 64 } 65 return common.BytesToHash(data) 66 } 67 68 //WriteHeaderHash存储当前规范头的哈希。 69 func WriteHeadHeaderHash(db DatabaseWriter, hash common.Hash) { 70 if err := db.Put(headHeaderKey, hash.Bytes()); err != nil { 71 log.Crit("Failed to store last header's hash", "err", err) 72 } 73 } 74 75 //readheadblockhash检索当前规范头块的哈希。 76 func ReadHeadBlockHash(db DatabaseReader) common.Hash { 77 data, _ := db.Get(headBlockKey) 78 if len(data) == 0 { 79 return common.Hash{} 80 } 81 return common.BytesToHash(data) 82 } 83 84 //WriteHeadBlockHash存储头块的哈希。 85 func WriteHeadBlockHash(db DatabaseWriter, hash common.Hash) { 86 if err := db.Put(headBlockKey, hash.Bytes()); err != nil { 87 log.Crit("Failed to store last block's hash", "err", err) 88 } 89 } 90 91 //readHeadFastBlockHash检索当前快速同步头块的哈希。 92 func ReadHeadFastBlockHash(db DatabaseReader) common.Hash { 93 data, _ := db.Get(headFastBlockKey) 94 if len(data) == 0 { 95 return common.Hash{} 96 } 97 return common.BytesToHash(data) 98 } 99 100 //WriteHeadFastBlockHash存储当前快速同步头块的哈希。 101 func WriteHeadFastBlockHash(db DatabaseWriter, hash common.Hash) { 102 if err := db.Put(headFastBlockKey, hash.Bytes()); err != nil { 103 log.Crit("Failed to store last fast block's hash", "err", err) 104 } 105 } 106 107 //readfasttriegrogress检索快速同步以允许的尝试次数节点 108 //在重新启动时报告正确的数字。 109 func ReadFastTrieProgress(db DatabaseReader) uint64 { 110 data, _ := db.Get(fastTrieProgressKey) 111 if len(data) == 0 { 112 return 0 113 } 114 return new(big.Int).SetBytes(data).Uint64() 115 } 116 117 //WriteFastTrieProgress存储要支持的快速同步Trie进程计数器 118 //重新启动时检索。 119 func WriteFastTrieProgress(db DatabaseWriter, count uint64) { 120 if err := db.Put(fastTrieProgressKey, new(big.Int).SetUint64(count).Bytes()); err != nil { 121 log.Crit("Failed to store fast sync trie progress", "err", err) 122 } 123 } 124 125 //readheaderrlp以其原始RLP数据库编码检索块头。 126 func ReadHeaderRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue { 127 data, _ := db.Get(headerKey(number, hash)) 128 return data 129 } 130 131 //散列头验证与散列对应的块头是否存在。 132 func HasHeader(db DatabaseReader, hash common.Hash, number uint64) bool { 133 if has, err := db.Has(headerKey(number, hash)); !has || err != nil { 134 return false 135 } 136 return true 137 } 138 139 //readheader检索与哈希对应的块头。 140 func ReadHeader(db DatabaseReader, hash common.Hash, number uint64) *types.Header { 141 data := ReadHeaderRLP(db, hash, number) 142 if len(data) == 0 { 143 return nil 144 } 145 header := new(types.Header) 146 if err := rlp.Decode(bytes.NewReader(data), header); err != nil { 147 log.Error("Invalid block header RLP", "hash", hash, "err", err) 148 return nil 149 } 150 return header 151 } 152 153 //WriteHeader将一个块头存储到数据库中,还存储哈希- 154 //到数字映射。 155 func WriteHeader(db DatabaseWriter, header *types.Header) { 156 //写入哈希->数字映射 157 var ( 158 hash = header.Hash() 159 number = header.Number.Uint64() 160 encoded = encodeBlockNumber(number) 161 ) 162 key := headerNumberKey(hash) 163 if err := db.Put(key, encoded); err != nil { 164 log.Crit("Failed to store hash to number mapping", "err", err) 165 } 166 //写入编码的头 167 data, err := rlp.EncodeToBytes(header) 168 if err != nil { 169 log.Crit("Failed to RLP encode header", "err", err) 170 } 171 key = headerKey(number, hash) 172 if err := db.Put(key, data); err != nil { 173 log.Crit("Failed to store header", "err", err) 174 } 175 } 176 177 //DeleteHeader删除与哈希关联的所有块头数据。 178 func DeleteHeader(db DatabaseDeleter, hash common.Hash, number uint64) { 179 if err := db.Delete(headerKey(number, hash)); err != nil { 180 log.Crit("Failed to delete header", "err", err) 181 } 182 if err := db.Delete(headerNumberKey(hash)); err != nil { 183 log.Crit("Failed to delete hash to number mapping", "err", err) 184 } 185 } 186 187 //readbodyrlp以rlp编码方式检索块体(事务和uncles)。 188 func ReadBodyRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue { 189 data, _ := db.Get(blockBodyKey(number, hash)) 190 return data 191 } 192 193 //writebodyrlp将RLP编码的块体存储到数据库中。 194 func WriteBodyRLP(db DatabaseWriter, hash common.Hash, number uint64, rlp rlp.RawValue) { 195 if err := db.Put(blockBodyKey(number, hash), rlp); err != nil { 196 log.Crit("Failed to store block body", "err", err) 197 } 198 } 199 200 //hasbody验证哈希对应的块体的存在。 201 func HasBody(db DatabaseReader, hash common.Hash, number uint64) bool { 202 if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil { 203 return false 204 } 205 return true 206 } 207 208 //readbody检索与哈希相对应的块体。 209 func ReadBody(db DatabaseReader, hash common.Hash, number uint64) *types.Body { 210 data := ReadBodyRLP(db, hash, number) 211 if len(data) == 0 { 212 return nil 213 } 214 body := new(types.Body) 215 if err := rlp.Decode(bytes.NewReader(data), body); err != nil { 216 log.Error("Invalid block body RLP", "hash", hash, "err", err) 217 return nil 218 } 219 return body 220 } 221 222 //WriteBody将块体存储到数据库中。 223 func WriteBody(db DatabaseWriter, hash common.Hash, number uint64, body *types.Body) { 224 data, err := rlp.EncodeToBytes(body) 225 if err != nil { 226 log.Crit("Failed to RLP encode body", "err", err) 227 } 228 WriteBodyRLP(db, hash, number, data) 229 } 230 231 //DeleteBody删除与哈希关联的所有块体数据。 232 func DeleteBody(db DatabaseDeleter, hash common.Hash, number uint64) { 233 if err := db.Delete(blockBodyKey(number, hash)); err != nil { 234 log.Crit("Failed to delete block body", "err", err) 235 } 236 } 237 238 //readtd检索与哈希相对应的块的总难度。 239 func ReadTd(db DatabaseReader, hash common.Hash, number uint64) *big.Int { 240 data, _ := db.Get(headerTDKey(number, hash)) 241 if len(data) == 0 { 242 return nil 243 } 244 td := new(big.Int) 245 if err := rlp.Decode(bytes.NewReader(data), td); err != nil { 246 log.Error("Invalid block total difficulty RLP", "hash", hash, "err", err) 247 return nil 248 } 249 return td 250 } 251 252 //writetd将块的总难度存储到数据库中。 253 func WriteTd(db DatabaseWriter, hash common.Hash, number uint64, td *big.Int) { 254 data, err := rlp.EncodeToBytes(td) 255 if err != nil { 256 log.Crit("Failed to RLP encode block total difficulty", "err", err) 257 } 258 if err := db.Put(headerTDKey(number, hash), data); err != nil { 259 log.Crit("Failed to store block total difficulty", "err", err) 260 } 261 } 262 263 //DeleteTd removes all block total difficulty data associated with a hash. 264 func DeleteTd(db DatabaseDeleter, hash common.Hash, number uint64) { 265 if err := db.Delete(headerTDKey(number, hash)); err != nil { 266 log.Crit("Failed to delete block total difficulty", "err", err) 267 } 268 } 269 270 //hasReceipts验证所有属于 271 //到街区。 272 func HasReceipts(db DatabaseReader, hash common.Hash, number uint64) bool { 273 if has, err := db.Has(blockReceiptsKey(number, hash)); !has || err != nil { 274 return false 275 } 276 return true 277 } 278 279 //readReceipts检索属于块的所有事务收据。 280 func ReadReceipts(db DatabaseReader, hash common.Hash, number uint64) types.Receipts { 281 //检索扁平收据切片 282 data, _ := db.Get(blockReceiptsKey(number, hash)) 283 if len(data) == 0 { 284 return nil 285 } 286 //将其存储表单中的收据转换为内部表示形式 287 storageReceipts := []*types.ReceiptForStorage{} 288 if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { 289 log.Error("Invalid receipt array RLP", "hash", hash, "err", err) 290 return nil 291 } 292 receipts := make(types.Receipts, len(storageReceipts)) 293 for i, receipt := range storageReceipts { 294 receipts[i] = (*types.Receipt)(receipt) 295 } 296 return receipts 297 } 298 299 //WriteReceipts存储属于某个块的所有交易记录收据。 300 func WriteReceipts(db DatabaseWriter, hash common.Hash, number uint64, receipts types.Receipts) { 301 //将收据转换为其存储表单并将其序列化 302 storageReceipts := make([]*types.ReceiptForStorage, len(receipts)) 303 for i, receipt := range receipts { 304 storageReceipts[i] = (*types.ReceiptForStorage)(receipt) 305 } 306 bytes, err := rlp.EncodeToBytes(storageReceipts) 307 if err != nil { 308 log.Crit("Failed to encode block receipts", "err", err) 309 } 310 //存储扁平收据切片 311 if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil { 312 log.Crit("Failed to store block receipts", "err", err) 313 } 314 } 315 316 //删除收据删除与块哈希关联的所有收据数据。 317 func DeleteReceipts(db DatabaseDeleter, hash common.Hash, number uint64) { 318 if err := db.Delete(blockReceiptsKey(number, hash)); err != nil { 319 log.Crit("Failed to delete block receipts", "err", err) 320 } 321 } 322 323 //readblock检索与哈希相对应的整个块,对其进行组装 324 //从存储的标题和正文返回。如果标题或正文不能 325 //收回零。 326 // 327 //注意,由于头和块体同时下载,因此头和块体 328 //规范散列可以存储在数据库中,但主体数据尚未存储。 329 func ReadBlock(db DatabaseReader, hash common.Hash, number uint64) *types.Block { 330 header := ReadHeader(db, hash, number) 331 if header == nil { 332 return nil 333 } 334 body := ReadBody(db, hash, number) 335 if body == nil { 336 return nil 337 } 338 return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles) 339 } 340 341 //WriteBlock将块分别序列化到数据库、头和正文中。 342 func WriteBlock(db DatabaseWriter, block *types.Block) { 343 WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) 344 WriteHeader(db, block.Header()) 345 } 346 347 //删除块删除与哈希关联的所有块数据。 348 func DeleteBlock(db DatabaseDeleter, hash common.Hash, number uint64) { 349 DeleteReceipts(db, hash, number) 350 DeleteHeader(db, hash, number) 351 DeleteBody(db, hash, number) 352 DeleteTd(db, hash, number) 353 } 354 355 //findcommonancestor返回两个块头的最后一个公共祖先 356 func FindCommonAncestor(db DatabaseReader, a, b *types.Header) *types.Header { 357 for bn := b.Number.Uint64(); a.Number.Uint64() > bn; { 358 a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) 359 if a == nil { 360 return nil 361 } 362 } 363 for an := a.Number.Uint64(); an < b.Number.Uint64(); { 364 b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) 365 if b == nil { 366 return nil 367 } 368 } 369 for a.Hash() != b.Hash() { 370 a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) 371 if a == nil { 372 return nil 373 } 374 b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) 375 if b == nil { 376 return nil 377 } 378 } 379 return a 380 } 381