github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/network/stream/syncer.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:44</date>
    10  //</624450115867774976>
    11  
    12  
    13  package stream
    14  
    15  import (
    16  	"context"
    17  	"strconv"
    18  	"time"
    19  
    20  	"github.com/ethereum/go-ethereum/metrics"
    21  	"github.com/ethereum/go-ethereum/swarm/log"
    22  	"github.com/ethereum/go-ethereum/swarm/storage"
    23  )
    24  
    25  const (
    26  	BatchSize = 128
    27  )
    28  
    29  //swarmsyncerserver实现在存储箱上同步历史记录的服务器
    30  //提供的流:
    31  //*带或不带支票的实时请求交付
    32  //(实时/非实时历史记录)每个邻近箱的块同步
    33  type SwarmSyncerServer struct {
    34  	po    uint8
    35  	store storage.SyncChunkStore
    36  	quit  chan struct{}
    37  }
    38  
    39  //newswarmsyncerserver是swarmsyncerserver的构造函数
    40  func NewSwarmSyncerServer(po uint8, syncChunkStore storage.SyncChunkStore) (*SwarmSyncerServer, error) {
    41  	return &SwarmSyncerServer{
    42  		po:    po,
    43  		store: syncChunkStore,
    44  		quit:  make(chan struct{}),
    45  	}, nil
    46  }
    47  
    48  func RegisterSwarmSyncerServer(streamer *Registry, syncChunkStore storage.SyncChunkStore) {
    49  	streamer.RegisterServerFunc("SYNC", func(_ *Peer, t string, _ bool) (Server, error) {
    50  		po, err := ParseSyncBinKey(t)
    51  		if err != nil {
    52  			return nil, err
    53  		}
    54  		return NewSwarmSyncerServer(po, syncChunkStore)
    55  	})
    56  //streamer.registerserverfunc(stream,func(p*peer)(服务器,错误)
    57  //返回newoutgoingprovableswarmsyncer(po,db)
    58  //})
    59  }
    60  
    61  //需要在流服务器上调用Close
    62  func (s *SwarmSyncerServer) Close() {
    63  	close(s.quit)
    64  }
    65  
    66  //getdata从netstore检索实际块
    67  func (s *SwarmSyncerServer) GetData(ctx context.Context, key []byte) ([]byte, error) {
    68  	chunk, err := s.store.Get(ctx, storage.Address(key))
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	return chunk.Data(), nil
    73  }
    74  
    75  //sessionindex返回当前存储箱(po)索引。
    76  func (s *SwarmSyncerServer) SessionIndex() (uint64, error) {
    77  	return s.store.BinIndex(s.po), nil
    78  }
    79  
    80  //getbatch从dbstore检索下一批哈希
    81  func (s *SwarmSyncerServer) SetNextBatch(from, to uint64) ([]byte, uint64, uint64, *HandoverProof, error) {
    82  	var batch []byte
    83  	i := 0
    84  
    85  	var ticker *time.Ticker
    86  	defer func() {
    87  		if ticker != nil {
    88  			ticker.Stop()
    89  		}
    90  	}()
    91  	var wait bool
    92  	for {
    93  		if wait {
    94  			if ticker == nil {
    95  				ticker = time.NewTicker(1000 * time.Millisecond)
    96  			}
    97  			select {
    98  			case <-ticker.C:
    99  			case <-s.quit:
   100  				return nil, 0, 0, nil, nil
   101  			}
   102  		}
   103  
   104  		metrics.GetOrRegisterCounter("syncer.setnextbatch.iterator", nil).Inc(1)
   105  		err := s.store.Iterator(from, to, s.po, func(key storage.Address, idx uint64) bool {
   106  			batch = append(batch, key[:]...)
   107  			i++
   108  			to = idx
   109  			return i < BatchSize
   110  		})
   111  		if err != nil {
   112  			return nil, 0, 0, nil, err
   113  		}
   114  		if len(batch) > 0 {
   115  			break
   116  		}
   117  		wait = true
   118  	}
   119  
   120  	log.Trace("Swarm syncer offer batch", "po", s.po, "len", i, "from", from, "to", to, "current store count", s.store.BinIndex(s.po))
   121  	return batch, from, to, nil, nil
   122  }
   123  
   124  //垃圾同步机
   125  type SwarmSyncerClient struct {
   126  	store  storage.SyncChunkStore
   127  	peer   *Peer
   128  	stream Stream
   129  }
   130  
   131  //NewsWarmSyncerClient是可验证数据交换同步器的控制器
   132  func NewSwarmSyncerClient(p *Peer, store storage.SyncChunkStore, stream Stream) (*SwarmSyncerClient, error) {
   133  	return &SwarmSyncerClient{
   134  		store:  store,
   135  		peer:   p,
   136  		stream: stream,
   137  	}, nil
   138  }
   139  
   140  ////newincomingprovableswamsyncer是可验证数据交换同步器的控制器
   141  //func newincomingprovableswarmsyncer(po int,priority int,index uint64,sessionna uint64,interval[]uint64,sessionroot storage.address,chunker*storage.pyramidchunker,store storage.chunkstore,p peer)*swarmsyncerclient
   142  //检索:=make(storage.chunk,chunkscap)
   143  //runchunkrequester(P,检索)
   144  //storec:=make(storage.chunk,chunkscap)
   145  //runchunkstorer(商店、商店)
   146  //S:=和SwarmSyncerClient
   147  //采购订单:采购订单,
   148  //优先级:优先级,
   149  //sessiona:会话,
   150  //开始:索引,
   151  //结束:索引,
   152  //下一步:制造(Chan结构,1)
   153  //间隔:间隔,
   154  //sessionroot:会话根,
   155  //sessionreader:chunker.join(sessionroot,retrievec),
   156  //检索:检索,
   157  //storec:storec,
   158  //}
   159  //返回S
   160  //}
   161  
   162  ////在对等机上调用StartSyncing以启动同步进程
   163  ////其理念是只有当卡德米利亚接近健康时才调用它
   164  //func开始同步(s*拖缆,peerid enode.id,po uint8,nn bool)
   165  //拉斯坡
   166  //如果神经网络{
   167  //LaSTPO=Max
   168  //}
   169  //
   170  //对于i:=po;i<=lastpo;i++
   171  //s.subscribe(peerid,“同步”,newsynclabel(“实时”,po),0,0,high,true)
   172  //s.subscribe(peerid,“同步”,newsynclabel(“历史”,po),0,0,mid,false)
   173  //}
   174  //}
   175  
   176  //registerwarmsyncerclient为注册客户端构造函数函数
   177  //处理传入的同步流
   178  func RegisterSwarmSyncerClient(streamer *Registry, store storage.SyncChunkStore) {
   179  	streamer.RegisterClientFunc("SYNC", func(p *Peer, t string, live bool) (Client, error) {
   180  		return NewSwarmSyncerClient(p, store, NewStream("SYNC", t, live))
   181  	})
   182  }
   183  
   184  //需求数据
   185  func (s *SwarmSyncerClient) NeedData(ctx context.Context, key []byte) (wait func(context.Context) error) {
   186  	return s.store.FetchFunc(ctx, key)
   187  }
   188  
   189  //巴奇多
   190  func (s *SwarmSyncerClient) BatchDone(stream Stream, from uint64, hashes []byte, root []byte) func() (*TakeoverProof, error) {
   191  //TODO:使用putter/getter重构代码重新启用此项
   192  //如果S.Cukes!= nIL{
   193  //return func()(*takeoveroof,error)返回s.takeoveroof(stream,from,hashes,root)
   194  //}
   195  	return nil
   196  }
   197  
   198  func (s *SwarmSyncerClient) Close() {}
   199  
   200  //分析和格式化同步bin键的基础
   201  //它必须是2<=基<=36
   202  const syncBinKeyBase = 36
   203  
   204  //FormatSyncBinkey返回的字符串表示形式
   205  //要用作同步流密钥的Kademlia bin号。
   206  func FormatSyncBinKey(bin uint8) string {
   207  	return strconv.FormatUint(uint64(bin), syncBinKeyBase)
   208  }
   209  
   210  //ParseSyncBinKey分析字符串表示形式
   211  //并返回Kademlia bin编号。
   212  func ParseSyncBinKey(s string) (uint8, error) {
   213  	bin, err := strconv.ParseUint(s, syncBinKeyBase, 8)
   214  	if err != nil {
   215  		return 0, err
   216  	}
   217  	return uint8(bin), nil
   218  }
   219