github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/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 12:09:34</date> 10 //</624342616753836032> 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删除与哈希关联的所有块总难度数据。 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 //readReceipts检索属于块的所有事务收据。 271 func ReadReceipts(db DatabaseReader, hash common.Hash, number uint64) types.Receipts { 272 //检索扁平收据切片 273 data, _ := db.Get(blockReceiptsKey(number, hash)) 274 if len(data) == 0 { 275 return nil 276 } 277 //将revcepts从其存储表单转换为内部表示形式 278 storageReceipts := []*types.ReceiptForStorage{} 279 if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { 280 log.Error("Invalid receipt array RLP", "hash", hash, "err", err) 281 return nil 282 } 283 receipts := make(types.Receipts, len(storageReceipts)) 284 for i, receipt := range storageReceipts { 285 receipts[i] = (*types.Receipt)(receipt) 286 } 287 return receipts 288 } 289 290 //WriteReceipts存储属于某个块的所有交易记录收据。 291 func WriteReceipts(db DatabaseWriter, hash common.Hash, number uint64, receipts types.Receipts) { 292 //将收据转换为其存储表单并将其序列化 293 storageReceipts := make([]*types.ReceiptForStorage, len(receipts)) 294 for i, receipt := range receipts { 295 storageReceipts[i] = (*types.ReceiptForStorage)(receipt) 296 } 297 bytes, err := rlp.EncodeToBytes(storageReceipts) 298 if err != nil { 299 log.Crit("Failed to encode block receipts", "err", err) 300 } 301 //存储扁平收据切片 302 if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil { 303 log.Crit("Failed to store block receipts", "err", err) 304 } 305 } 306 307 //删除收据删除与块哈希关联的所有收据数据。 308 func DeleteReceipts(db DatabaseDeleter, hash common.Hash, number uint64) { 309 if err := db.Delete(blockReceiptsKey(number, hash)); err != nil { 310 log.Crit("Failed to delete block receipts", "err", err) 311 } 312 } 313 314 //readblock检索与哈希相对应的整个块,对其进行组装 315 //从存储的标题和正文返回。如果标题或正文不能 316 //收回零。 317 // 318 //注意,由于头和块体同时下载,因此头和块体 319 //规范散列可以存储在数据库中,但主体数据尚未存储。 320 func ReadBlock(db DatabaseReader, hash common.Hash, number uint64) *types.Block { 321 header := ReadHeader(db, hash, number) 322 if header == nil { 323 return nil 324 } 325 body := ReadBody(db, hash, number) 326 if body == nil { 327 return nil 328 } 329 return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles) 330 } 331 332 //WriteBlock将块分别序列化到数据库、头和正文中。 333 func WriteBlock(db DatabaseWriter, block *types.Block) { 334 WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) 335 WriteHeader(db, block.Header()) 336 } 337 338 //删除块删除与哈希关联的所有块数据。 339 func DeleteBlock(db DatabaseDeleter, hash common.Hash, number uint64) { 340 DeleteReceipts(db, hash, number) 341 DeleteHeader(db, hash, number) 342 DeleteBody(db, hash, number) 343 DeleteTd(db, hash, number) 344 } 345 346 //findcommonancestor返回两个块头的最后一个公共祖先 347 func FindCommonAncestor(db DatabaseReader, a, b *types.Header) *types.Header { 348 for bn := b.Number.Uint64(); a.Number.Uint64() > bn; { 349 a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) 350 if a == nil { 351 return nil 352 } 353 } 354 for an := a.Number.Uint64(); an < b.Number.Uint64(); { 355 b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) 356 if b == nil { 357 return nil 358 } 359 } 360 for a.Hash() != b.Hash() { 361 a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) 362 if a == nil { 363 return nil 364 } 365 b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) 366 if b == nil { 367 return nil 368 } 369 } 370 return a 371 } 372