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