enable full safety selection through api
This commit is contained in:
@@ -16,14 +16,28 @@ from .conftest import server_info
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_routing_contexts(api_connection: veilid.VeilidAPI):
|
||||
rc = await api_connection.new_routing_context()
|
||||
async with rc:
|
||||
pass
|
||||
|
||||
rc = await api_connection.new_routing_context()
|
||||
async with rc:
|
||||
rcp = await rc.with_privacy(release=False)
|
||||
async with rcp:
|
||||
rcps = await rcp.with_sequencing(veilid.Sequencing.ENSURE_ORDERED, release=False)
|
||||
async with rcps:
|
||||
rcpscp = await rcps.with_custom_privacy(veilid.Stability.RELIABLE, release=False)
|
||||
await rcpscp.release()
|
||||
pass
|
||||
|
||||
rc = await (await api_connection.new_routing_context()).with_sequencing(veilid.Sequencing.ENSURE_ORDERED)
|
||||
async with rc:
|
||||
pass
|
||||
|
||||
rc = await (await api_connection.new_routing_context()).with_custom_privacy(
|
||||
veilid.SafetySelection.safe(
|
||||
veilid.SafetySpec(None, 2, veilid.Stability.RELIABLE, veilid.Sequencing.ENSURE_ORDERED)
|
||||
))
|
||||
await rc.release()
|
||||
|
||||
rc = await (await api_connection.new_routing_context()).with_custom_privacy(veilid.SafetySelection.unsafe(veilid.Sequencing.ENSURE_ORDERED))
|
||||
await rc.release()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
@@ -27,7 +27,7 @@ class RoutingContext(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def with_custom_privacy(self, stability: types.Stability, release = True) -> Self:
|
||||
async def with_custom_privacy(self, safety_selection: types.SafetySelection, release = True) -> Self:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
@@ -16,7 +16,7 @@ from .state import VeilidState, VeilidUpdate
|
||||
from .types import (CryptoKey, CryptoKeyDistance, CryptoKind,
|
||||
DHTRecordDescriptor, DHTSchema, HashDigest, KeyPair,
|
||||
NewPrivateRouteResult, Nonce, OperationId, PublicKey,
|
||||
RouteId, SecretKey, Sequencing, SharedSecret, Signature,
|
||||
RouteId, SafetySelection, SecretKey, Sequencing, SharedSecret, Signature,
|
||||
Stability, Timestamp, TypedKey, TypedKeyPair,
|
||||
TypedSignature, ValueData, ValueSubkey, VeilidJSONEncoder,
|
||||
VeilidVersion, urlsafe_b64decode_no_pad)
|
||||
@@ -459,14 +459,14 @@ class _JsonRoutingContext(RoutingContext):
|
||||
await self.release()
|
||||
return self.__class__(self.api, new_rc_id)
|
||||
|
||||
async def with_custom_privacy(self, stability: Stability, release = True) -> Self:
|
||||
async def with_custom_privacy(self, safety_selection: SafetySelection, release = True) -> Self:
|
||||
new_rc_id = raise_api_result(
|
||||
await self.api.send_ndjson_request(
|
||||
Operation.ROUTING_CONTEXT,
|
||||
validate=validate_rc_op,
|
||||
rc_id=self.rc_id,
|
||||
rc_op=RoutingContextOperation.WITH_CUSTOM_PRIVACY,
|
||||
stability=stability,
|
||||
safety_selection=safety_selection,
|
||||
)
|
||||
)
|
||||
if release:
|
||||
|
@@ -224,7 +224,7 @@
|
||||
"type": "object",
|
||||
"required": [
|
||||
"rc_op",
|
||||
"stability"
|
||||
"safety_selection"
|
||||
],
|
||||
"properties": {
|
||||
"rc_op": {
|
||||
@@ -233,8 +233,8 @@
|
||||
"WithCustomPrivacy"
|
||||
]
|
||||
},
|
||||
"stability": {
|
||||
"$ref": "#/definitions/Stability"
|
||||
"safety_selection": {
|
||||
"$ref": "#/definitions/SafetySelection"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1566,6 +1566,77 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"SafetySelection": {
|
||||
"description": "The choice of safety route to include in compiled routes",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Don't use a safety route, only specify the sequencing preference",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"Unsafe"
|
||||
],
|
||||
"properties": {
|
||||
"Unsafe": {
|
||||
"$ref": "#/definitions/Sequencing"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"description": "Use a safety route and parameters specified by a SafetySpec",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"Safe"
|
||||
],
|
||||
"properties": {
|
||||
"Safe": {
|
||||
"$ref": "#/definitions/SafetySpec"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"SafetySpec": {
|
||||
"description": "Options for safety routes (sender privacy)",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"hop_count",
|
||||
"sequencing",
|
||||
"stability"
|
||||
],
|
||||
"properties": {
|
||||
"hop_count": {
|
||||
"description": "must be greater than 0",
|
||||
"type": "integer",
|
||||
"format": "uint",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"preferred_route": {
|
||||
"description": "preferred safety route set id if it still exists",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sequencing": {
|
||||
"description": "prefer connection-oriented sequenced protocols",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Sequencing"
|
||||
}
|
||||
]
|
||||
},
|
||||
"stability": {
|
||||
"description": "prefer reliability over speed",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Stability"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Sequencing": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
@@ -67,6 +67,9 @@ class DHTSchemaKind(StrEnum):
|
||||
DFLT = "DFLT"
|
||||
SMPL = "SMPL"
|
||||
|
||||
class SafetySelectionKind(StrEnum):
|
||||
UNSAFE = "Unsafe"
|
||||
SAFE = "Safe"
|
||||
|
||||
####################################################################
|
||||
|
||||
@@ -357,7 +360,7 @@ class ValueData:
|
||||
|
||||
def __lt__(self, other):
|
||||
if other is None:
|
||||
return true
|
||||
return True
|
||||
if self.data < other.data:
|
||||
return True
|
||||
if self.data > other.data:
|
||||
@@ -383,3 +386,61 @@ class ValueData:
|
||||
|
||||
def to_json(self) -> dict:
|
||||
return self.__dict__
|
||||
|
||||
|
||||
####################################################################
|
||||
|
||||
class SafetySpec:
|
||||
preferred_route: Optional[RouteId]
|
||||
hop_count: int
|
||||
stability: Stability
|
||||
sequencing: Sequencing
|
||||
|
||||
def __init__(self, preferred_route: Optional[RouteId], hop_count: int, stability: Stability, sequencing: Sequencing):
|
||||
self.preferred_route = preferred_route
|
||||
self.hop_count = hop_count
|
||||
self.stability = stability
|
||||
self.sequencing = sequencing
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, j: dict) -> Self:
|
||||
return cls(RouteId(j["preferred_route"]) if "preferred_route" in j else None,
|
||||
j["hop_count"],
|
||||
Stability(j["stability"]),
|
||||
Sequencing(j["sequencing"]))
|
||||
|
||||
def to_json(self) -> dict:
|
||||
return self.__dict__
|
||||
|
||||
class SafetySelection:
|
||||
kind: SafetySelectionKind
|
||||
|
||||
def __init__(self, kind: SafetySelectionKind, **kwargs):
|
||||
self.kind = kind
|
||||
for k, v in kwargs.items():
|
||||
setattr(self, k, v)
|
||||
|
||||
@classmethod
|
||||
def unsafe(cls, sequencing: Sequencing) -> Self:
|
||||
return cls(SafetySelectionKind.UNSAFE, sequencing=sequencing)
|
||||
|
||||
@classmethod
|
||||
def safe(cls, safety_spec: SafetySpec) -> Self:
|
||||
return cls(SafetySelectionKind.SAFE, safety_spec=safety_spec)
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, j: dict) -> Self:
|
||||
if "Safe" in j:
|
||||
return cls.safe(SafetySpec.from_json(j["Safe"]))
|
||||
elif "Unsafe" in j:
|
||||
return cls.unsafe(Sequencing(j["Unsafe"]))
|
||||
raise Exception("Invalid SafetySelection")
|
||||
|
||||
def to_json(self) -> dict:
|
||||
if self.kind == SafetySelectionKind.UNSAFE:
|
||||
return {"Unsafe": self.sequencing }
|
||||
elif self.kind == SafetySelectionKind.SAFE:
|
||||
return {"Safe": self.safety_spec.to_json() }
|
||||
else:
|
||||
raise Exception("Invalid SafetySelection")
|
||||
|
||||
|
Reference in New Issue
Block a user