|
42 | 42 |
|
43 | 43 | const maxResponseErrors = 50 // number of invalid responses tolerated (makes the protocol less brittle but still avoids spam)
|
44 | 44 |
|
| 45 | +// if the total encoded size of a sent transaction batch is over txSizeCostLimit |
| 46 | +// per transaction then the request cost is calculated as proportional to the |
| 47 | +// encoded size instead of the transaction count |
| 48 | +const txSizeCostLimit = 0x4000 |
| 49 | + |
45 | 50 | const (
|
46 | 51 | announceTypeNone = iota
|
47 | 52 | announceTypeSimple
|
@@ -163,7 +168,41 @@ func (p *peer) GetRequestCost(msgcode uint64, amount int) uint64 {
|
163 | 168 | p.lock.RLock()
|
164 | 169 | defer p.lock.RUnlock()
|
165 | 170 |
|
166 |
| - cost := p.fcCosts[msgcode].baseCost + p.fcCosts[msgcode].reqCost*uint64(amount) |
| 171 | + costs := p.fcCosts[msgcode] |
| 172 | + if costs == nil { |
| 173 | + return 0 |
| 174 | + } |
| 175 | + cost := costs.baseCost + costs.reqCost*uint64(amount) |
| 176 | + if cost > p.fcServerParams.BufLimit { |
| 177 | + cost = p.fcServerParams.BufLimit |
| 178 | + } |
| 179 | + return cost |
| 180 | +} |
| 181 | + |
| 182 | +func (p *peer) GetTxRelayCost(amount, size int) uint64 { |
| 183 | + p.lock.RLock() |
| 184 | + defer p.lock.RUnlock() |
| 185 | + |
| 186 | + var msgcode uint64 |
| 187 | + switch p.version { |
| 188 | + case lpv1: |
| 189 | + msgcode = SendTxMsg |
| 190 | + case lpv2: |
| 191 | + msgcode = SendTxV2Msg |
| 192 | + default: |
| 193 | + panic(nil) |
| 194 | + } |
| 195 | + |
| 196 | + costs := p.fcCosts[msgcode] |
| 197 | + if costs == nil { |
| 198 | + return 0 |
| 199 | + } |
| 200 | + cost := costs.baseCost + costs.reqCost*uint64(amount) |
| 201 | + sizeCost := costs.baseCost + costs.reqCost*uint64(size)/txSizeCostLimit |
| 202 | + if sizeCost > cost { |
| 203 | + cost = sizeCost |
| 204 | + } |
| 205 | + |
167 | 206 | if cost > p.fcServerParams.BufLimit {
|
168 | 207 | cost = p.fcServerParams.BufLimit
|
169 | 208 | }
|
@@ -307,9 +346,9 @@ func (p *peer) RequestTxStatus(reqID, cost uint64, txHashes []common.Hash) error
|
307 | 346 | return sendRequest(p.rw, GetTxStatusMsg, reqID, cost, txHashes)
|
308 | 347 | }
|
309 | 348 |
|
310 |
| -// SendTxStatus sends a batch of transactions to be added to the remote transaction pool. |
311 |
| -func (p *peer) SendTxs(reqID, cost uint64, txs types.Transactions) error { |
312 |
| - p.Log().Debug("Fetching batch of transactions", "count", len(txs)) |
| 349 | +// SendTxs sends a batch of transactions to be added to the remote transaction pool. |
| 350 | +func (p *peer) SendTxs(reqID, cost uint64, txs rlp.RawValue) error { |
| 351 | + p.Log().Debug("Fetching batch of transactions", "size", len(txs)) |
313 | 352 | switch p.version {
|
314 | 353 | case lpv1:
|
315 | 354 | return p2p.Send(p.rw, SendTxMsg, txs) // old message format does not include reqID
|
@@ -485,6 +524,20 @@ func (p *peer) Handshake(td *big.Int, head common.Hash, headNum uint64, genesis
|
485 | 524 | p.fcServerParams = params
|
486 | 525 | p.fcServer = flowcontrol.NewServerNode(params)
|
487 | 526 | p.fcCosts = MRC.decode()
|
| 527 | + var checkList []uint64 |
| 528 | + switch p.version { |
| 529 | + case lpv1: |
| 530 | + checkList = reqListV1 |
| 531 | + case lpv2: |
| 532 | + checkList = reqListV2 |
| 533 | + default: |
| 534 | + panic(nil) |
| 535 | + } |
| 536 | + for _, msgCode := range checkList { |
| 537 | + if p.fcCosts[msgCode] == nil { |
| 538 | + return errResp(ErrUselessPeer, "peer does not support message %d", msgCode) |
| 539 | + } |
| 540 | + } |
488 | 541 | }
|
489 | 542 |
|
490 | 543 | p.headInfo = &announceData{Td: rTd, Hash: rHash, Number: rNum}
|
|
0 commit comments