mirror of
https://gitlab.com/veilid/veilid.git
synced 2024-12-25 15:29:32 -05:00
add inspect to python api
This commit is contained in:
parent
1e681790e6
commit
cfce0a35b4
@ -390,6 +390,15 @@ impl RoutingTable {
|
|||||||
for b in &c.network.routing_table.bootstrap {
|
for b in &c.network.routing_table.bootstrap {
|
||||||
cache_validity_key.append(&mut b.as_bytes().to_vec());
|
cache_validity_key.append(&mut b.as_bytes().to_vec());
|
||||||
}
|
}
|
||||||
|
cache_validity_key.append(
|
||||||
|
&mut c
|
||||||
|
.network
|
||||||
|
.network_key_password
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.as_bytes()
|
||||||
|
.to_vec(),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Deserialize bucket map and all entries from the table store
|
// Deserialize bucket map and all entries from the table store
|
||||||
|
@ -354,6 +354,18 @@ impl JsonRequestProcessor {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RoutingContextRequestOp::InspectDhtRecord {
|
||||||
|
key,
|
||||||
|
subkeys,
|
||||||
|
scope,
|
||||||
|
} => RoutingContextResponseOp::InspectDhtRecord {
|
||||||
|
result: to_json_api_result(
|
||||||
|
routing_context
|
||||||
|
.inspect_dht_record(key, subkeys, scope)
|
||||||
|
.await
|
||||||
|
.map(Box::new),
|
||||||
|
),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
RoutingContextResponse {
|
RoutingContextResponse {
|
||||||
rc_id: rcr.rc_id,
|
rc_id: rcr.rc_id,
|
||||||
|
@ -85,7 +85,14 @@ pub enum RoutingContextRequestOp {
|
|||||||
key: TypedKey,
|
key: TypedKey,
|
||||||
subkeys: ValueSubkeyRangeSet,
|
subkeys: ValueSubkeyRangeSet,
|
||||||
},
|
},
|
||||||
|
InspectDhtRecord {
|
||||||
|
#[schemars(with = "String")]
|
||||||
|
key: TypedKey,
|
||||||
|
subkeys: ValueSubkeyRangeSet,
|
||||||
|
scope: DHTReportScope,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
|
||||||
#[serde(tag = "rc_op")]
|
#[serde(tag = "rc_op")]
|
||||||
pub enum RoutingContextResponseOp {
|
pub enum RoutingContextResponseOp {
|
||||||
@ -146,4 +153,8 @@ pub enum RoutingContextResponseOp {
|
|||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
result: ApiResult<bool>,
|
result: ApiResult<bool>,
|
||||||
},
|
},
|
||||||
|
InspectDhtRecord {
|
||||||
|
#[serde(flatten)]
|
||||||
|
result: ApiResult<Box<DHTRecordReport>>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
@ -202,3 +202,28 @@ async def test_open_writer_dht_value(api_connection: veilid.VeilidAPI):
|
|||||||
# Clean up
|
# Clean up
|
||||||
await rc.close_dht_record(key)
|
await rc.close_dht_record(key)
|
||||||
await rc.delete_dht_record(key)
|
await rc.delete_dht_record(key)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_inspect_dht_record(api_connection: veilid.VeilidAPI):
|
||||||
|
rc = await api_connection.new_routing_context()
|
||||||
|
async with rc:
|
||||||
|
rec = await rc.create_dht_record(veilid.DHTSchema.dflt(2))
|
||||||
|
|
||||||
|
vd = await rc.set_dht_value(rec.key, 0, b"BLAH BLAH BLAH")
|
||||||
|
assert vd == None
|
||||||
|
|
||||||
|
rr = await rc.inspect_dht_record(rec.key, [], veilid.DHTReportScope.LOCAL)
|
||||||
|
print("rr: {}", rr.__dict__)
|
||||||
|
assert rr.subkeys == [[0,1]]
|
||||||
|
assert rr.local_seqs == [0, 0xFFFFFFFF]
|
||||||
|
assert rr.network_seqs == []
|
||||||
|
|
||||||
|
rr2 = await rc.inspect_dht_record(rec.key, [], veilid.DHTReportScope.SYNC_GET)
|
||||||
|
print("rr2: {}", rr2.__dict__)
|
||||||
|
assert rr2.subkeys == [[0,1]]
|
||||||
|
assert rr2.local_seqs == [0, 0xFFFFFFFF]
|
||||||
|
assert rr2.network_seqs == [0, 0xFFFFFFFF]
|
||||||
|
|
||||||
|
await rc.close_dht_record(rec.key)
|
||||||
|
await rc.delete_dht_record(rec.key)
|
@ -97,6 +97,16 @@ class RoutingContext(ABC):
|
|||||||
) -> bool:
|
) -> bool:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
async def inspect_dht_record(
|
||||||
|
self,
|
||||||
|
key: types.TypedKey,
|
||||||
|
subkeys: list[tuple[types.ValueSubkey, types.ValueSubkey]],
|
||||||
|
scope: types.DHTReportScope,
|
||||||
|
) -> types.DHTRecordReport:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TableDbTransaction(ABC):
|
class TableDbTransaction(ABC):
|
||||||
async def __aenter__(self) -> Self:
|
async def __aenter__(self) -> Self:
|
||||||
|
@ -23,6 +23,8 @@ from .types import (
|
|||||||
CryptoKeyDistance,
|
CryptoKeyDistance,
|
||||||
CryptoKind,
|
CryptoKind,
|
||||||
DHTRecordDescriptor,
|
DHTRecordDescriptor,
|
||||||
|
DHTRecordReport,
|
||||||
|
DHTReportScope,
|
||||||
DHTSchema,
|
DHTSchema,
|
||||||
HashDigest,
|
HashDigest,
|
||||||
KeyPair,
|
KeyPair,
|
||||||
@ -681,6 +683,28 @@ class _JsonRoutingContext(RoutingContext):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def inspect_dht_record(
|
||||||
|
self,
|
||||||
|
key: TypedKey,
|
||||||
|
subkeys: list[tuple[ValueSubkey, ValueSubkey]],
|
||||||
|
scope: DHTReportScope,
|
||||||
|
) -> DHTRecordReport:
|
||||||
|
return DHTRecordReport.from_json(
|
||||||
|
raise_api_result(
|
||||||
|
await self.api.send_ndjson_request(
|
||||||
|
Operation.ROUTING_CONTEXT,
|
||||||
|
validate=validate_rc_op,
|
||||||
|
rc_id=self.rc_id,
|
||||||
|
rc_op=RoutingContextOperation.INSPECT_DHT_RECORD,
|
||||||
|
key=key,
|
||||||
|
subkeys=subkeys,
|
||||||
|
scope=scope,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
######################################################
|
######################################################
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ class RoutingContextOperation(StrEnum):
|
|||||||
SET_DHT_VALUE = "SetDhtValue"
|
SET_DHT_VALUE = "SetDhtValue"
|
||||||
WATCH_DHT_VALUES = "WatchDhtValues"
|
WATCH_DHT_VALUES = "WatchDhtValues"
|
||||||
CANCEL_DHT_WATCH = "CancelDhtWatch"
|
CANCEL_DHT_WATCH = "CancelDhtWatch"
|
||||||
|
INSPECT_DHT_RECORD = "InspectDhtRecord"
|
||||||
|
|
||||||
|
|
||||||
class TableDbOperation(StrEnum):
|
class TableDbOperation(StrEnum):
|
||||||
|
@ -923,6 +923,44 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/definitions/DHTRecordReport"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"error"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"error": {
|
||||||
|
"$ref": "#/definitions/VeilidAPIError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"required": [
|
||||||
|
"rc_op"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"rc_op": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"InspectDhtRecord"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"required": [
|
"required": [
|
||||||
@ -2717,6 +2755,56 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"DHTRecordReport": {
|
||||||
|
"description": "DHT Record Report",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"local_seqs",
|
||||||
|
"network_seqs",
|
||||||
|
"subkeys"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"local_seqs": {
|
||||||
|
"description": "The sequence numbers of each subkey requested from a locally stored DHT Record",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint32",
|
||||||
|
"minimum": 0.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"network_seqs": {
|
||||||
|
"description": "The sequence numbers of each subkey requested from the DHT over the network",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint32",
|
||||||
|
"minimum": 0.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"subkeys": {
|
||||||
|
"description": "The actual subkey range within the schema being reported on This may be a subset of the requested range if it exceeds the schema limits or has more than 512 subkeys",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint32",
|
||||||
|
"minimum": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint32",
|
||||||
|
"minimum": 0.0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"maxItems": 2,
|
||||||
|
"minItems": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"DHTSchema": {
|
"DHTSchema": {
|
||||||
"description": "Enum over all the supported DHT Schemas",
|
"description": "Enum over all the supported DHT Schemas",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
|
@ -547,6 +547,49 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"key",
|
||||||
|
"rc_op",
|
||||||
|
"scope",
|
||||||
|
"subkeys"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"key": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"rc_op": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"InspectDhtRecord"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"$ref": "#/definitions/DHTReportScope"
|
||||||
|
},
|
||||||
|
"subkeys": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint32",
|
||||||
|
"minimum": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint32",
|
||||||
|
"minimum": 0.0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"maxItems": 2,
|
||||||
|
"minItems": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"required": [
|
"required": [
|
||||||
@ -1525,6 +1568,46 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
"DHTReportScope": {
|
||||||
|
"description": "DHT Record Report Scope",
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"description": "Return only the local copy sequence numbers Useful for seeing what subkeys you have locally and which ones have not been retrieved",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Local"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Return the local sequence numbers and the network sequence numbers with GetValue fanout parameters Provides an independent view of both the local sequence numbers and the network sequence numbers for nodes that would be reached as if the local copy did not exist locally. Useful for determining if the current local copy should be updated from the network.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"SyncGet"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Return the local sequence numbers and the network sequence numbers with SetValue fanout parameters Provides an independent view of both the local sequence numbers and the network sequence numbers for nodes that would be reached as if the local copy did not exist locally. Useful for determining if the unchanged local copy should be pushed to the network.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"SyncSet"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Return the local sequence numbers and the network sequence numbers with GetValue fanout parameters Provides an view of both the local sequence numbers and the network sequence numbers for nodes that would be reached as if a GetValue operation were being performed, including accepting newer values from the network. Useful for determining which subkeys would change with a GetValue operation",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"UpdateGet"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Return the local sequence numbers and the network sequence numbers with SetValue fanout parameters Provides an view of both the local sequence numbers and the network sequence numbers for nodes that would be reached as if a SetValue operation were being performed, including accepting newer values from the network. This simulates a SetValue with the initial sequence number incremented by 1, like a real SetValue would when updating. Useful for determine which subkeys would change on an SetValue operation",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"UpdateSet"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"DHTSchema": {
|
"DHTSchema": {
|
||||||
"description": "Enum over all the supported DHT Schemas",
|
"description": "Enum over all the supported DHT Schemas",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
|
@ -85,6 +85,14 @@ class SafetySelectionKind(StrEnum):
|
|||||||
SAFE = "Safe"
|
SAFE = "Safe"
|
||||||
|
|
||||||
|
|
||||||
|
class DHTReportScope(StrEnum):
|
||||||
|
LOCAL = "Local"
|
||||||
|
SYNC_GET = "SyncGet"
|
||||||
|
SYNC_SET = "SyncSet"
|
||||||
|
UPDATE_GET = "UpdateGet"
|
||||||
|
UPDATE_SET = "UpdateSet"
|
||||||
|
|
||||||
|
|
||||||
####################################################################
|
####################################################################
|
||||||
|
|
||||||
|
|
||||||
@ -353,7 +361,7 @@ class DHTRecordDescriptor:
|
|||||||
self.schema = schema
|
self.schema = schema
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<{self.__class__.__name__}(key={self.key!r})>"
|
return f"<{self.__class__.__name__}(key={self.key!r}, owner={self.owner!r}, owner_secret={self.owner_secret!r}, schema={self.schema!r})>"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, j: dict) -> Self:
|
def from_json(cls, j: dict) -> Self:
|
||||||
@ -368,6 +376,37 @@ class DHTRecordDescriptor:
|
|||||||
return self.__dict__
|
return self.__dict__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class DHTRecordReport:
|
||||||
|
subkeys: list[tuple[ValueSubkey, ValueSubkey]]
|
||||||
|
local_seqs: list[ValueSeqNum]
|
||||||
|
network_seqs: list[ValueSeqNum]
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
subkeys: list[tuple[ValueSubkey, ValueSubkey]],
|
||||||
|
local_seqs: list[ValueSeqNum],
|
||||||
|
network_seqs: list[ValueSeqNum],
|
||||||
|
):
|
||||||
|
self.subkeys = subkeys
|
||||||
|
self.local_seqs = local_seqs
|
||||||
|
self.network_seqs = network_seqs
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<{self.__class__.__name__}(subkeys={self.subkeys!r}, local_seqs={self.local_seqs!r}, network_seqs={self.network_seqs!r})>"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, j: dict) -> Self:
|
||||||
|
return cls(
|
||||||
|
[[p[0], p[1]] for p in j["subkeys"]],
|
||||||
|
[ValueSeqNum(s) for s in j["local_seqs"]],
|
||||||
|
[ValueSeqNum(s) for s in j["network_seqs"]],
|
||||||
|
)
|
||||||
|
|
||||||
|
def to_json(self) -> dict:
|
||||||
|
return self.__dict__
|
||||||
|
|
||||||
|
|
||||||
@total_ordering
|
@total_ordering
|
||||||
class ValueData:
|
class ValueData:
|
||||||
seq: ValueSeqNum
|
seq: ValueSeqNum
|
||||||
|
Loading…
Reference in New Issue
Block a user