wapod_types/
session.rs

1//! Worker session update message and its signed version.
2
3use scale::{Decode, Encode, MaxEncodedLen};
4use scale_info::TypeInfo;
5
6use crate::{
7    crypto::{
8        verify::{verify_message, Verifiable},
9        CryptoProvider, Signature,
10    },
11    primitives::{BoundedVec, WorkerPubkey},
12    Address, ContentType,
13};
14
15/// A session update info.
16#[derive(Debug, Clone, Encode, Decode, TypeInfo, MaxEncodedLen, PartialEq, Eq)]
17pub struct SessionUpdate {
18    /// The session id.
19    pub session: [u8; 32],
20    /// The nonce for the session generated by the worker.
21    pub nonce: [u8; 32],
22    /// The account address that used to receive the settlement payment.
23    pub recipient: BoundedVec<u8, 32>,
24}
25
26impl SessionUpdate {
27    /// Calculate the session id from the seed and nonce.
28    ///
29    /// The session id is calculated as `blake2b_256(nonce || metrics_nonce)` where `nonce` is generated
30    /// on-the-fly by the worker and `metrics_nonce` should be the last metrics nonce submitted to the chain.
31    pub fn calc_session_id<Crypto: CryptoProvider>(
32        nonce: [u8; 32],
33        metrics_nonce: &[u8],
34    ) -> [u8; 32] {
35        Crypto::blake2b_256(&[&nonce, metrics_nonce].concat())
36    }
37
38    /// Create a new session update.
39    pub fn new<Crypto: CryptoProvider>(
40        nonce: [u8; 32],
41        metrics_nonce: &[u8],
42        recipient: Address,
43    ) -> Self {
44        let session = Self::calc_session_id::<Crypto>(nonce, metrics_nonce);
45        Self {
46            session,
47            nonce,
48            recipient: recipient.to_vec().into(),
49        }
50    }
51}
52
53/// A signed session update.
54#[derive(Debug, Clone, Encode, Decode, TypeInfo, PartialEq, Eq)]
55pub struct SignedSessionUpdate {
56    /// The session update data.
57    pub update: SessionUpdate,
58    /// The signature of the update.
59    pub signature: Signature,
60    /// The public key of the worker that signed the update.
61    pub public_key: WorkerPubkey,
62}
63
64impl Verifiable for SignedSessionUpdate {
65    fn verify<Crypto: CryptoProvider>(&self) -> bool {
66        let message = self.update.encode();
67        verify_message::<Crypto>(
68            ContentType::SessionUpdate,
69            &message,
70            &self.signature,
71            &self.public_key,
72        )
73    }
74}