320 lines
14 KiB
Nim
320 lines
14 KiB
Nim
# Nim-Libp2p
|
|
# Copyright (c) 2023 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.
|
|
|
|
when (NimMajor, NimMinor) < (1, 4):
|
|
{.push raises: [Defect].}
|
|
else:
|
|
{.push raises: [].}
|
|
|
|
import tables, hashes
|
|
import varint, vbuffer
|
|
import stew/results
|
|
export results
|
|
|
|
## 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),
|
|
("onion3", 0x01BD),
|
|
("p2p-circuit", 0x0122),
|
|
("libp2p-peer-record", 0x0301),
|
|
("dns", 0x35),
|
|
("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* = enum
|
|
MultiCodecNotSupported
|
|
|
|
const
|
|
InvalidMultiCodec* = MultiCodec(-1)
|
|
|
|
proc initMultiCodecNameTable(): Table[string, int] {.compileTime.} =
|
|
for item in MultiCodecList:
|
|
result[item[0]] = item[1]
|
|
|
|
proc initMultiCodecCodeTable(): Table[int, string] {.compileTime.} =
|
|
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.
|
|
let code = NameCodecs.getOrDefault(name, -1)
|
|
doAssert(code != -1)
|
|
MultiCodec(code)
|
|
|
|
proc multiCodec*(code: int): MultiCodec {.compileTime.} =
|
|
## Generate MultiCodec from integer ``code`` at compile time.
|
|
let name = CodeCodecs.getOrDefault(code, "")
|
|
doAssert(name != "")
|
|
MultiCodec(code)
|
|
|
|
proc `$`*(mc: MultiCodec): string =
|
|
## Returns string representation of MultiCodec ``mc``.
|
|
let name = CodeCodecs.getOrDefault(int(mc), "")
|
|
doAssert(name != "")
|
|
name
|
|
|
|
proc `==`*(mc: MultiCodec, name: string): bool {.inline.} =
|
|
## Compares MultiCodec ``mc`` with string ``name``.
|
|
let 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``.
|
|
(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.
|
|
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.
|
|
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 == "":
|
|
InvalidMultiCodec
|
|
else:
|
|
MultiCodec(code)
|
|
|
|
proc write*(vb: var VBuffer, mc: MultiCodec) {.inline.} =
|
|
## Write MultiCodec to buffer ``vb``.
|
|
vb.writeVarint(cast[uint](mc))
|