github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/database/store_geter.go (about) 1 package database 2 3 import ( 4 "encoding/binary" 5 "encoding/json" 6 "fmt" 7 8 dbm "github.com/bytom/bytom/database/leveldb" 9 "github.com/bytom/bytom/protocol/bc" 10 "github.com/bytom/bytom/protocol/bc/types" 11 ) 12 13 const ( 14 colon = byte(0x3a) 15 16 blockHashes byte = iota + 1 17 blockHeader 18 blockTransactions 19 mainChainIndex 20 checkpoint 21 utxo 22 contract 23 ) 24 25 var ( 26 // BlockHashesKeyPrefix key Prefix 27 BlockHashesKeyPrefix = []byte{blockHashes, colon} 28 blockHeaderKeyPrefix = []byte{blockHeader, colon} 29 blockTransactionsKey = []byte{blockTransactions, colon} 30 mainChainIndexKeyPrefix = []byte{mainChainIndex, colon} 31 checkpointKeyPrefix = []byte{checkpoint, colon} 32 UtxoKeyPrefix = []byte{utxo, colon} 33 ContractPrefix = []byte{contract, colon} 34 ) 35 36 func calcMainChainIndexPrefix(height uint64) []byte { 37 buf := [8]byte{} 38 binary.BigEndian.PutUint64(buf[:], height) 39 return append(mainChainIndexKeyPrefix, buf[:]...) 40 } 41 42 // CalcBlockHeaderKey make up header key with prefix + hash 43 func CalcBlockHeaderKey(hash *bc.Hash) []byte { 44 return append(blockHeaderKeyPrefix, hash.Bytes()...) 45 } 46 47 // CalcBlockHashesKey make up hashes key with prefix + height 48 func CalcBlockHashesKey(height uint64) []byte { 49 buf := [8]byte{} 50 binary.BigEndian.PutUint64(buf[:], height) 51 return append(BlockHashesKeyPrefix, buf[:]...) 52 } 53 54 // CalcBlockTransactionsKey make up txs key with prefix + hash 55 func CalcBlockTransactionsKey(hash *bc.Hash) []byte { 56 return append(blockTransactionsKey, hash.Bytes()...) 57 } 58 59 // GetBlockHeader return the block header by given hash 60 func GetBlockHeader(db dbm.DB, hash *bc.Hash) (*types.BlockHeader, error) { 61 binaryBlockHeader := db.Get(CalcBlockHeaderKey(hash)) 62 if binaryBlockHeader == nil { 63 return nil, fmt.Errorf("There are no blockHeader with given hash %s", hash.String()) 64 } 65 66 blockHeader := &types.BlockHeader{} 67 if err := blockHeader.UnmarshalText(binaryBlockHeader); err != nil { 68 return nil, err 69 } 70 return blockHeader, nil 71 } 72 73 // GetBlockTransactions return the block transactions by given hash 74 func GetBlockTransactions(db dbm.DB, hash *bc.Hash) ([]*types.Tx, error) { 75 binaryBlockTxs := db.Get(CalcBlockTransactionsKey(hash)) 76 if binaryBlockTxs == nil { 77 return nil, fmt.Errorf("There are no block transactions with given hash %s", hash.String()) 78 } 79 80 block := &types.Block{} 81 if err := block.UnmarshalText(binaryBlockTxs); err != nil { 82 return nil, err 83 } 84 return block.Transactions, nil 85 } 86 87 // GetBlockHashesByHeight return block hashes by given height 88 func GetBlockHashesByHeight(db dbm.DB, height uint64) ([]*bc.Hash, error) { 89 binaryHashes := db.Get(CalcBlockHashesKey(height)) 90 if binaryHashes == nil { 91 return []*bc.Hash{}, nil 92 } 93 94 hashes := []*bc.Hash{} 95 if err := json.Unmarshal(binaryHashes, &hashes); err != nil { 96 return nil, err 97 } 98 return hashes, nil 99 } 100 101 // GetMainChainHash return BlockHash by given height 102 func GetMainChainHash(db dbm.DB, height uint64) (*bc.Hash, error) { 103 binaryHash := db.Get(calcMainChainIndexPrefix(height)) 104 if binaryHash == nil { 105 return nil, fmt.Errorf("There are no BlockHash with given height %d", height) 106 } 107 108 hash := &bc.Hash{} 109 if err := hash.UnmarshalText(binaryHash); err != nil { 110 return nil, err 111 } 112 113 return hash, nil 114 }