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