Skip to content

Commit 8ad906c

Browse files
authored
Merge pull request #59 from ntninja/master
Spec updates, Python 3.4- unsupport & custom registries
2 parents df7176c + 8df4450 commit 8ad906c

28 files changed

+554
-358
lines changed

.travis.yml

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,18 @@
1-
sudo: false
21
language: python
32
matrix:
43
include:
54
- python: 3.6
65
env: TOXENV=lint
7-
- python: 2.7
8-
env: TOXENV=py27
9-
- python: 3.4
10-
env: TOXENV=py34
116
- python: 3.5
127
env: TOXENV=py35
138
- python: 3.6
149
env: TOXENV=py36
1510
- python: 3.7
1611
env: TOXENV=py37
17-
dist: xenial
12+
- python: 3.8
13+
env: TOXENV=py38
1814
- python: pypy3.5
1915
env: TOXENV=pypy3
20-
allow_failures:
21-
- python: 2.7
22-
env: TOXENV=py27
2316

2417
install:
2518
- pip install tox

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
Steven Buss <[email protected]>
22
Fred Thomsen <[email protected]>
33
Jesse Weinstein <[email protected]>
4+
Alexander Schlarb <[email protected]>

LICENSE-MIT

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
The MIT License (MIT)
22

33
Copyright (c) 2014-2015 Steven Buss
4+
Copyright (c) 2019-2020 Alexander Schlarb
45

56
Permission is hereby granted, free of charge, to any person obtaining a copy
67
of this software and associated documentation files (the "Software"), to deal

USAGE.rst

Whitespace-only changes.

multiaddr/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# -*- coding: utf-8 -*-
21
from .multiaddr import Multiaddr # NOQA
32

43
__author__ = 'Steven Buss'

multiaddr/codecs/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# -*- encoding: utf-8 -*-
2-
from __future__ import absolute_import
31
import importlib
42

53

multiaddr/codecs/_util.py

Lines changed: 0 additions & 8 deletions
This file was deleted.

