mirror of
https://github.com/logos-blockchain/logos-blockchain-block-explorer-template.git
synced 2026-05-18 07:19:27 +00:00
update schemas to v0.1.3rc5
This commit is contained in:
parent
3e61dc8d80
commit
2045b8df6f
@ -1,5 +1,5 @@
|
||||
from enum import Enum
|
||||
from typing import List, Literal, Optional
|
||||
from typing import Any, List, Literal, Optional
|
||||
|
||||
from core.models import NbeSchema
|
||||
from core.types import HexBytes
|
||||
@ -59,7 +59,7 @@ class SDPDeclareServiceType(Enum):
|
||||
class SDPDeclare(NbeContent):
|
||||
type: Literal["SDPDeclare"] = "SDPDeclare"
|
||||
service_type: SDPDeclareServiceType
|
||||
locators: List[bytes]
|
||||
locators: List[str]
|
||||
provider_id: HexBytes
|
||||
zk_id: HexBytes
|
||||
locked_note_id: HexBytes
|
||||
@ -74,8 +74,8 @@ class SDPWithdraw(NbeContent):
|
||||
class SDPActive(NbeContent):
|
||||
type: Literal["SDPActive"] = "SDPActive"
|
||||
declaration_id: HexBytes
|
||||
nonce: HexBytes
|
||||
metadata: Optional[bytes]
|
||||
nonce: int
|
||||
metadata: Optional[Any] = None
|
||||
|
||||
|
||||
class LeaderClaim(NbeContent):
|
||||
|
||||
@ -25,7 +25,7 @@ class HttpNodeApi(NodeApi):
|
||||
# Paths can't have a leading slash since they are relative to the base URL
|
||||
ENDPOINT_INFO = "cryptarchia/info"
|
||||
ENDPOINT_BLOCKS_STREAM = "cryptarchia/events/blocks/stream"
|
||||
ENDPOINT_BLOCK_BY_HASH = "storage/block"
|
||||
ENDPOINT_BLOCK_BY_HASH = "cryptarchia/blocks/" # block hash appended as path segment
|
||||
|
||||
def __init__(self, settings: "NBESettings"):
|
||||
self.host: str = settings.node_api_host
|
||||
@ -82,8 +82,8 @@ class HttpNodeApi(NodeApi):
|
||||
return InfoSerializer.model_validate(response.json())
|
||||
|
||||
async def get_block_by_hash(self, block_hash: str) -> Optional[BlockSerializer]:
|
||||
url = urljoin(self.base_url, self.ENDPOINT_BLOCK_BY_HASH)
|
||||
response = await self._client.post(url, json=block_hash)
|
||||
url = urljoin(self.base_url, self.ENDPOINT_BLOCK_BY_HASH + block_hash)
|
||||
response = await self._client.get(url)
|
||||
if response.status_code == 404:
|
||||
return None
|
||||
response.raise_for_status()
|
||||
@ -91,12 +91,7 @@ class HttpNodeApi(NodeApi):
|
||||
if json_data is None:
|
||||
logger.warning(f"Block {block_hash} returned null from API")
|
||||
return None
|
||||
block = BlockSerializer.model_validate(json_data)
|
||||
# The storage endpoint doesn't include the block hash in the response,
|
||||
# so we set it from the request body
|
||||
if not block.header.hash:
|
||||
block.header.hash = bytes.fromhex(block_hash)
|
||||
return block
|
||||
return BlockSerializer.model_validate(json_data)
|
||||
|
||||
async def get_blocks_stream(self) -> AsyncIterator[BlockSerializer]:
|
||||
url = urljoin(self.base_url, self.ENDPOINT_BLOCKS_STREAM)
|
||||
|
||||
@ -1,17 +1,20 @@
|
||||
from random import randint
|
||||
from typing import Annotated, Any, List, Self, Union
|
||||
from typing import Annotated, Any, List, Optional, Self, Union
|
||||
|
||||
from pydantic import BeforeValidator, Field
|
||||
|
||||
from core.models import NbeSerializer
|
||||
from models.transactions.operations.contents import SDPDeclareServiceType
|
||||
from node.api.serializers.fields import BytesFromHex, BytesFromIntArray
|
||||
from node.api.serializers.note import NoteSerializer
|
||||
from utils.protocols import FromRandom
|
||||
from utils.random import random_bytes
|
||||
|
||||
# Mantle op opcodes (new node release).
|
||||
# Mantle op opcodes.
|
||||
OPCODE_LEDGER = 0
|
||||
OPCODE_CHANNEL_INSCRIBE = 17
|
||||
OPCODE_SDP_DECLARE = 32
|
||||
OPCODE_SDP_ACTIVE = 34
|
||||
|
||||
|
||||
class LedgerOpSerializer(NbeSerializer, FromRandom):
|
||||
@ -52,14 +55,68 @@ class ChannelInscribeOpSerializer(NbeSerializer, FromRandom):
|
||||
)
|
||||
|
||||
|
||||
class SDPDeclareOpSerializer(NbeSerializer, FromRandom):
|
||||
"""SDP declare op (opcode 32): registers a service provider."""
|
||||
|
||||
service_type: SDPDeclareServiceType
|
||||
locators: List[str] = Field(description="Multiaddr strings, e.g. /ip4/.../udp/.../quic-v1.")
|
||||
provider_id: BytesFromHex = Field(description="Provider ID in hex format.")
|
||||
zk_id: BytesFromHex = Field(description="ZK ID in hex format.")
|
||||
locked_note_id: BytesFromHex = Field(description="Locked note ID in hex format.")
|
||||
|
||||
@classmethod
|
||||
def from_random(cls) -> Self:
|
||||
return cls.model_validate(
|
||||
{
|
||||
"service_type": "BN",
|
||||
"locators": ["/ip4/127.0.0.1/udp/3400/quic-v1"],
|
||||
"provider_id": random_bytes(32).hex(),
|
||||
"zk_id": random_bytes(32).hex(),
|
||||
"locked_note_id": random_bytes(32).hex(),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class SDPActiveOpSerializer(NbeSerializer, FromRandom):
|
||||
"""SDP active op (opcode 34): proves a declared provider is online."""
|
||||
|
||||
declaration_id: BytesFromHex = Field(description="Declaration ID in hex format.")
|
||||
nonce: int = Field(description="Activity nonce in u64 format.")
|
||||
metadata: Optional[Any] = Field(
|
||||
default=None,
|
||||
description="Service-specific metadata (e.g. Blend session/proofs). Stored verbatim.",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_random(cls) -> Self:
|
||||
return cls.model_validate(
|
||||
{
|
||||
"declaration_id": random_bytes(32).hex(),
|
||||
"nonce": randint(0, 1_000),
|
||||
"metadata": None,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
OPCODE_TO_SERIALIZER: dict[int, type] = {
|
||||
OPCODE_LEDGER: LedgerOpSerializer,
|
||||
OPCODE_CHANNEL_INSCRIBE: ChannelInscribeOpSerializer,
|
||||
OPCODE_SDP_DECLARE: SDPDeclareOpSerializer,
|
||||
OPCODE_SDP_ACTIVE: SDPActiveOpSerializer,
|
||||
}
|
||||
|
||||
|
||||
def _parse_mantle_op(data: Any) -> Union[LedgerOpSerializer, ChannelInscribeOpSerializer]:
|
||||
if isinstance(data, (LedgerOpSerializer, ChannelInscribeOpSerializer)):
|
||||
MantleOpSerializerVariants = Union[
|
||||
LedgerOpSerializer,
|
||||
ChannelInscribeOpSerializer,
|
||||
SDPDeclareOpSerializer,
|
||||
SDPActiveOpSerializer,
|
||||
]
|
||||
_MANTLE_OP_SERIALIZER_CLASSES = tuple(OPCODE_TO_SERIALIZER.values())
|
||||
|
||||
|
||||
def _parse_mantle_op(data: Any) -> MantleOpSerializerVariants:
|
||||
if isinstance(data, _MANTLE_OP_SERIALIZER_CLASSES):
|
||||
return data
|
||||
if isinstance(data, dict) and "opcode" in data:
|
||||
opcode = data["opcode"]
|
||||
@ -72,5 +129,4 @@ def _parse_mantle_op(data: Any) -> Union[LedgerOpSerializer, ChannelInscribeOpSe
|
||||
raise ValueError(f"Cannot parse mantle op from {type(data).__name__}.")
|
||||
|
||||
|
||||
MantleOpSerializerVariants = Union[LedgerOpSerializer, ChannelInscribeOpSerializer]
|
||||
MantleOpSerializerField = Annotated[MantleOpSerializerVariants, BeforeValidator(_parse_mantle_op)]
|
||||
|
||||
@ -10,7 +10,7 @@ from models.transactions.operations.proofs import (
|
||||
ZkAndEd25519Signature,
|
||||
ZkSignature,
|
||||
)
|
||||
from node.api.serializers.fields import BytesFromIntArray
|
||||
from node.api.serializers.fields import BytesFromHex, BytesFromIntArray
|
||||
from utils.protocols import EnforceSubclassFromRandom
|
||||
from utils.random import random_bytes
|
||||
|
||||
@ -65,13 +65,13 @@ class ZkSignatureSerializer(OperationProofSerializer, NbeSerializer):
|
||||
|
||||
|
||||
class ZkAndEd25519SignaturesSerializer(OperationProofSerializer, NbeSerializer):
|
||||
zk_signature: BytesFromIntArray = Field(alias="zk_sig")
|
||||
ed25519_signature: BytesFromIntArray = Field(alias="ed25519_sig")
|
||||
zk_signature: ZkSignatureSerializer = Field(alias="zk_sig")
|
||||
ed25519_signature: BytesFromHex = Field(alias="ed25519_sig")
|
||||
|
||||
def into_operation_proof(self) -> NbeSignature:
|
||||
return ZkAndEd25519Signature.model_validate(
|
||||
{
|
||||
"zk_signature": self.zk_signature,
|
||||
"zk_signature": self.zk_signature.to_bytes(),
|
||||
"ed25519_signature": self.ed25519_signature,
|
||||
}
|
||||
)
|
||||
@ -80,8 +80,12 @@ class ZkAndEd25519SignaturesSerializer(OperationProofSerializer, NbeSerializer):
|
||||
def from_random(cls, *args, **kwargs) -> Self:
|
||||
return ZkAndEd25519SignaturesSerializer.model_validate(
|
||||
{
|
||||
"zk_sig": list(random_bytes(32)),
|
||||
"ed25519_sig": list(random_bytes(64)),
|
||||
"zk_sig": {
|
||||
"pi_a": list(random_bytes(32)),
|
||||
"pi_b": list(random_bytes(64)),
|
||||
"pi_c": list(random_bytes(32)),
|
||||
},
|
||||
"ed25519_sig": random_bytes(64).hex(),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ from models.header.proof_of_leadership import (
|
||||
Groth16ProofOfLeadership,
|
||||
ProofOfLeadership,
|
||||
)
|
||||
from node.api.serializers.fields import BytesFromHex, BytesFromIntArray
|
||||
from node.api.serializers.fields import BytesFromHex
|
||||
from utils.protocols import EnforceSubclassFromRandom
|
||||
from utils.random import random_bytes
|
||||
|
||||
@ -22,10 +22,8 @@ class ProofOfLeadershipSerializer(NbeSerializer, EnforceSubclassFromRandom, ABC)
|
||||
|
||||
class Groth16LeaderProofSerializer(ProofOfLeadershipSerializer, NbeSerializer):
|
||||
entropy_contribution: BytesFromHex = Field(description="Fr integer.")
|
||||
leader_key: BytesFromHex = Field(description="Bytes in Integer Array format.")
|
||||
proof: BytesFromIntArray = Field(
|
||||
description="Bytes in Integer Array format.",
|
||||
)
|
||||
leader_key: BytesFromHex = Field(description="Hash in hex format.")
|
||||
proof: BytesFromHex = Field(description="Groth16 proof bytes (128B) in hex format.")
|
||||
voucher_cm: BytesFromHex = Field(description="Hash.")
|
||||
|
||||
def into_proof_of_leadership(self) -> ProofOfLeadership:
|
||||
@ -44,7 +42,7 @@ class Groth16LeaderProofSerializer(ProofOfLeadershipSerializer, NbeSerializer):
|
||||
{
|
||||
"entropy_contribution": random_bytes(32).hex(),
|
||||
"leader_key": random_bytes(32).hex(),
|
||||
"proof": list(random_bytes(128)),
|
||||
"proof": random_bytes(128).hex(),
|
||||
"voucher_cm": random_bytes(32).hex(),
|
||||
}
|
||||
)
|
||||
|
||||
@ -9,16 +9,33 @@ from models.transactions.transaction import Transaction
|
||||
from node.api.serializers.operation import (
|
||||
ChannelInscribeOpSerializer,
|
||||
LedgerOpSerializer,
|
||||
SDPActiveOpSerializer,
|
||||
SDPDeclareOpSerializer,
|
||||
)
|
||||
from node.api.serializers.proof import (
|
||||
Ed25519SignatureSerializer,
|
||||
OperationProofSerializerField,
|
||||
ZkAndEd25519SignaturesSerializer,
|
||||
ZkSignatureSerializer,
|
||||
)
|
||||
from node.api.serializers.transaction import TransactionSerializer
|
||||
from utils.protocols import FromRandom
|
||||
|
||||
|
||||
def _proof_to_internal(proof) -> dict:
|
||||
if isinstance(proof, ZkSignatureSerializer):
|
||||
return {"type": "Zk", "signature": proof.to_bytes()}
|
||||
if isinstance(proof, Ed25519SignatureSerializer):
|
||||
return {"type": "Ed25519", "signature": proof.root}
|
||||
if isinstance(proof, ZkAndEd25519SignaturesSerializer):
|
||||
return {
|
||||
"type": "ZkAndEd25519",
|
||||
"zk_signature": proof.zk_signature.to_bytes(),
|
||||
"ed25519_signature": proof.ed25519_signature,
|
||||
}
|
||||
raise ValueError(f"Unsupported proof type: {type(proof).__name__}")
|
||||
|
||||
|
||||
class SignedTransactionSerializer(NbeSerializer, FromRandom):
|
||||
transaction: TransactionSerializer = Field(alias="mantle_tx", description="Transaction.")
|
||||
operations_proofs: List[OperationProofSerializerField] = Field(
|
||||
@ -53,10 +70,7 @@ class SignedTransactionSerializer(NbeSerializer, FromRandom):
|
||||
"inputs": list(op.inputs),
|
||||
"outputs": [o.into_note() for o in op.outputs],
|
||||
},
|
||||
"proof": {
|
||||
"type": "Zk",
|
||||
"signature": proof.to_bytes(),
|
||||
},
|
||||
"proof": _proof_to_internal(proof),
|
||||
}
|
||||
)
|
||||
elif isinstance(op, ChannelInscribeOpSerializer):
|
||||
@ -73,10 +87,33 @@ class SignedTransactionSerializer(NbeSerializer, FromRandom):
|
||||
"parent": op.parent,
|
||||
"signer": op.signer,
|
||||
},
|
||||
"proof": {
|
||||
"type": "Ed25519",
|
||||
"signature": proof.root,
|
||||
"proof": _proof_to_internal(proof),
|
||||
}
|
||||
)
|
||||
elif isinstance(op, SDPDeclareOpSerializer):
|
||||
operations.append(
|
||||
{
|
||||
"content": {
|
||||
"type": "SDPDeclare",
|
||||
"service_type": op.service_type,
|
||||
"locators": list(op.locators),
|
||||
"provider_id": op.provider_id,
|
||||
"zk_id": op.zk_id,
|
||||
"locked_note_id": op.locked_note_id,
|
||||
},
|
||||
"proof": _proof_to_internal(proof),
|
||||
}
|
||||
)
|
||||
elif isinstance(op, SDPActiveOpSerializer):
|
||||
operations.append(
|
||||
{
|
||||
"content": {
|
||||
"type": "SDPActive",
|
||||
"declaration_id": op.declaration_id,
|
||||
"nonce": op.nonce,
|
||||
"metadata": op.metadata,
|
||||
},
|
||||
"proof": _proof_to_internal(proof),
|
||||
}
|
||||
)
|
||||
else:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user