diff --git a/libp2p/multiaddress.nim b/libp2p/multiaddress.nim index a94d412..e87d59f 100644 --- a/libp2p/multiaddress.nim +++ b/libp2p/multiaddress.nim @@ -12,7 +12,7 @@ import nativesockets import tables, strutils, net import chronos import multicodec, multihash, multibase, transcoder, vbuffer -import stew/[base58, base32] +import stew/[base58, base32, endians2] from peer import PeerID {.deadCodeElim:on.} @@ -704,6 +704,24 @@ proc init*(mtype: typedesc[MultiAddress], protocol: MultiCodec): MultiAddress = result.data.writeVarint(cast[uint64](proto.mcodec)) result.data.finish() +proc init*(mtype: typedesc[MultiAddress], protocol: MultiCodec, + value: int): MultiAddress = + ## Initialize MultiAddress object from protocol id ``protocol`` and integer + ## ``value``. This procedure can be used to instantiate ``tcp``, ``udp``, + ## ``dccp`` and ``sctp`` MultiAddresses. + var allowed = [multiCodec("tcp"), multiCodec("udp"), multiCodec("dccp"), + multiCodec("sctp")] + if protocol notin allowed: + raise newException(MultiAddressError, + "Incorrect protocol for integer value") + let proto = CodeAddresses.getOrDefault(protocol) + result.data = initVBuffer() + result.data.writeVarint(cast[uint64](proto.mcodec)) + if value < 0 or value > 65535: + raise newException(MultiAddressError, "Incorrect integer value") + result.data.writeArray(toBytesBE(cast[uint16](value))) + result.data.finish() + proc getProtocol(name: string): MAProtocol {.inline.} = let mc = MultiCodec.codec(name) if mc != InvalidMultiCodec: diff --git a/tests/testmultiaddress.nim b/tests/testmultiaddress.nim index 22c92dc..0b39dfe 100644 --- a/tests/testmultiaddress.nim +++ b/tests/testmultiaddress.nim @@ -1,5 +1,5 @@ import unittest -import ../libp2p/multiaddress +import ../libp2p/[multicodec, multiaddress] when defined(nimHasUsed): {.used.} @@ -363,3 +363,31 @@ suite "MultiAddress test suite": for bitem in item.bad: var a = MultiAddress.init(bitem) check item.pattern.match(a) == false + + test "MultiAddress init(\"tcp/udp/dccp/sctp\", int) test": + check: + $MultiAddress.init(multiCodec("tcp"), 0) == "/tcp/0" + $MultiAddress.init(multiCodec("tcp"), 65535) == "/tcp/65535" + $MultiAddress.init(multiCodec("tcp"), 34000) == "/tcp/34000" + $MultiAddress.init(multiCodec("udp"), 0) == "/udp/0" + $MultiAddress.init(multiCodec("udp"), 65535) == "/udp/65535" + $MultiAddress.init(multiCodec("udp"), 34000) == "/udp/34000" + $MultiAddress.init(multiCodec("dccp"), 0) == "/dccp/0" + $MultiAddress.init(multiCodec("dccp"), 65535) == "/dccp/65535" + $MultiAddress.init(multiCodec("dccp"), 34000) == "/dccp/34000" + $MultiAddress.init(multiCodec("sctp"), 0) == "/sctp/0" + $MultiAddress.init(multiCodec("sctp"), 65535) == "/sctp/65535" + $MultiAddress.init(multiCodec("sctp"), 34000) == "/sctp/34000" + + expect(MultiAddressError): + discard MultiAddress.init(multiCodec("ip4"), 0) + discard MultiAddress.init(multiCodec("ip6"), 0) + discard MultiAddress.init(multiCodec("p2p"), 0) + discard MultiAddress.init(multiCodec("tcp"), 65536) + discard MultiAddress.init(multiCodec("udp"), 65536) + discard MultiAddress.init(multiCodec("dccp"), 65536) + discard MultiAddress.init(multiCodec("sctp"), 65536) + discard MultiAddress.init(multiCodec("tcp"), -1) + discard MultiAddress.init(multiCodec("udp"), -1) + discard MultiAddress.init(multiCodec("dccp"), -1) + discard MultiAddress.init(multiCodec("sctp"), -1)