mirror of
https://github.com/logos-blockchain/logos-blockchain-block-explorer-template.git
synced 2026-01-02 05:03:07 +00:00
Sync block structure with latest state
This commit is contained in:
parent
6fa406f83f
commit
cce312ecb6
@ -1,4 +1,4 @@
|
||||
from typing import Annotated
|
||||
from typing import Annotated, Union
|
||||
|
||||
from pydantic import BeforeValidator, PlainSerializer, ValidationError
|
||||
|
||||
@ -28,6 +28,20 @@ def bytes_from_int(data: int) -> bytes:
|
||||
return data.to_bytes((data.bit_length() + 7) // 8) # TODO: Ensure endianness is correct.
|
||||
|
||||
|
||||
def bytes_from_hex_or_intarray(data: Union[str, list[int]]) -> bytes:
|
||||
"""Accepts either hex string or int array and converts to bytes."""
|
||||
if isinstance(data, str):
|
||||
return bytes.fromhex(data)
|
||||
elif isinstance(data, list):
|
||||
if not all(isinstance(item, int) for item in data):
|
||||
raise ValueError("List items must be integers.")
|
||||
return bytes(data)
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Unsupported data type for bytes deserialization. Expected string or list, got {type(data).__name__}."
|
||||
)
|
||||
|
||||
|
||||
def bytes_into_hex(data: bytes) -> str:
|
||||
return data.hex()
|
||||
|
||||
@ -35,3 +49,4 @@ def bytes_into_hex(data: bytes) -> str:
|
||||
BytesFromIntArray = Annotated[bytes, BeforeValidator(bytes_from_intarray), PlainSerializer(bytes_into_hex)]
|
||||
BytesFromHex = Annotated[bytes, BeforeValidator(bytes_from_hex), PlainSerializer(bytes_into_hex)]
|
||||
BytesFromInt = Annotated[bytes, BeforeValidator(bytes_from_int), PlainSerializer(bytes_into_hex)]
|
||||
BytesFlexible = Annotated[bytes, BeforeValidator(bytes_from_hex_or_intarray), PlainSerializer(bytes_into_hex)]
|
||||
@ -1,8 +1,9 @@
|
||||
from enum import IntEnum
|
||||
from random import randint
|
||||
from typing import Self
|
||||
from typing import Optional, Self
|
||||
|
||||
from pydantic import Field
|
||||
from rusty_results import Option, Some
|
||||
from pydantic import Field, computed_field
|
||||
from rusty_results import Option
|
||||
|
||||
from core.models import NbeSerializer
|
||||
from node.api.serializers.fields import BytesFromHex
|
||||
@ -14,21 +15,33 @@ from utils.protocols import FromRandom
|
||||
from utils.random import random_hash
|
||||
|
||||
|
||||
class Version(IntEnum):
|
||||
Bedrock = 1
|
||||
|
||||
|
||||
class HeaderSerializer(NbeSerializer, FromRandom):
|
||||
hash: BytesFromHex = Field(alias="id", description="Hash id in hex format.")
|
||||
id: Optional[BytesFromHex] = Field(default=None, description="Header ID hash in hex format.")
|
||||
version: Version = Field(default=Version.Bedrock, description="Block version.")
|
||||
parent_block: BytesFromHex = Field(description="Hash in hex format.")
|
||||
slot: int = Field(description="Integer in u64 format.")
|
||||
block_root: BytesFromHex = Field(description="Hash in hex format.")
|
||||
proof_of_leadership: ProofOfLeadershipSerializerField
|
||||
|
||||
@computed_field
|
||||
@property
|
||||
def hash(self) -> bytes:
|
||||
"""Return the header hash (id if available, otherwise block_root)."""
|
||||
return self.id if self.id is not None else self.block_root
|
||||
|
||||
@classmethod
|
||||
def from_random(cls, *, slot: Option[int]) -> Self:
|
||||
return cls.model_validate(
|
||||
{
|
||||
"id": random_hash().hex(),
|
||||
"version": Version.Bedrock,
|
||||
"parent_block": random_hash().hex(),
|
||||
"slot": slot.unwrap_or_else(lambda: randint(0, 10_000)),
|
||||
"block_root": random_hash().hex(),
|
||||
"proof_of_leadership": ProofOfLeadershipSerializer.from_random(slot=slot),
|
||||
}
|
||||
)
|
||||
)
|
||||
@ -1,9 +1,9 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from enum import Enum
|
||||
from enum import IntEnum
|
||||
from random import choice, randint
|
||||
from typing import Annotated, List, Optional, Self, Union
|
||||
from typing import Annotated, Any, Dict, List, Optional, Self, Union
|
||||
|
||||
from pydantic import Field
|
||||
from pydantic import Field, model_validator
|
||||
|
||||
from core.models import NbeSerializer
|
||||
from models.transactions.operations.contents import (
|
||||
@ -16,7 +16,7 @@ from models.transactions.operations.contents import (
|
||||
SDPDeclare,
|
||||
SDPWithdraw,
|
||||
)
|
||||
from node.api.serializers.fields import BytesFromHex, BytesFromInt, BytesFromIntArray
|
||||
from node.api.serializers.fields import BytesFlexible, BytesFromHex, BytesFromInt, BytesFromIntArray
|
||||
from utils.protocols import EnforceSubclassFromRandom
|
||||
from utils.random import random_bytes
|
||||
|
||||
@ -28,9 +28,9 @@ class OperationContentSerializer(NbeSerializer, EnforceSubclassFromRandom, ABC):
|
||||
|
||||
|
||||
class ChannelInscribeSerializer(OperationContentSerializer):
|
||||
channel_id: BytesFromIntArray = Field(description="Bytes as a 32-integer array.")
|
||||
inscription: BytesFromIntArray = Field(description="Bytes as an integer array.")
|
||||
parent: BytesFromIntArray = Field(description="Bytes as a 32-integer array.")
|
||||
channel_id: BytesFlexible = Field(description="Bytes as hex or 32-integer array.")
|
||||
inscription: BytesFlexible = Field(description="Bytes as hex or integer array.")
|
||||
parent: BytesFlexible = Field(description="Bytes as hex or 32-integer array.")
|
||||
signer: BytesFromHex = Field(description="Public Key in hex format.")
|
||||
|
||||
def into_operation_content(self) -> ChannelInscribe:
|
||||
@ -56,11 +56,11 @@ class ChannelInscribeSerializer(OperationContentSerializer):
|
||||
|
||||
|
||||
class ChannelBlobSerializer(OperationContentSerializer):
|
||||
channel: BytesFromIntArray = Field(description="Bytes as a 32-integer array.")
|
||||
blob: BytesFromIntArray = Field(description="Bytes as a 32-integer array.")
|
||||
channel: BytesFlexible = Field(description="Bytes as hex or 32-integer array.")
|
||||
blob: BytesFlexible = Field(description="Bytes as hex or 32-integer array.")
|
||||
blob_size: int
|
||||
da_storage_gas_price: int
|
||||
parent: BytesFromIntArray = Field(description="Bytes as a 32-integer array.")
|
||||
parent: BytesFlexible = Field(description="Bytes as hex or 32-integer array.")
|
||||
signer: BytesFromHex = Field(description="Public Key in hex format.")
|
||||
|
||||
def into_operation_content(self) -> ChannelBlob:
|
||||
@ -90,7 +90,7 @@ class ChannelBlobSerializer(OperationContentSerializer):
|
||||
|
||||
|
||||
class ChannelSetKeysSerializer(OperationContentSerializer):
|
||||
channel: BytesFromIntArray = Field(description="Bytes as a 32-integer array.")
|
||||
channel: BytesFlexible = Field(description="Bytes as hex or 32-integer array.")
|
||||
keys: List[BytesFromHex] = Field(description="List of Public Keys in hex format.")
|
||||
|
||||
def into_operation_content(self) -> ChannelSetKeys:
|
||||
@ -112,9 +112,9 @@ class ChannelSetKeysSerializer(OperationContentSerializer):
|
||||
)
|
||||
|
||||
|
||||
class SDPDeclareServiceType(Enum):
|
||||
BN = "BN"
|
||||
DA = "DA"
|
||||
class SDPDeclareServiceType(IntEnum):
|
||||
BN = 0
|
||||
DA = 1
|
||||
|
||||
|
||||
class SDPDeclareSerializer(OperationContentSerializer):
|
||||
@ -127,7 +127,7 @@ class SDPDeclareSerializer(OperationContentSerializer):
|
||||
def into_operation_content(self) -> SDPDeclare:
|
||||
return SDPDeclare.model_validate(
|
||||
{
|
||||
"service_type": self.service_type.value,
|
||||
"service_type": self.service_type.name,
|
||||
"locators": self.locators,
|
||||
"provider_id": self.provider_id,
|
||||
"zk_id": self.zk_id,
|
||||
@ -140,7 +140,7 @@ class SDPDeclareSerializer(OperationContentSerializer):
|
||||
n = 1 if randint(0, 1) <= 0.5 else randint(1, 5)
|
||||
return cls.model_validate(
|
||||
{
|
||||
"service_type": choice(list(SDPDeclareServiceType)).value,
|
||||
"service_type": choice(list(SDPDeclareServiceType)),
|
||||
"locators": [random_bytes(32).hex() for _ in range(n)],
|
||||
"provider_id": list(random_bytes(32)),
|
||||
"zk_id": random_bytes(32).hex(),
|
||||
@ -174,7 +174,7 @@ class SDPWithdrawSerializer(OperationContentSerializer):
|
||||
class SDPActiveSerializer(OperationContentSerializer):
|
||||
declaration_id: BytesFromIntArray = Field(description="Bytes as a 32-integer array.")
|
||||
nonce: BytesFromInt
|
||||
metadata: Optional[BytesFromIntArray] = Field(description="Bytes as an integer array.")
|
||||
metadata: Optional[BytesFromIntArray] = Field(default=None, description="Bytes as an integer array.")
|
||||
|
||||
def into_operation_content(self) -> SDPActive:
|
||||
return SDPActive.model_validate(
|
||||
@ -221,6 +221,59 @@ class LeaderClaimSerializer(OperationContentSerializer):
|
||||
)
|
||||
|
||||
|
||||
class OpCode(IntEnum):
|
||||
ChannelInscribe = 0
|
||||
ChannelBlob = 1
|
||||
ChannelSetKeys = 2
|
||||
SDPDeclare = 3
|
||||
SDPWithdraw = 4
|
||||
SDPActive = 5
|
||||
LeaderClaim = 6
|
||||
|
||||
|
||||
# Map opcode to serializer class
|
||||
OPCODE_TO_SERIALIZER: Dict[int, type[OperationContentSerializer]] = {
|
||||
OpCode.ChannelInscribe: ChannelInscribeSerializer,
|
||||
OpCode.ChannelBlob: ChannelBlobSerializer,
|
||||
OpCode.ChannelSetKeys: ChannelSetKeysSerializer,
|
||||
OpCode.SDPDeclare: SDPDeclareSerializer,
|
||||
OpCode.SDPWithdraw: SDPWithdrawSerializer,
|
||||
OpCode.SDPActive: SDPActiveSerializer,
|
||||
OpCode.LeaderClaim: LeaderClaimSerializer,
|
||||
}
|
||||
|
||||
|
||||
class OperationWrapper(NbeSerializer):
|
||||
"""Wrapper for operations with opcode and payload structure."""
|
||||
opcode: int
|
||||
payload: Dict[str, Any]
|
||||
|
||||
_content: Optional[OperationContentSerializer] = None
|
||||
|
||||
@model_validator(mode="after")
|
||||
def parse_payload(self) -> Self:
|
||||
serializer_cls = OPCODE_TO_SERIALIZER.get(self.opcode)
|
||||
if serializer_cls is None:
|
||||
raise ValueError(f"Unknown opcode: {self.opcode}")
|
||||
self._content = serializer_cls.model_validate(self.payload)
|
||||
return self
|
||||
|
||||
def into_operation_content(self) -> NbeContent:
|
||||
if self._content is None:
|
||||
raise ValueError("Content not parsed")
|
||||
return self._content.into_operation_content()
|
||||
|
||||
@classmethod
|
||||
def from_random(cls) -> Self:
|
||||
opcode = choice(list(OpCode))
|
||||
serializer_cls = OPCODE_TO_SERIALIZER[opcode]
|
||||
content = serializer_cls.from_random()
|
||||
return cls.model_validate({
|
||||
"opcode": opcode,
|
||||
"payload": content.model_dump(),
|
||||
})
|
||||
|
||||
|
||||
type OperationContentSerializerVariants = Union[
|
||||
ChannelInscribeSerializer,
|
||||
ChannelBlobSerializer,
|
||||
@ -230,4 +283,4 @@ type OperationContentSerializerVariants = Union[
|
||||
SDPActiveSerializer,
|
||||
LeaderClaimSerializer,
|
||||
]
|
||||
OperationContentSerializerField = Annotated[OperationContentSerializerVariants, Field(union_mode="left_to_right")]
|
||||
OperationContentSerializerField = Annotated[OperationContentSerializerVariants, Field(union_mode="left_to_right")]
|
||||
@ -1,7 +1,7 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Annotated, Self, Union
|
||||
from typing import Annotated, Any, Dict, Self, Union
|
||||
|
||||
from pydantic import Field, RootModel
|
||||
from pydantic import Field, RootModel, model_validator
|
||||
|
||||
from core.models import NbeSerializer
|
||||
from models.transactions.operations.proofs import (
|
||||
@ -10,7 +10,7 @@ from models.transactions.operations.proofs import (
|
||||
ZkAndEd25519Signature,
|
||||
ZkSignature,
|
||||
)
|
||||
from node.api.serializers.fields import BytesFromHex
|
||||
from node.api.serializers.fields import BytesFromHex, BytesFromIntArray
|
||||
from utils.protocols import EnforceSubclassFromRandom
|
||||
from utils.random import random_bytes
|
||||
|
||||
@ -21,57 +21,77 @@ class OperationProofSerializer(EnforceSubclassFromRandom, ABC):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
# TODO: Differentiate between Ed25519SignatureSerializer and ZkSignatureSerializer
|
||||
|
||||
|
||||
class Ed25519SignatureSerializer(OperationProofSerializer, RootModel[str]):
|
||||
root: BytesFromHex
|
||||
class Ed25519SignatureSerializer(OperationProofSerializer, NbeSerializer):
|
||||
"""Ed25519 signature as int array, wrapped in Ed25519Sig key."""
|
||||
signature: BytesFromIntArray = Field(alias="Ed25519Sig")
|
||||
|
||||
def into_operation_proof(self) -> NbeSignature:
|
||||
return Ed25519Signature.model_validate(
|
||||
{
|
||||
"signature": self.root,
|
||||
"signature": self.signature,
|
||||
}
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_random(cls, *args, **kwargs) -> Self:
|
||||
return cls.model_validate(random_bytes(64).hex())
|
||||
return cls.model_validate({"Ed25519Sig": list(random_bytes(64))})
|
||||
|
||||
|
||||
class ZkSignatureSerializer(OperationProofSerializer, RootModel[str]):
|
||||
root: BytesFromHex
|
||||
class ZkSignatureComponentsSerializer(NbeSerializer):
|
||||
"""ZK signature proof with pi_a, pi_b, pi_c components as int arrays."""
|
||||
pi_a: BytesFromIntArray = Field(description="32 bytes as int array")
|
||||
pi_b: BytesFromIntArray = Field(description="64 bytes as int array")
|
||||
pi_c: BytesFromIntArray = Field(description="32 bytes as int array")
|
||||
|
||||
|
||||
class ZkSignatureSerializer(OperationProofSerializer, NbeSerializer):
|
||||
"""ZK signature wrapped in ZkSig key."""
|
||||
zk_sig: ZkSignatureComponentsSerializer = Field(alias="ZkSig")
|
||||
|
||||
def into_operation_proof(self) -> NbeSignature:
|
||||
# Concatenate the components for storage
|
||||
signature = self.zk_sig.pi_a + self.zk_sig.pi_b + self.zk_sig.pi_c
|
||||
return ZkSignature.model_validate(
|
||||
{
|
||||
"signature": self.root,
|
||||
"signature": signature,
|
||||
}
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_random(cls, *args, **kwargs) -> Self:
|
||||
return cls.model_validate(random_bytes(32).hex())
|
||||
return cls.model_validate({
|
||||
"ZkSig": {
|
||||
"pi_a": list(random_bytes(32)),
|
||||
"pi_b": list(random_bytes(64)),
|
||||
"pi_c": list(random_bytes(32)),
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
class ZkAndEd25519SignaturesSerializer(OperationProofSerializer, NbeSerializer):
|
||||
zk_signature: BytesFromHex = Field(alias="zk_sig")
|
||||
ed25519_signature: BytesFromHex = Field(alias="ed25519_sig")
|
||||
"""Combined ZK and Ed25519 signatures."""
|
||||
zk_signature: ZkSignatureComponentsSerializer = Field(alias="zk_sig")
|
||||
ed25519_signature: BytesFromIntArray = Field(alias="ed25519_sig")
|
||||
|
||||
def into_operation_proof(self) -> NbeSignature:
|
||||
zk_sig = self.zk_signature.pi_a + self.zk_signature.pi_b + self.zk_signature.pi_c
|
||||
return ZkAndEd25519Signature.model_validate(
|
||||
{
|
||||
"zk_signature": self.zk_signature,
|
||||
"zk_signature": zk_sig,
|
||||
"ed25519_signature": self.ed25519_signature,
|
||||
}
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_random(cls, *args, **kwargs) -> Self:
|
||||
return ZkAndEd25519SignaturesSerializer.model_validate(
|
||||
return cls.model_validate(
|
||||
{
|
||||
"zk_sig": random_bytes(32).hex(),
|
||||
"ed25519_sig": random_bytes(32).hex(),
|
||||
"zk_sig": {
|
||||
"pi_a": list(random_bytes(32)),
|
||||
"pi_b": list(random_bytes(64)),
|
||||
"pi_c": list(random_bytes(32)),
|
||||
},
|
||||
"ed25519_sig": list(random_bytes(64)),
|
||||
}
|
||||
)
|
||||
|
||||
@ -79,4 +99,4 @@ class ZkAndEd25519SignaturesSerializer(OperationProofSerializer, NbeSerializer):
|
||||
OperationProofSerializerVariants = Union[
|
||||
Ed25519SignatureSerializer, ZkSignatureSerializer, ZkAndEd25519SignaturesSerializer
|
||||
]
|
||||
OperationProofSerializerField = Annotated[OperationProofSerializerVariants, Field(union_mode="left_to_right")]
|
||||
OperationProofSerializerField = Annotated[OperationProofSerializerVariants, Field(union_mode="left_to_right")]
|
||||
@ -1,7 +1,7 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Annotated, Optional, Self, Union
|
||||
|
||||
from pydantic import Field
|
||||
from pydantic import BeforeValidator, Field
|
||||
from rusty_results import Option
|
||||
|
||||
from core.models import NbeSerializer
|
||||
@ -22,13 +22,11 @@ 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.",
|
||||
)
|
||||
public: Optional[PublicSerializer] = Field(description="Only received if Node is running in dev mode.")
|
||||
voucher_cm: BytesFromHex = Field(description="Hash.")
|
||||
proof: BytesFromIntArray = Field(description="Bytes in Integer Array format (128 bytes).")
|
||||
entropy_contribution: BytesFromHex = Field(description="Fr integer in hex.")
|
||||
leader_key: BytesFromHex = Field(description="Ed25519PublicKey in hex.")
|
||||
voucher_cm: BytesFromHex = Field(description="VoucherCm hash in hex.")
|
||||
public: Optional[PublicSerializer] = Field(default=None, description="Only received if Node is running in dev mode.")
|
||||
|
||||
def into_proof_of_leadership(self) -> ProofOfLeadership:
|
||||
public = self.public.into_public() if self.public else None
|
||||
@ -46,29 +44,23 @@ class Groth16LeaderProofSerializer(ProofOfLeadershipSerializer, NbeSerializer):
|
||||
def from_random(cls, *, slot: Option[int]) -> Self:
|
||||
return cls.model_validate(
|
||||
{
|
||||
"proof": list(random_bytes(128)),
|
||||
"entropy_contribution": random_bytes(32).hex(),
|
||||
"leader_key": random_bytes(32).hex(),
|
||||
"proof": list(random_bytes(128)),
|
||||
"public": PublicSerializer.from_random(slot),
|
||||
"voucher_cm": random_bytes(32).hex(),
|
||||
"public": PublicSerializer.from_random(slot),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
# Fake Variant that never resolves to allow union type checking to work
|
||||
# TODO: Remove this when another Variant is added
|
||||
from pydantic import BeforeValidator
|
||||
|
||||
|
||||
def _always_fail(_):
|
||||
raise ValueError("Never matches.")
|
||||
|
||||
|
||||
_NeverType = Annotated[object, BeforeValidator(_always_fail)]
|
||||
#
|
||||
|
||||
|
||||
ProofOfLeadershipVariants = Union[
|
||||
Groth16LeaderProofSerializer, _NeverType
|
||||
] # TODO: Remove _NeverType when another Variant is added
|
||||
ProofOfLeadershipSerializerField = Annotated[ProofOfLeadershipVariants, Field(union_mode="left_to_right")]
|
||||
ProofOfLeadershipSerializerField = Annotated[ProofOfLeadershipVariants, Field(union_mode="left_to_right")]
|
||||
@ -1,14 +1,14 @@
|
||||
from typing import List, Self
|
||||
|
||||
from pydantic import Field
|
||||
from rusty_results import Option
|
||||
|
||||
from core.models import NbeSerializer
|
||||
from models.transactions.transaction import Transaction
|
||||
from node.api.serializers.fields import BytesFromHex
|
||||
from node.api.serializers.fields import BytesFromIntArray
|
||||
from node.api.serializers.proof import (
|
||||
OperationProofSerializer,
|
||||
OperationProofSerializerField,
|
||||
ZkSignatureComponentsSerializer,
|
||||
)
|
||||
from node.api.serializers.transaction import TransactionSerializer
|
||||
from utils.protocols import FromRandom
|
||||
@ -20,8 +20,8 @@ class SignedTransactionSerializer(NbeSerializer, FromRandom):
|
||||
operations_proofs: List[OperationProofSerializerField] = Field(
|
||||
alias="ops_proofs", description="List of OperationProof. Order should match `Self::transaction::operations`."
|
||||
)
|
||||
ledger_transaction_proof: BytesFromHex = Field(
|
||||
alias="ledger_tx_proof", description="Hash.", min_length=128, max_length=128
|
||||
ledger_transaction_proof: ZkSignatureComponentsSerializer = Field(
|
||||
alias="ledger_tx_proof", description="ZK proof with pi_a, pi_b, pi_c."
|
||||
)
|
||||
|
||||
def into_transaction(self) -> Transaction:
|
||||
@ -42,13 +42,20 @@ class SignedTransactionSerializer(NbeSerializer, FromRandom):
|
||||
ledger_transaction = self.transaction.ledger_transaction
|
||||
outputs = [output.into_note() for output in ledger_transaction.outputs]
|
||||
|
||||
# Combine pi_a, pi_b, pi_c into single proof bytes
|
||||
proof_bytes = (
|
||||
self.ledger_transaction_proof.pi_a +
|
||||
self.ledger_transaction_proof.pi_b +
|
||||
self.ledger_transaction_proof.pi_c
|
||||
)
|
||||
|
||||
return Transaction.model_validate(
|
||||
{
|
||||
"hash": self.transaction.hash,
|
||||
"operations": operations,
|
||||
"inputs": ledger_transaction.inputs,
|
||||
"outputs": outputs,
|
||||
"proof": self.ledger_transaction_proof,
|
||||
"proof": proof_bytes,
|
||||
"execution_gas_price": self.transaction.execution_gas_price,
|
||||
"storage_gas_price": self.transaction.storage_gas_price,
|
||||
}
|
||||
@ -60,5 +67,13 @@ class SignedTransactionSerializer(NbeSerializer, FromRandom):
|
||||
n = len(transaction.operations_contents)
|
||||
operations_proofs = [OperationProofSerializer.from_random() for _ in range(n)]
|
||||
return cls.model_validate(
|
||||
{"mantle_tx": transaction, "ops_proofs": operations_proofs, "ledger_tx_proof": random_bytes(128).hex()}
|
||||
)
|
||||
{
|
||||
"mantle_tx": transaction,
|
||||
"ops_proofs": operations_proofs,
|
||||
"ledger_tx_proof": {
|
||||
"pi_a": list(random_bytes(32)),
|
||||
"pi_b": list(random_bytes(64)),
|
||||
"pi_c": list(random_bytes(32)),
|
||||
},
|
||||
}
|
||||
)
|
||||
@ -6,17 +6,14 @@ from pydantic import Field
|
||||
from core.models import NbeSerializer
|
||||
from node.api.serializers.fields import BytesFromHex
|
||||
from node.api.serializers.ledger_transaction import LedgerTransactionSerializer
|
||||
from node.api.serializers.operation import (
|
||||
OperationContentSerializer,
|
||||
OperationContentSerializerField,
|
||||
)
|
||||
from node.api.serializers.operation import OperationWrapper
|
||||
from utils.protocols import FromRandom
|
||||
from utils.random import random_bytes
|
||||
|
||||
|
||||
class TransactionSerializer(NbeSerializer, FromRandom):
|
||||
hash: BytesFromHex = Field(description="Hash id in hex format.")
|
||||
operations_contents: List[OperationContentSerializerField] = Field(alias="ops")
|
||||
hash: BytesFromHex = Field(description="Transaction hash in hex format.")
|
||||
operations_contents: List[OperationWrapper] = Field(alias="ops")
|
||||
ledger_transaction: LedgerTransactionSerializer = Field(alias="ledger_tx")
|
||||
execution_gas_price: int = Field(description="Integer in u64 format.")
|
||||
storage_gas_price: int = Field(description="Integer in u64 format.")
|
||||
@ -24,7 +21,7 @@ class TransactionSerializer(NbeSerializer, FromRandom):
|
||||
@classmethod
|
||||
def from_random(cls) -> Self:
|
||||
n = 0 if randint(0, 1) <= 0.5 else randint(1, 5)
|
||||
operations_contents = [OperationContentSerializer.from_random() for _ in range(n)]
|
||||
operations_contents = [OperationWrapper.from_random() for _ in range(n)]
|
||||
return cls.model_validate(
|
||||
{
|
||||
"hash": random_bytes(32).hex(),
|
||||
@ -33,4 +30,4 @@ class TransactionSerializer(NbeSerializer, FromRandom):
|
||||
"execution_gas_price": randint(1, 10_000),
|
||||
"storage_gas_price": randint(1, 10_000),
|
||||
}
|
||||
)
|
||||
)
|
||||
Loading…
x
Reference in New Issue
Block a user