Skip to content

Commit 0de9f32

Browse files
committed
les: backported new SendTx cost calculation
1 parent 14ae124 commit 0de9f32

File tree

3 files changed

+42
-8
lines changed

3 files changed

+42
-8
lines changed

les/handler_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,8 +508,9 @@ func TestTransactionStatusLes2(t *testing.T) {
508508
test := func(tx *types.Transaction, send bool, expStatus txStatus) {
509509
reqID++
510510
if send {
511-
cost := peer.GetRequestCost(SendTxV2Msg, 1)
512-
sendRequest(peer.app, SendTxV2Msg, reqID, cost, types.Transactions{tx})
511+
enc, _ := rlp.EncodeToBytes(types.Transactions{tx})
512+
cost := peer.GetTxRelayCost(1, len(enc))
513+
sendRequest(peer.app, SendTxV2Msg, reqID, cost, rlp.RawValue(enc))
513514
} else {
514515
cost := peer.GetRequestCost(GetTxStatusMsg, 1)
515516
sendRequest(peer.app, GetTxStatusMsg, reqID, cost, []common.Hash{tx.Hash()})

les/peer.go

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ var (
4242

4343
const maxResponseErrors = 50 // number of invalid responses tolerated (makes the protocol less brittle but still avoids spam)
4444

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+
4550
const (
4651
announceTypeNone = iota
4752
announceTypeSimple
@@ -170,6 +175,32 @@ func (p *peer) GetRequestCost(msgcode uint64, amount int) uint64 {
170175
return cost
171176
}
172177

178+
func (p *peer) GetTxRelayCost(amount, size int) uint64 {
179+
p.lock.RLock()
180+
defer p.lock.RUnlock()
181+
182+
var msgcode uint64
183+
switch p.version {
184+
case lpv1:
185+
msgcode = SendTxMsg
186+
case lpv2:
187+
msgcode = SendTxV2Msg
188+
default:
189+
panic(nil)
190+
}
191+
192+
cost := p.fcCosts[msgcode].baseCost + p.fcCosts[msgcode].reqCost*uint64(amount)
193+
sizeCost := p.fcCosts[msgcode].baseCost + p.fcCosts[msgcode].reqCost*uint64(size)/txSizeCostLimit
194+
if sizeCost > cost {
195+
cost = sizeCost
196+
}
197+
198+
if cost > p.fcServerParams.BufLimit {
199+
cost = p.fcServerParams.BufLimit
200+
}
201+
return cost
202+
}
203+
173204
// HasBlock checks if the peer has a given block
174205
func (p *peer) HasBlock(hash common.Hash, number uint64, hasState bool) bool {
175206
p.lock.RLock()
@@ -307,9 +338,9 @@ func (p *peer) RequestTxStatus(reqID, cost uint64, txHashes []common.Hash) error
307338
return sendRequest(p.rw, GetTxStatusMsg, reqID, cost, txHashes)
308339
}
309340

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))
341+
// SendTxs sends a batch of transactions to be added to the remote transaction pool.
342+
func (p *peer) SendTxs(reqID, cost uint64, txs rlp.RawValue) error {
343+
p.Log().Debug("Fetching batch of transactions", "size", len(txs))
313344
switch p.version {
314345
case lpv1:
315346
return p2p.Send(p.rw, SendTxMsg, txs) // old message format does not include reqID

les/txrelay.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
"github.com/ethereum/go-ethereum/common"
2323
"github.com/ethereum/go-ethereum/core/types"
24+
"github.com/ethereum/go-ethereum/rlp"
2425
)
2526

2627
type ltrInfo struct {
@@ -113,21 +114,22 @@ func (self *LesTxRelay) send(txs types.Transactions, count int) {
113114
for p, list := range sendTo {
114115
pp := p
115116
ll := list
117+
enc, _ := rlp.EncodeToBytes(ll)
116118

117119
reqID := genReqID()
118120
rq := &distReq{
119121
getCost: func(dp distPeer) uint64 {
120122
peer := dp.(*peer)
121-
return peer.GetRequestCost(SendTxMsg, len(ll))
123+
return peer.GetTxRelayCost(len(ll), len(enc))
122124
},
123125
canSend: func(dp distPeer) bool {
124126
return dp.(*peer) == pp
125127
},
126128
request: func(dp distPeer) func() {
127129
peer := dp.(*peer)
128-
cost := peer.GetRequestCost(SendTxMsg, len(ll))
130+
cost := peer.GetTxRelayCost(len(ll), len(enc))
129131
peer.fcServer.QueueRequest(reqID, cost)
130-
return func() { peer.SendTxs(reqID, cost, ll) }
132+
return func() { peer.SendTxs(reqID, cost, enc) }
131133
},
132134
}
133135
self.reqDist.queue(rq)

0 commit comments

Comments
 (0)