1use super::{
5 generated::{self, *},
6 upward::Upward,
7 Require,
8};
9use crate::types::{
10 chain_parameters,
11 queries::{ConcordiumBFTDetails, ProtocolVersionInt},
12 AccountReleaseSchedule, ActiveBakerPoolStatus,
13};
14use chrono::TimeZone;
15use concordium_base::{
16 base,
17 common::{Deserial, Versioned, VERSION_0},
18 id::{
19 constants::{ArCurve, AttributeKind, IpPairing},
20 types::{
21 AccountCredentialWithoutProofs, CredentialDeploymentValues,
22 InitialCredentialDeploymentValues,
23 },
24 },
25 smart_contracts::WasmVersionInt,
26 updates,
27};
28use cooldown::CooldownStatus;
29use std::collections::{BTreeMap, BTreeSet};
30
31fn consume<A: Deserial>(bytes: &[u8]) -> Result<A, tonic::Status> {
32 let mut cursor = std::io::Cursor::new(bytes);
33 let res = A::deserial(&mut cursor);
34 match res {
35 Ok(v) if cursor.position() == bytes.len() as u64 => Ok(v),
36 Err(e) => Err(tonic::Status::internal(format!(
37 "Could not deserialize response: {}",
38 e
39 ))),
40 Ok(_) => Err(tonic::Status::internal(
41 "Could not deserialize response: trailing bytes",
42 )),
43 }
44}
45
46fn protocol_version_int_from_enum(tag_number: i32) -> Result<ProtocolVersionInt, tonic::Status> {
49 if tag_number < 0 {
50 Err(tonic::Status::internal(format!(
51 "Invalid protocol version: {tag_number}"
52 )))
53 } else {
54 Ok(ProtocolVersionInt(tag_number as u64 + 1))
55 }
56}
57
58impl TryFrom<AccountAddress> for super::AccountAddress {
59 type Error = tonic::Status;
60
61 fn try_from(value: AccountAddress) -> Result<Self, Self::Error> {
62 match value.value.try_into() {
63 Ok(addr) => Ok(Self(addr)),
64 Err(_) => Err(tonic::Status::internal(
65 "Unexpected account address format.",
66 )),
67 }
68 }
69}
70
71impl From<super::ContractAddress> for ContractAddress {
72 fn from(value: super::ContractAddress) -> Self {
73 Self {
74 index: value.index,
75 subindex: value.subindex,
76 }
77 }
78}
79
80impl TryFrom<Address> for super::types::Address {
81 type Error = tonic::Status;
82
83 fn try_from(value: Address) -> Result<Self, Self::Error> {
84 match value.r#type.require()? {
85 address::Type::Account(acc) => Ok(Self::Account(acc.try_into()?)),
86 address::Type::Contract(contr) => Ok(Self::Contract(contr.into())),
87 }
88 }
89}
90
91impl TryFrom<ModuleRef> for super::ModuleReference {
92 type Error = tonic::Status;
93
94 fn try_from(value: ModuleRef) -> Result<Self, Self::Error> {
95 match value.value.try_into() {
96 Ok(mod_ref) => Ok(Self::new(mod_ref)),
97 Err(_) => Err(tonic::Status::internal(
98 "Unexpected module reference format.",
99 )),
100 }
101 }
102}
103
104impl From<ContractAddress> for super::ContractAddress {
105 fn from(value: ContractAddress) -> Self {
106 super::ContractAddress::new(value.index, value.subindex)
107 }
108}
109
110impl From<Slot> for super::types::Slot {
111 fn from(value: Slot) -> Self {
112 super::types::Slot { slot: value.value }
113 }
114}
115
116impl TryFrom<VersionedModuleSource> for super::types::smart_contracts::WasmModule {
117 type Error = tonic::Status;
118
119 fn try_from(versioned_module: VersionedModuleSource) -> Result<Self, Self::Error> {
120 use super::types::smart_contracts::WasmVersion;
121 let module = match versioned_module.module.require()? {
122 versioned_module_source::Module::V0(versioned_module_source::ModuleSourceV0 {
123 value,
124 }) => super::types::smart_contracts::WasmModule {
125 version: WasmVersion::V0,
126 source: value.into(),
127 },
128 versioned_module_source::Module::V1(versioned_module_source::ModuleSourceV1 {
129 value,
130 }) => super::types::smart_contracts::WasmModule {
131 version: WasmVersion::V1,
132 source: value.into(),
133 },
134 };
135 Ok(module)
136 }
137}
138
139impl TryFrom<Parameter> for super::types::smart_contracts::OwnedParameter {
140 type Error = tonic::Status;
141
142 fn try_from(value: Parameter) -> Result<Self, Self::Error> {
143 Self::try_from(value.value).map_err(
144 |e: concordium_base::smart_contracts::ExceedsParameterSize| {
145 tonic::Status::invalid_argument(e.to_string())
146 },
147 )
148 }
149}
150
151impl TryFrom<InstanceInfo> for super::InstanceInfo {
152 type Error = tonic::Status;
153
154 fn try_from(value: InstanceInfo) -> Result<Self, Self::Error> {
155 match value.version.require()? {
156 instance_info::Version::V0(v0) => Ok(Self::V0 {
157 model: v0.model.require()?.value,
158 owner: v0.owner.require()?.try_into()?,
159 amount: v0.amount.require()?.into(),
160 methods: v0
161 .methods
162 .into_iter()
163 .map(TryFrom::try_from)
164 .collect::<Result<_, tonic::Status>>()?,
165 name: v0.name.require()?.try_into()?,
166 source_module: v0.source_module.require()?.try_into()?,
167 }),
168 instance_info::Version::V1(v1) => Ok(Self::V1 {
169 owner: v1.owner.require()?.try_into()?,
170 amount: v1.amount.require()?.into(),
171 methods: v1
172 .methods
173 .into_iter()
174 .map(TryFrom::try_from)
175 .collect::<Result<_, tonic::Status>>()?,
176 name: v1.name.require()?.try_into()?,
177 source_module: v1.source_module.require()?.try_into()?,
178 }),
179 }
180 }
181}
182
183impl TryFrom<ReceiveName> for concordium_base::contracts_common::OwnedReceiveName {
184 type Error = tonic::Status;
185
186 fn try_from(value: ReceiveName) -> Result<Self, Self::Error> {
187 match Self::new(value.value) {
188 Ok(rn) => Ok(rn),
189 Err(_) => Err(tonic::Status::internal("Unexpected receive name format.")),
190 }
191 }
192}
193
194impl TryFrom<InitName> for concordium_base::contracts_common::OwnedContractName {
195 type Error = tonic::Status;
196
197 fn try_from(value: InitName) -> Result<Self, Self::Error> {
198 match Self::new(value.value) {
199 Ok(cn) => Ok(cn),
200 Err(_) => Err(tonic::Status::internal("Unexpected contract name format.")),
201 }
202 }
203}
204
205impl TryFrom<BlockHash> for super::BlockHash {
206 type Error = tonic::Status;
207
208 fn try_from(value: BlockHash) -> Result<Self, Self::Error> {
209 match value.value.try_into() {
210 Ok(hash) => Ok(Self::new(hash)),
211 Err(_) => Err(tonic::Status::internal("Unexpected block hash format.")),
212 }
213 }
214}
215
216impl TryFrom<TransactionHash> for super::hashes::TransactionHash {
217 type Error = tonic::Status;
218
219 fn try_from(value: TransactionHash) -> Result<Self, Self::Error> {
220 match value.value.try_into() {
221 Ok(hash) => Ok(Self::new(hash)),
222 Err(_) => Err(tonic::Status::internal(
223 "Unexpected transaction hash format.",
224 )),
225 }
226 }
227}
228
229impl TryFrom<AccountTransactionSignHash> for super::hashes::TransactionSignHash {
230 type Error = tonic::Status;
231
232 fn try_from(value: AccountTransactionSignHash) -> Result<Self, Self::Error> {
233 match value.value.try_into() {
234 Ok(hash) => Ok(Self::new(hash)),
235 Err(_) => Err(tonic::Status::internal(
236 "Unexpected account transaction sign hash format.",
237 )),
238 }
239 }
240}
241
242impl TryFrom<Sha256Hash> for super::hashes::Hash {
243 type Error = tonic::Status;
244
245 fn try_from(value: Sha256Hash) -> Result<Self, Self::Error> {
246 match value.value.try_into() {
247 Ok(hash) => Ok(Self::new(hash)),
248 Err(_) => Err(tonic::Status::internal("Unexpected hash format.")),
249 }
250 }
251}
252
253impl TryFrom<StateHash> for super::hashes::StateHash {
254 type Error = tonic::Status;
255
256 fn try_from(value: StateHash) -> Result<Self, Self::Error> {
257 match value.value.try_into() {
258 Ok(hash) => Ok(Self::new(hash)),
259 Err(_) => Err(tonic::Status::internal("Unexpected state hash format.")),
260 }
261 }
262}
263
264impl TryFrom<LeadershipElectionNonce> for super::hashes::LeadershipElectionNonce {
265 type Error = tonic::Status;
266
267 fn try_from(value: LeadershipElectionNonce) -> Result<Self, Self::Error> {
268 match value.value.try_into() {
269 Ok(hash) => Ok(Self::new(hash)),
270 Err(_) => Err(tonic::Status::internal(
271 "Unexpected leadership election nonce format.",
272 )),
273 }
274 }
275}
276
277impl From<AbsoluteBlockHeight> for super::AbsoluteBlockHeight {
278 fn from(abh: AbsoluteBlockHeight) -> Self {
279 Self { height: abh.value }
280 }
281}
282
283impl From<BlockHeight> for super::types::BlockHeight {
284 fn from(bh: BlockHeight) -> Self {
285 Self { height: bh.value }
286 }
287}
288
289impl From<super::AbsoluteBlockHeight> for AbsoluteBlockHeight {
290 fn from(abh: super::AbsoluteBlockHeight) -> Self {
291 Self { value: abh.height }
292 }
293}
294
295impl From<super::RelativeBlockHeight> for block_hash_input::RelativeHeight {
296 fn from(relative_block_height: super::RelativeBlockHeight) -> Self {
297 Self {
298 genesis_index: Some(relative_block_height.genesis_index.into()),
299 height: Some(relative_block_height.height.into()),
300 restrict: relative_block_height.restrict,
301 }
302 }
303}
304
305impl From<super::types::BlockHeight> for BlockHeight {
306 fn from(bh: super::types::BlockHeight) -> Self {
307 Self { value: bh.height }
308 }
309}
310
311impl From<SequenceNumber> for super::types::Nonce {
312 fn from(n: SequenceNumber) -> Self {
313 Self { nonce: n.value }
314 }
315}
316
317impl From<Amount> for super::super::common::types::Amount {
318 fn from(n: Amount) -> Self {
319 Self { micro_ccd: n.value }
320 }
321}
322
323impl From<AccountIndex> for super::types::AccountIndex {
324 fn from(n: AccountIndex) -> Self {
325 Self { index: n.value }
326 }
327}
328
329impl From<super::types::AccountIndex> for AccountIndex {
330 fn from(n: super::types::AccountIndex) -> Self {
331 Self { value: n.index }
332 }
333}
334
335impl From<BakerId> for super::types::BakerId {
336 fn from(n: BakerId) -> Self {
337 Self { id: n.value.into() }
338 }
339}
340
341impl From<super::types::BakerId> for BakerId {
342 fn from(n: super::types::BakerId) -> Self {
343 Self { value: n.id.into() }
344 }
345}
346
347impl TryFrom<DelegationTarget> for super::types::DelegationTarget {
348 type Error = tonic::Status;
349
350 fn try_from(dt: DelegationTarget) -> Result<Self, Self::Error> {
351 match dt.target.require()? {
352 delegation_target::Target::Passive(_) => Ok(Self::Passive),
353 delegation_target::Target::Baker(bid) => Ok(Self::Baker {
354 baker_id: bid.into(),
355 }),
356 }
357 }
358}
359
360impl TryFrom<EncryptionKey> for crate::id::elgamal::PublicKey<ArCurve> {
361 type Error = tonic::Status;
362
363 fn try_from(value: EncryptionKey) -> Result<Self, Self::Error> {
364 consume(&value.value)
365 }
366}
367
368impl TryFrom<ar_info::ArPublicKey> for crate::id::elgamal::PublicKey<ArCurve> {
369 type Error = tonic::Status;
370
371 fn try_from(value: ar_info::ArPublicKey) -> Result<Self, Self::Error> {
372 consume(&value.value)
373 }
374}
375
376impl TryFrom<AccountThreshold> for super::types::AccountThreshold {
377 type Error = tonic::Status;
378
379 fn try_from(value: AccountThreshold) -> Result<Self, Self::Error> {
380 if let Ok(Ok(v)) = u8::try_from(value.value).map(Self::try_from) {
381 Ok(v)
382 } else {
383 Err(tonic::Status::internal("Unexpected account threshold."))
384 }
385 }
386}
387
388impl TryFrom<EncryptedAmount> for crate::encrypted_transfers::types::EncryptedAmount<ArCurve> {
389 type Error = tonic::Status;
390
391 fn try_from(value: EncryptedAmount) -> Result<Self, Self::Error> {
392 consume(&value.value)
393 }
394}
395
396impl TryFrom<BakerElectionVerifyKey> for super::types::BakerElectionVerifyKey {
397 type Error = tonic::Status;
398
399 fn try_from(value: BakerElectionVerifyKey) -> Result<Self, Self::Error> {
400 consume(&value.value)
401 }
402}
403
404impl TryFrom<BakerSignatureVerifyKey> for super::types::BakerSignatureVerifyKey {
405 type Error = tonic::Status;
406
407 fn try_from(value: BakerSignatureVerifyKey) -> Result<Self, Self::Error> {
408 consume(&value.value)
409 }
410}
411
412impl TryFrom<BakerAggregationVerifyKey> for super::types::BakerAggregationVerifyKey {
413 type Error = tonic::Status;
414
415 fn try_from(value: BakerAggregationVerifyKey) -> Result<Self, Self::Error> {
416 consume(&value.value)
417 }
418}
419
420impl TryFrom<EncryptedBalance> for super::types::AccountEncryptedAmount {
421 type Error = tonic::Status;
422
423 fn try_from(value: EncryptedBalance) -> Result<Self, Self::Error> {
424 let self_amount = value.self_amount.require()?.try_into()?;
425 let start_index = value.start_index;
426 let aggregated_amount = match (value.aggregated_amount, value.num_aggregated) {
427 (Some(aa), Some(si)) => Some((aa.try_into()?, si)),
428 (None, None) => None,
429 _ => {
430 return Err(tonic::Status::internal(
431 "Unexpected response for 'EncryptedBalance'.",
432 ))
433 }
434 };
435 let incoming_amounts = value
436 .incoming_amounts
437 .into_iter()
438 .map(TryFrom::try_from)
439 .collect::<Result<_, tonic::Status>>()?;
440 Ok(Self {
441 self_amount,
442 start_index,
443 aggregated_amount,
444 incoming_amounts,
445 })
446 }
447}
448
449impl TryFrom<Duration> for chrono::Duration {
450 type Error = tonic::Status;
451
452 fn try_from(value: Duration) -> Result<Self, Self::Error> {
453 chrono::TimeDelta::try_milliseconds(value.value as i64).ok_or_else(|| {
454 tonic::Status::internal("Unexpected response for 'Duration': Duration out of bounds.")
455 })
456 }
457}
458
459impl From<Duration> for super::types::SlotDuration {
460 fn from(value: Duration) -> Self {
461 super::types::SlotDuration {
462 millis: value.value,
463 }
464 }
465}
466
467impl From<Duration> for concordium_base::contracts_common::Duration {
468 fn from(value: Duration) -> Self {
469 concordium_base::contracts_common::Duration::from_millis(value.value)
470 }
471}
472
473impl From<GenesisIndex> for super::types::GenesisIndex {
474 fn from(value: GenesisIndex) -> Self {
475 value.value.into()
476 }
477}
478
479impl From<super::types::GenesisIndex> for GenesisIndex {
480 fn from(value: super::types::GenesisIndex) -> Self {
481 GenesisIndex {
482 value: value.into(),
483 }
484 }
485}
486
487impl From<ProtocolVersion> for super::types::ProtocolVersion {
488 fn from(value: ProtocolVersion) -> Self {
489 match value {
490 ProtocolVersion::ProtocolVersion1 => super::types::ProtocolVersion::P1,
491 ProtocolVersion::ProtocolVersion2 => super::types::ProtocolVersion::P2,
492 ProtocolVersion::ProtocolVersion3 => super::types::ProtocolVersion::P3,
493 ProtocolVersion::ProtocolVersion4 => super::types::ProtocolVersion::P4,
494 ProtocolVersion::ProtocolVersion5 => super::types::ProtocolVersion::P5,
495 ProtocolVersion::ProtocolVersion6 => super::types::ProtocolVersion::P6,
496 ProtocolVersion::ProtocolVersion7 => super::types::ProtocolVersion::P7,
497 ProtocolVersion::ProtocolVersion8 => super::types::ProtocolVersion::P8,
498 ProtocolVersion::ProtocolVersion9 => super::types::ProtocolVersion::P9,
499 }
500 }
501}
502
503impl From<super::types::ProtocolVersion> for ProtocolVersion {
504 fn from(value: super::types::ProtocolVersion) -> Self {
505 match value {
506 super::types::ProtocolVersion::P1 => ProtocolVersion::ProtocolVersion1,
507 super::types::ProtocolVersion::P2 => ProtocolVersion::ProtocolVersion2,
508 super::types::ProtocolVersion::P3 => ProtocolVersion::ProtocolVersion3,
509 super::types::ProtocolVersion::P4 => ProtocolVersion::ProtocolVersion4,
510 super::types::ProtocolVersion::P5 => ProtocolVersion::ProtocolVersion5,
511 super::types::ProtocolVersion::P6 => ProtocolVersion::ProtocolVersion6,
512 super::types::ProtocolVersion::P7 => ProtocolVersion::ProtocolVersion7,
513 super::types::ProtocolVersion::P8 => ProtocolVersion::ProtocolVersion8,
514 super::types::ProtocolVersion::P9 => ProtocolVersion::ProtocolVersion9,
515 }
516 }
517}
518
519impl TryFrom<StakePendingChange> for super::types::StakePendingChange {
520 type Error = tonic::Status;
521
522 fn try_from(value: StakePendingChange) -> Result<Self, Self::Error> {
523 match value.change.require()? {
524 stake_pending_change::Change::Reduce(rs) => Ok(Self::ReduceStake {
525 new_stake: rs.new_stake.require()?.into(),
526 effective_time: rs.effective_time.require()?.try_into()?,
527 }),
528 stake_pending_change::Change::Remove(rs) => {
529 let effective_time = rs.try_into()?;
530 Ok(Self::RemoveStake { effective_time })
531 }
532 }
533 }
534}
535
536impl TryFrom<BakerInfo> for super::types::BakerInfo {
537 type Error = tonic::Status;
538
539 fn try_from(value: BakerInfo) -> Result<Self, Self::Error> {
540 Ok(Self {
541 baker_id: value.baker_id.require()?.into(),
542 baker_election_verify_key: value.election_key.require()?.try_into()?,
543 baker_signature_verify_key: value.signature_key.require()?.try_into()?,
544 baker_aggregation_verify_key: value.aggregation_key.require()?.try_into()?,
545 })
546 }
547}
548
549impl From<OpenStatus> for super::types::OpenStatus {
550 fn from(os: OpenStatus) -> Self {
551 match os {
552 OpenStatus::OpenForAll => Self::OpenForAll,
553 OpenStatus::ClosedForNew => Self::ClosedForNew,
554 OpenStatus::ClosedForAll => Self::ClosedForAll,
555 }
556 }
557}
558
559impl From<AmountFraction> for super::types::AmountFraction {
560 fn from(af: AmountFraction) -> Self {
561 Self::new_unchecked(af.parts_per_hundred_thousand)
562 }
563}
564
565impl From<AmountFraction> for super::types::PartsPerHundredThousands {
566 fn from(af: AmountFraction) -> Self {
567 Self::new_unchecked(af.parts_per_hundred_thousand)
568 }
569}
570
571impl TryFrom<CommissionRates> for super::types::CommissionRates {
572 type Error = tonic::Status;
573
574 fn try_from(value: CommissionRates) -> Result<Self, Self::Error> {
575 Ok(Self {
576 finalization: value.finalization.require()?.into(),
577 baking: value.baking.require()?.into(),
578 transaction: value.transaction.require()?.into(),
579 })
580 }
581}
582
583impl TryFrom<BakerPoolInfo> for super::types::BakerPoolInfo {
584 type Error = tonic::Status;
585
586 fn try_from(value: BakerPoolInfo) -> Result<Self, Self::Error> {
587 let open_status = Upward::from(OpenStatus::try_from(value.open_status).ok())
588 .map(super::types::OpenStatus::from);
589 let metadata_url = value
590 .url
591 .try_into()
592 .map_err(|_| tonic::Status::internal("Unexpected metadata length."))?;
593 let commission_rates = value.commission_rates.require()?.try_into()?;
594 Ok(Self {
595 open_status,
596 metadata_url,
597 commission_rates,
598 })
599 }
600}
601
602impl TryFrom<account_staking_info::StakingInfo> for super::types::AccountStakingInfo {
603 type Error = tonic::Status;
604
605 fn try_from(value: account_staking_info::StakingInfo) -> Result<Self, Self::Error> {
606 match value {
607 account_staking_info::StakingInfo::Baker(bsi) => {
608 let staked_amount = bsi.staked_amount.require()?.into();
609 let restake_earnings = bsi.restake_earnings;
610 let baker_info = bsi.baker_info.require()?.try_into()?;
611 let pending_change = match bsi.pending_change {
612 None => None,
613 Some(pc) => Some(pc.try_into()?),
614 };
615 let pool_info = match bsi.pool_info {
616 None => None,
617 Some(bi) => Some(bi.try_into()?),
618 };
619 let is_suspended = bsi.is_suspended;
620 Ok(Self::Baker {
621 staked_amount,
622 restake_earnings,
623 baker_info: Box::new(baker_info),
624 pending_change,
625 pool_info,
626 is_suspended,
627 })
628 }
629 account_staking_info::StakingInfo::Delegator(dsi) => {
630 let staked_amount = dsi.staked_amount.require()?.into();
631 let restake_earnings = dsi.restake_earnings;
632 let delegation_target = dsi.target.require()?.try_into()?;
633 let pending_change = match dsi.pending_change {
634 None => None,
635 Some(pc) => Some(pc.try_into()?),
636 };
637 Ok(Self::Delegated {
638 staked_amount,
639 restake_earnings,
640 delegation_target,
641 pending_change,
642 })
643 }
644 }
645 }
646}
647
648impl TryFrom<Release> for super::types::Release {
649 type Error = tonic::Status;
650
651 fn try_from(value: Release) -> Result<Self, Self::Error> {
652 Ok(Self {
653 timestamp: value.timestamp.require()?.try_into()?,
654 amount: value.amount.require()?.into(),
655 transactions: value
656 .transactions
657 .into_iter()
658 .map(TryFrom::try_from)
659 .collect::<Result<_, tonic::Status>>()?,
660 })
661 }
662}
663
664impl TryFrom<ReleaseSchedule> for super::types::AccountReleaseSchedule {
665 type Error = tonic::Status;
666
667 fn try_from(value: ReleaseSchedule) -> Result<Self, Self::Error> {
668 Ok(Self {
669 total: value.total.require()?.into(),
670 schedule: value
671 .schedules
672 .into_iter()
673 .map(TryFrom::try_from)
674 .collect::<Result<_, tonic::Status>>()?,
675 })
676 }
677}
678
679impl TryFrom<AccountVerifyKey> for Upward<crate::id::types::VerifyKey> {
680 type Error = tonic::Status;
681
682 fn try_from(value: AccountVerifyKey) -> Result<Self, Self::Error> {
683 let Some(key) = value.key else {
684 return Ok(Upward::Unknown(()));
685 };
686 match key {
687 account_verify_key::Key::Ed25519Key(v) => Ok(Upward::Known(
688 crate::id::types::VerifyKey::Ed25519VerifyKey(consume(&v)?),
689 )),
690 }
691 }
692}
693
694impl TryFrom<ip_info::IpCdiVerifyKey> for ed25519_dalek::VerifyingKey {
695 type Error = tonic::Status;
696
697 fn try_from(value: ip_info::IpCdiVerifyKey) -> Result<Self, Self::Error> {
698 consume(&value.value)
699 }
700}
701
702impl TryFrom<ip_info::IpVerifyKey> for crate::id::ps_sig::PublicKey<IpPairing> {
703 type Error = tonic::Status;
704
705 fn try_from(value: ip_info::IpVerifyKey) -> Result<Self, Self::Error> {
706 consume(&value.value)
707 }
708}
709
710impl TryFrom<UpdatePublicKey> for super::types::UpdatePublicKey {
711 type Error = tonic::Status;
712
713 fn try_from(value: UpdatePublicKey) -> Result<Self, Self::Error> {
714 Ok(super::types::UpdatePublicKey {
715 public: crate::id::types::VerifyKey::Ed25519VerifyKey(consume(&value.value)?),
716 })
717 }
718}
719
720impl TryFrom<SignatureThreshold> for crate::id::types::SignatureThreshold {
721 type Error = tonic::Status;
722
723 fn try_from(value: SignatureThreshold) -> Result<Self, Self::Error> {
724 if let Ok(v) = u8::try_from(value.value) {
725 crate::id::types::SignatureThreshold::try_from(v)
726 .map_err(|_| tonic::Status::internal("Unexpected zero signature threshold."))
727 } else {
728 Err(tonic::Status::internal("Unexpected signature threshold."))
729 }
730 }
731}
732
733impl TryFrom<ArThreshold> for crate::id::secret_sharing::Threshold {
734 type Error = tonic::Status;
735
736 fn try_from(value: ArThreshold) -> Result<Self, Self::Error> {
737 if let Ok(v) = u8::try_from(value.value) {
738 if v == 0 {
739 Err(tonic::Status::internal("Unexpected zero AR threshold."))
740 } else {
741 Ok(Self(v))
742 }
743 } else {
744 Err(tonic::Status::internal("Unexpected AR threshold."))
745 }
746 }
747}
748
749impl TryFrom<CredentialPublicKeys> for Upward<crate::id::types::CredentialPublicKeys> {
750 type Error = tonic::Status;
751
752 fn try_from(value: CredentialPublicKeys) -> Result<Self, Self::Error> {
753 let mut keys = BTreeMap::new();
754 for (index, key) in value.keys {
755 let k = u8::try_from(index)
756 .map_err(|_| tonic::Status::internal("Unexpected key index."))?
757 .into();
758
759 let Upward::Known(v) = key.try_into()? else {
760 return Ok(Upward::Unknown(()));
761 };
762 keys.insert(k, v);
763 }
764 Ok(Upward::Known(crate::id::types::CredentialPublicKeys {
765 keys,
766 threshold: value.threshold.require()?.try_into()?,
767 }))
768 }
769}
770
771impl TryFrom<CredentialRegistrationId> for super::types::CredentialRegistrationID {
772 type Error = tonic::Status;
773
774 fn try_from(value: CredentialRegistrationId) -> Result<Self, Self::Error> {
775 consume(&value.value)
776 }
777}
778
779impl TryFrom<CredentialRegistrationId> for ArCurve {
780 type Error = tonic::Status;
781
782 fn try_from(value: CredentialRegistrationId) -> Result<Self, Self::Error> {
783 consume(&value.value)
784 }
785}
786
787impl From<IdentityProviderIdentity> for crate::id::types::IpIdentity {
788 fn from(v: IdentityProviderIdentity) -> Self {
789 Self(v.value)
790 }
791}
792
793impl TryFrom<YearMonth> for crate::id::types::YearMonth {
794 type Error = tonic::Status;
795
796 fn try_from(value: YearMonth) -> Result<Self, Self::Error> {
797 Ok(Self {
798 year: value
799 .year
800 .try_into()
801 .map_err(|_| tonic::Status::internal("Unexpected year."))?,
802 month: value
803 .month
804 .try_into()
805 .map_err(|_| tonic::Status::internal("Unexpected year."))?,
806 })
807 }
808}
809
810impl TryFrom<Policy> for crate::id::types::Policy<ArCurve, AttributeKind> {
811 type Error = tonic::Status;
812
813 fn try_from(value: Policy) -> Result<Self, Self::Error> {
814 Ok(Self {
815 valid_to: value.valid_to.require()?.try_into()?,
816 created_at: value.created_at.require()?.try_into()?,
817 policy_vec: value
818 .attributes
819 .into_iter()
820 .map(|(k, v)| {
821 let k = crate::id::types::AttributeTag(
822 k.try_into()
823 .map_err(|_| tonic::Status::internal("Unexpected attribute tag."))?,
824 );
825 let v = AttributeKind::try_new(String::from_utf8(v).map_err(|_| {
826 tonic::Status::internal("Invalid attribute value. Expected UTF8 encoding")
827 })?)
828 .map_err(|_| tonic::Status::internal("Attribute value too long."))?;
829 Ok((k, v))
830 })
831 .collect::<Result<_, tonic::Status>>()?,
832 _phantom: std::marker::PhantomData,
833 })
834 }
835}
836
837impl TryFrom<ChainArData> for crate::id::types::ChainArData<ArCurve> {
838 type Error = tonic::Status;
839
840 fn try_from(value: ChainArData) -> Result<Self, Self::Error> {
841 consume(&value.enc_id_cred_pub_share)
842 }
843}
844
845impl TryFrom<Commitment> for crate::id::pedersen_commitment::Commitment<ArCurve> {
846 type Error = tonic::Status;
847
848 fn try_from(value: Commitment) -> Result<Self, Self::Error> {
849 consume(&value.value)
850 }
851}
852
853impl TryFrom<CredentialCommitments> for crate::id::types::CredentialDeploymentCommitments<ArCurve> {
854 type Error = tonic::Status;
855
856 fn try_from(value: CredentialCommitments) -> Result<Self, Self::Error> {
857 Ok(Self {
858 cmm_prf: value.prf.require()?.try_into()?,
859 cmm_cred_counter: value.cred_counter.require()?.try_into()?,
860 cmm_max_accounts: value.max_accounts.require()?.try_into()?,
861 cmm_attributes: value
862 .attributes
863 .into_iter()
864 .map(|(k, v)| {
865 let k = crate::id::types::AttributeTag(
866 k.try_into()
867 .map_err(|_| tonic::Status::internal("Unexpected attribute tag."))?,
868 );
869 let v = v.try_into()?;
870 Ok((k, v))
871 })
872 .collect::<Result<_, tonic::Status>>()?,
873 cmm_id_cred_sec_sharing_coeff: value
874 .id_cred_sec_sharing_coeff
875 .into_iter()
876 .map(TryFrom::try_from)
877 .collect::<Result<_, tonic::Status>>()?,
878 })
879 }
880}
881
882impl TryFrom<AccountCredential> for Upward<AccountCredentialWithoutProofs<ArCurve, AttributeKind>> {
883 type Error = tonic::Status;
884
885 fn try_from(message: AccountCredential) -> Result<Self, Self::Error> {
886 let Some(values) = message.credential_values else {
887 return Ok(Upward::Unknown(()));
888 };
889 values.try_into()
890 }
891}
892
893impl TryFrom<account_credential::CredentialValues>
894 for Upward<AccountCredentialWithoutProofs<ArCurve, AttributeKind>>
895{
896 type Error = tonic::Status;
897
898 fn try_from(cred: account_credential::CredentialValues) -> Result<Self, Self::Error> {
899 match cred {
900 account_credential::CredentialValues::Initial(ic) => {
901 let Upward::Known(cred_account) = ic.keys.require()?.try_into()? else {
902 return Ok(Upward::Unknown(()));
903 };
904 let icdv = InitialCredentialDeploymentValues {
905 cred_account,
906 reg_id: ic.cred_id.require()?.try_into()?,
907 ip_identity: ic.ip_id.require()?.into(),
908 policy: ic.policy.require()?.try_into()?,
909 };
910 Ok(Upward::Known(AccountCredentialWithoutProofs::Initial {
911 icdv,
912 }))
913 }
914 account_credential::CredentialValues::Normal(nc) => {
915 let Upward::Known(cred_key_info) = nc.keys.require()?.try_into()? else {
916 return Ok(Upward::Unknown(()));
917 };
918
919 let cdv = CredentialDeploymentValues {
920 cred_key_info,
921 cred_id: nc.cred_id.require()?.try_into()?,
922 ip_identity: nc.ip_id.require()?.into(),
923 threshold: nc.ar_threshold.require()?.try_into()?,
924 ar_data: nc
925 .ar_data
926 .into_iter()
927 .map(|(k, v)| {
928 let k = k
929 .try_into()
930 .map_err(|_| tonic::Status::internal("Unexpected AR identity."))?;
931 let v = v.try_into()?;
932 Ok((k, v))
933 })
934 .collect::<Result<_, tonic::Status>>()?,
935 policy: nc.policy.require()?.try_into()?,
936 };
937 let commitments = nc.commitments.require()?.try_into()?;
938 Ok(Upward::Known(AccountCredentialWithoutProofs::Normal {
939 cdv,
940 commitments,
941 }))
942 }
943 }
944 }
945}
946
947impl From<Timestamp> for concordium_base::common::types::Timestamp {
948 fn from(value: Timestamp) -> Self {
949 value.value.into()
950 }
951}
952
953impl From<concordium_base::common::types::Timestamp> for Timestamp {
954 fn from(value: concordium_base::common::types::Timestamp) -> Self {
955 Timestamp {
956 value: value.millis,
957 }
958 }
959}
960
961impl TryFrom<Timestamp> for chrono::DateTime<chrono::Utc> {
962 type Error = tonic::Status;
963
964 fn try_from(value: Timestamp) -> Result<Self, Self::Error> {
965 let ts = chrono::Utc.timestamp_millis_opt(
966 value
967 .value
968 .try_into()
969 .map_err(|_| tonic::Status::internal("Timestamp out of range."))?,
970 );
971 ts.single()
972 .ok_or_else(|| tonic::Status::internal("Ambiguous time."))
973 }
974}
975
976impl TryFrom<DelegatorInfo> for super::types::DelegatorInfo {
977 type Error = tonic::Status;
978
979 fn try_from(delegator: DelegatorInfo) -> Result<Self, Self::Error> {
980 Ok(Self {
981 account: delegator.account.require()?.try_into()?,
982 stake: delegator.stake.require()?.into(),
983 pending_change: delegator
984 .pending_change
985 .map(TryFrom::try_from)
986 .transpose()?,
987 })
988 }
989}
990
991impl TryFrom<DelegatorRewardPeriodInfo> for super::types::DelegatorRewardPeriodInfo {
992 type Error = tonic::Status;
993
994 fn try_from(delegator: DelegatorRewardPeriodInfo) -> Result<Self, Self::Error> {
995 Ok(Self {
996 account: delegator.account.require()?.try_into()?,
997 stake: delegator.stake.require()?.into(),
998 })
999 }
1000}
1001
1002impl From<CooldownStatus> for super::types::CooldownStatus {
1003 fn from(cds: CooldownStatus) -> Self {
1004 match cds {
1005 CooldownStatus::Cooldown => Self::Cooldown,
1006 CooldownStatus::PreCooldown => Self::PreCooldown,
1007 CooldownStatus::PrePreCooldown => Self::PrePreCooldown,
1008 }
1009 }
1010}
1011
1012impl TryFrom<Cooldown> for super::types::Cooldown {
1013 type Error = tonic::Status;
1014
1015 fn try_from(cd: Cooldown) -> Result<Self, Self::Error> {
1016 Ok(Self {
1017 status: Upward::from(CooldownStatus::try_from(cd.status).ok())
1018 .map(super::types::CooldownStatus::from),
1019 end_time: cd.end_time.require()?.into(),
1020 amount: cd.amount.require()?.into(),
1021 })
1022 }
1023}
1024
1025impl TryFrom<AccountInfo> for super::types::AccountInfo {
1026 type Error = tonic::Status;
1027
1028 fn try_from(value: AccountInfo) -> Result<Self, Self::Error> {
1029 let AccountInfo {
1030 sequence_number,
1031 amount,
1032 schedule,
1033 creds,
1034 threshold,
1035 encrypted_balance,
1036 encryption_key,
1037 index,
1038 stake,
1039 address,
1040 cooldowns,
1041 available_balance,
1042 tokens,
1043 } = value;
1044 let account_nonce = sequence_number.require()?.into();
1045 let account_amount = amount.require()?.into();
1046 let account_release_schedule: AccountReleaseSchedule = schedule.require()?.try_into()?;
1047 let account_threshold = threshold.require()?.try_into()?;
1048 let account_encrypted_amount = encrypted_balance.require()?.try_into()?;
1049 let account_encryption_key = encryption_key.require()?.try_into()?;
1050 let account_index = index.require()?.into();
1051 let account_stake: Option<Upward<super::types::AccountStakingInfo>> = match stake {
1052 Some(stake) => Some(Upward::from(
1053 stake.staking_info.map(TryInto::try_into).transpose()?,
1054 )),
1055 None => None,
1056 };
1057 let account_address = address.require()?.try_into()?;
1058 let mut cds: Vec<super::types::Cooldown> = Vec::with_capacity(cooldowns.len());
1059 for cooldown in cooldowns.into_iter() {
1060 cds.push(cooldown.try_into()?)
1061 }
1062 let cooldowns = cds;
1063
1064 let available_balance = available_balance.map(|ab| ab.into()).unwrap_or_else(|| {
1072 let active_stake = if let Some(Upward::Known(staking_info)) = &account_stake {
1073 staking_info.staked_amount()
1074 } else {
1075 Default::default()
1076 };
1077
1078 let inactive_stake = cooldowns.iter().map(|cd| cd.amount).sum();
1079
1080 let staked_amount = active_stake + inactive_stake;
1081
1082 let locked_amount = Ord::max(account_release_schedule.total, staked_amount);
1085
1086 account_amount - locked_amount
1090 });
1091
1092 let tokens = tokens
1093 .into_iter()
1094 .map(|token| token.try_into())
1095 .collect::<Result<_, _>>()?;
1096 Ok(Self {
1097 account_nonce,
1098 account_amount,
1099 account_release_schedule,
1100 account_credentials: creds
1101 .into_iter()
1102 .map(|(k, v)| {
1103 let k = u8::try_from(k)
1104 .map_err(|_| tonic::Status::internal("Unexpected credential index."))?
1105 .into();
1106 let v = v.try_into()?;
1107 Ok((k, Versioned::new(VERSION_0, v)))
1108 })
1109 .collect::<Result<_, tonic::Status>>()?,
1110 account_threshold,
1111 account_encrypted_amount,
1112 account_encryption_key,
1113 account_index,
1114 account_stake,
1115 account_address,
1116 cooldowns,
1117 available_balance,
1118 tokens,
1119 })
1120 }
1121}
1122
1123impl TryFrom<BlockItemStatus> for super::types::TransactionStatus {
1124 type Error = tonic::Status;
1125
1126 fn try_from(value: BlockItemStatus) -> Result<Self, Self::Error> {
1127 match value.status.require()? {
1128 block_item_status::Status::Received(_) => Ok(super::types::TransactionStatus::Received),
1129 block_item_status::Status::Finalized(f) => {
1130 let mut summaries: BTreeMap<super::BlockHash, super::types::BlockItemSummary> =
1131 BTreeMap::new();
1132 let o = f.outcome.require()?;
1133 let k = o.block_hash.require()?.try_into()?;
1134 let v = o.outcome.require()?.try_into()?;
1135 summaries.insert(k, v);
1136 Ok(super::types::TransactionStatus::Finalized(summaries))
1137 }
1138 block_item_status::Status::Committed(cs) => {
1139 let mut summaries: BTreeMap<super::BlockHash, super::types::BlockItemSummary> =
1140 BTreeMap::new();
1141 for o in cs.outcomes {
1142 let k = o.block_hash.require()?.try_into()?;
1143 let v = o.outcome.require()?.try_into()?;
1144 summaries.insert(k, v);
1145 }
1146 Ok(super::types::TransactionStatus::Committed(summaries))
1147 }
1148 }
1149 }
1150}
1151
1152impl TryFrom<AccountTransactionPayload> for concordium_base::transactions::EncodedPayload {
1153 type Error = tonic::Status;
1154
1155 fn try_from(value: AccountTransactionPayload) -> Result<Self, Self::Error> {
1156 use concordium_base::transactions::PayloadLike;
1157 match value.payload.require()? {
1158 account_transaction_payload::Payload::RawPayload(rp) => {
1159 Self::try_from(rp).map_err(|_| {
1160 tonic::Status::invalid_argument("Payload size exceeds maximum allowed.")
1161 })
1162 }
1163 account_transaction_payload::Payload::DeployModule(dm) => {
1164 let module = match dm.module.require()? {
1165 versioned_module_source::Module::V0(source) => {
1166 concordium_base::smart_contracts::WasmModule {
1167 version: concordium_base::smart_contracts::WasmVersion::V0,
1168 source: source.value.into(),
1169 }
1170 }
1171 versioned_module_source::Module::V1(source) => {
1172 concordium_base::smart_contracts::WasmModule {
1173 version: concordium_base::smart_contracts::WasmVersion::V1,
1174 source: source.value.into(),
1175 }
1176 }
1177 };
1178 Ok(concordium_base::transactions::Payload::DeployModule { module }.encode())
1179 }
1180 account_transaction_payload::Payload::InitContract(ic) => {
1181 let payload = concordium_base::transactions::InitContractPayload {
1182 amount: ic.amount.require()?.into(),
1183 mod_ref: ic.module_ref.require()?.try_into()?,
1184 init_name: ic.init_name.require()?.try_into()?,
1185 param: ic.parameter.require()?.try_into()?,
1186 };
1187 Ok(concordium_base::transactions::Payload::InitContract { payload }.encode())
1188 }
1189 account_transaction_payload::Payload::UpdateContract(uc) => {
1190 let payload = concordium_base::transactions::UpdateContractPayload {
1191 amount: uc.amount.require()?.into(),
1192 address: uc.address.require()?.into(),
1193 receive_name: uc.receive_name.require()?.try_into()?,
1194 message: uc.parameter.require()?.try_into()?,
1195 };
1196 Ok(concordium_base::transactions::Payload::Update { payload }.encode())
1197 }
1198 account_transaction_payload::Payload::Transfer(t) => {
1199 let payload = concordium_base::transactions::Payload::Transfer {
1200 to_address: t.receiver.require()?.try_into()?,
1201 amount: t.amount.require()?.into(),
1202 };
1203 Ok(payload.encode())
1204 }
1205 account_transaction_payload::Payload::TransferWithMemo(t) => {
1206 let payload = concordium_base::transactions::Payload::TransferWithMemo {
1207 to_address: t.receiver.require()?.try_into()?,
1208 amount: t.amount.require()?.into(),
1209 memo: t.memo.require()?.try_into()?,
1210 };
1211 Ok(payload.encode())
1212 }
1213 account_transaction_payload::Payload::RegisterData(t) => {
1214 let payload = concordium_base::transactions::Payload::RegisterData {
1215 data: t.try_into()?,
1216 };
1217 Ok(payload.encode())
1218 }
1219 }
1220 }
1221}
1222
1223impl TryFrom<Signature> for concordium_base::common::types::Signature {
1224 type Error = tonic::Status;
1225
1226 fn try_from(value: Signature) -> Result<Self, Self::Error> {
1227 if value.value.len() <= usize::from(u16::MAX) {
1228 Ok(Self { sig: value.value })
1229 } else {
1230 Err(tonic::Status::invalid_argument("Signature is too large."))
1231 }
1232 }
1233}
1234
1235impl TryFrom<AccountTransactionSignature> for concordium_base::common::types::TransactionSignature {
1236 type Error = tonic::Status;
1237
1238 fn try_from(value: AccountTransactionSignature) -> Result<Self, Self::Error> {
1239 let signatures = value
1240 .signatures
1241 .into_iter()
1242 .map(|(ci, m)| {
1243 let ci = u8::try_from(ci)
1244 .map_err(|_| tonic::Status::invalid_argument("Invalid credential index."))?;
1245 let cred_sigs = m
1246 .signatures
1247 .into_iter()
1248 .map(|(ki, sig)| {
1249 let ki = u8::try_from(ki)
1250 .map_err(|_| tonic::Status::invalid_argument("Invalid key index."))?;
1251 let sig = sig.try_into()?;
1252 Ok::<_, tonic::Status>((ki.into(), sig))
1253 })
1254 .collect::<Result<_, _>>()?;
1255 Ok::<_, tonic::Status>((ci.into(), cred_sigs))
1256 })
1257 .collect::<Result<_, _>>()?;
1258 Ok(Self { signatures })
1259 }
1260}
1261
1262impl TryFrom<AccountTransaction>
1263 for concordium_base::transactions::AccountTransaction<
1264 concordium_base::transactions::EncodedPayload,
1265 >
1266{
1267 type Error = tonic::Status;
1268
1269 fn try_from(value: AccountTransaction) -> Result<Self, Self::Error> {
1270 let payload: concordium_base::transactions::EncodedPayload =
1271 value.payload.require()?.try_into()?;
1272 let payload_size = payload.size();
1273 let header = {
1274 let header = value.header.require()?;
1275 let sender = header.sender.require()?.try_into()?;
1276 let nonce = header.sequence_number.require()?.into();
1277 let energy_amount = header.energy_amount.require()?.into();
1278 let expiry = header.expiry.require()?.into();
1279 concordium_base::transactions::TransactionHeader {
1280 sender,
1281 nonce,
1282 energy_amount,
1283 payload_size,
1284 expiry,
1285 }
1286 };
1287 Ok(Self {
1288 signature: value.signature.require()?.try_into()?,
1289 header,
1290 payload,
1291 })
1292 }
1293}
1294
1295impl TryFrom<CredentialDeployment>
1296 for crate::id::types::AccountCredentialMessage<
1297 crate::id::constants::IpPairing,
1298 crate::id::constants::ArCurve,
1299 crate::id::constants::AttributeKind,
1300 >
1301{
1302 type Error = tonic::Status;
1303
1304 fn try_from(value: CredentialDeployment) -> Result<Self, Self::Error> {
1305 let message_expiry = value.message_expiry.require()?.into();
1306 let credential_deployment::Payload::RawPayload(data) = value.payload.require()?;
1307 let credential = consume(&data)?;
1308 Ok(Self {
1309 message_expiry,
1310 credential,
1311 })
1312 }
1313}
1314
1315impl TryFrom<SignatureMap> for concordium_base::updates::UpdateInstructionSignature {
1316 type Error = tonic::Status;
1317
1318 fn try_from(value: SignatureMap) -> Result<Self, Self::Error> {
1319 let signatures = value
1320 .signatures
1321 .into_iter()
1322 .map(|(k, sig)| {
1323 let k = u16::try_from(k)
1324 .map_err(|_| tonic::Status::invalid_argument("Update key index too large."))?;
1325 let sig = sig.try_into()?;
1326 Ok::<_, tonic::Status>((k.into(), sig))
1327 })
1328 .collect::<Result<_, _>>()?;
1329 Ok(Self { signatures })
1330 }
1331}
1332
1333impl TryFrom<UpdateInstruction> for concordium_base::updates::UpdateInstruction {
1334 type Error = tonic::Status;
1335
1336 fn try_from(value: UpdateInstruction) -> Result<Self, Self::Error> {
1337 let header = value.header.require()?;
1338 let update_instruction_payload::Payload::RawPayload(payload) =
1339 value.payload.require()?.payload.require()?;
1340 let header = concordium_base::updates::UpdateHeader {
1341 seq_number: header.sequence_number.require()?.into(),
1342 effective_time: header.effective_time.require()?.into(),
1343 timeout: header.timeout.require()?.into(),
1344 payload_size: (payload.len() as u32).into(), };
1348 let signatures: concordium_base::updates::UpdateInstructionSignature =
1349 value.signatures.require()?.try_into()?;
1350 let payload = updates::EncodedUpdatePayload::from(payload);
1351 Ok(Self {
1352 header,
1353 payload,
1354 signatures,
1355 })
1356 }
1357}
1358
1359impl TryFrom<BlockItem>
1360 for Upward<
1361 concordium_base::transactions::BlockItem<concordium_base::transactions::EncodedPayload>,
1362 >
1363{
1364 type Error = tonic::Status;
1365
1366 fn try_from(value: BlockItem) -> Result<Self, Self::Error> {
1367 if let Some(item) = value.block_item {
1368 Ok(Upward::Known(item.try_into()?))
1369 } else {
1370 Ok(Upward::Unknown(()))
1371 }
1372 }
1373}
1374
1375impl TryFrom<block_item::BlockItem>
1376 for concordium_base::transactions::BlockItem<concordium_base::transactions::EncodedPayload>
1377{
1378 type Error = tonic::Status;
1379
1380 fn try_from(item: block_item::BlockItem) -> Result<Self, Self::Error> {
1381 type Item =
1382 concordium_base::transactions::BlockItem<concordium_base::transactions::EncodedPayload>;
1383 let out = match item {
1384 block_item::BlockItem::AccountTransaction(at) => {
1385 Item::AccountTransaction(at.try_into()?)
1386 }
1387 block_item::BlockItem::CredentialDeployment(cd) => {
1388 Item::CredentialDeployment(Box::new(cd.try_into()?))
1389 }
1390 block_item::BlockItem::UpdateInstruction(ui) => Item::UpdateInstruction(ui.try_into()?),
1391 };
1392 Ok(out)
1393 }
1394}
1395
1396impl TryFrom<AccountTransactionDetails> for super::types::AccountTransactionDetails {
1397 type Error = tonic::Status;
1398
1399 fn try_from(v: AccountTransactionDetails) -> Result<Self, Self::Error> {
1400 Ok(Self {
1401 cost: v.cost.require()?.into(),
1402 sender: v.sender.require()?.try_into()?,
1403 effects: Upward::from(v.effects.map(TryFrom::try_from).transpose()?),
1404 })
1405 }
1406}
1407
1408impl TryFrom<BlockItemSummary> for super::types::BlockItemSummary {
1409 type Error = tonic::Status;
1410
1411 fn try_from(value: BlockItemSummary) -> Result<Self, Self::Error> {
1412 Ok(Self {
1413 index: value.index.require()?.into(),
1414 energy_cost: value.energy_cost.require()?.into(),
1415 hash: value.hash.require()?.try_into()?,
1416 details: Upward::from(value.details.map(TryFrom::try_from).transpose()?),
1417 })
1418 }
1419}
1420
1421impl TryFrom<block_item_summary::Details> for super::types::BlockItemSummaryDetails {
1422 type Error = tonic::Status;
1423
1424 fn try_from(value: block_item_summary::Details) -> Result<Self, Self::Error> {
1425 let out = match value {
1426 block_item_summary::Details::AccountTransaction(v) => {
1427 super::types::BlockItemSummaryDetails::AccountTransaction(v.try_into()?)
1428 }
1429 block_item_summary::Details::AccountCreation(v) => {
1430 super::types::BlockItemSummaryDetails::AccountCreation(
1431 super::types::AccountCreationDetails {
1432 credential_type: v.credential_type().into(),
1433 address: v.address.require()?.try_into()?,
1434 reg_id: v.reg_id.require()?.try_into()?,
1435 },
1436 )
1437 }
1438 block_item_summary::Details::Update(v) => {
1439 super::types::BlockItemSummaryDetails::Update(super::types::UpdateDetails {
1440 effective_time: v.effective_time.require()?.into(),
1441 payload: Upward::from(
1442 v.payload
1443 .map(super::types::UpdatePayload::try_from)
1444 .transpose()?,
1445 ),
1446 })
1447 }
1448 block_item_summary::Details::TokenCreation(v) => {
1449 super::types::BlockItemSummaryDetails::TokenCreationDetails(
1450 super::types::TokenCreationDetails {
1451 create_plt: v.create_plt.require()?.try_into()?,
1452 events: v
1453 .events
1454 .into_iter()
1455 .map(TryInto::try_into)
1456 .collect::<Result<_, tonic::Status>>()?,
1457 },
1458 )
1459 }
1460 };
1461 Ok(out)
1462 }
1463}
1464
1465impl TryFrom<ElectionDifficulty> for super::types::ElectionDifficulty {
1466 type Error = tonic::Status;
1467
1468 fn try_from(value: ElectionDifficulty) -> Result<Self, Self::Error> {
1469 Self::new(value.value.require()?.parts_per_hundred_thousand).ok_or_else(|| {
1470 tonic::Status::internal("Election difficulty more than 1, which is not allowed.")
1471 })
1472 }
1473}
1474
1475impl TryFrom<UpdatePayload> for super::types::UpdatePayload {
1476 type Error = tonic::Status;
1477
1478 fn try_from(value: UpdatePayload) -> Result<Self, Self::Error> {
1479 Ok(match value.payload.require()? {
1480 update_payload::Payload::ProtocolUpdate(v) => Self::Protocol(v.try_into()?),
1481 update_payload::Payload::ElectionDifficultyUpdate(v) => {
1482 Self::ElectionDifficulty(v.try_into()?)
1483 }
1484 update_payload::Payload::EuroPerEnergyUpdate(v) => Self::EuroPerEnergy(v.try_into()?),
1485 update_payload::Payload::MicroCcdPerEuroUpdate(v) => {
1486 Self::MicroGTUPerEuro(v.try_into()?)
1487 }
1488 update_payload::Payload::FoundationAccountUpdate(v) => {
1489 Self::FoundationAccount(v.try_into()?)
1490 }
1491 update_payload::Payload::MintDistributionUpdate(v) => {
1492 Self::MintDistribution(v.try_into()?)
1493 }
1494 update_payload::Payload::TransactionFeeDistributionUpdate(v) => {
1495 Self::TransactionFeeDistribution(v.try_into()?)
1496 }
1497 update_payload::Payload::GasRewardsUpdate(v) => Self::GASRewards(v.try_into()?),
1498 update_payload::Payload::BakerStakeThresholdUpdate(v) => {
1499 Self::BakerStakeThreshold(v.try_into()?)
1500 }
1501 update_payload::Payload::RootUpdate(v) => {
1502 Self::Root(match v.update_type.require()? {
1503 root_update::UpdateType::RootKeysUpdate(u) => {
1504 super::types::RootUpdate::RootKeysUpdate(u.try_into()?)
1505 }
1506 root_update::UpdateType::Level1KeysUpdate(u) => {
1507 super::types::RootUpdate::Level1KeysUpdate(u.try_into()?)
1508 }
1509 root_update::UpdateType::Level2KeysUpdateV0(u) => {
1510 super::types::RootUpdate::Level2KeysUpdate(Box::new(u.try_into()?))
1511 }
1512 root_update::UpdateType::Level2KeysUpdateV1(u) => {
1513 super::types::RootUpdate::Level2KeysUpdateV1(Box::new(u.try_into()?))
1514 }
1515 })
1516 }
1517 update_payload::Payload::Level1Update(v) => {
1518 Self::Level1(match v.update_type.require()? {
1519 level1_update::UpdateType::Level1KeysUpdate(u) => {
1520 super::types::Level1Update::Level1KeysUpdate(u.try_into()?)
1521 }
1522 level1_update::UpdateType::Level2KeysUpdateV0(u) => {
1523 super::types::Level1Update::Level2KeysUpdate(Box::new(u.try_into()?))
1524 }
1525 level1_update::UpdateType::Level2KeysUpdateV1(u) => {
1526 super::types::Level1Update::Level2KeysUpdateV1(Box::new(u.try_into()?))
1527 }
1528 })
1529 }
1530 update_payload::Payload::AddAnonymityRevokerUpdate(v) => {
1531 Self::AddAnonymityRevoker(Box::new(v.try_into()?))
1532 }
1533 update_payload::Payload::AddIdentityProviderUpdate(v) => {
1534 Self::AddIdentityProvider(Box::new(v.try_into()?))
1535 }
1536 update_payload::Payload::CooldownParametersCpv1Update(v) => {
1537 Self::CooldownParametersCPV1(v.try_into()?)
1538 }
1539 update_payload::Payload::PoolParametersCpv1Update(v) => {
1540 Self::PoolParametersCPV1(v.try_into()?)
1541 }
1542 update_payload::Payload::TimeParametersCpv1Update(v) => {
1543 Self::TimeParametersCPV1(v.try_into()?)
1544 }
1545 update_payload::Payload::MintDistributionCpv1Update(v) => {
1546 Self::MintDistributionCPV1(v.try_into()?)
1547 }
1548 update_payload::Payload::GasRewardsCpv2Update(v) => Self::GASRewardsCPV2(v.try_into()?),
1549 update_payload::Payload::TimeoutParametersUpdate(v) => {
1550 Self::TimeoutParametersCPV2(v.try_into()?)
1551 }
1552 update_payload::Payload::MinBlockTimeUpdate(v) => Self::MinBlockTimeCPV2(v.into()),
1553 update_payload::Payload::BlockEnergyLimitUpdate(v) => {
1554 Self::BlockEnergyLimitCPV2(v.into())
1555 }
1556 update_payload::Payload::FinalizationCommitteeParametersUpdate(v) => {
1557 Self::FinalizationCommitteeParametersCPV2(v.try_into()?)
1558 }
1559 update_payload::Payload::ValidatorScoreParametersUpdate(v) => {
1560 Self::ValidatorScoreParametersCPV3(v.try_into()?)
1561 }
1562 update_payload::Payload::CreatePltUpdate(create_plt) => {
1563 Self::CreatePlt(create_plt.try_into()?)
1564 }
1565 })
1566 }
1567}
1568
1569impl TryFrom<super::generated::plt::CreatePlt> for concordium_base::updates::CreatePlt {
1570 type Error = tonic::Status;
1571
1572 fn try_from(value: super::generated::plt::CreatePlt) -> Result<Self, Self::Error> {
1573 Ok(Self {
1574 token_id: value.token_id.require()?.try_into()?,
1575 token_module: value.token_module.require()?.try_into()?,
1576 decimals: value.decimals.try_into().map_err(|_| {
1577 tonic::Status::internal("Unexpected integer size for token decimals.")
1578 })?,
1579 initialization_parameters: value.initialization_parameters.require()?.into(),
1580 })
1581 }
1582}
1583
1584impl TryFrom<CapitalBound> for super::types::CapitalBound {
1585 type Error = tonic::Status;
1586
1587 fn try_from(value: CapitalBound) -> Result<Self, Self::Error> {
1588 Ok(Self {
1589 bound: value.value.require()?.into(),
1590 })
1591 }
1592}
1593
1594impl TryFrom<InclusiveRangeAmountFraction>
1595 for super::types::InclusiveRange<super::types::AmountFraction>
1596{
1597 type Error = tonic::Status;
1598
1599 fn try_from(value: InclusiveRangeAmountFraction) -> Result<Self, Self::Error> {
1600 let min = value.min.require()?.into();
1601 let max = value.max.require()?.into();
1602 if min <= max {
1603 Ok(Self { min, max })
1604 } else {
1605 Err(tonic::Status::internal(
1606 "Lower bound must not be more than the upper bound.",
1607 ))
1608 }
1609 }
1610}
1611
1612impl From<DurationSeconds> for super::types::DurationSeconds {
1613 fn from(value: DurationSeconds) -> Self {
1614 Self {
1615 seconds: value.value,
1616 }
1617 }
1618}
1619
1620impl TryFrom<IpInfo> for crate::id::types::IpInfo<IpPairing> {
1621 type Error = tonic::Status;
1622
1623 fn try_from(value: IpInfo) -> Result<Self, Self::Error> {
1624 Ok(Self {
1625 ip_identity: crate::id::types::IpIdentity(value.identity.require()?.value),
1626 ip_description: value.description.require()?.into(),
1627 ip_verify_key: value.verify_key.require()?.try_into()?,
1628 ip_cdi_verify_key: value.cdi_verify_key.require()?.try_into()?,
1629 })
1630 }
1631}
1632
1633impl TryFrom<ArInfo> for crate::id::types::ArInfo<ArCurve> {
1634 type Error = tonic::Status;
1635
1636 fn try_from(value: ArInfo) -> Result<Self, Self::Error> {
1637 Ok(Self {
1638 ar_identity: crate::id::types::ArIdentity::try_from(value.identity.require()?.value)
1639 .map_err(tonic::Status::internal)?,
1640 ar_description: value.description.require()?.into(),
1641 ar_public_key: value.public_key.require()?.try_into()?,
1642 })
1643 }
1644}
1645
1646impl From<Description> for crate::id::types::Description {
1647 fn from(value: Description) -> Self {
1648 Self {
1649 name: value.name,
1650 url: value.url,
1651 description: value.description,
1652 }
1653 }
1654}
1655
1656impl TryFrom<AuthorizationsV0> for super::types::AuthorizationsV0 {
1657 type Error = tonic::Status;
1658
1659 fn try_from(value: AuthorizationsV0) -> Result<Self, Self::Error> {
1660 Ok(Self {
1661 keys: value
1662 .keys
1663 .into_iter()
1664 .map(TryInto::try_into)
1665 .collect::<Result<_, tonic::Status>>()?,
1666 emergency: value.emergency.require()?.try_into()?,
1667 protocol: value.protocol.require()?.try_into()?,
1668 election_difficulty: value.parameter_consensus.require()?.try_into()?,
1669 euro_per_energy: value.parameter_euro_per_energy.require()?.try_into()?,
1670 micro_gtu_per_euro: value.parameter_micro_ccd_per_euro.require()?.try_into()?,
1671 foundation_account: value.parameter_foundation_account.require()?.try_into()?,
1672 mint_distribution: value.parameter_mint_distribution.require()?.try_into()?,
1673 transaction_fee_distribution: value
1674 .parameter_transaction_fee_distribution
1675 .require()?
1676 .try_into()?,
1677 param_gas_rewards: value.parameter_gas_rewards.require()?.try_into()?,
1678 pool_parameters: value.pool_parameters.require()?.try_into()?,
1679 add_anonymity_revoker: value.add_anonymity_revoker.require()?.try_into()?,
1680 add_identity_provider: value.add_identity_provider.require()?.try_into()?,
1681 })
1682 }
1683}
1684
1685impl TryFrom<AuthorizationsV1> for super::types::AuthorizationsV1 {
1686 type Error = tonic::Status;
1687
1688 fn try_from(value: AuthorizationsV1) -> Result<Self, Self::Error> {
1689 Ok(Self {
1690 v0: value.v0.require()?.try_into()?,
1691 cooldown_parameters: value.parameter_cooldown.require()?.try_into()?,
1692 time_parameters: value.parameter_time.require()?.try_into()?,
1693 create_plt: value.create_plt.map(|x| x.try_into()).transpose()?,
1694 })
1695 }
1696}
1697
1698impl TryFrom<AuthorizationsV0> for chain_parameters::Level2Keys {
1699 type Error = tonic::Status;
1700
1701 fn try_from(value: AuthorizationsV0) -> Result<Self, Self::Error> {
1702 Ok(Self {
1703 keys: value
1704 .keys
1705 .into_iter()
1706 .map(TryInto::try_into)
1707 .collect::<Result<_, tonic::Status>>()?,
1708 emergency: value.emergency.map(TryInto::try_into).transpose()?,
1709 protocol: value.protocol.map(TryInto::try_into).transpose()?,
1710 consensus: value
1711 .parameter_consensus
1712 .map(TryInto::try_into)
1713 .transpose()?,
1714 euro_per_energy: value
1715 .parameter_euro_per_energy
1716 .map(TryInto::try_into)
1717 .transpose()?,
1718 micro_ccd_per_euro: value
1719 .parameter_micro_ccd_per_euro
1720 .map(TryInto::try_into)
1721 .transpose()?,
1722 foundation_account: value
1723 .parameter_foundation_account
1724 .map(TryInto::try_into)
1725 .transpose()?,
1726 mint_distribution: value
1727 .parameter_mint_distribution
1728 .map(TryInto::try_into)
1729 .transpose()?,
1730 transaction_fee_distribution: value
1731 .parameter_transaction_fee_distribution
1732 .map(TryInto::try_into)
1733 .transpose()?,
1734 param_gas_rewards: value
1735 .parameter_gas_rewards
1736 .map(TryInto::try_into)
1737 .transpose()?,
1738 pool_parameters: value.pool_parameters.map(TryInto::try_into).transpose()?,
1739 add_anonymity_revoker: value
1740 .add_anonymity_revoker
1741 .map(TryInto::try_into)
1742 .transpose()?,
1743 add_identity_provider: value
1744 .add_identity_provider
1745 .map(TryInto::try_into)
1746 .transpose()?,
1747 cooldown_parameters: None,
1748 time_parameters: None,
1749 create_plt: None,
1750 })
1751 }
1752}
1753
1754impl TryFrom<AuthorizationsV1> for chain_parameters::Level2Keys {
1755 type Error = tonic::Status;
1756
1757 fn try_from(value: AuthorizationsV1) -> Result<Self, Self::Error> {
1758 let keys: Self = value.v0.require()?.try_into()?;
1759 Ok(Self {
1760 cooldown_parameters: value
1761 .parameter_cooldown
1762 .map(TryInto::try_into)
1763 .transpose()?,
1764 time_parameters: value.parameter_time.map(TryInto::try_into).transpose()?,
1765 create_plt: value.create_plt.map(|x| x.try_into()).transpose()?,
1766 ..keys
1767 })
1768 }
1769}
1770
1771impl TryFrom<AccessStructure> for super::types::AccessStructure {
1772 type Error = tonic::Status;
1773
1774 fn try_from(value: AccessStructure) -> Result<Self, Self::Error> {
1775 let authorized_keys = value
1776 .access_public_keys
1777 .into_iter()
1778 .map(TryInto::try_into)
1779 .collect::<Result<_, tonic::Status>>()?;
1780 let threshold = value.access_threshold.require()?.try_into()?;
1781 Ok(Self {
1782 authorized_keys,
1783 threshold,
1784 })
1785 }
1786}
1787
1788impl TryFrom<UpdateKeysIndex> for super::types::UpdateKeysIndex {
1789 type Error = tonic::Status;
1790
1791 fn try_from(value: UpdateKeysIndex) -> Result<Self, Self::Error> {
1792 Ok(Self {
1793 index: value.value.try_into().map_err(|_| {
1794 tonic::Status::internal("Invalid update keys index: could not fit into a u16.")
1795 })?,
1796 })
1797 }
1798}
1799
1800impl TryFrom<UpdateKeysThreshold> for super::types::UpdateKeysThreshold {
1801 type Error = tonic::Status;
1802
1803 fn try_from(value: UpdateKeysThreshold) -> Result<Self, Self::Error> {
1804 Self::try_from(
1805 u16::try_from(value.value)
1806 .map_err(|_| tonic::Status::internal("Threshold could not fit into a u16."))?,
1807 )
1808 .map_err(|_| tonic::Status::invalid_argument("UpdateKeysThreshold cannot be 0."))
1809 }
1810}
1811
1812impl TryFrom<MintRate> for super::types::MintRate {
1813 type Error = tonic::Status;
1814
1815 fn try_from(value: MintRate) -> Result<Self, Self::Error> {
1816 Ok(Self {
1817 mantissa: value.mantissa,
1818 exponent: value.exponent.try_into().map_err(|_| {
1819 tonic::Status::internal(
1820 "Invalid exponent value. Could not be represented in an u8.",
1821 )
1822 })?,
1823 })
1824 }
1825}
1826
1827impl From<TransactionTime> for super::super::common::types::TransactionTime {
1828 fn from(value: TransactionTime) -> Self {
1829 Self {
1830 seconds: value.value,
1831 }
1832 }
1833}
1834
1835impl From<CredentialType> for super::types::CredentialType {
1836 fn from(value: CredentialType) -> Self {
1837 match value {
1838 CredentialType::Initial => Self::Initial,
1839 CredentialType::Normal => Self::Normal,
1840 }
1841 }
1842}
1843
1844impl TryFrom<AccountTransactionEffects> for super::types::AccountTransactionEffects {
1845 type Error = tonic::Status;
1846
1847 fn try_from(value: AccountTransactionEffects) -> Result<Self, Self::Error> {
1848 match value.effect.require()? {
1849 account_transaction_effects::Effect::None(n) => Ok(Self::None {
1850 transaction_type: {
1851 match n.transaction_type {
1852 None => None,
1853 Some(tt) => Some(
1854 super::types::TransactionType::try_from(tt)
1855 .map_err(|e| tonic::Status::invalid_argument(e.to_string()))?,
1856 ),
1857 }
1858 },
1859 reject_reason: n
1860 .reject_reason
1861 .map(super::types::RejectReason::try_from)
1862 .transpose()?
1863 .into(),
1864 }),
1865 account_transaction_effects::Effect::AccountTransfer(at) => {
1866 let amount = at.amount.require()?.into();
1867 let to = at.receiver.require()?.try_into()?;
1868 match at.memo {
1869 None => Ok(Self::AccountTransfer { amount, to }),
1870 Some(memo) => Ok(Self::AccountTransferWithMemo {
1871 amount,
1872 to,
1873 memo: memo.try_into()?,
1874 }),
1875 }
1876 }
1877 account_transaction_effects::Effect::ModuleDeployed(module_ref) => {
1878 Ok(Self::ModuleDeployed {
1879 module_ref: module_ref.try_into()?,
1880 })
1881 }
1882 account_transaction_effects::Effect::ContractInitialized(cie) => {
1883 Ok(Self::ContractInitialized {
1884 data: super::types::ContractInitializedEvent {
1885 contract_version: u8::try_from(cie.contract_version)
1886 .map(WasmVersionInt)
1887 .map_err(|err| {
1888 tonic::Status::internal(format!(
1889 "Could not map contract version from i32 to u8: {err}"
1890 ))
1891 })?,
1892 origin_ref: cie.origin_ref.require()?.try_into()?,
1893 address: cie.address.require()?.into(),
1894 amount: cie.amount.require()?.into(),
1895 init_name: cie.init_name.require()?.try_into()?,
1896 events: cie.events.into_iter().map(Into::into).collect(),
1897 parameter: cie.parameter.map(TryInto::try_into).transpose()?,
1898 },
1899 })
1900 }
1901 account_transaction_effects::Effect::ContractUpdateIssued(cui) => {
1902 let effects = cui
1903 .effects
1904 .into_iter()
1905 .map(|trace| {
1906 Ok(Upward::from(
1907 trace
1908 .element
1909 .map(super::types::ContractTraceElement::try_from)
1910 .transpose()?,
1911 ))
1912 })
1913 .collect::<Result<_, tonic::Status>>()?;
1914 Ok(Self::ContractUpdateIssued { effects })
1915 }
1916 account_transaction_effects::Effect::BakerAdded(ba) => {
1917 let baker_added_event = super::types::BakerAddedEvent {
1918 keys_event: ba.keys_event.require()?.try_into()?,
1919 stake: ba.stake.require()?.into(),
1920 restake_earnings: ba.restake_earnings,
1921 };
1922 Ok(Self::BakerAdded {
1923 data: Box::new(baker_added_event),
1924 })
1925 }
1926 account_transaction_effects::Effect::BakerRemoved(baker_id) => Ok(Self::BakerRemoved {
1927 baker_id: baker_id.into(),
1928 }),
1929 account_transaction_effects::Effect::BakerStakeUpdated(bsu) => {
1930 let data = match bsu.update {
1931 None => None,
1932 Some(d) => Some(super::types::BakerStakeUpdatedData {
1933 baker_id: d.baker_id.require()?.into(),
1934 new_stake: d.new_stake.require()?.into(),
1935 increased: d.increased,
1936 }),
1937 };
1938 Ok(Self::BakerStakeUpdated { data })
1939 }
1940 account_transaction_effects::Effect::BakerRestakeEarningsUpdated(breu) => {
1941 Ok(Self::BakerRestakeEarningsUpdated {
1942 baker_id: breu.baker_id.require()?.into(),
1943 restake_earnings: breu.restake_earnings,
1944 })
1945 }
1946 account_transaction_effects::Effect::BakerKeysUpdated(keys_event) => {
1947 Ok(Self::BakerKeysUpdated {
1948 data: Box::new(keys_event.try_into()?),
1949 })
1950 }
1951 account_transaction_effects::Effect::EncryptedAmountTransferred(eat) => {
1952 let removed = Box::new(eat.removed.require()?.try_into()?);
1953 let added = Box::new(eat.added.require()?.try_into()?);
1954 match eat.memo {
1955 None => Ok(Self::EncryptedAmountTransferred { removed, added }),
1956 Some(memo) => Ok(Self::EncryptedAmountTransferredWithMemo {
1957 removed,
1958 added,
1959 memo: memo.try_into()?,
1960 }),
1961 }
1962 }
1963 account_transaction_effects::Effect::TransferredToEncrypted(esaae) => {
1964 Ok(Self::TransferredToEncrypted {
1965 data: Box::new(super::types::EncryptedSelfAmountAddedEvent {
1966 account: esaae.account.require()?.try_into()?,
1967 new_amount: esaae.new_amount.require()?.try_into()?,
1968 amount: esaae.amount.require()?.into(),
1969 }),
1970 })
1971 }
1972 account_transaction_effects::Effect::TransferredToPublic(ttp) => {
1973 Ok(Self::TransferredToPublic {
1974 removed: Box::new(ttp.removed.require()?.try_into()?),
1975 amount: ttp.amount.require()?.into(),
1976 })
1977 }
1978 account_transaction_effects::Effect::TransferredWithSchedule(tws) => {
1979 let to = tws.receiver.require()?.try_into()?;
1980 let amount = tws
1981 .amount
1982 .into_iter()
1983 .map(TryInto::try_into)
1984 .collect::<Result<_, tonic::Status>>()?;
1985 match tws.memo {
1986 None => Ok(Self::TransferredWithSchedule { to, amount }),
1987 Some(memo) => Ok(Self::TransferredWithScheduleAndMemo {
1988 to,
1989 amount,
1990 memo: memo.try_into()?,
1991 }),
1992 }
1993 }
1994 account_transaction_effects::Effect::CredentialKeysUpdated(cri) => {
1995 Ok(Self::CredentialKeysUpdated {
1996 cred_id: cri.try_into()?,
1997 })
1998 }
1999 account_transaction_effects::Effect::CredentialsUpdated(cu) => {
2000 Ok(Self::CredentialsUpdated {
2001 new_cred_ids: cu
2002 .new_cred_ids
2003 .into_iter()
2004 .map(TryInto::try_into)
2005 .collect::<Result<_, tonic::Status>>()?,
2006 removed_cred_ids: cu
2007 .removed_cred_ids
2008 .into_iter()
2009 .map(TryInto::try_into)
2010 .collect::<Result<_, tonic::Status>>()?,
2011 new_threshold: cu.new_threshold.require()?.try_into()?,
2012 })
2013 }
2014 account_transaction_effects::Effect::DataRegistered(rd) => Ok(Self::DataRegistered {
2015 data: rd.try_into()?,
2016 }),
2017 account_transaction_effects::Effect::BakerConfigured(bc) => Ok(Self::BakerConfigured {
2018 data: bc
2019 .events
2020 .into_iter()
2021 .map(|event| {
2022 Ok(Upward::from(
2023 event
2024 .event
2025 .map(super::types::BakerEvent::try_from)
2026 .transpose()?,
2027 ))
2028 })
2029 .collect::<Result<_, tonic::Status>>()?,
2030 }),
2031 account_transaction_effects::Effect::DelegationConfigured(dc) => {
2032 Ok(Self::DelegationConfigured {
2033 data: dc
2034 .events
2035 .into_iter()
2036 .map(|event| {
2037 Ok(Upward::from(
2038 event
2039 .event
2040 .map(super::types::DelegationEvent::try_from)
2041 .transpose()?,
2042 ))
2043 })
2044 .collect::<Result<_, tonic::Status>>()?,
2045 })
2046 }
2047 account_transaction_effects::Effect::TokenUpdateEffect(token_effect) => {
2048 Ok(Self::TokenUpdate {
2049 events: token_effect
2050 .events
2051 .into_iter()
2052 .map(TryInto::try_into)
2053 .collect::<Result<_, tonic::Status>>()?,
2054 })
2055 }
2056 }
2057 }
2058}
2059
2060impl TryFrom<contract_trace_element::Element> for super::types::ContractTraceElement {
2061 type Error = tonic::Status;
2062
2063 fn try_from(element: contract_trace_element::Element) -> Result<Self, Self::Error> {
2064 Ok(match element {
2065 contract_trace_element::Element::Updated(u) => {
2066 super::types::ContractTraceElement::Updated {
2067 data: u.try_into()?,
2068 }
2069 }
2070 contract_trace_element::Element::Transferred(t) => {
2071 super::types::ContractTraceElement::Transferred {
2072 from: t.sender.require()?.into(),
2073 amount: t.amount.require()?.into(),
2074 to: t.receiver.require()?.try_into()?,
2075 }
2076 }
2077 contract_trace_element::Element::Interrupted(i) => {
2078 super::types::ContractTraceElement::Interrupted {
2079 address: i.address.require()?.into(),
2080 events: i.events.into_iter().map(Into::into).collect(),
2081 }
2082 }
2083 contract_trace_element::Element::Resumed(r) => {
2084 super::types::ContractTraceElement::Resumed {
2085 address: r.address.require()?.into(),
2086 success: r.success,
2087 }
2088 }
2089 contract_trace_element::Element::Upgraded(r) => {
2090 super::types::ContractTraceElement::Upgraded {
2091 address: r.address.require()?.into(),
2092 from: r.from.require()?.try_into()?,
2093 to: r.to.require()?.try_into()?,
2094 }
2095 }
2096 })
2097 }
2098}
2099
2100impl TryFrom<delegation_event::Event> for super::types::DelegationEvent {
2101 type Error = tonic::Status;
2102
2103 fn try_from(value: delegation_event::Event) -> Result<Self, Self::Error> {
2104 Ok(match value {
2105 delegation_event::Event::DelegationStakeIncreased(v) => {
2106 Self::DelegationStakeIncreased {
2107 delegator_id: v.delegator_id.require()?.try_into()?,
2108 new_stake: v.new_stake.require()?.into(),
2109 }
2110 }
2111 delegation_event::Event::DelegationStakeDecreased(v) => {
2112 Self::DelegationStakeDecreased {
2113 delegator_id: v.delegator_id.require()?.try_into()?,
2114 new_stake: v.new_stake.require()?.into(),
2115 }
2116 }
2117 delegation_event::Event::DelegationSetRestakeEarnings(v) => {
2118 Self::DelegationSetRestakeEarnings {
2119 delegator_id: v.delegator_id.require()?.try_into()?,
2120 restake_earnings: v.restake_earnings,
2121 }
2122 }
2123 delegation_event::Event::DelegationSetDelegationTarget(v) => {
2124 Self::DelegationSetDelegationTarget {
2125 delegator_id: v.delegator_id.require()?.try_into()?,
2126 delegation_target: v.delegation_target.require()?.try_into()?,
2127 }
2128 }
2129 delegation_event::Event::DelegationAdded(v) => Self::DelegationAdded {
2130 delegator_id: v.try_into()?,
2131 },
2132 delegation_event::Event::DelegationRemoved(v) => Self::DelegationRemoved {
2133 delegator_id: v.try_into()?,
2134 },
2135 delegation_event::Event::BakerRemoved(v) => Self::BakerRemoved {
2136 baker_id: v.baker_id.require()?.into(),
2137 },
2138 })
2139 }
2140}
2141
2142impl TryFrom<DelegatorId> for super::types::DelegatorId {
2143 type Error = tonic::Status;
2144
2145 fn try_from(value: DelegatorId) -> Result<Self, Self::Error> {
2146 Ok(Self {
2147 id: value.id.require()?.into(),
2148 })
2149 }
2150}
2151
2152impl TryFrom<baker_event::Event> for super::types::BakerEvent {
2153 type Error = tonic::Status;
2154
2155 fn try_from(value: baker_event::Event) -> Result<Self, Self::Error> {
2156 Ok(match value {
2157 baker_event::Event::BakerAdded(v) => Self::BakerAdded {
2158 data: Box::new(super::types::BakerAddedEvent {
2159 keys_event: v.keys_event.require()?.try_into()?,
2160 stake: v.stake.require()?.into(),
2161 restake_earnings: v.restake_earnings,
2162 }),
2163 },
2164 baker_event::Event::BakerRemoved(v) => Self::BakerRemoved { baker_id: v.into() },
2165 baker_event::Event::BakerStakeIncreased(v) => Self::BakerStakeIncreased {
2166 baker_id: v.baker_id.require()?.into(),
2167 new_stake: v.new_stake.require()?.into(),
2168 },
2169 baker_event::Event::BakerStakeDecreased(v) => Self::BakerStakeDecreased {
2170 baker_id: v.baker_id.require()?.into(),
2171 new_stake: v.new_stake.require()?.into(),
2172 },
2173 baker_event::Event::BakerRestakeEarningsUpdated(v) => {
2174 Self::BakerRestakeEarningsUpdated {
2175 baker_id: v.baker_id.require()?.into(),
2176 restake_earnings: v.restake_earnings,
2177 }
2178 }
2179 baker_event::Event::BakerKeysUpdated(v) => Self::BakerKeysUpdated {
2180 data: Box::new(v.try_into()?),
2181 },
2182 baker_event::Event::BakerSetOpenStatus(v) => {
2183 let open_status = Upward::from(OpenStatus::try_from(v.open_status).ok())
2184 .map(super::types::OpenStatus::from);
2185 Self::BakerSetOpenStatus {
2186 baker_id: v.baker_id.require()?.into(),
2187 open_status,
2188 }
2189 }
2190 baker_event::Event::BakerSetMetadataUrl(v) => Self::BakerSetMetadataURL {
2191 baker_id: v.baker_id.require()?.into(),
2192 metadata_url: v.url.try_into().map_err(|e| {
2193 tonic::Status::invalid_argument(format!("Invalid argument: {}", e))
2194 })?,
2195 },
2196 baker_event::Event::BakerSetTransactionFeeCommission(v) => {
2197 Self::BakerSetTransactionFeeCommission {
2198 baker_id: v.baker_id.require()?.into(),
2199 transaction_fee_commission: v.transaction_fee_commission.require()?.into(),
2200 }
2201 }
2202 baker_event::Event::BakerSetBakingRewardCommission(v) => {
2203 Self::BakerSetBakingRewardCommission {
2204 baker_id: v.baker_id.require()?.into(),
2205 baking_reward_commission: v.baking_reward_commission.require()?.into(),
2206 }
2207 }
2208 baker_event::Event::BakerSetFinalizationRewardCommission(v) => {
2209 Self::BakerSetFinalizationRewardCommission {
2210 baker_id: v.baker_id.require()?.into(),
2211 finalization_reward_commission: v
2212 .finalization_reward_commission
2213 .require()?
2214 .into(),
2215 }
2216 }
2217 baker_event::Event::DelegationRemoved(v) => Self::DelegationRemoved {
2218 delegator_id: v.delegator_id.require()?.try_into()?,
2219 },
2220 baker_event::Event::BakerSuspended(v) => Self::BakerSuspended {
2221 baker_id: v.baker_id.require()?.into(),
2222 },
2223 baker_event::Event::BakerResumed(v) => Self::BakerResumed {
2224 baker_id: v.baker_id.require()?.into(),
2225 },
2226 })
2227 }
2228}
2229
2230impl TryFrom<RegisteredData> for super::types::RegisteredData {
2231 type Error = tonic::Status;
2232
2233 fn try_from(value: RegisteredData) -> Result<Self, Self::Error> {
2234 value
2235 .value
2236 .try_into()
2237 .map_err(|e| tonic::Status::invalid_argument(format!("{}", e)))
2238 }
2239}
2240
2241impl TryFrom<NewRelease>
2242 for (
2243 super::super::common::types::Timestamp,
2244 super::super::common::types::Amount,
2245 )
2246{
2247 type Error = tonic::Status;
2248
2249 fn try_from(value: NewRelease) -> Result<Self, Self::Error> {
2250 let timestamp = super::super::common::types::Timestamp {
2251 millis: value.timestamp.require()?.value,
2252 };
2253 Ok((timestamp, value.amount.require()?.into()))
2254 }
2255}
2256
2257impl TryFrom<EncryptedAmountRemovedEvent> for super::types::EncryptedAmountRemovedEvent {
2258 type Error = tonic::Status;
2259
2260 fn try_from(value: EncryptedAmountRemovedEvent) -> Result<Self, Self::Error> {
2261 Ok(Self {
2262 account: value.account.require()?.try_into()?,
2263 new_amount: value.new_amount.require()?.try_into()?,
2264 input_amount: value.input_amount.require()?.try_into()?,
2265 up_to_index: crate::encrypted_transfers::types::EncryptedAmountAggIndex {
2266 index: value.up_to_index,
2267 },
2268 })
2269 }
2270}
2271
2272impl TryFrom<NewEncryptedAmountEvent> for super::types::NewEncryptedAmountEvent {
2273 type Error = tonic::Status;
2274
2275 fn try_from(value: NewEncryptedAmountEvent) -> Result<Self, Self::Error> {
2276 Ok(Self {
2277 receiver: value.receiver.require()?.try_into()?,
2278 new_index: crate::encrypted_transfers::types::EncryptedAmountIndex {
2279 index: value.new_index,
2280 },
2281 encrypted_amount: value.encrypted_amount.require()?.try_into()?,
2282 })
2283 }
2284}
2285
2286impl TryFrom<Memo> for super::types::Memo {
2287 type Error = tonic::Status;
2288
2289 fn try_from(value: Memo) -> Result<Self, Self::Error> {
2290 value
2291 .value
2292 .try_into()
2293 .map_err(|_| tonic::Status::invalid_argument("Memo is invalid because it is too big."))
2294 }
2295}
2296impl TryFrom<BakerKeysEvent> for super::types::BakerKeysEvent {
2297 type Error = tonic::Status;
2298
2299 fn try_from(value: BakerKeysEvent) -> Result<Self, Self::Error> {
2300 Ok(Self {
2301 baker_id: value.baker_id.require()?.into(),
2302 account: value.account.require()?.try_into()?,
2303 sign_key: value.sign_key.require()?.try_into()?,
2304 election_key: value.election_key.require()?.try_into()?,
2305 aggregation_key: value.aggregation_key.require()?.try_into()?,
2306 })
2307 }
2308}
2309
2310impl TryFrom<InstanceUpdatedEvent> for super::types::InstanceUpdatedEvent {
2311 type Error = tonic::Status;
2312
2313 fn try_from(value: InstanceUpdatedEvent) -> Result<Self, Self::Error> {
2314 Ok(Self {
2315 contract_version: u8::try_from(value.contract_version)
2316 .map(WasmVersionInt)
2317 .map_err(|err| {
2318 tonic::Status::internal(format!(
2319 "Could not map contract version from i32 to u8: {err}"
2320 ))
2321 })?,
2322 address: value.address.require()?.into(),
2323 instigator: value.instigator.require()?.try_into()?,
2324 amount: value.amount.require()?.into(),
2325 message: value.parameter.require()?.try_into()?,
2326 receive_name: value.receive_name.require()?.try_into()?,
2327 events: value.events.into_iter().map(Into::into).collect(),
2328 })
2329 }
2330}
2331
2332impl From<ContractEvent> for super::types::smart_contracts::ContractEvent {
2333 fn from(value: ContractEvent) -> Self {
2334 value.value.into()
2335 }
2336}
2337
2338impl TryFrom<RejectReason> for super::types::RejectReason {
2339 type Error = tonic::Status;
2340
2341 fn try_from(value: RejectReason) -> Result<Self, Self::Error> {
2342 Ok(match value.reason.require()? {
2343 reject_reason::Reason::ModuleNotWf(_) => Self::ModuleNotWF,
2344 reject_reason::Reason::ModuleHashAlreadyExists(v) => Self::ModuleHashAlreadyExists {
2345 contents: v.try_into()?,
2346 },
2347 reject_reason::Reason::InvalidAccountReference(v) => Self::InvalidAccountReference {
2348 contents: v.try_into()?,
2349 },
2350 reject_reason::Reason::InvalidInitMethod(v) => Self::InvalidInitMethod {
2351 contents: (
2352 v.module_ref.require()?.try_into()?,
2353 v.init_name.require()?.try_into()?,
2354 ),
2355 },
2356 reject_reason::Reason::InvalidReceiveMethod(v) => Self::InvalidReceiveMethod {
2357 contents: (
2358 v.module_ref.require()?.try_into()?,
2359 v.receive_name.require()?.try_into()?,
2360 ),
2361 },
2362 reject_reason::Reason::InvalidModuleReference(v) => Self::InvalidModuleReference {
2363 contents: v.try_into()?,
2364 },
2365 reject_reason::Reason::InvalidContractAddress(v) => {
2366 Self::InvalidContractAddress { contents: v.into() }
2367 }
2368 reject_reason::Reason::RuntimeFailure(_) => Self::RuntimeFailure,
2369 reject_reason::Reason::AmountTooLarge(v) => Self::AmountTooLarge {
2370 contents: (v.address.require()?.try_into()?, v.amount.require()?.into()),
2371 },
2372 reject_reason::Reason::SerializationFailure(_) => Self::SerializationFailure,
2373 reject_reason::Reason::OutOfEnergy(_) => Self::OutOfEnergy,
2374 reject_reason::Reason::RejectedInit(v) => Self::RejectedInit {
2375 reject_reason: v.reject_reason,
2376 },
2377 reject_reason::Reason::RejectedReceive(v) => Self::RejectedReceive {
2378 reject_reason: v.reject_reason,
2379 contract_address: v.contract_address.require()?.into(),
2380 receive_name: v.receive_name.require()?.try_into()?,
2381 parameter: v.parameter.require()?.try_into()?,
2382 },
2383 reject_reason::Reason::InvalidProof(_) => Self::InvalidProof,
2384 reject_reason::Reason::AlreadyABaker(v) => Self::AlreadyABaker { contents: v.into() },
2385 reject_reason::Reason::NotABaker(v) => Self::NotABaker {
2386 contents: v.try_into()?,
2387 },
2388 reject_reason::Reason::InsufficientBalanceForBakerStake(_) => {
2389 Self::InsufficientBalanceForBakerStake
2390 }
2391 reject_reason::Reason::StakeUnderMinimumThresholdForBaking(_) => {
2392 Self::StakeUnderMinimumThresholdForBaking
2393 }
2394 reject_reason::Reason::BakerInCooldown(_) => Self::BakerInCooldown,
2395 reject_reason::Reason::DuplicateAggregationKey(v) => Self::DuplicateAggregationKey {
2396 contents: Box::new(v.try_into()?),
2397 },
2398 reject_reason::Reason::NonExistentCredentialId(_) => Self::NonExistentCredentialID,
2399 reject_reason::Reason::KeyIndexAlreadyInUse(_) => Self::KeyIndexAlreadyInUse,
2400 reject_reason::Reason::InvalidAccountThreshold(_) => Self::InvalidAccountThreshold,
2401 reject_reason::Reason::InvalidCredentialKeySignThreshold(_) => {
2402 Self::InvalidCredentialKeySignThreshold
2403 }
2404 reject_reason::Reason::InvalidEncryptedAmountTransferProof(_) => {
2405 Self::InvalidEncryptedAmountTransferProof
2406 }
2407 reject_reason::Reason::InvalidTransferToPublicProof(_) => {
2408 Self::InvalidTransferToPublicProof
2409 }
2410 reject_reason::Reason::EncryptedAmountSelfTransfer(v) => {
2411 Self::EncryptedAmountSelfTransfer {
2412 contents: v.try_into()?,
2413 }
2414 }
2415 reject_reason::Reason::InvalidIndexOnEncryptedTransfer(_) => {
2416 Self::InvalidIndexOnEncryptedTransfer
2417 }
2418 reject_reason::Reason::ZeroScheduledAmount(_) => Self::ZeroScheduledAmount,
2419 reject_reason::Reason::NonIncreasingSchedule(_) => Self::NonIncreasingSchedule,
2420 reject_reason::Reason::FirstScheduledReleaseExpired(_) => {
2421 Self::FirstScheduledReleaseExpired
2422 }
2423 reject_reason::Reason::ScheduledSelfTransfer(v) => Self::ScheduledSelfTransfer {
2424 contents: v.try_into()?,
2425 },
2426 reject_reason::Reason::InvalidCredentials(_) => Self::InvalidCredentials,
2427 reject_reason::Reason::DuplicateCredIds(v) => Self::DuplicateCredIDs {
2428 contents: v
2429 .ids
2430 .into_iter()
2431 .map(TryFrom::try_from)
2432 .collect::<Result<_, tonic::Status>>()?,
2433 },
2434 reject_reason::Reason::NonExistentCredIds(v) => Self::NonExistentCredIDs {
2435 contents: v
2436 .ids
2437 .into_iter()
2438 .map(TryFrom::try_from)
2439 .collect::<Result<_, tonic::Status>>()?,
2440 },
2441 reject_reason::Reason::RemoveFirstCredential(_) => Self::RemoveFirstCredential,
2442 reject_reason::Reason::CredentialHolderDidNotSign(_) => {
2443 Self::CredentialHolderDidNotSign
2444 }
2445 reject_reason::Reason::NotAllowedMultipleCredentials(_) => {
2446 Self::NotAllowedMultipleCredentials
2447 }
2448 reject_reason::Reason::NotAllowedToReceiveEncrypted(_) => {
2449 Self::NotAllowedToReceiveEncrypted
2450 }
2451 reject_reason::Reason::NotAllowedToHandleEncrypted(_) => {
2452 Self::NotAllowedToHandleEncrypted
2453 }
2454 reject_reason::Reason::MissingBakerAddParameters(_) => Self::MissingBakerAddParameters,
2455 reject_reason::Reason::FinalizationRewardCommissionNotInRange(_) => {
2456 Self::FinalizationRewardCommissionNotInRange
2457 }
2458 reject_reason::Reason::BakingRewardCommissionNotInRange(_) => {
2459 Self::BakingRewardCommissionNotInRange
2460 }
2461 reject_reason::Reason::TransactionFeeCommissionNotInRange(_) => {
2462 Self::TransactionFeeCommissionNotInRange
2463 }
2464 reject_reason::Reason::AlreadyADelegator(_) => Self::AlreadyADelegator,
2465 reject_reason::Reason::InsufficientBalanceForDelegationStake(_) => {
2466 Self::InsufficientBalanceForDelegationStake
2467 }
2468 reject_reason::Reason::MissingDelegationAddParameters(_) => {
2469 Self::MissingDelegationAddParameters
2470 }
2471 reject_reason::Reason::InsufficientDelegationStake(_) => {
2472 Self::InsufficientDelegationStake
2473 }
2474 reject_reason::Reason::DelegatorInCooldown(_) => Self::DelegatorInCooldown,
2475 reject_reason::Reason::NotADelegator(v) => Self::NotADelegator {
2476 address: v.try_into()?,
2477 },
2478 reject_reason::Reason::DelegationTargetNotABaker(v) => {
2479 Self::DelegationTargetNotABaker { target: v.into() }
2480 }
2481 reject_reason::Reason::StakeOverMaximumThresholdForPool(_) => {
2482 Self::StakeOverMaximumThresholdForPool
2483 }
2484 reject_reason::Reason::PoolWouldBecomeOverDelegated(_) => {
2485 Self::PoolWouldBecomeOverDelegated
2486 }
2487 reject_reason::Reason::PoolClosed(_) => Self::PoolClosed,
2488 reject_reason::Reason::NonExistentTokenId(token_id) => Self::NonExistentTokenId {
2489 token_id: token_id.try_into()?,
2490 },
2491 reject_reason::Reason::TokenUpdateTransactionFailed(token_module_reject_reason) => {
2492 Self::TokenUpdateTransactionFailed {
2493 reject_reason: token_module_reject_reason.try_into()?,
2494 }
2495 }
2496 })
2497 }
2498}
2499
2500impl TryFrom<NextAccountSequenceNumber> for super::types::queries::AccountNonceResponse {
2501 type Error = tonic::Status;
2502
2503 fn try_from(value: NextAccountSequenceNumber) -> Result<Self, Self::Error> {
2504 Ok(Self {
2505 nonce: value.sequence_number.require()?.into(),
2506 all_final: value.all_final,
2507 })
2508 }
2509}
2510
2511impl From<block_item_summary::TransactionIndex> for super::types::TransactionIndex {
2512 fn from(value: block_item_summary::TransactionIndex) -> Self {
2513 Self { index: value.value }
2514 }
2515}
2516
2517impl From<Energy> for super::types::Energy {
2518 fn from(value: Energy) -> Self {
2519 Self {
2520 energy: value.value,
2521 }
2522 }
2523}
2524
2525impl TryFrom<ConsensusInfo> for super::types::queries::ConsensusInfo {
2526 type Error = tonic::Status;
2527
2528 fn try_from(value: ConsensusInfo) -> Result<Self, Self::Error> {
2529 let protocol_version = protocol_version_int_from_enum(value.protocol_version)?;
2530 Ok(Self {
2531 last_finalized_block_height: value.last_finalized_block_height.require()?.into(),
2532 block_arrive_latency_e_m_s_d: value.block_arrive_latency_emsd,
2533 block_receive_latency_e_m_s_d: value.block_receive_latency_emsd,
2534 last_finalized_block: value.last_finalized_block.require()?.try_into()?,
2535 block_receive_period_e_m_s_d: value.block_receive_period_emsd,
2536 block_arrive_period_e_m_s_d: value.block_arrive_period_emsd,
2537 blocks_received_count: value.blocks_received_count.into(),
2538 transactions_per_block_e_m_s_d: value.transactions_per_block_emsd,
2539 finalization_period_e_m_a: value.finalization_period_ema,
2540 best_block_height: value.best_block_height.require()?.into(),
2541 last_finalized_time: value
2542 .last_finalized_time
2543 .map(|v| v.try_into())
2544 .transpose()?,
2545 finalization_count: value.finalization_count.into(),
2546 epoch_duration: value.epoch_duration.require()?.try_into()?,
2547 blocks_verified_count: value.blocks_verified_count.into(),
2548 slot_duration: value.slot_duration.map(Into::into),
2549 genesis_time: value.genesis_time.require()?.try_into()?,
2550 finalization_period_e_m_s_d: value.finalization_period_emsd,
2551 transactions_per_block_e_m_a: value.transactions_per_block_ema,
2552 block_arrive_latency_e_m_a: value.block_arrive_latency_ema,
2553 block_receive_latency_e_m_a: value.block_receive_latency_ema,
2554 block_arrive_period_e_m_a: value.block_arrive_period_ema,
2555 block_receive_period_e_m_a: value.block_receive_period_ema,
2556 block_last_arrived_time: value
2557 .block_last_arrived_time
2558 .map(|v| v.try_into())
2559 .transpose()?,
2560 best_block: value.best_block.require()?.try_into()?,
2561 genesis_block: value.genesis_block.require()?.try_into()?,
2562 block_last_received_time: value
2563 .block_last_received_time
2564 .map(|v| v.try_into())
2565 .transpose()?,
2566 protocol_version,
2567 genesis_index: value.genesis_index.require()?.into(),
2568 current_era_genesis_block: value.current_era_genesis_block.require()?.try_into()?,
2569 current_era_genesis_time: value.current_era_genesis_time.require()?.try_into()?,
2570 concordium_bft_status: if protocol_version <= super::types::ProtocolVersion::P5.into() {
2571 None
2572 } else {
2573 Some(ConcordiumBFTDetails {
2574 current_timeout_duration: value
2575 .current_timeout_duration
2576 .require()?
2577 .try_into()?,
2578 current_round: value.current_round.require()?.into(),
2579 current_epoch: value.current_epoch.require()?.into(),
2580 trigger_block_time: value.trigger_block_time.require()?.try_into()?,
2581 })
2582 },
2583 })
2584 }
2585}
2586
2587impl TryFrom<InvokeInstanceResponse> for super::types::smart_contracts::InvokeContractResult {
2588 type Error = tonic::Status;
2589
2590 fn try_from(response: InvokeInstanceResponse) -> Result<Self, Self::Error> {
2591 use super::types::smart_contracts::{InvokeContractResult, ReturnValue};
2592 let result = match response.result.require()? {
2593 invoke_instance_response::Result::Failure(value) => InvokeContractResult::Failure {
2594 return_value: value.return_value.map(|b| ReturnValue { value: b }),
2595 reason: Upward::from(value.reason.map(TryFrom::try_from).transpose()?),
2596 used_energy: value.used_energy.require()?.into(),
2597 },
2598 invoke_instance_response::Result::Success(value) => InvokeContractResult::Success {
2599 return_value: value.return_value.map(|b| ReturnValue { value: b }),
2600 events: value
2601 .effects
2602 .into_iter()
2603 .map(|trace| {
2604 Ok(Upward::from(
2605 trace
2606 .element
2607 .map(super::types::ContractTraceElement::try_from)
2608 .transpose()?,
2609 ))
2610 })
2611 .collect::<Result<_, tonic::Status>>()?,
2612 used_energy: value.used_energy.require()?.into(),
2613 },
2614 };
2615 Ok(result)
2616 }
2617}
2618
2619impl TryFrom<CryptographicParameters> for super::types::CryptographicParameters {
2620 type Error = tonic::Status;
2621
2622 fn try_from(value: CryptographicParameters) -> Result<Self, Self::Error> {
2623 Ok(Self {
2624 genesis_string: value.genesis_string,
2625 on_chain_commitment_key: concordium_base::common::from_bytes(
2626 &mut std::io::Cursor::new(&value.on_chain_commitment_key),
2627 )
2628 .map_err(|_| tonic::Status::internal("Invalid on_chain_commitment_key received"))?,
2629
2630 bulletproof_generators: concordium_base::common::from_bytes(&mut std::io::Cursor::new(
2631 &value.bulletproof_generators,
2632 ))
2633 .map_err(|_| tonic::Status::internal("Invalid bulletproof_generators received"))?,
2634 })
2635 }
2636}
2637
2638impl TryFrom<CredentialsPerBlockLimit> for super::types::CredentialsPerBlockLimit {
2639 type Error = tonic::Status;
2640
2641 fn try_from(value: CredentialsPerBlockLimit) -> Result<Self, Self::Error> {
2642 Ok(Self {
2643 limit: value.value.try_into().map_err(|_| {
2644 tonic::Status::internal("Unexpectedly large account creation limit")
2645 })?,
2646 })
2647 }
2648}
2649
2650impl TryFrom<TimeoutParameters> for chain_parameters::TimeoutParameters {
2651 type Error = tonic::Status;
2652
2653 fn try_from(value: TimeoutParameters) -> Result<Self, Self::Error> {
2654 Ok(Self {
2655 base: value.timeout_base.map(Into::into),
2656 increase: value.timeout_increase.map(TryInto::try_into).transpose()?,
2657 decrease: value.timeout_decrease.map(TryInto::try_into).transpose()?,
2658 })
2659 }
2660}
2661
2662impl From<CooldownParametersCpv1> for chain_parameters::CooldownParameters {
2663 fn from(value: CooldownParametersCpv1) -> Self {
2664 Self {
2665 baker_cooldown_epochs: None,
2666 pool_owner_cooldown: value.pool_owner_cooldown.map(Into::into),
2667 delegator_cooldown: value.delegator_cooldown.map(Into::into),
2668 }
2669 }
2670}
2671
2672impl From<MintDistributionCpv0> for chain_parameters::MintDistribution {
2673 fn from(value: MintDistributionCpv0) -> Self {
2674 Self {
2675 baking_reward: value.baking_reward.map(Into::into),
2676 finalization_reward: value.finalization_reward.map(Into::into),
2677 }
2678 }
2679}
2680
2681impl From<MintDistributionCpv1> for chain_parameters::MintDistribution {
2682 fn from(value: MintDistributionCpv1) -> Self {
2683 Self {
2684 baking_reward: value.baking_reward.map(Into::into),
2685 finalization_reward: value.finalization_reward.map(Into::into),
2686 }
2687 }
2688}
2689
2690impl From<TransactionFeeDistribution> for chain_parameters::TransactionFeeDistribution {
2691 fn from(value: TransactionFeeDistribution) -> Self {
2692 Self {
2693 baker: value.baker.map(Into::into),
2694 gas_account: value.gas_account.map(Into::into),
2695 }
2696 }
2697}
2698
2699impl From<GasRewards> for chain_parameters::GasRewards {
2700 fn from(value: GasRewards) -> Self {
2701 Self {
2702 baker: value.baker.map(Into::into),
2703 finalization_proof: value.finalization_proof.map(Into::into),
2704 account_creation: value.account_creation.map(Into::into),
2705 chain_update: value.chain_update.map(Into::into),
2706 }
2707 }
2708}
2709
2710impl From<GasRewardsCpv2> for chain_parameters::GasRewards {
2711 fn from(value: GasRewardsCpv2) -> Self {
2712 Self {
2713 baker: value.baker.map(Into::into),
2714 finalization_proof: None,
2715 account_creation: value.account_creation.map(Into::into),
2716 chain_update: value.chain_update.map(Into::into),
2717 }
2718 }
2719}
2720
2721impl TryFrom<PoolParametersCpv1> for chain_parameters::StakingParameters {
2722 type Error = tonic::Status;
2723
2724 fn try_from(value: PoolParametersCpv1) -> Result<Self, Self::Error> {
2725 Ok(Self {
2726 passive_finalization_commission: value.passive_finalization_commission.map(Into::into),
2727 passive_baking_commission: value.passive_baking_commission.map(Into::into),
2728 passive_transaction_commission: value.passive_transaction_commission.map(Into::into),
2729 finalization_commission_range: value
2730 .commission_bounds
2731 .as_ref()
2732 .and_then(|cb| cb.finalization.map(TryInto::try_into))
2733 .transpose()?,
2734 baking_commission_range: value
2735 .commission_bounds
2736 .as_ref()
2737 .and_then(|cb| cb.baking.map(TryInto::try_into))
2738 .transpose()?,
2739 transaction_commission_range: value
2740 .commission_bounds
2741 .as_ref()
2742 .and_then(|cb| cb.transaction.map(TryInto::try_into))
2743 .transpose()?,
2744 minimum_equity_capital: value.minimum_equity_capital.map(Into::into),
2745 capital_bound: value.capital_bound.map(TryInto::try_into).transpose()?,
2746 leverage_bound: value.leverage_bound.map(TryInto::try_into).transpose()?,
2747 })
2748 }
2749}
2750
2751impl From<FinalizationCommitteeParameters> for chain_parameters::FinalizationCommitteeParameters {
2752 fn from(value: FinalizationCommitteeParameters) -> Self {
2753 Self {
2754 min_finalizers: Some(value.minimum_finalizers),
2755 max_finalizers: Some(value.maximum_finalizers),
2756 finalizers_relative_stake_threshold: value
2757 .finalizer_relative_stake_threshold
2758 .map(Into::into),
2759 }
2760 }
2761}
2762
2763impl TryFrom<ChainParametersV0> for chain_parameters::ChainParameters {
2764 type Error = tonic::Status;
2765
2766 fn try_from(value: ChainParametersV0) -> Result<Self, Self::Error> {
2767 Ok(Self {
2768 timeout_parameters: Default::default(),
2769 election_difficulty: value
2770 .election_difficulty
2771 .map(TryInto::try_into)
2772 .transpose()?,
2773 min_block_time: None,
2774 block_energy_limit: None,
2775 euro_per_energy: value.euro_per_energy.map(TryInto::try_into).transpose()?,
2776 micro_ccd_per_euro: value
2777 .micro_ccd_per_euro
2778 .map(TryInto::try_into)
2779 .transpose()?,
2780 cooldown_parameters: value
2781 .baker_cooldown_epochs
2782 .map(|bce| chain_parameters::CooldownParameters {
2783 baker_cooldown_epochs: Some(bce.into()),
2784 pool_owner_cooldown: None,
2785 delegator_cooldown: None,
2786 })
2787 .unwrap_or_default(),
2788 reward_period_length: None,
2789 mint_per_payday: None,
2790 mint_per_slot: value
2791 .mint_distribution
2792 .and_then(|md| md.mint_per_slot.map(TryInto::try_into))
2793 .transpose()?,
2794 mint_distribution: value.mint_distribution.map(Into::into).unwrap_or_default(),
2795 account_creation_limit: value
2796 .account_creation_limit
2797 .map(TryInto::try_into)
2798 .transpose()?,
2799 transaction_fee_distribution: value
2800 .transaction_fee_distribution
2801 .map(Into::into)
2802 .unwrap_or_default(),
2803 gas_rewards: value.gas_rewards.map(Into::into).unwrap_or_default(),
2804 foundation_account: value
2805 .foundation_account
2806 .map(TryInto::try_into)
2807 .transpose()?,
2808 staking_parameters: value
2809 .minimum_threshold_for_baking
2810 .map(|mtfb| chain_parameters::StakingParameters {
2811 minimum_equity_capital: Some(mtfb.into()),
2812 ..Default::default()
2813 })
2814 .unwrap_or_default(),
2815 finalization_committee_parameters: Default::default(),
2816 validator_max_missed_rounds: None,
2817
2818 keys: chain_parameters::UpdateKeys {
2819 root_keys: value.root_keys.map(TryInto::try_into).transpose()?,
2820 level_1_keys: value.level1_keys.map(TryInto::try_into).transpose()?,
2821 level_2_keys: value.level2_keys.map(TryInto::try_into).transpose()?,
2822 },
2823 })
2824 }
2825}
2826
2827impl TryFrom<ChainParametersV1> for chain_parameters::ChainParameters {
2828 type Error = tonic::Status;
2829
2830 fn try_from(value: ChainParametersV1) -> Result<Self, Self::Error> {
2831 Ok(Self {
2832 timeout_parameters: Default::default(),
2833 election_difficulty: value
2834 .election_difficulty
2835 .map(TryInto::try_into)
2836 .transpose()?,
2837 min_block_time: None,
2838 block_energy_limit: None,
2839 euro_per_energy: value.euro_per_energy.map(TryInto::try_into).transpose()?,
2840 micro_ccd_per_euro: value
2841 .micro_ccd_per_euro
2842 .map(TryInto::try_into)
2843 .transpose()?,
2844 cooldown_parameters: value
2845 .cooldown_parameters
2846 .map(Into::into)
2847 .unwrap_or_default(),
2848 reward_period_length: value
2849 .time_parameters
2850 .as_ref()
2851 .and_then(|tp| tp.reward_period_length.map(TryInto::try_into))
2852 .transpose()?,
2853 mint_per_payday: value
2854 .time_parameters
2855 .as_ref()
2856 .and_then(|tp| tp.mint_per_payday.map(TryInto::try_into))
2857 .transpose()?,
2858 mint_per_slot: None,
2859 account_creation_limit: value
2860 .account_creation_limit
2861 .map(TryInto::try_into)
2862 .transpose()?,
2863 mint_distribution: value.mint_distribution.map(Into::into).unwrap_or_default(),
2864 transaction_fee_distribution: value
2865 .transaction_fee_distribution
2866 .map(Into::into)
2867 .unwrap_or_default(),
2868 gas_rewards: value.gas_rewards.map(Into::into).unwrap_or_default(),
2869 foundation_account: value
2870 .foundation_account
2871 .map(TryInto::try_into)
2872 .transpose()?,
2873 staking_parameters: value
2874 .pool_parameters
2875 .map(TryInto::try_into)
2876 .transpose()?
2877 .unwrap_or_default(),
2878 finalization_committee_parameters: Default::default(),
2879 validator_max_missed_rounds: None,
2880 keys: chain_parameters::UpdateKeys {
2881 root_keys: value.root_keys.map(TryInto::try_into).transpose()?,
2882 level_1_keys: value.level1_keys.map(TryInto::try_into).transpose()?,
2883 level_2_keys: value.level2_keys.map(TryInto::try_into).transpose()?,
2884 },
2885 })
2886 }
2887}
2888
2889impl TryFrom<ChainParametersV2> for chain_parameters::ChainParameters {
2890 type Error = tonic::Status;
2891
2892 fn try_from(value: ChainParametersV2) -> Result<Self, Self::Error> {
2893 Ok(Self {
2894 timeout_parameters: value
2895 .consensus_parameters
2896 .as_ref()
2897 .and_then(|cp| cp.timeout_parameters.map(TryInto::try_into))
2898 .transpose()?
2899 .unwrap_or_default(),
2900 election_difficulty: None,
2901 min_block_time: value
2902 .consensus_parameters
2903 .as_ref()
2904 .and_then(|cp| cp.min_block_time.map(Into::into)),
2905 block_energy_limit: value
2906 .consensus_parameters
2907 .as_ref()
2908 .and_then(|cp| cp.block_energy_limit.map(Into::into)),
2909 euro_per_energy: value.euro_per_energy.map(TryInto::try_into).transpose()?,
2910 micro_ccd_per_euro: value
2911 .micro_ccd_per_euro
2912 .map(TryInto::try_into)
2913 .transpose()?,
2914 cooldown_parameters: value
2915 .cooldown_parameters
2916 .map(Into::into)
2917 .unwrap_or_default(),
2918 reward_period_length: value
2919 .time_parameters
2920 .as_ref()
2921 .and_then(|tp| tp.reward_period_length.map(TryInto::try_into))
2922 .transpose()?,
2923 mint_per_payday: value
2924 .time_parameters
2925 .as_ref()
2926 .and_then(|tp| tp.mint_per_payday.map(TryInto::try_into))
2927 .transpose()?,
2928 mint_per_slot: None,
2929 account_creation_limit: value
2930 .account_creation_limit
2931 .map(TryInto::try_into)
2932 .transpose()?,
2933 mint_distribution: value.mint_distribution.map(Into::into).unwrap_or_default(),
2934 transaction_fee_distribution: value
2935 .transaction_fee_distribution
2936 .map(Into::into)
2937 .unwrap_or_default(),
2938 gas_rewards: value.gas_rewards.map(Into::into).unwrap_or_default(),
2939 foundation_account: value
2940 .foundation_account
2941 .map(TryInto::try_into)
2942 .transpose()?,
2943 staking_parameters: value
2944 .pool_parameters
2945 .map(TryInto::try_into)
2946 .transpose()?
2947 .unwrap_or_default(),
2948 finalization_committee_parameters: value
2949 .finalization_committee_parameters
2950 .map(Into::into)
2951 .unwrap_or_default(),
2952 validator_max_missed_rounds: None,
2953 keys: chain_parameters::UpdateKeys {
2954 root_keys: value.root_keys.map(TryInto::try_into).transpose()?,
2955 level_1_keys: value.level1_keys.map(TryInto::try_into).transpose()?,
2956 level_2_keys: value.level2_keys.map(TryInto::try_into).transpose()?,
2957 },
2958 })
2959 }
2960}
2961
2962impl TryFrom<ChainParametersV3> for chain_parameters::ChainParameters {
2963 type Error = tonic::Status;
2964
2965 fn try_from(value: ChainParametersV3) -> Result<Self, Self::Error> {
2966 Ok(Self {
2967 timeout_parameters: value
2968 .consensus_parameters
2969 .as_ref()
2970 .and_then(|cp| cp.timeout_parameters.map(TryInto::try_into))
2971 .transpose()?
2972 .unwrap_or_default(),
2973 election_difficulty: None,
2974 min_block_time: value
2975 .consensus_parameters
2976 .as_ref()
2977 .and_then(|cp| cp.min_block_time.map(Into::into)),
2978 block_energy_limit: value
2979 .consensus_parameters
2980 .as_ref()
2981 .and_then(|cp| cp.block_energy_limit.map(Into::into)),
2982 euro_per_energy: value.euro_per_energy.map(TryInto::try_into).transpose()?,
2983 micro_ccd_per_euro: value
2984 .micro_ccd_per_euro
2985 .map(TryInto::try_into)
2986 .transpose()?,
2987 cooldown_parameters: value
2988 .cooldown_parameters
2989 .map(Into::into)
2990 .unwrap_or_default(),
2991 reward_period_length: value
2992 .time_parameters
2993 .as_ref()
2994 .and_then(|tp| tp.reward_period_length.map(TryInto::try_into))
2995 .transpose()?,
2996 mint_per_payday: value
2997 .time_parameters
2998 .as_ref()
2999 .and_then(|tp| tp.mint_per_payday.map(TryInto::try_into))
3000 .transpose()?,
3001 mint_per_slot: None,
3002 account_creation_limit: value
3003 .account_creation_limit
3004 .map(TryInto::try_into)
3005 .transpose()?,
3006 mint_distribution: value.mint_distribution.map(Into::into).unwrap_or_default(),
3007 transaction_fee_distribution: value
3008 .transaction_fee_distribution
3009 .map(Into::into)
3010 .unwrap_or_default(),
3011 gas_rewards: value.gas_rewards.map(Into::into).unwrap_or_default(),
3012 foundation_account: value
3013 .foundation_account
3014 .map(TryInto::try_into)
3015 .transpose()?,
3016 staking_parameters: value
3017 .pool_parameters
3018 .map(TryInto::try_into)
3019 .transpose()?
3020 .unwrap_or_default(),
3021 finalization_committee_parameters: value
3022 .finalization_committee_parameters
3023 .map(Into::into)
3024 .unwrap_or_default(),
3025 validator_max_missed_rounds: value
3026 .validator_score_parameters
3027 .map(|vsp| vsp.maximum_missed_rounds),
3028 keys: chain_parameters::UpdateKeys {
3029 root_keys: value.root_keys.map(TryInto::try_into).transpose()?,
3030 level_1_keys: value.level1_keys.map(TryInto::try_into).transpose()?,
3031 level_2_keys: value.level2_keys.map(TryInto::try_into).transpose()?,
3032 },
3033 })
3034 }
3035}
3036
3037impl TryFrom<ChainParameters> for chain_parameters::ChainParameters {
3038 type Error = tonic::Status;
3039
3040 fn try_from(value: ChainParameters) -> Result<Self, Self::Error> {
3041 match value.parameters.require()? {
3042 generated::chain_parameters::Parameters::V0(v0) => v0.try_into(),
3043 generated::chain_parameters::Parameters::V1(v1) => v1.try_into(),
3044 generated::chain_parameters::Parameters::V2(v2) => v2.try_into(),
3045 generated::chain_parameters::Parameters::V3(v3) => v3.try_into(),
3046 }
3047 }
3048}
3049
3050impl TryFrom<FinalizationSummaryParty> for super::types::FinalizationSummaryParty {
3051 type Error = tonic::Status;
3052
3053 fn try_from(value: FinalizationSummaryParty) -> Result<Self, Self::Error> {
3054 Ok(Self {
3055 baker_id: value.baker.require()?.into(),
3056 weight: value.weight,
3057 signed: value.signed,
3058 })
3059 }
3060}
3061
3062impl From<FinalizationIndex> for super::types::FinalizationIndex {
3063 fn from(value: FinalizationIndex) -> Self {
3064 value.value.into()
3065 }
3066}
3067
3068impl TryFrom<BlockFinalizationSummary> for Option<super::types::FinalizationSummary> {
3069 type Error = tonic::Status;
3070
3071 fn try_from(value: BlockFinalizationSummary) -> Result<Self, Self::Error> {
3072 match value.summary.require()? {
3073 block_finalization_summary::Summary::None(_) => Ok(None),
3074 block_finalization_summary::Summary::Record(r) => {
3075 Ok(Some(super::types::FinalizationSummary {
3076 block_pointer: r.block.require()?.try_into()?,
3077 index: r.index.require()?.into(),
3078 delay: r.delay.require()?.into(),
3079 finalizers: r
3080 .finalizers
3081 .into_iter()
3082 .map(super::types::FinalizationSummaryParty::try_from)
3083 .collect::<Result<_, tonic::Status>>()?,
3084 }))
3085 }
3086 }
3087 }
3088}
3089
3090impl TryFrom<BlockInfo> for super::types::queries::BlockInfo {
3091 type Error = tonic::Status;
3092
3093 fn try_from(value: BlockInfo) -> Result<Self, Self::Error> {
3094 let protocol_version = protocol_version_int_from_enum(value.protocol_version)?;
3095
3096 Ok(Self {
3097 transactions_size: value.transactions_size.into(),
3098 block_parent: value.parent_block.require()?.try_into()?,
3099 block_hash: value.hash.require()?.try_into()?,
3100 finalized: value.finalized,
3101 block_state_hash: value.state_hash.require()?.try_into()?,
3102 block_arrive_time: value.arrive_time.require()?.try_into()?,
3103 block_receive_time: value.receive_time.require()?.try_into()?,
3104 transaction_count: value.transaction_count.into(),
3105 transaction_energy_cost: value.transactions_energy_cost.require()?.into(),
3106 block_slot: if protocol_version <= super::types::ProtocolVersion::P5.into() {
3107 Some(value.slot_number.require()?.into())
3108 } else {
3109 None
3110 },
3111 block_last_finalized: value.last_finalized_block.require()?.try_into()?,
3112 block_slot_time: value.slot_time.require()?.try_into()?,
3113 block_height: value.height.require()?.into(),
3114 era_block_height: value.era_block_height.require()?.into(),
3115 genesis_index: value.genesis_index.require()?.into(),
3116 block_baker: value.baker.map(|b| b.into()),
3117 protocol_version,
3118 round: if protocol_version >= super::types::ProtocolVersion::P6.into() {
3119 Some(value.round.require()?.into())
3120 } else {
3121 None
3122 },
3123 epoch: if protocol_version >= super::types::ProtocolVersion::P6.into() {
3124 Some(value.epoch.require()?.into())
3125 } else {
3126 None
3127 },
3128 })
3129 }
3130}
3131
3132impl TryFrom<PoolInfoResponse> for super::types::BakerPoolStatus {
3133 type Error = tonic::Status;
3134
3135 fn try_from(value: PoolInfoResponse) -> Result<Self, Self::Error> {
3136 let active_baker_pool_status = match value.pool_info {
3139 None => None,
3140 Some(pi) => Some(ActiveBakerPoolStatus {
3141 baker_equity_capital: value.equity_capital.require()?.into(),
3142 delegated_capital: value.delegated_capital.require()?.into(),
3143 delegated_capital_cap: value.delegated_capital_cap.require()?.into(),
3144 pool_info: pi.try_into()?,
3145 baker_stake_pending_change: value.equity_pending_change.try_into()?,
3146 }),
3147 };
3148
3149 Ok(Self {
3150 baker_id: value.baker.require()?.into(),
3151 baker_address: value.address.require()?.try_into()?,
3152 active_baker_pool_status,
3153 current_payday_status: if let Some(v) = value.current_payday_info {
3154 Some(v.try_into()?)
3155 } else {
3156 None
3157 },
3158 all_pool_total_capital: value.all_pool_total_capital.require()?.into(),
3159 })
3160 }
3161}
3162
3163impl TryFrom<Option<PoolPendingChange>> for super::types::PoolPendingChange {
3164 type Error = tonic::Status;
3165
3166 fn try_from(value: Option<PoolPendingChange>) -> Result<Self, Self::Error> {
3167 if let Some(value) = value {
3168 match value.change.require()? {
3169 pool_pending_change::Change::Reduce(rs) => Ok(Self::ReduceBakerCapital {
3170 baker_equity_capital: rs.reduced_equity_capital.require()?.into(),
3171 effective_time: rs.effective_time.require()?.try_into()?,
3172 }),
3173 pool_pending_change::Change::Remove(rs) => Ok(Self::RemovePool {
3174 effective_time: rs.effective_time.require()?.try_into()?,
3175 }),
3176 }
3177 } else {
3178 Ok(Self::NoChange)
3179 }
3180 }
3181}
3182
3183impl TryFrom<PoolCurrentPaydayInfo> for super::types::CurrentPaydayBakerPoolStatus {
3184 type Error = tonic::Status;
3185
3186 fn try_from(value: PoolCurrentPaydayInfo) -> Result<Self, Self::Error> {
3187 Ok(Self {
3188 blocks_baked: value.blocks_baked,
3189 finalization_live: value.finalization_live,
3190 transaction_fees_earned: value.transaction_fees_earned.require()?.into(),
3191 effective_stake: value.effective_stake.require()?.into(),
3192 lottery_power: value.lottery_power,
3193 baker_equity_capital: value.baker_equity_capital.require()?.into(),
3194 delegated_capital: value.delegated_capital.require()?.into(),
3195 commission_rates: value.commission_rates.require()?.try_into()?,
3196 })
3197 }
3198}
3199
3200impl TryFrom<PassiveDelegationInfo> for super::types::PassiveDelegationStatus {
3201 type Error = tonic::Status;
3202
3203 fn try_from(value: PassiveDelegationInfo) -> Result<Self, Self::Error> {
3204 Ok(Self {
3205 delegated_capital: value.delegated_capital.require()?.into(),
3206 commission_rates: value.commission_rates.require()?.try_into()?,
3207 current_payday_transaction_fees_earned: value
3208 .current_payday_transaction_fees_earned
3209 .require()?
3210 .into(),
3211 current_payday_delegated_capital: value
3212 .current_payday_delegated_capital
3213 .require()?
3214 .into(),
3215 all_pool_total_capital: value.all_pool_total_capital.require()?.into(),
3216 })
3217 }
3218}
3219
3220impl From<&super::endpoints::BlocksAtHeightInput> for BlocksAtHeightRequest {
3221 fn from(&input: &super::endpoints::BlocksAtHeightInput) -> Self {
3222 let blocks_at_height = match input {
3223 super::endpoints::BlocksAtHeightInput::Absolute { height } => {
3224 blocks_at_height_request::BlocksAtHeight::Absolute(
3225 blocks_at_height_request::Absolute {
3226 height: Some(height.into()),
3227 },
3228 )
3229 }
3230
3231 super::endpoints::BlocksAtHeightInput::Relative {
3232 height,
3233 genesis_index,
3234 restrict,
3235 } => blocks_at_height_request::BlocksAtHeight::Relative(
3236 blocks_at_height_request::Relative {
3237 height: Some(height.into()),
3238 genesis_index: Some(genesis_index.into()),
3239 restrict,
3240 },
3241 ),
3242 };
3243 BlocksAtHeightRequest {
3244 blocks_at_height: Some(blocks_at_height),
3245 }
3246 }
3247}
3248
3249impl TryFrom<TokenomicsInfo> for super::types::RewardsOverview {
3250 type Error = tonic::Status;
3251
3252 fn try_from(value: TokenomicsInfo) -> Result<Self, Self::Error> {
3253 match value.tokenomics.require()? {
3254 tokenomics_info::Tokenomics::V0(value) => Ok(Self::V0 {
3255 data: super::types::CommonRewardData {
3256 protocol_version: protocol_version_int_from_enum(value.protocol_version)?,
3257 total_amount: value.total_amount.require()?.into(),
3258 total_encrypted_amount: value.total_encrypted_amount.require()?.into(),
3259 baking_reward_account: value.baking_reward_account.require()?.into(),
3260 finalization_reward_account: value
3261 .finalization_reward_account
3262 .require()?
3263 .into(),
3264 gas_account: value.gas_account.require()?.into(),
3265 },
3266 }),
3267 tokenomics_info::Tokenomics::V1(value) => Ok(Self::V1 {
3268 common: super::types::CommonRewardData {
3269 protocol_version: protocol_version_int_from_enum(value.protocol_version)?,
3270 total_amount: value.total_amount.require()?.into(),
3271 total_encrypted_amount: value.total_encrypted_amount.require()?.into(),
3272 baking_reward_account: value.baking_reward_account.require()?.into(),
3273 finalization_reward_account: value
3274 .finalization_reward_account
3275 .require()?
3276 .into(),
3277 gas_account: value.gas_account.require()?.into(),
3278 },
3279 foundation_transaction_rewards: value
3280 .foundation_transaction_rewards
3281 .require()?
3282 .into(),
3283 next_payday_time: value.next_payday_time.require()?.try_into()?,
3284 next_payday_mint_rate: value.next_payday_mint_rate.require()?.try_into()?,
3285 total_staked_capital: value.total_staked_capital.require()?.into(),
3286 }),
3287 }
3288 }
3289}
3290
3291impl TryFrom<Branch> for super::types::queries::Branch {
3292 type Error = tonic::Status;
3293
3294 fn try_from(value: Branch) -> Result<Self, Self::Error> {
3295 let mut next = Vec::new();
3297 let mut dfs = Vec::new();
3299
3300 next.extend(value.children.iter());
3302 dfs.push(&value);
3303 while let Some(value) = next.pop() {
3304 dfs.push(value);
3305 next.extend(value.children.iter());
3306 }
3307
3308 let mut nodes = Vec::new();
3310 while let Some(value) = dfs.pop() {
3311 let mut children = Vec::new();
3312 for _ in 0..value.children.len() {
3313 children.push(nodes.pop().require()?);
3315 }
3316
3317 let node = Self {
3318 block_hash: value.block_hash.clone().require()?.try_into()?,
3319 children,
3320 };
3321 nodes.push(node)
3322 }
3323
3324 let root = nodes.pop().require()?;
3326 Ok(root)
3327 }
3328}
3329
3330impl TryFrom<election_info::Baker> for super::types::BirkBaker {
3331 type Error = tonic::Status;
3332
3333 fn try_from(info: election_info::Baker) -> Result<Self, Self::Error> {
3334 Ok(Self {
3335 baker_id: info.baker.require()?.into(),
3336 baker_lottery_power: info.lottery_power,
3337 baker_account: info.account.require()?.try_into()?,
3338 })
3339 }
3340}
3341
3342impl TryFrom<ElectionInfo> for super::types::BirkParameters {
3343 type Error = tonic::Status;
3344
3345 fn try_from(info: ElectionInfo) -> Result<Self, Self::Error> {
3346 Ok(Self {
3347 election_difficulty: info.election_difficulty.map(|x| x.try_into()).transpose()?,
3348 election_nonce: info.election_nonce.require()?.try_into()?,
3349 bakers: info
3350 .baker_election_info
3351 .into_iter()
3352 .map(|c| c.try_into())
3353 .collect::<Result<_, _>>()?,
3354 })
3355 }
3356}
3357
3358impl TryFrom<block_special_event::AccountAmounts>
3359 for BTreeMap<super::AccountAddress, super::Amount>
3360{
3361 type Error = tonic::Status;
3362
3363 fn try_from(message: block_special_event::AccountAmounts) -> Result<Self, Self::Error> {
3364 fn mapper(
3365 entry: block_special_event::account_amounts::Entry,
3366 ) -> Result<(super::AccountAddress, super::Amount), tonic::Status> {
3367 Ok((
3368 entry.account.require()?.try_into()?,
3369 entry.amount.require()?.into(),
3370 ))
3371 }
3372
3373 message
3374 .entries
3375 .into_iter()
3376 .map(mapper)
3377 .collect::<Result<_, _>>()
3378 }
3379}
3380
3381impl TryFrom<block_special_event::Event> for super::types::SpecialTransactionOutcome {
3382 type Error = tonic::Status;
3383
3384 fn try_from(special_event: block_special_event::Event) -> Result<Self, Self::Error> {
3385 let event = match special_event {
3386 block_special_event::Event::BakingRewards(event) => Self::BakingRewards {
3387 baker_rewards: event.baker_rewards.require()?.try_into()?,
3388 remainder: event.remainder.require()?.into(),
3389 },
3390 block_special_event::Event::Mint(event) => Self::Mint {
3391 mint_baking_reward: event.mint_baking_reward.require()?.into(),
3392 mint_finalization_reward: event.mint_finalization_reward.require()?.into(),
3393 mint_platform_development_charge: event
3394 .mint_platform_development_charge
3395 .require()?
3396 .into(),
3397 foundation_account: event.foundation_account.require()?.try_into()?,
3398 },
3399 block_special_event::Event::FinalizationRewards(event) => Self::FinalizationRewards {
3400 finalization_rewards: event.finalization_rewards.require()?.try_into()?,
3401 remainder: event.remainder.require()?.into(),
3402 },
3403 block_special_event::Event::BlockReward(event) => Self::BlockReward {
3404 transaction_fees: event.transaction_fees.require()?.into(),
3405 old_gas_account: event.old_gas_account.require()?.into(),
3406 new_gas_account: event.new_gas_account.require()?.into(),
3407 baker_reward: event.baker_reward.require()?.into(),
3408 foundation_charge: event.foundation_charge.require()?.into(),
3409 baker: event.baker.require()?.try_into()?,
3410 foundation_account: event.foundation_account.require()?.try_into()?,
3411 },
3412 block_special_event::Event::PaydayFoundationReward(event) => {
3413 Self::PaydayFoundationReward {
3414 foundation_account: event.foundation_account.require()?.try_into()?,
3415 development_charge: event.development_charge.require()?.into(),
3416 }
3417 }
3418 block_special_event::Event::PaydayAccountReward(event) => Self::PaydayAccountReward {
3419 account: event.account.require()?.try_into()?,
3420 transaction_fees: event.transaction_fees.require()?.into(),
3421 baker_reward: event.baker_reward.require()?.into(),
3422 finalization_reward: event.finalization_reward.require()?.into(),
3423 },
3424 block_special_event::Event::BlockAccrueReward(event) => Self::BlockAccrueReward {
3425 transaction_fees: event.transaction_fees.require()?.into(),
3426 old_gas_account: event.old_gas_account.require()?.into(),
3427 new_gas_account: event.new_gas_account.require()?.into(),
3428 baker_reward: event.baker_reward.require()?.into(),
3429 passive_reward: event.passive_reward.require()?.into(),
3430 foundation_charge: event.foundation_charge.require()?.into(),
3431 baker_id: event.baker.require()?.into(),
3432 },
3433 block_special_event::Event::PaydayPoolReward(event) => Self::PaydayPoolReward {
3434 pool_owner: event.pool_owner.map(|b| b.into()),
3435 transaction_fees: event.transaction_fees.require()?.into(),
3436 baker_reward: event.baker_reward.require()?.into(),
3437 finalization_reward: event.finalization_reward.require()?.into(),
3438 },
3439 block_special_event::Event::ValidatorSuspended(event) => Self::ValidatorSuspended {
3440 baker_id: event.baker_id.require()?.into(),
3441 account: event.account.require()?.try_into()?,
3442 },
3443 block_special_event::Event::ValidatorPrimedForSuspension(event) => {
3444 Self::ValidatorPrimedForSuspension {
3445 baker_id: event.baker_id.require()?.into(),
3446 account: event.account.require()?.try_into()?,
3447 }
3448 }
3449 };
3450 Ok(event)
3451 }
3452}
3453
3454impl TryFrom<BlockSpecialEvent> for Upward<super::types::SpecialTransactionOutcome> {
3455 type Error = tonic::Status;
3456
3457 fn try_from(message: BlockSpecialEvent) -> Result<Self, Self::Error> {
3458 let event = message
3459 .event
3460 .map(super::types::SpecialTransactionOutcome::try_from)
3461 .transpose()?;
3462 Ok(Upward::from(event))
3463 }
3464}
3465
3466impl<K> TryFrom<HigherLevelKeys> for updates::HigherLevelAccessStructure<K> {
3467 type Error = tonic::Status;
3468
3469 fn try_from(message: HigherLevelKeys) -> Result<Self, Self::Error> {
3470 Ok(Self {
3471 keys: message
3472 .keys
3473 .into_iter()
3474 .map(TryFrom::try_from)
3475 .collect::<Result<_, _>>()?,
3476 threshold: message.threshold.require()?.try_into()?,
3477 _phantom: Default::default(),
3478 })
3479 }
3480}
3481
3482impl TryFrom<ProtocolUpdate> for updates::ProtocolUpdate {
3483 type Error = tonic::Status;
3484
3485 fn try_from(value: ProtocolUpdate) -> Result<Self, Self::Error> {
3486 let message = value.message;
3487 let specification_url = value.specification_url;
3488 let specification_hash = value.specification_hash.require()?.try_into()?;
3489 let specification_auxiliary_data = value.specification_auxiliary_data;
3490 Ok(Self {
3491 message,
3492 specification_url,
3493 specification_hash,
3494 specification_auxiliary_data,
3495 })
3496 }
3497}
3498
3499impl TryFrom<ExchangeRate> for base::ExchangeRate {
3500 type Error = tonic::Status;
3501
3502 fn try_from(value: ExchangeRate) -> Result<Self, Self::Error> {
3503 let ratio = value.value.require()?;
3504 Self::new(ratio.numerator, ratio.denominator)
3505 .ok_or_else(|| tonic::Status::internal("Not a valid exchange rate."))
3506 }
3507}
3508
3509impl TryFrom<MintDistributionCpv0> for base::MintDistributionV0 {
3510 type Error = tonic::Status;
3511
3512 fn try_from(value: MintDistributionCpv0) -> Result<Self, Self::Error> {
3513 Ok(Self {
3514 mint_per_slot: value.mint_per_slot.require()?.try_into()?,
3515 baking_reward: value.baking_reward.require()?.into(),
3516 finalization_reward: value.finalization_reward.require()?.into(),
3517 })
3518 }
3519}
3520
3521impl TryFrom<MintDistributionCpv1> for base::MintDistributionV1 {
3522 type Error = tonic::Status;
3523
3524 fn try_from(value: MintDistributionCpv1) -> Result<Self, Self::Error> {
3525 Ok(Self {
3526 baking_reward: value.baking_reward.require()?.into(),
3527 finalization_reward: value.finalization_reward.require()?.into(),
3528 })
3529 }
3530}
3531
3532impl TryFrom<TransactionFeeDistribution> for updates::TransactionFeeDistribution {
3533 type Error = tonic::Status;
3534
3535 fn try_from(value: TransactionFeeDistribution) -> Result<Self, Self::Error> {
3536 Ok(Self {
3537 baker: value.baker.require()?.into(),
3538 gas_account: value.gas_account.require()?.into(),
3539 })
3540 }
3541}
3542
3543impl TryFrom<GasRewards> for updates::GASRewards {
3544 type Error = tonic::Status;
3545
3546 fn try_from(value: GasRewards) -> Result<Self, Self::Error> {
3547 Ok(Self {
3548 baker: value.baker.require()?.into(),
3549 finalization_proof: value.finalization_proof.require()?.into(),
3550 account_creation: value.account_creation.require()?.into(),
3551 chain_update: value.chain_update.require()?.into(),
3552 })
3553 }
3554}
3555
3556impl TryFrom<GasRewardsCpv2> for updates::GASRewardsV1 {
3557 type Error = tonic::Status;
3558
3559 fn try_from(value: GasRewardsCpv2) -> Result<Self, Self::Error> {
3560 Ok(Self {
3561 baker: value.baker.require()?.into(),
3562 account_creation: value.account_creation.require()?.into(),
3563 chain_update: value.chain_update.require()?.into(),
3564 })
3565 }
3566}
3567
3568impl TryFrom<TimeoutParameters> for updates::TimeoutParameters {
3569 type Error = tonic::Status;
3570
3571 fn try_from(value: TimeoutParameters) -> Result<Self, Self::Error> {
3572 let base = value.timeout_base.require()?.into();
3573 let increase = value.timeout_increase.require()?.try_into()?;
3574 let decrease = value.timeout_decrease.require()?.try_into()?;
3575 Self::new(base, increase, decrease).map_err(|err| tonic::Status::internal(err.to_string()))
3576 }
3577}
3578
3579impl TryFrom<Ratio> for concordium_base::common::types::Ratio {
3580 type Error = tonic::Status;
3581
3582 fn try_from(value: Ratio) -> Result<Self, Self::Error> {
3583 Self::new(value.numerator, value.denominator)
3584 .map_err(|err| tonic::Status::internal(err.to_string()))
3585 }
3586}
3587
3588impl TryFrom<FinalizationCommitteeParameters> for updates::FinalizationCommitteeParameters {
3589 type Error = tonic::Status;
3590
3591 fn try_from(value: FinalizationCommitteeParameters) -> Result<Self, Self::Error> {
3592 Ok(Self {
3593 min_finalizers: value.minimum_finalizers,
3594 max_finalizers: value.maximum_finalizers,
3595 finalizers_relative_stake_threshold: value
3596 .finalizer_relative_stake_threshold
3597 .require()?
3598 .into(),
3599 })
3600 }
3601}
3602
3603impl TryFrom<ValidatorScoreParameters> for updates::ValidatorScoreParameters {
3604 type Error = tonic::Status;
3605
3606 fn try_from(value: ValidatorScoreParameters) -> Result<Self, Self::Error> {
3607 Ok(Self {
3608 max_missed_rounds: value.maximum_missed_rounds,
3609 })
3610 }
3611}
3612
3613impl TryFrom<PoolParametersCpv1> for updates::PoolParameters {
3614 type Error = tonic::Status;
3615
3616 fn try_from(value: PoolParametersCpv1) -> Result<Self, Self::Error> {
3617 Ok(Self {
3618 passive_finalization_commission: value
3619 .passive_finalization_commission
3620 .require()?
3621 .into(),
3622 passive_baking_commission: value.passive_baking_commission.require()?.into(),
3623 passive_transaction_commission: value.passive_transaction_commission.require()?.into(),
3624 commission_bounds: value.commission_bounds.require()?.try_into()?,
3625 minimum_equity_capital: value.minimum_equity_capital.require()?.into(),
3626 capital_bound: value.capital_bound.require()?.try_into()?,
3627 leverage_bound: value.leverage_bound.require()?.try_into()?,
3628 })
3629 }
3630}
3631
3632impl TryFrom<LeverageFactor> for super::types::LeverageFactor {
3633 type Error = tonic::Status;
3634
3635 fn try_from(value: LeverageFactor) -> Result<Self, Self::Error> {
3636 let ratio = value.value.require()?;
3637 Self::new(ratio.numerator, ratio.denominator)
3638 .ok_or_else(|| tonic::Status::internal("Invalid leverage factor."))
3639 }
3640}
3641
3642impl TryFrom<CommissionRanges> for super::types::CommissionRanges {
3643 type Error = tonic::Status;
3644
3645 fn try_from(value: CommissionRanges) -> Result<Self, Self::Error> {
3646 Ok(Self {
3647 finalization: value.finalization.require()?.try_into()?,
3648 baking: value.baking.require()?.try_into()?,
3649 transaction: value.transaction.require()?.try_into()?,
3650 })
3651 }
3652}
3653
3654impl TryFrom<BakerStakeThreshold> for updates::BakerParameters {
3655 type Error = tonic::Status;
3656
3657 fn try_from(value: BakerStakeThreshold) -> Result<Self, Self::Error> {
3658 Ok(Self {
3659 minimum_threshold_for_baking: value.baker_stake_threshold.require()?.into(),
3660 })
3661 }
3662}
3663
3664impl TryFrom<CooldownParametersCpv1> for updates::CooldownParameters {
3665 type Error = tonic::Status;
3666
3667 fn try_from(value: CooldownParametersCpv1) -> Result<Self, Self::Error> {
3668 Ok(Self {
3669 pool_owner_cooldown: value.pool_owner_cooldown.require()?.into(),
3670 delegator_cooldown: value.delegator_cooldown.require()?.into(),
3671 })
3672 }
3673}
3674
3675impl TryFrom<TimeParametersCpv1> for updates::TimeParameters {
3676 type Error = tonic::Status;
3677
3678 fn try_from(value: TimeParametersCpv1) -> Result<Self, Self::Error> {
3679 Ok(Self {
3680 reward_period_length: value.reward_period_length.require()?.try_into()?,
3681 mint_per_payday: value.mint_per_payday.require()?.try_into()?,
3682 })
3683 }
3684}
3685
3686impl TryFrom<RewardPeriodLength> for updates::RewardPeriodLength {
3687 type Error = tonic::Status;
3688
3689 fn try_from(value: RewardPeriodLength) -> Result<Self, Self::Error> {
3690 Ok(Self::from(base::Epoch::from(value.value.require()?)))
3691 }
3692}
3693
3694impl From<Epoch> for base::Epoch {
3695 fn from(value: Epoch) -> Self {
3696 Self { epoch: value.value }
3697 }
3698}
3699
3700impl From<Round> for base::Round {
3701 fn from(value: Round) -> Self {
3702 Self { round: value.value }
3703 }
3704}
3705
3706impl TryFrom<PendingUpdate> for super::types::queries::PendingUpdate {
3707 type Error = tonic::Status;
3708
3709 fn try_from(message: PendingUpdate) -> Result<Self, Self::Error> {
3710 let effective_time = message.effective_time.require()?.into();
3711 let effect = message
3712 .effect
3713 .map(super::types::queries::PendingUpdateEffect::try_from)
3714 .transpose()?
3715 .into();
3716 Ok(Self {
3717 effective_time,
3718 effect,
3719 })
3720 }
3721}
3722
3723impl TryFrom<pending_update::Effect> for super::types::queries::PendingUpdateEffect {
3724 type Error = tonic::Status;
3725
3726 fn try_from(effect: pending_update::Effect) -> Result<Self, Self::Error> {
3727 use super::types::queries::PendingUpdateEffect;
3728 let out = match effect {
3729 pending_update::Effect::RootKeys(e) => PendingUpdateEffect::RootKeys(e.try_into()?),
3730 pending_update::Effect::Level1Keys(l1) => {
3731 PendingUpdateEffect::Level1Keys(l1.try_into()?)
3732 }
3733 pending_update::Effect::Level2KeysCpv0(l2) => {
3734 PendingUpdateEffect::Level2KeysCPV0(l2.try_into()?)
3735 }
3736 pending_update::Effect::Level2KeysCpv1(l2) => {
3737 PendingUpdateEffect::Level2KeysCPV1(l2.try_into()?)
3738 }
3739 pending_update::Effect::Protocol(p) => PendingUpdateEffect::Protocol(p.try_into()?),
3740 pending_update::Effect::ElectionDifficulty(ed) => {
3741 PendingUpdateEffect::ElectionDifficulty(ed.try_into()?)
3742 }
3743 pending_update::Effect::EuroPerEnergy(ee) => {
3744 PendingUpdateEffect::EuroPerEnergy(ee.try_into()?)
3745 }
3746 pending_update::Effect::MicroCcdPerEuro(mpe) => {
3747 PendingUpdateEffect::MicroCcdPerEnergy(mpe.try_into()?)
3748 }
3749 pending_update::Effect::FoundationAccount(fa) => {
3750 PendingUpdateEffect::FoundationAccount(fa.try_into()?)
3751 }
3752 pending_update::Effect::MintDistributionCpv0(md) => {
3753 PendingUpdateEffect::MintDistributionV0(md.try_into()?)
3754 }
3755 pending_update::Effect::MintDistributionCpv1(md) => {
3756 PendingUpdateEffect::MintDistributionV1(md.try_into()?)
3757 }
3758 pending_update::Effect::TransactionFeeDistribution(tfd) => {
3759 PendingUpdateEffect::TransactionFeeDistribution(tfd.try_into()?)
3760 }
3761 pending_update::Effect::GasRewards(gr) => {
3762 PendingUpdateEffect::GasRewards(gr.try_into()?)
3763 }
3764 pending_update::Effect::PoolParametersCpv0(pp) => {
3765 PendingUpdateEffect::PoolParametersV0(pp.try_into()?)
3766 }
3767 pending_update::Effect::PoolParametersCpv1(pp) => {
3768 PendingUpdateEffect::PoolParametersV1(pp.try_into()?)
3769 }
3770 pending_update::Effect::AddAnonymityRevoker(aar) => {
3771 PendingUpdateEffect::AddAnonymityRevoker(Box::new(aar.try_into()?))
3772 }
3773 pending_update::Effect::AddIdentityProvider(aidp) => {
3774 PendingUpdateEffect::AddIdentityProvider(Box::new(aidp.try_into()?))
3775 }
3776 pending_update::Effect::CooldownParameters(cdp) => {
3777 PendingUpdateEffect::CooldownParameters(cdp.try_into()?)
3778 }
3779 pending_update::Effect::TimeParameters(tp) => {
3780 PendingUpdateEffect::TimeParameters(tp.try_into()?)
3781 }
3782 pending_update::Effect::GasRewardsCpv2(update) => {
3783 PendingUpdateEffect::GasRewardsV1(update.try_into()?)
3784 }
3785 pending_update::Effect::TimeoutParameters(update) => {
3786 PendingUpdateEffect::TimeoutParameters(update.try_into()?)
3787 }
3788 pending_update::Effect::MinBlockTime(update) => {
3789 PendingUpdateEffect::MinBlockTime(update.into())
3790 }
3791 pending_update::Effect::BlockEnergyLimit(update) => {
3792 PendingUpdateEffect::BlockEnergyLimit(update.into())
3793 }
3794 pending_update::Effect::FinalizationCommitteeParameters(update) => {
3795 PendingUpdateEffect::FinalizationCommitteeParameters(update.try_into()?)
3796 }
3797 pending_update::Effect::ValidatorScoreParameters(update) => {
3798 PendingUpdateEffect::ValidatorScoreParameters(update.try_into()?)
3799 }
3800 };
3801 Ok(out)
3802 }
3803}
3804
3805impl From<SequenceNumber> for super::types::UpdateSequenceNumber {
3806 fn from(message: SequenceNumber) -> Self {
3807 message.value.into()
3808 }
3809}
3810
3811impl From<UpdateSequenceNumber> for super::types::UpdateSequenceNumber {
3812 fn from(message: UpdateSequenceNumber) -> Self {
3813 message.value.into()
3814 }
3815}
3816
3817impl TryFrom<NextUpdateSequenceNumbers> for super::types::queries::NextUpdateSequenceNumbers {
3818 type Error = tonic::Status;
3819
3820 fn try_from(message: NextUpdateSequenceNumbers) -> Result<Self, Self::Error> {
3821 Ok(Self {
3822 root_keys: message.root_keys.require()?.into(),
3823 level_1_keys: message.level1_keys.require()?.into(),
3824 level_2_keys: message.level2_keys.require()?.into(),
3825 protocol: message.protocol.require()?.into(),
3826 election_difficulty: message.election_difficulty.require()?.into(),
3827 euro_per_energy: message.euro_per_energy.require()?.into(),
3828 micro_ccd_per_euro: message.micro_ccd_per_euro.require()?.into(),
3829 foundation_account: message.foundation_account.require()?.into(),
3830 mint_distribution: message.mint_distribution.require()?.into(),
3831 transaction_fee_distribution: message.transaction_fee_distribution.require()?.into(),
3832 gas_rewards: message.gas_rewards.require()?.into(),
3833 pool_parameters: message.pool_parameters.require()?.into(),
3834 add_anonymity_revoker: message.add_anonymity_revoker.require()?.into(),
3835 add_identity_provider: message.add_identity_provider.require()?.into(),
3836 cooldown_parameters: message.cooldown_parameters.require()?.into(),
3837 time_parameters: message.time_parameters.require()?.into(),
3838 timeout_parameters: message.timeout_parameters.require()?.into(),
3839 min_block_time: message.min_block_time.require()?.into(),
3840 block_energy_limit: message.block_energy_limit.require()?.into(),
3841 finalization_committee_parameters: message
3842 .finalization_committee_parameters
3843 .require()?
3844 .into(),
3845 validator_score_parameters: message
3846 .validator_score_parameters
3847 .map(Into::into)
3848 .unwrap_or_default(),
3849 protocol_level_tokens: message
3850 .protocol_level_tokens
3851 .map(Into::into)
3852 .unwrap_or_default(),
3853 })
3854 }
3855}
3856
3857impl TryFrom<QuorumSignature> for super::types::block_certificates::QuorumSignature {
3858 type Error = tonic::Status;
3859
3860 fn try_from(message: QuorumSignature) -> Result<Self, Self::Error> {
3861 consume(&message.value)
3862 }
3863}
3864
3865impl TryFrom<QuorumCertificate> for super::types::block_certificates::QuorumCertificate {
3866 type Error = tonic::Status;
3867
3868 fn try_from(message: QuorumCertificate) -> Result<Self, Self::Error> {
3869 Ok(Self {
3870 block_hash: message.block_hash.require()?.try_into()?,
3871 round: message.round.require()?.into(),
3872 epoch: message.epoch.require()?.into(),
3873 aggregate_signature: message.aggregate_signature.require()?.try_into()?,
3874 signatories: message
3875 .signatories
3876 .into_iter()
3877 .map(From::from)
3878 .collect::<BTreeSet<super::types::BakerId>>(),
3879 })
3880 }
3881}
3882
3883impl TryFrom<SuccessorProof> for super::hashes::SuccessorProof {
3884 type Error = tonic::Status;
3885
3886 fn try_from(message: SuccessorProof) -> Result<Self, Self::Error> {
3887 match message.value.try_into() {
3888 Ok(hash) => Ok(Self::new(hash)),
3889 Err(_) => Err(tonic::Status::internal(
3890 "Unexpected successor proof format.",
3891 )),
3892 }
3893 }
3894}
3895
3896impl TryFrom<EpochFinalizationEntry> for super::types::block_certificates::EpochFinalizationEntry {
3897 type Error = tonic::Status;
3898
3899 fn try_from(message: EpochFinalizationEntry) -> Result<Self, Self::Error> {
3900 Ok(Self {
3901 finalized_qc: message.finalized_qc.require()?.try_into()?,
3902 successor_qc: message.successor_qc.require()?.try_into()?,
3903 successor_proof: message.successor_proof.require()?.try_into()?,
3904 })
3905 }
3906}
3907
3908impl TryFrom<FinalizerRound> for super::types::block_certificates::FinalizerRound {
3909 type Error = tonic::Status;
3910
3911 fn try_from(message: FinalizerRound) -> Result<Self, Self::Error> {
3912 Ok(Self {
3913 round: message.round.require()?.into(),
3914 finalizers: message
3915 .finalizers
3916 .into_iter()
3917 .map(From::from)
3918 .collect::<Vec<super::types::BakerId>>(),
3919 })
3920 }
3921}
3922
3923impl TryFrom<TimeoutSignature> for super::types::block_certificates::TimeoutSignature {
3924 type Error = tonic::Status;
3925
3926 fn try_from(message: TimeoutSignature) -> Result<Self, Self::Error> {
3927 consume(&message.value)
3928 }
3929}
3930
3931impl TryFrom<TimeoutCertificate> for super::types::block_certificates::TimeoutCertificate {
3932 type Error = tonic::Status;
3933
3934 fn try_from(message: TimeoutCertificate) -> Result<Self, Self::Error> {
3935 Ok(
3936 Self {
3937 round: message.round.require()?.into(),
3938 min_epoch: message.min_epoch.require()?.into(),
3939 qc_rounds_first_epoch:
3940 message
3941 .qc_rounds_first_epoch
3942 .into_iter()
3943 .map(TryFrom::try_from)
3944 .collect::<Result<
3945 Vec<super::types::block_certificates::FinalizerRound>,
3946 tonic::Status,
3947 >>()?,
3948 qc_rounds_second_epoch:
3949 message
3950 .qc_rounds_second_epoch
3951 .into_iter()
3952 .map(TryFrom::try_from)
3953 .collect::<Result<
3954 Vec<super::types::block_certificates::FinalizerRound>,
3955 tonic::Status,
3956 >>()?,
3957 aggregate_signature: message.aggregate_signature.require()?.try_into()?,
3958 },
3959 )
3960 }
3961}
3962
3963impl TryFrom<BlockCertificates> for super::types::block_certificates::BlockCertificates {
3964 type Error = tonic::Status;
3965
3966 fn try_from(message: BlockCertificates) -> Result<Self, Self::Error> {
3967 Ok(Self {
3968 quorum_certificate: message
3969 .quorum_certificate
3970 .map(TryFrom::try_from)
3971 .transpose()?,
3972 timeout_certificate: message
3973 .timeout_certificate
3974 .map(TryFrom::try_from)
3975 .transpose()?,
3976 epoch_finalization_entry: message
3977 .epoch_finalization_entry
3978 .map(TryFrom::try_from)
3979 .transpose()?,
3980 })
3981 }
3982}
3983
3984impl TryFrom<WinningBaker> for super::types::WinningBaker {
3985 type Error = tonic::Status;
3986
3987 fn try_from(wb: WinningBaker) -> Result<Self, Self::Error> {
3988 Ok(Self {
3989 round: wb.round.require()?.value.into(),
3990 winner: super::types::BakerId {
3991 id: wb.winner.require()?.value.into(),
3992 },
3993 present: wb.present,
3994 })
3995 }
3996}
3997
3998impl TryFrom<AccountPending> for super::types::AccountPending {
3999 type Error = tonic::Status;
4000
4001 fn try_from(pending: AccountPending) -> Result<Self, Self::Error> {
4002 Ok(Self {
4003 account_index: pending.account_index.require()?.into(),
4004 first_timestamp: pending.first_timestamp.require()?.into(),
4005 })
4006 }
4007}
4008
4009impl TryFrom<BakerRewardPeriodInfo> for super::types::BakerRewardPeriodInfo {
4010 type Error = tonic::Status;
4011
4012 fn try_from(message: BakerRewardPeriodInfo) -> Result<Self, Self::Error> {
4013 Ok(Self {
4014 baker: message.baker.require()?.try_into()?,
4015 effective_stake: message.effective_stake.require()?.into(),
4016 commission_rates: message.commission_rates.require()?.try_into()?,
4017 equity_capital: message.equity_capital.require()?.into(),
4018 delegated_capital: message.delegated_capital.require()?.into(),
4019 is_finalizer: message.is_finalizer,
4020 })
4021 }
4022}
4023
4024impl From<FinalizerIndex> for super::types::block_certificates::raw::FinalizerIndex {
4025 fn from(value: FinalizerIndex) -> Self {
4026 Self { index: value.value }
4027 }
4028}
4029
4030impl TryFrom<QuorumMessage> for super::types::block_certificates::raw::QuorumMessage {
4031 type Error = tonic::Status;
4032
4033 fn try_from(message: QuorumMessage) -> Result<Self, Self::Error> {
4034 Ok(Self {
4035 signature: message.signature.require()?.try_into()?,
4036 block: message.block.require()?.try_into()?,
4037 finalizer: message.finalizer.require()?.into(),
4038 round: message.round.require()?.into(),
4039 epoch: message.epoch.require()?.into(),
4040 })
4041 }
4042}
4043
4044impl TryFrom<RawQuorumCertificate> for super::types::block_certificates::raw::QuorumCertificate {
4045 type Error = tonic::Status;
4046
4047 fn try_from(value: RawQuorumCertificate) -> Result<Self, Self::Error> {
4048 Ok(Self {
4049 block_hash: value.block_hash.require()?.try_into()?,
4050 round: value.round.require()?.into(),
4051 epoch: value.epoch.require()?.into(),
4052 aggregate_signature: value.aggregate_signature.require()?.try_into()?,
4053 signatories: value.signatories.into_iter().map(From::from).collect(),
4054 })
4055 }
4056}
4057
4058impl TryFrom<RawTimeoutCertificate> for super::types::block_certificates::raw::TimeoutCertificate {
4059 type Error = tonic::Status;
4060
4061 fn try_from(value: RawTimeoutCertificate) -> Result<Self, Self::Error> {
4062 Ok(Self {
4063 round: value.round.require()?.into(),
4064 min_epoch: value.min_epoch.require()?.into(),
4065 qc_rounds_first_epoch: value
4066 .qc_rounds_first_epoch
4067 .into_iter()
4068 .map(TryFrom::try_from)
4069 .collect::<Result<_, _>>()?,
4070 qc_rounds_second_epoch: value
4071 .qc_rounds_second_epoch
4072 .into_iter()
4073 .map(TryFrom::try_from)
4074 .collect::<Result<_, _>>()?,
4075 aggregate_signature: value.aggregate_signature.require()?.try_into()?,
4076 })
4077 }
4078}
4079
4080impl TryFrom<RawFinalizerRound> for super::types::block_certificates::raw::FinalizerRound {
4081 type Error = tonic::Status;
4082
4083 fn try_from(value: RawFinalizerRound) -> Result<Self, Self::Error> {
4084 Ok(Self {
4085 round: value.round.require()?.into(),
4086 finalizers: value.finalizers.into_iter().map(From::from).collect(),
4087 })
4088 }
4089}
4090
4091impl TryFrom<BlockSignature> for super::types::block_certificates::raw::BlockSignature {
4092 type Error = tonic::Status;
4093
4094 fn try_from(message: BlockSignature) -> Result<Self, Self::Error> {
4095 consume(&message.value)
4096 }
4097}
4098
4099impl TryFrom<TimeoutMessage> for super::types::block_certificates::raw::TimeoutMessage {
4100 type Error = tonic::Status;
4101
4102 fn try_from(value: TimeoutMessage) -> Result<Self, Self::Error> {
4103 Ok(Self {
4104 finalizer: value.finalizer.require()?.into(),
4105 round: value.round.require()?.into(),
4106 epoch: value.epoch.require()?.into(),
4107 quorum_certificate: value.quorum_certificate.require()?.try_into()?,
4108 signature: value.signature.require()?.try_into()?,
4109 message_signature: value.message_signature.require()?.try_into()?,
4110 })
4111 }
4112}
4113
4114impl TryFrom<RawFinalizationEntry> for super::types::block_certificates::raw::FinalizationEntry {
4115 type Error = tonic::Status;
4116
4117 fn try_from(value: RawFinalizationEntry) -> Result<Self, Self::Error> {
4118 Ok(Self {
4119 finalized_qc: value.finalized_qc.require()?.try_into()?,
4120 successor_qc: value.successor_qc.require()?.try_into()?,
4121 successor_proof: value.successor_proof.require()?.try_into()?,
4122 })
4123 }
4124}
4125
4126impl TryFrom<TimeoutMessages> for super::types::block_certificates::raw::TimeoutMessages {
4127 type Error = tonic::Status;
4128
4129 fn try_from(value: TimeoutMessages) -> Result<Self, Self::Error> {
4130 Ok(Self {
4131 first_epoch: value.first_epoch.require()?.into(),
4132 first_epoch_timeouts: value
4133 .first_epoch_timeouts
4134 .into_iter()
4135 .map(TryFrom::try_from)
4136 .collect::<Result<_, _>>()?,
4137 second_epoch_timeouts: value
4138 .second_epoch_timeouts
4139 .into_iter()
4140 .map(TryFrom::try_from)
4141 .collect::<Result<_, _>>()?,
4142 })
4143 }
4144}
4145
4146impl TryFrom<PersistentRoundStatus> for super::types::queries::PersistentRoundStatus {
4147 type Error = tonic::Status;
4148
4149 fn try_from(value: PersistentRoundStatus) -> Result<Self, Self::Error> {
4150 Ok(Self {
4151 last_signed_quorum_message: value
4152 .last_signed_quorum_message
4153 .map(TryFrom::try_from)
4154 .transpose()?,
4155 last_signed_timeout_message: value
4156 .last_signed_timeout_message
4157 .map(TryFrom::try_from)
4158 .transpose()?,
4159 last_baked_round: value.last_baked_round.require()?.into(),
4160 latest_timeout: value.latest_timeout.map(TryFrom::try_from).transpose()?,
4161 })
4162 }
4163}
4164
4165impl TryFrom<RoundTimeout> for super::types::queries::RoundTimeout {
4166 type Error = tonic::Status;
4167
4168 fn try_from(value: RoundTimeout) -> Result<Self, Self::Error> {
4169 Ok(Self {
4170 timeout_certificate: value.timeout_certificate.require()?.try_into()?,
4171 quorum_certificate: value.quorum_certificate.require()?.try_into()?,
4172 })
4173 }
4174}
4175
4176impl TryFrom<RoundStatus> for super::types::queries::RoundStatus {
4177 type Error = tonic::Status;
4178
4179 fn try_from(value: RoundStatus) -> Result<Self, Self::Error> {
4180 Ok(Self {
4181 current_round: value.current_round.require()?.into(),
4182 highest_certified_block: value.highest_certified_block.require()?.try_into()?,
4183 previous_round_timeout: value
4184 .previous_round_timeout
4185 .map(TryFrom::try_from)
4186 .transpose()?,
4187 round_eligible_to_bake: value.round_eligible_to_bake,
4188 current_epoch: value.current_epoch.require()?.into(),
4189 last_epoch_finalization_entry: value
4190 .last_epoch_finalization_entry
4191 .map(TryFrom::try_from)
4192 .transpose()?,
4193 current_timeout: value.current_timeout.require()?.into(),
4194 })
4195 }
4196}
4197
4198impl TryFrom<BlockTableSummary> for super::types::queries::BlockTableSummary {
4199 type Error = tonic::Status;
4200
4201 fn try_from(value: BlockTableSummary) -> Result<Self, Self::Error> {
4202 Ok(Self {
4203 dead_block_cache_size: value.dead_block_cache_size,
4204 live_blocks: value
4205 .live_blocks
4206 .into_iter()
4207 .map(TryFrom::try_from)
4208 .collect::<Result<_, _>>()?,
4209 })
4210 }
4211}
4212
4213impl TryFrom<RoundExistingBlock> for super::types::queries::RoundExistingBlock {
4214 type Error = tonic::Status;
4215
4216 fn try_from(value: RoundExistingBlock) -> Result<Self, Self::Error> {
4217 Ok(Self {
4218 round: value.round.require()?.into(),
4219 baker: value.baker.require()?.into(),
4220 block: value.block.require()?.try_into()?,
4221 })
4222 }
4223}
4224
4225impl TryFrom<RoundExistingQc> for super::types::queries::RoundExistingQC {
4226 type Error = tonic::Status;
4227
4228 fn try_from(value: RoundExistingQc) -> Result<Self, Self::Error> {
4229 Ok(Self {
4230 round: value.round.require()?.into(),
4231 epoch: value.epoch.require()?.into(),
4232 })
4233 }
4234}
4235
4236impl TryFrom<FullBakerInfo> for super::types::queries::FullBakerInfo {
4237 type Error = tonic::Status;
4238
4239 fn try_from(value: FullBakerInfo) -> Result<Self, Self::Error> {
4240 Ok(Self {
4241 baker_identity: value.baker_identity.require()?.into(),
4242 election_verify_key: value.election_verify_key.require()?.try_into()?,
4243 signature_verify_key: value.signature_verify_key.require()?.try_into()?,
4244 aggregation_verify_key: value.aggregation_verify_key.require()?.try_into()?,
4245 stake: value.stake.require()?.into(),
4246 })
4247 }
4248}
4249
4250impl TryFrom<FinalizationCommitteeHash> for concordium_base::hashes::FinalizationCommitteeHash {
4251 type Error = tonic::Status;
4252
4253 fn try_from(value: FinalizationCommitteeHash) -> Result<Self, Self::Error> {
4254 match value.value.try_into() {
4255 Ok(hash) => Ok(Self::new(hash)),
4256 Err(_) => Err(tonic::Status::internal(
4257 "Unexpected finalization committee hash format.",
4258 )),
4259 }
4260 }
4261}
4262
4263impl TryFrom<BakersAndFinalizers> for super::types::queries::BakersAndFinalizers {
4264 type Error = tonic::Status;
4265
4266 fn try_from(value: BakersAndFinalizers) -> Result<Self, Self::Error> {
4267 Ok(Self {
4268 bakers: value
4269 .bakers
4270 .into_iter()
4271 .map(TryFrom::try_from)
4272 .collect::<Result<_, _>>()?,
4273 finalizers: value.finalizers.into_iter().map(From::from).collect(),
4274 baker_total_stake: value.baker_total_stake.require()?.into(),
4275 finalizer_total_stake: value.finalizer_total_stake.require()?.into(),
4276 finalization_committee_hash: value.finalization_committee_hash.require()?.try_into()?,
4277 })
4278 }
4279}
4280
4281impl TryFrom<EpochBakers> for super::types::queries::EpochBakers {
4282 type Error = tonic::Status;
4283
4284 fn try_from(value: EpochBakers) -> Result<Self, Self::Error> {
4285 Ok(Self {
4286 previous_epoch_bakers: value.previous_epoch_bakers.require()?.try_into()?,
4287 current_epoch_bakers: value
4288 .current_epoch_bakers
4289 .map(TryFrom::try_from)
4290 .transpose()?,
4291 next_epoch_bakers: value.next_epoch_bakers.map(TryFrom::try_from).transpose()?,
4292 next_payday: value.next_payday.require()?.into(),
4293 })
4294 }
4295}
4296
4297impl TryFrom<BranchBlocks> for Vec<super::BlockHash> {
4298 type Error = tonic::Status;
4299
4300 fn try_from(value: BranchBlocks) -> Result<Self, Self::Error> {
4301 value
4302 .blocks_at_branch_height
4303 .into_iter()
4304 .map(TryFrom::try_from)
4305 .collect()
4306 }
4307}
4308
4309impl TryFrom<ConsensusDetailedStatus> for super::types::queries::ConsensusDetailedStatus {
4310 type Error = tonic::Status;
4311
4312 fn try_from(value: ConsensusDetailedStatus) -> Result<Self, Self::Error> {
4313 Ok(Self {
4314 genesis_block: value.genesis_block.require()?.try_into()?,
4315 persistent_round_status: value.persistent_round_status.require()?.try_into()?,
4316 round_status: value.round_status.require()?.try_into()?,
4317 non_finalized_transaction_count: value.non_finalized_transaction_count,
4318 transaction_table_purge_counter: value.transaction_table_purge_counter,
4319 block_table: value.block_table.require()?.try_into()?,
4320 branches: value
4321 .branches
4322 .into_iter()
4323 .map(TryFrom::try_from)
4324 .collect::<Result<_, _>>()?,
4325 round_existing_blocks: value
4326 .round_existing_blocks
4327 .into_iter()
4328 .map(TryFrom::try_from)
4329 .collect::<Result<_, _>>()?,
4330 round_existing_qcs: value
4331 .round_existing_qcs
4332 .into_iter()
4333 .map(TryFrom::try_from)
4334 .collect::<Result<_, _>>()?,
4335 genesis_block_height: value.genesis_block_height.require()?.into(),
4336 last_finalized_block: value.last_finalized_block.require()?.try_into()?,
4337 last_finalized_block_height: value.last_finalized_block_height.require()?.into(),
4338 latest_finalization_entry: value
4339 .latest_finalization_entry
4340 .map(TryFrom::try_from)
4341 .transpose()?,
4342 epoch_bakers: value.epoch_bakers.require()?.try_into()?,
4343 timeout_messages: value.timeout_messages.map(TryFrom::try_from).transpose()?,
4344 terminal_block: value.terminal_block.map(TryFrom::try_from).transpose()?,
4345 })
4346 }
4347}
4348
4349#[cfg(test)]
4350mod test {
4351 use concordium_base::{
4352 base::{self, PartsPerHundredThousands, UpdateKeyPair},
4353 common::{Deserial, Serial},
4354 contracts_common,
4355 };
4356 use rand::{rngs::StdRng, SeedableRng};
4357
4358 use super::*;
4359
4360 #[test]
4361 fn test_try_from_branch() {
4362 use crate::types::queries::Branch as QBranch;
4363
4364 let from = Branch {
4365 block_hash: Some(BlockHash {
4366 value: vec![0u8; 32],
4367 }),
4368 children: vec![
4369 Branch {
4370 block_hash: Some(BlockHash {
4371 value: vec![1u8; 32],
4372 }),
4373 children: vec![],
4374 },
4375 Branch {
4376 block_hash: Some(BlockHash {
4377 value: vec![2u8; 32],
4378 }),
4379 children: vec![Branch {
4380 block_hash: Some(BlockHash {
4381 value: vec![3u8; 32],
4382 }),
4383 children: vec![],
4384 }],
4385 },
4386 ],
4387 };
4388
4389 let to_target = QBranch {
4390 block_hash: [0u8; 32].into(),
4391 children: vec![
4392 QBranch {
4393 block_hash: [2u8; 32].into(),
4394 children: vec![QBranch {
4395 block_hash: [3u8; 32].into(),
4396 children: vec![],
4397 }],
4398 },
4399 QBranch {
4400 block_hash: [1u8; 32].into(),
4401 children: vec![],
4402 },
4403 ],
4404 };
4405 let to = QBranch::try_from(from).expect("Failed to convert branch");
4406
4407 assert_eq!(to, to_target);
4408 }
4409
4410 fn gen_public_key(rng: &mut StdRng) -> (base::UpdatePublicKey, Vec<u8>) {
4412 let key = base::UpdatePublicKey::from(&UpdateKeyPair::generate(rng));
4413 let mut buffer = Vec::with_capacity(33);
4414 key.serial(&mut buffer);
4415 let bytes = buffer[1..].to_vec();
4417 let norm_key = base::UpdatePublicKey::deserial(&mut &buffer[..]).unwrap();
4421 (norm_key, bytes)
4422 }
4423
4424 #[test]
4425 fn test_try_from_chain_parameters_v0() {
4426 let mut rng = StdRng::seed_from_u64(0);
4427 let (root_key, root_key_bytes) = gen_public_key(&mut rng);
4428 let (level_1_key, level_1_key_bytes) = gen_public_key(&mut rng);
4429 let (level_2_key_1, level_2_key_1_bytes) = gen_public_key(&mut rng);
4430 let (level_2_key_2, level_2_key_2_bytes) = gen_public_key(&mut rng);
4431 let cpv0 = ChainParametersV0 {
4432 election_difficulty: Some(ElectionDifficulty {
4433 value: Some(AmountFraction {
4434 parts_per_hundred_thousand: 11111,
4435 }),
4436 }),
4437 euro_per_energy: Some(ExchangeRate {
4438 value: Some(Ratio {
4439 numerator: 13,
4440 denominator: 17,
4441 }),
4442 }),
4443 micro_ccd_per_euro: Some(ExchangeRate {
4444 value: Some(Ratio {
4445 numerator: 19,
4446 denominator: 23,
4447 }),
4448 }),
4449 baker_cooldown_epochs: Some(Epoch { value: 29 }),
4450 account_creation_limit: Some(CredentialsPerBlockLimit { value: 31 }),
4451 mint_distribution: Some(MintDistributionCpv0 {
4452 mint_per_slot: Some(MintRate {
4453 mantissa: 37,
4454 exponent: 41,
4455 }),
4456 baking_reward: Some(AmountFraction {
4457 parts_per_hundred_thousand: 43,
4458 }),
4459 finalization_reward: Some(AmountFraction {
4460 parts_per_hundred_thousand: 47,
4461 }),
4462 }),
4463 transaction_fee_distribution: Some(TransactionFeeDistribution {
4464 baker: Some(AmountFraction {
4465 parts_per_hundred_thousand: 53,
4466 }),
4467 gas_account: Some(AmountFraction {
4468 parts_per_hundred_thousand: 59,
4469 }),
4470 }),
4471 gas_rewards: Some(GasRewards {
4472 baker: Some(AmountFraction {
4473 parts_per_hundred_thousand: 61,
4474 }),
4475 finalization_proof: Some(AmountFraction {
4476 parts_per_hundred_thousand: 67,
4477 }),
4478 account_creation: Some(AmountFraction {
4479 parts_per_hundred_thousand: 71,
4480 }),
4481 chain_update: Some(AmountFraction {
4482 parts_per_hundred_thousand: 73,
4483 }),
4484 }),
4485 foundation_account: Some(AccountAddress {
4486 value: vec![79u8; 32],
4487 }),
4488 minimum_threshold_for_baking: Some(Amount { value: 83 }),
4489 root_keys: Some(HigherLevelKeys {
4490 keys: vec![UpdatePublicKey {
4491 value: root_key_bytes,
4492 }],
4493 threshold: Some(UpdateKeysThreshold { value: 97 }),
4494 }),
4495 level1_keys: Some(HigherLevelKeys {
4496 keys: vec![UpdatePublicKey {
4497 value: level_1_key_bytes,
4498 }],
4499 threshold: Some(UpdateKeysThreshold { value: 103 }),
4500 }),
4501 level2_keys: Some(AuthorizationsV0 {
4502 keys: vec![
4503 UpdatePublicKey {
4504 value: level_2_key_1_bytes,
4505 },
4506 UpdatePublicKey {
4507 value: level_2_key_2_bytes,
4508 },
4509 ],
4510 emergency: Some(AccessStructure {
4511 access_public_keys: vec![UpdateKeysIndex { value: 113 }],
4512 access_threshold: Some(UpdateKeysThreshold { value: 127 }),
4513 }),
4514 protocol: Some(AccessStructure {
4515 access_public_keys: vec![UpdateKeysIndex { value: 131 }],
4516 access_threshold: Some(UpdateKeysThreshold { value: 137 }),
4517 }),
4518 parameter_consensus: Some(AccessStructure {
4519 access_public_keys: vec![UpdateKeysIndex { value: 139 }],
4520 access_threshold: Some(UpdateKeysThreshold { value: 149 }),
4521 }),
4522 parameter_euro_per_energy: Some(AccessStructure {
4523 access_public_keys: vec![UpdateKeysIndex { value: 151 }],
4524 access_threshold: Some(UpdateKeysThreshold { value: 157 }),
4525 }),
4526 parameter_micro_ccd_per_euro: Some(AccessStructure {
4527 access_public_keys: vec![UpdateKeysIndex { value: 173 }],
4528 access_threshold: Some(UpdateKeysThreshold { value: 179 }),
4529 }),
4530 parameter_foundation_account: Some(AccessStructure {
4531 access_public_keys: vec![UpdateKeysIndex { value: 181 }],
4532 access_threshold: Some(UpdateKeysThreshold { value: 191 }),
4533 }),
4534 parameter_mint_distribution: Some(AccessStructure {
4535 access_public_keys: vec![UpdateKeysIndex { value: 193 }],
4536 access_threshold: Some(UpdateKeysThreshold { value: 197 }),
4537 }),
4538 parameter_transaction_fee_distribution: Some(AccessStructure {
4539 access_public_keys: vec![UpdateKeysIndex { value: 199 }],
4540 access_threshold: Some(UpdateKeysThreshold { value: 211 }),
4541 }),
4542 parameter_gas_rewards: Some(AccessStructure {
4543 access_public_keys: vec![UpdateKeysIndex { value: 223 }],
4544 access_threshold: Some(UpdateKeysThreshold { value: 227 }),
4545 }),
4546 pool_parameters: Some(AccessStructure {
4547 access_public_keys: vec![UpdateKeysIndex { value: 229 }],
4548 access_threshold: Some(UpdateKeysThreshold { value: 233 }),
4549 }),
4550 add_anonymity_revoker: Some(AccessStructure {
4551 access_public_keys: vec![UpdateKeysIndex { value: 239 }],
4552 access_threshold: Some(UpdateKeysThreshold { value: 241 }),
4553 }),
4554 add_identity_provider: Some(AccessStructure {
4555 access_public_keys: vec![UpdateKeysIndex { value: 251 }],
4556 access_threshold: Some(UpdateKeysThreshold { value: 257 }),
4557 }),
4558 }),
4559 };
4560 let params = ChainParameters {
4561 parameters: Some(generated::chain_parameters::Parameters::V0(cpv0)),
4562 };
4563 let converted = crate::v2::ChainParameters::try_from(params)
4564 .expect("Failed to convert chain parameters v0");
4565 let expected = crate::v2::ChainParameters {
4566 timeout_parameters: Default::default(),
4567 election_difficulty: Some(base::ElectionDifficulty::new_unchecked(11111)),
4568 min_block_time: None,
4569 block_energy_limit: None,
4570 euro_per_energy: Some(base::ExchangeRate::new_unchecked(13, 17)),
4571 micro_ccd_per_euro: Some(base::ExchangeRate::new_unchecked(19, 23)),
4572 cooldown_parameters: chain_parameters::CooldownParameters {
4573 baker_cooldown_epochs: Some(base::Epoch::from(29)),
4574 pool_owner_cooldown: None,
4575 delegator_cooldown: None,
4576 },
4577 reward_period_length: None,
4578 mint_per_payday: None,
4579 mint_per_slot: Some(base::MintRate {
4580 mantissa: 37,
4581 exponent: 41,
4582 }),
4583 account_creation_limit: Some(base::CredentialsPerBlockLimit::from(31)),
4584 mint_distribution: chain_parameters::MintDistribution {
4585 baking_reward: Some(base::AmountFraction::new_unchecked(43)),
4586 finalization_reward: Some(base::AmountFraction::new_unchecked(47)),
4587 },
4588 transaction_fee_distribution: chain_parameters::TransactionFeeDistribution {
4589 baker: Some(base::AmountFraction::new_unchecked(53)),
4590 gas_account: Some(base::AmountFraction::new_unchecked(59)),
4591 },
4592 gas_rewards: chain_parameters::GasRewards {
4593 baker: Some(base::AmountFraction::new_unchecked(61)),
4594 finalization_proof: Some(base::AmountFraction::new_unchecked(67)),
4595 account_creation: Some(base::AmountFraction::new_unchecked(71)),
4596 chain_update: Some(base::AmountFraction::new_unchecked(73)),
4597 },
4598 foundation_account: Some(contracts_common::AccountAddress([79u8; 32])),
4599 staking_parameters: chain_parameters::StakingParameters {
4600 minimum_equity_capital: Some(contracts_common::Amount::from_micro_ccd(83)),
4601 ..Default::default()
4602 },
4603 finalization_committee_parameters: Default::default(),
4604 validator_max_missed_rounds: None,
4605 keys: chain_parameters::UpdateKeys {
4606 root_keys: Some(concordium_base::updates::HigherLevelAccessStructure::<
4607 concordium_base::updates::RootKeysKind,
4608 > {
4609 keys: vec![base::UpdatePublicKey::from(
4610 crate::id::types::VerifyKey::from(root_key),
4611 )],
4612 threshold: 97.try_into().unwrap(),
4613 _phantom: Default::default(),
4614 }),
4615 level_1_keys: Some(concordium_base::updates::HigherLevelAccessStructure::<
4616 concordium_base::updates::Level1KeysKind,
4617 > {
4618 keys: vec![base::UpdatePublicKey::from(
4619 crate::id::types::VerifyKey::from(level_1_key),
4620 )],
4621 threshold: 103.try_into().unwrap(),
4622 _phantom: Default::default(),
4623 }),
4624 level_2_keys: Some(chain_parameters::Level2Keys {
4625 keys: vec![
4626 base::UpdatePublicKey::from(crate::id::types::VerifyKey::from(
4627 level_2_key_1,
4628 )),
4629 base::UpdatePublicKey::from(crate::id::types::VerifyKey::from(
4630 level_2_key_2,
4631 )),
4632 ],
4633 emergency: Some(updates::AccessStructure {
4634 authorized_keys: [base::UpdateKeysIndex::from(113)].into(),
4635 threshold: 127.try_into().unwrap(),
4636 }),
4637 protocol: Some(updates::AccessStructure {
4638 authorized_keys: [base::UpdateKeysIndex::from(131)].into(),
4639 threshold: 137.try_into().unwrap(),
4640 }),
4641 consensus: Some(updates::AccessStructure {
4642 authorized_keys: [base::UpdateKeysIndex::from(139)].into(),
4643 threshold: 149.try_into().unwrap(),
4644 }),
4645 euro_per_energy: Some(updates::AccessStructure {
4646 authorized_keys: [base::UpdateKeysIndex::from(151)].into(),
4647 threshold: 157.try_into().unwrap(),
4648 }),
4649 micro_ccd_per_euro: Some(updates::AccessStructure {
4650 authorized_keys: [base::UpdateKeysIndex::from(173)].into(),
4651 threshold: 179.try_into().unwrap(),
4652 }),
4653 foundation_account: Some(updates::AccessStructure {
4654 authorized_keys: [base::UpdateKeysIndex::from(181)].into(),
4655 threshold: 191.try_into().unwrap(),
4656 }),
4657 mint_distribution: Some(updates::AccessStructure {
4658 authorized_keys: [base::UpdateKeysIndex::from(193)].into(),
4659 threshold: 197.try_into().unwrap(),
4660 }),
4661 transaction_fee_distribution: Some(updates::AccessStructure {
4662 authorized_keys: [base::UpdateKeysIndex::from(199)].into(),
4663 threshold: 211.try_into().unwrap(),
4664 }),
4665 param_gas_rewards: Some(updates::AccessStructure {
4666 authorized_keys: [base::UpdateKeysIndex::from(223)].into(),
4667 threshold: 227.try_into().unwrap(),
4668 }),
4669 pool_parameters: Some(updates::AccessStructure {
4670 authorized_keys: [base::UpdateKeysIndex::from(229)].into(),
4671 threshold: 233.try_into().unwrap(),
4672 }),
4673 add_anonymity_revoker: Some(updates::AccessStructure {
4674 authorized_keys: [base::UpdateKeysIndex::from(239)].into(),
4675 threshold: 241.try_into().unwrap(),
4676 }),
4677 add_identity_provider: Some(updates::AccessStructure {
4678 authorized_keys: [base::UpdateKeysIndex::from(251)].into(),
4679 threshold: 257.try_into().unwrap(),
4680 }),
4681 cooldown_parameters: None,
4682 time_parameters: None,
4683 create_plt: None,
4684 }),
4685 },
4686 };
4687 assert_eq!(converted, expected);
4688 }
4689
4690 #[test]
4691 fn test_try_from_chain_parameters_v1() {
4692 let mut rng = StdRng::seed_from_u64(1);
4693 let (root_key, root_key_bytes) = gen_public_key(&mut rng);
4694 let (level_1_key, level_1_key_bytes) = gen_public_key(&mut rng);
4695 let (level_2_key_1, level_2_key_1_bytes) = gen_public_key(&mut rng);
4696 let (level_2_key_2, level_2_key_2_bytes) = gen_public_key(&mut rng);
4697 let cpv1 = ChainParametersV1 {
4698 election_difficulty: Some(ElectionDifficulty {
4699 value: Some(AmountFraction {
4700 parts_per_hundred_thousand: 21111,
4701 }),
4702 }),
4703 euro_per_energy: Some(ExchangeRate {
4704 value: Some(Ratio {
4705 numerator: 2,
4706 denominator: 3,
4707 }),
4708 }),
4709 micro_ccd_per_euro: Some(ExchangeRate {
4710 value: Some(Ratio {
4711 numerator: 4,
4712 denominator: 5,
4713 }),
4714 }),
4715 cooldown_parameters: Some(CooldownParametersCpv1 {
4716 pool_owner_cooldown: Some(DurationSeconds { value: 6 }),
4717 delegator_cooldown: Some(DurationSeconds { value: 7 }),
4718 }),
4719 time_parameters: Some(TimeParametersCpv1 {
4720 reward_period_length: Some(RewardPeriodLength {
4721 value: Some(Epoch { value: 8 }),
4722 }),
4723 mint_per_payday: Some(MintRate {
4724 mantissa: 9,
4725 exponent: 10,
4726 }),
4727 }),
4728 account_creation_limit: Some(CredentialsPerBlockLimit { value: 11 }),
4729 mint_distribution: Some(MintDistributionCpv1 {
4730 baking_reward: Some(AmountFraction {
4731 parts_per_hundred_thousand: 12,
4732 }),
4733 finalization_reward: Some(AmountFraction {
4734 parts_per_hundred_thousand: 13,
4735 }),
4736 }),
4737 transaction_fee_distribution: Some(TransactionFeeDistribution {
4738 baker: Some(AmountFraction {
4739 parts_per_hundred_thousand: 14,
4740 }),
4741 gas_account: Some(AmountFraction {
4742 parts_per_hundred_thousand: 15,
4743 }),
4744 }),
4745 gas_rewards: Some(GasRewards {
4746 baker: Some(AmountFraction {
4747 parts_per_hundred_thousand: 16,
4748 }),
4749 finalization_proof: Some(AmountFraction {
4750 parts_per_hundred_thousand: 17,
4751 }),
4752 account_creation: Some(AmountFraction {
4753 parts_per_hundred_thousand: 18,
4754 }),
4755 chain_update: Some(AmountFraction {
4756 parts_per_hundred_thousand: 19,
4757 }),
4758 }),
4759 foundation_account: Some(AccountAddress {
4760 value: vec![20u8; 32],
4761 }),
4762 pool_parameters: Some(PoolParametersCpv1 {
4763 passive_finalization_commission: Some(AmountFraction {
4764 parts_per_hundred_thousand: 21,
4765 }),
4766 passive_baking_commission: Some(AmountFraction {
4767 parts_per_hundred_thousand: 22,
4768 }),
4769 passive_transaction_commission: Some(AmountFraction {
4770 parts_per_hundred_thousand: 23,
4771 }),
4772 commission_bounds: Some(CommissionRanges {
4773 finalization: Some(InclusiveRangeAmountFraction {
4774 min: Some(AmountFraction {
4775 parts_per_hundred_thousand: 24,
4776 }),
4777 max: Some(AmountFraction {
4778 parts_per_hundred_thousand: 25,
4779 }),
4780 }),
4781 baking: Some(InclusiveRangeAmountFraction {
4782 min: Some(AmountFraction {
4783 parts_per_hundred_thousand: 26,
4784 }),
4785 max: Some(AmountFraction {
4786 parts_per_hundred_thousand: 27,
4787 }),
4788 }),
4789 transaction: Some(InclusiveRangeAmountFraction {
4790 min: Some(AmountFraction {
4791 parts_per_hundred_thousand: 28,
4792 }),
4793 max: Some(AmountFraction {
4794 parts_per_hundred_thousand: 29,
4795 }),
4796 }),
4797 }),
4798 minimum_equity_capital: Some(Amount { value: 30 }),
4799 capital_bound: Some(CapitalBound {
4800 value: Some(AmountFraction {
4801 parts_per_hundred_thousand: 31,
4802 }),
4803 }),
4804 leverage_bound: Some(LeverageFactor {
4805 value: Some(Ratio {
4806 numerator: 33,
4807 denominator: 32,
4808 }),
4809 }),
4810 }),
4811 root_keys: Some(HigherLevelKeys {
4812 keys: vec![UpdatePublicKey {
4813 value: root_key_bytes,
4814 }],
4815 threshold: Some(UpdateKeysThreshold { value: 34 }),
4816 }),
4817 level1_keys: Some(HigherLevelKeys {
4818 keys: vec![UpdatePublicKey {
4819 value: level_1_key_bytes,
4820 }],
4821 threshold: Some(UpdateKeysThreshold { value: 35 }),
4822 }),
4823 level2_keys: Some(AuthorizationsV1 {
4824 v0: Some(AuthorizationsV0 {
4825 keys: vec![
4826 UpdatePublicKey {
4827 value: level_2_key_1_bytes,
4828 },
4829 UpdatePublicKey {
4830 value: level_2_key_2_bytes,
4831 },
4832 ],
4833 emergency: Some(AccessStructure {
4834 access_public_keys: vec![UpdateKeysIndex { value: 113 }],
4835 access_threshold: Some(UpdateKeysThreshold { value: 127 }),
4836 }),
4837 protocol: Some(AccessStructure {
4838 access_public_keys: vec![UpdateKeysIndex { value: 131 }],
4839 access_threshold: Some(UpdateKeysThreshold { value: 137 }),
4840 }),
4841 parameter_consensus: Some(AccessStructure {
4842 access_public_keys: vec![UpdateKeysIndex { value: 139 }],
4843 access_threshold: Some(UpdateKeysThreshold { value: 149 }),
4844 }),
4845 parameter_euro_per_energy: Some(AccessStructure {
4846 access_public_keys: vec![UpdateKeysIndex { value: 151 }],
4847 access_threshold: Some(UpdateKeysThreshold { value: 157 }),
4848 }),
4849 parameter_micro_ccd_per_euro: Some(AccessStructure {
4850 access_public_keys: vec![UpdateKeysIndex { value: 173 }],
4851 access_threshold: Some(UpdateKeysThreshold { value: 179 }),
4852 }),
4853 parameter_foundation_account: Some(AccessStructure {
4854 access_public_keys: vec![UpdateKeysIndex { value: 181 }],
4855 access_threshold: Some(UpdateKeysThreshold { value: 191 }),
4856 }),
4857 parameter_mint_distribution: Some(AccessStructure {
4858 access_public_keys: vec![UpdateKeysIndex { value: 193 }],
4859 access_threshold: Some(UpdateKeysThreshold { value: 197 }),
4860 }),
4861 parameter_transaction_fee_distribution: Some(AccessStructure {
4862 access_public_keys: vec![UpdateKeysIndex { value: 199 }],
4863 access_threshold: Some(UpdateKeysThreshold { value: 211 }),
4864 }),
4865 parameter_gas_rewards: Some(AccessStructure {
4866 access_public_keys: vec![UpdateKeysIndex { value: 223 }],
4867 access_threshold: Some(UpdateKeysThreshold { value: 227 }),
4868 }),
4869 pool_parameters: Some(AccessStructure {
4870 access_public_keys: vec![UpdateKeysIndex { value: 229 }],
4871 access_threshold: Some(UpdateKeysThreshold { value: 233 }),
4872 }),
4873 add_anonymity_revoker: Some(AccessStructure {
4874 access_public_keys: vec![UpdateKeysIndex { value: 239 }],
4875 access_threshold: Some(UpdateKeysThreshold { value: 241 }),
4876 }),
4877 add_identity_provider: Some(AccessStructure {
4878 access_public_keys: vec![UpdateKeysIndex { value: 251 }],
4879 access_threshold: Some(UpdateKeysThreshold { value: 257 }),
4880 }),
4881 }),
4882 parameter_cooldown: Some(AccessStructure {
4883 access_public_keys: vec![UpdateKeysIndex { value: 263 }],
4884 access_threshold: Some(UpdateKeysThreshold { value: 269 }),
4885 }),
4886 parameter_time: Some(AccessStructure {
4887 access_public_keys: vec![UpdateKeysIndex { value: 271 }],
4888 access_threshold: Some(UpdateKeysThreshold { value: 277 }),
4889 }),
4890 create_plt: None,
4891 }),
4892 };
4893 let params = ChainParameters {
4894 parameters: Some(generated::chain_parameters::Parameters::V1(cpv1)),
4895 };
4896 let converted = crate::v2::ChainParameters::try_from(params)
4897 .expect("Failed to convert chain parameters v1");
4898 let expected = crate::v2::ChainParameters {
4899 timeout_parameters: Default::default(),
4900 election_difficulty: Some(base::ElectionDifficulty::new_unchecked(21111)),
4901 min_block_time: None,
4902 block_energy_limit: None,
4903 euro_per_energy: Some(base::ExchangeRate::new_unchecked(2, 3)),
4904 micro_ccd_per_euro: Some(base::ExchangeRate::new_unchecked(4, 5)),
4905 cooldown_parameters: chain_parameters::CooldownParameters {
4906 baker_cooldown_epochs: None,
4907 pool_owner_cooldown: Some(base::DurationSeconds::from(6)),
4908 delegator_cooldown: Some(base::DurationSeconds::from(7)),
4909 },
4910 reward_period_length: Some(updates::RewardPeriodLength::from(base::Epoch::from(8))),
4911 mint_per_payday: Some(base::MintRate {
4912 mantissa: 9,
4913 exponent: 10,
4914 }),
4915 mint_per_slot: None,
4916 account_creation_limit: Some(base::CredentialsPerBlockLimit::from(11)),
4917 mint_distribution: chain_parameters::MintDistribution {
4918 baking_reward: Some(base::AmountFraction::new_unchecked(12)),
4919 finalization_reward: Some(base::AmountFraction::new_unchecked(13)),
4920 },
4921 transaction_fee_distribution: chain_parameters::TransactionFeeDistribution {
4922 baker: Some(base::AmountFraction::new_unchecked(14)),
4923 gas_account: Some(base::AmountFraction::new_unchecked(15)),
4924 },
4925 gas_rewards: chain_parameters::GasRewards {
4926 baker: Some(base::AmountFraction::new_unchecked(16)),
4927 finalization_proof: Some(base::AmountFraction::new_unchecked(17)),
4928 account_creation: Some(base::AmountFraction::new_unchecked(18)),
4929 chain_update: Some(base::AmountFraction::new_unchecked(19)),
4930 },
4931 foundation_account: Some(contracts_common::AccountAddress([20u8; 32])),
4932 staking_parameters: chain_parameters::StakingParameters {
4933 passive_finalization_commission: Some(base::AmountFraction::new_unchecked(21)),
4934 passive_baking_commission: Some(base::AmountFraction::new_unchecked(22)),
4935 passive_transaction_commission: Some(base::AmountFraction::new_unchecked(23)),
4936 finalization_commission_range: Some(base::InclusiveRange {
4937 min: base::AmountFraction::new_unchecked(24),
4938 max: base::AmountFraction::new_unchecked(25),
4939 }),
4940 baking_commission_range: Some(base::InclusiveRange {
4941 min: base::AmountFraction::new_unchecked(26),
4942 max: base::AmountFraction::new_unchecked(27),
4943 }),
4944 transaction_commission_range: Some(base::InclusiveRange {
4945 min: base::AmountFraction::new_unchecked(28),
4946 max: base::AmountFraction::new_unchecked(29),
4947 }),
4948 minimum_equity_capital: Some(contracts_common::Amount::from_micro_ccd(30)),
4949 capital_bound: Some(base::CapitalBound {
4950 bound: base::AmountFraction::new_unchecked(31),
4951 }),
4952 leverage_bound: Some(base::LeverageFactor {
4953 numerator: 33,
4954 denominator: 32,
4955 }),
4956 },
4957 finalization_committee_parameters: Default::default(),
4958 validator_max_missed_rounds: None,
4959 keys: chain_parameters::UpdateKeys {
4960 root_keys: Some(concordium_base::updates::HigherLevelAccessStructure::<
4961 concordium_base::updates::RootKeysKind,
4962 > {
4963 keys: vec![base::UpdatePublicKey::from(
4964 crate::id::types::VerifyKey::from(root_key),
4965 )],
4966 threshold: 34.try_into().unwrap(),
4967 _phantom: Default::default(),
4968 }),
4969 level_1_keys: Some(concordium_base::updates::HigherLevelAccessStructure::<
4970 concordium_base::updates::Level1KeysKind,
4971 > {
4972 keys: vec![base::UpdatePublicKey::from(
4973 crate::id::types::VerifyKey::from(level_1_key),
4974 )],
4975 threshold: 35.try_into().unwrap(),
4976 _phantom: Default::default(),
4977 }),
4978 level_2_keys: Some(chain_parameters::Level2Keys {
4979 keys: vec![
4980 base::UpdatePublicKey::from(crate::id::types::VerifyKey::from(
4981 level_2_key_1,
4982 )),
4983 base::UpdatePublicKey::from(crate::id::types::VerifyKey::from(
4984 level_2_key_2,
4985 )),
4986 ],
4987 emergency: Some(updates::AccessStructure {
4988 authorized_keys: [base::UpdateKeysIndex::from(113)].into(),
4989 threshold: 127.try_into().unwrap(),
4990 }),
4991 protocol: Some(updates::AccessStructure {
4992 authorized_keys: [base::UpdateKeysIndex::from(131)].into(),
4993 threshold: 137.try_into().unwrap(),
4994 }),
4995 consensus: Some(updates::AccessStructure {
4996 authorized_keys: [base::UpdateKeysIndex::from(139)].into(),
4997 threshold: 149.try_into().unwrap(),
4998 }),
4999 euro_per_energy: Some(updates::AccessStructure {
5000 authorized_keys: [base::UpdateKeysIndex::from(151)].into(),
5001 threshold: 157.try_into().unwrap(),
5002 }),
5003 micro_ccd_per_euro: Some(updates::AccessStructure {
5004 authorized_keys: [base::UpdateKeysIndex::from(173)].into(),
5005 threshold: 179.try_into().unwrap(),
5006 }),
5007 foundation_account: Some(updates::AccessStructure {
5008 authorized_keys: [base::UpdateKeysIndex::from(181)].into(),
5009 threshold: 191.try_into().unwrap(),
5010 }),
5011 mint_distribution: Some(updates::AccessStructure {
5012 authorized_keys: [base::UpdateKeysIndex::from(193)].into(),
5013 threshold: 197.try_into().unwrap(),
5014 }),
5015 transaction_fee_distribution: Some(updates::AccessStructure {
5016 authorized_keys: [base::UpdateKeysIndex::from(199)].into(),
5017 threshold: 211.try_into().unwrap(),
5018 }),
5019 param_gas_rewards: Some(updates::AccessStructure {
5020 authorized_keys: [base::UpdateKeysIndex::from(223)].into(),
5021 threshold: 227.try_into().unwrap(),
5022 }),
5023 pool_parameters: Some(updates::AccessStructure {
5024 authorized_keys: [base::UpdateKeysIndex::from(229)].into(),
5025 threshold: 233.try_into().unwrap(),
5026 }),
5027 add_anonymity_revoker: Some(updates::AccessStructure {
5028 authorized_keys: [base::UpdateKeysIndex::from(239)].into(),
5029 threshold: 241.try_into().unwrap(),
5030 }),
5031 add_identity_provider: Some(updates::AccessStructure {
5032 authorized_keys: [base::UpdateKeysIndex::from(251)].into(),
5033 threshold: 257.try_into().unwrap(),
5034 }),
5035 cooldown_parameters: Some(updates::AccessStructure {
5036 authorized_keys: [base::UpdateKeysIndex::from(263)].into(),
5037 threshold: 269.try_into().unwrap(),
5038 }),
5039 time_parameters: Some(updates::AccessStructure {
5040 authorized_keys: [base::UpdateKeysIndex::from(271)].into(),
5041 threshold: 277.try_into().unwrap(),
5042 }),
5043 create_plt: None,
5044 }),
5045 },
5046 };
5047 assert_eq!(converted, expected);
5048 }
5049
5050 #[test]
5051 fn test_try_from_chain_parameters_v2() {
5052 let mut rng = StdRng::seed_from_u64(1);
5053 let (root_key, root_key_bytes) = gen_public_key(&mut rng);
5054 let (level_1_key, level_1_key_bytes) = gen_public_key(&mut rng);
5055 let (level_2_key_1, level_2_key_1_bytes) = gen_public_key(&mut rng);
5056 let (level_2_key_2, level_2_key_2_bytes) = gen_public_key(&mut rng);
5057 let cpv2 = ChainParametersV2 {
5058 consensus_parameters: Some(ConsensusParametersV1 {
5059 timeout_parameters: Some(TimeoutParameters {
5060 timeout_base: Some(Duration { value: 500 }),
5061 timeout_increase: Some(Ratio {
5062 numerator: 502,
5063 denominator: 501,
5064 }),
5065 timeout_decrease: Some(Ratio {
5066 numerator: 503,
5067 denominator: 504,
5068 }),
5069 }),
5070 min_block_time: Some(Duration { value: 505 }),
5071 block_energy_limit: Some(Energy { value: 506 }),
5072 }),
5073 euro_per_energy: Some(ExchangeRate {
5074 value: Some(Ratio {
5075 numerator: 2,
5076 denominator: 3,
5077 }),
5078 }),
5079 micro_ccd_per_euro: Some(ExchangeRate {
5080 value: Some(Ratio {
5081 numerator: 4,
5082 denominator: 5,
5083 }),
5084 }),
5085 cooldown_parameters: Some(CooldownParametersCpv1 {
5086 pool_owner_cooldown: Some(DurationSeconds { value: 6 }),
5087 delegator_cooldown: Some(DurationSeconds { value: 7 }),
5088 }),
5089 time_parameters: Some(TimeParametersCpv1 {
5090 reward_period_length: Some(RewardPeriodLength {
5091 value: Some(Epoch { value: 8 }),
5092 }),
5093 mint_per_payday: Some(MintRate {
5094 mantissa: 9,
5095 exponent: 10,
5096 }),
5097 }),
5098 account_creation_limit: Some(CredentialsPerBlockLimit { value: 11 }),
5099 mint_distribution: Some(MintDistributionCpv1 {
5100 baking_reward: Some(AmountFraction {
5101 parts_per_hundred_thousand: 12,
5102 }),
5103 finalization_reward: Some(AmountFraction {
5104 parts_per_hundred_thousand: 13,
5105 }),
5106 }),
5107 transaction_fee_distribution: Some(TransactionFeeDistribution {
5108 baker: Some(AmountFraction {
5109 parts_per_hundred_thousand: 14,
5110 }),
5111 gas_account: Some(AmountFraction {
5112 parts_per_hundred_thousand: 15,
5113 }),
5114 }),
5115 gas_rewards: Some(GasRewardsCpv2 {
5116 baker: Some(AmountFraction {
5117 parts_per_hundred_thousand: 16,
5118 }),
5119 account_creation: Some(AmountFraction {
5120 parts_per_hundred_thousand: 18,
5121 }),
5122 chain_update: Some(AmountFraction {
5123 parts_per_hundred_thousand: 19,
5124 }),
5125 }),
5126 foundation_account: Some(AccountAddress {
5127 value: vec![20u8; 32],
5128 }),
5129 pool_parameters: Some(PoolParametersCpv1 {
5130 passive_finalization_commission: Some(AmountFraction {
5131 parts_per_hundred_thousand: 21,
5132 }),
5133 passive_baking_commission: Some(AmountFraction {
5134 parts_per_hundred_thousand: 22,
5135 }),
5136 passive_transaction_commission: Some(AmountFraction {
5137 parts_per_hundred_thousand: 23,
5138 }),
5139 commission_bounds: Some(CommissionRanges {
5140 finalization: Some(InclusiveRangeAmountFraction {
5141 min: Some(AmountFraction {
5142 parts_per_hundred_thousand: 24,
5143 }),
5144 max: Some(AmountFraction {
5145 parts_per_hundred_thousand: 25,
5146 }),
5147 }),
5148 baking: Some(InclusiveRangeAmountFraction {
5149 min: Some(AmountFraction {
5150 parts_per_hundred_thousand: 26,
5151 }),
5152 max: Some(AmountFraction {
5153 parts_per_hundred_thousand: 27,
5154 }),
5155 }),
5156 transaction: Some(InclusiveRangeAmountFraction {
5157 min: Some(AmountFraction {
5158 parts_per_hundred_thousand: 28,
5159 }),
5160 max: Some(AmountFraction {
5161 parts_per_hundred_thousand: 29,
5162 }),
5163 }),
5164 }),
5165 minimum_equity_capital: Some(Amount { value: 30 }),
5166 capital_bound: Some(CapitalBound {
5167 value: Some(AmountFraction {
5168 parts_per_hundred_thousand: 31,
5169 }),
5170 }),
5171 leverage_bound: Some(LeverageFactor {
5172 value: Some(Ratio {
5173 numerator: 33,
5174 denominator: 32,
5175 }),
5176 }),
5177 }),
5178 root_keys: Some(HigherLevelKeys {
5179 keys: vec![UpdatePublicKey {
5180 value: root_key_bytes,
5181 }],
5182 threshold: Some(UpdateKeysThreshold { value: 34 }),
5183 }),
5184 level1_keys: Some(HigherLevelKeys {
5185 keys: vec![UpdatePublicKey {
5186 value: level_1_key_bytes,
5187 }],
5188 threshold: Some(UpdateKeysThreshold { value: 35 }),
5189 }),
5190 level2_keys: Some(AuthorizationsV1 {
5191 v0: Some(AuthorizationsV0 {
5192 keys: vec![
5193 UpdatePublicKey {
5194 value: level_2_key_1_bytes,
5195 },
5196 UpdatePublicKey {
5197 value: level_2_key_2_bytes,
5198 },
5199 ],
5200 emergency: Some(AccessStructure {
5201 access_public_keys: vec![UpdateKeysIndex { value: 113 }],
5202 access_threshold: Some(UpdateKeysThreshold { value: 127 }),
5203 }),
5204 protocol: Some(AccessStructure {
5205 access_public_keys: vec![UpdateKeysIndex { value: 131 }],
5206 access_threshold: Some(UpdateKeysThreshold { value: 137 }),
5207 }),
5208 parameter_consensus: Some(AccessStructure {
5209 access_public_keys: vec![UpdateKeysIndex { value: 139 }],
5210 access_threshold: Some(UpdateKeysThreshold { value: 149 }),
5211 }),
5212 parameter_euro_per_energy: Some(AccessStructure {
5213 access_public_keys: vec![UpdateKeysIndex { value: 151 }],
5214 access_threshold: Some(UpdateKeysThreshold { value: 157 }),
5215 }),
5216 parameter_micro_ccd_per_euro: Some(AccessStructure {
5217 access_public_keys: vec![UpdateKeysIndex { value: 173 }],
5218 access_threshold: Some(UpdateKeysThreshold { value: 179 }),
5219 }),
5220 parameter_foundation_account: Some(AccessStructure {
5221 access_public_keys: vec![UpdateKeysIndex { value: 181 }],
5222 access_threshold: Some(UpdateKeysThreshold { value: 191 }),
5223 }),
5224 parameter_mint_distribution: Some(AccessStructure {
5225 access_public_keys: vec![UpdateKeysIndex { value: 193 }],
5226 access_threshold: Some(UpdateKeysThreshold { value: 197 }),
5227 }),
5228 parameter_transaction_fee_distribution: Some(AccessStructure {
5229 access_public_keys: vec![UpdateKeysIndex { value: 199 }],
5230 access_threshold: Some(UpdateKeysThreshold { value: 211 }),
5231 }),
5232 parameter_gas_rewards: Some(AccessStructure {
5233 access_public_keys: vec![UpdateKeysIndex { value: 223 }],
5234 access_threshold: Some(UpdateKeysThreshold { value: 227 }),
5235 }),
5236 pool_parameters: Some(AccessStructure {
5237 access_public_keys: vec![UpdateKeysIndex { value: 229 }],
5238 access_threshold: Some(UpdateKeysThreshold { value: 233 }),
5239 }),
5240 add_anonymity_revoker: Some(AccessStructure {
5241 access_public_keys: vec![UpdateKeysIndex { value: 239 }],
5242 access_threshold: Some(UpdateKeysThreshold { value: 241 }),
5243 }),
5244 add_identity_provider: Some(AccessStructure {
5245 access_public_keys: vec![UpdateKeysIndex { value: 251 }],
5246 access_threshold: Some(UpdateKeysThreshold { value: 257 }),
5247 }),
5248 }),
5249 parameter_cooldown: Some(AccessStructure {
5250 access_public_keys: vec![UpdateKeysIndex { value: 263 }],
5251 access_threshold: Some(UpdateKeysThreshold { value: 269 }),
5252 }),
5253 parameter_time: Some(AccessStructure {
5254 access_public_keys: vec![UpdateKeysIndex { value: 271 }],
5255 access_threshold: Some(UpdateKeysThreshold { value: 277 }),
5256 }),
5257 create_plt: None,
5258 }),
5259 finalization_committee_parameters: Some(FinalizationCommitteeParameters {
5260 minimum_finalizers: 601,
5261 maximum_finalizers: 602,
5262 finalizer_relative_stake_threshold: Some(AmountFraction {
5263 parts_per_hundred_thousand: 603,
5264 }),
5265 }),
5266 };
5267 let params = ChainParameters {
5268 parameters: Some(generated::chain_parameters::Parameters::V2(cpv2)),
5269 };
5270 let converted = crate::v2::ChainParameters::try_from(params)
5271 .expect("Failed to convert chain parameters v1");
5272 let expected = crate::v2::ChainParameters {
5273 timeout_parameters: chain_parameters::TimeoutParameters {
5274 base: Some(contracts_common::Duration::from_millis(500)),
5275 increase: Some(concordium_base::common::types::Ratio::new_unchecked(
5276 502, 501,
5277 )),
5278 decrease: Some(concordium_base::common::types::Ratio::new_unchecked(
5279 503, 504,
5280 )),
5281 },
5282 election_difficulty: None,
5283 min_block_time: Some(contracts_common::Duration::from_millis(505)),
5284 block_energy_limit: Some(base::Energy::from(506)),
5285 euro_per_energy: Some(base::ExchangeRate::new_unchecked(2, 3)),
5286 micro_ccd_per_euro: Some(base::ExchangeRate::new_unchecked(4, 5)),
5287 cooldown_parameters: chain_parameters::CooldownParameters {
5288 baker_cooldown_epochs: None,
5289 pool_owner_cooldown: Some(base::DurationSeconds::from(6)),
5290 delegator_cooldown: Some(base::DurationSeconds::from(7)),
5291 },
5292 reward_period_length: Some(updates::RewardPeriodLength::from(base::Epoch::from(8))),
5293 mint_per_payday: Some(base::MintRate {
5294 mantissa: 9,
5295 exponent: 10,
5296 }),
5297 mint_per_slot: None,
5298 account_creation_limit: Some(base::CredentialsPerBlockLimit::from(11)),
5299 mint_distribution: chain_parameters::MintDistribution {
5300 baking_reward: Some(base::AmountFraction::new_unchecked(12)),
5301 finalization_reward: Some(base::AmountFraction::new_unchecked(13)),
5302 },
5303 transaction_fee_distribution: chain_parameters::TransactionFeeDistribution {
5304 baker: Some(base::AmountFraction::new_unchecked(14)),
5305 gas_account: Some(base::AmountFraction::new_unchecked(15)),
5306 },
5307 gas_rewards: chain_parameters::GasRewards {
5308 baker: Some(base::AmountFraction::new_unchecked(16)),
5309 finalization_proof: None,
5310 account_creation: Some(base::AmountFraction::new_unchecked(18)),
5311 chain_update: Some(base::AmountFraction::new_unchecked(19)),
5312 },
5313 foundation_account: Some(contracts_common::AccountAddress([20u8; 32])),
5314 staking_parameters: chain_parameters::StakingParameters {
5315 passive_finalization_commission: Some(base::AmountFraction::new_unchecked(21)),
5316 passive_baking_commission: Some(base::AmountFraction::new_unchecked(22)),
5317 passive_transaction_commission: Some(base::AmountFraction::new_unchecked(23)),
5318 finalization_commission_range: Some(base::InclusiveRange {
5319 min: base::AmountFraction::new_unchecked(24),
5320 max: base::AmountFraction::new_unchecked(25),
5321 }),
5322 baking_commission_range: Some(base::InclusiveRange {
5323 min: base::AmountFraction::new_unchecked(26),
5324 max: base::AmountFraction::new_unchecked(27),
5325 }),
5326 transaction_commission_range: Some(base::InclusiveRange {
5327 min: base::AmountFraction::new_unchecked(28),
5328 max: base::AmountFraction::new_unchecked(29),
5329 }),
5330 minimum_equity_capital: Some(contracts_common::Amount::from_micro_ccd(30)),
5331 capital_bound: Some(base::CapitalBound {
5332 bound: base::AmountFraction::new_unchecked(31),
5333 }),
5334 leverage_bound: Some(base::LeverageFactor {
5335 numerator: 33,
5336 denominator: 32,
5337 }),
5338 },
5339 finalization_committee_parameters: chain_parameters::FinalizationCommitteeParameters {
5340 min_finalizers: Some(601),
5341 max_finalizers: Some(602),
5342 finalizers_relative_stake_threshold: Some(PartsPerHundredThousands::new_unchecked(
5343 603,
5344 )),
5345 },
5346 validator_max_missed_rounds: None,
5347 keys: chain_parameters::UpdateKeys {
5348 root_keys: Some(concordium_base::updates::HigherLevelAccessStructure::<
5349 concordium_base::updates::RootKeysKind,
5350 > {
5351 keys: vec![base::UpdatePublicKey::from(
5352 crate::id::types::VerifyKey::from(root_key),
5353 )],
5354 threshold: 34.try_into().unwrap(),
5355 _phantom: Default::default(),
5356 }),
5357 level_1_keys: Some(concordium_base::updates::HigherLevelAccessStructure::<
5358 concordium_base::updates::Level1KeysKind,
5359 > {
5360 keys: vec![base::UpdatePublicKey::from(
5361 crate::id::types::VerifyKey::from(level_1_key),
5362 )],
5363 threshold: 35.try_into().unwrap(),
5364 _phantom: Default::default(),
5365 }),
5366 level_2_keys: Some(chain_parameters::Level2Keys {
5367 keys: vec![
5368 base::UpdatePublicKey::from(crate::id::types::VerifyKey::from(
5369 level_2_key_1,
5370 )),
5371 base::UpdatePublicKey::from(crate::id::types::VerifyKey::from(
5372 level_2_key_2,
5373 )),
5374 ],
5375 emergency: Some(updates::AccessStructure {
5376 authorized_keys: [base::UpdateKeysIndex::from(113)].into(),
5377 threshold: 127.try_into().unwrap(),
5378 }),
5379 protocol: Some(updates::AccessStructure {
5380 authorized_keys: [base::UpdateKeysIndex::from(131)].into(),
5381 threshold: 137.try_into().unwrap(),
5382 }),
5383 consensus: Some(updates::AccessStructure {
5384 authorized_keys: [base::UpdateKeysIndex::from(139)].into(),
5385 threshold: 149.try_into().unwrap(),
5386 }),
5387 euro_per_energy: Some(updates::AccessStructure {
5388 authorized_keys: [base::UpdateKeysIndex::from(151)].into(),
5389 threshold: 157.try_into().unwrap(),
5390 }),
5391 micro_ccd_per_euro: Some(updates::AccessStructure {
5392 authorized_keys: [base::UpdateKeysIndex::from(173)].into(),
5393 threshold: 179.try_into().unwrap(),
5394 }),
5395 foundation_account: Some(updates::AccessStructure {
5396 authorized_keys: [base::UpdateKeysIndex::from(181)].into(),
5397 threshold: 191.try_into().unwrap(),
5398 }),
5399 mint_distribution: Some(updates::AccessStructure {
5400 authorized_keys: [base::UpdateKeysIndex::from(193)].into(),
5401 threshold: 197.try_into().unwrap(),
5402 }),
5403 transaction_fee_distribution: Some(updates::AccessStructure {
5404 authorized_keys: [base::UpdateKeysIndex::from(199)].into(),
5405 threshold: 211.try_into().unwrap(),
5406 }),
5407 param_gas_rewards: Some(updates::AccessStructure {
5408 authorized_keys: [base::UpdateKeysIndex::from(223)].into(),
5409 threshold: 227.try_into().unwrap(),
5410 }),
5411 pool_parameters: Some(updates::AccessStructure {
5412 authorized_keys: [base::UpdateKeysIndex::from(229)].into(),
5413 threshold: 233.try_into().unwrap(),
5414 }),
5415 add_anonymity_revoker: Some(updates::AccessStructure {
5416 authorized_keys: [base::UpdateKeysIndex::from(239)].into(),
5417 threshold: 241.try_into().unwrap(),
5418 }),
5419 add_identity_provider: Some(updates::AccessStructure {
5420 authorized_keys: [base::UpdateKeysIndex::from(251)].into(),
5421 threshold: 257.try_into().unwrap(),
5422 }),
5423 cooldown_parameters: Some(updates::AccessStructure {
5424 authorized_keys: [base::UpdateKeysIndex::from(263)].into(),
5425 threshold: 269.try_into().unwrap(),
5426 }),
5427 time_parameters: Some(updates::AccessStructure {
5428 authorized_keys: [base::UpdateKeysIndex::from(271)].into(),
5429 threshold: 277.try_into().unwrap(),
5430 }),
5431 create_plt: None,
5432 }),
5433 },
5434 };
5435 assert_eq!(converted, expected);
5436 }
5437
5438 #[test]
5439 fn test_try_from_chain_parameters_v3() {
5440 let mut rng = StdRng::seed_from_u64(1);
5441 let (root_key, root_key_bytes) = gen_public_key(&mut rng);
5442 let (level_1_key, level_1_key_bytes) = gen_public_key(&mut rng);
5443 let (level_2_key_1, level_2_key_1_bytes) = gen_public_key(&mut rng);
5444 let (level_2_key_2, level_2_key_2_bytes) = gen_public_key(&mut rng);
5445 let cpv3 = ChainParametersV3 {
5446 consensus_parameters: Some(ConsensusParametersV1 {
5447 timeout_parameters: Some(TimeoutParameters {
5448 timeout_base: Some(Duration { value: 500 }),
5449 timeout_increase: Some(Ratio {
5450 numerator: 502,
5451 denominator: 501,
5452 }),
5453 timeout_decrease: Some(Ratio {
5454 numerator: 503,
5455 denominator: 504,
5456 }),
5457 }),
5458 min_block_time: Some(Duration { value: 505 }),
5459 block_energy_limit: Some(Energy { value: 506 }),
5460 }),
5461 euro_per_energy: Some(ExchangeRate {
5462 value: Some(Ratio {
5463 numerator: 2,
5464 denominator: 3,
5465 }),
5466 }),
5467 micro_ccd_per_euro: Some(ExchangeRate {
5468 value: Some(Ratio {
5469 numerator: 4,
5470 denominator: 5,
5471 }),
5472 }),
5473 cooldown_parameters: Some(CooldownParametersCpv1 {
5474 pool_owner_cooldown: Some(DurationSeconds { value: 6 }),
5475 delegator_cooldown: Some(DurationSeconds { value: 7 }),
5476 }),
5477 time_parameters: Some(TimeParametersCpv1 {
5478 reward_period_length: Some(RewardPeriodLength {
5479 value: Some(Epoch { value: 8 }),
5480 }),
5481 mint_per_payday: Some(MintRate {
5482 mantissa: 9,
5483 exponent: 10,
5484 }),
5485 }),
5486 account_creation_limit: Some(CredentialsPerBlockLimit { value: 11 }),
5487 mint_distribution: Some(MintDistributionCpv1 {
5488 baking_reward: Some(AmountFraction {
5489 parts_per_hundred_thousand: 12,
5490 }),
5491 finalization_reward: Some(AmountFraction {
5492 parts_per_hundred_thousand: 13,
5493 }),
5494 }),
5495 transaction_fee_distribution: Some(TransactionFeeDistribution {
5496 baker: Some(AmountFraction {
5497 parts_per_hundred_thousand: 14,
5498 }),
5499 gas_account: Some(AmountFraction {
5500 parts_per_hundred_thousand: 15,
5501 }),
5502 }),
5503 gas_rewards: Some(GasRewardsCpv2 {
5504 baker: Some(AmountFraction {
5505 parts_per_hundred_thousand: 16,
5506 }),
5507 account_creation: Some(AmountFraction {
5508 parts_per_hundred_thousand: 18,
5509 }),
5510 chain_update: Some(AmountFraction {
5511 parts_per_hundred_thousand: 19,
5512 }),
5513 }),
5514 foundation_account: Some(AccountAddress {
5515 value: vec![20u8; 32],
5516 }),
5517 pool_parameters: Some(PoolParametersCpv1 {
5518 passive_finalization_commission: Some(AmountFraction {
5519 parts_per_hundred_thousand: 21,
5520 }),
5521 passive_baking_commission: Some(AmountFraction {
5522 parts_per_hundred_thousand: 22,
5523 }),
5524 passive_transaction_commission: Some(AmountFraction {
5525 parts_per_hundred_thousand: 23,
5526 }),
5527 commission_bounds: Some(CommissionRanges {
5528 finalization: Some(InclusiveRangeAmountFraction {
5529 min: Some(AmountFraction {
5530 parts_per_hundred_thousand: 24,
5531 }),
5532 max: Some(AmountFraction {
5533 parts_per_hundred_thousand: 25,
5534 }),
5535 }),
5536 baking: Some(InclusiveRangeAmountFraction {
5537 min: Some(AmountFraction {
5538 parts_per_hundred_thousand: 26,
5539 }),
5540 max: Some(AmountFraction {
5541 parts_per_hundred_thousand: 27,
5542 }),
5543 }),
5544 transaction: Some(InclusiveRangeAmountFraction {
5545 min: Some(AmountFraction {
5546 parts_per_hundred_thousand: 28,
5547 }),
5548 max: Some(AmountFraction {
5549 parts_per_hundred_thousand: 29,
5550 }),
5551 }),
5552 }),
5553 minimum_equity_capital: Some(Amount { value: 30 }),
5554 capital_bound: Some(CapitalBound {
5555 value: Some(AmountFraction {
5556 parts_per_hundred_thousand: 31,
5557 }),
5558 }),
5559 leverage_bound: Some(LeverageFactor {
5560 value: Some(Ratio {
5561 numerator: 33,
5562 denominator: 32,
5563 }),
5564 }),
5565 }),
5566 root_keys: Some(HigherLevelKeys {
5567 keys: vec![UpdatePublicKey {
5568 value: root_key_bytes,
5569 }],
5570 threshold: Some(UpdateKeysThreshold { value: 34 }),
5571 }),
5572 level1_keys: Some(HigherLevelKeys {
5573 keys: vec![UpdatePublicKey {
5574 value: level_1_key_bytes,
5575 }],
5576 threshold: Some(UpdateKeysThreshold { value: 35 }),
5577 }),
5578 level2_keys: Some(AuthorizationsV1 {
5579 v0: Some(AuthorizationsV0 {
5580 keys: vec![
5581 UpdatePublicKey {
5582 value: level_2_key_1_bytes,
5583 },
5584 UpdatePublicKey {
5585 value: level_2_key_2_bytes,
5586 },
5587 ],
5588 emergency: Some(AccessStructure {
5589 access_public_keys: vec![UpdateKeysIndex { value: 113 }],
5590 access_threshold: Some(UpdateKeysThreshold { value: 127 }),
5591 }),
5592 protocol: Some(AccessStructure {
5593 access_public_keys: vec![UpdateKeysIndex { value: 131 }],
5594 access_threshold: Some(UpdateKeysThreshold { value: 137 }),
5595 }),
5596 parameter_consensus: Some(AccessStructure {
5597 access_public_keys: vec![UpdateKeysIndex { value: 139 }],
5598 access_threshold: Some(UpdateKeysThreshold { value: 149 }),
5599 }),
5600 parameter_euro_per_energy: Some(AccessStructure {
5601 access_public_keys: vec![UpdateKeysIndex { value: 151 }],
5602 access_threshold: Some(UpdateKeysThreshold { value: 157 }),
5603 }),
5604 parameter_micro_ccd_per_euro: Some(AccessStructure {
5605 access_public_keys: vec![UpdateKeysIndex { value: 173 }],
5606 access_threshold: Some(UpdateKeysThreshold { value: 179 }),
5607 }),
5608 parameter_foundation_account: Some(AccessStructure {
5609 access_public_keys: vec![UpdateKeysIndex { value: 181 }],
5610 access_threshold: Some(UpdateKeysThreshold { value: 191 }),
5611 }),
5612 parameter_mint_distribution: Some(AccessStructure {
5613 access_public_keys: vec![UpdateKeysIndex { value: 193 }],
5614 access_threshold: Some(UpdateKeysThreshold { value: 197 }),
5615 }),
5616 parameter_transaction_fee_distribution: Some(AccessStructure {
5617 access_public_keys: vec![UpdateKeysIndex { value: 199 }],
5618 access_threshold: Some(UpdateKeysThreshold { value: 211 }),
5619 }),
5620 parameter_gas_rewards: Some(AccessStructure {
5621 access_public_keys: vec![UpdateKeysIndex { value: 223 }],
5622 access_threshold: Some(UpdateKeysThreshold { value: 227 }),
5623 }),
5624 pool_parameters: Some(AccessStructure {
5625 access_public_keys: vec![UpdateKeysIndex { value: 229 }],
5626 access_threshold: Some(UpdateKeysThreshold { value: 233 }),
5627 }),
5628 add_anonymity_revoker: Some(AccessStructure {
5629 access_public_keys: vec![UpdateKeysIndex { value: 239 }],
5630 access_threshold: Some(UpdateKeysThreshold { value: 241 }),
5631 }),
5632 add_identity_provider: Some(AccessStructure {
5633 access_public_keys: vec![UpdateKeysIndex { value: 251 }],
5634 access_threshold: Some(UpdateKeysThreshold { value: 257 }),
5635 }),
5636 }),
5637 parameter_cooldown: Some(AccessStructure {
5638 access_public_keys: vec![UpdateKeysIndex { value: 263 }],
5639 access_threshold: Some(UpdateKeysThreshold { value: 269 }),
5640 }),
5641 parameter_time: Some(AccessStructure {
5642 access_public_keys: vec![UpdateKeysIndex { value: 271 }],
5643 access_threshold: Some(UpdateKeysThreshold { value: 277 }),
5644 }),
5645 create_plt: Some(AccessStructure {
5646 access_public_keys: vec![
5647 UpdateKeysIndex { value: 281 },
5648 UpdateKeysIndex { value: 283 },
5649 ],
5650 access_threshold: Some(UpdateKeysThreshold { value: 293 }),
5651 }),
5652 }),
5653 finalization_committee_parameters: Some(FinalizationCommitteeParameters {
5654 minimum_finalizers: 601,
5655 maximum_finalizers: 602,
5656 finalizer_relative_stake_threshold: Some(AmountFraction {
5657 parts_per_hundred_thousand: 603,
5658 }),
5659 }),
5660 validator_score_parameters: Some(ValidatorScoreParameters {
5661 maximum_missed_rounds: 607,
5662 }),
5663 };
5664 let params = ChainParameters {
5665 parameters: Some(generated::chain_parameters::Parameters::V3(cpv3)),
5666 };
5667 let converted = crate::v2::ChainParameters::try_from(params)
5668 .expect("Failed to convert chain parameters v1");
5669 let expected = crate::v2::ChainParameters {
5670 timeout_parameters: chain_parameters::TimeoutParameters {
5671 base: Some(contracts_common::Duration::from_millis(500)),
5672 increase: Some(concordium_base::common::types::Ratio::new_unchecked(
5673 502, 501,
5674 )),
5675 decrease: Some(concordium_base::common::types::Ratio::new_unchecked(
5676 503, 504,
5677 )),
5678 },
5679 election_difficulty: None,
5680 min_block_time: Some(contracts_common::Duration::from_millis(505)),
5681 block_energy_limit: Some(base::Energy::from(506)),
5682 euro_per_energy: Some(base::ExchangeRate::new_unchecked(2, 3)),
5683 micro_ccd_per_euro: Some(base::ExchangeRate::new_unchecked(4, 5)),
5684 cooldown_parameters: chain_parameters::CooldownParameters {
5685 baker_cooldown_epochs: None,
5686 pool_owner_cooldown: Some(base::DurationSeconds::from(6)),
5687 delegator_cooldown: Some(base::DurationSeconds::from(7)),
5688 },
5689 reward_period_length: Some(updates::RewardPeriodLength::from(base::Epoch::from(8))),
5690 mint_per_payday: Some(base::MintRate {
5691 mantissa: 9,
5692 exponent: 10,
5693 }),
5694 mint_per_slot: None,
5695 account_creation_limit: Some(base::CredentialsPerBlockLimit::from(11)),
5696 mint_distribution: chain_parameters::MintDistribution {
5697 baking_reward: Some(base::AmountFraction::new_unchecked(12)),
5698 finalization_reward: Some(base::AmountFraction::new_unchecked(13)),
5699 },
5700 transaction_fee_distribution: chain_parameters::TransactionFeeDistribution {
5701 baker: Some(base::AmountFraction::new_unchecked(14)),
5702 gas_account: Some(base::AmountFraction::new_unchecked(15)),
5703 },
5704 gas_rewards: chain_parameters::GasRewards {
5705 baker: Some(base::AmountFraction::new_unchecked(16)),
5706 finalization_proof: None,
5707 account_creation: Some(base::AmountFraction::new_unchecked(18)),
5708 chain_update: Some(base::AmountFraction::new_unchecked(19)),
5709 },
5710 foundation_account: Some(contracts_common::AccountAddress([20u8; 32])),
5711 staking_parameters: chain_parameters::StakingParameters {
5712 passive_finalization_commission: Some(base::AmountFraction::new_unchecked(21)),
5713 passive_baking_commission: Some(base::AmountFraction::new_unchecked(22)),
5714 passive_transaction_commission: Some(base::AmountFraction::new_unchecked(23)),
5715 finalization_commission_range: Some(base::InclusiveRange {
5716 min: base::AmountFraction::new_unchecked(24),
5717 max: base::AmountFraction::new_unchecked(25),
5718 }),
5719 baking_commission_range: Some(base::InclusiveRange {
5720 min: base::AmountFraction::new_unchecked(26),
5721 max: base::AmountFraction::new_unchecked(27),
5722 }),
5723 transaction_commission_range: Some(base::InclusiveRange {
5724 min: base::AmountFraction::new_unchecked(28),
5725 max: base::AmountFraction::new_unchecked(29),
5726 }),
5727 minimum_equity_capital: Some(contracts_common::Amount::from_micro_ccd(30)),
5728 capital_bound: Some(base::CapitalBound {
5729 bound: base::AmountFraction::new_unchecked(31),
5730 }),
5731 leverage_bound: Some(base::LeverageFactor {
5732 numerator: 33,
5733 denominator: 32,
5734 }),
5735 },
5736 finalization_committee_parameters: chain_parameters::FinalizationCommitteeParameters {
5737 min_finalizers: Some(601),
5738 max_finalizers: Some(602),
5739 finalizers_relative_stake_threshold: Some(PartsPerHundredThousands::new_unchecked(
5740 603,
5741 )),
5742 },
5743 validator_max_missed_rounds: Some(607),
5744 keys: chain_parameters::UpdateKeys {
5745 root_keys: Some(concordium_base::updates::HigherLevelAccessStructure::<
5746 concordium_base::updates::RootKeysKind,
5747 > {
5748 keys: vec![base::UpdatePublicKey::from(
5749 crate::id::types::VerifyKey::from(root_key),
5750 )],
5751 threshold: 34.try_into().unwrap(),
5752 _phantom: Default::default(),
5753 }),
5754 level_1_keys: Some(concordium_base::updates::HigherLevelAccessStructure::<
5755 concordium_base::updates::Level1KeysKind,
5756 > {
5757 keys: vec![base::UpdatePublicKey::from(
5758 crate::id::types::VerifyKey::from(level_1_key),
5759 )],
5760 threshold: 35.try_into().unwrap(),
5761 _phantom: Default::default(),
5762 }),
5763 level_2_keys: Some(chain_parameters::Level2Keys {
5764 keys: vec![
5765 base::UpdatePublicKey::from(crate::id::types::VerifyKey::from(
5766 level_2_key_1,
5767 )),
5768 base::UpdatePublicKey::from(crate::id::types::VerifyKey::from(
5769 level_2_key_2,
5770 )),
5771 ],
5772 emergency: Some(updates::AccessStructure {
5773 authorized_keys: [base::UpdateKeysIndex::from(113)].into(),
5774 threshold: 127.try_into().unwrap(),
5775 }),
5776 protocol: Some(updates::AccessStructure {
5777 authorized_keys: [base::UpdateKeysIndex::from(131)].into(),
5778 threshold: 137.try_into().unwrap(),
5779 }),
5780 consensus: Some(updates::AccessStructure {
5781 authorized_keys: [base::UpdateKeysIndex::from(139)].into(),
5782 threshold: 149.try_into().unwrap(),
5783 }),
5784 euro_per_energy: Some(updates::AccessStructure {
5785 authorized_keys: [base::UpdateKeysIndex::from(151)].into(),
5786 threshold: 157.try_into().unwrap(),
5787 }),
5788 micro_ccd_per_euro: Some(updates::AccessStructure {
5789 authorized_keys: [base::UpdateKeysIndex::from(173)].into(),
5790 threshold: 179.try_into().unwrap(),
5791 }),
5792 foundation_account: Some(updates::AccessStructure {
5793 authorized_keys: [base::UpdateKeysIndex::from(181)].into(),
5794 threshold: 191.try_into().unwrap(),
5795 }),
5796 mint_distribution: Some(updates::AccessStructure {
5797 authorized_keys: [base::UpdateKeysIndex::from(193)].into(),
5798 threshold: 197.try_into().unwrap(),
5799 }),
5800 transaction_fee_distribution: Some(updates::AccessStructure {
5801 authorized_keys: [base::UpdateKeysIndex::from(199)].into(),
5802 threshold: 211.try_into().unwrap(),
5803 }),
5804 param_gas_rewards: Some(updates::AccessStructure {
5805 authorized_keys: [base::UpdateKeysIndex::from(223)].into(),
5806 threshold: 227.try_into().unwrap(),
5807 }),
5808 pool_parameters: Some(updates::AccessStructure {
5809 authorized_keys: [base::UpdateKeysIndex::from(229)].into(),
5810 threshold: 233.try_into().unwrap(),
5811 }),
5812 add_anonymity_revoker: Some(updates::AccessStructure {
5813 authorized_keys: [base::UpdateKeysIndex::from(239)].into(),
5814 threshold: 241.try_into().unwrap(),
5815 }),
5816 add_identity_provider: Some(updates::AccessStructure {
5817 authorized_keys: [base::UpdateKeysIndex::from(251)].into(),
5818 threshold: 257.try_into().unwrap(),
5819 }),
5820 cooldown_parameters: Some(updates::AccessStructure {
5821 authorized_keys: [base::UpdateKeysIndex::from(263)].into(),
5822 threshold: 269.try_into().unwrap(),
5823 }),
5824 time_parameters: Some(updates::AccessStructure {
5825 authorized_keys: [base::UpdateKeysIndex::from(271)].into(),
5826 threshold: 277.try_into().unwrap(),
5827 }),
5828 create_plt: Some(updates::AccessStructure {
5829 authorized_keys: [
5830 base::UpdateKeysIndex::from(281),
5831 base::UpdateKeysIndex::from(283),
5832 ]
5833 .into(),
5834 threshold: 293.try_into().unwrap(),
5835 }),
5836 }),
5837 },
5838 };
5839 assert_eq!(converted, expected);
5840 }
5841}