# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: band/base/oracle/v1beta1/proof.proto
# plugin: python-betterproto
# This file has been @generated

from dataclasses import dataclass
from typing import (
    TYPE_CHECKING,
    Dict,
    List,
    Optional,
)

import betterproto
import grpclib
from betterproto.grpc.grpclib_server import ServiceBase

from ....oracle import v1 as __oracle_v1__


if TYPE_CHECKING:
    import grpclib.server
    from betterproto.grpc.grpclib_client import MetadataLike
    from grpclib.metadata import Deadline


@dataclass(eq=False, repr=False)
class ProofRequest(betterproto.Message):
    """ProofRequest is request type for the Service/Proof RPC method."""

    request_id: int = betterproto.uint64_field(1)
    """RequestID is ID of an oracle request"""

    height: int = betterproto.int64_field(2)
    """height is block height"""


@dataclass(eq=False, repr=False)
class ProofResponse(betterproto.Message):
    """ProofResponse is response type for the Service/Proof RPC method."""

    height: int = betterproto.int64_field(1)
    """height is block height"""

    result: "SingleProofResult" = betterproto.message_field(2)
    """result is the proof"""


@dataclass(eq=False, repr=False)
class MultiProofRequest(betterproto.Message):
    """
    MultiProofRequest is request type for the Service/MultiProof RPC method.
    """

    request_ids: List[int] = betterproto.uint64_field(1)
    """request_ids is the list of request IDs"""


@dataclass(eq=False, repr=False)
class MultiProofResponse(betterproto.Message):
    """
    MultiProofResponse is response type for the Service/MultiProof RPC method.
    """

    height: int = betterproto.int64_field(1)
    result: "MultiProofResult" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class RequestCountProofRequest(betterproto.Message):
    """
    RequestCountProofRequest is request type for the Service/RequestCountProof RPC method.
    """

    pass


@dataclass(eq=False, repr=False)
class RequestCountProofResponse(betterproto.Message):
    """
    RequestCountProofResponse is response type for the Service/RequestCountProof RPC method.
    """

    height: int = betterproto.int64_field(1)
    result: "CountProofResult" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class SingleProofResult(betterproto.Message):
    """
    SingleProofResponse is the data structure for response of single proof
    """

    proof: "SingleProof" = betterproto.message_field(1)
    evm_proof_bytes: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class MultiProofResult(betterproto.Message):
    """MultiProofResult is the data structure for response of multi proof"""

    proof: "MultiProof" = betterproto.message_field(1)
    evm_proof_bytes: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class CountProofResult(betterproto.Message):
    """CountProofResult is the data structure for response of count proof"""

    proof: "CountProof" = betterproto.message_field(1)
    evm_proof_bytes: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class SingleProof(betterproto.Message):
    """
    SingleProof contains block height, oracle data proof and block relay proof
    """

    block_height: int = betterproto.uint64_field(1)
    oracle_data_proof: "OracleDataProof" = betterproto.message_field(2)
    block_relay_proof: "BlockRelayProof" = betterproto.message_field(3)


@dataclass(eq=False, repr=False)
class MultiProof(betterproto.Message):
    """
    MultiProof contains block height, list of oracle data proof and block relay proof
    """

    block_height: int = betterproto.uint64_field(1)
    oracle_data_multi_proof: List["OracleDataProof"] = betterproto.message_field(2)
    block_relay_proof: "BlockRelayProof" = betterproto.message_field(3)


@dataclass(eq=False, repr=False)
class CountProof(betterproto.Message):
    """CountProof contains block height, count proof and block relay proof"""

    block_height: int = betterproto.uint64_field(1)
    count_proof: "RequestsCountProof" = betterproto.message_field(2)
    block_relay_proof: "BlockRelayProof" = betterproto.message_field(3)


@dataclass(eq=False, repr=False)
class OracleDataProof(betterproto.Message):
    """OracleDataProof contains result, version and merkle paths"""

    result: "__oracle_v1__.Result" = betterproto.message_field(1)
    version: int = betterproto.uint64_field(2)
    merkle_paths: List["IavlMerklePath"] = betterproto.message_field(3)


@dataclass(eq=False, repr=False)
class IavlMerklePath(betterproto.Message):
    """
    IAVLMerklePath represents a Merkle step to a leaf data node in an iAVL tree.
    """

    is_data_on_right: bool = betterproto.bool_field(1)
    subtree_height: int = betterproto.uint32_field(2)
    subtree_size: int = betterproto.uint64_field(3)
    subtree_version: int = betterproto.uint64_field(4)
    sibling_hash: bytes = betterproto.bytes_field(5)


