Skip to content

Commit

Permalink
refactor: redo binary codec types to simplify (#396)
Browse files Browse the repository at this point in the history
* fix SerializedType circular typing

* simplify FieldInstance logic

* rename SerializedDict -> STObject (to match rippled)

* rename SerializedList -> STArray (to match rippled)

* fix tests
  • Loading branch information
mvadari committed Jun 13, 2022
1 parent 5bfb875 commit 5d51072
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 115 deletions.
40 changes: 20 additions & 20 deletions tests/unit/core/binarycodec/fixtures/data/data-driven-tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
"ordinal": 8
},
{
"name": "SerializedDict",
"name": "STObject",
"ordinal": 14
},
{
"name": "SerializedList",
"name": "STArray",
"ordinal": 15
},
{
Expand Down Expand Up @@ -736,126 +736,126 @@
"expected_hex": "88"
},
{
"type_name": "SerializedDict",
"type_name": "STObject",
"name": "ObjectEndMarker",
"nth_of_type": 1,
"type": 14,
"expected_hex": "E1"
},
{
"type_name": "SerializedDict",
"type_name": "STObject",
"name": "TransactionMetaData",
"nth_of_type": 2,
"type": 14,
"expected_hex": "E2"
},
{
"type_name": "SerializedDict",
"type_name": "STObject",
"name": "CreatedNode",
"nth_of_type": 3,
"type": 14,
"expected_hex": "E3"
},
{
"type_name": "SerializedDict",
"type_name": "STObject",
"name": "DeletedNode",
"nth_of_type": 4,
"type": 14,
"expected_hex": "E4"
},
{
"type_name": "SerializedDict",
"type_name": "STObject",
"name": "ModifiedNode",
"nth_of_type": 5,
"type": 14,
"expected_hex": "E5"
},
{
"type_name": "SerializedDict",
"type_name": "STObject",
"name": "PreviousFields",
"nth_of_type": 6,
"type": 14,
"expected_hex": "E6"
},
{
"type_name": "SerializedDict",
"type_name": "STObject",
"name": "FinalFields",
"nth_of_type": 7,
"type": 14,
"expected_hex": "E7"
},
{
"type_name": "SerializedDict",
"type_name": "STObject",
"name": "NewFields",
"nth_of_type": 8,
"type": 14,
"expected_hex": "E8"
},
{
"type_name": "SerializedDict",
"type_name": "STObject",
"name": "TemplateEntry",
"nth_of_type": 9,
"type": 14,
"expected_hex": "E9"
},
{
"type_name": "SerializedDict",
"type_name": "STObject",
"name": "Memo",
"nth_of_type": 10,
"type": 14,
"expected_hex": "EA"
},
{
"type_name": "SerializedList",
"type_name": "STArray",
"name": "ArrayEndMarker",
"nth_of_type": 1,
"type": 15,
"expected_hex": "F1"
},
{
"type_name": "SerializedList",
"type_name": "STArray",
"name": "Signers",
"nth_of_type": 3,
"type": 15,
"expected_hex": "F3"
},
{
"type_name": "SerializedList",
"type_name": "STArray",
"name": "SignerEntries",
"nth_of_type": 4,
"type": 15,
"expected_hex": "F4"
},
{
"type_name": "SerializedList",
"type_name": "STArray",
"name": "Template",
"nth_of_type": 5,
"type": 15,
"expected_hex": "F5"
},
{
"type_name": "SerializedList",
"type_name": "STArray",
"name": "Necessary",
"nth_of_type": 6,
"type": 15,
"expected_hex": "F6"
},
{
"type_name": "SerializedList",
"type_name": "STArray",
"name": "Sufficient",
"nth_of_type": 7,
"type": 15,
"expected_hex": "F7"
},
{
"type_name": "SerializedList",
"type_name": "STArray",
"name": "AffectedNodes",
"nth_of_type": 8,
"type": 15,
"expected_hex": "F8"
},
{
"type_name": "SerializedList",
"type_name": "STArray",
"name": "Memos",
"nth_of_type": 9,
"type": 15,
Expand Down
10 changes: 5 additions & 5 deletions tests/unit/core/binarycodec/types/test_serialized_dict.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from unittest import TestCase

from xrpl.core.binarycodec.binary_wrappers.binary_parser import BinaryParser
from xrpl.core.binarycodec.types.serialized_dict import SerializedDict
from xrpl.core.binarycodec.types.st_object import STObject

expected_json = {
"Account": "raD5qJMAShLeHZXf9wjUmo6vRK4arj9cF3",
Expand Down Expand Up @@ -37,18 +37,18 @@
)


class TestSerializedDict(TestCase):
class TestSTObject(TestCase):
maxDiff = 1000

def test_from_value(self):
transaction = SerializedDict.from_value(expected_json)
transaction = STObject.from_value(expected_json)
self.assertEqual(buffer, str(transaction).upper())

def test_from_value_to_json(self):
transaction = SerializedDict.from_value(expected_json)
transaction = STObject.from_value(expected_json)
self.assertEqual(transaction.to_json(), expected_json)

def test_from_parser_to_json(self):
parser = BinaryParser(buffer)
transaction = SerializedDict.from_parser(parser)
transaction = STObject.from_parser(parser)
self.assertEqual(transaction.to_json(), expected_json)
21 changes: 9 additions & 12 deletions tests/unit/core/binarycodec/types/test_serialized_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

from xrpl.core.binarycodec.binary_wrappers.binary_parser import BinaryParser
from xrpl.core.binarycodec.exceptions import XRPLBinaryCodecException
from xrpl.core.binarycodec.types.serialized_list import (
_ARRAY_END_MARKER,
SerializedList,
)
from xrpl.core.binarycodec.types.st_array import _ARRAY_END_MARKER, STArray

MEMO = {
"Memo": {
Expand All @@ -22,43 +19,43 @@
BUFFER = MEMO_HEX + MEMO_HEX + _ARRAY_END_MARKER.hex().upper()


class TestSerializedList(TestCase):
class TestSTArray(TestCase):
maxDiff = 1000

def test_from_value(self):
serialized_list = SerializedList.from_value(EXPECTED_JSON)
serialized_list = STArray.from_value(EXPECTED_JSON)
self.assertEqual(BUFFER, str(serialized_list))

def test_from_parser(self):
parser = BinaryParser(BUFFER)
serialized_list = SerializedList.from_parser(parser)
serialized_list = STArray.from_parser(parser)
self.assertEqual(BUFFER, str(serialized_list))

def test_from_value_to_json(self):
serialized_list = SerializedList.from_value(EXPECTED_JSON)
serialized_list = STArray.from_value(EXPECTED_JSON)
actual_json = serialized_list.to_json()
self.assertEqual(actual_json[0], actual_json[1])
self.assertEqual(actual_json, EXPECTED_JSON)

def test_from_parser_to_json(self):
parser = BinaryParser(BUFFER)
serialized_list = SerializedList.from_parser(parser)
serialized_list = STArray.from_parser(parser)
self.assertEqual(serialized_list.to_json(), EXPECTED_JSON)

def test_from_value_non_list(self):
obj = 123
with self.assertRaises(XRPLBinaryCodecException):
SerializedList.from_value(obj)
STArray.from_value(obj)

def test_from_value_bad_list(self):
obj = [123]
with self.assertRaises(XRPLBinaryCodecException):
SerializedList.from_value(obj)
STArray.from_value(obj)

def test_raises_invalid_value_type(self):
invalid_value = 1
self.assertRaises(
XRPLBinaryCodecException,
SerializedList.from_value,
STArray.from_value,
invalid_value,
)
34 changes: 4 additions & 30 deletions xrpl/core/binarycodec/definitions/field_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,38 +21,12 @@ def _get_type_by_name(name: str) -> Type[SerializedType]:
Returns:
The corresponding class object.
"""
from xrpl.core.binarycodec.types.account_id import AccountID
from xrpl.core.binarycodec.types.amount import Amount
from xrpl.core.binarycodec.types.blob import Blob
from xrpl.core.binarycodec.types.currency import Currency
from xrpl.core.binarycodec.types.hash128 import Hash128
from xrpl.core.binarycodec.types.hash160 import Hash160
from xrpl.core.binarycodec.types.hash256 import Hash256
from xrpl.core.binarycodec.types.path_set import PathSet
from xrpl.core.binarycodec.types.serialized_dict import SerializedDict
from xrpl.core.binarycodec.types.serialized_list import SerializedList
from xrpl.core.binarycodec.types.uint8 import UInt8
from xrpl.core.binarycodec.types.uint16 import UInt16
from xrpl.core.binarycodec.types.uint32 import UInt32
from xrpl.core.binarycodec.types.uint64 import UInt64
from xrpl.core.binarycodec.types.vector256 import Vector256
import xrpl.core.binarycodec.types as types

type_map: Dict[str, Type[SerializedType]] = {
"AccountID": AccountID,
"Amount": Amount,
"Blob": Blob,
"Currency": Currency,
"Hash128": Hash128,
"Hash160": Hash160,
"Hash256": Hash256,
"PathSet": PathSet,
"STArray": SerializedList,
"STObject": SerializedDict,
"UInt8": UInt8,
"UInt16": UInt16,
"UInt32": UInt32,
"UInt64": UInt64,
"Vector256": Vector256,
name: object_type
for (name, object_type) in types.__dict__.items()
if name in types.__all__
}

return type_map[name]
Expand Down
6 changes: 3 additions & 3 deletions xrpl/core/binarycodec/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from xrpl.core.binarycodec.binary_wrappers.binary_parser import BinaryParser
from xrpl.core.binarycodec.types.account_id import AccountID
from xrpl.core.binarycodec.types.hash256 import Hash256
from xrpl.core.binarycodec.types.serialized_dict import SerializedDict
from xrpl.core.binarycodec.types.st_object import STObject
from xrpl.core.binarycodec.types.uint64 import UInt64


Expand Down Expand Up @@ -108,7 +108,7 @@ def decode(buffer: str) -> Dict[str, Any]:
A JSON-like dictionary representation of the transaction.
"""
parser = BinaryParser(buffer)
parsed_type = cast(SerializedDict, parser.read_type(SerializedDict))
parsed_type = cast(STObject, parser.read_type(STObject))
return parsed_type.to_json()


Expand All @@ -122,7 +122,7 @@ def _serialize_json(
if prefix is not None:
buffer += prefix

buffer += bytes(SerializedDict.from_value(json, signing_only))
buffer += bytes(STObject.from_value(json, signing_only))

if suffix is not None:
buffer += suffix
Expand Down
6 changes: 4 additions & 2 deletions xrpl/core/binarycodec/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from xrpl.core.binarycodec.types.hash160 import Hash160
from xrpl.core.binarycodec.types.hash256 import Hash256
from xrpl.core.binarycodec.types.path_set import PathSet
from xrpl.core.binarycodec.types.serialized_type import SerializedType
from xrpl.core.binarycodec.types.st_array import STArray
from xrpl.core.binarycodec.types.st_object import STObject
from xrpl.core.binarycodec.types.uint import UInt
from xrpl.core.binarycodec.types.uint8 import UInt8
from xrpl.core.binarycodec.types.uint16 import UInt16
Expand All @@ -26,7 +27,8 @@
"Hash160",
"Hash256",
"PathSet",
"SerializedType",
"STObject",
"STArray",
"UInt",
"UInt8",
"UInt16",
Expand Down
9 changes: 6 additions & 3 deletions xrpl/core/binarycodec/types/serialized_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Any, Type
from typing import TYPE_CHECKING, Any, Type

if TYPE_CHECKING:
# To prevent a circular dependency.
from xrpl.core.binarycodec.binary_wrappers.binary_parser import BinaryParser


class SerializedType(ABC):
Expand All @@ -16,8 +20,7 @@ def __init__(self: SerializedType, buffer: bytes = bytes()) -> None:
@abstractmethod
def from_parser( # noqa: D102
cls: Type[SerializedType],
# TODO: Resolve Any (can't be ``BinaryParser`` because of circular imports)
parser: Any,
parser: BinaryParser,
# length_hint is Any so that subclasses can choose whether or not to require it.
length_hint: Any,
) -> SerializedType:
Expand Down

0 comments on commit 5d51072

Please sign in to comment.