multiaddr/codecs/cid.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import base58
2+
import cid
3+
4+
from . import LENGTH_PREFIXED_VAR_SIZE
5+
6+
7+
SIZE = LENGTH_PREFIXED_VAR_SIZE
8+
IS_PATH = False
9+
10+
11+
# Spec: https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#string-representation
12+
CIDv0_PREFIX_TO_LENGTH = {
13+
# base58btc prefixes for valid lengths 1 – 42 with the identity “hash” function
14+
'12': [5, 12, 19, 23, 30, 41, 52, 56],
15+
'13': [9, 16, 34, 45],
16+
'14': [27, 38, 49, 60],
17+
'15': [3, 6, 20],
18+
'16': [3, 6, 13, 20, 31, 42, 53],
19+
'17': [3, 13, 42],
20+
'18': [3],
21+
'19': [3, 24, 57],
22+
'1A': [24, 35, 46],
23+
'1B': [35],
24+
'1D': [17],
25+
'1E': [10, 17],
26+
'1F': [10],
27+
'1G': [10, 28, 50],
28+
'1H': [28, 39],
29+
'1P': [21],
30+
'1Q': [21],
31+
'1R': [21, 54],
32+
'1S': [54],
33+
'1T': [7, 32, 43],
34+
'1U': [7, 32, 43],
35+
'1V': [7],
36+
'1W': [7, 14],
37+
'1X': [7, 14],
38+
'1Y': [7, 14],
39+
'1Z': [7, 14],
40+
'1f': [4],
41+
'1g': [4, 58],
42+
'1h': [4, 25, 58],
43+
'1i': [4, 25],
44+
'1j': [4, 25],
45+
'1k': [4, 25, 47],
46+
'1m': [4, 36, 47],
47+
'1n': [4, 36],
48+
'1o': [4, 36],
49+
'1p': [4],
50+
'1q': [4],
51+
'1r': [4],
52+
'1s': [4],
53+
'1t': [4],
54+
'1u': [4],
55+
'1v': [4],
56+
'1w': [4],
57+
'1x': [4],
58+
'1y': [4],
59+
'1z': [4, 18],
60+
61+
# base58btc prefix for length 42 with the sha256 hash function
62+
'Qm': [46],
63+
}
64+
65+
PROTO_NAME_TO_CIDv1_CODEC = {
66+
# The “p2p” multiaddr protocol requires all keys to use the “libp2p-key” multicodec
67+
"p2p": "libp2p-key",
68+
}
69+
70+
71+
def to_bytes(proto, string):
72+
expected_codec = PROTO_NAME_TO_CIDv1_CODEC.get(proto.name)
73+
74+
if len(string) in CIDv0_PREFIX_TO_LENGTH.get(string[0:2], ()): # CIDv0
75+
# Upgrade the wire (binary) representation of any received CIDv0 string
76+
# to CIDv1 if we can determine which multicodec value to use
77+
if expected_codec:
78+
return cid.make_cid(1, expected_codec, base58.b58decode(string)).buffer
79+
80+
return base58.b58decode(string)
81+
else: # CIDv1+
82+
parsed = cid.from_string(string)
83+
84+
# Ensure CID has correct codec for protocol
85+
if expected_codec and parsed.codec != expected_codec:
86+
raise ValueError("“{0}” multiaddr CIDs must use the “{1}” multicodec"
87+
.format(proto.name, expected_codec))
88+
89+
return parsed.buffer
90+
91+
92+
def _is_binary_cidv0_multihash(buf):
93+
if buf.startswith(b"\x12\x20") and len(buf) == 34: # SHA2-256
94+
return True
95+
96+
if (buf[0] == 0x00 and buf[1] in range(43)) and len(buf) == (buf[1] + 2): # Identity hash
97+
return True
98+
99+
return False
100+
101+
102+
def to_string(proto, buf):
103+
expected_codec = PROTO_NAME_TO_CIDv1_CODEC.get(proto.name)
104+
105+
if _is_binary_cidv0_multihash(buf): # CIDv0
106+
if not expected_codec:
107+
# Simply encode as base58btc as there is nothing better to do
108+
return base58.b58encode(buf).decode('ascii')
109+
110+
# “Implementations SHOULD display peer IDs using the first (raw
111+
# base58btc encoded multihash) format until the second format is
112+
# widely supported.”
113+
#
114+
# In the future the following line should instead convert the multihash
115+
# to CIDv1 and with the `expected_codec` and wrap it in base32:
116+
# return cid.make_cid(1, expected_codec, buf).encode("base32").decode("ascii")
117+
return base58.b58encode(buf).decode("ascii")
118+
else: # CIDv1+
119+
parsed = cid.from_bytes(buf)
120+
121+
# Ensure CID has correct codec for protocol
122+
if expected_codec and parsed.codec != expected_codec:
123+
raise ValueError("“{0}” multiaddr CIDs must use the “{1}” multicodec"
124+
.format(proto.name, expected_codec))
125+
126+
# “Implementations SHOULD display peer IDs using the first (raw
127+
# base58btc encoded multihash) format until the second format is
128+
# widely supported.”
129+
if expected_codec and _is_binary_cidv0_multihash(parsed.multihash):
130+
return base58.b58encode(parsed.multihash).decode("ascii")
131+
132+
return parsed.encode("base32").decode("ascii")

multiaddr/codecs/domain.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import idna
2+
3+
from . import LENGTH_PREFIXED_VAR_SIZE
4+
5+
6+
SIZE = LENGTH_PREFIXED_VAR_SIZE
7+
IS_PATH = False
8+
9+
10+
def to_bytes(proto, string):
11+
return idna.uts46_remap(string).encode("utf-8")
12+
13+
14+
def to_string(proto, buf):
15+
string = buf.decode("utf-8")
16+
for label in string.split("."):
17+
idna.check_label(label)
18+
return string

multiaddr/codecs/fspath.py

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,15 @@
1-
from __future__ import absolute_import
21
import os
32

4-
import six
5-
63
from . import LENGTH_PREFIXED_VAR_SIZE
74

85

96
SIZE = LENGTH_PREFIXED_VAR_SIZE
107
IS_PATH = True
118

129

13-
if hasattr(os, "fsencode") and hasattr(os, "fsdecode"):
14-
fsencode = os.fsencode
15-
fsdecode = os.fsdecode
16-
else: # pragma: no cover (PY2)
17-
import sys
18-
19-
def fsencode(path):
20-
if not isinstance(path, six.binary_type):
21-
path = path.encode(sys.getfilesystemencoding())
22-
return path
23-
24-
def fsdecode(path):
25-
if not isinstance(path, six.text_type):
26-
path = path.decode(sys.getfilesystemencoding())
27-
return path
28-
29-
3010
def to_bytes(proto, string):
31-
return fsencode(string)
11+
return os.fsencode(string)
3212

3313

3414
def to_string(proto, buf):
35-
return fsdecode(buf)
15+
return os.fsdecode(buf)

0 commit comments

Comments
 (0)