Add PeerID support to multiaddress.

Change some PeerID api.
Some fixes to chat.
This commit is contained in:
cheatfate 2019-03-05 14:09:26 +02:00
parent 215c6c4257
commit a96718cf9e
No known key found for this signature in database
GPG Key ID: 46ADD633A7201F95
3 changed files with 83 additions and 42 deletions

View File

@ -1,5 +1,5 @@
import asyncdispatch2, nimcrypto, strutils import chronos, nimcrypto, strutils
import ../libp2p/daemon/daemonapi, ../libp2p/[base58, multiaddress] import ../libp2p/daemon/daemonapi
const const
ConsoleAddress = "/tmp/console-chat.sock" ConsoleAddress = "/tmp/console-chat.sock"
@ -39,10 +39,10 @@ proc serveThread(server: StreamServer,
if line.startsWith("/connect"): if line.startsWith("/connect"):
var parts = line.split(" ") var parts = line.split(" ")
if len(parts) == 2: if len(parts) == 2:
var peerId = Base58.decode(parts[1]) var peerId = PeerID.init(parts[1])
var address = MultiAddress.init(P_P2PCIRCUIT) var address = MultiAddress.init(multiCodec("p2p-circuit"))
address &= MultiAddress.init(P_P2P, peerId) address &= MultiAddress.init(multiCodec("p2p"), peerId)
echo "= Searching for peer ", parts[1] echo "= Searching for peer ", peerId.pretty()
var id = await udata.api.dhtFindPeer(peerId) var id = await udata.api.dhtFindPeer(peerId)
echo "= Peer " & parts[1] & " found at addresses:" echo "= Peer " & parts[1] & " found at addresses:"
for item in id.addresses: for item in id.addresses:
@ -57,8 +57,8 @@ proc serveThread(server: StreamServer,
elif line.startsWith("/search"): elif line.startsWith("/search"):
var parts = line.split(" ") var parts = line.split(" ")
if len(parts) == 2: if len(parts) == 2:
var peerId = Base58.decode(parts[1]) var peerId = PeerID.init(parts[1])
echo "= Searching for peer ", parts[1] echo "= Searching for peer ", peerId.pretty()
var id = await udata.api.dhtFindPeer(peerId) var id = await udata.api.dhtFindPeer(peerId)
echo "= Peer " & parts[1] & " found at addresses:" echo "= Peer " & parts[1] & " found at addresses:"
for item in id.addresses: for item in id.addresses:
@ -66,12 +66,12 @@ proc serveThread(server: StreamServer,
elif line.startsWith("/consearch"): elif line.startsWith("/consearch"):
var parts = line.split(" ") var parts = line.split(" ")
if len(parts) == 2: if len(parts) == 2:
var peerId = Base58.decode(parts[1]) var peerId = PeerID.init(parts[1])
echo "= Searching for peers connected to peer ", parts[1] echo "= Searching for peers connected to peer ", parts[1]
var peers = await udata.api.dhtFindPeersConnectedToPeer(peerId) var peers = await udata.api.dhtFindPeersConnectedToPeer(peerId)
echo "= Found ", len(peers), " connected to peer ", parts[1] echo "= Found ", len(peers), " connected to peer ", parts[1]
for item in peers: for item in peers:
var peer = Base58.encode(item.peer) var peer = item.peer
var addresses = newSeq[string]() var addresses = newSeq[string]()
var relay = false var relay = false
for a in item.addresses: for a in item.addresses:
@ -80,9 +80,9 @@ proc serveThread(server: StreamServer,
relay = true relay = true
break break
if relay: if relay:
echo peer, " * ", " [", addresses.join(", "), "]" echo peer.pretty(), " * ", " [", addresses.join(", "), "]"
else: else:
echo peer, " [", addresses.join(", "), "]" echo peer.pretty(), " [", addresses.join(", "), "]"
elif line.startsWith("/exit"): elif line.startsWith("/exit"):
quit(0) quit(0)
else: else:
@ -112,7 +112,7 @@ proc main() {.async.} =
var id = await data.api.identity() var id = await data.api.identity()
proc streamHandler(api: DaemonAPI, stream: P2PStream) {.async.} = proc streamHandler(api: DaemonAPI, stream: P2PStream) {.async.} =
echo "= Peer ", Base58.encode(stream.peer), " joined chat" echo "= Peer ", stream.peer.pretty(), " joined chat"
data.remotes.add(stream.transp) data.remotes.add(stream.transp)
while true: while true:
var line = await stream.transp.readLine() var line = await stream.transp.readLine()
@ -121,8 +121,8 @@ proc main() {.async.} =
echo ">> ", line echo ">> ", line
await data.api.addHandler(ServerProtocols, streamHandler) await data.api.addHandler(ServerProtocols, streamHandler)
echo "= Your PeerID is ", Base58.encode(id.peer) echo "= Your PeerID is ", id.peer.pretty()
when isMainModule: when isMainModule:
waitFor(main()) waitFor(main())
while true: while true:

View File

@ -10,6 +10,7 @@
## This module implements MultiAddress. ## This module implements MultiAddress.
import tables, strutils, net import tables, strutils, net
import multicodec, multihash, multibase, transcoder, base58, base32, vbuffer import multicodec, multihash, multibase, transcoder, base58, base32, vbuffer
import peer
{.deadCodeElim:on.} {.deadCodeElim:on.}
@ -562,7 +563,7 @@ proc validate*(ma: MultiAddress): bool =
discard discard
result = true result = true
proc init*(mtype: typedesc[MultiAddress], protocol: int, proc init*(mtype: typedesc[MultiAddress], protocol: MultiCodec,
value: openarray[byte]): MultiAddress = value: openarray[byte]): MultiAddress =
## Initialize MultiAddress object from protocol id ``protocol`` and array ## Initialize MultiAddress object from protocol id ``protocol`` and array
## of bytes ``value``. ## of bytes ``value``.
@ -582,7 +583,13 @@ proc init*(mtype: typedesc[MultiAddress], protocol: int,
result.data.writeSeq(data) result.data.writeSeq(data)
result.data.finish() result.data.finish()
proc init*(mtype: typedesc[MultiAddress], protocol: int): MultiAddress = proc init*(mtype: typedesc[MultiAddress], protocol: MultiCodec,
value: PeerID): MultiAddress {.inline.} =
## Initialize MultiAddress object from protocol id ``protocol`` and peer id
## ``value``.
init(mtype, protocol, cast[seq[byte]](value))
proc init*(mtype: typedesc[MultiAddress], protocol: MultiCodec): MultiAddress =
## Initialize MultiAddress object from protocol id ``protocol``. ## Initialize MultiAddress object from protocol id ``protocol``.
let proto = CodeAddresses.getOrDefault(protocol) let proto = CodeAddresses.getOrDefault(protocol)
if proto.kind == None: if proto.kind == None:
@ -590,7 +597,7 @@ proc init*(mtype: typedesc[MultiAddress], protocol: int): MultiAddress =
result.data = initVBuffer() result.data = initVBuffer()
if proto.kind != Marker: if proto.kind != Marker:
raise newException(MultiAddressError, "Protocol missing value") raise newException(MultiAddressError, "Protocol missing value")
result.data.writeVarint(cast[uint64](proto.code)) result.data.writeVarint(cast[uint64](proto.mcodec))
result.data.finish() result.data.finish()
proc getProtocol(name: string): MAProtocol {.inline.} = proc getProtocol(name: string): MAProtocol {.inline.} =

View File

@ -19,6 +19,8 @@ const
type type
PeerID* = distinct seq[byte] PeerID* = distinct seq[byte]
PeerIDError* = object of Exception
proc pretty*(peerid: PeerID): string {.inline.} = proc pretty*(peerid: PeerID): string {.inline.} =
## Return base58 encoded ``peerid`` representation. ## Return base58 encoded ``peerid`` representation.
Base58.encode(cast[seq[byte]](peerid)) Base58.encode(cast[seq[byte]](peerid))
@ -37,22 +39,7 @@ proc getBytes*(peerid: PeerID): seq[byte] {.inline.} =
var p = cast[seq[byte]](peerid) var p = cast[seq[byte]](peerid)
result = @p result = @p
proc fromKey*(pubkey: PublicKey): PeerID = proc hex*(peerid: PeerID): string {.inline.} =
## 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``. ## Returns hexadecimal string representation of ``peerid``.
var p = cast[seq[byte]](peerid) var p = cast[seq[byte]](peerid)
if len(p) > 0: if len(p) > 0:
@ -124,14 +111,6 @@ proc extractPublicKey*(peerid: PeerID, pubkey: var PublicKey): bool =
let length = len(mh.data.buffer) let length = len(mh.data.buffer)
result = pubkey.init(mh.data.buffer.toOpenArray(mh.dpos, length - 1)) 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 = proc `$`*(peerid: PeerID): string =
## Returns compact string representation of ``peerid``. ## Returns compact string representation of ``peerid``.
var pid = peerid.pretty() var pid = peerid.pretty()
@ -144,6 +123,61 @@ proc `$`*(peerid: PeerID): string =
for i in (len(pid) - 6)..(len(pid) - 1): for i in (len(pid) - 6)..(len(pid) - 1):
result.add(pid[i]) result.add(pid[i])
proc init*(pid: var PeerID, data: openarray[byte]): bool =
## Initialize peer id from raw binary representation ``data``.
##
## Returns ``true`` if peer was successfully initialiazed.
var p = cast[PeerID](@data)
if p.validate():
pid = p
proc init*(pid: var PeerID, data: string): bool =
## Initialize peer id from base58 encoded string representation.
##
## Returns ``true`` if peer was successfully initialiazed.
var p = newSeq[byte](len(data) + 4)
var length = 0
if Base58.decode(data, p, length) == Base58Status.Success:
p.setLen(length)
var opid = cast[PeerID](p)
if opid.validate():
pid = opid
proc init*(t: typedesc[PeerID], data: openarray[byte]): PeerID {.inline.} =
## Create new peer id from raw binary representation ``data``.
if not init(result, data):
raise newException(PeerIDError, "Incorrect PeerID binary form")
proc init*(t: typedesc[PeerID], data: string): PeerID {.inline.} =
## Create new peer id from base58 encoded string representation ``data``.
if not init(result, data):
raise newException(PeerIDError, "Incorrect PeerID string")
proc init*(t: typedesc[PeerID], pubkey: PublicKey): PeerID =
## Create new peer id from 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 init*(t: typedesc[PeerID], seckey: PrivateKey): PeerID {.inline.} =
## Create new peer id from private key ``seckey``.
result = PeerID.init(seckey.getKey())
proc match*(peerid: PeerID, pubkey: PublicKey): bool {.inline.} =
## Returns ``true`` if ``peerid`` matches public key ``pubkey``.
result = (peerid == PeerID.init(pubkey))
proc match*(peerid: PeerID, seckey: PrivateKey): bool {.inline.} =
## Returns ``true`` if ``peerid`` matches private key ``seckey``.
result = (peerid == PeerID.init(seckey))
## Serialization/Deserialization helpers
proc write*(vb: var VBuffer, peerid: PeerID) {.inline.} = proc write*(vb: var VBuffer, peerid: PeerID) {.inline.} =
## Write PeerID value ``peerid`` to buffer ``vb``. ## Write PeerID value ``peerid`` to buffer ``vb``.
var p = cast[seq[byte]](peerid) var p = cast[seq[byte]](peerid)