Skip to content

Commit

Permalink
les: backported new SendTx cost calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
zsfelfoldi committed Apr 10, 2019
1 parent 14ae124 commit 0de9f32
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 8 deletions.
5 changes: 3 additions & 2 deletions les/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,9 @@ func TestTransactionStatusLes2(t *testing.T) {
test := func(tx *types.Transaction, send bool, expStatus txStatus) {
reqID++
if send {
cost := peer.GetRequestCost(SendTxV2Msg, 1)
sendRequest(peer.app, SendTxV2Msg, reqID, cost, types.Transactions{tx})
enc, _ := rlp.EncodeToBytes(types.Transactions{tx})
cost := peer.GetTxRelayCost(1, len(enc))
sendRequest(peer.app, SendTxV2Msg, reqID, cost, rlp.RawValue(enc))
} else {
cost := peer.GetRequestCost(GetTxStatusMsg, 1)
sendRequest(peer.app, GetTxStatusMsg, reqID, cost, []common.Hash{tx.Hash()})
Expand Down
37 changes: 34 additions & 3 deletions les/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ var (

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

// if the total encoded size of a sent transaction batch is over txSizeCostLimit
// per transaction then the request cost is calculated as proportional to the
// encoded size instead of the transaction count
const txSizeCostLimit = 0x4000

const (
announceTypeNone = iota
announceTypeSimple
Expand Down Expand Up @@ -170,6 +175,32 @@ func (p *peer) GetRequestCost(msgcode uint64, amount int) uint64 {
return cost
}

func (p *peer) GetTxRelayCost(amount, size int) uint64 {
p.lock.RLock()
defer p.lock.RUnlock()

var msgcode uint64
switch p.version {
case lpv1:
msgcode = SendTxMsg
case lpv2:
msgcode = SendTxV2Msg
default:
panic(nil)
}

cost := p.fcCosts[msgcode].baseCost + p.fcCosts[msgcode].reqCost*uint64(amount)
sizeCost := p.fcCosts[msgcode].baseCost + p.fcCosts[msgcode].reqCost*uint64(size)/txSizeCostLimit
if sizeCost > cost {
cost = sizeCost
}

if cost > p.fcServerParams.BufLimit {
cost = p.fcServerParams.BufLimit
}
return cost
}

// HasBlock checks if the peer has a given block
func (p *peer) HasBlock(hash common.Hash, number uint64, hasState bool) bool {
p.lock.RLock()
Expand Down Expand Up @@ -307,9 +338,9 @@ func (p *peer) RequestTxStatus(reqID, cost uint64, txHashes []common.Hash) error
return sendRequest(p.rw, GetTxStatusMsg, reqID, cost, txHashes)
}

// SendTxStatus sends a batch of transactions to be added to the remote transaction pool.
func (p *peer) SendTxs(reqID, cost uint64, txs types.Transactions) error {
p.Log().Debug("Fetching batch of transactions", "count", len(txs))
// SendTxs sends a batch of transactions to be added to the remote transaction pool.
func (p *peer) SendTxs(reqID, cost uint64, txs rlp.RawValue) error {
p.Log().Debug("Fetching batch of transactions", "size", len(txs))
switch p.version {
case lpv1:
return p2p.Send(p.rw, SendTxMsg, txs) // old message format does not include reqID
Expand Down
8 changes: 5 additions & 3 deletions les/txrelay.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
)

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

reqID := genReqID()
rq := &distReq{
getCost: func(dp distPeer) uint64 {
peer := dp.(*peer)
return peer.GetRequestCost(SendTxMsg, len(ll))
return peer.GetTxRelayCost(len(ll), len(enc))
},
canSend: func(dp distPeer) bool {
return dp.(*peer) == pp
},
request: func(dp distPeer) func() {
peer := dp.(*peer)
cost := peer.GetRequestCost(SendTxMsg, len(ll))
cost := peer.GetTxRelayCost(len(ll), len(enc))
peer.fcServer.QueueRequest(reqID, cost)
return func() { peer.SendTxs(reqID, cost, ll) }
return func() { peer.SendTxs(reqID, cost, enc) }
},
}
self.reqDist.queue(rq)
Expand Down

0 comments on commit 0de9f32

Please sign in to comment.