github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/light/odr.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:39</date>
    10  //</624450096498479104>
    11  
    12  
    13  //package light实现可按需检索的状态和链对象
    14  //对于以太坊Light客户端。
    15  package light
    16  
    17  import (
    18  	"context"
    19  	"errors"
    20  	"math/big"
    21  
    22  	"github.com/ethereum/go-ethereum/common"
    23  	"github.com/ethereum/go-ethereum/core"
    24  	"github.com/ethereum/go-ethereum/core/rawdb"
    25  	"github.com/ethereum/go-ethereum/core/types"
    26  	"github.com/ethereum/go-ethereum/ethdb"
    27  )
    28  
    29  //noodr是当odr
    30  //不需要服务。
    31  var NoOdr = context.Background()
    32  
    33  //如果没有能够为排队请求提供服务的对等方可用,则返回errnopeers。
    34  var ErrNoPeers = errors.New("no suitable peers available")
    35  
    36  //odr backend是后端服务的接口,用于处理odr检索类型
    37  type OdrBackend interface {
    38  	Database() ethdb.Database
    39  	ChtIndexer() *core.ChainIndexer
    40  	BloomTrieIndexer() *core.ChainIndexer
    41  	BloomIndexer() *core.ChainIndexer
    42  	Retrieve(ctx context.Context, req OdrRequest) error
    43  	IndexerConfig() *IndexerConfig
    44  }
    45  
    46  //ODRRequest是一个用于检索请求的接口
    47  type OdrRequest interface {
    48  	StoreResult(db ethdb.Database)
    49  }
    50  
    51  //trieid标识状态或帐户存储trie
    52  type TrieID struct {
    53  	BlockHash, Root common.Hash
    54  	BlockNumber     uint64
    55  	AccKey          []byte
    56  }
    57  
    58  //state trieid返回属于某个块的state trie的trieid
    59  //标题。
    60  func StateTrieID(header *types.Header) *TrieID {
    61  	return &TrieID{
    62  		BlockHash:   header.Hash(),
    63  		BlockNumber: header.Number.Uint64(),
    64  		AccKey:      nil,
    65  		Root:        header.Root,
    66  	}
    67  }
    68  
    69  //storage trieid返回给定帐户上合同存储trie的trieid
    70  //一个给定的国家的。它还需要trie的根散列
    71  //检查Merkle校样。
    72  func StorageTrieID(state *TrieID, addrHash, root common.Hash) *TrieID {
    73  	return &TrieID{
    74  		BlockHash:   state.BlockHash,
    75  		BlockNumber: state.BlockNumber,
    76  		AccKey:      addrHash[:],
    77  		Root:        root,
    78  	}
    79  }
    80  
    81  //trieRequest是状态/存储trie项的ODR请求类型
    82  type TrieRequest struct {
    83  	OdrRequest
    84  	Id    *TrieID
    85  	Key   []byte
    86  	Proof *NodeSet
    87  }
    88  
    89  //storeresult将检索到的数据存储在本地数据库中
    90  func (req *TrieRequest) StoreResult(db ethdb.Database) {
    91  	req.Proof.Store(db)
    92  }
    93  
    94  //code request是用于检索合同代码的ODR请求类型
    95  type CodeRequest struct {
    96  	OdrRequest
    97  Id   *TrieID //账户参考存储检索
    98  	Hash common.Hash
    99  	Data []byte
   100  }
   101  
   102  //storeresult将检索到的数据存储在本地数据库中
   103  func (req *CodeRequest) StoreResult(db ethdb.Database) {
   104  	db.Put(req.Hash[:], req.Data)
   105  }
   106  
   107  //BlockRequest是用于检索块体的ODR请求类型
   108  type BlockRequest struct {
   109  	OdrRequest
   110  	Hash   common.Hash
   111  	Number uint64
   112  	Rlp    []byte
   113  }
   114  
   115  //storeresult将检索到的数据存储在本地数据库中
   116  func (req *BlockRequest) StoreResult(db ethdb.Database) {
   117  	rawdb.WriteBodyRLP(db, req.Hash, req.Number, req.Rlp)
   118  }
   119  
   120  //ReceiptsRequest是用于检索块体的ODR请求类型
   121  type ReceiptsRequest struct {
   122  	OdrRequest
   123  	Hash     common.Hash
   124  	Number   uint64
   125  	Receipts types.Receipts
   126  }
   127  
   128  //storeresult将检索到的数据存储在本地数据库中
   129  func (req *ReceiptsRequest) StoreResult(db ethdb.Database) {
   130  	rawdb.WriteReceipts(db, req.Hash, req.Number, req.Receipts)
   131  }
   132  
   133  //chtRequest是状态/存储trie项的odr请求类型
   134  type ChtRequest struct {
   135  	OdrRequest
   136  	Config           *IndexerConfig
   137  	ChtNum, BlockNum uint64
   138  	ChtRoot          common.Hash
   139  	Header           *types.Header
   140  	Td               *big.Int
   141  	Proof            *NodeSet
   142  }
   143  
   144  //storeresult将检索到的数据存储在本地数据库中
   145  func (req *ChtRequest) StoreResult(db ethdb.Database) {
   146  	hash, num := req.Header.Hash(), req.Header.Number.Uint64()
   147  
   148  	rawdb.WriteHeader(db, req.Header)
   149  	rawdb.WriteTd(db, hash, num, req.Td)
   150  	rawdb.WriteCanonicalHash(db, hash, num)
   151  }
   152  
   153  //BloomRequest是用于从CHT结构检索Bloom筛选器的ODR请求类型。
   154  type BloomRequest struct {
   155  	OdrRequest
   156  	Config           *IndexerConfig
   157  	BloomTrieNum     uint64
   158  	BitIdx           uint
   159  	SectionIndexList []uint64
   160  	BloomTrieRoot    common.Hash
   161  	BloomBits        [][]byte
   162  	Proofs           *NodeSet
   163  }
   164  
   165  //storeresult将检索到的数据存储在本地数据库中
   166  func (req *BloomRequest) StoreResult(db ethdb.Database) {
   167  	for i, sectionIdx := range req.SectionIndexList {
   168  		sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*req.Config.BloomTrieSize-1)
   169  //如果没有为此节头编号存储规范散列,我们仍然将其存储在
   170  //一个零分区头的键。如果我们仍然没有规范的
   171  //搞砸。在不太可能的情况下,我们从那以后就检索到了段头散列,我们只检索
   172  //再次从网络中得到位矢量。
   173  		rawdb.WriteBloomBits(db, req.BitIdx, sectionIdx, sectionHead, req.BloomBits[i])
   174  	}
   175  }
   176