protobuf message for bandwidth pricing

This commit is contained in:
Mark Spanbroek 2021-04-07 12:19:00 +02:00 committed by markspanbroek
parent 37c065f160
commit 1f2a9f90d5
5 changed files with 109 additions and 0 deletions

View File

@ -0,0 +1,43 @@
import pkg/protobuf_serialization
import pkg/nitro
import pkg/questionable
import_proto3 "payments.proto"
export PricingMessage
export nitro
type
Pricing* = object
address*: EthAddress
asset*: EthAddress
price*: UInt256
func init*(_: type PricingMessage, pricing: Pricing): PricingMessage =
PricingMessage(
address: @(pricing.address.toArray),
asset: @(pricing.asset.toArray),
price: @(pricing.price.toBytesBE)
)
func parse(_: type EthAddress, bytes: seq[byte]): ?EthAddress =
var address: array[20, byte]
if bytes.len != address.len:
return EthAddress.none
for i in 0..<address.len:
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 =
let address = EthAddress.parse(message.address)
let asset = EThAddress.parse(message.asset)
let price = UInt256.parse(message.price)
if address.isNone or asset.isNone or price.isNone:
return Pricing.none
Pricing(address: address.get, asset: asset.get, price: price.get).some

View File

@ -0,0 +1,9 @@
syntax = "proto3";
package bitswap.payments.pb;
message PricingMessage {
bytes address = 1; // Ethereum address to which payments should be made
bytes asset = 2; // Asset (coin) with which to pay
bytes price = 3; // Amount of assets to pay per byte (UInt256)
}

View File

@ -0,0 +1,45 @@
import pkg/asynctest
import pkg/chronos
import ../../examples
import ../../../../dagger/bitswap/protobuf/payments
suite "pricing protobuf messages":
let address = EthAddress.example
let asset = EthAddress.example
let price = UInt256.example
let pricing = Pricing(address: address, asset: asset, price: price)
let message = PricingMessage.init(pricing)
test "encodes recipient of payments":
check message.address == @(address.toArray)
test "encodes address of asset":
check message.asset == @(asset.toArray)
test "encodes price per byte":
check message.price == @(price.toBytesBE)
test "decodes recipient of payments":
check Pricing.init(message)?.address == address.some
test "decodes address of asset":
check Pricing.init(message)?.asset == asset.some
test "decodes price":
check Pricing.init(message)?.price == price.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 asset has incorrect number of bytes":
var incorrect = message
incorrect.asset.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

11
tests/dagger/examples.nim Normal file
View File

@ -0,0 +1,11 @@
import std/random
import pkg/nitro
proc example*(_: type EthAddress): EthAddress =
EthPrivateKey.random().toPublicKey.toAddress
proc example*(_: type UInt256): UInt256 =
var bytes: array[32, byte]
for b in bytes.mitems:
b = rand(byte)
UInt256.fromBytes(bytes)

View File

@ -1,6 +1,7 @@
import ./dagger/bitswap/testbitswap
import ./dagger/bitswap/testengine
import ./dagger/bitswap/testnetwork
import ./dagger/bitswap/protobuf/testpayments
import ./dagger/testasyncheapqueue
import ./dagger/testblockstore
import ./dagger/testchunking