hopr_db_entity/conversions/
tickets.rs

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