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

Implement Confidential message type #99

Merged
merged 10 commits into from
Jun 18, 2024
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:

- name: Test with ruff in the Docker image
run: |
docker run aleph-message:${GITHUB_REF##*/} ruff aleph_message
docker run aleph-message:${GITHUB_REF##*/} ruff check aleph_message

- name: Pytest in the Docker image
run: |
Expand Down
16 changes: 14 additions & 2 deletions aleph_message/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .abstract import BaseContent
from .base import Chain, HashType, MessageType
from .execution.base import MachineType, Payment, PaymentType # noqa
from .execution.confidential import ConfidentialContent
from .execution.instance import InstanceContent
from .execution.program import ProgramContent
from .item_hash import ItemHash, ItemType
Expand Down Expand Up @@ -297,12 +298,18 @@ class InstanceMessage(BaseMessage):
content: InstanceContent


class ConfidentialMessage(BaseMessage):
type: Literal[MessageType.confidential]
content: ConfidentialContent


AlephMessage: TypeAlias = Union[
PostMessage,
AggregateMessage,
StoreMessage,
ProgramMessage,
InstanceMessage,
ConfidentialMessage,
ForgetMessage,
]

Expand All @@ -317,11 +324,16 @@ class InstanceMessage(BaseMessage):
StoreMessage,
ProgramMessage,
InstanceMessage,
ConfidentialMessage,
ForgetMessage,
]

ExecutableContent: TypeAlias = Union[InstanceContent, ProgramContent]
ExecutableMessage: TypeAlias = Union[InstanceMessage, ProgramMessage]
ExecutableContent: TypeAlias = Union[
InstanceContent, ProgramContent, ConfidentialContent
]
ExecutableMessage: TypeAlias = Union[
InstanceMessage, ProgramMessage, ConfidentialMessage
]


def parse_message(message_dict: Dict) -> AlephMessage:
Expand Down
1 change: 1 addition & 0 deletions aleph_message/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ class MessageType(str, Enum):
store = "STORE"
program = "PROGRAM"
instance = "INSTANCE"
confidential = "CONFIDENTIAL"
nesitor marked this conversation as resolved.
Show resolved Hide resolved
forget = "FORGET"
8 changes: 7 additions & 1 deletion aleph_message/models/execution/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
from .abstract import BaseExecutableContent
from .confidential import ConfidentialContent
from .instance import InstanceContent
from .program import ProgramContent

__all__ = ["BaseExecutableContent", "InstanceContent", "ProgramContent"]
__all__ = [
"BaseExecutableContent",
"ConfidentialContent",
"InstanceContent",
"ProgramContent",
]
28 changes: 28 additions & 0 deletions aleph_message/models/execution/confidential.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from __future__ import annotations

from pydantic import Field

from .abstract import BaseExecutableContent
from .base import Payment
from .volume import RootfsVolume
from ..item_hash import ItemHash


class ConfidentialPayment(Payment):
"""Payment information for a confidential instance execution."""

# Added node item hash required on the payment field
node_hash: ItemHash
"""Node item hash that execute the message"""


class ConfidentialContent(BaseExecutableContent):
"""Message content for scheduling a VM confidential instance on the network."""

# Make payment field required for confidential messages
payment: ConfidentialPayment = Field(
description="Payment details for the confidential execution"
)
rootfs: RootfsVolume = Field(
description="Root filesystem of the system, will be booted by the kernel"
)
18 changes: 1 addition & 17 deletions aleph_message/models/execution/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,8 @@

from pydantic import Field

from aleph_message.models.abstract import HashableModel

from .abstract import BaseExecutableContent
from .volume import ParentVolume, PersistentVolumeSizeMib, VolumePersistence


class RootfsVolume(HashableModel):
"""
Root file system of a VM instance.

The root file system of an instance is built as a copy of a reference image, named parent
image. The user determines a custom size and persistence model.
"""

parent: ParentVolume
persistence: VolumePersistence
# Use the same size constraint as persistent volumes for now
size_mib: PersistentVolumeSizeMib
from .volume import RootfsVolume


class InstanceContent(BaseExecutableContent):
Expand Down
14 changes: 14 additions & 0 deletions aleph_message/models/execution/volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,18 @@ def is_read_only(self):
return False


class RootfsVolume(HashableModel):
"""
Root file system of a VM instance.

The root file system of an instance is built as a copy of a reference image, named parent
image. The user determines a custom size and persistence model.
"""

parent: ParentVolume
persistence: VolumePersistence
# Use the same size constraint as persistent volumes for now
size_mib: PersistentVolumeSizeMib


MachineVolume = Union[ImmutableVolume, EphemeralVolume, PersistentVolume]
100 changes: 100 additions & 0 deletions aleph_message/tests/messages/confidential_machine.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{
"_id": {
"$oid": "6080402d7f44efefd611dc1e"
},
"chain": "ETH",
"sender": "0x9319Ad3B7A8E0eE24f2E639c40D8eD124C5520Ba",
"type": "CONFIDENTIAL",
"channel": "Fun-dApps",
"confirmed": true,
"content": {
"address": "0x9319Ad3B7A8E0eE24f2E639c40D8eD124C5520Ba",
"allow_amend": false,
"variables": {
"VM_CUSTOM_VARIABLE": "SOMETHING",
"VM_CUSTOM_VARIABLE_2": "32"
},
"environment": {
"reproducible": true,
"internet": false,
"aleph_api": false,
"shared_cache": false
},
"resources": {
"vcpus": 1,
"memory": 2048,
"seconds": 30
},
"requirements": {
"cpu": {
"architecture": "x86_64"
}
},
"rootfs": {
"parent": {
"ref": "549ec451d9b099cad112d4aaa2c00ac40fb6729a92ff252ff22eef0b5c3cb613",
"use_latest": true
},
"persistence": "host",
"size_mib": 20480
},
"payment": {
"chain": "AVAX",
"receiver": "0x4145f182EF2F06b45E50468519C1B92C60FBd4A0",
"type": "superfluid",
"node_hash": "589d81de8531bc8f9281ca43610d6640571228eae07cc879c675ffdb28ffaf3c"
},
"authorized_keys": [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGULT6A41Msmw2KEu0R9MvUjhuWNAsbdeZ0DOwYbt4Qt user@example",
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH0jqdc5dmt75QhTrWqeHDV9xN8vxbgFyOYs2fuQl7CI",
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDRsrQV1HVrcnskNhyH0may8TG9fHCPawpAi3ZgAWU6V/R7ezvZOHnZdaFeIsOpFbPbt/l67Fur3qniSXllI2kvuh2D4BBJ9PwwlB2sgWzFDF34ADsfLQf+C/vpwrWemEEE91Tpj0dWbnf219i3mZLxy/+5Sv6kUy9YJlzWnDEUbaMAZK2CXrlK90b9Ns7mT82h6h3x9dLF/oCjBAKOSxbH2X+KgsDEZT0soxyluDqKNgKflkav+pvKFyD4J9IWM4j36r80yW+OPGsHqWoWleEhprfNb60RJPwKAYCDiBiSg6wCq5P+kS15O79Ko45wPaYDUwhRoNTcrWeadvTaCZgz9X3KDHgrX6wzdKqzQwtQeabhCaIGLFRMNl1Oy/BR8VozPbIe/mY28IN84An50UYkbve7nOGJucKc4hKxZKEVPpnVpRtIoWGwBJY2fi6C6wy2pBa8UX4C4t9NLJjNQSwFBzYOrphLu3ZW9A+267nogQHGnsJ5xnQ/MXximP3BlwM= user@example"
],
"volumes": [
{
"comment": "Python libraries. Read-only since a 'ref' is specified.",
"mount": "/opt/venv",
"ref": "5f31b0706f59404fad3d0bff97ef89ddf24da4761608ea0646329362c662ba51",
"use_latest": false
},
{
"comment": "Ephemeral storage, read-write but will not persist after the VM stops",
"mount": "/var/cache",
"ephemeral": true,
"size_mib": 5
},
{
"comment": "Working data persisted on the VM supervisor, not available on other nodes",
"mount": "/var/lib/sqlite",
"name": "sqlite-data",
"persistence": "host",
"size_mib": 10
},
{
"comment": "Working data persisted on the Aleph network. New VMs will try to use the latest version of this volume, with no guarantee against conflicts",
"mount": "/var/lib/statistics",
"name": "statistics",
"persistence": "store",
"size_mib": 10
},
{
"comment": "Raw drive to use by a process, do not mount it",
"name": "raw-data",
"persistence": "host",
"size_mib": 10
}
],
"replaces": "0x9319Ad3B7A8E0eE24f2E639c40D8eD124C5520Ba",
"time": 1619017773.8950517
},
"item_type": "inline",
"signature": "0x372da8230552b8c3e65c05b31a0ff3a24666d66c575f8e11019f62579bf48c2b7fe2f0bbe907a2a5bf8050989cdaf8a59ff8a1cbcafcdef0656c54279b4aa0c71b",
"size": 749,
"time": 1619017773.8950577,
"confirmations": [
{
"chain": "ETH",
"height": 12284734,
"hash": "0x67f2f3cde5e94e70615c92629c70d22dc959a118f46e9411b29659c2fce87cdc"
}
]
}
11 changes: 11 additions & 0 deletions aleph_message/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from aleph_message.exceptions import UnknownHashError
from aleph_message.models import (
AggregateMessage,
ConfidentialMessage,
ForgetMessage,
InstanceMessage,
ItemType,
Expand Down Expand Up @@ -149,6 +150,16 @@ def test_instance_message_machine():
assert hash(message.content)


def test_confidential_message_machine():
path = Path(
os.path.abspath(os.path.join(__file__, "../messages/confidential_machine.json"))
)
message = create_message_from_file(path, factory=ConfidentialMessage)

assert isinstance(message, ConfidentialMessage)
assert hash(message.content)


def test_message_machine_port_mapping():
message_dict = {
"chain": "ETH",
Expand Down
Loading