safe_nd/
transfer.rs

1use super::keys::{PublicKey, Signature, SignatureShare};
2use super::money::Money;
3use crdts::Dot;
4use serde::{Deserialize, Serialize};
5use std::fmt::Debug;
6use threshold_crypto::PublicKeySet;
7
8/// Actor id
9pub type AccountId = PublicKey;
10
11/// Transfer ID.
12pub type TransferId = Dot<AccountId>;
13
14/// A transfer of money between two keys.
15#[derive(Clone, Hash, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Debug)]
16pub struct Transfer {
17    /// Transfer ID, containing source key.
18    pub id: TransferId,
19    /// The destination to transfer to.
20    pub to: AccountId,
21    /// The amount to transfer.
22    pub amount: Money,
23}
24
25impl Transfer {
26    /// Get the transfer id
27    pub fn id(&self) -> TransferId {
28        self.id
29    }
30
31    /// Get the amount of this transfer
32    pub fn amount(&self) -> Money {
33        self.amount
34    }
35
36    /// Get the sender of this transfer
37    pub fn from(&self) -> AccountId {
38        self.id.actor
39    }
40
41    /// Get the recipient of this transfer
42    pub fn to(&self) -> PublicKey {
43        self.to
44    }
45}
46
47/// The aggregated Replica signatures of the Actor debit cmd.
48#[derive(Clone, Hash, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Debug)]
49pub struct DebitAgreementProof {
50    /// The cmd generated by sender Actor.
51    pub signed_transfer: SignedTransfer,
52    /// Quorum of Replica sigs over the transfer cmd.
53    pub debiting_replicas_sig: Signature,
54    /// PublicKeySet of the replica when it validated the transfer.
55    pub replica_key: ReplicaPublicKeySet,
56}
57
58impl DebitAgreementProof {
59    /// Get the transfer id
60    pub fn id(&self) -> TransferId {
61        self.signed_transfer.id()
62    }
63
64    /// Get the amount of this transfer
65    pub fn amount(&self) -> Money {
66        self.signed_transfer.amount()
67    }
68
69    /// Get the sender of this transfer
70    pub fn from(&self) -> PublicKey {
71        self.signed_transfer.from()
72    }
73
74    /// Get the recipient of this transfer
75    pub fn to(&self) -> PublicKey {
76        self.signed_transfer.to()
77    }
78
79    /// Get the PublicKeySet of the replica that validated this transfer
80    pub fn replica_keys(&self) -> ReplicaPublicKeySet {
81        self.replica_key.clone()
82    }
83}
84
85/// An Actor cmd.
86#[derive(Clone, Hash, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Debug)]
87pub struct SignedTransfer {
88    /// The transfer.
89    pub transfer: Transfer,
90    /// Actor signature over the transfer.
91    pub actor_signature: Signature,
92}
93
94impl SignedTransfer {
95    /// Get the transfer id
96    pub fn id(&self) -> TransferId {
97        self.transfer.id
98    }
99
100    /// Get the amount of this transfer
101    pub fn amount(&self) -> Money {
102        self.transfer.amount
103    }
104
105    /// Get the sender of this transfer
106    pub fn from(&self) -> PublicKey {
107        self.transfer.id.actor
108    }
109
110    /// Get the recipient of this transfer
111    pub fn to(&self) -> PublicKey {
112        self.transfer.to
113    }
114}
115
116// ------------------------------------------------------------
117//                      Replica
118// ------------------------------------------------------------
119
120/// Events raised by the Replica.
121#[allow(clippy::large_enum_variant)]
122#[derive(Clone, Hash, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Debug)]
123pub enum ReplicaEvent {
124    /// The event raised when
125    /// ValidateTransfer cmd has been successful.
126    TransferValidated(TransferValidated),
127    /// The event raised when
128    /// RegisterTransfer cmd has been successful.
129    TransferRegistered(TransferRegistered),
130    /// The event raised when
131    /// PropagateTransfer cmd has been successful.
132    TransferPropagated(TransferPropagated),
133    // /// The event raised when
134    // /// peers changed so that we have a new PublicKeySet.
135    // PeersChanged(PeersChanged),
136    /// The event raised when
137    /// we learn of a new group PK set.
138    KnownGroupAdded(KnownGroupAdded),
139}
140
141/// The debiting Replica event raised when
142/// ValidateTransfer cmd has been successful.
143#[derive(Clone, Hash, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Debug)]
144pub struct TransferValidated {
145    /// The cmd generated by Actor.
146    pub signed_transfer: SignedTransfer,
147    /// Replica signature over the transfer cmd.
148    pub replica_signature: SignatureShare,
149    /// The PK Set of the Replicas
150    pub replicas: PublicKeySet,
151    // NB: I'm a bit ambivalent to this implicit communication of public key change.
152    // I generally prefer an explicit cmd + event for such a significant part of the logic.
153    // Including it here minimizes msg types and traffic, and seamlessly - apparently -
154    // updates Actors on any public key change, which they can accumulate in order to
155    // apply the change to local state.
156    // But it inflicts on, and complicates the logic for validating a transfer..
157    // Cost / benefit to be discussed..
158}
159
160impl TransferValidated {
161    /// Get the transfer id
162    pub fn id(&self) -> TransferId {
163        self.signed_transfer.id()
164    }
165
166    /// Get the amount of this transfer
167    pub fn amount(&self) -> Money {
168        self.signed_transfer.amount()
169    }
170
171    /// Get the recipient of this transfer
172    pub fn from(&self) -> PublicKey {
173        self.signed_transfer.from()
174    }
175
176    /// Get the recipient of this transfer
177    pub fn to(&self) -> PublicKey {
178        self.signed_transfer.to()
179    }
180}
181
182/// The debiting Replica event raised when
183/// RegisterTransfer cmd has been successful.
184#[derive(Clone, Hash, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Debug)]
185pub struct TransferRegistered {
186    /// The debit proof.
187    pub debit_proof: DebitAgreementProof,
188}
189
190impl TransferRegistered {
191    /// Get the transfer id
192    pub fn id(&self) -> TransferId {
193        self.debit_proof.id()
194    }
195
196    /// Get the amount of this transfer
197    pub fn amount(&self) -> Money {
198        self.debit_proof.amount()
199    }
200
201    /// Get the recipient of this transfer
202    pub fn from(&self) -> PublicKey {
203        self.debit_proof.from()
204    }
205
206    /// Get the recipient of this transfer
207    pub fn to(&self) -> PublicKey {
208        self.debit_proof.to()
209    }
210}
211
212/// The crediting Replica event raised when
213/// PropagateTransfer cmd has been successful.
214#[derive(Clone, Hash, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Debug)]
215pub struct TransferPropagated {
216    /// The debiting Replicas' proof.
217    pub debit_proof: DebitAgreementProof,
218    /// The pub key of the debiting Replicas.
219    pub debiting_replicas: PublicKey,
220    /// The crediting Replica signature.
221    pub crediting_replica_sig: SignatureShare,
222}
223
224impl TransferPropagated {
225    /// Get the transfer id
226    pub fn id(&self) -> TransferId {
227        self.debit_proof.id()
228    }
229
230    /// Get the amount of this transfer
231    pub fn amount(&self) -> Money {
232        self.debit_proof.amount()
233    }
234
235    /// Get the recipient of this transfer
236    pub fn from(&self) -> PublicKey {
237        self.debit_proof.from()
238    }
239
240    /// Get the recipient of this transfer
241    pub fn to(&self) -> PublicKey {
242        self.debit_proof.to()
243    }
244}
245
246/// Public Key Set for a group of transfer replicas.
247pub type ReplicaPublicKeySet = PublicKeySet;
248/// The Replica event raised when
249/// we learn of a new group PK set.
250#[derive(Clone, Hash, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Debug)]
251pub struct KnownGroupAdded {
252    /// The PublicKeySet of the group.
253    pub group: PublicKeySet,
254}
255
256// /// (Draft) An Actor cmd to roll back a failed transfer.
257// #[derive(Clone, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize, Debug)]
258// pub struct CancelTransfer {
259//     /// The transfer id.
260//     pub transfer_id: TransferId,
261//     /// Actor signature over the transfer id.
262//     pub actor_signature: Signature,
263// }
264
265/// Notification of a Transfer sent to a recipient.
266#[derive(Hash, Eq, PartialEq, PartialOrd, Clone, Serialize, Deserialize, Debug)]
267pub struct TransferNotification(pub DebitAgreementProof);