diff --git a/libp2p/multiaddress.nim b/libp2p/multiaddress.nim index 3020ee612..493e4d140 100644 --- a/libp2p/multiaddress.nim +++ b/libp2p/multiaddress.nim @@ -9,43 +9,16 @@ ## This module implements MultiAddress. import tables, strutils, net -import multihash, transcoder, base58, base32, vbuffer +import multicodec, multihash, transcoder, base58, base32, vbuffer {.deadCodeElim:on.} -const - P_IP4* = 0x0004 - P_TCP* = 0x0006 - P_UDP* = 0x0111 - P_DCCP* = 0x0021 - P_IP6* = 0x0029 - P_IP6ZONE* = 0x002A - P_DNS4* = 0x0036 - P_DNS6* = 0x0037 - P_DNSADDR* = 0x0038 - P_QUIC* = 0x01CC - P_SCTP* = 0x0084 - P_UDT* = 0x012D - P_UTP* = 0x012E - P_UNIX* = 0x0190 - P_P2P* = 0x01A5 - P_IPFS* = 0x01A5 # alias for backwards compatability - P_HTTP* = 0x01E0 - P_HTTPS* = 0x01BB - P_ONION* = 0x01BC - P_WS* = 0x01DD - LP2P_WSSTAR* = 0x01DF - LP2P_WRTCSTAR* = 0x0113 - LP2P_WRTCDIR* = 0x0114 - P_P2PCIRCUIT* = 0x0122 - type MAKind* = enum None, Fixed, Length, Path, Marker MAProtocol* = object - name*: string - code*: int + mcodec*: MultiCodec size*: int kind: MAKind coder*: Transcoder @@ -288,109 +261,101 @@ const ) ProtocolsList = [ MAProtocol( - name: "ip4", code: P_IP4, kind: Fixed, size: 4, + mcodec: multiCodec("ip4"), kind: Fixed, size: 4, coder: TranscoderIP4 ), MAProtocol( - name: "tcp", code: P_TCP, kind: Fixed, size: 2, + mcodec: multiCodec("tcp"), kind: Fixed, size: 2, coder: TranscoderPort ), MAProtocol( - name: "udp", code: P_UDP, kind: Fixed, size: 2, + mcodec: multiCodec("udp"), kind: Fixed, size: 2, coder: TranscoderPort ), MAProtocol( - name: "ip6", code: P_IP6, kind: Fixed, size: 16, + mcodec: multiCodec("ip6"), kind: Fixed, size: 16, coder: TranscoderIP6 ), MAProtocol( - name: "dccp", code: P_DCCP, kind: Fixed, size: 2, + mcodec: multiCodec("dccp"), kind: Fixed, size: 2, coder: TranscoderPort ), MAProtocol( - name: "sctp", code: P_SCTP, kind: Fixed, size: 2, + mcodec: multiCodec("sctp"), kind: Fixed, size: 2, coder: TranscoderPort ), MAProtocol( - name: "udt", code: P_UDT, kind: Marker, size: 0 + mcodec: multiCodec("udt"), kind: Marker, size: 0 ), MAProtocol( - name: "utp", code: P_UTP, kind: Marker, size: 0 + mcodec: multiCodec("utp"), kind: Marker, size: 0 ), MAProtocol( - name: "http", code: P_HTTP, kind: Marker, size: 0 + mcodec: multiCodec("http"), kind: Marker, size: 0 ), MAProtocol( - name: "https", code: P_HTTPS, kind: Marker, size: 0 + mcodec: multiCodec("https"), kind: Marker, size: 0 ), MAProtocol( - name: "quic", code: P_QUIC, kind: Marker, size: 0 + mcodec: multiCodec("quic"), kind: Marker, size: 0 ), MAProtocol( - name: "ip6zone", code: P_IP6ZONE, kind: Length, size: 0, + mcodec: multiCodec("ip6zone"), kind: Length, size: 0, coder: TranscoderIP6Zone ), MAProtocol( - name: "onion", code: P_ONION, kind: Fixed, size: 10, + mcodec: multiCodec("onion"), kind: Fixed, size: 10, coder: TranscoderOnion ), MAProtocol( - name: "ws", code: P_WS, kind: Marker, size: 0 + mcodec: multiCodec("ws"), kind: Marker, size: 0 ), MAProtocol( - name: "ws", code: P_WS, kind: Marker, size: 0 - ), - MAProtocol( - name: "ipfs", code: P_IPFS, kind: Length, size: 0, + mcodec: multiCodec("ipfs"), kind: Length, size: 0, coder: TranscoderP2P ), MAProtocol( - name: "p2p", code: P_P2P, kind: Length, size: 0, + mcodec: multiCodec("p2p"), kind: Length, size: 0, coder: TranscoderP2P ), MAProtocol( - name: "unix", code: P_UNIX, kind: Path, size: 0, + mcodec: multiCodec("unix"), kind: Path, size: 0, coder: TranscoderUnix ), MAProtocol( - name: "dns4", code: P_DNS4, kind: Length, size: 0, + mcodec: multiCodec("dns4"), kind: Length, size: 0, coder: TranscoderDNS ), MAProtocol( - name: "dns6", code: P_DNS6, kind: Length, size: 0, + mcodec: multiCodec("dns6"), kind: Length, size: 0, coder: TranscoderDNS ), MAProtocol( - name: "dnsaddr", code: P_DNS6, kind: Length, size: 0, + mcodec: multiCodec("dnsaddr"), kind: Length, size: 0, coder: TranscoderDNS ), MAProtocol( - name: "p2p-circuit", code: P_P2PCIRCUIT, kind: Marker, size: 0 + mcodec: multiCodec("p2p-circuit"), kind: Marker, size: 0 ), MAProtocol( - name: "p2p-websocket-star", code: LP2P_WSSTAR, kind: Marker, size: 0 + mcodec: multiCodec("p2p-websocket-star"), kind: Marker, size: 0 ), MAProtocol( - name: "p2p-webrtc-star", code: LP2P_WRTCSTAR, kind: Marker, size: 0 + mcodec: multiCodec("p2p-webrtc-star"), kind: Marker, size: 0 ), MAProtocol( - name: "p2p-webrtc-direct", code: LP2P_WRTCDIR, kind: Marker, size: 0 + mcodec: multiCodec("p2p-webrtc-direct"), kind: Marker, size: 0 ) ] -proc initMultiAddressNameTable(): Table[string, MAProtocol] {.compileTime.} = - result = initTable[string, MAProtocol]() +proc initMultiAddressCodeTable(): Table[MultiCodec, + MAProtocol] {.compileTime.} = + result = initTable[MultiCodec, MAProtocol]() for item in ProtocolsList: - result[item.name] = item - -proc initMultiAddressCodeTable(): Table[int, MAProtocol] {.compileTime.} = - result = initTable[int, MAProtocol]() - for item in ProtocolsList: - result[item.code] = item + result[item.mcodec] = item const CodeAddresses = initMultiAddressCodeTable() - NameAddresses = initMultiAddressNameTable() proc trimRight(s: string, ch: char): string = ## Consume trailing characters ``ch`` from string ``s`` and return result. @@ -407,32 +372,18 @@ proc shcopy*(m1: var MultiAddress, m2: MultiAddress) = m1.data.offset = m2.data.offset m1.data.length = m2.data.length -proc protoCode*(mtype: typedesc[MultiAddress], protocol: string): int = - ## Returns protocol code from protocol name ``protocol``. - let proto = NameAddresses.getOrDefault(protocol) - if proto.kind == None: - raise newException(MultiAddressError, "Protocol not found") - result = proto.code - -proc protoName*(mtype: typedesc[MultiAddress], protocol: int): string = - ## Returns protocol name from protocol code ``protocol``. - let proto = CodeAddresses.getOrDefault(protocol) - if proto.kind == None: - raise newException(MultiAddressError, "Protocol not found") - result = proto.name - -proc protoCode*(ma: MultiAddress): int = +proc protoCode*(ma: MultiAddress): MultiCodec = ## Returns MultiAddress ``ma`` protocol code. var header: uint64 var vb: MultiAddress shcopy(vb, ma) if vb.data.readVarint(header) == -1: raise newException(MultiAddressError, "Malformed binary address!") - let proto = CodeAddresses.getOrDefault(int(header)) + let proto = CodeAddresses.getOrDefault(MultiCodec(header)) if proto.kind == None: raise newException(MultiAddressError, "Unsupported protocol '" & $header & "'") - result = proto.code + result = proto.mcodec proc protoName*(ma: MultiAddress): string = ## Returns MultiAddress ``ma`` protocol name. @@ -441,11 +392,11 @@ proc protoName*(ma: MultiAddress): string = shcopy(vb, ma) if vb.data.readVarint(header) == -1: raise newException(MultiAddressError, "Malformed binary address!") - let proto = CodeAddresses.getOrDefault(int(header)) + let proto = CodeAddresses.getOrDefault(MultiCodec(header)) if proto.kind == None: raise newException(MultiAddressError, "Unsupported protocol '" & $header & "'") - result = proto.name + result = $(proto.mcodec) proc protoArgument*(ma: MultiAddress, value: var openarray[byte]): int = ## Returns MultiAddress ``ma`` protocol argument value. @@ -458,7 +409,7 @@ proc protoArgument*(ma: MultiAddress, value: var openarray[byte]): int = shcopy(vb, ma) if vb.data.readVarint(header) == -1: raise newException(MultiAddressError, "Malformed binary address!") - let proto = CodeAddresses.getOrDefault(int(header)) + let proto = CodeAddresses.getOrDefault(MultiCodec(header)) if proto.kind == None: raise newException(MultiAddressError, "Unsupported protocol '" & $header & "'") @@ -483,7 +434,7 @@ proc getPart(ma: MultiAddress, index: int): MultiAddress = while offset <= index: if vb.data.readVarint(header) == -1: raise newException(MultiAddressError, "Malformed binary address!") - let proto = CodeAddresses.getOrDefault(int(header)) + let proto = CodeAddresses.getOrDefault(MultiCodec(header)) if proto.kind == None: raise newException(MultiAddressError, "Unsupported protocol '" & $header & "'") @@ -522,7 +473,7 @@ iterator items*(ma: MultiAddress): MultiAddress = var res = MultiAddress(data: initVBuffer()) if vb.data.readVarint(header) == -1: raise newException(MultiAddressError, "Malformed binary address!") - let proto = CodeAddresses.getOrDefault(int(header)) + let proto = CodeAddresses.getOrDefault(MultiCodec(header)) if proto.kind == None: raise newException(MultiAddressError, "Unsupported protocol '" & $header & "'") @@ -554,20 +505,20 @@ proc `$`*(value: MultiAddress): string = break if vb.data.readVarint(header) == -1: raise newException(MultiAddressError, "Malformed binary address!") - let proto = CodeAddresses.getOrDefault(int(header)) + let proto = CodeAddresses.getOrDefault(MultiCodec(header)) if proto.kind == None: raise newException(MultiAddressError, "Unsupported protocol '" & $header & "'") if proto.kind in {Fixed, Length, Path}: if isNil(proto.coder.bufferToString): raise newException(MultiAddressError, - "Missing protocol '" & proto.name & "' transcoder") + "Missing protocol '" & $(proto.mcodec) & "' coder") if not proto.coder.bufferToString(vb.data, part): raise newException(MultiAddressError, "Decoding protocol error") - parts.add(proto.name) + parts.add($(proto.mcodec)) parts.add(part) elif proto.kind == Marker: - parts.add(proto.name) + parts.add($(proto.mcodec)) if len(parts) > 0: result = "/" & parts.join("/") @@ -585,7 +536,7 @@ proc validate*(ma: MultiAddress): bool = break if vb.data.readVarint(header) == -1: return false - let proto = CodeAddresses.getOrDefault(int(header)) + let proto = CodeAddresses.getOrDefault(MultiCodec(header)) if proto.kind == None: return false if proto.kind in {Fixed, Length, Path}: @@ -628,6 +579,11 @@ proc init*(mtype: typedesc[MultiAddress], protocol: int): MultiAddress = result.data.writeVarint(cast[uint64](proto.code)) result.data.finish() +proc getProtocol(name: string): MAProtocol {.inline.} = + let mc = MultiCodec.codec(name) + if mc != InvalidMultiCodec: + result = CodeAddresses.getOrDefault(mc) + proc init*(mtype: typedesc[MultiAddress], value: string): MultiAddress = ## Initialize MultiAddress object from string representation ``value``. var parts = value.trimRight('/').split('/') @@ -638,7 +594,7 @@ proc init*(mtype: typedesc[MultiAddress], value: string): MultiAddress = result.data = initVBuffer() while offset < len(parts): let part = parts[offset] - let proto = NameAddresses.getOrDefault(part) + let proto = getProtocol(part) if proto.kind == None: raise newException(MultiAddressError, "Unsupported protocol '" & part & "'") @@ -651,20 +607,21 @@ proc init*(mtype: typedesc[MultiAddress], value: string): MultiAddress = "Missing protocol '" & part & "' argument") if proto.kind in {Fixed, Length}: - result.data.writeVarint(cast[uint](proto.code)) - if not proto.coder.stringToBuffer(parts[offset + 1], result.data): + result.data.writeCodec(proto.mcodec) + let res = proto.coder.stringToBuffer(parts[offset + 1], result.data) + if not res: raise newException(MultiAddressError, "Error encoding `$1/$2`" % [part, parts[offset + 1]]) offset += 2 elif proto.kind == Path: var path = "/" & (parts[(offset + 1)..^1].join("/")) - result.data.writeVarint(cast[uint](proto.code)) + result.data.writeCodec(proto.mcodec) if not proto.coder.stringToBuffer(path, result.data): raise newException(MultiAddressError, "Error encoding `$1/$2`" % [part, path]) break elif proto.kind == Marker: - result.data.writeVarint(cast[uint](proto.code)) + result.data.writeCodec(proto.mcodec) offset += 1 result.data.finish() diff --git a/libp2p/multicodec.nim b/libp2p/multicodec.nim new file mode 100644 index 000000000..4c8b127a2 --- /dev/null +++ b/libp2p/multicodec.nim @@ -0,0 +1,316 @@ +## 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 implements MultiCodec. +import tables, hashes +import varint, vbuffer + +{.deadCodeElim: on.} + +## List of officially supported codecs can BE found here +## https://github.com/multiformats/multicodec/blob/master/table.csv +const MultiCodecList = [ + ("raw", 0x55), + # serialization formats + ("cbor", 0x51), + ("protobuf", 0x50), + ("rlp", 0x60), + ("bencode", 0x63), + # multiformats + ("multicodec", 0x30), + ("multihash", 0x31), + ("multiaddr", 0x32), + ("multibase", 0x33), + # multihashes + ("identity", 0x00), + ("md4", 0xD4), + ("md5", 0xD5), + ("sha1", 0x11), + ("sha2-256", 0x12), + ("sha2-512", 0x13), + ("dbl-sha2-256", 0x56), + ("sha3-224", 0x17), + ("sha3-256", 0x16), + ("sha3-384", 0x15), + ("sha3-512", 0x14), + ("shake-128", 0x18), + ("shake-256", 0x19), + ("keccak-224", 0x1A), + ("keccak-256", 0x1B), + ("keccak-384", 0x1C), + ("keccak-512", 0x1D), + ("murmur3", 0x22), + ("blake2b-8", 0xB201), ("blake2b-16", 0xB202), ("blake2b-24", 0xB203), + ("blake2b-32", 0xB204), ("blake2b-40", 0xB205), ("blake2b-48", 0xB206), + ("blake2b-56", 0xB207), ("blake2b-64", 0xB208), ("blake2b-72", 0xB209), + ("blake2b-80", 0xB20A), ("blake2b-88", 0xB20B), ("blake2b-96", 0xB20C), + ("blake2b-104", 0xB20D), ("blake2b-112", 0xB20E), ("blake2b-120", 0xB20F), + ("blake2b-128", 0xB210), ("blake2b-136", 0xB211), ("blake2b-144", 0xB212), + ("blake2b-152", 0xB213), ("blake2b-160", 0xB214), ("blake2b-168", 0xB215), + ("blake2b-176", 0xB216), ("blake2b-184", 0xB217), ("blake2b-192", 0xB218), + ("blake2b-200", 0xB219), ("blake2b-208", 0xB21A), ("blake2b-216", 0xB21B), + ("blake2b-224", 0xB21C), ("blake2b-232", 0xB21D), ("blake2b-240", 0xB21E), + ("blake2b-248", 0xB21F), ("blake2b-256", 0xB220), ("blake2b-264", 0xB221), + ("blake2b-272", 0xB222), ("blake2b-280", 0xB223), ("blake2b-288", 0xB224), + ("blake2b-296", 0xB225), ("blake2b-304", 0xB226), ("blake2b-312", 0xB227), + ("blake2b-320", 0xB228), ("blake2b-328", 0xB229), ("blake2b-336", 0xB22A), + ("blake2b-344", 0xB22B), ("blake2b-352", 0xB22C), ("blake2b-360", 0xB22D), + ("blake2b-368", 0xB22E), ("blake2b-376", 0xB22F), ("blake2b-384", 0xB230), + ("blake2b-392", 0xB231), ("blake2b-400", 0xB232), ("blake2b-408", 0xB233), + ("blake2b-416", 0xB234), ("blake2b-424", 0xB235), ("blake2b-432", 0xB236), + ("blake2b-440", 0xB237), ("blake2b-448", 0xB238), ("blake2b-456", 0xB239), + ("blake2b-464", 0xB23A), ("blake2b-472", 0xB23B), ("blake2b-480", 0xB23C), + ("blake2b-488", 0xB23D), ("blake2b-496", 0xB23E), ("blake2b-504", 0xB23F), + ("blake2b-512", 0xB240), ("blake2s-8", 0xB241), ("blake2s-16", 0xB242), + ("blake2s-24", 0xB243), ("blake2s-32", 0xB244), ("blake2s-40", 0xB245), + ("blake2s-48", 0xB246), ("blake2s-56", 0xB247), ("blake2s-64", 0xB248), + ("blake2s-72", 0xB249), ("blake2s-80", 0xB24A), ("blake2s-88", 0xB24B), + ("blake2s-96", 0xB24C), ("blake2s-104", 0xB24D), ("blake2s-112", 0xB24E), + ("blake2s-120", 0xB24F), ("blake2s-128", 0xB250), ("blake2s-136", 0xB251), + ("blake2s-144", 0xB252), ("blake2s-152", 0xB253), ("blake2s-160", 0xB254), + ("blake2s-168", 0xB255), ("blake2s-176", 0xB256), ("blake2s-184", 0xB257), + ("blake2s-192", 0xB258), ("blake2s-200", 0xB259), ("blake2s-208", 0xB25A), + ("blake2s-216", 0xB25B), ("blake2s-224", 0xB25C), ("blake2s-232", 0xB25D), + ("blake2s-240", 0xB25E), ("blake2s-248", 0xB25F), ("blake2s-256", 0xB260), + ("skein256-8", 0xB301), ("skein256-16", 0xB302), ("skein256-24", 0xB303), + ("skein256-32", 0xB304), ("skein256-40", 0xB305), ("skein256-48", 0xB306), + ("skein256-56", 0xB307), ("skein256-64", 0xB308), ("skein256-72", 0xB309), + ("skein256-80", 0xB30A), ("skein256-88", 0xB30B), ("skein256-96", 0xB30C), + ("skein256-104", 0xB30D), ("skein256-112", 0xB30E), ("skein256-120", 0xB30F), + ("skein256-128", 0xB310), ("skein256-136", 0xB311), ("skein256-144", 0xB312), + ("skein256-152", 0xB313), ("skein256-160", 0xB314), ("skein256-168", 0xB315), + ("skein256-176", 0xB316), ("skein256-184", 0xB317), ("skein256-192", 0xB318), + ("skein256-200", 0xB319), ("skein256-208", 0xB31A), ("skein256-216", 0xB31B), + ("skein256-224", 0xB31C), ("skein256-232", 0xB31D), ("skein256-240", 0xB31E), + ("skein256-248", 0xB31F), ("skein256-256", 0xB320), + ("skein512-8", 0xB321), ("skein512-16", 0xB322), ("skein512-24", 0xB323), + ("skein512-32", 0xB324), ("skein512-40", 0xB325), ("skein512-48", 0xB326), + ("skein512-56", 0xB327), ("skein512-64", 0xB328), ("skein512-72", 0xB329), + ("skein512-80", 0xB32A), ("skein512-88", 0xB32B), ("skein512-96", 0xB32C), + ("skein512-104", 0xB32D), ("skein512-112", 0xB32E), ("skein512-120", 0xB32F), + ("skein512-128", 0xB330), ("skein512-136", 0xB331), ("skein512-144", 0xB332), + ("skein512-152", 0xB333), ("skein512-160", 0xB334), ("skein512-168", 0xB335), + ("skein512-176", 0xB336), ("skein512-184", 0xB337), ("skein512-192", 0xB338), + ("skein512-200", 0xB339), ("skein512-208", 0xB33A), ("skein512-216", 0xB33B), + ("skein512-224", 0xB33C), ("skein512-232", 0xB33D), ("skein512-240", 0xB33E), + ("skein512-248", 0xB33F), ("skein512-256", 0xB340), ("skein512-264", 0xB341), + ("skein512-272", 0xB342), ("skein512-280", 0xB343), ("skein512-288", 0xB344), + ("skein512-296", 0xB345), ("skein512-304", 0xB346), ("skein512-312", 0xB347), + ("skein512-320", 0xB348), ("skein512-328", 0xB349), ("skein512-336", 0xB34A), + ("skein512-344", 0xB34B), ("skein512-352", 0xB34C), ("skein512-360", 0xB34D), + ("skein512-368", 0xB34E), ("skein512-376", 0xB34F), ("skein512-384", 0xB350), + ("skein512-392", 0xB351), ("skein512-400", 0xB352), ("skein512-408", 0xB353), + ("skein512-416", 0xB354), ("skein512-424", 0xB355), ("skein512-432", 0xB356), + ("skein512-440", 0xB357), ("skein512-448", 0xB358), ("skein512-456", 0xB359), + ("skein512-464", 0xB35A), ("skein512-472", 0xB35B), ("skein512-480", 0xB35C), + ("skein512-488", 0xB35D), ("skein512-496", 0xB35E), ("skein512-504", 0xB35F), + ("skein512-512", 0xB360), ("skein1024-8", 0xB361), ("skein1024-16", 0xB362), + ("skein1024-24", 0xB363), ("skein1024-32", 0xB364), ("skein1024-40", 0xB365), + ("skein1024-48", 0xB366), ("skein1024-56", 0xB367), ("skein1024-64", 0xB368), + ("skein1024-72", 0xB369), ("skein1024-80", 0xB36A), ("skein1024-88", 0xB36B), + ("skein1024-96", 0xB36C), ("skein1024-104", 0xB36D), + ("skein1024-112", 0xB36E), ("skein1024-120", 0xB36F), + ("skein1024-128", 0xB370), ("skein1024-136", 0xB371), + ("skein1024-144", 0xB372), ("skein1024-152", 0xB373), + ("skein1024-160", 0xB374), ("skein1024-168", 0xB375), + ("skein1024-176", 0xB376), ("skein1024-184", 0xB377), + ("skein1024-192", 0xB378), ("skein1024-200", 0xB379), + ("skein1024-208", 0xB37A), ("skein1024-216", 0xB37B), + ("skein1024-224", 0xB37C), ("skein1024-232", 0xB37D), + ("skein1024-240", 0xB37E), ("skein1024-248", 0xB37F), + ("skein1024-256", 0xB380), ("skein1024-264", 0xB381), + ("skein1024-272", 0xB382), ("skein1024-280", 0xB383), + ("skein1024-288", 0xB384), ("skein1024-296", 0xB385), + ("skein1024-304", 0xB386), ("skein1024-312", 0xB387), + ("skein1024-320", 0xB388), ("skein1024-328", 0xB389), + ("skein1024-336", 0xB38A), ("skein1024-344", 0xB38B), + ("skein1024-352", 0xB38C), ("skein1024-360", 0xB38D), + ("skein1024-368", 0xB38E), ("skein1024-376", 0xB38F), + ("skein1024-384", 0xB390), ("skein1024-392", 0xB391), + ("skein1024-400", 0xB392), ("skein1024-408", 0xB393), + ("skein1024-416", 0xB394), ("skein1024-424", 0xB395), + ("skein1024-432", 0xB396), ("skein1024-440", 0xB397), + ("skein1024-448", 0xB398), ("skein1024-456", 0xB399), + ("skein1024-464", 0xB39A), ("skein1024-472", 0xB39B), + ("skein1024-480", 0xB39C), ("skein1024-488", 0xB39D), + ("skein1024-496", 0xB39E), ("skein1024-504", 0xB39F), + ("skein1024-512", 0xB3A0), ("skein1024-520", 0xB3A1), + ("skein1024-528", 0xB3A2), ("skein1024-536", 0xB3A3), + ("skein1024-544", 0xB3A4), ("skein1024-552", 0xB3A5), + ("skein1024-560", 0xB3A6), ("skein1024-568", 0xB3A7), + ("skein1024-576", 0xB3A8), ("skein1024-584", 0xB3A9), + ("skein1024-592", 0xB3AA), ("skein1024-600", 0xB3AB), + ("skein1024-608", 0xB3AC), ("skein1024-616", 0xB3AD), + ("skein1024-624", 0xB3AE), ("skein1024-632", 0xB3AF), + ("skein1024-640", 0xB3B0), ("skein1024-648", 0xB3B1), + ("skein1024-656", 0xB3B2), ("skein1024-664", 0xB3B3), + ("skein1024-672", 0xB3B4), ("skein1024-680", 0xB3B5), + ("skein1024-688", 0xB3B6), ("skein1024-696", 0xB3B7), + ("skein1024-704", 0xB3B8), ("skein1024-712", 0xB3B9), + ("skein1024-720", 0xB3BA), ("skein1024-728", 0xB3BB), + ("skein1024-736", 0xB3BC), ("skein1024-744", 0xB3BD), + ("skein1024-752", 0xB3BE), ("skein1024-760", 0xB3BF), + ("skein1024-768", 0xB3C0), ("skein1024-776", 0xB3C1), + ("skein1024-784", 0xB3C2), ("skein1024-792", 0xB3C3), + ("skein1024-800", 0xB3C4), ("skein1024-808", 0xB3C5), + ("skein1024-816", 0xB3C6), ("skein1024-824", 0xB3C7), + ("skein1024-832", 0xB3C8), ("skein1024-840", 0xB3C9), + ("skein1024-848", 0xB3CA), ("skein1024-856", 0xB3CB), + ("skein1024-864", 0xB3CC), ("skein1024-872", 0xB3CD), + ("skein1024-880", 0xB3CE), ("skein1024-888", 0xB3CF), + ("skein1024-896", 0xB3D0), ("skein1024-904", 0xB3D1), + ("skein1024-912", 0xB3D2), ("skein1024-920", 0xB3D3), + ("skein1024-928", 0xB3D4), ("skein1024-936", 0xB3D5), + ("skein1024-944", 0xB3D6), ("skein1024-952", 0xB3D7), + ("skein1024-960", 0xB3D8), ("skein1024-968", 0xB3D9), + ("skein1024-976", 0xB3DA), ("skein1024-984", 0xB3DB), + ("skein1024-992", 0xB3DC), ("skein1024-1000", 0xB3DD), + ("skein1024-1008", 0xB3DE), ("skein1024-1016", 0xB3DF), + ("skein1024-1024", 0xB3E0), + # multiaddrs + ("ip4", 0x04), + ("ip6", 0x29), + ("ip6zone", 0x2A), + ("tcp", 0x06), + ("udp", 0x0111), + ("dccp", 0x21), + ("sctp", 0x84), + ("udt", 0x012D), + ("utp", 0x012E), + ("unix", 0x0190), # not in multicodec list + ("ipfs", 0x01A5), + ("p2p", 0x01A5), + ("http", 0x01E0), + ("https", 0x01BB), + ("quic", 0x01CC), + ("ws", 0x01DD), + ("wss", 0x01DE), # not in multicodec list + ("p2p-websocket-star", 0x01DF), # not in multicodec list + ("p2p-webrtc-star", 0x0113), # not in multicodec list + ("p2p-webrtc-direct", 0x0114), # not in multicodec list + ("onion", 0x01BC), + ("p2p-circuit", 0x0122), + ("dns4", 0x36), + ("dns6", 0x37), + ("dnsaddr", 0x38), + # IPLD formats + ("dag-pb", 0x70), + ("dag-cbor", 0x71), + ("dag-json", 0x129), + ("git-raw", 0x78), + ("eth-block", 0x90), + ("eth-block-list", 0x91), + ("eth-tx-trie", 0x92), + ("eth-tx", 0x93), + ("eth-tx-receipt-trie", 0x94), + ("eth-tx-receipt", 0x95), + ("eth-state-trie", 0x96), + ("eth-account-snapshot", 0x97), + ("eth-storage-trie", 0x98), + ("bitcoin-block", 0xB0), + ("bitcoin-tx", 0xB1), + ("zcash-block", 0xC0), + ("zcash-tx", 0xC1), + ("stellar-block", 0xD0), + ("stellar-tx", 0xD1), + ("decred-block", 0xE0), + ("decred-tx", 0xE1), + ("dash-block", 0xF0), + ("dash-tx", 0xF1), + ("torrent-info", 0x7B), + ("torrent-file", 0x7C), + ("ed25519-pub", 0xED) +] + +type + MultiCodec* = distinct int + MultiCodecError* = object of Exception + +const + InvalidMultiCodec* = MultiCodec(-1) + +proc initMultiCodecNameTable(): Table[string, int] {.compileTime.} = + result = initTable[string, int]() + for item in MultiCodecList: + result[item[0]] = item[1] + +proc initMultiCodecCodeTable(): Table[int, string] {.compileTime.} = + result = initTable[int, string]() + for item in MultiCodecList: + result[item[1]] = item[0] + +const + CodeCodecs = initMultiCodecCodeTable() + NameCodecs = initMultiCodecNameTable() + +proc multiCodec*(name: string): MultiCodec {.compileTime.} = + ## Generate MultiCodec from string ``name`` at compile time. + var code = NameCodecs.getOrDefault(name, -1) + if code == -1: + raise newException(MultiCodecError, + "MultiCodec `" & name & "` not supported!") + result = MultiCodec(code) + +proc multiCodec*(code: int): MultiCodec {.compileTime.} = + ## Generate MultiCodec from integer ``code`` at compile time. + var name = CodeCodecs.getOrDefault(code, "") + if name == "": + raise newException(MultiCodecError, + "MultiCodec with code " & $code & " not supported!") + result = MultiCodec(code) + +proc `$`*(mc: MultiCodec): string = + ## Returns string representation of MultiCodec ``mc``. + result = CodeCodecs.getOrDefault(int(mc), "") + if result == "": + raise newException(MultiCodecError, + "MultiCodec with code " & $int(mc) & " not supported!") + +proc `==`*(mc: MultiCodec, name: string): bool {.inline.} = + ## Compares MultiCodec ``mc`` with string ``name``. + var mcname = CodeCodecs.getOrDefault(int(mc), "") + if mcname == "": + return false + result = (mcname == name) + +proc `==`*(mc: MultiCodec, code: int): bool {.inline.} = + ## Compares MultiCodec ``mc`` with integer ``code``. + result = (int(mc) == code) + +proc `==`*(a, b: MultiCodec): bool = + ## Returns ``true`` if MultiCodecs ``a`` and ``b`` are equal. + int(a) == int(b) + +proc `!=`*(a, b: MultiCodec): bool = + ## Returns ``true`` if MultiCodecs ``a`` and ``b`` are not equal. + int(a) != int(b) + +proc hash*(m: MultiCodec): Hash {.inline.} = + ## Hash procedure for tables. + result = hash(int(m)) + +proc codec*(mt: typedesc[MultiCodec], name: string): MultiCodec {.inline.} = + ## Return MultiCodec from string representation ``name``. + ## If ``name`` is not valid multicodec name, then ``InvalidMultiCodec`` will + ## be returned. + result = MultiCodec(NameCodecs.getOrDefault(name, -1)) + +proc codec*(mt: typedesc[MultiCodec], code: int): MultiCodec {.inline.} = + ## Return MultiCodec from integer representation ``code``. + ## If ``code`` is not valid multicodec code, then ``InvalidMultiCodec`` will + ## be returned. + let res = CodeCodecs.getOrDefault(code, "") + if res == "": + result = InvalidMultiCodec + else: + result = MultiCodec(code) + +proc writeCodec*(vb: var VBuffer, mc: MultiCodec) {.inline.} = + ## Write MultiCodec to buffer ``vb``. + vb.writeVarint(cast[uint](mc)) diff --git a/libp2p/multihash.nim b/libp2p/multihash.nim index 23051a2b5..1ec8261ca 100644 --- a/libp2p/multihash.nim +++ b/libp2p/multihash.nim @@ -22,7 +22,7 @@ ## 3. MURMUR import tables import nimcrypto/[sha2, keccak, blake2, hash, utils] -import varint, vbuffer, base58 +import varint, vbuffer, base58, multicodec const MaxHashSize* = 128 @@ -31,14 +31,13 @@ type MHashCoderProc* = proc(data: openarray[byte], output: var openarray[byte]) {.nimcall, gcsafe.} MHash* = object - name*: string - code*: int + mcodec*: MultiCodec size*: int coder*: MHashCoderProc MultiHash* = object data*: VBuffer - code*: int + mcodec*: MultiCodec size*: int dpos*: int @@ -162,175 +161,154 @@ proc shake_256hash(data: openarray[byte], output: var openarray[byte]) = const HashesList = [ - MHash(name: "identity", code: 0x00, size: 0, coder: identhash), - MHash(name: "dbl-sha2-256", code: 0x56, size: sha256.sizeDigest, + MHash(mcodec: multiCodec("identity"), size: 0, + coder: identhash), + MHash(mcodec: multiCodec("dbl-sha2-256"), size: sha256.sizeDigest, coder: dblsha2_256hash ), - MHash(name: "sha2-256", code: 0x12, size: sha256.sizeDigest, + MHash(mcodec: multiCodec("sha2-256"), size: sha256.sizeDigest, coder: sha2_256hash ), - MHash(name: "sha2-512", code: 0x13, size: sha512.sizeDigest, + MHash(mcodec: multiCodec("sha2-512"), size: sha512.sizeDigest, coder: sha2_512hash ), - MHash(name: "sha3-224", code: 0x17, size: sha3_224.sizeDigest, + MHash(mcodec: multiCodec("sha3-224"), size: sha3_224.sizeDigest, coder: sha3_224hash ), - MHash(name: "sha3-256", code: 0x16, size: sha3_256.sizeDigest, + MHash(mcodec: multiCodec("sha3-256"), size: sha3_256.sizeDigest, coder: sha3_256hash ), - MHash(name: "sha3-384", code: 0x15, size: sha3_384.sizeDigest, + MHash(mcodec: multiCodec("sha3-384"), size: sha3_384.sizeDigest, coder: sha3_384hash ), - MHash(name: "sha3-512", code: 0x14, size: sha3_512.sizeDigest, + MHash(mcodec: multiCodec("sha3-512"), size: sha3_512.sizeDigest, coder: sha3_512hash ), - MHash(name: "shake-128", code: 0x18, size: 32, coder: shake_128hash), - MHash(name: "shake-256", code: 0x19, size: 64, coder: shake_256hash), - MHash(name: "keccak-224", code: 0x1A, size: keccak_224.sizeDigest, + MHash(mcodec: multiCodec("shake-128"), size: 32, coder: shake_128hash), + MHash(mcodec: multiCodec("shake-256"), size: 64, coder: shake_256hash), + MHash(mcodec: multiCodec("keccak-224"), size: keccak_224.sizeDigest, coder: keccak_224hash ), - MHash(name: "keccak-256", code: 0x1B, size: keccak_256.sizeDigest, + MHash(mcodec: multiCodec("keccak-256"), size: keccak_256.sizeDigest, coder: keccak_256hash ), - MHash(name: "keccak-384", code: 0x1C, size: keccak_384.sizeDigest, + MHash(mcodec: multiCodec("keccak-384"), size: keccak_384.sizeDigest, coder: keccak_384hash ), - MHash(name: "keccak-512", code: 0x1D, size: keccak_512.sizeDigest, + MHash(mcodec: multiCodec("keccak-512"), size: keccak_512.sizeDigest, coder: keccak_512hash ), - MHash(name: "blake2b-8", code: 0xB201, size: 1, coder: blake2Bhash), - MHash(name: "blake2b-16", code: 0xB202, size: 2, coder: blake2Bhash), - MHash(name: "blake2b-24", code: 0xB203, size: 3, coder: blake2Bhash), - MHash(name: "blake2b-32", code: 0xB204, size: 4, coder: blake2Bhash), - MHash(name: "blake2b-40", code: 0xB205, size: 5, coder: blake2Bhash), - MHash(name: "blake2b-48", code: 0xB206, size: 6, coder: blake2Bhash), - MHash(name: "blake2b-56", code: 0xB207, size: 7, coder: blake2Bhash), - MHash(name: "blake2b-64", code: 0xB208, size: 8, coder: blake2Bhash), - MHash(name: "blake2b-72", code: 0xB209, size: 9, coder: blake2Bhash), - MHash(name: "blake2b-80", code: 0xB20A, size: 10, coder: blake2Bhash), - MHash(name: "blake2b-88", code: 0xB20B, size: 11, coder: blake2Bhash), - MHash(name: "blake2b-96", code: 0xB20C, size: 12, coder: blake2Bhash), - MHash(name: "blake2b-104", code: 0xB20D, size: 13, coder: blake2Bhash), - MHash(name: "blake2b-112", code: 0xB20E, size: 14, coder: blake2Bhash), - MHash(name: "blake2b-120", code: 0xB20F, size: 15, coder: blake2Bhash), - MHash(name: "blake2b-128", code: 0xB210, size: 16, coder: blake2Bhash), - MHash(name: "blake2b-136", code: 0xB211, size: 17, coder: blake2Bhash), - MHash(name: "blake2b-144", code: 0xB212, size: 18, coder: blake2Bhash), - MHash(name: "blake2b-152", code: 0xB213, size: 19, coder: blake2Bhash), - MHash(name: "blake2b-160", code: 0xB214, size: 20, coder: blake2Bhash), - MHash(name: "blake2b-168", code: 0xB215, size: 21, coder: blake2Bhash), - MHash(name: "blake2b-176", code: 0xB216, size: 22, coder: blake2Bhash), - MHash(name: "blake2b-184", code: 0xB217, size: 23, coder: blake2Bhash), - MHash(name: "blake2b-192", code: 0xB218, size: 24, coder: blake2Bhash), - MHash(name: "blake2b-200", code: 0xB219, size: 25, coder: blake2Bhash), - MHash(name: "blake2b-208", code: 0xB21A, size: 26, coder: blake2Bhash), - MHash(name: "blake2b-216", code: 0xB21B, size: 27, coder: blake2Bhash), - MHash(name: "blake2b-224", code: 0xB21C, size: 28, coder: blake2Bhash), - MHash(name: "blake2b-232", code: 0xB21D, size: 29, coder: blake2Bhash), - MHash(name: "blake2b-240", code: 0xB21E, size: 30, coder: blake2Bhash), - MHash(name: "blake2b-248", code: 0xB21F, size: 31, coder: blake2Bhash), - MHash(name: "blake2b-256", code: 0xB220, size: 32, coder: blake2Bhash), - MHash(name: "blake2b-264", code: 0xB221, size: 33, coder: blake2Bhash), - MHash(name: "blake2b-272", code: 0xB222, size: 34, coder: blake2Bhash), - MHash(name: "blake2b-280", code: 0xB223, size: 35, coder: blake2Bhash), - MHash(name: "blake2b-288", code: 0xB224, size: 36, coder: blake2Bhash), - MHash(name: "blake2b-296", code: 0xB225, size: 37, coder: blake2Bhash), - MHash(name: "blake2b-304", code: 0xB226, size: 38, coder: blake2Bhash), - MHash(name: "blake2b-312", code: 0xB227, size: 39, coder: blake2Bhash), - MHash(name: "blake2b-320", code: 0xB228, size: 40, coder: blake2Bhash), - MHash(name: "blake2b-328", code: 0xB229, size: 41, coder: blake2Bhash), - MHash(name: "blake2b-336", code: 0xB22A, size: 42, coder: blake2Bhash), - MHash(name: "blake2b-344", code: 0xB22B, size: 43, coder: blake2Bhash), - MHash(name: "blake2b-352", code: 0xB22C, size: 44, coder: blake2Bhash), - MHash(name: "blake2b-360", code: 0xB22D, size: 45, coder: blake2Bhash), - MHash(name: "blake2b-368", code: 0xB22E, size: 46, coder: blake2Bhash), - MHash(name: "blake2b-376", code: 0xB22F, size: 47, coder: blake2Bhash), - MHash(name: "blake2b-384", code: 0xB230, size: 48, coder: blake2Bhash), - MHash(name: "blake2b-392", code: 0xB231, size: 49, coder: blake2Bhash), - MHash(name: "blake2b-400", code: 0xB232, size: 50, coder: blake2Bhash), - MHash(name: "blake2b-408", code: 0xB233, size: 51, coder: blake2Bhash), - MHash(name: "blake2b-416", code: 0xB234, size: 52, coder: blake2Bhash), - MHash(name: "blake2b-424", code: 0xB235, size: 53, coder: blake2Bhash), - MHash(name: "blake2b-432", code: 0xB236, size: 54, coder: blake2Bhash), - MHash(name: "blake2b-440", code: 0xB237, size: 55, coder: blake2Bhash), - MHash(name: "blake2b-448", code: 0xB238, size: 56, coder: blake2Bhash), - MHash(name: "blake2b-456", code: 0xB239, size: 57, coder: blake2Bhash), - MHash(name: "blake2b-464", code: 0xB23A, size: 58, coder: blake2Bhash), - MHash(name: "blake2b-472", code: 0xB23B, size: 59, coder: blake2Bhash), - MHash(name: "blake2b-480", code: 0xB23C, size: 60, coder: blake2Bhash), - MHash(name: "blake2b-488", code: 0xB23D, size: 61, coder: blake2Bhash), - MHash(name: "blake2b-496", code: 0xB23E, size: 62, coder: blake2Bhash), - MHash(name: "blake2b-504", code: 0xB23F, size: 63, coder: blake2Bhash), - MHash(name: "blake2b-512", code: 0xB240, size: 64, coder: blake2Bhash), - MHash(name: "blake2s-8", code: 0xB241, size: 1, coder: blake2Shash), - MHash(name: "blake2s-16", code: 0xB242, size: 2, coder: blake2Shash), - MHash(name: "blake2s-24", code: 0xB243, size: 3, coder: blake2Shash), - MHash(name: "blake2s-32", code: 0xB244, size: 4, coder: blake2Shash), - MHash(name: "blake2s-40", code: 0xB245, size: 5, coder: blake2Shash), - MHash(name: "blake2s-48", code: 0xB246, size: 6, coder: blake2Shash), - MHash(name: "blake2s-56", code: 0xB247, size: 7, coder: blake2Shash), - MHash(name: "blake2s-64", code: 0xB248, size: 8, coder: blake2Shash), - MHash(name: "blake2s-72", code: 0xB249, size: 9, coder: blake2Shash), - MHash(name: "blake2s-80", code: 0xB24A, size: 10, coder: blake2Shash), - MHash(name: "blake2s-88", code: 0xB24B, size: 11, coder: blake2Shash), - MHash(name: "blake2s-96", code: 0xB24C, size: 12, coder: blake2Shash), - MHash(name: "blake2s-104", code: 0xB24D, size: 13, coder: blake2Shash), - MHash(name: "blake2s-112", code: 0xB24E, size: 14, coder: blake2Shash), - MHash(name: "blake2s-120", code: 0xB24F, size: 15, coder: blake2Shash), - MHash(name: "blake2s-128", code: 0xB250, size: 16, coder: blake2Shash), - MHash(name: "blake2s-136", code: 0xB251, size: 17, coder: blake2Shash), - MHash(name: "blake2s-144", code: 0xB252, size: 18, coder: blake2Shash), - MHash(name: "blake2s-152", code: 0xB253, size: 19, coder: blake2Shash), - MHash(name: "blake2s-160", code: 0xB254, size: 20, coder: blake2Shash), - MHash(name: "blake2s-168", code: 0xB255, size: 21, coder: blake2Shash), - MHash(name: "blake2s-176", code: 0xB256, size: 22, coder: blake2Shash), - MHash(name: "blake2s-184", code: 0xB257, size: 23, coder: blake2Shash), - MHash(name: "blake2s-192", code: 0xB258, size: 24, coder: blake2Shash), - MHash(name: "blake2s-200", code: 0xB259, size: 25, coder: blake2Shash), - MHash(name: "blake2s-208", code: 0xB25A, size: 26, coder: blake2Shash), - MHash(name: "blake2s-216", code: 0xB25B, size: 27, coder: blake2Shash), - MHash(name: "blake2s-224", code: 0xB25C, size: 28, coder: blake2Shash), - MHash(name: "blake2s-232", code: 0xB25D, size: 29, coder: blake2Shash), - MHash(name: "blake2s-240", code: 0xB25E, size: 30, coder: blake2Shash), - MHash(name: "blake2s-248", code: 0xB25F, size: 31, coder: blake2Shash), - MHash(name: "blake2s-256", code: 0xB260, size: 32, coder: blake2Shash) + MHash(mcodec: multiCodec("blake2b-8"), size: 1, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-16"), size: 2, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-24"), size: 3, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-32"), size: 4, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-40"), size: 5, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-48"), size: 6, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-56"), size: 7, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-64"), size: 8, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-72"), size: 9, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-80"), size: 10, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-88"), size: 11, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-96"), size: 12, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-104"), size: 13, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-112"), size: 14, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-120"), size: 15, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-128"), size: 16, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-136"), size: 17, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-144"), size: 18, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-152"), size: 19, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-160"), size: 20, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-168"), size: 21, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-176"), size: 22, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-184"), size: 23, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-192"), size: 24, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-200"), size: 25, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-208"), size: 26, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-216"), size: 27, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-224"), size: 28, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-232"), size: 29, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-240"), size: 30, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-248"), size: 31, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-256"), size: 32, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-264"), size: 33, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-272"), size: 34, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-280"), size: 35, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-288"), size: 36, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-296"), size: 37, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-304"), size: 38, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-312"), size: 39, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-320"), size: 40, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-328"), size: 41, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-336"), size: 42, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-344"), size: 43, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-352"), size: 44, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-360"), size: 45, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-368"), size: 46, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-376"), size: 47, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-384"), size: 48, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-392"), size: 49, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-400"), size: 50, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-408"), size: 51, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-416"), size: 52, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-424"), size: 53, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-432"), size: 54, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-440"), size: 55, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-448"), size: 56, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-456"), size: 57, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-464"), size: 58, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-472"), size: 59, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-480"), size: 60, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-488"), size: 61, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-496"), size: 62, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-504"), size: 63, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2b-512"), size: 64, coder: blake2Bhash), + MHash(mcodec: multiCodec("blake2s-8"), size: 1, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-16"), size: 2, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-24"), size: 3, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-32"), size: 4, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-40"), size: 5, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-48"), size: 6, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-56"), size: 7, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-64"), size: 8, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-72"), size: 9, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-80"), size: 10, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-88"), size: 11, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-96"), size: 12, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-104"), size: 13, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-112"), size: 14, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-120"), size: 15, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-128"), size: 16, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-136"), size: 17, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-144"), size: 18, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-152"), size: 19, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-160"), size: 20, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-168"), size: 21, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-176"), size: 22, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-184"), size: 23, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-192"), size: 24, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-200"), size: 25, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-208"), size: 26, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-216"), size: 27, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-224"), size: 28, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-232"), size: 29, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-240"), size: 30, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-248"), size: 31, coder: blake2Shash), + MHash(mcodec: multiCodec("blake2s-256"), size: 32, coder: blake2Shash) ] -proc initMultiHashNameTable(): Table[string, MHash] {.compileTime.} = - result = initTable[string, MHash]() +proc initMultiHashCodeTable(): Table[MultiCodec, MHash] {.compileTime.} = + result = initTable[MultiCodec, MHash]() for item in HashesList: - result[item.name] = item - -proc initMultiHashCodeTable(): Table[int, MHash] {.compileTime.} = - result = initTable[int, MHash]() - for item in HashesList: - result[item.code] = item + result[item.mcodec] = item const CodeHashes = initMultiHashCodeTable() - NameHashes = initMultiHashNameTable() - -proc multihashName*(code: int): string = - ## Returns MultiHash digest name from its code. - let hash = CodeHashes.getOrDefault(code) - if isNil(hash.coder): - raise newException(MultiHashError, "Hash not supported") - else: - result = hash.name - -proc multihashCode*(name: string): int = - ## Returns MultiHash digest code from its name. - let hash = NameHashes.getOrDefault(name) - if isNil(hash.coder): - raise newException(MultiHashError, "Hash not supported") - else: - result = hash.code proc digestImplWithHash(hash: MHash, data: openarray[byte]): MultiHash = var buffer: array[MaxHashSize, byte] result.data = initVBuffer() - result.code = hash.code - result.data.writeVarint(uint(hash.code)) + result.mcodec = hash.mcodec + result.data.writeCodec(hash.mcodec) if hash.size == 0: result.data.writeVarint(uint(len(data))) result.dpos = len(result.data.buffer) @@ -345,9 +323,9 @@ proc digestImplWithHash(hash: MHash, data: openarray[byte]): MultiHash = proc digestImplWithoutHash(hash: MHash, data: openarray[byte]): MultiHash = result.data = initVBuffer() - result.code = hash.code + result.mcodec = hash.mcodec result.size = len(data) - result.data.writeVarint(uint(hash.code)) + result.data.writeCodec(hash.mcodec) result.data.writeVarint(uint(len(data))) result.dpos = len(result.data.buffer) result.data.writeArray(data) @@ -356,7 +334,10 @@ proc digest*(mhtype: typedesc[MultiHash], hashname: string, data: openarray[byte]): MultiHash {.inline.} = ## Perform digest calculation using hash algorithm with name ``hashname`` on ## data array ``data``. - let hash = NameHashes.getOrDefault(hashname) + let mc = MultiCodec.codec(hashname) + if mc == InvalidMultiCodec: + raise newException(MultihashError, "Incorrect hash name") + let hash = CodeHashes.getOrDefault(mc) if isNil(hash.coder): raise newException(MultihashError, "Hash not supported") result = digestImplWithHash(hash, data) @@ -374,14 +355,17 @@ proc init*[T](mhtype: typedesc[MultiHash], hashname: string, mdigest: MDigest[T]): MultiHash {.inline.} = ## Create MultiHash from nimcrypto's `MDigest` object and hash algorithm name ## ``hashname``. - let hash = NameHashes.getOrDefault(hashname) + let mc = MultiCodec.codec(hashname) + if mc == InvalidMultiCodec: + raise newException(MultihashError, "Incorrect hash name") + let hash = CodeHashes.getOrDefault(mc) if isNil(hash.coder): raise newException(MultihashError, "Hash not supported") if hash.size != len(mdigest.data): raise newException(MultiHashError, "Incorrect MDigest[T] size") result = digestImplWithoutHash(hash, mdigest.data) -proc init*[T](mhtype: typedesc[MultiHash], hashcode: int, +proc init*[T](mhtype: typedesc[MultiHash], hashcode: MultiCodec, mdigest: MDigest[T]): MultiHash {.inline.} = ## Create MultiHash from nimcrypto's `MDigest` and hash algorithm code ## ``hashcode``. @@ -396,14 +380,17 @@ proc init*(mhtype: typedesc[MultiHash], hashname: string, bdigest: openarray[byte]): MultiHash {.inline.} = ## Create MultiHash from array of bytes ``bdigest`` and hash algorithm code ## ``hashcode``. - let hash = NameHashes.getOrDefault(hashname) + let mc = MultiCodec.codec(hashname) + if mc == InvalidMultiCodec: + raise newException(MultihashError, "Incorrect hash name") + let hash = CodeHashes.getOrDefault(mc) if isNil(hash.coder): raise newException(MultihashError, "Hash not supported") if (hash.size != 0) and (hash.size != len(bdigest)): raise newException(MultiHashError, "Incorrect bdigest size") result = digestImplWithoutHash(hash, bdigest) -proc init*(mhtype: typedesc[MultiHash], hashcode: int, +proc init*(mhtype: typedesc[MultiHash], hashcode: MultiCodec, bdigest: openarray[byte]): MultiHash {.inline.} = ## Create MultiHash from array of bytes ``bdigest`` and hash algorithm code ## ``hashcode``. @@ -439,14 +426,14 @@ proc decode*(mhtype: typedesc[MultiHash], data: openarray[byte], dpos += res if size > 0x7FFF_FFFF'u64: return -1 - let hash = CodeHashes.getOrDefault(int(code)) + let hash = CodeHashes.getOrDefault(MultiCodec(code)) if isNil(hash.coder): return -1 if (hash.size != 0) and (hash.size != int(size)): return -1 if not vb.isEnough(int(size)): return -1 - mhash = MultiHash.init(int(code), + mhash = MultiHash.init(MultiCodec(code), vb.buffer.toOpenArray(vb.offset, vb.offset + int(size) - 1)) result = vb.offset + int(size) @@ -494,12 +481,12 @@ proc `==`*[T](mdigest: MDigest[T], mh: MultiHash): bool {.inline.} = ## hashes are equal, ``false`` otherwise. result = `==`(mh, mdigest) -proc `==`*(a, b: MultiHash): bool = +proc `==`*(a: MultiHash, b: MultiHash): bool = ## Compares MultiHashes ``a`` and ``b``, returns ``true`` if ## hashes are equal, ``false`` otherwise. if a.dpos == 0 and b.dpos == 0: return true - if a.code != b.code: + if a.mcodec != b.mcodec: return false if a.size != b.size: return false @@ -514,8 +501,8 @@ proc base58*(value: MultiHash): string = ## Return Base58 encoded string representation of MultiHash ``value``. result = Base58.encode(value.data.buffer) -proc `$`*(value: MultiHash): string = +proc `$`*(mh: MultiHash): string = ## Return string representation of MultiHash ``value``. - let digest = toHex(value.data.buffer.toOpenArray(value.dpos, - value.dpos + value.size - 1)) - result = multihashName(value.code) & "/" & digest + let digest = toHex(mh.data.buffer.toOpenArray(mh.dpos, + mh.dpos + mh.size - 1)) + result = $(mh.mcodec) & "/" & digest diff --git a/libp2p/transcoder.nim b/libp2p/transcoder.nim index a9079d7a8..efe2ea561 100644 --- a/libp2p/transcoder.nim +++ b/libp2p/transcoder.nim @@ -12,6 +12,8 @@ import vbuffer type Transcoder* = object - stringToBuffer*: proc(s: string, vb: var VBuffer): bool {.nimcall.} - bufferToString*: proc(vb: var VBuffer, s: var string): bool {.nimcall.} - validateBuffer*: proc(vb: var VBuffer): bool {.nimcall.} + stringToBuffer*: proc(s: string, + vb: var VBuffer): bool {.nimcall, gcsafe.} + bufferToString*: proc(vb: var VBuffer, + s: var string): bool {.nimcall, gcsafe.} + validateBuffer*: proc(vb: var VBuffer): bool {.nimcall, gcsafe.}