Pay per-block price instead of per-peer price

This commit is contained in:
Mark Spanbroek 2021-05-10 13:47:15 +02:00 committed by markspanbroek
parent f69827d582
commit fa05bffeac
6 changed files with 20 additions and 16 deletions

View File

@ -194,11 +194,8 @@ proc payForBlocks(engine: BitswapEngine,
if sendPayment.isNil: if sendPayment.isNil:
return return
var amountOfBytes = 0 let cids = blocks.mapIt(it.cid)
for blck in blocks: if payment =? engine.wallet.pay(peer, peer.price(cids)):
amountOfBytes += blck.data.len
if payment =? engine.wallet.pay(peer, amountOfBytes):
sendPayment(peer.id, payment) sendPayment(peer.id, payment)
proc blocksHandler*( proc blocksHandler*(

View File

@ -30,9 +30,8 @@ func getOrOpenChannel(wallet: WalletRef, peer: BitswapPeerCtx): ?!ChannelId =
func pay*(wallet: WalletRef, func pay*(wallet: WalletRef,
peer: BitswapPeerCtx, peer: BitswapPeerCtx,
amountOfBytes: int): ?!SignedState = amount: UInt256): ?!SignedState =
if pricing =? peer.pricing: if pricing =? peer.pricing:
let amount = amountOfBytes.u256 * pricing.price
let asset = Asset let asset = Asset
let receiver = pricing.address let receiver = pricing.address
let channel = ?wallet.getOrOpenChannel(peer) let channel = ?wallet.getOrOpenChannel(peer)

View File

@ -46,3 +46,8 @@ func updatePresence*(context: BitswapPeerCtx, presence: Presence) =
elif cid in context.peerHave and not presence.have: elif cid in context.peerHave and not presence.have:
context.peerHave.keepItIf(it != cid) context.peerHave.keepItIf(it != cid)
context.peerPrices.del(cid) context.peerPrices.del(cid)
func price*(context: BitswapPeerCtx, cids: seq[Cid]): UInt256 =
for cid in cids:
if price =? context.peerPrices.?[cid]:
result += price

View File

@ -4,7 +4,7 @@ import ../../examples
suite "engine payments": suite "engine payments":
let amountOfBytes = 42 let amount = 42.u256
var wallet: WalletRef var wallet: WalletRef
var peer: BitswapPeerCtx var peer: BitswapPeerCtx
@ -14,19 +14,19 @@ suite "engine payments":
peer = BitswapPeerCtx.example peer = BitswapPeerCtx.example
peer.pricing = Pricing.example.some peer.pricing = Pricing.example.some
test "pays for received bytes": test "pays for received blocks":
let payment = !wallet.pay(peer, amountOfBytes) let payment = !wallet.pay(peer, amount)
let pricing = !peer.pricing let pricing = !peer.pricing
let balances = payment.state.outcome.balances(Asset) let balances = payment.state.outcome.balances(Asset)
let destination = pricing.address.toDestination let destination = pricing.address.toDestination
check !balances[destination] == amountOfBytes.u256 * pricing.price check !balances[destination] == amount
test "no payment when no price is set": test "no payment when no price is set":
peer.pricing = Pricing.none peer.pricing = Pricing.none
check wallet.pay(peer, amountOfBytes).isFailure check wallet.pay(peer, amount).isFailure
test "uses same channel for consecutive payments": test "uses same channel for consecutive payments":
let payment1, payment2 = wallet.pay(peer, amountOfBytes) let payment1, payment2 = wallet.pay(peer, amount)
let channel1 = payment1.?state.?channel.?getChannelId let channel1 = payment1.?state.?channel.?getChannelId
let channel2 = payment2.?state.?channel.?getChannelId let channel2 = payment2.?state.?channel.?getChannelId
check channel1 == channel2 check channel1 == channel2

View File

@ -1,4 +1,5 @@
import std/sequtils import std/sequtils
import std/random
import pkg/stew/byteutils import pkg/stew/byteutils
import pkg/asynctest import pkg/asynctest
@ -153,10 +154,12 @@ suite "Bitswap engine handlers":
test "sends payments for received blocks": test "sends payments for received blocks":
let pricing = Pricing.example let pricing = Pricing.example
engine.getPeerCtx(peerId).pricing = pricing.some let peerContext = engine.getPeerCtx(peerId)
peerContext.pricing = pricing.some
peerContext.peerPrices = blocks.mapIt((it.cid, rand(uint16).u256)).toTable
engine.request.sendPayment = proc(receiver: PeerID, payment: SignedState) = engine.request.sendPayment = proc(receiver: PeerID, payment: SignedState) =
let amount = blocks.mapIt(it.data.len).foldl(a+b).u256 * pricing.price let amount = blocks.mapIt(peerContext.peerPrices[it.cid]).foldl(a+b)
let balances = !payment.state.outcome.balances(Asset) let balances = !payment.state.outcome.balances(Asset)
check receiver == peerId check receiver == peerId
check balances[pricing.address.toDestination] == amount check balances[pricing.address.toDestination] == amount

View File

@ -37,7 +37,7 @@ proc example*(_: type SignedState): SignedState =
proc example*(_: type Pricing): Pricing = proc example*(_: type Pricing): Pricing =
Pricing( Pricing(
address: EthAddress.example, address: EthAddress.example,
price: uint32.example.u256 price: uint32.rand.u256
) )
proc example*(_: type Block): Block = proc example*(_: type Block): Block =