database_util.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. // Copyright 2015 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. package core
  17. import (
  18. "bytes"
  19. "encoding/binary"
  20. "encoding/json"
  21. "errors"
  22. "fmt"
  23. "math/big"
  24. "sync"
  25. "github.com/ethereum/go-ethereum/common"
  26. "github.com/ethereum/go-ethereum/core/types"
  27. "github.com/ethereum/go-ethereum/ethdb"
  28. "github.com/ethereum/go-ethereum/log"
  29. "github.com/ethereum/go-ethereum/metrics"
  30. "github.com/ethereum/go-ethereum/params"
  31. "github.com/ethereum/go-ethereum/rlp"
  32. )
  33. var (
  34. headHeaderKey = []byte("LastHeader")
  35. headBlockKey = []byte("LastBlock")
  36. headFastKey = []byte("LastFast")
  37. headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header
  38. tdSuffix = []byte("t") // headerPrefix + num (uint64 big endian) + hash + tdSuffix -> td
  39. numSuffix = []byte("n") // headerPrefix + num (uint64 big endian) + numSuffix -> hash
  40. blockHashPrefix = []byte("H") // blockHashPrefix + hash -> num (uint64 big endian)
  41. bodyPrefix = []byte("b") // bodyPrefix + num (uint64 big endian) + hash -> block body
  42. blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts
  43. preimagePrefix = "secure-key-" // preimagePrefix + hash -> preimage
  44. txMetaSuffix = []byte{0x01}
  45. receiptsPrefix = []byte("receipts-")
  46. mipmapPre = []byte("mipmap-log-bloom-")
  47. MIPMapLevels = []uint64{1000000, 500000, 100000, 50000, 1000}
  48. configPrefix = []byte("ethereum-config-") // config prefix for the db
  49. // used by old (non-sequential keys) db, now only used for conversion
  50. oldBlockPrefix = []byte("block-")
  51. oldHeaderSuffix = []byte("-header")
  52. oldTdSuffix = []byte("-td") // headerPrefix + num (uint64 big endian) + hash + tdSuffix -> td
  53. oldBodySuffix = []byte("-body")
  54. oldBlockNumPrefix = []byte("block-num-")
  55. oldBlockReceiptsPrefix = []byte("receipts-block-")
  56. oldBlockHashPrefix = []byte("block-hash-") // [deprecated by the header/block split, remove eventually]
  57. ErrChainConfigNotFound = errors.New("ChainConfig not found") // general config not found error
  58. mipmapBloomMu sync.Mutex // protect against race condition when updating mipmap blooms
  59. preimageCounter = metrics.NewCounter("db/preimage/total")
  60. preimageHitCounter = metrics.NewCounter("db/preimage/hits")
  61. )
  62. // encodeBlockNumber encodes a block number as big endian uint64
  63. func encodeBlockNumber(number uint64) []byte {
  64. enc := make([]byte, 8)
  65. binary.BigEndian.PutUint64(enc, number)
  66. return enc
  67. }
  68. // GetCanonicalHash retrieves a hash assigned to a canonical block number.
  69. func GetCanonicalHash(db ethdb.Database, number uint64) common.Hash {
  70. data, _ := db.Get(append(append(headerPrefix, encodeBlockNumber(number)...), numSuffix...))
  71. if len(data) == 0 {
  72. data, _ = db.Get(append(oldBlockNumPrefix, big.NewInt(int64(number)).Bytes()...))
  73. if len(data) == 0 {
  74. return common.Hash{}
  75. }
  76. }
  77. return common.BytesToHash(data)
  78. }
  79. // missingNumber is returned by GetBlockNumber if no header with the
  80. // given block hash has been stored in the database
  81. const missingNumber = uint64(0xffffffffffffffff)
  82. // GetBlockNumber returns the block number assigned to a block hash
  83. // if the corresponding header is present in the database
  84. func GetBlockNumber(db ethdb.Database, hash common.Hash) uint64 {
  85. data, _ := db.Get(append(blockHashPrefix, hash.Bytes()...))
  86. if len(data) != 8 {
  87. data, _ := db.Get(append(append(oldBlockPrefix, hash.Bytes()...), oldHeaderSuffix...))
  88. if len(data) == 0 {
  89. return missingNumber
  90. }
  91. header := new(types.Header)
  92. if err := rlp.Decode(bytes.NewReader(data), header); err != nil {
  93. log.Crit("Failed to decode block header", "err", err)
  94. }
  95. return header.Number.Uint64()
  96. }
  97. return binary.BigEndian.Uint64(data)
  98. }
  99. // GetHeadHeaderHash retrieves the hash of the current canonical head block's
  100. // header. The difference between this and GetHeadBlockHash is that whereas the
  101. // last block hash is only updated upon a full block import, the last header
  102. // hash is updated already at header import, allowing head tracking for the
  103. // light synchronization mechanism.
  104. func GetHeadHeaderHash(db ethdb.Database) common.Hash {
  105. data, _ := db.Get(headHeaderKey)
  106. if len(data) == 0 {
  107. return common.Hash{}
  108. }
  109. return common.BytesToHash(data)
  110. }
  111. // GetHeadBlockHash retrieves the hash of the current canonical head block.
  112. func GetHeadBlockHash(db ethdb.Database) common.Hash {
  113. data, _ := db.Get(headBlockKey)
  114. if len(data) == 0 {
  115. return common.Hash{}
  116. }
  117. return common.BytesToHash(data)
  118. }
  119. // GetHeadFastBlockHash retrieves the hash of the current canonical head block during
  120. // fast synchronization. The difference between this and GetHeadBlockHash is that
  121. // whereas the last block hash is only updated upon a full block import, the last
  122. // fast hash is updated when importing pre-processed blocks.
  123. func GetHeadFastBlockHash(db ethdb.Database) common.Hash {
  124. data, _ := db.Get(headFastKey)
  125. if len(data) == 0 {
  126. return common.Hash{}
  127. }
  128. return common.BytesToHash(data)
  129. }
  130. // GetHeaderRLP retrieves a block header in its raw RLP database encoding, or nil
  131. // if the header's not found.
  132. func GetHeaderRLP(db ethdb.Database, hash common.Hash, number uint64) rlp.RawValue {
  133. data, _ := db.Get(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
  134. if len(data) == 0 {
  135. data, _ = db.Get(append(append(oldBlockPrefix, hash.Bytes()...), oldHeaderSuffix...))
  136. }
  137. return data
  138. }
  139. // GetHeader retrieves the block header corresponding to the hash, nil if none
  140. // found.
  141. func GetHeader(db ethdb.Database, hash common.Hash, number uint64) *types.Header {
  142. data := GetHeaderRLP(db, hash, number)
  143. if len(data) == 0 {
  144. return nil
  145. }
  146. header := new(types.Header)
  147. if err := rlp.Decode(bytes.NewReader(data), header); err != nil {
  148. log.Error("Invalid block header RLP", "hash", hash, "err", err)
  149. return nil
  150. }
  151. return header
  152. }
  153. // GetBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
  154. func GetBodyRLP(db ethdb.Database, hash common.Hash, number uint64) rlp.RawValue {
  155. data, _ := db.Get(append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
  156. if len(data) == 0 {
  157. data, _ = db.Get(append(append(oldBlockPrefix, hash.Bytes()...), oldBodySuffix...))
  158. }
  159. return data
  160. }
  161. // GetBody retrieves the block body (transactons, uncles) corresponding to the
  162. // hash, nil if none found.
  163. func GetBody(db ethdb.Database, hash common.Hash, number uint64) *types.Body {
  164. data := GetBodyRLP(db, hash, number)
  165. if len(data) == 0 {
  166. return nil
  167. }
  168. body := new(types.Body)
  169. if err := rlp.Decode(bytes.NewReader(data), body); err != nil {
  170. log.Error("Invalid block body RLP", "hash", hash, "err", err)
  171. return nil
  172. }
  173. return body
  174. }
  175. // GetTd retrieves a block's total difficulty corresponding to the hash, nil if
  176. // none found.
  177. func GetTd(db ethdb.Database, hash common.Hash, number uint64) *big.Int {
  178. data, _ := db.Get(append(append(append(headerPrefix, encodeBlockNumber(number)...), hash[:]...), tdSuffix...))
  179. if len(data) == 0 {
  180. data, _ = db.Get(append(append(oldBlockPrefix, hash.Bytes()...), oldTdSuffix...))
  181. if len(data) == 0 {
  182. return nil
  183. }
  184. }
  185. td := new(big.Int)
  186. if err := rlp.Decode(bytes.NewReader(data), td); err != nil {
  187. log.Error("Invalid block total difficulty RLP", "hash", hash, "err", err)
  188. return nil
  189. }
  190. return td
  191. }
  192. // GetBlock retrieves an entire block corresponding to the hash, assembling it
  193. // back from the stored header and body. If either the header or body could not
  194. // be retrieved nil is returned.
  195. //
  196. // Note, due to concurrent download of header and block body the header and thus
  197. // canonical hash can be stored in the database but the body data not (yet).
  198. func GetBlock(db ethdb.Database, hash common.Hash, number uint64) *types.Block {
  199. // Retrieve the block header and body contents
  200. header := GetHeader(db, hash, number)
  201. if header == nil {
  202. return nil
  203. }
  204. body := GetBody(db, hash, number)
  205. if body == nil {
  206. return nil
  207. }
  208. // Reassemble the block and return
  209. return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles)
  210. }
  211. // GetBlockReceipts retrieves the receipts generated by the transactions included
  212. // in a block given by its hash.
  213. func GetBlockReceipts(db ethdb.Database, hash common.Hash, number uint64) types.Receipts {
  214. data, _ := db.Get(append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash[:]...))
  215. if len(data) == 0 {
  216. data, _ = db.Get(append(oldBlockReceiptsPrefix, hash.Bytes()...))
  217. if len(data) == 0 {
  218. return nil
  219. }
  220. }
  221. storageReceipts := []*types.ReceiptForStorage{}
  222. if err := rlp.DecodeBytes(data, &storageReceipts); err != nil {
  223. log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
  224. return nil
  225. }
  226. receipts := make(types.Receipts, len(storageReceipts))
  227. for i, receipt := range storageReceipts {
  228. receipts[i] = (*types.Receipt)(receipt)
  229. }
  230. return receipts
  231. }
  232. // GetTransaction retrieves a specific transaction from the database, along with
  233. // its added positional metadata.
  234. func GetTransaction(db ethdb.Database, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) {
  235. // Retrieve the transaction itself from the database
  236. data, _ := db.Get(hash.Bytes())
  237. if len(data) == 0 {
  238. return nil, common.Hash{}, 0, 0
  239. }
  240. var tx types.Transaction
  241. if err := rlp.DecodeBytes(data, &tx); err != nil {
  242. return nil, common.Hash{}, 0, 0
  243. }
  244. // Retrieve the blockchain positional metadata
  245. data, _ = db.Get(append(hash.Bytes(), txMetaSuffix...))
  246. if len(data) == 0 {
  247. return nil, common.Hash{}, 0, 0
  248. }
  249. var meta struct {
  250. BlockHash common.Hash
  251. BlockIndex uint64
  252. Index uint64
  253. }
  254. if err := rlp.DecodeBytes(data, &meta); err != nil {
  255. return nil, common.Hash{}, 0, 0
  256. }
  257. return &tx, meta.BlockHash, meta.BlockIndex, meta.Index
  258. }
  259. // GetReceipt returns a receipt by hash
  260. func GetReceipt(db ethdb.Database, hash common.Hash) *types.Receipt {
  261. data, _ := db.Get(append(receiptsPrefix, hash[:]...))
  262. if len(data) == 0 {
  263. return nil
  264. }
  265. var receipt types.ReceiptForStorage
  266. err := rlp.DecodeBytes(data, &receipt)
  267. if err != nil {
  268. log.Error("Invalid receipt RLP", "hash", hash, "err", err)
  269. }
  270. return (*types.Receipt)(&receipt)
  271. }
  272. // WriteCanonicalHash stores the canonical hash for the given block number.
  273. func WriteCanonicalHash(db ethdb.Database, hash common.Hash, number uint64) error {
  274. key := append(append(headerPrefix, encodeBlockNumber(number)...), numSuffix...)
  275. if err := db.Put(key, hash.Bytes()); err != nil {
  276. log.Crit("Failed to store number to hash mapping", "err", err)
  277. }
  278. return nil
  279. }
  280. // WriteHeadHeaderHash stores the head header's hash.
  281. func WriteHeadHeaderHash(db ethdb.Database, hash common.Hash) error {
  282. if err := db.Put(headHeaderKey, hash.Bytes()); err != nil {
  283. log.Crit("Failed to store last header's hash", "err", err)
  284. }
  285. return nil
  286. }
  287. // WriteHeadBlockHash stores the head block's hash.
  288. func WriteHeadBlockHash(db ethdb.Database, hash common.Hash) error {
  289. if err := db.Put(headBlockKey, hash.Bytes()); err != nil {
  290. log.Crit("Failed to store last block's hash", "err", err)
  291. }
  292. return nil
  293. }
  294. // WriteHeadFastBlockHash stores the fast head block's hash.
  295. func WriteHeadFastBlockHash(db ethdb.Database, hash common.Hash) error {
  296. if err := db.Put(headFastKey, hash.Bytes()); err != nil {
  297. log.Crit("Failed to store last fast block's hash", "err", err)
  298. }
  299. return nil
  300. }
  301. // WriteHeader serializes a block header into the database.
  302. func WriteHeader(db ethdb.Database, header *types.Header) error {
  303. data, err := rlp.EncodeToBytes(header)
  304. if err != nil {
  305. return err
  306. }
  307. hash := header.Hash().Bytes()
  308. num := header.Number.Uint64()
  309. encNum := encodeBlockNumber(num)
  310. key := append(blockHashPrefix, hash...)
  311. if err := db.Put(key, encNum); err != nil {
  312. log.Crit("Failed to store hash to number mapping", "err", err)
  313. }
  314. key = append(append(headerPrefix, encNum...), hash...)
  315. if err := db.Put(key, data); err != nil {
  316. log.Crit("Failed to store header", "err", err)
  317. }
  318. return nil
  319. }
  320. // WriteBody serializes the body of a block into the database.
  321. func WriteBody(db ethdb.Database, hash common.Hash, number uint64, body *types.Body) error {
  322. data, err := rlp.EncodeToBytes(body)
  323. if err != nil {
  324. return err
  325. }
  326. return WriteBodyRLP(db, hash, number, data)
  327. }
  328. // WriteBodyRLP writes a serialized body of a block into the database.
  329. func WriteBodyRLP(db ethdb.Database, hash common.Hash, number uint64, rlp rlp.RawValue) error {
  330. key := append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
  331. if err := db.Put(key, rlp); err != nil {
  332. log.Crit("Failed to store block body", "err", err)
  333. }
  334. return nil
  335. }
  336. // WriteTd serializes the total difficulty of a block into the database.
  337. func WriteTd(db ethdb.Database, hash common.Hash, number uint64, td *big.Int) error {
  338. data, err := rlp.EncodeToBytes(td)
  339. if err != nil {
  340. return err
  341. }
  342. key := append(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...), tdSuffix...)
  343. if err := db.Put(key, data); err != nil {
  344. log.Crit("Failed to store block total difficulty", "err", err)
  345. }
  346. return nil
  347. }
  348. // WriteBlock serializes a block into the database, header and body separately.
  349. func WriteBlock(db ethdb.Database, block *types.Block) error {
  350. // Store the body first to retain database consistency
  351. if err := WriteBody(db, block.Hash(), block.NumberU64(), block.Body()); err != nil {
  352. return err
  353. }
  354. // Store the header too, signaling full block ownership
  355. if err := WriteHeader(db, block.Header()); err != nil {
  356. return err
  357. }
  358. return nil
  359. }
  360. // WriteBlockReceipts stores all the transaction receipts belonging to a block
  361. // as a single receipt slice. This is used during chain reorganisations for
  362. // rescheduling dropped transactions.
  363. func WriteBlockReceipts(db ethdb.Database, hash common.Hash, number uint64, receipts types.Receipts) error {
  364. // Convert the receipts into their storage form and serialize them
  365. storageReceipts := make([]*types.ReceiptForStorage, len(receipts))
  366. for i, receipt := range receipts {
  367. storageReceipts[i] = (*types.ReceiptForStorage)(receipt)
  368. }
  369. bytes, err := rlp.EncodeToBytes(storageReceipts)
  370. if err != nil {
  371. return err
  372. }
  373. // Store the flattened receipt slice
  374. key := append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
  375. if err := db.Put(key, bytes); err != nil {
  376. log.Crit("Failed to store block receipts", "err", err)
  377. }
  378. return nil
  379. }
  380. // WriteTransactions stores the transactions associated with a specific block
  381. // into the given database. Beside writing the transaction, the function also
  382. // stores a metadata entry along with the transaction, detailing the position
  383. // of this within the blockchain.
  384. func WriteTransactions(db ethdb.Database, block *types.Block) error {
  385. batch := db.NewBatch()
  386. // Iterate over each transaction and encode it with its metadata
  387. for i, tx := range block.Transactions() {
  388. // Encode and queue up the transaction for storage
  389. data, err := rlp.EncodeToBytes(tx)
  390. if err != nil {
  391. return err
  392. }
  393. if err = batch.Put(tx.Hash().Bytes(), data); err != nil {
  394. return err
  395. }
  396. // Encode and queue up the transaction metadata for storage
  397. meta := struct {
  398. BlockHash common.Hash
  399. BlockIndex uint64
  400. Index uint64
  401. }{
  402. BlockHash: block.Hash(),
  403. BlockIndex: block.NumberU64(),
  404. Index: uint64(i),
  405. }
  406. data, err = rlp.EncodeToBytes(meta)
  407. if err != nil {
  408. return err
  409. }
  410. if err := batch.Put(append(tx.Hash().Bytes(), txMetaSuffix...), data); err != nil {
  411. return err
  412. }
  413. }
  414. // Write the scheduled data into the database
  415. if err := batch.Write(); err != nil {
  416. log.Crit("Failed to store transactions", "err", err)
  417. }
  418. return nil
  419. }
  420. // WriteReceipt stores a single transaction receipt into the database.
  421. func WriteReceipt(db ethdb.Database, receipt *types.Receipt) error {
  422. storageReceipt := (*types.ReceiptForStorage)(receipt)
  423. data, err := rlp.EncodeToBytes(storageReceipt)
  424. if err != nil {
  425. return err
  426. }
  427. return db.Put(append(receiptsPrefix, receipt.TxHash.Bytes()...), data)
  428. }
  429. // WriteReceipts stores a batch of transaction receipts into the database.
  430. func WriteReceipts(db ethdb.Database, receipts types.Receipts) error {
  431. batch := db.NewBatch()
  432. // Iterate over all the receipts and queue them for database injection
  433. for _, receipt := range receipts {
  434. storageReceipt := (*types.ReceiptForStorage)(receipt)
  435. data, err := rlp.EncodeToBytes(storageReceipt)
  436. if err != nil {
  437. return err
  438. }
  439. if err := batch.Put(append(receiptsPrefix, receipt.TxHash.Bytes()...), data); err != nil {
  440. return err
  441. }
  442. }
  443. // Write the scheduled data into the database
  444. if err := batch.Write(); err != nil {
  445. log.Crit("Failed to store receipts", "err", err)
  446. }
  447. return nil
  448. }
  449. // DeleteCanonicalHash removes the number to hash canonical mapping.
  450. func DeleteCanonicalHash(db ethdb.Database, number uint64) {
  451. db.Delete(append(append(headerPrefix, encodeBlockNumber(number)...), numSuffix...))
  452. }
  453. // DeleteHeader removes all block header data associated with a hash.
  454. func DeleteHeader(db ethdb.Database, hash common.Hash, number uint64) {
  455. db.Delete(append(blockHashPrefix, hash.Bytes()...))
  456. db.Delete(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
  457. }
  458. // DeleteBody removes all block body data associated with a hash.
  459. func DeleteBody(db ethdb.Database, hash common.Hash, number uint64) {
  460. db.Delete(append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
  461. }
  462. // DeleteTd removes all block total difficulty data associated with a hash.
  463. func DeleteTd(db ethdb.Database, hash common.Hash, number uint64) {
  464. db.Delete(append(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...), tdSuffix...))
  465. }
  466. // DeleteBlock removes all block data associated with a hash.
  467. func DeleteBlock(db ethdb.Database, hash common.Hash, number uint64) {
  468. DeleteBlockReceipts(db, hash, number)
  469. DeleteHeader(db, hash, number)
  470. DeleteBody(db, hash, number)
  471. DeleteTd(db, hash, number)
  472. }
  473. // DeleteBlockReceipts removes all receipt data associated with a block hash.
  474. func DeleteBlockReceipts(db ethdb.Database, hash common.Hash, number uint64) {
  475. db.Delete(append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
  476. }
  477. // DeleteTransaction removes all transaction data associated with a hash.
  478. func DeleteTransaction(db ethdb.Database, hash common.Hash) {
  479. db.Delete(hash.Bytes())
  480. db.Delete(append(hash.Bytes(), txMetaSuffix...))
  481. }
  482. // DeleteReceipt removes all receipt data associated with a transaction hash.
  483. func DeleteReceipt(db ethdb.Database, hash common.Hash) {
  484. db.Delete(append(receiptsPrefix, hash.Bytes()...))
  485. }
  486. // returns a formatted MIP mapped key by adding prefix, canonical number and level
  487. //
  488. // ex. fn(98, 1000) = (prefix || 1000 || 0)
  489. func mipmapKey(num, level uint64) []byte {
  490. lkey := make([]byte, 8)
  491. binary.BigEndian.PutUint64(lkey, level)
  492. key := new(big.Int).SetUint64(num / level * level)
  493. return append(mipmapPre, append(lkey, key.Bytes()...)...)
  494. }
  495. // WriteMipmapBloom writes each address included in the receipts' logs to the
  496. // MIP bloom bin.
  497. func WriteMipmapBloom(db ethdb.Database, number uint64, receipts types.Receipts) error {
  498. mipmapBloomMu.Lock()
  499. defer mipmapBloomMu.Unlock()
  500. batch := db.NewBatch()
  501. for _, level := range MIPMapLevels {
  502. key := mipmapKey(number, level)
  503. bloomDat, _ := db.Get(key)
  504. bloom := types.BytesToBloom(bloomDat)
  505. for _, receipt := range receipts {
  506. for _, log := range receipt.Logs {
  507. bloom.Add(log.Address.Big())
  508. }
  509. }
  510. batch.Put(key, bloom.Bytes())
  511. }
  512. if err := batch.Write(); err != nil {
  513. return fmt.Errorf("mipmap write fail for: %d: %v", number, err)
  514. }
  515. return nil
  516. }
  517. // GetMipmapBloom returns a bloom filter using the number and level as input
  518. // parameters. For available levels see MIPMapLevels.
  519. func GetMipmapBloom(db ethdb.Database, number, level uint64) types.Bloom {
  520. bloomDat, _ := db.Get(mipmapKey(number, level))
  521. return types.BytesToBloom(bloomDat)
  522. }
  523. // PreimageTable returns a Database instance with the key prefix for preimage entries.
  524. func PreimageTable(db ethdb.Database) ethdb.Database {
  525. return ethdb.NewTable(db, preimagePrefix)
  526. }
  527. // WritePreimages writes the provided set of preimages to the database. `number` is the
  528. // current block number, and is used for debug messages only.
  529. func WritePreimages(db ethdb.Database, number uint64, preimages map[common.Hash][]byte) error {
  530. table := PreimageTable(db)
  531. batch := table.NewBatch()
  532. hitCount := 0
  533. for hash, preimage := range preimages {
  534. if _, err := table.Get(hash.Bytes()); err != nil {
  535. batch.Put(hash.Bytes(), preimage)
  536. hitCount++
  537. }
  538. }
  539. preimageCounter.Inc(int64(len(preimages)))
  540. preimageHitCounter.Inc(int64(hitCount))
  541. if hitCount > 0 {
  542. if err := batch.Write(); err != nil {
  543. return fmt.Errorf("preimage write fail for block %d: %v", number, err)
  544. }
  545. }
  546. return nil
  547. }
  548. // GetBlockChainVersion reads the version number from db.
  549. func GetBlockChainVersion(db ethdb.Database) int {
  550. var vsn uint
  551. enc, _ := db.Get([]byte("BlockchainVersion"))
  552. rlp.DecodeBytes(enc, &vsn)
  553. return int(vsn)
  554. }
  555. // WriteBlockChainVersion writes vsn as the version number to db.
  556. func WriteBlockChainVersion(db ethdb.Database, vsn int) {
  557. enc, _ := rlp.EncodeToBytes(uint(vsn))
  558. db.Put([]byte("BlockchainVersion"), enc)
  559. }
  560. // WriteChainConfig writes the chain config settings to the database.
  561. func WriteChainConfig(db ethdb.Database, hash common.Hash, cfg *params.ChainConfig) error {
  562. // short circuit and ignore if nil config. GetChainConfig
  563. // will return a default.
  564. if cfg == nil {
  565. return nil
  566. }
  567. jsonChainConfig, err := json.Marshal(cfg)
  568. if err != nil {
  569. return err
  570. }
  571. return db.Put(append(configPrefix, hash[:]...), jsonChainConfig)
  572. }
  573. // GetChainConfig will fetch the network settings based on the given hash.
  574. func GetChainConfig(db ethdb.Database, hash common.Hash) (*params.ChainConfig, error) {
  575. jsonChainConfig, _ := db.Get(append(configPrefix, hash[:]...))
  576. if len(jsonChainConfig) == 0 {
  577. return nil, ErrChainConfigNotFound
  578. }
  579. var config params.ChainConfig
  580. if err := json.Unmarshal(jsonChainConfig, &config); err != nil {
  581. return nil, err
  582. }
  583. return &config, nil
  584. }
  585. // FindCommonAncestor returns the last common ancestor of two block headers
  586. func FindCommonAncestor(db ethdb.Database, a, b *types.Header) *types.Header {
  587. for bn := b.Number.Uint64(); a.Number.Uint64() > bn; {
  588. a = GetHeader(db, a.ParentHash, a.Number.Uint64()-1)
  589. if a == nil {
  590. return nil
  591. }
  592. }
  593. for an := a.Number.Uint64(); an < b.Number.Uint64(); {
  594. b = GetHeader(db, b.ParentHash, b.Number.Uint64()-1)
  595. if b == nil {
  596. return nil
  597. }
  598. }
  599. for a.Hash() != b.Hash() {
  600. a = GetHeader(db, a.ParentHash, a.Number.Uint64()-1)
  601. if a == nil {
  602. return nil
  603. }
  604. b = GetHeader(db, b.ParentHash, b.Number.Uint64()-1)
  605. if b == nil {
  606. return nil
  607. }
  608. }
  609. return a
  610. }