Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions multiaddr/codecs/memory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import struct
from ..codecs import CodecBase
from ..exceptions import BinaryParseError

SIZE = 64
IS_PATH = False

class Codec(CodecBase):
SIZE = SIZE
IS_PATH = IS_PATH

def to_bytes(self, proto, string: str) -> bytes:
# Parse as unsigned 64-bit int
value = int(string, 10)
if value < 0 or value > 0xFFFFFFFFFFFFFFFF:
raise ValueError("Value out of range for uint64")
return struct.pack(">Q", value) # big-endian uint64

def to_string(self, proto, buf: bytes) -> str:
if len(buf) != 8:
raise BinaryParseError("Expected 8 bytes for uint64", buf, "memory")
value = struct.unpack(">Q", buf)[0]
return str(value)

def memory_validate(self, b: bytes) -> None:
if len(b) != 8:
raise ValueError(f"Invalid length: must be exactly 8 bytes, got {len(b)}")

2 changes: 2 additions & 0 deletions multiaddr/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
P_SNI = 0x01C1
P_NOISE = 0x01C6
P_WEBTRANSPORT = 0x01D1
P_MEMORY = 0x309


class Protocol:
Expand Down Expand Up @@ -166,6 +167,7 @@ def __repr__(self) -> str:
Protocol(P_P2P_CIRCUIT, "p2p-circuit", None),
Protocol(P_WEBTRANSPORT, "webtransport", None),
Protocol(P_UNIX, "unix", "fspath"),
Protocol(P_MEMORY, "memory", None)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what to write in the codec part here (so temporarily went with None), please clarify the correct parameter.

]


Expand Down
66 changes: 66 additions & 0 deletions tests/test_codec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import pytest
import struct

from multiaddr.codecs import memory
from multiaddr.exceptions import BinaryParseError


def test_to_bytes_and_to_string_roundtrip():
codec = memory.Codec()

# some valid values
for val in [0, 1, 42, 2**32, 2**64 - 1]:
s = str(val)
b = codec.to_bytes(None, s)
# must be exactly 8 bytes
assert isinstance(b, bytes)
assert len(b) == 8
# roundtrip back to string
out = codec.to_string(None, b)
assert out == s

def test_invalid_string_to_bytes():
codec = memory.Codec()

# not a number
with pytest.raises(ValueError):
codec.to_bytes(None, "abc")

# negative number
with pytest.raises(ValueError):
codec.to_bytes(None, "-1")

# too large
with pytest.raises(ValueError):
codec.to_bytes(None, str(2**64))

def test_invalid_bytes_to_string():
codec = memory.Codec()

# too short
with pytest.raises(BinaryParseError):
codec.to_string(None, b"\x00\x01")

# too long
with pytest.raises(BinaryParseError):
codec.to_string(None, b"\x00" * 9)


def test_specific_encoding():
codec = memory.Codec()

# 42 encoded in big-endian
expected_bytes = b"\x00\x00\x00\x00\x00\x00\x00*"
assert codec.to_bytes(None, "42") == expected_bytes
assert codec.to_string(None, expected_bytes) == "42"

def test_memory_validate_function():
# Directly test the helper
codec = memory.Codec()

# Valid case
codec.memory_validate(b"\x00" * 8) # should not raise

# Invalid length
with pytest.raises(ValueError):
codec.memory_validate(b"\x00" * 7)
Loading