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);