database_util.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  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. ChainConfigNotFoundErr = 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(fmt.Sprintf("failed to decode block header: %v", 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(fmt.Sprintf("invalid block header RLP for hash %x: %v", hash, 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(fmt.Sprintf("invalid block body RLP for hash %x: %v", hash, 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(fmt.Sprintf("invalid block total difficulty RLP for hash %x: %v", hash, 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(fmt.Sprintf("invalid receipt array RLP for hash %x: %v", hash, 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, txHash common.Hash) *types.Receipt {
  261. data, _ := db.Get(append(receiptsPrefix, txHash[:]...))
  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.Debug(fmt.Sprint("GetReceipt 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(fmt.Sprintf("failed to store number to hash mapping into database: %v", 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(fmt.Sprintf("failed to store last header's hash into database: %v", 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(fmt.Sprintf("failed to store last block's hash into database: %v", 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(fmt.Sprintf("failed to store last fast block's hash into database: %v", 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(fmt.Sprintf("failed to store hash to number mapping into database: %v", err))
  313. }
  314. key = append(append(headerPrefix, encNum...), hash...)
  315. if err := db.Put(key, data); err != nil {
  316. log.Crit(fmt.Sprintf("failed to store header into database: %v", err))
  317. }
  318. log.Debug(fmt.Sprintf("stored header #%v [%x…]", header.Number, hash[:4]))
  319. return nil
  320. }
  321. // WriteBody serializes the body of a block into the database.
  322. func WriteBody(db ethdb.Database, hash common.Hash, number uint64, body *types.Body) error {
  323. data, err := rlp.EncodeToBytes(body)
  324. if err != nil {
  325. return err
  326. }
  327. return WriteBodyRLP(db, hash, number, data)
  328. }
  329. // WriteBodyRLP writes a serialized body of a block into the database.
  330. func WriteBodyRLP(db ethdb.Database, hash common.Hash, number uint64, rlp rlp.RawValue) error {
  331. key := append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
  332. if err := db.Put(key, rlp); err != nil {
  333. log.Crit(fmt.Sprintf("failed to store block body into database: %v", err))
  334. }
  335. log.Debug(fmt.Sprintf("stored block body [%x…]", hash.Bytes()[:4]))
  336. return nil
  337. }
  338. // WriteTd serializes the total difficulty of a block into the database.
  339. func WriteTd(db ethdb.Database, hash common.Hash, number uint64, td *big.Int) error {
  340. data, err := rlp.EncodeToBytes(td)
  341. if err != nil {
  342. return err
  343. }
  344. key := append(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...), tdSuffix...)
  345. if err := db.Put(key, data); err != nil {
  346. log.Crit(fmt.Sprintf("failed to store block total difficulty into database: %v", err))
  347. }
  348. log.Debug(fmt.Sprintf("stored block total difficulty [%x…]: %v", hash.Bytes()[:4], td))
  349. return nil
  350. }
  351. // WriteBlock serializes a block into the database, header and body separately.
  352. func WriteBlock(db ethdb.Database, block *types.Block) error {
  353. // Store the body first to retain database consistency
  354. if err := WriteBody(db, block.Hash(), block.NumberU64(), block.Body()); err != nil {
  355. return err
  356. }
  357. // Store the header too, signaling full block ownership
  358. if err := WriteHeader(db, block.Header()); err != nil {
  359. return err
  360. }
  361. return nil
  362. }
  363. // WriteBlockReceipts stores all the transaction receipts belonging to a block
  364. // as a single receipt slice. This is used during chain reorganisations for
  365. // rescheduling dropped transactions.
  366. func WriteBlockReceipts(db ethdb.Database, hash common.Hash, number uint64, receipts types.Receipts) error {
  367. // Convert the receipts into their storage form and serialize them
  368. storageReceipts := make([]*types.ReceiptForStorage, len(receipts))
  369. for i, receipt := range receipts {
  370. storageReceipts[i] = (*types.ReceiptForStorage)(receipt)
  371. }
  372. bytes, err := rlp.EncodeToBytes(storageReceipts)
  373. if err != nil {
  374. return err
  375. }
  376. // Store the flattened receipt slice
  377. key := append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
  378. if err := db.Put(key, bytes); err != nil {
  379. log.Crit(fmt.Sprintf("failed to store block receipts into database: %v", err))
  380. }
  381. log.Debug(fmt.Sprintf("stored block receipts [%x…]", hash.Bytes()[:4]))
  382. return nil
  383. }
  384. // WriteTransactions stores the transactions associated with a specific block
  385. // into the given database. Beside writing the transaction, the function also
  386. // stores a metadata entry along with the transaction, detailing the position
  387. // of this within the blockchain.
  388. func WriteTransactions(db ethdb.Database, block *types.Block) error {
  389. batch := db.NewBatch()
  390. // Iterate over each transaction and encode it with its metadata
  391. for i, tx := range block.Transactions() {
  392. // Encode and queue up the transaction for storage
  393. data, err := rlp.EncodeToBytes(tx)
  394. if err != nil {
  395. return err
  396. }
  397. if err := batch.Put(tx.Hash().Bytes(), data); err != nil {
  398. return err
  399. }
  400. // Encode and queue up the transaction metadata for storage
  401. meta := struct {
  402. BlockHash common.Hash
  403. BlockIndex uint64
  404. Index uint64
  405. }{
  406. BlockHash: block.Hash(),
  407. BlockIndex: block.NumberU64(),
  408. Index: uint64(i),
  409. }
  410. data, err = rlp.EncodeToBytes(meta)
  411. if err != nil {
  412. return err
  413. }
  414. if err := batch.Put(append(tx.Hash().Bytes(), txMetaSuffix...), data); err != nil {
  415. return err
  416. }
  417. }
  418. // Write the scheduled data into the database
  419. if err := batch.Write(); err != nil {
  420. log.Crit(fmt.Sprintf("failed to store transactions into database: %v", err))
  421. }
  422. return nil
  423. }
  424. // WriteReceipt stores a single transaction receipt into the database.
  425. func WriteReceipt(db ethdb.Database, receipt *types.Receipt) error {
  426. storageReceipt := (*types.ReceiptForStorage)(receipt)
  427. data, err := rlp.EncodeToBytes(storageReceipt)
  428. if err != nil {
  429. return err
  430. }
  431. return db.Put(append(receiptsPrefix, receipt.TxHash.Bytes()...), data)
  432. }
  433. // WriteReceipts stores a batch of transaction receipts into the database.
  434. func WriteReceipts(db ethdb.Database, receipts types.Receipts) error {
  435. batch := db.NewBatch()
  436. // Iterate over all the receipts and queue them for database injection
  437. for _, receipt := range receipts {
  438. storageReceipt := (*types.ReceiptForStorage)(receipt)
  439. data, err := rlp.EncodeToBytes(storageReceipt)
  440. if err != nil {
  441. return err
  442. }
  443. if err := batch.Put(append(receiptsPrefix, receipt.TxHash.Bytes()...), data); err != nil {
  444. return err
  445. }
  446. }
  447. // Write the scheduled data into the database
  448. if err := batch.Write(); err != nil {
  449. log.Crit(fmt.Sprintf("failed to store receipts into database: %v", err))
  450. }
  451. return nil
  452. }
  453. // DeleteCanonicalHash removes the number to hash canonical mapping.
  454. func DeleteCanonicalHash(db ethdb.Database, number uint64) {
  455. db.Delete(append(append(headerPrefix, encodeBlockNumber(number)...), numSuffix...))
  456. }
  457. // DeleteHeader removes all block header data associated with a hash.
  458. func DeleteHeader(db ethdb.Database, hash common.Hash, number uint64) {
  459. db.Delete(append(blockHashPrefix, hash.Bytes()...))
  460. db.Delete(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
  461. }
  462. // DeleteBody removes all block body data associated with a hash.
  463. func DeleteBody(db ethdb.Database, hash common.Hash, number uint64) {
  464. db.Delete(append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
  465. }
  466. // DeleteTd removes all block total difficulty data associated with a hash.
  467. func DeleteTd(db ethdb.Database, hash common.Hash, number uint64) {
  468. db.Delete(append(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...), tdSuffix...))
  469. }
  470. // DeleteBlock removes all block data associated with a hash.
  471. func DeleteBlock(db ethdb.Database, hash common.Hash, number uint64) {
  472. DeleteBlockReceipts(db, hash, number)
  473. DeleteHeader(db, hash, number)
  474. DeleteBody(db, hash, number)
  475. DeleteTd(db, hash, number)
  476. }
  477. // DeleteBlockReceipts removes all receipt data associated with a block hash.
  478. func DeleteBlockReceipts(db ethdb.Database, hash common.Hash, number uint64) {
  479. db.Delete(append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
  480. }
  481. // DeleteTransaction removes all transaction data associated with a hash.
  482. func DeleteTransaction(db ethdb.Database, hash common.Hash) {
  483. db.Delete(hash.Bytes())
  484. db.Delete(append(hash.Bytes(), txMetaSuffix...))
  485. }
  486. // DeleteReceipt removes all receipt data associated with a transaction hash.
  487. func DeleteReceipt(db ethdb.Database, hash common.Hash) {
  488. db.Delete(append(receiptsPrefix, hash.Bytes()...))
  489. }
  490. // [deprecated by the header/block split, remove eventually]
  491. // GetBlockByHashOld returns the old combined block corresponding to the hash
  492. // or nil if not found. This method is only used by the upgrade mechanism to
  493. // access the old combined block representation. It will be dropped after the
  494. // network transitions to eth/63.
  495. func GetBlockByHashOld(db ethdb.Database, hash common.Hash) *types.Block {
  496. data, _ := db.Get(append(oldBlockHashPrefix, hash[:]...))
  497. if len(data) == 0 {
  498. return nil
  499. }
  500. var block types.StorageBlock
  501. if err := rlp.Decode(bytes.NewReader(data), &block); err != nil {
  502. log.Error(fmt.Sprintf("invalid block RLP for hash %x: %v", hash, err))
  503. return nil
  504. }
  505. return (*types.Block)(&block)
  506. }
  507. // returns a formatted MIP mapped key by adding prefix, canonical number and level
  508. //
  509. // ex. fn(98, 1000) = (prefix || 1000 || 0)
  510. func mipmapKey(num, level uint64) []byte {
  511. lkey := make([]byte, 8)
  512. binary.BigEndian.PutUint64(lkey, level)
  513. key := new(big.Int).SetUint64(num / level * level)
  514. return append(mipmapPre, append(lkey, key.Bytes()...)...)
  515. }
  516. // WriteMapmapBloom writes each address included in the receipts' logs to the
  517. // MIP bloom bin.
  518. func WriteMipmapBloom(db ethdb.Database, number uint64, receipts types.Receipts) error {
  519. mipmapBloomMu.Lock()
  520. defer mipmapBloomMu.Unlock()
  521. batch := db.NewBatch()
  522. for _, level := range MIPMapLevels {
  523. key := mipmapKey(number, level)
  524. bloomDat, _ := db.Get(key)
  525. bloom := types.BytesToBloom(bloomDat)
  526. for _, receipt := range receipts {
  527. for _, log := range receipt.Logs {
  528. bloom.Add(log.Address.Big())
  529. }
  530. }
  531. batch.Put(key, bloom.Bytes())
  532. }
  533. if err := batch.Write(); err != nil {
  534. return fmt.Errorf("mipmap write fail for: %d: %v", number, err)
  535. }
  536. return nil
  537. }
  538. // GetMipmapBloom returns a bloom filter using the number and level as input
  539. // parameters. For available levels see MIPMapLevels.
  540. func GetMipmapBloom(db ethdb.Database, number, level uint64) types.Bloom {
  541. bloomDat, _ := db.Get(mipmapKey(number, level))
  542. return types.BytesToBloom(bloomDat)
  543. }
  544. // PreimageTable returns a Database instance with the key prefix for preimage entries.
  545. func PreimageTable(db ethdb.Database) ethdb.Database {
  546. return ethdb.NewTable(db, preimagePrefix)
  547. }
  548. // WritePreimages writes the provided set of preimages to the database. `number` is the
  549. // current block number, and is used for debug messages only.
  550. func WritePreimages(db ethdb.Database, number uint64, preimages map[common.Hash][]byte) error {
  551. table := PreimageTable(db)
  552. batch := table.NewBatch()
  553. hitCount := 0
  554. for hash, preimage := range preimages {
  555. if _, err := table.Get(hash.Bytes()); err != nil {
  556. batch.Put(hash.Bytes(), preimage)
  557. hitCount += 1
  558. }
  559. }
  560. preimageCounter.Inc(int64(len(preimages)))
  561. preimageHitCounter.Inc(int64(hitCount))
  562. if hitCount > 0 {
  563. if err := batch.Write(); err != nil {
  564. return fmt.Errorf("preimage write fail for block %d: %v", number, err)
  565. }
  566. log.Debug(fmt.Sprintf("%d preimages in block %d, including %d new", len(preimages), number, hitCount))
  567. }
  568. return nil
  569. }
  570. // GetBlockChainVersion reads the version number from db.
  571. func GetBlockChainVersion(db ethdb.Database) int {
  572. var vsn uint
  573. enc, _ := db.Get([]byte("BlockchainVersion"))
  574. rlp.DecodeBytes(enc, &vsn)
  575. return int(vsn)
  576. }
  577. // WriteBlockChainVersion writes vsn as the version number to db.
  578. func WriteBlockChainVersion(db ethdb.Database, vsn int) {
  579. enc, _ := rlp.EncodeToBytes(uint(vsn))
  580. db.Put([]byte("BlockchainVersion"), enc)
  581. }
  582. // WriteChainConfig writes the chain config settings to the database.
  583. func WriteChainConfig(db ethdb.Database, hash common.Hash, cfg *params.ChainConfig) error {
  584. // short circuit and ignore if nil config. GetChainConfig
  585. // will return a default.
  586. if cfg == nil {
  587. return nil
  588. }
  589. jsonChainConfig, err := json.Marshal(cfg)
  590. if err != nil {
  591. return err
  592. }
  593. return db.Put(append(configPrefix, hash[:]...), jsonChainConfig)
  594. }
  595. // GetChainConfig will fetch the network settings based on the given hash.
  596. func GetChainConfig(db ethdb.Database, hash common.Hash) (*params.ChainConfig, error) {
  597. jsonChainConfig, _ := db.Get(append(configPrefix, hash[:]...))
  598. if len(jsonChainConfig) == 0 {
  599. return nil, ChainConfigNotFoundErr
  600. }
  601. var config params.ChainConfig
  602. if err := json.Unmarshal(jsonChainConfig, &config); err != nil {
  603. return nil, err
  604. }
  605. return &config, nil
  606. }
  607. // FindCommonAncestor returns the last common ancestor of two block headers
  608. func FindCommonAncestor(db ethdb.Database, a, b *types.Header) *types.Header {
  609. for bn := b.Number.Uint64(); a.Number.Uint64() > bn; {
  610. a = GetHeader(db, a.ParentHash, a.Number.Uint64()-1)
  611. if a == nil {
  612. return nil
  613. }
  614. }
  615. for an := a.Number.Uint64(); an < b.Number.Uint64(); {
  616. b = GetHeader(db, b.ParentHash, b.Number.Uint64()-1)
  617. if b == nil {
  618. return nil
  619. }
  620. }
  621. for a.Hash() != b.Hash() {
  622. a = GetHeader(db, a.ParentHash, a.Number.Uint64()-1)
  623. if a == nil {
  624. return nil
  625. }
  626. b = GetHeader(db, b.ParentHash, b.Number.Uint64()-1)
  627. if b == nil {
  628. return nil
  629. }
  630. }
  631. return a
  632. }