Skip to main content

hopr_db_entity/conversions/
tickets.rs

1use hopr_types::{crypto::prelude::*, internal::prelude::*, primitive::prelude::*};
2use sea_orm::Set;
3
4use crate::{errors::DbEntityError, ticket};
5
6impl TryFrom<&ticket::Model> for RedeemableTicket {
7    type Error = DbEntityError;
8
9    fn try_from(value: &ticket::Model) -> Result<Self, Self::Error> {
10        let response = Response::try_from(value.response.as_ref())?;
11
12        let ticket = TicketBuilder::default()
13            .counterparty(Address::from_hex(&value.counterparty)?)
14            .amount(U256::from_be_bytes(&value.amount))
15            .index(u64::from_be_bytes(value.index.clone().try_into().map_err(|_| {
16                DbEntityError::ConversionError("invalid ticket index".into())
17            })?))
18            .win_prob(
19                value
20                    .winning_probability
21                    .as_slice()
22                    .try_into()
23                    .map_err(|_| DbEntityError::ConversionError("invalid winning probability".into()))?,
24            )
25            .channel_epoch(u32::from_be_bytes(
26                value
27                    .channel_epoch
28                    .clone()
29                    .try_into()
30                    .map_err(|_| DbEntityError::ConversionError("invalid channel epoch".into()))?,
31            ))
32            .challenge(response.to_challenge()?)
33            .signature(
34                value
35                    .signature
36                    .as_slice()
37                    .try_into()
38                    .map_err(|_| DbEntityError::ConversionError("invalid signature format".into()))?,
39            )
40            .build_verified(
41                value
42                    .hash
43                    .as_slice()
44                    .try_into()
45                    .map_err(|_| DbEntityError::ConversionError("invalid ticket hash".into()))?,
46            )
47            .map_err(|e| DbEntityError::ConversionError(format!("invalid ticket in the db: {e}")))?;
48
49        Ok(RedeemableTicket {
50            ticket,
51            response,
52            vrf_params: VrfParameters::try_from(value.vrf_params.as_slice())?,
53            channel_dst: Hash::try_from(value.channel_dst.as_slice())?,
54        })
55    }
56}
57
58impl TryFrom<ticket::Model> for RedeemableTicket {
59    type Error = DbEntityError;
60
61    fn try_from(value: ticket::Model) -> Result<Self, Self::Error> {
62        Self::try_from(&value)
63    }
64}
65
66impl From<RedeemableTicket> for ticket::ActiveModel {
67    fn from(value: RedeemableTicket) -> Self {
68        ticket::ActiveModel {
69            channel_id: Set(hex::encode(value.ticket.channel_id())), // serialize without 0x prefix
70            counterparty: Set(hex::encode(value.verified_ticket().counterparty)), // serialize without 0x prefix
71            amount: Set(value.verified_ticket().amount.amount().to_be_bytes().to_vec()),
72            index: Set(value.verified_ticket().index.to_be_bytes().to_vec()),
73            winning_probability: Set(value.verified_ticket().encoded_win_prob.to_vec()),
74            channel_epoch: Set(value.verified_ticket().channel_epoch.to_be_bytes().to_vec()),
75            signature: Set(value.verified_ticket().signature.unwrap().as_ref().to_vec()),
76            response: Set(value.response.as_ref().to_vec()),
77            vrf_params: Set(value.vrf_params.into_encoded().to_vec()),
78            channel_dst: Set(value.channel_dst.as_ref().to_vec()),
79            hash: Set(value.ticket.verified_hash().as_ref().to_vec()),
80            ..Default::default() // State is always set to 0 = Untouched
81        }
82    }
83}