@dataclass(eq=False, repr=False)
class BlockRelayProof(betterproto.Message):
    """
    BlockRelayProof contains multi store proof, block header merkle parts, common encoded part and signatures
    """

    multi_store_proof: "MultiStoreProof" = betterproto.message_field(1)
    block_header_merkle_parts: "BlockHeaderMerkleParts" = betterproto.message_field(2)
    common_encoded_vote_part: "CommonEncodedVotePart" = betterproto.message_field(3)
    signatures: List["TmSignature"] = betterproto.message_field(4)


@dataclass(eq=False, repr=False)
class MultiStoreProof(betterproto.Message):
    """
    MultiStoreProof stores a compact of other Cosmos-SDK modules' storage hash in multistore to
     compute (in combination with oracle store hash) Tendermint's application state hash at a given block.
    
                                       __________________________[AppHash]__________________________
                                      /                                                             \
                        ___________[N24]____________                                    ___________[N25]________
                       /                            \                                  /                        \                        
                _____[N20]_____                 ____[N21]______                   ____[N22]______              _[N23]_
               /               \               /               \                 /               \            /       \
           _[N12]_          _[N13]_          _[N14]_          _[N15]_          _[N16]_          _[N17]_     [N18]     [Q]
          /       \        /       \        /       \        /       \        /       \        /       \    /   \
        [N0]     [N1]    [N2]     [N3]    [N4]     [N5]    [N6]     [N7]    [N8]     [N9]   [N10]    [N11] [O] [P]
       /   \    /   \    /  \    /   \   /   \    /   \   /   \    /   \   /   \    /   \   /   \    /   \
      [0] [1]  [2] [3] [4] [5]  [6] [7] [8] [9]  [A] [B] [C] [D]  [E] [F] [G] [H]  [I] [J] [K] [L]  [M] [N]
    
     [0] - acc (auth) [1] - authz         [2] - bandtss       [3] - bank        [4] - capability [5] - consensus
     [6] - crisis     [7] - distribution  [8] - evidence      [9] - feeds       [A] - feegrant   [B] - feeibc
     [C] - globalfee  [D] - gov           [E] - ibc           [F] - icahost     [G] - mint       [H] - oracle
     [I] - params     [J] - restake       [K] - rollingseed   [L] - slashing    [M] - staking    [N] - transfer
     [O] - tss        [P] - tunnel        [Q] - upgrade
    
     Notice that NOT all leaves of the Merkle tree are needed in order to compute the Merkle
     root hash, since we only want to validate the correctness of [H] In fact, only
     [G], [N9], [N17], [N23], and [N24] are needed in order to compute [AppHash].
    """

    oracle_iavl_state_hash: bytes = betterproto.bytes_field(1)
    mint_store_merkle_hash: bytes = betterproto.bytes_field(2)
    params_to_restake_stores_merkle_hash: bytes = betterproto.bytes_field(3)
    rollingseed_to_transfer_stores_merkle_hash: bytes = betterproto.bytes_field(4)
    tss_to_upgrade_stores_merkle_hash: bytes = betterproto.bytes_field(5)
    auth_to_icahost_stores_merkle_hash: bytes = betterproto.bytes_field(6)


@dataclass(eq=False, repr=False)
class BlockHeaderMerkleParts(betterproto.Message):
    """
    BlockHeaderMerkleParts stores a group of hashes using for computing Tendermint's block
     header hash from app hash, and height.
    
     In Tendermint, a block header hash is the Merkle hash of a binary tree with 14 leaf nodes.
     Each node encodes a data piece of the blockchain. The notable data leaves are: [A] app_hash,
     [2] height. All data pieces are combined into one 32-byte hash to be signed
     by block validators. The structure of the Merkle tree is shown below.
    
                                       [BlockHeader]
                                    /                \
                       [3A]                                    [3B]
                     /      \                                /      \
             [2A]                [2B]                [2C]                [2D]
            /    \              /    \              /    \              /    \
        [1A]      [1B]      [1C]      [1D]      [1E]      [1F]        [C]    [D]
        /  \      /  \      /  \      /  \      /  \      /  \
      [0]  [1]  [2]  [3]  [4]  [5]  [6]  [7]  [8]  [9]  [A]  [B]
    
      [0] - version               [1] - chain_id            [2] - height        [3] - time
      [4] - last_block_id         [5] - last_commit_hash    [6] - data_hash     [7] - validators_hash
      [8] - next_validators_hash  [9] - consensus_hash      [A] - app_hash      [B] - last_results_hash
      [C] - evidence_hash         [D] - proposer_address
    
     Notice that NOT all leaves of the Merkle tree are needed in order to compute the Merkle
     root hash, since we only want to validate the correctness of [2], [3], and [A]. In fact, only
     [1A], [2B], [1E], [B], and [2D] are needed in order to compute [BlockHeader].
    """

    version_and_chain_id_hash: bytes = betterproto.bytes_field(1)
    height: int = betterproto.uint64_field(2)
    time_second: int = betterproto.uint64_field(3)
    time_nano_second: int = betterproto.uint32_field(4)
    last_block_id_and_other: bytes = betterproto.bytes_field(5)
    next_validator_hash_and_consensus_hash: bytes = betterproto.bytes_field(6)
    last_results_hash: bytes = betterproto.bytes_field(7)
    evidence_and_proposer_hash: bytes = betterproto.bytes_field(8)


