@@ -18,6 +18,11 @@ import (
18
18
"github.com/ethereum/go-ethereum/rlp"
19
19
)
20
20
21
+ // This is the target maximum size of returned blocks for the
22
+ // getBlocks message. The reply message may exceed it
23
+ // if a single block is larger than the limit.
24
+ const maxBlockRespSize = 2 * 1024 * 1024
25
+
21
26
func errResp (code errCode , format string , v ... interface {}) error {
22
27
return fmt .Errorf ("%v - %v" , code , fmt .Sprintf (format , v ... ))
23
28
}
@@ -48,9 +53,11 @@ type ProtocolManager struct {
48
53
txSub event.Subscription
49
54
minedBlockSub event.Subscription
50
55
56
+ // channels for fetcher, syncer, txsyncLoop
51
57
newPeerCh chan * peer
52
58
newHashCh chan []* blockAnnounce
53
59
newBlockCh chan chan []* types.Block
60
+ txsyncCh chan * txsync
54
61
quitSync chan struct {}
55
62
56
63
// wait group is used for graceful shutdowns during downloading
@@ -71,9 +78,9 @@ func NewProtocolManager(protocolVersion, networkId int, mux *event.TypeMux, txpo
71
78
newPeerCh : make (chan * peer , 1 ),
72
79
newHashCh : make (chan []* blockAnnounce , 1 ),
73
80
newBlockCh : make (chan chan []* types.Block ),
81
+ txsyncCh : make (chan * txsync ),
74
82
quitSync : make (chan struct {}),
75
83
}
76
-
77
84
manager .SubProtocol = p2p.Protocol {
78
85
Name : "eth" ,
79
86
Version : uint (protocolVersion ),
@@ -113,13 +120,14 @@ func (pm *ProtocolManager) Start() {
113
120
// broadcast transactions
114
121
pm .txSub = pm .eventMux .Subscribe (core.TxPreEvent {})
115
122
go pm .txBroadcastLoop ()
116
-
117
123
// broadcast mined blocks
118
124
pm .minedBlockSub = pm .eventMux .Subscribe (core.NewMinedBlockEvent {})
119
125
go pm .minedBroadcastLoop ()
120
126
127
+ // start sync handlers
121
128
go pm .syncer ()
122
129
go pm .fetcher ()
130
+ go pm .txsyncLoop ()
123
131
}
124
132
125
133
func (pm * ProtocolManager ) Stop () {
@@ -130,7 +138,7 @@ func (pm *ProtocolManager) Stop() {
130
138
pm .quit = true
131
139
pm .txSub .Unsubscribe () // quits txBroadcastLoop
132
140
pm .minedBlockSub .Unsubscribe () // quits blockBroadcastLoop
133
- close (pm .quitSync ) // quits the sync handler
141
+ close (pm .quitSync ) // quits syncer, fetcher, txsyncLoop
134
142
135
143
// Wait for any process action
136
144
pm .wg .Wait ()
@@ -145,26 +153,29 @@ func (pm *ProtocolManager) newPeer(pv, nv int, p *p2p.Peer, rw p2p.MsgReadWriter
145
153
}
146
154
147
155
func (pm * ProtocolManager ) handle (p * peer ) error {
148
- // Execute the Ethereum handshake, short circuit if fails
156
+ // Execute the Ethereum handshake.
149
157
if err := p .handleStatus (); err != nil {
150
158
return err
151
159
}
152
- // Register the peer locally and in the downloader too
160
+
161
+ // Register the peer locally.
153
162
glog .V (logger .Detail ).Infoln ("Adding peer" , p .id )
154
163
if err := pm .peers .Register (p ); err != nil {
155
164
glog .V (logger .Error ).Infoln ("Addition failed:" , err )
156
165
return err
157
166
}
158
167
defer pm .removePeer (p .id )
159
168
169
+ // Register the peer in the downloader. If the downloader
170
+ // considers it banned, we disconnect.
160
171
if err := pm .downloader .RegisterPeer (p .id , p .Head (), p .requestHashes , p .requestBlocks ); err != nil {
161
172
return err
162
173
}
163
- // propagate existing transactions. new transactions appearing
174
+
175
+ // Propagate existing transactions. new transactions appearing
164
176
// after this will be sent via broadcasts.
165
- if err := p .sendTransactions (pm .txpool .GetTransactions ()); err != nil {
166
- return err
167
- }
177
+ pm .syncTransactions (p )
178
+
168
179
// main loop. handle incoming messages.
169
180
for {
170
181
if err := pm .handleMsg (p ); err != nil {
@@ -246,7 +257,10 @@ func (self *ProtocolManager) handleMsg(p *peer) error {
246
257
if _ , err := msgStream .List (); err != nil {
247
258
return err
248
259
}
249
- var i int
260
+ var (
261
+ i int
262
+ totalsize common.StorageSize
263
+ )
250
264
for {
251
265
i ++
252
266
var hash common.Hash
@@ -260,8 +274,9 @@ func (self *ProtocolManager) handleMsg(p *peer) error {
260
274
block := self .chainman .GetBlock (hash )
261
275
if block != nil {
262
276
blocks = append (blocks , block )
277
+ totalsize += block .Size ()
263
278
}
264
- if i == downloader .MaxBlockFetch {
279
+ if i == downloader .MaxBlockFetch || totalsize > maxBlockRespSize {
265
280
break
266
281
}
267
282
}
0 commit comments