github.com/Blockdaemon/celo-blockchain@v0.0.0-20200129231733-e667f6b08419/core/rawdb/accessors_chain.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package rawdb 18 19 import ( 20 "bytes" 21 "encoding/binary" 22 "math/big" 23 24 "github.com/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/consensus/istanbul" 26 "github.com/ethereum/go-ethereum/core/types" 27 "github.com/ethereum/go-ethereum/log" 28 "github.com/ethereum/go-ethereum/rlp" 29 ) 30 31 // ReadCanonicalHash retrieves the hash assigned to a canonical block number. 32 func ReadCanonicalHash(db DatabaseReader, number uint64) common.Hash { 33 data, _ := db.Get(headerHashKey(number)) 34 if len(data) == 0 { 35 return common.Hash{} 36 } 37 return common.BytesToHash(data) 38 } 39 40 // WriteCanonicalHash stores the hash assigned to a canonical block number. 41 func WriteCanonicalHash(db DatabaseWriter, hash common.Hash, number uint64) { 42 if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil { 43 log.Crit("Failed to store number to hash mapping", "err", err) 44 } 45 } 46 47 // DeleteCanonicalHash removes the number to hash canonical mapping. 48 func DeleteCanonicalHash(db DatabaseDeleter, number uint64) { 49 if err := db.Delete(headerHashKey(number)); err != nil { 50 log.Crit("Failed to delete number to hash mapping", "err", err) 51 } 52 } 53 54 // ReadHeaderNumber returns the header number assigned to a hash. 55 func ReadHeaderNumber(db DatabaseReader, hash common.Hash) *uint64 { 56 data, _ := db.Get(headerNumberKey(hash)) 57 if len(data) != 8 { 58 return nil 59 } 60 number := binary.BigEndian.Uint64(data) 61 return &number 62 } 63 64 // ReadHeadHeaderHash retrieves the hash of the current canonical head header. 65 func ReadHeadHeaderHash(db DatabaseReader) common.Hash { 66 data, _ := db.Get(headHeaderKey) 67 if len(data) == 0 { 68 return common.Hash{} 69 } 70 return common.BytesToHash(data) 71 } 72 73 // WriteHeadHeaderHash stores the hash of the current canonical head header. 74 func WriteHeadHeaderHash(db DatabaseWriter, hash common.Hash) { 75 if err := db.Put(headHeaderKey, hash.Bytes()); err != nil { 76 log.Crit("Failed to store last header's hash", "err", err) 77 } 78 } 79 80 // ReadHeadBlockHash retrieves the hash of the current canonical head block. 81 func ReadHeadBlockHash(db DatabaseReader) common.Hash { 82 data, _ := db.Get(headBlockKey) 83 if len(data) == 0 { 84 return common.Hash{} 85 } 86 return common.BytesToHash(data) 87 } 88 89 // WriteHeadBlockHash stores the head block's hash. 90 func WriteHeadBlockHash(db DatabaseWriter, hash common.Hash) { 91 if err := db.Put(headBlockKey, hash.Bytes()); err != nil { 92 log.Crit("Failed to store last block's hash", "err", err) 93 } 94 } 95 96 // ReadHeadFastBlockHash retrieves the hash of the current fast-sync head block. 97 func ReadHeadFastBlockHash(db DatabaseReader) common.Hash { 98 data, _ := db.Get(headFastBlockKey) 99 if len(data) == 0 { 100 return common.Hash{} 101 } 102 return common.BytesToHash(data) 103 } 104 105 // WriteHeadFastBlockHash stores the hash of the current fast-sync head block. 106 func WriteHeadFastBlockHash(db DatabaseWriter, hash common.Hash) { 107 if err := db.Put(headFastBlockKey, hash.Bytes()); err != nil { 108 log.Crit("Failed to store last fast block's hash", "err", err) 109 } 110 } 111 112 // ReadFastTrieProgress retrieves the number of tries nodes fast synced to allow 113 // reporting correct numbers across restarts. 114 func ReadFastTrieProgress(db DatabaseReader) uint64 { 115 data, _ := db.Get(fastTrieProgressKey) 116 if len(data) == 0 { 117 return 0 118 } 119 return new(big.Int).SetBytes(data).Uint64() 120 } 121 122 // WriteFastTrieProgress stores the fast sync trie process counter to support 123 // retrieving it across restarts. 124 func WriteFastTrieProgress(db DatabaseWriter, count uint64) { 125 if err := db.Put(fastTrieProgressKey, new(big.Int).SetUint64(count).Bytes()); err != nil { 126 log.Crit("Failed to store fast sync trie progress", "err", err) 127 } 128 } 129 130 // ReadHeaderRLP retrieves a block header in its raw RLP database encoding. 131 func ReadHeaderRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue { 132 data, _ := db.Get(headerKey(number, hash)) 133 return data 134 } 135 136 // HasHeader verifies the existence of a block header corresponding to the hash. 137 func HasHeader(db DatabaseReader, hash common.Hash, number uint64) bool { 138 if has, err := db.Has(headerKey(number, hash)); !has || err != nil { 139 return false 140 } 141 return true 142 } 143 144 // ReadHeader retrieves the block header corresponding to the hash. 145 func ReadHeader(db DatabaseReader, hash common.Hash, number uint64) *types.Header { 146 data := ReadHeaderRLP(db, hash, number) 147 if len(data) == 0 { 148 return nil 149 } 150 header := new(types.Header) 151 if err := rlp.Decode(bytes.NewReader(data), header); err != nil { 152 log.Error("Invalid block header RLP", "hash", hash, "err", err) 153 return nil 154 } 155 return header 156 } 157 158 // WriteHeader stores a block header into the database and also stores the hash- 159 // to-number mapping. 160 func WriteHeader(db DatabaseWriter, header *types.Header) { 161 // Write the hash -> number mapping 162 var ( 163 hash = header.Hash() 164 number = header.Number.Uint64() 165 encoded = encodeBlockNumber(number) 166 ) 167 key := headerNumberKey(hash) 168 if err := db.Put(key, encoded); err != nil { 169 log.Crit("Failed to store hash to number mapping", "err", err) 170 } 171 // Write the encoded header 172 data, err := rlp.EncodeToBytes(header) 173 if err != nil { 174 log.Crit("Failed to RLP encode header", "err", err) 175 } 176 key = headerKey(number, hash) 177 if err := db.Put(key, data); err != nil { 178 log.Crit("Failed to store header", "err", err) 179 } 180 } 181 182 // DeleteHeader removes all block header data associated with a hash. 183 func DeleteHeader(db DatabaseDeleter, hash common.Hash, number uint64) { 184 if err := db.Delete(headerKey(number, hash)); err != nil { 185 log.Crit("Failed to delete header", "err", err) 186 } 187 if err := db.Delete(headerNumberKey(hash)); err != nil { 188 log.Crit("Failed to delete hash to number mapping", "err", err) 189 } 190 } 191 192 // ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding. 193 func ReadBodyRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue { 194 data, _ := db.Get(blockBodyKey(number, hash)) 195 return data 196 } 197 198 // WriteBodyRLP stores an RLP encoded block body into the database. 199 func WriteBodyRLP(db DatabaseWriter, hash common.Hash, number uint64, rlp rlp.RawValue) { 200 if err := db.Put(blockBodyKey(number, hash), rlp); err != nil { 201 log.Crit("Failed to store block body", "err", err) 202 } 203 } 204 205 // HasBody verifies the existence of a block body corresponding to the hash. 206 func HasBody(db DatabaseReader, hash common.Hash, number uint64) bool { 207 if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil { 208 return false 209 } 210 return true 211 } 212 213 // ReadBody retrieves the block body corresponding to the hash. 214 func ReadBody(db DatabaseReader, hash common.Hash, number uint64) *types.Body { 215 data := ReadBodyRLP(db, hash, number) 216 if len(data) == 0 { 217 return nil 218 } 219 body := new(types.Body) 220 if err := rlp.Decode(bytes.NewReader(data), body); err != nil { 221 log.Error("Invalid block body RLP", "hash", hash, "err", err) 222 return nil 223 } 224 return body 225 } 226 227 // WriteBody storea a block body into the database. 228 func WriteBody(db DatabaseWriter, hash common.Hash, number uint64, body *types.Body) { 229 data, err := rlp.EncodeToBytes(body) 230 if err != nil { 231 log.Crit("Failed to RLP encode body", "err", err) 232 } 233 WriteBodyRLP(db, hash, number, data) 234 } 235 236 // DeleteBody removes all block body data associated with a hash. 237 func DeleteBody(db DatabaseDeleter, hash common.Hash, number uint64) { 238 if err := db.Delete(blockBodyKey(number, hash)); err != nil { 239 log.Crit("Failed to delete block body", "err", err) 240 } 241 } 242 243 // ReadTd retrieves a block's total difficulty corresponding to the hash. 244 func ReadTd(db DatabaseReader, hash common.Hash, number uint64) *big.Int { 245 data, _ := db.Get(headerTDKey(number, hash)) 246 if len(data) == 0 { 247 return nil 248 } 249 td := new(big.Int) 250 if err := rlp.Decode(bytes.NewReader(data), td); err != nil { 251 log.Error("Invalid block total difficulty RLP", "hash", hash, "err", err) 252 return nil 253 } 254 return td 255 } 256 257 // ReadAccumulatedEpochUptime retrieves the so-far accumulated uptime array for the validators of the specified epoch 258 func ReadAccumulatedEpochUptime(db DatabaseReader, epoch uint64) *istanbul.Uptime { 259 data, _ := db.Get(uptimeKey(epoch)) 260 if len(data) == 0 { 261 log.Trace("ReadAccumulatedEpochUptime EMPTY", "epoch", epoch) 262 return nil 263 } 264 uptime := new(istanbul.Uptime) 265 if err := rlp.Decode(bytes.NewReader(data), uptime); err != nil { 266 log.Error("Invalid uptime RLP", "err", err) 267 return nil 268 } 269 return uptime 270 } 271 272 // WriteAccumulatedEpochUptime updates the accumulated uptime array for the validators of the specified epoch 273 func WriteAccumulatedEpochUptime(db DatabaseWriter, epoch uint64, uptime *istanbul.Uptime) { 274 data, err := rlp.EncodeToBytes(uptime) 275 if err != nil { 276 log.Crit("Failed to RLP encode updated uptime", "err", err) 277 } 278 if err := db.Put(uptimeKey(epoch), data); err != nil { 279 log.Crit("Failed to store updated uptime", "err", err) 280 } 281 } 282 283 // DeleteAccumulatedEpochUptime removes all accumulated uptime data for that epoch 284 func DeleteAccumulatedEpochUptime(db DatabaseDeleter, epoch uint64) { 285 if err := db.Delete(uptimeKey(epoch)); err != nil { 286 log.Crit("Failed to delete stored uptime of validators", "err", err) 287 } 288 } 289 290 // WriteTd stores the total difficulty of a block into the database. 291 func WriteTd(db DatabaseWriter, hash common.Hash, number uint64, td *big.Int) { 292 data, err := rlp.EncodeToBytes(td) 293 if err != nil { 294 log.Crit("Failed to RLP encode block total difficulty", "err", err) 295 } 296 if err := db.Put(headerTDKey(number, hash), data); err != nil { 297 log.Crit("Failed to store block total difficulty", "err", err) 298 } 299 } 300 301 // DeleteTd removes all block total difficulty data associated with a hash. 302 func DeleteTd(db DatabaseDeleter, hash common.Hash, number uint64) { 303 if err := db.Delete(headerTDKey(number, hash)); err != nil { 304 log.Crit("Failed to delete block total difficulty", "err", err) 305 } 306 } 307 308 // HasReceipts verifies the existence of all the transaction receipts belonging 309 // to a block. 310 func HasReceipts(db DatabaseReader, hash common.Hash, number uint64) bool { 311 if has, err := db.Has(blockReceiptsKey(number, hash)); !has || err != nil { 312 return false 313 } 314 return true 315 } 316 317 // ReadReceipts retrieves all the transaction receipts belonging to a block. 318 func ReadReceipts(db DatabaseReader, hash common.Hash, number uint64) types.Receipts { 319 // Retrieve the flattened receipt slice 320 data, _ := db.Get(blockReceiptsKey(number, hash)) 321 if len(data) == 0 { 322 return nil 323 } 324 // Convert the receipts from their storage form to their internal representation 325 storageReceipts := []*types.ReceiptForStorage{} 326 if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { 327 log.Error("Invalid receipt array RLP", "hash", hash, "err", err) 328 return nil 329 } 330 receipts := make(types.Receipts, len(storageReceipts)) 331 for i, receipt := range storageReceipts { 332 receipts[i] = (*types.Receipt)(receipt) 333 } 334 return receipts 335 } 336 337 // WriteReceipts stores all the transaction receipts belonging to a block. 338 func WriteReceipts(db DatabaseWriter, hash common.Hash, number uint64, receipts types.Receipts) { 339 // Convert the receipts into their storage form and serialize them 340 storageReceipts := make([]*types.ReceiptForStorage, len(receipts)) 341 for i, receipt := range receipts { 342 storageReceipts[i] = (*types.ReceiptForStorage)(receipt) 343 } 344 bytes, err := rlp.EncodeToBytes(storageReceipts) 345 if err != nil { 346 log.Crit("Failed to encode block receipts", "err", err) 347 } 348 // Store the flattened receipt slice 349 if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil { 350 log.Crit("Failed to store block receipts", "err", err) 351 } 352 } 353 354 // DeleteReceipts removes all receipt data associated with a block hash. 355 func DeleteReceipts(db DatabaseDeleter, hash common.Hash, number uint64) { 356 if err := db.Delete(blockReceiptsKey(number, hash)); err != nil { 357 log.Crit("Failed to delete block receipts", "err", err) 358 } 359 } 360 361 // ReadBlock retrieves an entire block corresponding to the hash, assembling it 362 // back from the stored header and body. If either the header or body could not 363 // be retrieved nil is returned. 364 // 365 // Note, due to concurrent download of header and block body the header and thus 366 // canonical hash can be stored in the database but the body data not (yet). 367 func ReadBlock(db DatabaseReader, hash common.Hash, number uint64) *types.Block { 368 header := ReadHeader(db, hash, number) 369 if header == nil { 370 return nil 371 } 372 body := ReadBody(db, hash, number) 373 if body == nil { 374 return nil 375 } 376 return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles, body.Randomness, body.EpochSnarkData) 377 } 378 379 // WriteBlock serializes a block into the database, header and body separately. 380 func WriteBlock(db DatabaseWriter, block *types.Block) { 381 WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) 382 WriteHeader(db, block.Header()) 383 } 384 385 // DeleteBlock removes all block data associated with a hash. 386 func DeleteBlock(db DatabaseDeleter, hash common.Hash, number uint64) { 387 DeleteReceipts(db, hash, number) 388 DeleteHeader(db, hash, number) 389 DeleteBody(db, hash, number) 390 DeleteTd(db, hash, number) 391 } 392 393 // FindCommonAncestor returns the last common ancestor of two block headers 394 func FindCommonAncestor(db DatabaseReader, a, b *types.Header) *types.Header { 395 for bn := b.Number.Uint64(); a.Number.Uint64() > bn; { 396 a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) 397 if a == nil { 398 return nil 399 } 400 } 401 for an := a.Number.Uint64(); an < b.Number.Uint64(); { 402 b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) 403 if b == nil { 404 return nil 405 } 406 } 407 for a.Hash() != b.Hash() { 408 a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) 409 if a == nil { 410 return nil 411 } 412 b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) 413 if b == nil { 414 return nil 415 } 416 } 417 return a 418 }