github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/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 12:09:41</date>
    10  //</624342645627424768>
    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  }
    44  
    45  //ODRRequest是一个用于检索请求的接口
    46  type OdrRequest interface {
    47  	StoreResult(db ethdb.Database)
    48  }
    49  
    50  //trieid标识状态或帐户存储trie
    51  type TrieID struct {
    52  	BlockHash, Root common.Hash
    53  	BlockNumber     uint64
    54  	AccKey          []byte
    55  }
    56  
    57  //state trieid返回属于某个块的state trie的trieid
    58  //标题。
    59  func StateTrieID(header *types.Header) *TrieID {
    60  	return &TrieID{
    61  		BlockHash:   header.Hash(),
    62  		BlockNumber: header.Number.Uint64(),
    63  		AccKey:      nil,
    64  		Root:        header.Root,
    65  	}
    66  }
    67  
    68  //storage trieid返回给定帐户上合同存储trie的trieid
    69  //一个给定的国家的。它还需要trie的根散列
    70  //检查Merkle校样。
    71  func StorageTrieID(state *TrieID, addrHash, root common.Hash) *TrieID {
    72  	return &TrieID{
    73  		BlockHash:   state.BlockHash,
    74  		BlockNumber: state.BlockNumber,
    75  		AccKey:      addrHash[:],
    76  		Root:        root,
    77  	}
    78  }
    79  
    80  //trieRequest是状态/存储trie项的ODR请求类型
    81  type TrieRequest struct {
    82  	OdrRequest
    83  	Id    *TrieID
    84  	Key   []byte
    85  	Proof *NodeSet
    86  }
    87  
    88  //storeresult将检索到的数据存储在本地数据库中
    89  func (req *TrieRequest) StoreResult(db ethdb.Database) {
    90  	req.Proof.Store(db)
    91  }
    92  
    93  //code request是用于检索合同代码的ODR请求类型
    94  type CodeRequest struct {
    95  	OdrRequest
    96  Id   *TrieID //账户参考存储检索
    97  	Hash common.Hash
    98  	Data []byte
    99  }
   100  
   101  //storeresult将检索到的数据存储在本地数据库中
   102  func (req *CodeRequest) StoreResult(db ethdb.Database) {
   103  	db.Put(req.Hash[:], req.Data)
   104  }
   105  
   106  //BlockRequest是用于检索块体的ODR请求类型
   107  type BlockRequest struct {
   108  	OdrRequest
   109  	Hash   common.Hash
   110  	Number uint64
   111  	Rlp    []byte
   112  }
   113  
   114  //storeresult将检索到的数据存储在本地数据库中
   115  func (req *BlockRequest) StoreResult(db ethdb.Database) {
   116  	rawdb.WriteBodyRLP(db, req.Hash, req.Number, req.Rlp)
   117  }
   118  
   119  //ReceiptsRequest是用于检索块体的ODR请求类型
   120  type ReceiptsRequest struct {
   121  	OdrRequest
   122  	Hash     common.Hash
   123  	Number   uint64
   124  	Receipts types.Receipts
   125  }
   126  
   127  //storeresult将检索到的数据存储在本地数据库中
   128  func (req *ReceiptsRequest) StoreResult(db ethdb.Database) {
   129  	rawdb.WriteReceipts(db, req.Hash, req.Number, req.Receipts)
   130  }
   131  
   132  //chtRequest是状态/存储trie项的odr请求类型
   133  type ChtRequest struct {
   134  	OdrRequest
   135  	ChtNum, BlockNum uint64
   136  	ChtRoot          common.Hash
   137  	Header           *types.Header
   138  	Td               *big.Int
   139  	Proof            *NodeSet
   140  }
   141  
   142  //storeresult将检索到的数据存储在本地数据库中
   143  func (req *ChtRequest) StoreResult(db ethdb.Database) {
   144  	hash, num := req.Header.Hash(), req.Header.Number.Uint64()
   145  
   146  	rawdb.WriteHeader(db, req.Header)
   147  	rawdb.WriteTd(db, hash, num, req.Td)
   148  	rawdb.WriteCanonicalHash(db, hash, num)
   149  }
   150  
   151  //BloomRequest是用于从CHT结构检索Bloom筛选器的ODR请求类型。
   152  type BloomRequest struct {
   153  	OdrRequest
   154  	BloomTrieNum   uint64
   155  	BitIdx         uint
   156  	SectionIdxList []uint64
   157  	BloomTrieRoot  common.Hash
   158  	BloomBits      [][]byte
   159  	Proofs         *NodeSet
   160  }
   161  
   162  //storeresult将检索到的数据存储在本地数据库中
   163  func (req *BloomRequest) StoreResult(db ethdb.Database) {
   164  	for i, sectionIdx := range req.SectionIdxList {
   165  		sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*BloomTrieFrequency-1)
   166  //如果没有为此节头编号存储规范散列,我们仍然将其存储在
   167  //一个零分区头的键。如果我们仍然没有规范的
   168  //搞砸。在不太可能的情况下,我们从那以后就检索到了段头散列,我们只检索
   169  //再次从网络中得到位矢量。
   170  		rawdb.WriteBloomBits(db, req.BitIdx, sectionIdx, sectionHead, req.BloomBits[i])
   171  	}
   172  }
   173