diff --git a/dagger/bitswap.nim b/dagger/bitswap.nim index ebc5eb82..19766a70 100644 --- a/dagger/bitswap.nim +++ b/dagger/bitswap.nim @@ -157,8 +157,8 @@ proc new*( blocks: seq[bt.Block]) {.gcsafe.} = engine.blocksHandler(peer, blocks) - proc pricingHandler(peer: PeerId, pricing: Pricing) = - engine.pricingHandler(peer, pricing) + proc accountHandler(peer: PeerId, account: Account) = + engine.accountHandler(peer, account) proc paymentHandler(peer: PeerId, payment: SignedState) = engine.paymentHandler(peer, payment) @@ -167,7 +167,7 @@ proc new*( onWantList: blockWantListHandler, onBlocks: blocksHandler, onPresence: blockPresenceHandler, - onPricing: pricingHandler, + onAccount: accountHandler, onPayment: paymentHandler ) diff --git a/dagger/bitswap/engine.nim b/dagger/bitswap/engine.nim index 556badb3..4a424725 100644 --- a/dagger/bitswap/engine.nim +++ b/dagger/bitswap/engine.nim @@ -50,6 +50,10 @@ type wallet*: WalletRef # nitro wallet for micropayments pricing*: ?Pricing # optional bandwidth pricing + Pricing* = object + address*: EthAddress + price*: UInt256 + proc contains*(a: AsyncHeapQueue[Entry], b: Cid): bool = ## Convenience method to check for entry prepense ## @@ -246,21 +250,20 @@ proc wantListHandler*( if not b.scheduleTask(peerCtx): trace "Unable to schedule task for peer", peer -proc pricingHandler*(engine: BitswapEngine, peer: PeerID, pricing: Pricing) = +proc accountHandler*(engine: BitswapEngine, peer: PeerID, account: Account) = let context = engine.getPeerCtx(peer) if context.isNil: return - context.pricing = pricing.some + context.account = account.some proc paymentHandler*(engine: BitswapEngine, peer: PeerId, payment: SignedState) = without context =? engine.getPeerCtx(peer).option and - contextPricing =? context.pricing and - enginePricing =? engine.pricing: + account =? context.account: return if channel =? context.paymentChannel: - let sender = contextPricing.address + let sender = account.address discard engine.wallet.acceptPayment(channel, Asset, sender, payment) else: context.paymentChannel = engine.wallet.acceptChannel(payment).option @@ -280,8 +283,8 @@ proc setupPeer*(b: BitswapEngine, peer: PeerID) = if b.wantList.len > 0: b.request.sendWantList(peer, b.wantList, full = true) - if pricing =? b.pricing: - b.request.sendPricing(peer, pricing) + if address =? b.pricing.?address: + b.request.sendAccount(peer, Account(address: address)) proc dropPeer*(b: BitswapEngine, peer: PeerID) = ## Cleanup disconnected peer diff --git a/dagger/bitswap/engine/payments.nim b/dagger/bitswap/engine/payments.nim index 567b8f63..0beecc86 100644 --- a/dagger/bitswap/engine/payments.nim +++ b/dagger/bitswap/engine/payments.nim @@ -21,20 +21,20 @@ func openLedgerChannel*(wallet: WalletRef, func getOrOpenChannel(wallet: WalletRef, peer: BitswapPeerCtx): ?!ChannelId = if channel =? peer.paymentChannel: success channel - elif pricing =? peer.pricing: - let channel = ?wallet.openLedgerChannel(pricing.address, Asset) + elif account =? peer.account: + let channel = ?wallet.openLedgerChannel(account.address, Asset) peer.paymentChannel = channel.some success channel else: - failure "no pricing set for peer" + failure "no account set for peer" func pay*(wallet: WalletRef, peer: BitswapPeerCtx, amount: UInt256): ?!SignedState = - if pricing =? peer.pricing: + if account =? peer.account: let asset = Asset - let receiver = pricing.address + let receiver = account.address let channel = ?wallet.getOrOpenChannel(peer) wallet.pay(channel, asset, receiver, amount) else: - failure "no pricing set for peer" + failure "no account set for peer" diff --git a/dagger/bitswap/network.nim b/dagger/bitswap/network.nim index 2214b5c7..8774f3ca 100644 --- a/dagger/bitswap/network.nim +++ b/dagger/bitswap/network.nim @@ -31,14 +31,14 @@ type WantListHandler* = proc(peer: PeerID, wantList: WantList) {.gcsafe.} BlocksHandler* = proc(peer: PeerID, blocks: seq[bt.Block]) {.gcsafe.} BlockPresenceHandler* = proc(peer: PeerID, precense: seq[BlockPresence]) {.gcsafe.} - PricingHandler* = proc(peer: PeerID, pricing: Pricing) {.gcsafe.} + AccountHandler* = proc(peer: PeerID, account: Account) {.gcsafe.} PaymentHandler* = proc(peer: PeerID, payment: SignedState) {.gcsafe.} BitswapHandlers* = object onWantList*: WantListHandler onBlocks*: BlocksHandler onPresence*: BlockPresenceHandler - onPricing*: PricingHandler + onAccount*: AccountHandler onPayment*: PaymentHandler WantListBroadcaster* = proc( @@ -52,14 +52,14 @@ type BlocksBroadcaster* = proc(peer: PeerID, presence: seq[bt.Block]) {.gcsafe.} PresenceBroadcaster* = proc(peer: PeerID, presence: seq[BlockPresence]) {.gcsafe.} - PricingBroadcaster* = proc(peer: PeerID, pricing: Pricing) {.gcsafe.} + AccountBroadcaster* = proc(peer: PeerID, account: Account) {.gcsafe.} PaymentBroadcaster* = proc(peer: PeerID, payment: SignedState) {.gcsafe.} BitswapRequest* = object sendWantList*: WantListBroadcaster sendBlocks*: BlocksBroadcaster sendPresence*: PresenceBroadcaster - sendPricing*: PricingBroadcaster + sendAccount*: AccountBroadcaster sendPayment*: PaymentBroadcaster BitswapNetwork* = ref object of LPProtocol @@ -202,20 +202,20 @@ proc broadcastBlockPresence*( trace "Sending presence to peer", peer = id asyncSpawn b.peers[id].send(Message(blockPresences: presence)) -proc handlePricing(network: BitswapNetwork, +proc handleAccount(network: BitswapNetwork, peer: NetworkPeer, - pricing: Pricing) = - if network.handlers.onPricing.isNil: + account: Account) = + if network.handlers.onAccount.isNil: return - network.handlers.onPricing(peer.id, pricing) + network.handlers.onAccount(peer.id, account) -proc broadcastPricing*(network: BitswapNetwork, - id: PeerId, - pricing: Pricing) = +proc broadcastAccount*(network: BitswapNetwork, + id: PeerId, + account: Account) = if id notin network.peers: return - let message = Message(pricing: PricingMessage.init(pricing)) + let message = Message(account: AccountMessage.init(account)) asyncSpawn network.peers[id].send(message) proc broadcastPayment*(network: BitswapNetwork, @@ -248,8 +248,8 @@ proc rpcHandler(b: BitswapNetwork, peer: NetworkPeer, msg: Message) {.async.} = if msg.blockPresences.len > 0: b.handleBlockPresence(peer, msg.blockPresences) - if pricing =? Pricing.init(msg.pricing): - b.handlePricing(peer, pricing) + if account =? Account.init(msg.account): + b.handleAccount(peer, account) if payment =? SignedState.init(msg.payment): b.handlePayment(peer, payment) @@ -347,8 +347,8 @@ proc new*( proc sendPresence(id: PeerID, presence: seq[BlockPresence]) {.gcsafe.} = b.broadcastBlockPresence(id, presence) - proc sendPricing(id: PeerID, pricing: Pricing) = - b.broadcastPricing(id, pricing) + proc sendAccount(id: PeerID, account: Account) = + b.broadcastAccount(id, account) proc sendPayment(id: PeerID, payment: SignedState) = b.broadcastPayment(id, payment) @@ -357,7 +357,7 @@ proc new*( sendWantList: sendWantList, sendBlocks: sendBlocks, sendPresence: sendPresence, - sendPricing: sendPricing, + sendAccount: sendAccount, sendPayment: sendPayment ) diff --git a/dagger/bitswap/peercontext.nim b/dagger/bitswap/peercontext.nim index cc385c7a..74fcd909 100644 --- a/dagger/bitswap/peercontext.nim +++ b/dagger/bitswap/peercontext.nim @@ -18,7 +18,7 @@ type peerWants*: seq[Entry] # remote peers want lists exchanged*: int # times peer has exchanged with us lastExchange*: Moment # last time peer has exchanged with us - pricing*: ?Pricing # optional bandwidth price for this peer + account*: ?Account # ethereum account of this peer paymentChannel*: ?ChannelId # payment channel id proc peerHave*(context: BitswapPeerCtx): seq[Cid] = diff --git a/dagger/bitswap/protobuf/bitswap.nim b/dagger/bitswap/protobuf/bitswap.nim index e436bd0b..b7b7bf47 100644 --- a/dagger/bitswap/protobuf/bitswap.nim +++ b/dagger/bitswap/protobuf/bitswap.nim @@ -17,7 +17,7 @@ import_proto3 "message.proto" export Message export Wantlist, WantType, Entry export Block, BlockPresenceType, BlockPresence -export PricingMessage, StateChannelUpdate +export AccountMessage, StateChannelUpdate proc hash*(e: Entry): Hash = hash(e.`block`) diff --git a/dagger/bitswap/protobuf/message.proto b/dagger/bitswap/protobuf/message.proto index af4e2562..ac8b4e88 100644 --- a/dagger/bitswap/protobuf/message.proto +++ b/dagger/bitswap/protobuf/message.proto @@ -35,12 +35,11 @@ message Message { message BlockPresence { bytes cid = 1; BlockPresenceType type = 2; - bytes price = 3; // Amount of assets to pay per byte (UInt256) + bytes price = 3; // Amount of assets to pay for the block (UInt256) } - message PricingMessage { - bytes address = 1; // Ethereum address to which payments should be made - bytes price = 3; // Amount of assets to pay per byte (UInt256) + message AccountMessage { + bytes address = 1; // Ethereum address to which payments should be made } message StateChannelUpdate { @@ -52,6 +51,6 @@ message Message { repeated Block payload = 3; // used to send Blocks in bitswap 1.1.0 repeated BlockPresence blockPresences = 4; int32 pendingBytes = 5; - PricingMessage pricing = 6; + AccountMessage account = 6; StateChannelUpdate payment = 7; } diff --git a/dagger/bitswap/protobuf/payments.nim b/dagger/bitswap/protobuf/payments.nim index e01706e3..078b5f61 100644 --- a/dagger/bitswap/protobuf/payments.nim +++ b/dagger/bitswap/protobuf/payments.nim @@ -6,7 +6,7 @@ import pkg/questionable import pkg/upraises import ./bitswap -export PricingMessage +export AccountMessage export StateChannelUpdate export stint @@ -15,15 +15,11 @@ export nitro push: {.upraises: [].} type - Pricing* = object + Account* = object address*: EthAddress - price*: UInt256 -func init*(_: type PricingMessage, pricing: Pricing): PricingMessage = - PricingMessage( - address: @(pricing.address.toArray), - price: @(pricing.price.toBytesBE) - ) +func init*(_: type AccountMessage, account: Account): AccountMessage = + AccountMessage(address: @(account.address.toArray)) func parse(_: type EthAddress, bytes: seq[byte]): ?EthAddress = var address: array[20, byte] @@ -33,16 +29,10 @@ func parse(_: type EthAddress, bytes: seq[byte]): ?EthAddress = address[i] = bytes[i] EthAddress(address).some -func parse(_: type UInt256, bytes: seq[byte]): ?UInt256 = - if bytes.len > 32: - return UInt256.none - UInt256.fromBytesBE(bytes).some - -func init*(_: type Pricing, message: PricingMessage): ?Pricing = - without address =? EthAddress.parse(message.address) and - price =? UInt256.parse(message.price): - return Pricing.none - Pricing(address: address, price: price).some +func init*(_: type Account, message: AccountMessage): ?Account = + without address =? EthAddress.parse(message.address): + return none Account + some Account(address: address) func init*(_: type StateChannelUpdate, state: SignedState): StateChannelUpdate = StateChannelUpdate(update: state.toJson.toBytes) diff --git a/tests/dagger/bitswap/engine/testpayments.nim b/tests/dagger/bitswap/engine/testpayments.nim index 55427d0d..c46a2b5e 100644 --- a/tests/dagger/bitswap/engine/testpayments.nim +++ b/tests/dagger/bitswap/engine/testpayments.nim @@ -4,6 +4,7 @@ import ../../examples suite "engine payments": + let address = EthAddress.example let amount = 42.u256 var wallet: WalletRef @@ -12,17 +13,16 @@ suite "engine payments": setup: wallet = WalletRef.example peer = BitswapPeerCtx.example - peer.pricing = Pricing.example.some + peer.account = Account(address: address).some test "pays for received blocks": let payment = !wallet.pay(peer, amount) - let pricing = !peer.pricing let balances = payment.state.outcome.balances(Asset) - let destination = pricing.address.toDestination + let destination = address.toDestination check !balances[destination] == amount - test "no payment when no price is set": - peer.pricing = Pricing.none + test "no payment when no account is set": + peer.account = Account.none check wallet.pay(peer, amount).isFailure test "uses same channel for consecutive payments": diff --git a/tests/dagger/bitswap/protobuf/testpayments.nim b/tests/dagger/bitswap/protobuf/testpayments.nim index 76b35984..3fceecdc 100644 --- a/tests/dagger/bitswap/protobuf/testpayments.nim +++ b/tests/dagger/bitswap/protobuf/testpayments.nim @@ -4,34 +4,21 @@ import pkg/stew/byteutils import ../../examples import ../../../../dagger/bitswap/protobuf/payments -suite "pricing protobuf messages": +suite "account protobuf messages": - let address = EthAddress.example - let price = UInt256.example - let pricing = Pricing(address: address, price: price) - let message = PricingMessage.init(pricing) + let account = Account(address: EthAddress.example) + let message = AccountMessage.init(account) test "encodes recipient of payments": - check message.address == @(address.toArray) - - test "encodes price per byte": - check message.price == @(price.toBytesBE) + check message.address == @(account.address.toArray) test "decodes recipient of payments": - check Pricing.init(message).?address == address.some - - test "decodes price": - check Pricing.init(message).?price == price.some + check Account.init(message).?address == account.address.some test "fails to decode when address has incorrect number of bytes": var incorrect = message incorrect.address.del(0) - check Pricing.init(incorrect).isNone - - test "fails to decode when price has too many bytes": - var incorrect = message - incorrect.price = newSeq[byte](33) - check Pricing.init(incorrect).isNone + check Account.init(incorrect).isNone suite "channel update messages": diff --git a/tests/dagger/bitswap/testbitswap.nim b/tests/dagger/bitswap/testbitswap.nim index 673277a1..b5ae1a4d 100644 --- a/tests/dagger/bitswap/testbitswap.nim +++ b/tests/dagger/bitswap/testbitswap.nim @@ -103,9 +103,9 @@ suite "Bitswap engine - 2 nodes": peerCtx2.peerHave.mapIt( $it ).sorted(cmp[string]) == bitswap1.engine.wantList.mapIt( $it ).sorted(cmp[string]) - test "exchanges pricing on connect": - check peerCtx1.pricing == pricing1.some - check peerCtx2.pricing == pricing2.some + test "exchanges accounts on connect": + check peerCtx1.account.?address == pricing1.address.some + check peerCtx2.account.?address == pricing2.address.some test "should send want-have for block": let blk = bt.Block.new("Block 1".toBytes) @@ -152,7 +152,6 @@ suite "Bitswap engine - 2 nodes": test "receives payments for blocks that were sent": let blocks = await bitswap1.getBlocks(blocks2.mapIt(it.cid)) - let pricing = !bitswap2.engine.pricing await sleepAsync(100.millis) let channel = !peerCtx1.paymentChannel check wallet2.balance(channel, Asset) > 0 diff --git a/tests/dagger/bitswap/testengine.nim b/tests/dagger/bitswap/testengine.nim index 6b37538d..fabec292 100644 --- a/tests/dagger/bitswap/testengine.nim +++ b/tests/dagger/bitswap/testengine.nim @@ -57,14 +57,14 @@ suite "Bitswap engine basic": await done - test "sends pricing to new peers": + test "sends account to new peers": let pricing = Pricing.example - proc sendPricing(peer: PeerID, toBeSent: Pricing) = - check toBeSent == pricing + proc sendAccount(peer: PeerID, account: Account) = + check account.address == pricing.address done.complete() - let request = BitswapRequest(sendPricing: sendPricing) + let request = BitswapRequest(sendAccount: sendAccount) let engine = BitswapEngine.new(MemoryStore.new, wallet, request) engine.pricing = pricing.some @@ -153,16 +153,16 @@ suite "Bitswap engine handlers": check engine.localStore.hasBlock(b.cid) test "sends payments for received blocks": - let pricing = Pricing.example + let account = Account(address: EthAddress.example) let peerContext = engine.getPeerCtx(peerId) - peerContext.pricing = pricing.some + peerContext.account = account.some peerContext.peerPrices = blocks.mapIt((it.cid, rand(uint16).u256)).toTable engine.request.sendPayment = proc(receiver: PeerID, payment: SignedState) = let amount = blocks.mapIt(peerContext.peerPrices[it.cid]).foldl(a+b) let balances = !payment.state.outcome.balances(Asset) check receiver == peerId - check balances[pricing.address.toDestination] == amount + check balances[account.address.toDestination] == amount done.complete() engine.blocksHandler(peerId, blocks) diff --git a/tests/dagger/bitswap/testnetwork.nim b/tests/dagger/bitswap/testnetwork.nim index 69fe68c7..92077027 100644 --- a/tests/dagger/bitswap/testnetwork.nim +++ b/tests/dagger/bitswap/testnetwork.nim @@ -103,16 +103,16 @@ suite "Bitswap network": await done.wait(500.millis) - test "handles pricing messages": - let pricing = Pricing.example + test "handles account messages": + let account = Account(address: EthAddress.example) - proc handlePricing(peer: PeerID, received: Pricing) = - check received == pricing + proc handleAccount(peer: PeerID, received: Account) = + check received == account done.complete() - network.handlers.onPricing = handlePricing + network.handlers.onAccount = handleAccount - let message = Message(pricing: PricingMessage.init(pricing)) + let message = Message(account: AccountMessage.init(account)) await buffer.pushData(lenPrefix(Protobuf.encode(message))) await done.wait(100.millis) @@ -224,16 +224,16 @@ suite "Bitswap Network - e2e": await done.wait(500.millis) - test "broadcasts pricing": - let pricing = Pricing.example + test "broadcasts account": + let account = Account(address: EthAddress.example) - proc handlePricing(peer: PeerID, received: Pricing) = - check received == pricing + proc handleAccount(peer: PeerID, received: Account) = + check received == account done.complete() - network2.handlers.onPricing = handlePricing + network2.handlers.onAccount = handleAccount - network1.broadcastPricing(switch2.peerInfo.peerId, pricing) + network1.broadcastAccount(switch2.peerInfo.peerId, account) await done.wait(100.millis) diff --git a/tests/dagger/examples.nim b/tests/dagger/examples.nim index d36dcc99..d749e83f 100644 --- a/tests/dagger/examples.nim +++ b/tests/dagger/examples.nim @@ -5,6 +5,7 @@ import pkg/nitro import pkg/dagger/p2p/rng import pkg/dagger/bitswap/protobuf/payments import pkg/dagger/bitswap/peercontext +import pkg/dagger/bitswap/engine import pkg/dagger/blocktype proc example*(_: type EthAddress): EthAddress =