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