Fix examples.
Add peer.nim. Switch daemonapi to use PeerID from peer.nim.
This commit is contained in:
parent
e6c424618d
commit
1e6c8b2171
|
@ -1,4 +1,4 @@
|
||||||
import asyncdispatch2, nimcrypto, strutils
|
import chronos, nimcrypto, strutils
|
||||||
import ../libp2p/daemon/daemonapi, ../libp2p/[base58, multicodec, multiaddress]
|
import ../libp2p/daemon/daemonapi, ../libp2p/[base58, multicodec, multiaddress]
|
||||||
import hexdump
|
import hexdump
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import asyncdispatch2, nimcrypto, strutils, os
|
import chronos, nimcrypto, strutils, os
|
||||||
import ../libp2p/daemon/daemonapi, ../libp2p/[base58, multiaddress]
|
import ../libp2p/daemon/daemonapi, ../libp2p/[base58, multiaddress]
|
||||||
|
|
||||||
proc main(bn: string) {.async.} =
|
proc main(bn: string) {.async.} =
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
## This module implementes API for `go-libp2p-daemon`.
|
## This module implementes API for `go-libp2p-daemon`.
|
||||||
import os, osproc, strutils, tables, streams, strtabs
|
import os, osproc, strutils, tables, streams, strtabs
|
||||||
import chronos
|
import chronos
|
||||||
import ../varint, ../multiaddress, ../multicodec, ../base58, ../cid
|
import ../varint, ../multiaddress, ../multicodec, ../base58, ../cid, ../peer
|
||||||
import ../wire, ../protobuf/minprotobuf
|
import ../wire, ../protobuf/minprotobuf
|
||||||
|
|
||||||
when not defined(windows):
|
when not defined(windows):
|
||||||
|
@ -76,7 +76,7 @@ type
|
||||||
VALUE = 1,
|
VALUE = 1,
|
||||||
END = 2
|
END = 2
|
||||||
|
|
||||||
PeerID* = seq[byte]
|
# PeerID* = seq[byte]
|
||||||
MultiProtocol* = string
|
MultiProtocol* = string
|
||||||
LibP2PPublicKey* = seq[byte]
|
LibP2PPublicKey* = seq[byte]
|
||||||
DHTValue* = seq[byte]
|
DHTValue* = seq[byte]
|
||||||
|
@ -745,8 +745,7 @@ proc transactMessage(transp: StreamTransport,
|
||||||
proc getPeerInfo(pb: var ProtoBuffer): PeerInfo =
|
proc getPeerInfo(pb: var ProtoBuffer): PeerInfo =
|
||||||
## Get PeerInfo object from ``pb``.
|
## Get PeerInfo object from ``pb``.
|
||||||
result.addresses = newSeq[MultiAddress]()
|
result.addresses = newSeq[MultiAddress]()
|
||||||
result.peer = newSeq[byte]()
|
if pb.getValue(1, result.peer) == -1:
|
||||||
if pb.getBytes(1, result.peer) == -1:
|
|
||||||
raise newException(DaemonLocalError, "Missing required field `peer`!")
|
raise newException(DaemonLocalError, "Missing required field `peer`!")
|
||||||
var address = newSeq[byte]()
|
var address = newSeq[byte]()
|
||||||
while pb.getBytes(2, address) != -1:
|
while pb.getBytes(2, address) != -1:
|
||||||
|
@ -803,10 +802,10 @@ proc openStream*(api: DaemonAPI, peer: PeerID,
|
||||||
pb.withMessage() do:
|
pb.withMessage() do:
|
||||||
var res = pb.enterSubmessage()
|
var res = pb.enterSubmessage()
|
||||||
if res == cast[int](ResponseType.STREAMINFO):
|
if res == cast[int](ResponseType.STREAMINFO):
|
||||||
stream.peer = newSeq[byte]()
|
# stream.peer = newSeq[byte]()
|
||||||
var raddress = newSeq[byte]()
|
var raddress = newSeq[byte]()
|
||||||
stream.protocol = ""
|
stream.protocol = ""
|
||||||
if pb.getLengthValue(1, stream.peer) == -1:
|
if pb.getValue(1, stream.peer) == -1:
|
||||||
raise newException(DaemonLocalError, "Missing `peer` field!")
|
raise newException(DaemonLocalError, "Missing `peer` field!")
|
||||||
if pb.getLengthValue(2, raddress) == -1:
|
if pb.getLengthValue(2, raddress) == -1:
|
||||||
raise newException(DaemonLocalError, "Missing `address` field!")
|
raise newException(DaemonLocalError, "Missing `address` field!")
|
||||||
|
@ -825,10 +824,9 @@ proc streamHandler(server: StreamServer, transp: StreamTransport) {.async.} =
|
||||||
var message = await transp.recvMessage()
|
var message = await transp.recvMessage()
|
||||||
var pb = initProtoBuffer(message)
|
var pb = initProtoBuffer(message)
|
||||||
var stream = new P2PStream
|
var stream = new P2PStream
|
||||||
stream.peer = newSeq[byte]()
|
|
||||||
var raddress = newSeq[byte]()
|
var raddress = newSeq[byte]()
|
||||||
stream.protocol = ""
|
stream.protocol = ""
|
||||||
if pb.getLengthValue(1, stream.peer) == -1:
|
if pb.getValue(1, stream.peer) == -1:
|
||||||
raise newException(DaemonLocalError, "Missing `peer` field!")
|
raise newException(DaemonLocalError, "Missing `peer` field!")
|
||||||
if pb.getLengthValue(2, raddress) == -1:
|
if pb.getLengthValue(2, raddress) == -1:
|
||||||
raise newException(DaemonLocalError, "Missing `address` field!")
|
raise newException(DaemonLocalError, "Missing `address` field!")
|
||||||
|
@ -929,6 +927,10 @@ proc dhtGetSingleValue(pb: var ProtoBuffer): seq[byte] =
|
||||||
if pb.getLengthValue(3, result) == -1:
|
if pb.getLengthValue(3, result) == -1:
|
||||||
raise newException(DaemonLocalError, "Missing field `value`!")
|
raise newException(DaemonLocalError, "Missing field `value`!")
|
||||||
|
|
||||||
|
proc dhtGetSinglePeerID(pb: var ProtoBuffer): PeerID =
|
||||||
|
if pb.getValue(3, result) == -1:
|
||||||
|
raise newException(DaemonLocalError, "Missing field `value`!")
|
||||||
|
|
||||||
proc enterDhtMessage(pb: var ProtoBuffer, rt: DHTResponseType) {.inline.} =
|
proc enterDhtMessage(pb: var ProtoBuffer, rt: DHTResponseType) {.inline.} =
|
||||||
var dtype: uint
|
var dtype: uint
|
||||||
var res = pb.enterSubmessage()
|
var res = pb.enterSubmessage()
|
||||||
|
@ -1074,7 +1076,7 @@ proc dhtGetClosestPeers*(api: DaemonAPI, key: string,
|
||||||
var cpb = initProtoBuffer(message)
|
var cpb = initProtoBuffer(message)
|
||||||
if cpb.getDhtMessageType() == DHTResponseType.END:
|
if cpb.getDhtMessageType() == DHTResponseType.END:
|
||||||
break
|
break
|
||||||
list.add(cpb.dhtGetSingleValue())
|
list.add(cpb.dhtGetSinglePeerID())
|
||||||
result = list
|
result = list
|
||||||
finally:
|
finally:
|
||||||
await api.closeConnection(transp)
|
await api.closeConnection(transp)
|
||||||
|
@ -1152,12 +1154,11 @@ proc pubsubListPeers*(api: DaemonAPI,
|
||||||
try:
|
try:
|
||||||
var pb = await transp.transactMessage(requestPSListPeers(topic))
|
var pb = await transp.transactMessage(requestPSListPeers(topic))
|
||||||
withMessage(pb) do:
|
withMessage(pb) do:
|
||||||
|
var peer: PeerID
|
||||||
pb.enterPsMessage()
|
pb.enterPsMessage()
|
||||||
var peers = newSeq[PeerID]()
|
var peers = newSeq[PeerID]()
|
||||||
var peer = newSeq[byte]()
|
while pb.getValue(2, peer) != -1:
|
||||||
while pb.getBytes(2, peer) != -1:
|
|
||||||
peers.add(peer)
|
peers.add(peer)
|
||||||
peer.setLen(0)
|
|
||||||
result = peers
|
result = peers
|
||||||
finally:
|
finally:
|
||||||
await api.closeConnection(transp)
|
await api.closeConnection(transp)
|
||||||
|
@ -1174,28 +1175,25 @@ proc pubsubPublish*(api: DaemonAPI, topic: string,
|
||||||
await api.closeConnection(transp)
|
await api.closeConnection(transp)
|
||||||
|
|
||||||
proc getPubsubMessage*(pb: var ProtoBuffer): PubSubMessage =
|
proc getPubsubMessage*(pb: var ProtoBuffer): PubSubMessage =
|
||||||
|
result.data = newSeq[byte]()
|
||||||
|
result.seqno = newSeq[byte]()
|
||||||
|
result.signature = newSeq[byte]()
|
||||||
|
result.key = newSeq[byte]()
|
||||||
|
discard pb.getValue(1, result.peer)
|
||||||
|
discard pb.getBytes(2, result.data)
|
||||||
|
discard pb.getBytes(3, result.seqno)
|
||||||
var item = newSeq[byte]()
|
var item = newSeq[byte]()
|
||||||
for field in 1..6:
|
|
||||||
while true:
|
while true:
|
||||||
if pb.getBytes(field, item) == -1:
|
if pb.getBytes(4, item) == -1:
|
||||||
break
|
break
|
||||||
if field == 1:
|
|
||||||
result.peer = item
|
|
||||||
elif field == 2:
|
|
||||||
result.data = item
|
|
||||||
elif field == 3:
|
|
||||||
result.seqno = item
|
|
||||||
elif field == 4:
|
|
||||||
var copyitem = item
|
var copyitem = item
|
||||||
var stritem = cast[string](copyitem)
|
var stritem = cast[string](copyitem)
|
||||||
if len(result.topics) == 0:
|
if len(result.topics) == 0:
|
||||||
result.topics = newSeq[string]()
|
result.topics = newSeq[string]()
|
||||||
result.topics.add(stritem)
|
result.topics.add(stritem)
|
||||||
elif field == 5:
|
|
||||||
result.signature = item
|
|
||||||
elif field == 6:
|
|
||||||
result.key = item
|
|
||||||
item.setLen(0)
|
item.setLen(0)
|
||||||
|
discard pb.getBytes(5, result.signature)
|
||||||
|
discard pb.getBytes(6, result.key)
|
||||||
|
|
||||||
proc pubsubLoop(api: DaemonAPI, ticket: PubsubTicket) {.async.} =
|
proc pubsubLoop(api: DaemonAPI, ticket: PubsubTicket) {.async.} =
|
||||||
while true:
|
while true:
|
||||||
|
@ -1232,7 +1230,7 @@ proc `$`*(pinfo: PeerInfo): string =
|
||||||
## Get string representation of ``PeerInfo`` object.
|
## Get string representation of ``PeerInfo`` object.
|
||||||
result = newStringOfCap(128)
|
result = newStringOfCap(128)
|
||||||
result.add("{PeerID: '")
|
result.add("{PeerID: '")
|
||||||
result.add(Base58.encode(pinfo.peer))
|
result.add($pinfo.peer.pretty())
|
||||||
result.add("' Addresses: [")
|
result.add("' Addresses: [")
|
||||||
let length = len(pinfo.addresses)
|
let length = len(pinfo.addresses)
|
||||||
for i in 0..<length:
|
for i in 0..<length:
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
## Nim-LibP2P
|
||||||
|
## Copyright (c) 2018 Status Research & Development GmbH
|
||||||
|
## Licensed under either of
|
||||||
|
## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||||
|
## * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||||
|
## at your option.
|
||||||
|
## This file may not be copied, modified, or distributed except according to
|
||||||
|
## those terms.
|
||||||
|
|
||||||
|
## This module implementes API for libp2p peer.
|
||||||
|
import hashes
|
||||||
|
import nimcrypto/utils
|
||||||
|
import crypto/crypto, multicodec, multihash, base58, vbuffer
|
||||||
|
import protobuf/minprotobuf
|
||||||
|
|
||||||
|
const
|
||||||
|
maxInlineKeyLength* = 42
|
||||||
|
|
||||||
|
type
|
||||||
|
PeerID* = distinct seq[byte]
|
||||||
|
|
||||||
|
proc pretty*(peerid: PeerID): string {.inline.} =
|
||||||
|
## Return base58 encoded ``peerid`` representation.
|
||||||
|
Base58.encode(cast[seq[byte]](peerid))
|
||||||
|
|
||||||
|
proc toBytes*(peerid: PeerID, data: var openarray[byte]): int =
|
||||||
|
## Store PeerID ``peerid`` to array of bytes ``data``.
|
||||||
|
##
|
||||||
|
## Returns number of bytes needed to store ``peerid``.
|
||||||
|
var p = cast[seq[byte]](peerid)
|
||||||
|
result = len(p)
|
||||||
|
if len(data) >= result and result > 0:
|
||||||
|
copyMem(addr data[0], addr p[0], result)
|
||||||
|
|
||||||
|
proc getBytes*(peerid: PeerID): seq[byte] {.inline.} =
|
||||||
|
## Return PeerID as array of bytes.
|
||||||
|
var p = cast[seq[byte]](peerid)
|
||||||
|
result = @p
|
||||||
|
|
||||||
|
proc fromKey*(pubkey: PublicKey): PeerID =
|
||||||
|
## Returns the PeerID corresponding to public key ``pubkey``.
|
||||||
|
var pubraw = pubkey.getBytes()
|
||||||
|
var mh: MultiHash
|
||||||
|
var codec: MultiCodec
|
||||||
|
if len(pubraw) <= maxInlineKeyLength:
|
||||||
|
mh = MultiHash.digest("identity", pubraw)
|
||||||
|
else:
|
||||||
|
mh = MultiHash.digest("sha2-256", pubraw)
|
||||||
|
result = cast[PeerID](mh.data.buffer)
|
||||||
|
|
||||||
|
proc fromKey*(seckey: PrivateKey): PeerID {.inline.} =
|
||||||
|
## Returns the PeerID corresponding to private key ``seckey``.
|
||||||
|
result = fromKey(seckey.getKey())
|
||||||
|
|
||||||
|
proc hex*(peerid: PeerID): string =
|
||||||
|
## Returns hexadecimal string representation of ``peerid``.
|
||||||
|
var p = cast[seq[byte]](peerid)
|
||||||
|
if len(p) > 0:
|
||||||
|
result = toHex(p)
|
||||||
|
|
||||||
|
proc len*(a: PeerID): int {.borrow.}
|
||||||
|
|
||||||
|
proc cmp*(a, b: PeerID): int =
|
||||||
|
## Compares two peer ids ``a`` and ``b``.
|
||||||
|
## Returns:
|
||||||
|
##
|
||||||
|
## | 0 iff a == b
|
||||||
|
## | < 0 iff a < b
|
||||||
|
## | > 0 iff a > b
|
||||||
|
var ab = cast[seq[byte]](a)
|
||||||
|
var bb = cast[seq[byte]](b)
|
||||||
|
var i = 0
|
||||||
|
var m = min(len(ab), len(bb))
|
||||||
|
while i < m:
|
||||||
|
result = ord(ab[i]) - ord(bb[i])
|
||||||
|
if result != 0: return
|
||||||
|
inc(i)
|
||||||
|
result = len(ab) - len(bb)
|
||||||
|
|
||||||
|
proc `<=`*(a, b: PeerID): bool {.inline.} =
|
||||||
|
(cmp(a, b) <= 0)
|
||||||
|
|
||||||
|
proc `<`*(a, b: PeerID): bool {.inline.} =
|
||||||
|
(cmp(a, b) < 0)
|
||||||
|
|
||||||
|
proc `>=`*(a, b: PeerID): bool {.inline.} =
|
||||||
|
(cmp(a, b) >= 0)
|
||||||
|
|
||||||
|
proc `>`*(a, b: PeerID): bool {.inline.} =
|
||||||
|
(cmp(a, b) > 0)
|
||||||
|
|
||||||
|
proc `==`*(a, b: PeerID): bool {.inline.} =
|
||||||
|
(cmp(a, b) == 0)
|
||||||
|
|
||||||
|
proc hash*(peerid: PeerID): Hash {.inline.} =
|
||||||
|
var p = cast[seq[byte]](peerid)
|
||||||
|
result = hash(p)
|
||||||
|
|
||||||
|
proc validate*(peerid: PeerID): bool =
|
||||||
|
## Validate check if ``peerid`` is empty or not.
|
||||||
|
var p = cast[seq[byte]](peerid)
|
||||||
|
if len(p) > 0:
|
||||||
|
result = MultiHash.validate(p)
|
||||||
|
|
||||||
|
proc hasPublicKey*(peerid: PeerID): bool =
|
||||||
|
## Returns ``true`` if ``peerid`` is small enough to hold public key inside.
|
||||||
|
var mh: MultiHash
|
||||||
|
var p = cast[seq[byte]](peerid)
|
||||||
|
if len(p) > 0:
|
||||||
|
if MultiHash.decode(p, mh) > 0:
|
||||||
|
if mh.mcodec == multiCodec("identity"):
|
||||||
|
result = true
|
||||||
|
|
||||||
|
proc extractPublicKey*(peerid: PeerID, pubkey: var PublicKey): bool =
|
||||||
|
## Returns ``true`` if public key was successfully decoded and stored
|
||||||
|
## in ``pubkey``.
|
||||||
|
##
|
||||||
|
## Returns ``false`` otherwise
|
||||||
|
var mh: MultiHash
|
||||||
|
var p = cast[seq[byte]](peerid)
|
||||||
|
if len(p) > 0:
|
||||||
|
if MultiHash.decode(p, mh) > 0:
|
||||||
|
if mh.mcodec == multiCodec("identity"):
|
||||||
|
let length = len(mh.data.buffer)
|
||||||
|
result = pubkey.init(mh.data.buffer.toOpenArray(mh.dpos, length - 1))
|
||||||
|
|
||||||
|
proc match*(peerid: PeerID, pubkey: PublicKey): bool {.inline.} =
|
||||||
|
## Returns ``true`` if ``peerid`` matches public key ``pubkey``.
|
||||||
|
result = (peerid == pubkey.fromKey())
|
||||||
|
|
||||||
|
proc match*(peerid: PeerID, seckey: PrivateKey): bool {.inline.} =
|
||||||
|
## Returns ``true`` if ``peerid`` matches private key ``seckey``.
|
||||||
|
result = (peerid == seckey.fromKey())
|
||||||
|
|
||||||
|
proc `$`*(peerid: PeerID): string =
|
||||||
|
## Returns compact string representation of ``peerid``.
|
||||||
|
var pid = peerid.pretty()
|
||||||
|
if len(pid) <= 10:
|
||||||
|
result = pid
|
||||||
|
else:
|
||||||
|
for i in 0..<2:
|
||||||
|
result.add(pid[i])
|
||||||
|
result.add("*")
|
||||||
|
for i in (len(pid) - 6)..(len(pid) - 1):
|
||||||
|
result.add(pid[i])
|
||||||
|
|
||||||
|
proc write*(vb: var VBuffer, peerid: PeerID) {.inline.} =
|
||||||
|
## Write PeerID value ``peerid`` to buffer ``vb``.
|
||||||
|
var p = cast[seq[byte]](peerid)
|
||||||
|
vb.writeSeq(p)
|
||||||
|
|
||||||
|
proc initProtoField*(index: int, peerid: PeerID): ProtoField =
|
||||||
|
## Initialize ProtoField with PeerID ``value``.
|
||||||
|
var p = cast[seq[byte]](peerid)
|
||||||
|
result = initProtoField(index, p)
|
||||||
|
|
||||||
|
proc getValue*(data: var ProtoBuffer, field: int, value: var PeerID): int =
|
||||||
|
## Read ``PeerID`` from ProtoBuf's message and validate it.
|
||||||
|
var buffer: seq[byte]
|
||||||
|
result = getLengthValue(data, field, buffer)
|
||||||
|
if result > 0:
|
||||||
|
value = cast[PeerID](buffer)
|
||||||
|
if not value.validate():
|
||||||
|
result = -1
|
Loading…
Reference in New Issue