1use crate::{
4 common::{
5 base16_decode_string, deserial_string, types::Signature, Buffer, Deserial, Get,
6 ParseResult, Put, ReadBytesExt, SerdeBase16Serialize, SerdeDeserialize, SerdeSerialize,
7 Serial, Serialize,
8 },
9 curve_arithmetic::Curve,
10 id::{
11 constants::ArCurve,
12 types::{GlobalContext, VerifyKey},
13 },
14 pedersen_commitment::{Randomness, Value},
15 random_oracle::RandomOracle,
16};
17use concordium_contracts_common::AccountAddress;
18pub use concordium_contracts_common::{
19 AccountThreshold, Address, ContractAddress, ContractIndex, ContractSubIndex, ExchangeRate,
20 ZeroSignatureThreshold,
21};
22use derive_more::{Add, Display, From, FromStr, Into, Sub, Sum};
23use ed25519_dalek::Signer;
24use rand::{CryptoRng, Rng};
25use std::{
26 convert::{TryFrom, TryInto},
27 fmt,
28 hash::Hash,
29 str::FromStr,
30};
31use thiserror::Error;
32
33#[repr(transparent)] #[derive(Eq, Debug, Clone, Copy)]
40pub struct AccountAddressEq(pub(crate) AccountAddress);
41
42impl From<AccountAddressEq> for AccountAddress {
43 fn from(aae: AccountAddressEq) -> Self {
44 aae.0
45 }
46}
47
48impl From<AccountAddress> for AccountAddressEq {
49 fn from(address: AccountAddress) -> Self {
50 Self(address)
51 }
52}
53
54impl PartialEq for AccountAddressEq {
55 fn eq(&self, other: &Self) -> bool {
56 let bytes_1 = &self.0 .0;
57 let bytes_2 = &other.0 .0;
58 bytes_1[0..29] == bytes_2[0..29]
59 }
60}
61
62impl PartialOrd for AccountAddressEq {
63 #[inline]
64 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
65 Some(self.cmp(other))
66 }
67}
68
69impl Ord for AccountAddressEq {
70 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
71 let bytes_1 = &self.0 .0;
72 let bytes_2 = &other.0 .0;
73 bytes_1[0..29].cmp(&bytes_2[0..29])
74 }
75}
76
77impl Hash for AccountAddressEq {
78 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
79 self.0 .0[0..29].hash(state)
80 }
81}
82
83impl AsRef<AccountAddressEq> for AccountAddress {
87 fn as_ref(&self) -> &AccountAddressEq {
88 unsafe { std::mem::transmute(self) }
89 }
90}
91
92impl AsRef<AccountAddress> for AccountAddressEq {
96 fn as_ref(&self) -> &AccountAddress {
97 &self.0
98 }
99}
100
101#[repr(transparent)]
103#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
104#[serde(transparent)]
105#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
106pub struct SlotDuration {
107 pub millis: u64,
108}
109
110#[derive(Debug, thiserror::Error)]
113#[error("Slot duration is not representable as chrono::Duration.")]
114pub struct SlotDurationConversionError;
115
116impl TryFrom<SlotDuration> for chrono::Duration {
117 type Error = SlotDurationConversionError;
118
119 fn try_from(s: SlotDuration) -> Result<Self, Self::Error> {
120 let Ok(millis) = s.millis.try_into() else {
121 return Err(SlotDurationConversionError);
122 };
123 Self::try_milliseconds(millis).ok_or(SlotDurationConversionError)
124 }
125}
126
127#[repr(transparent)]
129#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
130#[serde(transparent)]
131#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
132pub struct DurationSeconds {
133 pub seconds: u64,
134}
135
136#[derive(Debug, thiserror::Error)]
139#[error("Duration in seconds is not representable as chrono::Duration.")]
140pub struct DurationSecondsConversionError;
141
142impl TryFrom<DurationSeconds> for chrono::Duration {
143 type Error = SlotDurationConversionError;
144
145 fn try_from(s: DurationSeconds) -> Result<Self, Self::Error> {
146 let Ok(millis) = s.seconds.try_into() else {
147 return Err(SlotDurationConversionError);
148 };
149 Self::try_seconds(millis).ok_or(SlotDurationConversionError)
150 }
151}
152
153#[repr(transparent)]
155#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
156#[serde(transparent)]
157#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
158pub struct BakerId {
159 pub id: AccountIndex,
160}
161
162#[repr(transparent)]
164#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
165#[serde(transparent)]
166#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
167pub struct DelegatorId {
168 pub id: AccountIndex,
169}
170
171#[repr(transparent)]
177#[derive(
178 SerdeSerialize,
179 SerdeDeserialize,
180 Serial,
181 Clone,
182 Eq,
183 PartialEq,
184 Ord,
185 PartialOrd,
186 Debug,
187 Display,
188 Into,
189 Default,
190)]
191#[serde(try_from = "String", into = "String")]
192pub struct UrlText {
193 #[string_size_length = 2]
194 url: String,
195}
196
197impl Deserial for UrlText {
198 fn deserial<R: ReadBytesExt>(source: &mut R) -> ParseResult<Self> {
199 let len: u16 = source.get()?;
200 anyhow::ensure!(
201 usize::from(len) <= crate::constants::MAX_URL_TEXT_LENGTH,
202 "URL length exceeds maximum allowed."
203 );
204 let url = deserial_string(source, len.into())?;
205 Ok(Self { url })
206 }
207}
208
209impl TryFrom<String> for UrlText {
210 type Error = anyhow::Error;
211
212 fn try_from(value: String) -> Result<Self, Self::Error> {
213 anyhow::ensure!(
214 value.as_bytes().len() <= crate::constants::MAX_URL_TEXT_LENGTH,
215 "URL length exceeds maximum allowed."
216 );
217 Ok(Self { url: value })
218 }
219}
220
221#[derive(SerdeSerialize, SerdeDeserialize, PartialEq, Eq, Debug, Clone, Copy)]
223#[serde(rename_all = "camelCase")]
224#[repr(u8)]
225pub enum OpenStatus {
226 OpenForAll = 0,
228 ClosedForNew = 1,
230 ClosedForAll = 2,
232}
233
234impl Serial for OpenStatus {
235 fn serial<B: Buffer>(&self, out: &mut B) {
236 (*self as u8).serial(out)
237 }
238}
239
240impl Deserial for OpenStatus {
241 fn deserial<R: ReadBytesExt>(source: &mut R) -> ParseResult<Self> {
242 let tag: u8 = source.get()?;
243 match tag {
244 0 => Ok(Self::OpenForAll),
245 1 => Ok(Self::ClosedForNew),
246 2 => Ok(Self::ClosedForAll),
247 _ => anyhow::bail!("Unrecognized OpenStatus tag {}", tag),
248 }
249 }
250}
251
252#[derive(SerdeSerialize, SerdeDeserialize, PartialEq, Eq, Debug, Clone)]
253#[serde(rename_all = "camelCase", tag = "delegateType")]
254pub enum DelegationTarget {
256 #[serde(rename = "Passive")]
257 Passive,
259 #[serde(rename = "Baker")]
260 Baker {
262 #[serde(rename = "bakerId")]
263 baker_id: BakerId,
264 },
265}
266
267impl From<BakerId> for DelegationTarget {
268 fn from(baker_id: BakerId) -> Self {
269 Self::Baker { baker_id }
270 }
271}
272
273impl Serial for DelegationTarget {
274 fn serial<B: Buffer>(&self, out: &mut B) {
275 match self {
276 DelegationTarget::Passive => 0u8.serial(out),
277 DelegationTarget::Baker { baker_id } => {
278 1u8.serial(out);
279 baker_id.serial(out)
280 }
281 }
282 }
283}
284
285impl Deserial for DelegationTarget {
286 fn deserial<R: ReadBytesExt>(source: &mut R) -> ParseResult<Self> {
287 let tag: u8 = source.get()?;
288 match tag {
289 0 => Ok(Self::Passive),
290 1 => {
291 let baker_id = source.get()?;
292 Ok(Self::Baker { baker_id })
293 }
294 _ => anyhow::bail!("Unrecognized delegation target tag: {}", tag),
295 }
296 }
297}
298
299#[repr(transparent)]
301#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
302#[serde(transparent)]
303#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
304pub struct Slot {
305 pub slot: u64,
306}
307
308#[repr(transparent)]
310#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
311#[serde(transparent)]
312#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
313pub struct Epoch {
314 pub epoch: u64,
315}
316
317#[repr(transparent)]
319#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
320#[serde(transparent)]
321#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
322pub struct Round {
323 pub round: u64,
324}
325
326#[repr(transparent)]
327#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
328#[serde(transparent)]
329#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
330pub struct Nonce {
334 pub nonce: u64,
335}
336
337impl Nonce {
338 pub fn next(self) -> Self {
340 Self {
341 nonce: self.nonce + 1,
342 }
343 }
344
345 pub fn next_mut(&mut self) {
347 self.nonce += 1;
348 }
349}
350
351#[repr(transparent)]
352#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
353#[serde(transparent)]
354#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
355pub struct UpdateSequenceNumber {
358 pub number: u64,
359}
360
361impl UpdateSequenceNumber {
362 #[must_use]
365 pub fn next(self) -> Self {
366 Self {
367 number: self.number + 1,
368 }
369 }
370
371 pub fn next_mut(&mut self) {
373 self.number += 1;
374 }
375}
376
377impl Default for UpdateSequenceNumber {
378 fn default() -> Self {
379 Self { number: 1 }
380 }
381}
382
383#[repr(transparent)]
384#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
385#[serde(transparent)]
386#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
387pub struct CredentialsPerBlockLimit {
391 pub limit: u16,
392}
393
394#[repr(transparent)]
397#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
398#[serde(transparent)]
399#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
400pub struct BlockHeight {
401 pub height: u64,
402}
403
404#[repr(transparent)]
408#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
409#[serde(transparent)]
410#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
411pub struct GenesisIndex {
412 pub height: u32,
413}
414
415#[derive(
419 SerdeSerialize, SerdeDeserialize, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Display,
420)]
421#[serde(into = "u64", try_from = "u64")]
422pub enum ProtocolVersion {
423 #[display(fmt = "P1")]
424 P1,
426 #[display(fmt = "P2")]
427 P2,
429 #[display(fmt = "P3")]
430 P3,
433 #[display(fmt = "P4")]
434 P4,
437 #[display(fmt = "P5")]
438 P5,
443 #[display(fmt = "P6")]
444 P6,
449 #[display(fmt = "P7")]
450 P7,
453 #[display(fmt = "P8")]
454 P8,
456 #[display(fmt = "P9")]
457 P9,
459}
460
461#[derive(Debug, Error, Display)]
462pub struct UnknownProtocolVersion {
465 version: u64,
467}
468
469impl TryFrom<u64> for ProtocolVersion {
470 type Error = UnknownProtocolVersion;
471
472 fn try_from(value: u64) -> Result<Self, Self::Error> {
473 match value {
474 1 => Ok(ProtocolVersion::P1),
475 2 => Ok(ProtocolVersion::P2),
476 3 => Ok(ProtocolVersion::P3),
477 4 => Ok(ProtocolVersion::P4),
478 5 => Ok(ProtocolVersion::P5),
479 6 => Ok(ProtocolVersion::P6),
480 7 => Ok(ProtocolVersion::P7),
481 8 => Ok(ProtocolVersion::P8),
482 9 => Ok(ProtocolVersion::P9),
483 version => Err(UnknownProtocolVersion { version }),
484 }
485 }
486}
487
488impl From<ProtocolVersion> for u64 {
489 fn from(pv: ProtocolVersion) -> Self {
490 match pv {
491 ProtocolVersion::P1 => 1,
492 ProtocolVersion::P2 => 2,
493 ProtocolVersion::P3 => 3,
494 ProtocolVersion::P4 => 4,
495 ProtocolVersion::P5 => 5,
496 ProtocolVersion::P6 => 6,
497 ProtocolVersion::P7 => 7,
498 ProtocolVersion::P8 => 8,
499 ProtocolVersion::P9 => 9,
500 }
501 }
502}
503
504impl Serial for ProtocolVersion {
505 fn serial<B: Buffer>(&self, out: &mut B) {
506 let n: u64 = (*self).into();
507 out.put(&n);
508 }
509}
510
511impl Deserial for ProtocolVersion {
512 fn deserial<R: ReadBytesExt>(source: &mut R) -> ParseResult<Self> {
513 let n: u64 = source.get()?;
514 let pv = ProtocolVersion::try_from(n)?;
515 Ok(pv)
516 }
517}
518
519#[repr(transparent)]
521#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
522#[serde(transparent)]
523#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
524pub struct AbsoluteBlockHeight {
525 pub height: u64,
526}
527
528impl AbsoluteBlockHeight {
529 #[must_use]
531 pub fn next(self) -> Self {
532 AbsoluteBlockHeight {
533 height: 1 + self.height,
534 }
535 }
536}
537
538#[repr(transparent)]
539#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
540#[serde(transparent)]
541#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
542pub struct AccountIndex {
545 pub index: u64,
546}
547
548#[repr(transparent)]
550#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
551#[serde(transparent)]
552#[derive(
553 Copy,
554 Clone,
555 Eq,
556 PartialEq,
557 Ord,
558 PartialOrd,
559 Debug,
560 Default,
561 FromStr,
562 Display,
563 From,
564 Into,
565 Add,
566 Sub,
567 Sum,
568)]
569pub struct Energy {
570 pub energy: u64,
571}
572
573impl Energy {
574 pub fn checked_sub(self, rhs: Energy) -> Option<Energy> {
578 self.energy.checked_sub(rhs.energy).map(From::from)
579 }
580
581 pub fn tick_energy(&mut self, amount: Energy) -> Result<(), InsufficientEnergy> {
585 if let Some(nrg) = self.energy.checked_sub(amount.energy) {
586 self.energy = nrg;
587 Ok(())
588 } else {
589 Err(InsufficientEnergy)
590 }
591 }
592}
593
594#[derive(Debug, PartialEq, Eq, Error)]
595#[error("Out of energy")]
596pub struct InsufficientEnergy;
599
600#[repr(transparent)]
602#[derive(SerdeSerialize, SerdeDeserialize, Debug, Serialize, Clone, Copy)]
603#[serde(transparent)]
604pub struct TransactionIndex {
605 pub index: u64,
606}
607
608pub type AggregateSigPairing = crate::id::constants::IpPairing;
609
610#[repr(transparent)]
611#[derive(SerdeBase16Serialize, Serialize)]
612pub struct BakerAggregationSignKey {
614 pub(crate) sign_key: crate::aggregate_sig::SecretKey<AggregateSigPairing>,
615}
616
617impl BakerAggregationSignKey {
618 pub fn generate<T: Rng>(csprng: &mut T) -> Self {
620 Self {
621 sign_key: crate::aggregate_sig::SecretKey::generate(csprng),
622 }
623 }
624
625 pub fn prove<T: Rng>(
628 &self,
629 csprng: &mut T,
630 random_oracle: &mut RandomOracle,
631 ) -> crate::aggregate_sig::Proof<AggregateSigPairing> {
632 self.sign_key.prove(csprng, random_oracle)
633 }
634}
635
636#[repr(transparent)]
637#[derive(SerdeBase16Serialize, Serialize, Clone, Debug, PartialEq)]
638pub struct BakerAggregationVerifyKey {
640 pub(crate) verify_key: crate::aggregate_sig::PublicKey<AggregateSigPairing>,
641}
642
643impl From<&BakerAggregationSignKey> for BakerAggregationVerifyKey {
644 fn from(secret: &BakerAggregationSignKey) -> Self {
645 Self {
646 verify_key: crate::aggregate_sig::PublicKey::from_secret(&secret.sign_key),
647 }
648 }
649}
650
651#[repr(transparent)]
652#[derive(SerdeBase16Serialize, Serialize)]
653pub struct BakerSignatureSignKey {
655 pub(crate) sign_key: ed25519_dalek::SecretKey,
656}
657
658impl BakerSignatureSignKey {
659 pub fn generate<T: CryptoRng + Rng>(csprng: &mut T) -> Self {
661 Self {
662 sign_key: csprng.gen(),
663 }
664 }
665}
666
667#[repr(transparent)]
668#[derive(SerdeBase16Serialize, Serialize, Clone, Debug, PartialEq, Eq)]
669pub struct BakerSignatureVerifyKey {
671 pub(crate) verify_key: ed25519_dalek::VerifyingKey,
672}
673
674impl From<&BakerSignatureSignKey> for BakerSignatureVerifyKey {
675 fn from(secret: &BakerSignatureSignKey) -> Self {
676 Self {
677 verify_key: ed25519_dalek::SigningKey::from(&secret.sign_key).verifying_key(),
678 }
679 }
680}
681
682#[repr(transparent)]
683#[derive(SerdeBase16Serialize, Serialize)]
684pub struct BakerElectionSignKey {
687 pub(crate) sign_key: crate::ecvrf::SecretKey,
688}
689
690impl BakerElectionSignKey {
691 pub fn generate<T: CryptoRng + Rng>(csprng: &mut T) -> Self {
692 Self {
693 sign_key: crate::ecvrf::SecretKey::generate(csprng),
694 }
695 }
696}
697
698#[repr(transparent)]
699#[derive(SerdeBase16Serialize, Serialize, Clone, Debug, PartialEq, Eq)]
700pub struct BakerElectionVerifyKey {
702 pub(crate) verify_key: crate::ecvrf::PublicKey,
703}
704
705impl From<&BakerElectionSignKey> for BakerElectionVerifyKey {
706 fn from(secret: &BakerElectionSignKey) -> Self {
707 Self {
708 verify_key: crate::ecvrf::PublicKey::from(&secret.sign_key),
709 }
710 }
711}
712
713#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
721pub struct BakerKeyPairs {
722 #[serde(rename = "signatureSignKey")]
723 pub signature_sign: BakerSignatureSignKey,
724 #[serde(rename = "signatureVerifyKey")]
725 pub signature_verify: BakerSignatureVerifyKey,
726 #[serde(rename = "electionPrivateKey")]
727 pub election_sign: BakerElectionSignKey,
728 #[serde(rename = "electionVerifyKey")]
729 pub election_verify: BakerElectionVerifyKey,
730 #[serde(rename = "aggregationSignKey")]
731 pub aggregation_sign: BakerAggregationSignKey,
732 #[serde(rename = "aggregationVerifyKey")]
733 pub aggregation_verify: BakerAggregationVerifyKey,
734}
735
736impl BakerKeyPairs {
737 pub fn generate<T: Rng + CryptoRng>(csprng: &mut T) -> Self {
739 let signature_sign = BakerSignatureSignKey::generate(csprng);
740 let signature_verify = BakerSignatureVerifyKey::from(&signature_sign);
741 let election_sign = BakerElectionSignKey::generate(csprng);
742 let election_verify = BakerElectionVerifyKey::from(&election_sign);
743 let aggregation_sign = BakerAggregationSignKey::generate(csprng);
744 let aggregation_verify = BakerAggregationVerifyKey::from(&aggregation_sign);
745 BakerKeyPairs {
746 signature_sign,
747 signature_verify,
748 election_sign,
749 election_verify,
750 aggregation_sign,
751 aggregation_verify,
752 }
753 }
754}
755
756#[derive(SerdeSerialize, SerdeDeserialize)]
762#[serde(rename_all = "camelCase")]
763pub struct BakerCredentials {
764 #[serde(alias = "validatorId")]
765 pub baker_id: BakerId,
766 #[serde(flatten)]
767 pub keys: BakerKeyPairs,
768}
769
770impl BakerCredentials {
771 pub fn new(baker_id: BakerId, keys: BakerKeyPairs) -> Self {
772 BakerCredentials { baker_id, keys }
773 }
774}
775
776#[derive(
777 SerdeBase16Serialize,
778 Serialize,
779 Debug,
780 Clone,
781 Copy,
782 derive_more::AsRef,
783 derive_more::Into,
784 PartialEq,
785 Eq,
786)]
787pub struct CredentialRegistrationID(crate::id::constants::ArCurve);
792
793impl FromStr for CredentialRegistrationID {
794 type Err = anyhow::Error;
795
796 fn from_str(s: &str) -> Result<Self, Self::Err> {
797 base16_decode_string(s)
798 }
799}
800
801impl CredentialRegistrationID {
802 pub fn new(g: crate::id::constants::ArCurve) -> Self {
803 Self(g)
804 }
805
806 pub fn from_exponent(
809 crypto_params: &GlobalContext<ArCurve>,
810 cexp: <crate::id::constants::ArCurve as Curve>::Scalar,
811 ) -> Self {
812 let cred_id = crypto_params
813 .on_chain_commitment_key
814 .hide(&Value::<ArCurve>::new(cexp), &Randomness::zero())
815 .0;
816 Self::new(cred_id)
817 }
818}
819
820impl fmt::Display for CredentialRegistrationID {
821 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
822 let s = hex::encode(crate::common::to_bytes(self));
823 s.fmt(f)
824 }
825}
826
827#[repr(transparent)]
828#[derive(Debug, SerdeSerialize, SerdeDeserialize, Serialize, Clone, Into, From, PartialEq, Eq)]
829#[serde(transparent)]
830pub struct UpdatePublicKey {
832 pub public: VerifyKey,
833}
834
835#[derive(Debug, SerdeSerialize, SerdeDeserialize, derive_more::AsRef, Clone)]
839#[serde(
840 try_from = "update_key_pair_json::UpdateKeyPair",
841 into = "update_key_pair_json::UpdateKeyPair"
842)]
843pub struct UpdateKeyPair {
844 inner: ed25519_dalek::SigningKey,
845}
846
847mod update_key_pair_json {
848 use crate::id::types::SchemeId;
849
850 use super::*;
851 #[derive(Debug, SerdeSerialize, SerdeDeserialize)]
855 pub struct UpdateKeyPair {
856 #[serde(
857 rename = "signKey",
858 serialize_with = "crate::common::base16_encode_array",
859 deserialize_with = "crate::common::base16_decode_array"
860 )]
861 pub secret: ed25519_dalek::SecretKey,
862 #[serde(
863 rename = "verifyKey",
864 serialize_with = "crate::common::base16_encode",
865 deserialize_with = "crate::common::base16_decode"
866 )]
867 pub public: ed25519_dalek::VerifyingKey,
868 pub schema: Option<SchemeId>,
869 }
870
871 impl TryFrom<UpdateKeyPair> for super::UpdateKeyPair {
872 type Error = ed25519_dalek::SignatureError;
873
874 fn try_from(value: UpdateKeyPair) -> Result<Self, Self::Error> {
875 let inner = ed25519_dalek::SigningKey::from_bytes(&value.secret);
876 if inner.verifying_key() != value.public {
877 Err(ed25519_dalek::SignatureError::from_source(
878 "Public key does not match secret key.",
879 ))
880 } else {
881 Ok(Self { inner })
882 }
883 }
884 }
885
886 impl From<super::UpdateKeyPair> for UpdateKeyPair {
887 fn from(value: super::UpdateKeyPair) -> Self {
888 Self {
889 secret: value.inner.to_bytes(),
890 public: value.inner.verifying_key(),
891 schema: Some(SchemeId::Ed25519),
892 }
893 }
894 }
895}
896
897impl UpdateKeyPair {
898 pub fn generate<R: rand::CryptoRng + rand::Rng>(rng: &mut R) -> Self {
900 let inner = ed25519_dalek::SigningKey::generate(rng);
901 Self { inner }
902 }
903
904 pub fn sign(&self, msg: &[u8]) -> Signature {
906 self.inner.sign(msg).into()
907 }
908}
909
910impl From<&UpdateKeyPair> for UpdatePublicKey {
911 fn from(kp: &UpdateKeyPair) -> Self {
912 UpdatePublicKey {
913 public: kp.inner.verifying_key().into(),
914 }
915 }
916}
917
918#[derive(
919 Debug, Clone, Copy, SerdeSerialize, SerdeDeserialize, Serialize, Into, Display, Eq, PartialEq,
920)]
921#[serde(transparent)]
922pub struct UpdateKeysThreshold {
925 pub(crate) threshold: std::num::NonZeroU16,
926}
927
928impl From<UpdateKeysThreshold> for u16 {
929 #[inline]
930 fn from(u: UpdateKeysThreshold) -> Self {
931 u.threshold.get()
932 }
933}
934
935impl TryFrom<u16> for UpdateKeysThreshold {
936 type Error = ZeroSignatureThreshold;
937
938 fn try_from(value: u16) -> Result<Self, Self::Error> {
939 std::num::NonZeroU16::new(value).map_or(Err(ZeroSignatureThreshold), |threshold| {
940 Ok(UpdateKeysThreshold { threshold })
941 })
942 }
943}
944
945#[repr(transparent)]
946#[derive(
947 Debug,
948 Clone,
949 Copy,
950 SerdeSerialize,
951 SerdeDeserialize,
952 Serialize,
953 PartialEq,
954 Eq,
955 PartialOrd,
956 Ord,
957 From,
958)]
959#[serde(transparent)]
960pub struct UpdateKeysIndex {
964 pub index: u16,
965}
966
967impl std::fmt::Display for UpdateKeysIndex {
968 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
969 self.index.fmt(f)
970 }
971}
972
973#[repr(transparent)]
974#[derive(
975 Debug, Clone, Copy, SerdeSerialize, SerdeDeserialize, Serialize, FromStr, PartialEq, Eq,
976)]
977#[serde(transparent)]
978pub struct ElectionDifficulty {
981 pub(crate) parts_per_hundred_thousands: PartsPerHundredThousands,
982}
983
984impl ElectionDifficulty {
985 pub fn new(parts: u32) -> Option<Self> {
989 let parts_per_hundred_thousands = PartsPerHundredThousands::new(parts)?;
990 Some(Self {
991 parts_per_hundred_thousands,
992 })
993 }
994
995 pub fn new_unchecked(parts: u32) -> Self {
997 Self {
998 parts_per_hundred_thousands: PartsPerHundredThousands::new_unchecked(parts),
999 }
1000 }
1001}
1002
1003impl From<ElectionDifficulty> for rust_decimal::Decimal {
1004 fn from(ed: ElectionDifficulty) -> Self {
1005 ed.parts_per_hundred_thousands.into()
1006 }
1007}
1008
1009#[repr(transparent)]
1010#[derive(Default, Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Into)]
1011pub struct PartsPerHundredThousands {
1014 pub(crate) parts: u32,
1015}
1016
1017impl PartsPerHundredThousands {
1018 pub fn new(parts: u32) -> Option<Self> {
1021 if parts <= 100_000 {
1022 Some(Self { parts })
1023 } else {
1024 None
1025 }
1026 }
1027
1028 pub fn new_unchecked(parts: u32) -> Self {
1031 Self { parts }
1032 }
1033}
1034
1035impl From<PartsPerHundredThousands> for rust_decimal::Decimal {
1036 fn from(pp: PartsPerHundredThousands) -> Self {
1037 rust_decimal::Decimal::new(pp.parts.into(), 5)
1038 }
1039}
1040
1041impl Serial for PartsPerHundredThousands {
1042 fn serial<B: Buffer>(&self, out: &mut B) {
1043 self.parts.serial(out)
1044 }
1045}
1046
1047impl Deserial for PartsPerHundredThousands {
1048 fn deserial<R: ReadBytesExt>(source: &mut R) -> ParseResult<Self> {
1049 let parts: u32 = source.get()?;
1050 Self::new(parts)
1051 .ok_or_else(|| anyhow::anyhow!("No more than 100_000 parts per hundred thousand."))
1052 }
1053}
1054
1055impl fmt::Display for PartsPerHundredThousands {
1057 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1058 let x = rust_decimal::Decimal::try_new(self.parts.into(), 5).map_err(|_| fmt::Error)?;
1059 x.fmt(f)
1060 }
1061}
1062
1063#[derive(SerdeSerialize, SerdeDeserialize, PartialEq, Eq, Serialize, Debug, Clone, Copy)]
1064pub struct CommissionRates {
1065 #[serde(rename = "finalizationCommission")]
1067 pub finalization: AmountFraction,
1068 #[serde(rename = "bakingCommission")]
1070 pub baking: AmountFraction,
1071 #[serde(rename = "transactionCommission")]
1073 pub transaction: AmountFraction,
1074}
1075
1076#[derive(Serialize, SerdeSerialize, SerdeDeserialize, Debug, Clone)]
1077pub struct CommissionRanges {
1079 #[serde(rename = "finalizationCommissionRange")]
1081 pub finalization: InclusiveRange<AmountFraction>,
1082 #[serde(rename = "bakingCommissionRange")]
1084 pub baking: InclusiveRange<AmountFraction>,
1085 #[serde(rename = "transactionCommissionRange")]
1087 pub transaction: InclusiveRange<AmountFraction>,
1088}
1089
1090#[derive(Debug, Copy, Clone, SerdeSerialize, SerdeDeserialize, Eq, PartialEq)]
1091pub struct InclusiveRange<T> {
1092 pub min: T,
1093 pub max: T,
1094}
1095
1096impl<T: Serial> Serial for InclusiveRange<T> {
1097 fn serial<B: Buffer>(&self, out: &mut B) {
1098 self.min.serial(out);
1099 self.max.serial(out)
1100 }
1101}
1102
1103impl<T: Deserial + Ord> Deserial for InclusiveRange<T> {
1104 fn deserial<R: ReadBytesExt>(source: &mut R) -> ParseResult<Self> {
1105 let min = source.get()?;
1106 let max = source.get()?;
1107 anyhow::ensure!(min <= max, "Invalid range.");
1108 Ok(Self { min, max })
1109 }
1110}
1111
1112impl<T: Ord> InclusiveRange<T> {
1113 pub fn contains(&self, x: &T) -> bool {
1114 &self.min <= x && x <= &self.max
1115 }
1116}
1117
1118#[derive(SerdeSerialize, SerdeDeserialize, Serial, Debug, Clone, Copy, Eq, PartialEq)]
1119#[serde(try_from = "leverage_factor_json::LeverageFactorRaw")]
1120pub struct LeverageFactor {
1123 #[serde(deserialize_with = "crate::internal::deserialize_non_default::deserialize")]
1124 pub numerator: u64,
1125 #[serde(deserialize_with = "crate::internal::deserialize_non_default::deserialize")]
1126 pub denominator: u64,
1127}
1128
1129impl LeverageFactor {
1130 pub fn new_integral(factor: u64) -> Self {
1132 Self {
1133 numerator: factor,
1134 denominator: 1,
1135 }
1136 }
1137
1138 pub fn new(numerator: u64, denominator: u64) -> Option<Self> {
1141 if numerator >= denominator
1142 && denominator != 0
1143 && num::integer::gcd(numerator, denominator) == 1
1144 {
1145 Some(Self {
1146 numerator,
1147 denominator,
1148 })
1149 } else {
1150 None
1151 }
1152 }
1153}
1154
1155mod leverage_factor_json {
1158 #[derive(super::SerdeDeserialize)]
1159 pub struct LeverageFactorRaw {
1160 pub numerator: u64,
1161 pub denominator: u64,
1162 }
1163
1164 impl std::convert::TryFrom<LeverageFactorRaw> for super::LeverageFactor {
1165 type Error = anyhow::Error;
1166
1167 fn try_from(value: LeverageFactorRaw) -> Result<Self, Self::Error> {
1168 let numerator = value.numerator;
1169 let denominator = value.denominator;
1170 super::LeverageFactor::new(numerator, denominator)
1171 .ok_or_else(|| anyhow::anyhow!("Invalid leverage factor."))
1172 }
1173 }
1174}
1175
1176impl Deserial for LeverageFactor {
1177 fn deserial<R: ReadBytesExt>(source: &mut R) -> ParseResult<Self> {
1178 let numerator = source.get()?;
1179 let denominator = source.get()?;
1180 Self::new(numerator, denominator).ok_or_else(|| anyhow::anyhow!("Invalid leverage factor."))
1181 }
1182}
1183
1184#[derive(SerdeSerialize, SerdeDeserialize, Serial, Debug, Clone)]
1185#[serde(rename_all = "camelCase")]
1186pub struct MintDistributionV0 {
1188 pub mint_per_slot: MintRate,
1190 pub baking_reward: AmountFraction,
1192 pub finalization_reward: AmountFraction,
1194}
1195
1196#[derive(SerdeSerialize, SerdeDeserialize, Serial, Debug, Clone)]
1197#[serde(rename_all = "camelCase")]
1198pub struct MintDistributionV1 {
1200 pub baking_reward: AmountFraction,
1202 pub finalization_reward: AmountFraction,
1204}
1205
1206impl Deserial for MintDistributionV0 {
1207 fn deserial<R: ReadBytesExt>(source: &mut R) -> ParseResult<Self> {
1208 let mint_per_slot = source.get()?;
1209 let baking_reward: AmountFraction = source.get()?;
1210 let finalization_reward: AmountFraction = source.get()?;
1211 anyhow::ensure!(
1212 (baking_reward + finalization_reward).is_some(),
1213 "Reward fractions exceed 100%."
1214 );
1215 Ok(Self {
1216 mint_per_slot,
1217 baking_reward,
1218 finalization_reward,
1219 })
1220 }
1221}
1222
1223impl Deserial for MintDistributionV1 {
1224 fn deserial<R: ReadBytesExt>(source: &mut R) -> ParseResult<Self> {
1225 let baking_reward: AmountFraction = source.get()?;
1226 let finalization_reward: AmountFraction = source.get()?;
1227 anyhow::ensure!(
1228 (baking_reward + finalization_reward).is_some(),
1229 "Reward fractions exceed 100%."
1230 );
1231 Ok(Self {
1232 baking_reward,
1233 finalization_reward,
1234 })
1235 }
1236}
1237
1238#[derive(Debug, Serialize, Clone, Copy, Eq, PartialEq)]
1239pub struct MintRate {
1250 pub mantissa: u32,
1251 pub exponent: u8,
1252}
1253
1254#[derive(
1255 Default,
1256 Debug,
1257 Display,
1258 Clone,
1259 Copy,
1260 SerdeSerialize,
1261 SerdeDeserialize,
1262 Serialize,
1263 PartialEq,
1264 Eq,
1265 PartialOrd,
1266 Ord,
1267 Into,
1268 FromStr,
1269)]
1270#[serde(transparent)]
1271pub struct AmountFraction {
1275 pub(crate) parts_per_hundred_thousands: PartsPerHundredThousands,
1276}
1277
1278impl AmountFraction {
1279 pub fn new(parts: u32) -> Option<Self> {
1282 let parts_per_hundred_thousands = PartsPerHundredThousands::new(parts)?;
1283 Some(Self {
1284 parts_per_hundred_thousands,
1285 })
1286 }
1287
1288 pub fn new_unchecked(parts: u32) -> Self {
1291 Self {
1292 parts_per_hundred_thousands: PartsPerHundredThousands::new_unchecked(parts),
1293 }
1294 }
1295}
1296
1297#[repr(transparent)]
1298#[derive(
1299 Debug, Clone, Copy, SerdeSerialize, SerdeDeserialize, Serialize, FromStr, Eq, PartialEq,
1300)]
1301#[serde(transparent)]
1302pub struct CapitalBound {
1305 #[serde(deserialize_with = "crate::internal::deserialize_non_default::deserialize")]
1306 pub bound: AmountFraction,
1307}
1308
1309#[repr(transparent)]
1310#[derive(SerdeSerialize, SerdeDeserialize, Serialize)]
1311#[serde(transparent)]
1312#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, FromStr, Display, From, Into)]
1313pub struct FinalizationIndex {
1315 pub index: u64,
1316}
1317
1318impl std::ops::Add for PartsPerHundredThousands {
1320 type Output = Option<Self>;
1321
1322 fn add(self, rhs: Self) -> Self::Output {
1323 let parts = self.parts.checked_add(rhs.parts)?;
1324 if parts <= 100_000 {
1325 Some(PartsPerHundredThousands { parts })
1326 } else {
1327 None
1328 }
1329 }
1330}
1331
1332impl std::ops::Add for AmountFraction {
1334 type Output = Option<Self>;
1335
1336 fn add(self, rhs: Self) -> Self::Output {
1337 let parts_per_hundred_thousands =
1338 (self.parts_per_hundred_thousands + rhs.parts_per_hundred_thousands)?;
1339 Some(AmountFraction {
1340 parts_per_hundred_thousands,
1341 })
1342 }
1343}
1344
1345impl SerdeSerialize for PartsPerHundredThousands {
1346 fn serialize<S: serde::Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
1347 let decimal = rust_decimal::Decimal::try_new(self.parts.into(), 5)
1348 .map_err(serde::ser::Error::custom)?;
1349 SerdeSerialize::serialize(&decimal, ser)
1350 }
1351}
1352
1353#[derive(Clone, PartialEq, Debug, Error)]
1354pub enum ConvertPartsPerHundredThousandsError {
1357 #[error("Parts per thousand should not have more than 5 decimals.")]
1358 TooManyDecimals,
1359 #[error("Parts per thousand should not be negative.")]
1360 Negative,
1361 #[error("Parts per thousand out of bounds.")]
1362 OutOfBounds,
1363 #[error("Scale out of bounds.")]
1364 ScaleError {
1365 #[from]
1366 inner: rust_decimal::Error,
1367 },
1368}
1369
1370impl TryFrom<rust_decimal::Decimal> for PartsPerHundredThousands {
1371 type Error = ConvertPartsPerHundredThousandsError;
1372
1373 fn try_from(value: rust_decimal::Decimal) -> Result<Self, Self::Error> {
1374 let mut f = value;
1375 f.normalize_assign();
1376 if f.scale() > 5 {
1377 return Err(ConvertPartsPerHundredThousandsError::TooManyDecimals);
1378 }
1379 if !f.is_sign_positive() && !f.is_zero() {
1380 return Err(ConvertPartsPerHundredThousandsError::Negative);
1381 }
1382 f.rescale(5);
1383 if f.mantissa() > 100_000 {
1384 return Err(ConvertPartsPerHundredThousandsError::OutOfBounds);
1385 }
1386 Ok(PartsPerHundredThousands {
1387 parts: f.mantissa() as u32,
1388 })
1389 }
1390}
1391
1392impl FromStr for PartsPerHundredThousands {
1393 type Err = ConvertPartsPerHundredThousandsError;
1394
1395 fn from_str(s: &str) -> Result<Self, Self::Err> {
1396 let decimal: rust_decimal::Decimal = s.parse()?;
1397 Self::try_from(decimal)
1398 }
1399}
1400
1401impl<'de> SerdeDeserialize<'de> for PartsPerHundredThousands {
1402 fn deserialize<D: serde::Deserializer<'de>>(des: D) -> Result<Self, D::Error> {
1403 let f: rust_decimal::Decimal =
1404 SerdeDeserialize::deserialize(des).map_err(serde::de::Error::custom)?;
1405 let parts = PartsPerHundredThousands::try_from(f).map_err(serde::de::Error::custom)?;
1406 Ok(parts)
1407 }
1408}
1409
1410impl SerdeSerialize for MintRate {
1411 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1412 where
1413 S: serde::Serializer,
1414 {
1415 let x = rust_decimal::Decimal::try_new(self.mantissa.into(), self.exponent.into())
1416 .map_err(serde::ser::Error::custom)?;
1417 SerdeSerialize::serialize(&x, serializer)
1418 }
1419}
1420
1421impl FromStr for MintRate {
1422 type Err = anyhow::Error;
1423
1424 fn from_str(s: &str) -> Result<Self, Self::Err> {
1425 let f: rust_decimal::Decimal = s.parse()?;
1426 f.try_into()
1427 }
1428}
1429
1430impl TryFrom<rust_decimal::Decimal> for MintRate {
1431 type Error = anyhow::Error;
1432
1433 fn try_from(mut value: rust_decimal::Decimal) -> Result<Self, Self::Error> {
1434 value.normalize_assign();
1437 if let Ok(exponent) = u8::try_from(value.scale()) {
1438 if let Ok(mantissa) = u32::try_from(value.mantissa()) {
1439 Ok(MintRate { mantissa, exponent })
1440 } else {
1441 anyhow::bail!("Unsupported mantissa range for MintRate.",);
1442 }
1443 } else {
1444 anyhow::bail!("Unsupported exponent range for MintRate.");
1445 }
1446 }
1447}
1448
1449impl<'de> SerdeDeserialize<'de> for MintRate {
1450 fn deserialize<D>(des: D) -> Result<Self, D::Error>
1451 where
1452 D: serde::Deserializer<'de>,
1453 {
1454 let f: rust_decimal::Decimal = SerdeDeserialize::deserialize(des)?;
1455 MintRate::try_from(f).map_err(serde::de::Error::custom)
1456 }
1457}
1458
1459#[cfg(test)]
1460mod tests {
1461 use super::*;
1462 #[test]
1463 fn test_parts_0() {
1464 assert_eq!(
1465 Ok(PartsPerHundredThousands::new_unchecked(12345)),
1466 "0.12345".parse(),
1467 "Case 1."
1468 );
1469 assert_eq!(
1470 Ok(PartsPerHundredThousands::new_unchecked(12345)),
1471 "0.123450".parse(),
1472 "Case 2."
1473 );
1474 assert_eq!(
1475 Ok(PartsPerHundredThousands::new_unchecked(12300)),
1476 "0.123".parse(),
1477 "Case 3."
1478 );
1479 assert_eq!(
1480 Ok(PartsPerHundredThousands::new_unchecked(12300)),
1481 "0.123000".parse(),
1482 "Case 4."
1483 );
1484 assert!("0.123456".parse::<PartsPerHundredThousands>().is_err());
1485 }
1486
1487 #[test]
1488 fn test_parts_json() {
1489 assert_eq!(
1490 PartsPerHundredThousands::new_unchecked(12345),
1491 serde_json::from_str("0.12345").unwrap(),
1492 "Case 1."
1493 );
1494 assert_eq!(
1495 PartsPerHundredThousands::new_unchecked(12345),
1496 serde_json::from_str("0.123450").unwrap(),
1497 "Case 2."
1498 );
1499 assert_eq!(
1500 PartsPerHundredThousands::new_unchecked(12300),
1501 serde_json::from_str("0.123").unwrap(),
1502 "Case 3."
1503 );
1504 assert_eq!(
1505 PartsPerHundredThousands::new_unchecked(12300),
1506 serde_json::from_str("0.123000").unwrap(),
1507 "Case 4."
1508 );
1509 assert!(serde_json::from_str::<PartsPerHundredThousands>("0.123456").is_err());
1510 }
1511}