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 hexdump
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import asyncdispatch2, nimcrypto, strutils, os
|
||||
import chronos, nimcrypto, strutils, os
|
||||
import ../libp2p/daemon/daemonapi, ../libp2p/[base58, multiaddress]
|
||||
|
||||
proc main(bn: string) {.async.} =
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
## This module implementes API for `go-libp2p-daemon`.
|
||||
import os, osproc, strutils, tables, streams, strtabs
|
||||
import chronos
|
||||
import ../varint, ../multiaddress, ../multicodec, ../base58, ../cid
|
||||
import ../varint, ../multiaddress, ../multicodec, ../base58, ../cid, ../peer
|
||||
import ../wire, ../protobuf/minprotobuf
|
||||
|
||||
when not defined(windows):
|
||||
|
@ -76,7 +76,7 @@ type
|
|||
VALUE = 1,
|
||||
END = 2
|
||||
|
||||
PeerID* = seq[byte]
|
||||
# PeerID* = seq[byte]
|
||||
MultiProtocol* = string
|
||||
LibP2PPublicKey* = seq[byte]
|
||||
DHTValue* = seq[byte]
|
||||
|
@ -745,8 +745,7 @@ proc transactMessage(transp: StreamTransport,
|
|||
proc getPeerInfo(pb: var ProtoBuffer): PeerInfo =
|
||||
## Get PeerInfo object from ``pb``.
|
||||
result.addresses = newSeq[MultiAddress]()
|
||||
result.peer = newSeq[byte]()
|
||||
if pb.getBytes(1, result.peer) == -1:
|
||||
if pb.getValue(1, result.peer) == -1:
|
||||
raise newException(DaemonLocalError, "Missing required field `peer`!")
|
||||
var address = newSeq[byte]()
|
||||
while pb.getBytes(2, address) != -1:
|
||||
|
@ -803,10 +802,10 @@ proc openStream*(api: DaemonAPI, peer: PeerID,
|
|||
pb.withMessage() do:
|
||||
var res = pb.enterSubmessage()
|
||||
if res == cast[int](ResponseType.STREAMINFO):
|
||||
stream.peer = newSeq[byte]()
|
||||
# stream.peer = newSeq[byte]()
|
||||
var raddress = newSeq[byte]()
|
||||
stream.protocol = ""
|
||||
if pb.getLengthValue(1, stream.peer) == -1:
|
||||
if pb.getValue(1, stream.peer) == -1:
|
||||
raise newException(DaemonLocalError, "Missing `peer` field!")
|
||||
if pb.getLengthValue(2, raddress) == -1:
|
||||
raise newException(DaemonLocalError, "Missing `address` field!")
|
||||
|
@ -825,10 +824,9 @@ proc streamHandler(server: StreamServer, transp: StreamTransport) {.async.} =
|
|||
var message = await transp.recvMessage()
|
||||
var pb = initProtoBuffer(message)
|
||||
var stream = new P2PStream
|
||||
stream.peer = newSeq[byte]()
|
||||
var raddress = newSeq[byte]()
|
||||
stream.protocol = ""
|
||||
if pb.getLengthValue(1, stream.peer) == -1:
|
||||
if pb.getValue(1, stream.peer) == -1:
|
||||
raise newException(DaemonLocalError, "Missing `peer` field!")
|
||||
if pb.getLengthValue(2, raddress) == -1:
|
||||
raise newException(DaemonLocalError, "Missing `address` field!")
|
||||
|
@ -929,6 +927,10 @@ proc dhtGetSingleValue(pb: var ProtoBuffer): seq[byte] =
|
|||
if pb.getLengthValue(3, result) == -1:
|
||||
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.} =
|
||||
var dtype: uint
|
||||
var res = pb.enterSubmessage()
|
||||
|
@ -1074,7 +1076,7 @@ proc dhtGetClosestPeers*(api: DaemonAPI, key: string,
|
|||
var cpb = initProtoBuffer(message)
|
||||
if cpb.getDhtMessageType() == DHTResponseType.END:
|
||||
break
|
||||
list.add(cpb.dhtGetSingleValue())
|
||||
list.add(cpb.dhtGetSinglePeerID())
|
||||
result = list
|
||||
finally:
|
||||
await api.closeConnection(transp)
|
||||
|
@ -1152,12 +1154,11 @@ proc pubsubListPeers*(api: DaemonAPI,
|
|||
try:
|
||||
var pb = await transp.transactMessage(requestPSListPeers(topic))
|
||||
withMessage(pb) do:
|
||||
var peer: PeerID
|
||||
pb.enterPsMessage()
|
||||
var peers = newSeq[PeerID]()
|
||||
var peer = newSeq[byte]()
|
||||
while pb.getBytes(2, peer) != -1:
|
||||
while pb.getValue(2, peer) != -1:
|
||||
peers.add(peer)
|
||||
peer.setLen(0)
|
||||
result = peers
|
||||
finally:
|
||||
await api.closeConnection(transp)
|
||||
|
@ -1174,28 +1175,25 @@ proc pubsubPublish*(api: DaemonAPI, topic: string,
|
|||
await api.closeConnection(transp)
|
||||
|
||||
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]()
|
||||
for field in 1..6:
|
||||
while true:
|
||||
if pb.getBytes(field, item) == -1:
|
||||
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 stritem = cast[string](copyitem)
|
||||
if len(result.topics) == 0:
|
||||
result.topics = newSeq[string]()
|
||||
result.topics.add(stritem)
|
||||
elif field == 5:
|
||||
result.signature = item
|
||||
elif field == 6:
|
||||
result.key = item
|
||||
item.setLen(0)
|
||||
while true:
|
||||
if pb.getBytes(4, item) == -1:
|
||||
break
|
||||
var copyitem = item
|
||||
var stritem = cast[string](copyitem)
|
||||
if len(result.topics) == 0:
|
||||
result.topics = newSeq[string]()
|
||||
result.topics.add(stritem)
|
||||
item.setLen(0)
|
||||
discard pb.getBytes(5, result.signature)
|
||||
discard pb.getBytes(6, result.key)
|
||||
|
||||
proc pubsubLoop(api: DaemonAPI, ticket: PubsubTicket) {.async.} =
|
||||
while true:
|
||||
|
@ -1232,7 +1230,7 @@ proc `$`*(pinfo: PeerInfo): string =
|
|||
## Get string representation of ``PeerInfo`` object.
|
||||
result = newStringOfCap(128)
|
||||
result.add("{PeerID: '")
|
||||
result.add(Base58.encode(pinfo.peer))
|
||||
result.add($pinfo.peer.pretty())
|
||||
result.add("' Addresses: [")
|
||||
let length = len(pinfo.addresses)
|
||||
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