@dataclass(eq=False, repr=False)
class CommonEncodedVotePart(betterproto.Message):
    """CommonEncodedVotePart represents the common part of encoded vote"""

    signed_data_prefix: bytes = betterproto.bytes_field(1)
    signed_data_suffix: bytes = betterproto.bytes_field(2)


@dataclass(eq=False, repr=False)
class TmSignature(betterproto.Message):
    """
    TMSignature contains all details of validator signature for performing signer recovery for ECDSA
     secp256k1 signature. Note that this struct is written specifically for signature signed on
     Tendermint's precommit data, which includes the block hash and some additional information prepended
     and appended to the block hash. The prepended part (prefix) and the appended part (suffix) are
     different for each signer (including signature size, machine clock, validator index, etc).
    """

    r: bytes = betterproto.bytes_field(1)
    s: bytes = betterproto.bytes_field(2)
    v: int = betterproto.uint32_field(3)
    encoded_timestamp: bytes = betterproto.bytes_field(4)


@dataclass(eq=False, repr=False)
class RequestsCountProof(betterproto.Message):
    """RequestsCountProof contains count, version and merkle paths"""

    count: int = betterproto.uint64_field(1)
    version: int = betterproto.uint64_field(2)
    merkle_paths: List["IavlMerklePath"] = betterproto.message_field(3)


class ServiceStub(betterproto.ServiceStub):
    async def proof(
        self,
        proof_request: "ProofRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "ProofResponse":
        return await self._unary_unary(
            "/band.base.oracle.v1beta1.Service/Proof",
            proof_request,
            ProofResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def multi_proof(
        self,
        multi_proof_request: "MultiProofRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "MultiProofResponse":
        return await self._unary_unary(
            "/band.base.oracle.v1beta1.Service/MultiProof",
            multi_proof_request,
            MultiProofResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def request_count_proof(
        self,
        request_count_proof_request: "RequestCountProofRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "RequestCountProofResponse":
        return await self._unary_unary(
            "/band.base.oracle.v1beta1.Service/RequestCountProof",
            request_count_proof_request,
            RequestCountProofResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class ServiceBase(ServiceBase):

    async def proof(self, proof_request: "ProofRequest") -> "ProofResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def multi_proof(
        self, multi_proof_request: "MultiProofRequest"
    ) -> "MultiProofResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def request_count_proof(
        self, request_count_proof_request: "RequestCountProofRequest"
    ) -> "RequestCountProofResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_proof(
        self, stream: "grpclib.server.Stream[ProofRequest, ProofResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.proof(request)
        await stream.send_message(response)

    async def __rpc_multi_proof(
        self, stream: "grpclib.server.Stream[MultiProofRequest, MultiProofResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.multi_proof(request)
        await stream.send_message(response)

    async def __rpc_request_count_proof(
        self,
        stream: "grpclib.server.Stream[RequestCountProofRequest, RequestCountProofResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.request_count_proof(request)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/band.base.oracle.v1beta1.Service/Proof": grpclib.const.Handler(
                self.__rpc_proof,
                grpclib.const.Cardinality.UNARY_UNARY,
                ProofRequest,
                ProofResponse,
            ),
            "/band.base.oracle.v1beta1.Service/MultiProof": grpclib.const.Handler(
                self.__rpc_multi_proof,
                grpclib.const.Cardinality.UNARY_UNARY,
                MultiProofRequest,
                MultiProofResponse,
            ),
            "/band.base.oracle.v1beta1.Service/RequestCountProof": grpclib.const.Handler(
                self.__rpc_request_count_proof,
                grpclib.const.Cardinality.UNARY_UNARY,
                RequestCountProofRequest,
                RequestCountProofResponse,
            ),
        }
