Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Message pack & unpack #10

Merged
merged 5 commits into from
Feb 21, 2024
Merged

Message pack & unpack #10

merged 5 commits into from
Feb 21, 2024

Conversation

popenta
Copy link
Collaborator

@popenta popenta commented Feb 9, 2024

Added functionality to "pack" and "unpack" a message.

@popenta popenta self-assigned this Feb 9, 2024


class Message:
def __init__(self, data: bytes, signature: bytes = b"") -> None:
def __init__(self, data: bytes, address: IAddress, signature: bytes = b"", version: int = 1) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

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

While the new ordering of the parameters is good and makes perfect sense, let's postpone the breaking change for some time - and make the new address optional, as well (and keep the previous order of the parameters).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

changed the order of the parameters and made address: Optional[IAddress] = None

}

def unpack(self, packed_message: Dict[str, Any]) -> Message:
data: str = packed_message["message"]
Copy link
Contributor

Choose a reason for hiding this comment

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

We should handle missing data - possibly allow something to be missing (e.g. address, version).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

now handling missing data, but that shouldn't happen because of the default values.


def unpack(self, packed_message: Dict[str, Any]) -> Message:
data: str = packed_message["message"]
if data.startswith("0x") or data.startswith("0X"):
Copy link
Contributor

Choose a reason for hiding this comment

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

Can extract to a private function e.g. trim_hex_prefix or so.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

def compute_bytes_for_verifying(self, message: IMessage) -> bytes:
return self.compute_bytes_for_signing(message)

def pack(self, message: IMessage) -> Dict[str, Any]:
Copy link
Contributor

Choose a reason for hiding this comment

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

I know here we are in the MessageComputer itself, but maybe we can name the functions pack_message() and unpack_message() (more explicit naming)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

renamed the methods.

@@ -1244,15 +1245,15 @@
}
],
"source": [
"from multiversx_sdk.core import TransactionComputer, MessageComputer\n",
"from multiversx_sdk.core import MessageComputer, TransactionComputer\n",
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, it's so nice to have the cookbook in the same repository :)

@@ -29,6 +31,8 @@ class ITransaction(Protocol):
class IMessage(Protocol):
data: bytes
signature: bytes
address: IAddress
version: int
Copy link
Contributor

Choose a reason for hiding this comment

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

Now that I think about it - there does not seem too much value in having an interface for the message DTO (neither for the transaction DTO, on that matter, but we'll see). Let's think about dropping some of these, if not very useful (e.g. a message DTO is easy to create / instantiate, it's very close to being a "primitive" piece of data).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will keep it in mind

assert message.signature.hex() == "7aff43cd6e3d880a65033bf0a1b16274854fd7dfa9fe5faa7fa9a665ee851afd4c449310f5f1697d348e42d1819eaef69080e33e7652d7393521ed50d7427a0e"

packed_message = message_computer.pack(message)
assert packed_message == {
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps add a test where the packed message is in the legacy form (with 0x)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

added a test using the legacy message

andreibancioiu
andreibancioiu previously approved these changes Feb 12, 2024

address = Address.from_bech32(packed_message["address"])
version = packed_message["version"]
version = packed_message.get("version", 1)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can be a constant (here and for the constructor of Message).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

@popenta popenta merged commit 3fd8a6e into main Feb 21, 2024
3 checks passed
@popenta popenta deleted the decode-message-from-dict branch February 21, 2024 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants