mina_tree/scan_state/
conv.rs

1#![allow(unused_variables, unreachable_code)]
2
3use std::sync::Arc;
4
5use ark_ff::fields::arithmetic::InvalidBigInt;
6use mina_curves::pasta::Fp;
7use mina_p2p_messages::{
8    binprot,
9    list::List,
10    pseq::PaddedSeq,
11    string::CharString,
12    v2::{
13        self, BlockTimeTimeStableV1,
14        ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1,
15        ConsensusProofOfStakeDataEpochDataStakingValueVersionedValueStableV1,
16        CurrencyAmountStableV1, CurrencyBalanceStableV1, CurrencyFeeStableV1,
17        DataHashLibStateHashStableV1, EpochSeed, LedgerProofProdStableV2,
18        MinaBaseAccountIdDigestStableV1, MinaBaseAccountIdStableV2,
19        MinaBaseAccountUpdateBodyEventsStableV1, MinaBaseAccountUpdateBodyFeePayerStableV1,
20        MinaBaseAccountUpdateBodyStableV1, MinaBaseAccountUpdateFeePayerStableV1,
21        MinaBaseAccountUpdateMayUseTokenStableV1, MinaBaseAccountUpdatePreconditionsStableV1,
22        MinaBaseAccountUpdateTStableV1, MinaBaseAccountUpdateUpdateStableV1,
23        MinaBaseAccountUpdateUpdateStableV1AppStateA,
24        MinaBaseAccountUpdateUpdateTimingInfoStableV1, MinaBaseCallStackDigestStableV1,
25        MinaBaseCoinbaseFeeTransferStableV1, MinaBaseCoinbaseStableV1, MinaBaseEpochSeedStableV1,
26        MinaBaseFeeExcessStableV1, MinaBaseFeeTransferSingleStableV2, MinaBaseFeeTransferStableV2,
27        MinaBaseLedgerHash0StableV1, MinaBasePaymentPayloadStableV2,
28        MinaBasePendingCoinbaseCoinbaseStackStableV1, MinaBasePendingCoinbaseHashBuilderStableV1,
29        MinaBasePendingCoinbaseHashVersionedStableV1,
30        MinaBasePendingCoinbaseMerkleTreeVersionedStableV2,
31        MinaBasePendingCoinbaseMerkleTreeVersionedStableV2Tree, MinaBasePendingCoinbaseStableV2,
32        MinaBasePendingCoinbaseStackHashStableV1, MinaBasePendingCoinbaseStackIdStableV1,
33        MinaBasePendingCoinbaseStackVersionedStableV1, MinaBasePendingCoinbaseStateStackStableV1,
34        MinaBasePendingCoinbaseUpdateActionStableV1, MinaBasePendingCoinbaseUpdateStableV1,
35        MinaBaseReceiptChainHashStableV1, MinaBaseSignatureStableV1,
36        MinaBaseSignedCommandMemoStableV1, MinaBaseSignedCommandPayloadBodyStableV2,
37        MinaBaseSignedCommandPayloadCommonStableV2, MinaBaseSignedCommandPayloadStableV2,
38        MinaBaseSignedCommandStableV2, MinaBaseSokMessageStableV1, MinaBaseStackFrameStableV1,
39        MinaBaseStagedLedgerHashNonSnarkStableV1, MinaBaseStagedLedgerHashStableV1,
40        MinaBaseStakeDelegationStableV2, MinaBaseStateBodyHashStableV1,
41        MinaBaseTransactionStatusFailureCollectionStableV1,
42        MinaBaseTransactionStatusFailureStableV2, MinaBaseTransactionStatusStableV2,
43        MinaBaseUserCommandStableV2, MinaBaseZkappCommandTStableV1WireStableV1,
44        MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesA,
45        MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA,
46        MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAACallsA,
47        MinaBaseZkappPreconditionAccountStableV2, MinaBaseZkappPreconditionAccountStableV2BalanceA,
48        MinaBaseZkappPreconditionProtocolStateEpochDataStableV1,
49        MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochLedger,
50        MinaBaseZkappPreconditionProtocolStateStableV1,
51        MinaBaseZkappPreconditionProtocolStateStableV1AmountA,
52        MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlotA,
53        MinaBaseZkappPreconditionProtocolStateStableV1Length,
54        MinaBaseZkappPreconditionProtocolStateStableV1LengthA,
55        MinaNumbersGlobalSlotSinceGenesisMStableV1, MinaNumbersGlobalSlotSinceHardForkMStableV1,
56        MinaNumbersGlobalSlotSpanStableV1,
57        MinaStateBlockchainStateValueStableV2LedgerProofStatement,
58        MinaStateBlockchainStateValueStableV2LedgerProofStatementSource,
59        MinaStateBlockchainStateValueStableV2SignedAmount, MinaStateSnarkedLedgerStateStableV2,
60        MinaStateSnarkedLedgerStateWithSokStableV2,
61        MinaTransactionLogicTransactionAppliedCoinbaseAppliedStableV2,
62        MinaTransactionLogicTransactionAppliedCoinbaseAppliedStableV2Coinbase,
63        MinaTransactionLogicTransactionAppliedCommandAppliedStableV2,
64        MinaTransactionLogicTransactionAppliedFeeTransferAppliedStableV2,
65        MinaTransactionLogicTransactionAppliedFeeTransferAppliedStableV2FeeTransfer,
66        MinaTransactionLogicTransactionAppliedSignedCommandAppliedBodyStableV2,
67        MinaTransactionLogicTransactionAppliedSignedCommandAppliedCommonStableV2,
68        MinaTransactionLogicTransactionAppliedSignedCommandAppliedCommonStableV2UserCommand,
69        MinaTransactionLogicTransactionAppliedSignedCommandAppliedStableV2,
70        MinaTransactionLogicTransactionAppliedStableV2,
71        MinaTransactionLogicTransactionAppliedVaryingStableV2,
72        MinaTransactionLogicTransactionAppliedZkappCommandAppliedStableV1,
73        MinaTransactionLogicTransactionAppliedZkappCommandAppliedStableV1Command,
74        MinaTransactionLogicZkappCommandLogicLocalStateValueStableV1,
75        MinaTransactionTransactionStableV2, ParallelScanJobStatusStableV1,
76        ParallelScanSequenceNumberStableV1, ParallelScanWeightStableV1, SgnStableV1, SignedAmount,
77        StagedLedgerDiffDiffDiffStableV2, StagedLedgerDiffDiffFtStableV1,
78        StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2,
79        StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2Coinbase,
80        StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2,
81        StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2B,
82        StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2Coinbase,
83        StagedLedgerDiffDiffStableV2, StateHash, TokenFeeExcess,
84        TransactionSnarkScanStateLedgerProofWithSokMessageStableV2,
85        TransactionSnarkScanStateStableV2,
86        TransactionSnarkScanStateStableV2PreviousIncompleteZkappUpdates1::Border_block_continued_in_the_next_tree,
87        TransactionSnarkScanStateStableV2ScanState,
88        TransactionSnarkScanStateStableV2ScanStateTreesABaseT1,
89        TransactionSnarkScanStateStableV2ScanStateTreesABaseT1Full,
90        TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1,
91        TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1Full,
92        TransactionSnarkScanStateStableV2TreesAMerge,
93        TransactionSnarkScanStateTransactionWithWitnessStableV2, TransactionSnarkStableV2,
94        TransactionSnarkWorkTStableV2, TransactionSnarkWorkTStableV2Proofs,
95        UnsignedExtendedUInt32StableV1, UnsignedExtendedUInt64Int64ForVersionTagsStableV1,
96    },
97};
98use mina_signer::Signature;
99
100use crate::{
101    array_into_with,
102    proofs::field::FieldWitness,
103    scan_state::{
104        currency::BlockTime,
105        pending_coinbase::{Stack, StackHasher},
106        scan_state::BorderBlockContinuedInTheNextTree,
107        transaction_logic::{
108            signed_command::{PaymentPayload, StakeDelegationPayload},
109            zkapp_command::{self, AuthorizationKind, CallForest, MayUseToken},
110            WithStatus,
111        },
112    },
113    staged_ledger::hash::{AuxHash, NonStark, PendingCoinbaseAux, StagedLedgerHash},
114    Account, AccountId, Address, HashesMatrix, MutableFp, TokenId, VerificationKey,
115    VerificationKeyWire, VotingFor,
116};
117
118use super::{
119    currency::{Amount, Balance, Fee, Index, Length, Nonce, Sgn, Signed, Slot, SlotSpan},
120    fee_excess::FeeExcess,
121    parallel_scan::{self, JobStatus, ParallelScan, SequenceNumber},
122    pending_coinbase::{self, PendingCoinbase},
123    scan_state::{
124        transaction_snark::{
125            LedgerProof, LedgerProofWithSokMessage, Registers, SokDigest, SokMessage, Statement,
126            TransactionSnark, TransactionWithWitness,
127        },
128        AvailableJob, AvailableJobMessage, ScanState,
129    },
130    transaction_logic::{
131        self,
132        local_state::LocalState,
133        protocol_state,
134        signed_command::SignedCommand,
135        transaction_applied::{self, TransactionApplied},
136        zkapp_command::{
137            verifiable, AccountUpdate, FeePayer, FeePayerBody, SetOrKeep, WithStackHash,
138        },
139        zkapp_statement::ZkappStatement,
140        CoinbaseFeeTransfer, FeeTransfer, Memo, SingleFeeTransfer, Transaction, TransactionFailure,
141        TransactionStatus, UserCommand,
142    },
143};
144
145impl From<CurrencyAmountStableV1> for Amount {
146    fn from(value: CurrencyAmountStableV1) -> Self {
147        Self(value.as_u64())
148    }
149}
150
151impl From<CurrencyAmountStableV1> for Balance {
152    fn from(value: CurrencyAmountStableV1) -> Self {
153        Self(value.as_u64())
154    }
155}
156
157impl From<Amount> for CurrencyAmountStableV1 {
158    fn from(value: Amount) -> Self {
159        Self(UnsignedExtendedUInt64Int64ForVersionTagsStableV1(
160            value.as_u64().into(),
161        ))
162    }
163}
164
165impl From<&Balance> for CurrencyBalanceStableV1 {
166    fn from(value: &Balance) -> Self {
167        Self((*value).into())
168    }
169}
170
171impl From<Balance> for CurrencyAmountStableV1 {
172    fn from(value: Balance) -> Self {
173        Self(UnsignedExtendedUInt64Int64ForVersionTagsStableV1(
174            value.as_u64().into(),
175        ))
176    }
177}
178
179impl From<&SignedAmount> for Signed<Amount> {
180    fn from(value: &SignedAmount) -> Self {
181        Self {
182            magnitude: Amount(value.magnitude.clone().as_u64()),
183            sgn: value.sgn.clone().into(),
184        }
185    }
186}
187
188impl From<&Amount> for CurrencyAmountStableV1 {
189    fn from(value: &Amount) -> Self {
190        CurrencyAmountStableV1(UnsignedExtendedUInt64Int64ForVersionTagsStableV1(
191            value.as_u64().into(),
192        ))
193    }
194}
195
196impl From<&Amount> for CurrencyFeeStableV1 {
197    fn from(value: &Amount) -> Self {
198        CurrencyFeeStableV1(UnsignedExtendedUInt64Int64ForVersionTagsStableV1(
199            value.as_u64().into(),
200        ))
201    }
202}
203
204impl From<&Signed<Amount>> for SignedAmount {
205    fn from(value: &Signed<Amount>) -> Self {
206        Self {
207            magnitude: (&value.magnitude).into(),
208            sgn: (&value.sgn).into(),
209        }
210    }
211}
212
213impl From<&CurrencyFeeStableV1> for Fee {
214    fn from(value: &CurrencyFeeStableV1) -> Self {
215        Self(value.as_u64())
216    }
217}
218
219impl From<&CurrencyAmountStableV1> for Fee {
220    fn from(value: &CurrencyAmountStableV1) -> Self {
221        Self(value.as_u64())
222    }
223}
224
225impl From<&Nonce> for mina_p2p_messages::v2::UnsignedExtendedUInt32StableV1 {
226    fn from(value: &Nonce) -> Self {
227        Self(value.as_u32().into())
228    }
229}
230
231impl From<&mina_p2p_messages::v2::UnsignedExtendedUInt32StableV1> for Nonce {
232    fn from(value: &mina_p2p_messages::v2::UnsignedExtendedUInt32StableV1) -> Self {
233        Self::from_u32(value.as_u32())
234    }
235}
236
237impl From<&mina_p2p_messages::v2::UnsignedExtendedUInt32StableV1> for Slot {
238    fn from(value: &mina_p2p_messages::v2::UnsignedExtendedUInt32StableV1) -> Self {
239        Self::from_u32(value.as_u32())
240    }
241}
242
243impl From<&Slot> for mina_p2p_messages::v2::UnsignedExtendedUInt32StableV1 {
244    fn from(value: &Slot) -> Self {
245        Self(value.as_u32().into())
246    }
247}
248
249impl From<&mina_p2p_messages::v2::UnsignedExtendedUInt32StableV1> for Length {
250    fn from(value: &mina_p2p_messages::v2::UnsignedExtendedUInt32StableV1) -> Self {
251        Self::from_u32(value.0.as_u32())
252    }
253}
254
255impl From<&Length> for mina_p2p_messages::v2::UnsignedExtendedUInt32StableV1 {
256    fn from(value: &Length) -> Self {
257        Self(value.as_u32().into())
258    }
259}
260
261impl From<SgnStableV1> for Sgn {
262    fn from(value: SgnStableV1) -> Self {
263        match value {
264            SgnStableV1::Pos => Self::Pos,
265            SgnStableV1::Neg => Self::Neg,
266        }
267    }
268}
269
270impl From<&SignedAmount> for Signed<Fee> {
271    fn from(value: &SignedAmount) -> Self {
272        Self {
273            magnitude: (&value.magnitude).into(),
274            sgn: value.sgn.clone().into(),
275        }
276    }
277}
278
279impl From<&Sgn> for SgnStableV1 {
280    fn from(value: &Sgn) -> Self {
281        match value {
282            Sgn::Pos => Self::Pos,
283            Sgn::Neg => Self::Neg,
284        }
285    }
286}
287
288impl From<&Fee> for CurrencyFeeStableV1 {
289    fn from(value: &Fee) -> Self {
290        Self(UnsignedExtendedUInt64Int64ForVersionTagsStableV1(
291            value.as_u64().into(),
292        ))
293    }
294}
295
296impl From<&Fee> for CurrencyAmountStableV1 {
297    fn from(value: &Fee) -> Self {
298        Self(UnsignedExtendedUInt64Int64ForVersionTagsStableV1(
299            value.as_u64().into(),
300        ))
301    }
302}
303
304impl From<&Signed<Fee>> for SignedAmount {
305    fn from(value: &Signed<Fee>) -> Self {
306        Self {
307            magnitude: (&value.magnitude).into(),
308            sgn: (&value.sgn).into(),
309        }
310    }
311}
312
313impl TryFrom<&MinaBaseFeeExcessStableV1> for FeeExcess {
314    type Error = InvalidBigInt;
315
316    fn try_from(value: &MinaBaseFeeExcessStableV1) -> Result<Self, Self::Error> {
317        Ok(Self {
318            fee_token_l: (&*value.0.token).try_into()?,
319            fee_excess_l: (&value.0.amount).into(),
320            fee_token_r: (&*value.1.token).try_into()?,
321            fee_excess_r: (&value.1.amount).into(),
322        })
323    }
324}
325
326impl From<&FeeExcess> for MinaBaseFeeExcessStableV1 {
327    fn from(value: &FeeExcess) -> Self {
328        Self(
329            TokenFeeExcess {
330                token: (&value.fee_token_l).into(),
331                amount: (&value.fee_excess_l).into(),
332            },
333            TokenFeeExcess {
334                token: (&value.fee_token_r).into(),
335                amount: (&value.fee_excess_r).into(),
336            },
337        )
338    }
339}
340
341impl TryFrom<&MinaBasePendingCoinbaseStackVersionedStableV1> for pending_coinbase::Stack {
342    type Error = InvalidBigInt;
343
344    fn try_from(
345        value: &MinaBasePendingCoinbaseStackVersionedStableV1,
346    ) -> Result<Self, Self::Error> {
347        Ok(Self {
348            data: pending_coinbase::CoinbaseStack(value.data.0.to_field()?),
349            state: pending_coinbase::StateStack {
350                init: value.state.init.0.to_field()?,
351                curr: value.state.curr.0.to_field()?,
352            },
353        })
354    }
355}
356
357impl From<&pending_coinbase::Stack> for MinaBasePendingCoinbaseStackVersionedStableV1 {
358    fn from(value: &pending_coinbase::Stack) -> Self {
359        Self {
360            data: MinaBasePendingCoinbaseCoinbaseStackStableV1::from(&value.data).into(),
361            state: (&value.state).into(),
362        }
363    }
364}
365
366impl From<&pending_coinbase::CoinbaseStack> for MinaBasePendingCoinbaseCoinbaseStackStableV1 {
367    fn from(value: &pending_coinbase::CoinbaseStack) -> Self {
368        Self(value.0.into())
369    }
370}
371
372impl From<&pending_coinbase::StateStack> for MinaBasePendingCoinbaseStateStackStableV1 {
373    fn from(value: &pending_coinbase::StateStack) -> Self {
374        Self {
375            init: MinaBasePendingCoinbaseStackHashStableV1(value.init.into()).into(),
376            curr: MinaBasePendingCoinbaseStackHashStableV1(value.curr.into()).into(),
377        }
378    }
379}
380
381impl From<&MinaBaseTransactionStatusFailureStableV2> for TransactionFailure {
382    fn from(value: &MinaBaseTransactionStatusFailureStableV2) -> Self {
383        use MinaBaseTransactionStatusFailureStableV2 as P2P;
384
385        match value {
386            P2P::Predicate => Self::Predicate,
387            P2P::SourceNotPresent => Self::SourceNotPresent,
388            P2P::ReceiverNotPresent => Self::ReceiverNotPresent,
389            P2P::AmountInsufficientToCreateAccount => Self::AmountInsufficientToCreateAccount,
390            P2P::CannotPayCreationFeeInToken => Self::CannotPayCreationFeeInToken,
391            P2P::SourceInsufficientBalance => Self::SourceInsufficientBalance,
392            P2P::SourceMinimumBalanceViolation => Self::SourceMinimumBalanceViolation,
393            P2P::ReceiverAlreadyExists => Self::ReceiverAlreadyExists,
394            P2P::TokenOwnerNotCaller => Self::TokenOwnerNotCaller,
395            P2P::Overflow => Self::Overflow,
396            P2P::GlobalExcessOverflow => Self::GlobalExcessOverflow,
397            P2P::LocalExcessOverflow => Self::LocalExcessOverflow,
398            P2P::LocalSupplyIncreaseOverflow => Self::LocalSupplyIncreaseOverflow,
399            P2P::GlobalSupplyIncreaseOverflow => Self::GlobalSupplyIncreaseOverflow,
400            P2P::SignedCommandOnZkappAccount => Self::SignedCommandOnZkappAccount,
401            P2P::ZkappAccountNotPresent => Self::ZkappAccountNotPresent,
402            P2P::UpdateNotPermittedBalance => Self::UpdateNotPermittedBalance,
403            // P2P::UpdateNotPermittedTimingExistingAccount => {
404            //     Self::UpdateNotPermittedTimingExistingAccount
405            // }
406            P2P::UpdateNotPermittedDelegate => Self::UpdateNotPermittedDelegate,
407            P2P::UpdateNotPermittedAppState => Self::UpdateNotPermittedAppState,
408            P2P::UpdateNotPermittedVerificationKey => Self::UpdateNotPermittedVerificationKey,
409            P2P::UpdateNotPermittedActionState => Self::UpdateNotPermittedActionState,
410            P2P::UpdateNotPermittedZkappUri => Self::UpdateNotPermittedZkappUri,
411            P2P::UpdateNotPermittedTokenSymbol => Self::UpdateNotPermittedTokenSymbol,
412            P2P::UpdateNotPermittedPermissions => Self::UpdateNotPermittedPermissions,
413            P2P::UpdateNotPermittedNonce => Self::UpdateNotPermittedNonce,
414            P2P::UpdateNotPermittedVotingFor => Self::UpdateNotPermittedVotingFor,
415            P2P::ZkappCommandReplayCheckFailed => Self::ZkappCommandReplayCheckFailed,
416            P2P::FeePayerNonceMustIncrease => Self::FeePayerNonceMustIncrease,
417            P2P::FeePayerMustBeSigned => Self::FeePayerMustBeSigned,
418            P2P::AccountBalancePreconditionUnsatisfied => {
419                Self::AccountBalancePreconditionUnsatisfied
420            }
421            P2P::AccountNoncePreconditionUnsatisfied => Self::AccountNoncePreconditionUnsatisfied,
422            P2P::AccountReceiptChainHashPreconditionUnsatisfied => {
423                Self::AccountReceiptChainHashPreconditionUnsatisfied
424            }
425            P2P::AccountDelegatePreconditionUnsatisfied => {
426                Self::AccountDelegatePreconditionUnsatisfied
427            }
428            P2P::AccountActionStatePreconditionUnsatisfied => {
429                Self::AccountActionStatePreconditionUnsatisfied
430            }
431            P2P::AccountAppStatePreconditionUnsatisfied(v) => {
432                Self::AccountAppStatePreconditionUnsatisfied(**v)
433            }
434            P2P::AccountProvedStatePreconditionUnsatisfied => {
435                Self::AccountProvedStatePreconditionUnsatisfied
436            }
437            P2P::AccountIsNewPreconditionUnsatisfied => Self::AccountIsNewPreconditionUnsatisfied,
438            P2P::ProtocolStatePreconditionUnsatisfied => Self::ProtocolStatePreconditionUnsatisfied,
439            P2P::IncorrectNonce => Self::IncorrectNonce,
440            P2P::InvalidFeeExcess => Self::InvalidFeeExcess,
441            P2P::Cancelled => Self::Cancelled,
442            P2P::UpdateNotPermittedAccess => Self::UpdateNotPermittedAccess,
443            P2P::UpdateNotPermittedTiming => Self::UpdateNotPermittedTiming,
444            P2P::UnexpectedVerificationKeyHash => Self::UnexpectedVerificationKeyHash,
445            P2P::ValidWhilePreconditionUnsatisfied => Self::ValidWhilePreconditionUnsatisfied,
446        }
447    }
448}
449
450impl From<&TransactionFailure> for MinaBaseTransactionStatusFailureStableV2 {
451    fn from(value: &TransactionFailure) -> Self {
452        use TransactionFailure as P2P;
453
454        match value {
455            P2P::Predicate => Self::Predicate,
456            P2P::SourceNotPresent => Self::SourceNotPresent,
457            P2P::ReceiverNotPresent => Self::ReceiverNotPresent,
458            P2P::AmountInsufficientToCreateAccount => Self::AmountInsufficientToCreateAccount,
459            P2P::CannotPayCreationFeeInToken => Self::CannotPayCreationFeeInToken,
460            P2P::SourceInsufficientBalance => Self::SourceInsufficientBalance,
461            P2P::SourceMinimumBalanceViolation => Self::SourceMinimumBalanceViolation,
462            P2P::ReceiverAlreadyExists => Self::ReceiverAlreadyExists,
463            P2P::TokenOwnerNotCaller => Self::TokenOwnerNotCaller,
464            P2P::Overflow => Self::Overflow,
465            P2P::GlobalExcessOverflow => Self::GlobalExcessOverflow,
466            P2P::LocalExcessOverflow => Self::LocalExcessOverflow,
467            P2P::LocalSupplyIncreaseOverflow => Self::LocalSupplyIncreaseOverflow,
468            P2P::GlobalSupplyIncreaseOverflow => Self::GlobalSupplyIncreaseOverflow,
469            P2P::SignedCommandOnZkappAccount => Self::SignedCommandOnZkappAccount,
470            P2P::ZkappAccountNotPresent => Self::ZkappAccountNotPresent,
471            P2P::UpdateNotPermittedBalance => Self::UpdateNotPermittedBalance,
472            // P2P::UpdateNotPermittedTimingExistingAccount => {
473            //     Self::UpdateNotPermittedTimingExistingAccount
474            // }
475            P2P::UpdateNotPermittedDelegate => Self::UpdateNotPermittedDelegate,
476            P2P::UpdateNotPermittedAppState => Self::UpdateNotPermittedAppState,
477            P2P::UpdateNotPermittedVerificationKey => Self::UpdateNotPermittedVerificationKey,
478            P2P::UpdateNotPermittedActionState => Self::UpdateNotPermittedActionState,
479            P2P::UpdateNotPermittedZkappUri => Self::UpdateNotPermittedZkappUri,
480            P2P::UpdateNotPermittedTokenSymbol => Self::UpdateNotPermittedTokenSymbol,
481            P2P::UpdateNotPermittedPermissions => Self::UpdateNotPermittedPermissions,
482            P2P::UpdateNotPermittedNonce => Self::UpdateNotPermittedNonce,
483            P2P::UpdateNotPermittedVotingFor => Self::UpdateNotPermittedVotingFor,
484            P2P::ZkappCommandReplayCheckFailed => Self::ZkappCommandReplayCheckFailed,
485            P2P::FeePayerNonceMustIncrease => Self::FeePayerNonceMustIncrease,
486            P2P::FeePayerMustBeSigned => Self::FeePayerMustBeSigned,
487            P2P::AccountBalancePreconditionUnsatisfied => {
488                Self::AccountBalancePreconditionUnsatisfied
489            }
490            P2P::AccountNoncePreconditionUnsatisfied => Self::AccountNoncePreconditionUnsatisfied,
491            P2P::AccountReceiptChainHashPreconditionUnsatisfied => {
492                Self::AccountReceiptChainHashPreconditionUnsatisfied
493            }
494            P2P::AccountDelegatePreconditionUnsatisfied => {
495                Self::AccountDelegatePreconditionUnsatisfied
496            }
497            P2P::AccountActionStatePreconditionUnsatisfied => {
498                Self::AccountActionStatePreconditionUnsatisfied
499            }
500            P2P::AccountAppStatePreconditionUnsatisfied(v) => {
501                Self::AccountAppStatePreconditionUnsatisfied((*v).into())
502            }
503            P2P::AccountProvedStatePreconditionUnsatisfied => {
504                Self::AccountProvedStatePreconditionUnsatisfied
505            }
506            P2P::AccountIsNewPreconditionUnsatisfied => Self::AccountIsNewPreconditionUnsatisfied,
507            P2P::ProtocolStatePreconditionUnsatisfied => Self::ProtocolStatePreconditionUnsatisfied,
508            P2P::IncorrectNonce => Self::IncorrectNonce,
509            P2P::InvalidFeeExcess => Self::InvalidFeeExcess,
510            P2P::Cancelled => Self::Cancelled,
511            P2P::UpdateNotPermittedAccess => Self::UpdateNotPermittedAccess,
512            P2P::UpdateNotPermittedTiming => Self::UpdateNotPermittedTiming,
513            P2P::UnexpectedVerificationKeyHash => Self::UnexpectedVerificationKeyHash,
514            P2P::ValidWhilePreconditionUnsatisfied => Self::ValidWhilePreconditionUnsatisfied,
515        }
516    }
517}
518
519impl TryFrom<&MinaStateBlockchainStateValueStableV2LedgerProofStatementSource> for Registers {
520    type Error = InvalidBigInt;
521
522    fn try_from(
523        value: &MinaStateBlockchainStateValueStableV2LedgerProofStatementSource,
524    ) -> Result<Self, Self::Error> {
525        Ok(Self {
526            first_pass_ledger: value.first_pass_ledger.to_field()?,
527            second_pass_ledger: value.second_pass_ledger.to_field()?,
528            pending_coinbase_stack: (&value.pending_coinbase_stack).try_into()?,
529            local_state: LocalState {
530                stack_frame: value.local_state.stack_frame.0.to_field()?,
531                call_stack: value.local_state.call_stack.0.to_field()?,
532                transaction_commitment: value.local_state.transaction_commitment.to_field()?,
533                full_transaction_commitment: value
534                    .local_state
535                    .full_transaction_commitment
536                    .to_field()?,
537                excess: (&value.local_state.excess).into(),
538                supply_increase: (&value.local_state.supply_increase).into(),
539                ledger: value.local_state.ledger.0.to_field()?,
540                success: value.local_state.success,
541                account_update_index: Index(value.local_state.account_update_index.0.as_u32()),
542                failure_status_tbl: value
543                    .local_state
544                    .failure_status_tbl
545                    .0
546                    .iter()
547                    .map(|s| s.iter().map(|s| s.into()).collect())
548                    .collect(),
549                will_succeed: value.local_state.will_succeed,
550            },
551        })
552    }
553}
554
555impl From<&MinaStateBlockchainStateValueStableV2SignedAmount> for Signed<Amount> {
556    fn from(value: &MinaStateBlockchainStateValueStableV2SignedAmount) -> Self {
557        let MinaStateBlockchainStateValueStableV2SignedAmount { magnitude, sgn } = value;
558
559        Self {
560            magnitude: (magnitude.clone()).into(),
561            sgn: (sgn.clone()).into(),
562        }
563    }
564}
565
566impl From<&Signed<Amount>> for MinaStateBlockchainStateValueStableV2SignedAmount {
567    fn from(value: &Signed<Amount>) -> Self {
568        let Signed::<Amount> { magnitude, sgn } = value;
569
570        Self {
571            magnitude: (*magnitude).into(),
572            sgn: sgn.into(),
573        }
574    }
575}
576
577impl TryFrom<&MinaStateBlockchainStateValueStableV2LedgerProofStatement> for Statement<()> {
578    type Error = InvalidBigInt;
579
580    fn try_from(
581        value: &MinaStateBlockchainStateValueStableV2LedgerProofStatement,
582    ) -> Result<Self, Self::Error> {
583        Ok(Self {
584            source: (&value.source).try_into()?,
585            target: (&value.target).try_into()?,
586            connecting_ledger_left: value.connecting_ledger_left.to_field()?,
587            connecting_ledger_right: value.connecting_ledger_right.to_field()?,
588            supply_increase: (&value.supply_increase).into(),
589            fee_excess: (&value.fee_excess).try_into()?,
590            sok_digest: (),
591        })
592    }
593}
594
595impl TryFrom<&MinaStateSnarkedLedgerStateWithSokStableV2> for Statement<SokDigest> {
596    type Error = InvalidBigInt;
597
598    fn try_from(value: &MinaStateSnarkedLedgerStateWithSokStableV2) -> Result<Self, Self::Error> {
599        Ok(Self {
600            source: (&value.source).try_into()?,
601            target: (&value.target).try_into()?,
602            connecting_ledger_left: value.connecting_ledger_left.to_field()?,
603            connecting_ledger_right: value.connecting_ledger_right.to_field()?,
604            supply_increase: (&value.supply_increase).into(),
605            fee_excess: (&value.fee_excess).try_into()?,
606            sok_digest: SokDigest(value.sok_digest.to_vec()),
607        })
608    }
609}
610
611impl TryFrom<&MinaStateSnarkedLedgerStateWithSokStableV2> for Statement<()> {
612    type Error = InvalidBigInt;
613
614    fn try_from(value: &MinaStateSnarkedLedgerStateWithSokStableV2) -> Result<Self, Self::Error> {
615        Ok(Self {
616            source: (&value.source).try_into()?,
617            target: (&value.target).try_into()?,
618            connecting_ledger_left: value.connecting_ledger_left.to_field()?,
619            connecting_ledger_right: value.connecting_ledger_right.to_field()?,
620            supply_increase: (&value.supply_increase).into(),
621            fee_excess: (&value.fee_excess).try_into()?,
622            sok_digest: (),
623        })
624    }
625}
626
627impl From<&Statement<SokDigest>> for MinaStateSnarkedLedgerStateWithSokStableV2 {
628    fn from(value: &Statement<SokDigest>) -> Self {
629        Self {
630            source: (&value.source).into(),
631            target: (&value.target).into(),
632            connecting_ledger_left: MinaBaseLedgerHash0StableV1(
633                (&value.connecting_ledger_left).into(),
634            )
635            .into(),
636            connecting_ledger_right: MinaBaseLedgerHash0StableV1(
637                (&value.connecting_ledger_right).into(),
638            )
639            .into(),
640            supply_increase: (&value.supply_increase).into(),
641            fee_excess: (&value.fee_excess).into(),
642            sok_digest: (&value.sok_digest).into(),
643        }
644    }
645}
646
647impl From<&MinaBaseTransactionStatusStableV2> for TransactionStatus {
648    fn from(value: &MinaBaseTransactionStatusStableV2) -> Self {
649        match value {
650            MinaBaseTransactionStatusStableV2::Applied => Self::Applied,
651            MinaBaseTransactionStatusStableV2::Failed(faileds) => Self::Failed(
652                faileds
653                    .0
654                    .iter()
655                    .map(|s| s.iter().map(Into::into).collect())
656                    .collect(),
657            ),
658        }
659    }
660}
661
662impl From<&TransactionStatus> for MinaBaseTransactionStatusStableV2 {
663    fn from(value: &TransactionStatus) -> Self {
664        match value {
665            TransactionStatus::Applied => Self::Applied,
666            TransactionStatus::Failed(faileds) => {
667                Self::Failed(MinaBaseTransactionStatusFailureCollectionStableV1(
668                    faileds
669                        .iter()
670                        .map(|s| s.iter().map(Into::into).collect())
671                        .collect(),
672                ))
673            }
674        }
675    }
676}
677
678impl TryFrom<&MinaBaseAccountUpdateFeePayerStableV1> for FeePayer {
679    type Error = InvalidBigInt;
680
681    fn try_from(value: &MinaBaseAccountUpdateFeePayerStableV1) -> Result<Self, Self::Error> {
682        Ok(Self {
683            body: FeePayerBody {
684                public_key: value.body.public_key.clone().into_inner().try_into()?,
685                fee: Fee::from_u64(value.body.fee.as_u64()),
686                valid_until: value
687                    .body
688                    .valid_until
689                    .as_ref()
690                    .map(|until| Slot::from_u32(until.as_u32())),
691                nonce: Nonce::from_u32(value.body.nonce.as_u32()),
692            },
693            authorization: Signature {
694                rx: value.authorization.0.to_field()?,
695                s: value.authorization.1.to_field()?,
696            },
697        })
698    }
699}
700
701impl From<&FeePayer> for MinaBaseAccountUpdateFeePayerStableV1 {
702    fn from(value: &FeePayer) -> Self {
703        Self {
704            body: MinaBaseAccountUpdateBodyFeePayerStableV1 {
705                public_key: (&value.body.public_key).into(),
706                fee: (&value.body.fee).into(),
707                valid_until: value.body.valid_until.as_ref().map(|until| until.into()),
708                nonce: (&value.body.nonce).into(),
709            },
710            authorization: MinaBaseSignatureStableV1::from(&value.authorization).into(),
711        }
712    }
713}
714
715impl From<&MinaBaseAccountUpdateUpdateTimingInfoStableV1> for zkapp_command::Timing {
716    fn from(t: &MinaBaseAccountUpdateUpdateTimingInfoStableV1) -> Self {
717        Self {
718            initial_minimum_balance: Balance::from_u64(t.initial_minimum_balance.as_u64()),
719            cliff_time: Slot::from_u32(t.cliff_time.as_u32()),
720            cliff_amount: Amount::from_u64(t.cliff_amount.as_u64()),
721            vesting_period: SlotSpan::from_u32(t.vesting_period.as_u32()),
722            vesting_increment: Amount::from_u64(t.vesting_increment.as_u64()),
723        }
724    }
725}
726
727impl From<&zkapp_command::Timing> for MinaBaseAccountUpdateUpdateTimingInfoStableV1 {
728    fn from(t: &zkapp_command::Timing) -> Self {
729        Self {
730            initial_minimum_balance: CurrencyBalanceStableV1(t.initial_minimum_balance.into()),
731            cliff_time: (&t.cliff_time).into(),
732            cliff_amount: t.cliff_amount.into(),
733            vesting_period: (&t.vesting_period).into(),
734            vesting_increment: t.vesting_increment.into(),
735        }
736    }
737}
738
739impl From<&MinaBaseZkappPreconditionProtocolStateStableV1Length>
740    for zkapp_command::Numeric<Length>
741{
742    fn from(value: &MinaBaseZkappPreconditionProtocolStateStableV1Length) -> Self {
743        use zkapp_command::{ClosedInterval, Numeric};
744        use MinaBaseZkappPreconditionProtocolStateStableV1Length as MLength;
745
746        match value {
747            MLength::Check(length) => Numeric::Check(ClosedInterval {
748                lower: Length::from_u32(length.lower.0.as_u32()),
749                upper: Length::from_u32(length.upper.0.as_u32()),
750            }),
751            MLength::Ignore => Numeric::Ignore,
752        }
753    }
754}
755
756impl From<&zkapp_command::Numeric<Length>>
757    for MinaBaseZkappPreconditionProtocolStateStableV1Length
758{
759    fn from(value: &zkapp_command::Numeric<Length>) -> Self {
760        use zkapp_command::Numeric;
761        use MinaBaseZkappPreconditionProtocolStateStableV1Length as MLength;
762
763        match value {
764            Numeric::Check(length) => {
765                MLength::Check(MinaBaseZkappPreconditionProtocolStateStableV1LengthA {
766                    lower: (&length.lower).into(),
767                    upper: (&length.upper).into(),
768                })
769            }
770            Numeric::Ignore => MLength::Ignore,
771        }
772    }
773}
774
775impl<F: FieldWitness> TryFrom<&ConsensusProofOfStakeDataEpochDataStakingValueVersionedValueStableV1>
776    for protocol_state::EpochData<F>
777{
778    type Error = InvalidBigInt;
779
780    fn try_from(
781        value: &ConsensusProofOfStakeDataEpochDataStakingValueVersionedValueStableV1,
782    ) -> Result<Self, Self::Error> {
783        Ok(Self {
784            ledger: protocol_state::EpochLedger {
785                hash: value.ledger.hash.0.to_field()?,
786                total_currency: value.ledger.total_currency.clone().into(),
787            },
788            seed: value.seed.0.to_field()?,
789            start_checkpoint: value.start_checkpoint.0.to_field()?,
790            lock_checkpoint: value.lock_checkpoint.0.to_field()?,
791            epoch_length: (&value.epoch_length).into(),
792        })
793    }
794}
795
796impl<F: FieldWitness> TryFrom<&ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1>
797    for protocol_state::EpochData<F>
798{
799    type Error = InvalidBigInt;
800
801    fn try_from(
802        value: &ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1,
803    ) -> Result<Self, Self::Error> {
804        Ok(Self {
805            ledger: protocol_state::EpochLedger {
806                hash: value.ledger.hash.0.to_field()?,
807                total_currency: value.ledger.total_currency.clone().into(),
808            },
809            seed: value.seed.0.to_field()?,
810            start_checkpoint: value.start_checkpoint.0.to_field()?,
811            lock_checkpoint: value.lock_checkpoint.0.to_field()?,
812            epoch_length: (&value.epoch_length).into(),
813        })
814    }
815}
816
817impl TryFrom<&MinaBaseZkappPreconditionProtocolStateEpochDataStableV1>
818    for zkapp_command::EpochData
819{
820    type Error = InvalidBigInt;
821
822    fn try_from(
823        value: &MinaBaseZkappPreconditionProtocolStateEpochDataStableV1,
824    ) -> Result<Self, Self::Error> {
825        use mina_p2p_messages::v2::{
826            MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochSeed as Seed,
827            MinaBaseZkappPreconditionProtocolStateEpochDataStableV1StartCheckpoint as Start,
828            MinaBaseZkappPreconditionProtocolStateStableV1Amount as MAmount,
829            MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash as Hash,
830        };
831        use zkapp_command::{ClosedInterval, OrIgnore};
832
833        Ok(Self {
834            ledger: zkapp_command::EpochLedger {
835                hash: match &value.ledger.hash {
836                    Hash::Check(hash) => OrIgnore::Check(hash.to_field()?),
837                    Hash::Ignore => OrIgnore::Ignore,
838                },
839                total_currency: match &value.ledger.total_currency {
840                    MAmount::Check(amount) => OrIgnore::Check(ClosedInterval {
841                        lower: Amount::from_u64(amount.lower.0 .0.as_u64()),
842                        upper: Amount::from_u64(amount.upper.0 .0.as_u64()),
843                    }),
844                    MAmount::Ignore => OrIgnore::Ignore,
845                },
846            },
847            seed: match &value.seed {
848                Seed::Check(seed) => OrIgnore::Check(seed.to_field()?),
849                Seed::Ignore => OrIgnore::Ignore,
850            },
851            start_checkpoint: match &value.start_checkpoint {
852                Start::Check(start) => OrIgnore::Check(start.to_field()?),
853                Start::Ignore => OrIgnore::Ignore,
854            },
855            lock_checkpoint: match &value.lock_checkpoint {
856                Start::Check(start) => OrIgnore::Check(start.to_field()?),
857                Start::Ignore => OrIgnore::Ignore,
858            },
859            epoch_length: (&value.epoch_length).into(),
860        })
861    }
862}
863
864fn fp_to_epochseed(value: &Fp) -> EpochSeed {
865    let hash: MinaBaseEpochSeedStableV1 = MinaBaseEpochSeedStableV1(value.into());
866    hash.into()
867}
868
869fn fp_to_statehash(value: &Fp) -> StateHash {
870    let hash: DataHashLibStateHashStableV1 = DataHashLibStateHashStableV1(value.into());
871    hash.into()
872}
873
874impl From<&zkapp_command::EpochData> for MinaBaseZkappPreconditionProtocolStateEpochDataStableV1 {
875    fn from(value: &zkapp_command::EpochData) -> Self {
876        use mina_p2p_messages::v2::{
877            MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochSeed as Seed,
878            MinaBaseZkappPreconditionProtocolStateEpochDataStableV1StartCheckpoint as Start,
879            MinaBaseZkappPreconditionProtocolStateStableV1Amount as MAmount,
880            MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash as Hash,
881        };
882        use zkapp_command::OrIgnore;
883
884        Self {
885            ledger: MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochLedger {
886                hash: match &value.ledger.hash {
887                    OrIgnore::Check(hash) => Hash::Check({
888                        let hash = MinaBaseLedgerHash0StableV1(hash.into());
889                        hash.into()
890                    }),
891                    OrIgnore::Ignore => Hash::Ignore,
892                },
893                total_currency: match &value.ledger.total_currency {
894                    OrIgnore::Check(amount) => {
895                        MAmount::Check(MinaBaseZkappPreconditionProtocolStateStableV1AmountA {
896                            lower: amount.lower.into(),
897                            upper: amount.upper.into(),
898                        })
899                    }
900                    OrIgnore::Ignore => MAmount::Ignore,
901                },
902            },
903            seed: match &value.seed {
904                OrIgnore::Check(seed) => Seed::Check(fp_to_epochseed(seed)),
905                OrIgnore::Ignore => Seed::Ignore,
906            },
907            start_checkpoint: match &value.start_checkpoint {
908                OrIgnore::Check(start) => Start::Check(fp_to_statehash(start)),
909                OrIgnore::Ignore => Start::Ignore,
910            },
911            lock_checkpoint: match &value.lock_checkpoint {
912                OrIgnore::Check(start) => Start::Check(fp_to_statehash(start)),
913                OrIgnore::Ignore => Start::Ignore,
914            },
915            epoch_length: (&value.epoch_length).into(),
916        }
917    }
918}
919
920impl TryFrom<&MinaBaseAccountUpdatePreconditionsStableV1> for zkapp_command::Preconditions {
921    type Error = InvalidBigInt;
922
923    fn try_from(value: &MinaBaseAccountUpdatePreconditionsStableV1) -> Result<Self, Self::Error> {
924        use mina_p2p_messages::v2::{
925            MinaBaseZkappPreconditionProtocolStateStableV1Amount as MAmount,
926            MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot as MSlot,
927            MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash as Ledger,
928        };
929        use zkapp_command::{AccountPreconditions, ClosedInterval, Numeric, OrIgnore};
930
931        Ok(Self {
932            network: zkapp_command::ZkAppPreconditions {
933                snarked_ledger_hash: match &value.network.snarked_ledger_hash {
934                    Ledger::Check(hash) => OrIgnore::Check(hash.to_field()?),
935                    Ledger::Ignore => OrIgnore::Ignore,
936                },
937                blockchain_length: (&value.network.blockchain_length).into(),
938                min_window_density: (&value.network.min_window_density).into(),
939                total_currency: match &value.network.total_currency {
940                    MAmount::Check(amount) => OrIgnore::Check(ClosedInterval {
941                        lower: Amount::from_u64(amount.lower.0 .0.as_u64()),
942                        upper: Amount::from_u64(amount.upper.0 .0.as_u64()),
943                    }),
944                    MAmount::Ignore => OrIgnore::Ignore,
945                },
946                global_slot_since_genesis: match &value.network.global_slot_since_genesis {
947                    MSlot::Check(length) => Numeric::Check(ClosedInterval {
948                        lower: (&length.lower).into(),
949                        upper: (&length.upper).into(),
950                    }),
951                    MSlot::Ignore => OrIgnore::Ignore,
952                },
953                staking_epoch_data: (&value.network.staking_epoch_data).try_into()?,
954                next_epoch_data: (&value.network.next_epoch_data).try_into()?,
955            },
956            account: {
957                let account = &value.account.0;
958                use mina_p2p_messages::v2::{
959                    MinaBaseZkappPreconditionAccountStableV2Balance as MBalance,
960                    MinaBaseZkappPreconditionAccountStableV2Delegate as Delegate,
961                    MinaBaseZkappPreconditionAccountStableV2ProvedState as Proved,
962                    MinaBaseZkappPreconditionAccountStableV2ReceiptChainHash as Receipt,
963                    MinaBaseZkappPreconditionAccountStableV2StateA as State,
964                    MinaBaseZkappPreconditionProtocolStateStableV1Length as MNonce,
965                };
966
967                AccountPreconditions(zkapp_command::Account {
968                    balance: match &account.balance {
969                        MBalance::Check(balance) => OrIgnore::Check(ClosedInterval {
970                            lower: Balance::from_u64(balance.lower.0.as_u64()),
971                            upper: Balance::from_u64(balance.upper.0.as_u64()),
972                        }),
973                        MBalance::Ignore => OrIgnore::Ignore,
974                    },
975                    nonce: match &account.nonce {
976                        MNonce::Check(balance) => OrIgnore::Check(ClosedInterval {
977                            lower: Nonce::from_u32(balance.lower.0.as_u32()),
978                            upper: Nonce::from_u32(balance.upper.0.as_u32()),
979                        }),
980                        MNonce::Ignore => OrIgnore::Ignore,
981                    },
982                    receipt_chain_hash: match &account.receipt_chain_hash {
983                        Receipt::Check(hash) => OrIgnore::Check(hash.to_field()?),
984                        Receipt::Ignore => OrIgnore::Ignore,
985                    },
986                    delegate: match &account.delegate {
987                        Delegate::Check(delegate) => {
988                            OrIgnore::Check(delegate.clone().into_inner().try_into()?)
989                        }
990                        Delegate::Ignore => OrIgnore::Ignore,
991                    },
992                    state: crate::try_array_into_with(&account.state, |s| match s {
993                        State::Check(s) => Ok(OrIgnore::Check(s.to_field()?)),
994                        State::Ignore => Ok(OrIgnore::Ignore),
995                    })?,
996                    action_state: match &account.action_state {
997                        State::Check(s) => OrIgnore::Check(s.to_field()?),
998                        State::Ignore => OrIgnore::Ignore,
999                    },
1000                    proved_state: match account.proved_state {
1001                        Proved::Check(state) => OrIgnore::Check(state),
1002                        Proved::Ignore => OrIgnore::Ignore,
1003                    },
1004                    is_new: match account.is_new {
1005                        Proved::Check(state) => OrIgnore::Check(state),
1006                        Proved::Ignore => OrIgnore::Ignore,
1007                    },
1008                })
1009            },
1010            valid_while: match &value.valid_while {
1011                MSlot::Check(valid_while) => OrIgnore::Check(ClosedInterval {
1012                    lower: (&valid_while.lower).into(),
1013                    upper: (&valid_while.upper).into(),
1014                }),
1015                MSlot::Ignore => OrIgnore::Ignore,
1016            },
1017        })
1018    }
1019}
1020
1021impl From<&BlockTime> for BlockTimeTimeStableV1 {
1022    fn from(value: &BlockTime) -> Self {
1023        Self(UnsignedExtendedUInt64Int64ForVersionTagsStableV1(
1024            value.as_u64().into(),
1025        ))
1026    }
1027}
1028
1029impl From<&zkapp_command::Preconditions> for MinaBaseAccountUpdatePreconditionsStableV1 {
1030    fn from(value: &zkapp_command::Preconditions) -> Self {
1031        use mina_p2p_messages::v2::{
1032            MinaBaseAccountUpdateAccountPreconditionStableV1 as MAccount,
1033            MinaBaseZkappPreconditionProtocolStateStableV1Amount as MAmount,
1034            MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot as MSlot,
1035            MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash as Ledger,
1036        };
1037        use zkapp_command::{Numeric, OrIgnore};
1038
1039        Self {
1040            network: MinaBaseZkappPreconditionProtocolStateStableV1 {
1041                snarked_ledger_hash: match &value.network.snarked_ledger_hash {
1042                    OrIgnore::Check(hash) => Ledger::Check({
1043                        let hash = MinaBaseLedgerHash0StableV1(hash.into());
1044                        hash.into()
1045                    }),
1046                    OrIgnore::Ignore => Ledger::Ignore,
1047                },
1048                blockchain_length: (&value.network.blockchain_length).into(),
1049                min_window_density: (&value.network.min_window_density).into(),
1050                total_currency: match &value.network.total_currency {
1051                    OrIgnore::Check(amount) => {
1052                        MAmount::Check(MinaBaseZkappPreconditionProtocolStateStableV1AmountA {
1053                            lower: amount.lower.into(),
1054                            upper: amount.upper.into(),
1055                        })
1056                    }
1057                    OrIgnore::Ignore => MAmount::Ignore,
1058                },
1059                global_slot_since_genesis: match &value.network.global_slot_since_genesis {
1060                    Numeric::Check(length) => {
1061                        MSlot::Check(MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlotA {
1062                            lower: (&length.lower).into(),
1063                            upper: (&length.upper).into(),
1064                        })
1065                    }
1066                    Numeric::Ignore => MSlot::Ignore,
1067                },
1068                staking_epoch_data: (&value.network.staking_epoch_data).into(),
1069                next_epoch_data: (&value.network.next_epoch_data).into(),
1070            },
1071            account: {
1072                use mina_p2p_messages::v2::{
1073                    MinaBaseZkappPreconditionAccountStableV2Balance as MBalance,
1074                    MinaBaseZkappPreconditionAccountStableV2Delegate as Delegate,
1075                    MinaBaseZkappPreconditionAccountStableV2ProvedState as Proved,
1076                    MinaBaseZkappPreconditionAccountStableV2ReceiptChainHash as Receipt,
1077                    MinaBaseZkappPreconditionAccountStableV2StateA as State,
1078                    MinaBaseZkappPreconditionProtocolStateStableV1Length as MNonce,
1079                };
1080
1081                let account = &value.account.0;
1082                MAccount(MinaBaseZkappPreconditionAccountStableV2 {
1083                    balance: match &account.balance {
1084                        OrIgnore::Check(balance) => {
1085                            MBalance::Check(MinaBaseZkappPreconditionAccountStableV2BalanceA {
1086                                lower: (&balance.lower).into(),
1087                                upper: (&balance.upper).into(),
1088                            })
1089                        }
1090                        OrIgnore::Ignore => MBalance::Ignore,
1091                    },
1092                    nonce: match &account.nonce {
1093                        OrIgnore::Check(nonce) => {
1094                            MNonce::Check(MinaBaseZkappPreconditionProtocolStateStableV1LengthA {
1095                                lower: (&nonce.lower).into(),
1096                                upper: (&nonce.upper).into(),
1097                            })
1098                        }
1099                        OrIgnore::Ignore => MNonce::Ignore,
1100                    },
1101                    receipt_chain_hash: match &account.receipt_chain_hash {
1102                        OrIgnore::Check(hash) => {
1103                            Receipt::Check(MinaBaseReceiptChainHashStableV1(hash.into()))
1104                        }
1105                        OrIgnore::Ignore => Receipt::Ignore,
1106                    },
1107                    delegate: match &account.delegate {
1108                        OrIgnore::Check(delegate) => Delegate::Check(delegate.into()),
1109                        OrIgnore::Ignore => Delegate::Ignore,
1110                    },
1111                    state: PaddedSeq(array_into_with(&account.state, |s| match s {
1112                        OrIgnore::Check(s) => State::Check(s.into()),
1113                        OrIgnore::Ignore => State::Ignore,
1114                    })),
1115                    action_state: match &account.action_state {
1116                        OrIgnore::Check(s) => State::Check(s.into()),
1117                        OrIgnore::Ignore => State::Ignore,
1118                    },
1119                    proved_state: match account.proved_state {
1120                        OrIgnore::Check(state) => Proved::Check(state),
1121                        OrIgnore::Ignore => Proved::Ignore,
1122                    },
1123                    is_new: match account.is_new {
1124                        OrIgnore::Check(state) => Proved::Check(state),
1125                        OrIgnore::Ignore => Proved::Ignore,
1126                    },
1127                })
1128            },
1129            valid_while: match &value.valid_while {
1130                OrIgnore::Check(valid_while) => {
1131                    MSlot::Check(MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlotA {
1132                        lower: (&valid_while.lower).into(),
1133                        upper: (&valid_while.upper).into(),
1134                    })
1135                }
1136                OrIgnore::Ignore => MSlot::Ignore,
1137            },
1138        }
1139    }
1140}
1141
1142/// <https://github.com/MinaProtocol/mina/blob/3fe924c80a4d01f418b69f27398f5f93eb652514/src/lib/mina_base/verification_key_wire.ml#L37>
1143fn of_vk(data: VerificationKey) -> VerificationKeyWire {
1144    VerificationKeyWire::new(data)
1145}
1146
1147impl TryFrom<&MinaBaseAccountUpdateTStableV1> for AccountUpdate {
1148    type Error = InvalidBigInt;
1149
1150    fn try_from(value: &MinaBaseAccountUpdateTStableV1) -> Result<Self, Self::Error> {
1151        use mina_p2p_messages::v2::{
1152            MinaBaseAccountUpdateUpdateStableV1Delegate as Delegate,
1153            MinaBaseAccountUpdateUpdateStableV1Permissions as Perm,
1154            MinaBaseAccountUpdateUpdateStableV1Timing as Timing,
1155            MinaBaseAccountUpdateUpdateStableV1TokenSymbol as TokenSymbol,
1156            MinaBaseAccountUpdateUpdateStableV1VerificationKey as VK,
1157            MinaBaseAccountUpdateUpdateStableV1VotingFor as Voting,
1158            MinaBaseAccountUpdateUpdateStableV1ZkappUri as ZkAppUri,
1159        };
1160        use MinaBaseAccountUpdateUpdateStableV1AppStateA as AppState;
1161
1162        Ok(Self {
1163            body: zkapp_command::Body {
1164                public_key: value.body.public_key.clone().into_inner().try_into()?,
1165                token_id: value.body.token_id.clone().into_inner().try_into()?,
1166                update: zkapp_command::Update {
1167                    app_state: crate::try_array_into_with(&value.body.update.app_state, |s| match s {
1168                            AppState::Set(bigint) => Ok(SetOrKeep::Set(bigint.to_field()?)),
1169                            AppState::Keep => Ok(SetOrKeep::Keep),
1170                    })?,
1171                    delegate: match &value.body.update.delegate {
1172                        Delegate::Set(v) => SetOrKeep::Set(v.try_into()?),
1173                        Delegate::Keep => SetOrKeep::Keep,
1174                    },
1175                    verification_key: match &value.body.update.verification_key {
1176                        VK::Set(vk) => SetOrKeep::Set(of_vk((&**vk).try_into()?)),
1177                        VK::Keep => SetOrKeep::Keep,
1178                    },
1179                    permissions: match &value.body.update.permissions {
1180                        Perm::Set(perms) => SetOrKeep::Set((&**perms).into()),
1181                        Perm::Keep => SetOrKeep::Keep,
1182                    },
1183                    zkapp_uri: match &value.body.update.zkapp_uri {
1184                        ZkAppUri::Set(s) => SetOrKeep::Set(s.into()),
1185                        ZkAppUri::Keep => SetOrKeep::Keep,
1186                    },
1187                    token_symbol: match &value.body.update.token_symbol {
1188                        TokenSymbol::Set(s) => SetOrKeep::Set(s.into()),
1189                        TokenSymbol::Keep => SetOrKeep::Keep,
1190                    },
1191                    timing: match &value.body.update.timing {
1192                        Timing::Set(timing) => SetOrKeep::Set((&**timing).into()),
1193                        Timing::Keep => SetOrKeep::Keep,
1194                    },
1195                    voting_for: match &value.body.update.voting_for {
1196                        Voting::Set(bigint) => SetOrKeep::Set(VotingFor(bigint.to_field()?)),
1197                        Voting::Keep => SetOrKeep::Keep,
1198                    },
1199                },
1200                balance_change: Signed::<Amount> {
1201                    magnitude: Amount(value.body.balance_change.magnitude.as_u64()),
1202                    sgn: value.body.balance_change.sgn.clone().into(),
1203                },
1204                increment_nonce: value.body.increment_nonce,
1205                events: zkapp_command::Events(
1206                    value
1207                        .body
1208                        .events
1209                        .0
1210                        .iter()
1211                        .map(|e| Ok(zkapp_command::Event(e.iter().map(|e| e.to_field()).collect::<Result<Vec<Fp>, _>>()?)))
1212                        .collect::<Result<_, _>>()?,
1213                ),
1214                actions: zkapp_command::Actions(
1215                    value
1216                        .body
1217                        .actions
1218                        .0
1219                        .iter()
1220                        .map(|e| Ok(zkapp_command::Event(e.iter().map(|e| e.to_field()).collect::<Result<Vec<Fp>, _>>()?)))
1221                        .collect::<Result<_, _>>()?,
1222                ),
1223                call_data: value.body.call_data.to_field()?,
1224                preconditions: (&value.body.preconditions).try_into()?,
1225                use_full_commitment: value.body.use_full_commitment,
1226                authorization_kind: match &value.body.authorization_kind {
1227                    mina_p2p_messages::v2::MinaBaseAccountUpdateAuthorizationKindStableV1::NoneGiven => AuthorizationKind::NoneGiven,
1228                    mina_p2p_messages::v2::MinaBaseAccountUpdateAuthorizationKindStableV1::Signature => AuthorizationKind::Signature,
1229                    mina_p2p_messages::v2::MinaBaseAccountUpdateAuthorizationKindStableV1::Proof(hash) => AuthorizationKind::Proof(hash.to_field()?),
1230                },
1231                implicit_account_creation_fee: value.body.implicit_account_creation_fee,
1232                may_use_token: match value.body.may_use_token {
1233                    MinaBaseAccountUpdateMayUseTokenStableV1::No => MayUseToken::No,
1234                    MinaBaseAccountUpdateMayUseTokenStableV1::ParentsOwnToken => MayUseToken::ParentsOwnToken,
1235                    MinaBaseAccountUpdateMayUseTokenStableV1::InheritFromParent => MayUseToken::InheritFromParent,
1236                },
1237            },
1238            authorization: match &value.authorization {
1239                mina_p2p_messages::v2::MinaBaseControlStableV2::Proof(proof) => zkapp_command::Control::Proof((**proof).clone().into()),
1240                mina_p2p_messages::v2::MinaBaseControlStableV2::Signature(signature) => zkapp_command::Control::Signature(Signature{
1241                    rx: signature.0.to_field()?,
1242                    s: signature.1.to_field()?
1243            }),
1244                mina_p2p_messages::v2::MinaBaseControlStableV2::NoneGiven => zkapp_command::Control::NoneGiven,
1245            },
1246        })
1247    }
1248}
1249
1250/// Notes: childs
1251impl TryFrom<&List<MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAACallsA>>
1252    for CallForest<AccountUpdate>
1253{
1254    type Error = InvalidBigInt;
1255
1256    fn try_from(
1257        value: &List<MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAACallsA>,
1258    ) -> Result<Self, Self::Error> {
1259        Ok(Self(
1260            value
1261                .iter()
1262                .map(|update| {
1263                    Ok(WithStackHash {
1264                        elt: zkapp_command::Tree {
1265                            account_update: (&update.elt.account_update).try_into()?,
1266                            account_update_digest: MutableFp::empty(), // replaced later
1267                            calls: (&update.elt.calls).try_into()?,
1268                        },
1269                        stack_hash: MutableFp::empty(), // replaced later
1270                    })
1271                })
1272                .collect::<Result<_, _>>()?,
1273        ))
1274    }
1275}
1276/// Notes: root
1277impl TryFrom<&List<MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesA>>
1278    for CallForest<AccountUpdate>
1279{
1280    type Error = InvalidBigInt;
1281
1282    fn try_from(
1283        value: &List<MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesA>,
1284    ) -> Result<Self, Self::Error> {
1285        let values = value
1286            .iter()
1287            .map(|update| {
1288                Ok(WithStackHash {
1289                    elt: zkapp_command::Tree {
1290                        account_update: (&update.elt.account_update).try_into()?,
1291                        account_update_digest: MutableFp::empty(), // replaced later in `of_wire`
1292                        calls: (&update.elt.calls).try_into()?,
1293                    },
1294                    stack_hash: MutableFp::empty(), // replaced later in `of_wire`
1295                })
1296            })
1297            .collect::<Result<Vec<_>, _>>()?;
1298
1299        // <https://github.com/MinaProtocol/mina/blob/3fe924c80a4d01f418b69f27398f5f93eb652514/src/lib/mina_base/zkapp_command.ml#L1113-L1115>
1300
1301        let call_forest = CallForest(values);
1302        // OCaml hashes the zkapp on deserialization:
1303        // <https://github.com/MinaProtocol/mina/blob/fb1c3c0a408c344810140bdbcedacc532a11be91/src/lib/mina_base/zkapp_command.ml#L805>
1304        // But we delay hashing until we need the hashes
1305        // call_forest.of_wire(&[]);
1306        // call_forest.of_wire(value);
1307
1308        Ok(call_forest)
1309    }
1310}
1311
1312impl TryFrom<&v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesDataA>
1313    for VerificationKeyWire
1314{
1315    type Error = InvalidBigInt;
1316
1317    fn try_from(
1318        value: &v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesDataA,
1319    ) -> Result<Self, Self::Error> {
1320        let v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesDataA { data, hash } = value;
1321        Ok(Self::with_hash(data.try_into()?, hash.try_into()?))
1322    }
1323}
1324
1325impl From<&VerificationKeyWire> for v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesDataA {
1326    fn from(value: &VerificationKeyWire) -> Self {
1327        let vk = value.vk();
1328        let hash = value.hash();
1329        Self {
1330            data: vk.into(),
1331            hash: hash.into(),
1332        }
1333    }
1334}
1335
1336/// Notes: childs for verifiable
1337impl TryFrom<&List<v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesAACallsA>>
1338    for CallForest<(AccountUpdate, Option<VerificationKeyWire>)>
1339{
1340    type Error = InvalidBigInt;
1341
1342    fn try_from(
1343        value: &List<v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesAACallsA>,
1344    ) -> Result<Self, Self::Error> {
1345        Ok(Self(
1346            value
1347                .iter()
1348                .map(|update| {
1349                    let v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesAACallsA {
1350                        elt,
1351                        stack_hash,
1352                    } = update;
1353                    let v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesAA {
1354                        account_update: (account, vk_opt),
1355                        account_update_digest,
1356                        calls,
1357                    } = &**elt;
1358                    let vk_opt = match vk_opt.as_ref() {
1359                        Some(vk) => Some(vk.try_into()?),
1360                        None => None,
1361                    };
1362                    Ok(WithStackHash {
1363                        elt: zkapp_command::Tree {
1364                            account_update: (account.try_into()?, vk_opt),
1365                            account_update_digest: MutableFp::new(
1366                                account_update_digest.to_field()?,
1367                            ),
1368                            calls: calls.try_into()?,
1369                        },
1370                        stack_hash: MutableFp::new(stack_hash.to_field()?),
1371                    })
1372                })
1373                .collect::<Result<Vec<_>, _>>()?,
1374        ))
1375    }
1376}
1377/// Notes: root for verifiable
1378impl TryFrom<&List<v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesA>>
1379    for CallForest<(AccountUpdate, Option<VerificationKeyWire>)>
1380{
1381    type Error = InvalidBigInt;
1382
1383    fn try_from(
1384        value: &List<v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesA>,
1385    ) -> Result<Self, Self::Error> {
1386        let values = value
1387            .iter()
1388            .map(|update| {
1389                let v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesA { elt, stack_hash } =
1390                    update;
1391                let v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesAA {
1392                    account_update: (account, vk_opt),
1393                    account_update_digest,
1394                    calls,
1395                } = elt;
1396                let vk_opt = match vk_opt.as_ref() {
1397                    Some(vk) => Some(vk.try_into()?),
1398                    None => None,
1399                };
1400                Ok(WithStackHash {
1401                    elt: zkapp_command::Tree {
1402                        account_update: (account.try_into()?, vk_opt),
1403                        account_update_digest: MutableFp::new(account_update_digest.to_field()?),
1404                        calls: calls.try_into()?,
1405                    },
1406                    stack_hash: MutableFp::new(stack_hash.to_field()?),
1407                })
1408            })
1409            .collect::<Result<Vec<_>, _>>()?;
1410
1411        // There is no need to call `of_wire`, because hashes are in our serialized types (verifiables types only)
1412        // call_forest.of_wire(&[]);
1413
1414        Ok(CallForest(values))
1415    }
1416}
1417
1418/// Childs for verifiable
1419impl From<&CallForest<(AccountUpdate, Option<VerificationKeyWire>)>>
1420    for List<v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesAACallsA>
1421{
1422    fn from(value: &CallForest<(AccountUpdate, Option<VerificationKeyWire>)>) -> Self {
1423        value
1424            .0
1425            .iter()
1426            .map(|update| {
1427                let (acc, opt) = &update.elt.account_update;
1428                v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesAACallsA {
1429                    elt: Box::new(v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesAA {
1430                        account_update: (acc.into(), opt.as_ref().map(Into::into)),
1431                        account_update_digest:
1432                            v2::MinaBaseZkappCommandCallForestMakeDigestStrAccountUpdateStableV1(
1433                                update.elt.account_update_digest.get().unwrap().into(), // Not fail, we must hash before serializing
1434                            ),
1435                        calls: (&update.elt.calls).into(),
1436                    }),
1437                    stack_hash: v2::MinaBaseZkappCommandCallForestMakeDigestStrForestStableV1(
1438                        update.stack_hash.get().unwrap().into(), // Not fail, we must hash before serializing
1439                    ),
1440                }
1441            })
1442            .collect()
1443    }
1444}
1445/// Root
1446impl From<&CallForest<(AccountUpdate, Option<VerificationKeyWire>)>>
1447    for List<v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesA>
1448{
1449    fn from(value: &CallForest<(AccountUpdate, Option<VerificationKeyWire>)>) -> Self {
1450        value
1451            .0
1452            .iter()
1453            .map(|update| {
1454                let (acc, opt) = &update.elt.account_update;
1455                v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesA {
1456                    elt: v2::MinaBaseZkappCommandVerifiableStableV1AccountUpdatesAA {
1457                        account_update: (acc.into(), opt.as_ref().map(Into::into)),
1458                        account_update_digest:
1459                            v2::MinaBaseZkappCommandCallForestMakeDigestStrAccountUpdateStableV1(
1460                                update.elt.account_update_digest.get().unwrap().into(), // Not fail, we must hash before serializing
1461                            ),
1462                        calls: (&update.elt.calls).into(),
1463                    },
1464                    stack_hash: v2::MinaBaseZkappCommandCallForestMakeDigestStrForestStableV1(
1465                        update.stack_hash.get().unwrap().into(), // Not fail, we must hash before serializing
1466                    ),
1467                }
1468            })
1469            .collect()
1470
1471        // There is no need to call `to_wire`, because hashes are in our serialized types (verifiables types only)
1472        // value.to_wire(&mut wired);
1473        // wired.into_iter().collect()
1474    }
1475}
1476
1477/// We need this trait because `mina-p2p-messages` contains different types for the same data
1478pub trait AsAccountUpdateWithHash {
1479    fn elt(&self) -> &MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA;
1480    fn elt_mut(&mut self) -> &mut MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA;
1481}
1482
1483impl AsAccountUpdateWithHash for MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesA {
1484    fn elt(&self) -> &MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA {
1485        &self.elt
1486    }
1487    fn elt_mut(&mut self) -> &mut MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA {
1488        &mut self.elt
1489    }
1490}
1491
1492impl AsAccountUpdateWithHash for MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAACallsA {
1493    fn elt(&self) -> &MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA {
1494        &self.elt
1495    }
1496    fn elt_mut(&mut self) -> &mut MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA {
1497        &mut self.elt
1498    }
1499}
1500
1501impl From<&AccountUpdate> for MinaBaseAccountUpdateTStableV1 {
1502    fn from(value: &AccountUpdate) -> Self {
1503        use mina_p2p_messages::v2::{
1504            MinaBaseAccountUpdateUpdateStableV1Delegate as Delegate,
1505            MinaBaseAccountUpdateUpdateStableV1Permissions as Perm,
1506            MinaBaseAccountUpdateUpdateStableV1Timing as Timing,
1507            MinaBaseAccountUpdateUpdateStableV1TokenSymbol as TokenSymbol,
1508            MinaBaseAccountUpdateUpdateStableV1VerificationKey as VK,
1509            MinaBaseAccountUpdateUpdateStableV1VotingFor as Voting,
1510            MinaBaseAccountUpdateUpdateStableV1ZkappUri as ZkAppUri,
1511        };
1512        use MinaBaseAccountUpdateUpdateStableV1AppStateA as AppState;
1513
1514        Self {
1515            body: MinaBaseAccountUpdateBodyStableV1 {
1516                public_key: (&value.body.public_key).into(),
1517                token_id: (&value.body.token_id).into(),
1518                update: MinaBaseAccountUpdateUpdateStableV1 {
1519                    app_state: PaddedSeq(value.body.update.app_state.each_ref().map(|s| match s {
1520                        SetOrKeep::Set(bigint) => AppState::Set(bigint.into()),
1521                        SetOrKeep::Keep => AppState::Keep,
1522                    })),
1523                    delegate: match &value.body.update.delegate {
1524                        SetOrKeep::Set(v) => Delegate::Set(v.into()),
1525                        SetOrKeep::Keep => Delegate::Keep,
1526                    },
1527                    verification_key: match &value.body.update.verification_key {
1528                        SetOrKeep::Set(vk) => VK::Set(Box::new((vk.vk()).into())),
1529                        SetOrKeep::Keep => VK::Keep,
1530                    },
1531                    permissions: match &value.body.update.permissions {
1532                        SetOrKeep::Set(perms) => Perm::Set(Box::new(perms.into())),
1533                        SetOrKeep::Keep => Perm::Keep,
1534                    },
1535                    zkapp_uri: match &value.body.update.zkapp_uri {
1536                        SetOrKeep::Set(s) => ZkAppUri::Set(s.into()),
1537                        SetOrKeep::Keep => ZkAppUri::Keep,
1538                    },
1539                    token_symbol: match &value.body.update.token_symbol {
1540                        SetOrKeep::Set(s) => TokenSymbol::Set(s.into()),
1541                        SetOrKeep::Keep => TokenSymbol::Keep,
1542                    },
1543                    timing: match &value.body.update.timing {
1544                        SetOrKeep::Set(timing) => Timing::Set(Box::new(timing.into())),
1545                        SetOrKeep::Keep => Timing::Keep,
1546                    },
1547                    voting_for: match &value.body.update.voting_for {
1548                        SetOrKeep::Set(bigint) => Voting::Set(DataHashLibStateHashStableV1(bigint.0.into()).into()),
1549                        SetOrKeep::Keep => Voting::Keep,
1550                    },
1551                },
1552                balance_change: (&value.body.balance_change).into(),
1553                increment_nonce: value.body.increment_nonce,
1554                events: MinaBaseAccountUpdateBodyEventsStableV1(
1555                    value
1556                        .body
1557                        .events
1558                        .0
1559                        .iter()
1560                        .map(|e| e.0.iter().map(|e| e.into()).collect())
1561                        .collect(),
1562                ),
1563                actions: MinaBaseAccountUpdateBodyEventsStableV1(
1564                    value
1565                        .body
1566                        .actions
1567                        .0
1568                        .iter()
1569                        .map(|e| e.0.iter().map(|e| e.into()).collect())
1570                        .collect(),
1571                ),
1572                call_data: value.body.call_data.into(),
1573                preconditions: (&value.body.preconditions).into(),
1574                use_full_commitment: value.body.use_full_commitment,
1575                authorization_kind: match value.body.authorization_kind {
1576                    AuthorizationKind::NoneGiven => mina_p2p_messages::v2::MinaBaseAccountUpdateAuthorizationKindStableV1::NoneGiven ,
1577                    AuthorizationKind::Signature => mina_p2p_messages::v2::MinaBaseAccountUpdateAuthorizationKindStableV1::Signature ,
1578                    AuthorizationKind::Proof(hash) => mina_p2p_messages::v2::MinaBaseAccountUpdateAuthorizationKindStableV1::Proof(hash.into()) ,
1579                },
1580                implicit_account_creation_fee: value.body.implicit_account_creation_fee,
1581                may_use_token: match value.body.may_use_token {
1582                    zkapp_command::MayUseToken::No => MinaBaseAccountUpdateMayUseTokenStableV1::No,
1583                    zkapp_command::MayUseToken::ParentsOwnToken => MinaBaseAccountUpdateMayUseTokenStableV1::ParentsOwnToken,
1584                    zkapp_command::MayUseToken::InheritFromParent => MinaBaseAccountUpdateMayUseTokenStableV1::InheritFromParent,
1585                },
1586            },
1587            authorization: match &value.authorization {
1588                zkapp_command::Control::Proof(proof) => mina_p2p_messages::v2::MinaBaseControlStableV2::Proof(Box::new((**proof).clone())),
1589                zkapp_command::Control::Signature(sig) => mina_p2p_messages::v2::MinaBaseControlStableV2::Signature({
1590                    let sig: MinaBaseSignatureStableV1 = sig.into();
1591                    sig.into()
1592                }),
1593                zkapp_command::Control::NoneGiven => mina_p2p_messages::v2::MinaBaseControlStableV2::NoneGiven,
1594            },
1595        }
1596    }
1597}
1598
1599/// Childs
1600impl From<&CallForest<AccountUpdate>>
1601    for List<MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAACallsA>
1602{
1603    fn from(value: &CallForest<AccountUpdate>) -> Self {
1604        value
1605            .0
1606            .iter()
1607            .map(
1608                |update| MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAACallsA {
1609                    elt: Box::new(MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA {
1610                        account_update: (&update.elt.account_update).into(),
1611                        account_update_digest: (),
1612                        calls: (&update.elt.calls).into(),
1613                    }),
1614                    stack_hash: (),
1615                },
1616            )
1617            .collect()
1618    }
1619}
1620
1621/// Root
1622impl From<&CallForest<AccountUpdate>>
1623    for List<MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesA>
1624{
1625    fn from(value: &CallForest<AccountUpdate>) -> Self {
1626        let mut wired: Vec<_> = value
1627            .0
1628            .iter()
1629            .map(
1630                |update| MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesA {
1631                    elt: MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA {
1632                        account_update: (&update.elt.account_update).into(),
1633                        account_update_digest: (),
1634                        calls: (&update.elt.calls).into(),
1635                    },
1636                    stack_hash: (),
1637                },
1638            )
1639            .collect();
1640
1641        value.to_wire(&mut wired);
1642        wired.into_iter().collect()
1643    }
1644}
1645
1646impl TryFrom<&MinaBaseFeeTransferSingleStableV2> for SingleFeeTransfer {
1647    type Error = InvalidBigInt;
1648
1649    fn try_from(value: &MinaBaseFeeTransferSingleStableV2) -> Result<Self, Self::Error> {
1650        Ok(Self {
1651            receiver_pk: (&value.receiver_pk).try_into()?,
1652            fee: Fee::from_u64(value.fee.as_u64()),
1653            fee_token: (&*value.fee_token).try_into()?,
1654        })
1655    }
1656}
1657
1658impl From<&SingleFeeTransfer> for MinaBaseFeeTransferSingleStableV2 {
1659    fn from(value: &SingleFeeTransfer) -> Self {
1660        Self {
1661            receiver_pk: (&value.receiver_pk).into(),
1662            fee: (&value.fee).into(),
1663            fee_token: (&value.fee_token).into(),
1664        }
1665    }
1666}
1667
1668impl TryFrom<&MinaBaseFeeTransferStableV2> for FeeTransfer {
1669    type Error = InvalidBigInt;
1670
1671    fn try_from(value: &MinaBaseFeeTransferStableV2) -> Result<Self, Self::Error> {
1672        use super::scan_state::transaction_snark::OneOrTwo::{One, Two};
1673
1674        match value {
1675            MinaBaseFeeTransferStableV2::One(ft) => Ok(FeeTransfer(One(ft.try_into()?))),
1676            MinaBaseFeeTransferStableV2::Two((a, b)) => {
1677                Ok(FeeTransfer(Two((a.try_into()?, b.try_into()?))))
1678            }
1679        }
1680    }
1681}
1682
1683impl From<&FeeTransfer> for MinaBaseFeeTransferStableV2 {
1684    fn from(value: &FeeTransfer) -> Self {
1685        use super::scan_state::transaction_snark::OneOrTwo::{One, Two};
1686
1687        match &value.0 {
1688            One(ft) => MinaBaseFeeTransferStableV2::One(ft.into()),
1689            Two((a, b)) => MinaBaseFeeTransferStableV2::Two((a.into(), b.into())),
1690        }
1691    }
1692}
1693
1694impl From<&MinaBaseSignedCommandMemoStableV1> for Memo {
1695    fn from(value: &MinaBaseSignedCommandMemoStableV1) -> Self {
1696        Self(value.0.as_ref().try_into().unwrap())
1697    }
1698}
1699
1700impl From<&Memo> for MinaBaseSignedCommandMemoStableV1 {
1701    fn from(value: &Memo) -> Self {
1702        Self(CharString::from(value.as_slice().to_vec()))
1703    }
1704}
1705
1706impl TryFrom<MinaBaseSignedCommandStableV2> for SignedCommand {
1707    type Error = InvalidBigInt;
1708
1709    fn try_from(value: MinaBaseSignedCommandStableV2) -> Result<Self, Self::Error> {
1710        (&value).try_into()
1711    }
1712}
1713
1714impl TryFrom<&MinaBaseSignedCommandStableV2> for SignedCommand {
1715    type Error = InvalidBigInt;
1716
1717    fn try_from(cmd: &MinaBaseSignedCommandStableV2) -> Result<Self, Self::Error> {
1718        Ok(Self {
1719            payload: transaction_logic::signed_command::SignedCommandPayload {
1720                common: transaction_logic::signed_command::Common {
1721                    fee: (&cmd.payload.common.fee).into(),
1722                    fee_payer_pk: (&cmd.payload.common.fee_payer_pk).try_into()?,
1723                    nonce: (&cmd.payload.common.nonce).into(),
1724                    valid_until: (&cmd.payload.common.valid_until).into(),
1725                    memo: (&cmd.payload.common.memo).into(),
1726                },
1727                body: match &cmd.payload.body {
1728                    MinaBaseSignedCommandPayloadBodyStableV2::Payment(payload) => {
1729                        transaction_logic::signed_command::Body::Payment(PaymentPayload {
1730                            receiver_pk: (&payload.receiver_pk).try_into()?,
1731                            amount: payload.amount.clone().into(),
1732                        })
1733                    }
1734                    MinaBaseSignedCommandPayloadBodyStableV2::StakeDelegation(
1735                        MinaBaseStakeDelegationStableV2::SetDelegate { new_delegate },
1736                    ) => transaction_logic::signed_command::Body::StakeDelegation(
1737                        StakeDelegationPayload::SetDelegate {
1738                            new_delegate: new_delegate.try_into()?,
1739                        },
1740                    ),
1741                },
1742            },
1743            signer: (&cmd.signer).try_into()?,
1744            signature: (&*cmd.signature).try_into()?,
1745        })
1746    }
1747}
1748
1749impl From<SignedCommand> for MinaBaseSignedCommandStableV2 {
1750    fn from(value: SignedCommand) -> Self {
1751        (&value).into()
1752    }
1753}
1754
1755impl From<&SignedCommand> for MinaBaseSignedCommandStableV2 {
1756    fn from(cmd: &SignedCommand) -> Self {
1757        Self {
1758            payload: MinaBaseSignedCommandPayloadStableV2 {
1759                common: MinaBaseSignedCommandPayloadCommonStableV2 {
1760                    fee: (&cmd.payload.common.fee).into(),
1761                    fee_payer_pk: (&cmd.payload.common.fee_payer_pk).into(),
1762                    nonce: (&cmd.payload.common.nonce).into(),
1763                    valid_until: (&cmd.payload.common.valid_until).into(),
1764                    memo: MinaBaseSignedCommandMemoStableV1(
1765                        cmd.payload.common.memo.as_slice().into(),
1766                    ),
1767                },
1768                body: match &cmd.payload.body {
1769                    crate::scan_state::transaction_logic::signed_command::Body::Payment(
1770                        payload,
1771                    ) => MinaBaseSignedCommandPayloadBodyStableV2::Payment(
1772                        MinaBasePaymentPayloadStableV2 {
1773                            receiver_pk: (&payload.receiver_pk).into(),
1774                            amount: payload.amount.into(),
1775                        },
1776                    ),
1777                    crate::scan_state::transaction_logic::signed_command::Body::StakeDelegation(
1778                        StakeDelegationPayload::SetDelegate { new_delegate },
1779                    ) => MinaBaseSignedCommandPayloadBodyStableV2::StakeDelegation(
1780                        MinaBaseStakeDelegationStableV2::SetDelegate {
1781                            new_delegate: new_delegate.into(),
1782                        },
1783                    ),
1784                },
1785            },
1786            signer: (&cmd.signer).into(),
1787            signature: MinaBaseSignatureStableV1::from(&cmd.signature).into(),
1788        }
1789    }
1790}
1791
1792impl TryFrom<&MinaBaseZkappCommandTStableV1WireStableV1> for zkapp_command::ZkAppCommand {
1793    type Error = InvalidBigInt;
1794
1795    fn try_from(cmd: &MinaBaseZkappCommandTStableV1WireStableV1) -> Result<Self, Self::Error> {
1796        Ok(Self {
1797            fee_payer: (&cmd.fee_payer).try_into()?,
1798            account_updates: (&cmd.account_updates).try_into()?,
1799            memo: (&cmd.memo).into(),
1800        })
1801    }
1802}
1803
1804impl TryFrom<v2::MinaBaseZkappCommandVerifiableStableV1> for verifiable::ZkAppCommand {
1805    type Error = InvalidBigInt;
1806
1807    fn try_from(value: v2::MinaBaseZkappCommandVerifiableStableV1) -> Result<Self, Self::Error> {
1808        let v2::MinaBaseZkappCommandVerifiableStableV1 {
1809            fee_payer,
1810            account_updates,
1811            memo,
1812        } = &value;
1813
1814        Ok(verifiable::ZkAppCommand {
1815            fee_payer: fee_payer.try_into()?,
1816            account_updates: account_updates.try_into()?,
1817            memo: memo.into(),
1818        })
1819    }
1820}
1821
1822impl From<verifiable::ZkAppCommand> for v2::MinaBaseZkappCommandVerifiableStableV1 {
1823    fn from(value: verifiable::ZkAppCommand) -> Self {
1824        let verifiable::ZkAppCommand {
1825            fee_payer,
1826            account_updates,
1827            memo,
1828        } = &value;
1829
1830        v2::MinaBaseZkappCommandVerifiableStableV1 {
1831            fee_payer: fee_payer.into(),
1832            account_updates: account_updates.into(),
1833            memo: memo.into(),
1834        }
1835    }
1836}
1837
1838impl From<&zkapp_command::ZkAppCommand> for MinaBaseZkappCommandTStableV1WireStableV1 {
1839    fn from(cmd: &zkapp_command::ZkAppCommand) -> Self {
1840        Self {
1841            fee_payer: (&cmd.fee_payer).into(),
1842            account_updates: (&cmd.account_updates).into(),
1843            memo: (&cmd.memo).into(),
1844        }
1845    }
1846}
1847
1848impl TryFrom<&MinaTransactionLogicTransactionAppliedVaryingStableV2>
1849    for transaction_applied::Varying
1850{
1851    type Error = InvalidBigInt;
1852
1853    fn try_from(
1854        value: &MinaTransactionLogicTransactionAppliedVaryingStableV2,
1855    ) -> Result<Self, Self::Error> {
1856        use mina_p2p_messages::v2::{
1857            MinaTransactionLogicTransactionAppliedCommandAppliedStableV2::*,
1858            MinaTransactionLogicTransactionAppliedSignedCommandAppliedBodyStableV2::*,
1859            MinaTransactionLogicTransactionAppliedVaryingStableV2::*,
1860        };
1861        use transaction_applied::signed_command_applied;
1862
1863        let result = match value {
1864            Command(cmd) => match cmd {
1865                SignedCommand(cmd) => transaction_applied::Varying::Command(
1866                    transaction_applied::CommandApplied::SignedCommand(Box::new(
1867                        transaction_applied::SignedCommandApplied {
1868                            common: transaction_applied::signed_command_applied::Common {
1869                                user_command: WithStatus {
1870                                    data: (&cmd.common.user_command.data).try_into()?,
1871                                    status: (&cmd.common.user_command.status).into(),
1872                                },
1873                            },
1874                            body: match &cmd.body {
1875                                Payment { new_accounts } => {
1876                                    signed_command_applied::Body::Payments {
1877                                        new_accounts: new_accounts
1878                                            .iter()
1879                                            .cloned()
1880                                            .map(TryInto::try_into)
1881                                            .collect::<Result<_, _>>()?,
1882                                    }
1883                                }
1884                                StakeDelegation { previous_delegate } => {
1885                                    signed_command_applied::Body::StakeDelegation {
1886                                        previous_delegate: match previous_delegate.as_ref() {
1887                                            Some(prev) => Some(prev.try_into()?),
1888                                            None => None,
1889                                        },
1890                                    }
1891                                }
1892                                Failed => signed_command_applied::Body::Failed,
1893                            },
1894                        },
1895                    )),
1896                ),
1897                ZkappCommand(cmd) => transaction_applied::Varying::Command(
1898                    transaction_applied::CommandApplied::ZkappCommand(Box::new(
1899                        transaction_applied::ZkappCommandApplied {
1900                            accounts: cmd
1901                                .accounts
1902                                .iter()
1903                                .map(|(id, account_opt)| {
1904                                    let id: AccountId = id.try_into()?;
1905                                    let account: Option<Account> = match account_opt.as_ref() {
1906                                        Some(account) => Some(account.try_into()?),
1907                                        None => None,
1908                                    };
1909                                    let account = account.map(Box::new);
1910
1911                                    Ok((id, account))
1912                                })
1913                                .collect::<Result<_, _>>()?,
1914                            command: WithStatus {
1915                                data: (&cmd.command.data).try_into()?,
1916                                status: (&cmd.command.status).into(),
1917                            },
1918                            new_accounts: cmd
1919                                .new_accounts
1920                                .iter()
1921                                .map(TryInto::try_into)
1922                                .collect::<Result<_, _>>()?,
1923                        },
1924                    )),
1925                ),
1926            },
1927            FeeTransfer(ft) => {
1928                transaction_applied::Varying::FeeTransfer(transaction_applied::FeeTransferApplied {
1929                    fee_transfer: WithStatus {
1930                        data: (&ft.fee_transfer.data).try_into()?,
1931                        status: (&ft.fee_transfer.status).into(),
1932                    },
1933                    new_accounts: ft
1934                        .new_accounts
1935                        .iter()
1936                        .map(TryInto::try_into)
1937                        .collect::<Result<_, _>>()?,
1938                    burned_tokens: ft.burned_tokens.clone().into(),
1939                })
1940            }
1941            Coinbase(cb) => {
1942                transaction_applied::Varying::Coinbase(transaction_applied::CoinbaseApplied {
1943                    coinbase: WithStatus {
1944                        data: crate::scan_state::transaction_logic::Coinbase {
1945                            receiver: (&cb.coinbase.data.receiver).try_into()?,
1946                            amount: cb.coinbase.data.amount.clone().into(),
1947                            fee_transfer: match cb.coinbase.data.fee_transfer.as_ref() {
1948                                Some(ft) => Some(
1949                                    crate::scan_state::transaction_logic::CoinbaseFeeTransfer {
1950                                        receiver_pk: (&ft.receiver_pk).try_into()?,
1951                                        fee: Fee::from_u64(ft.fee.as_u64()),
1952                                    },
1953                                ),
1954                                None => None,
1955                            },
1956                        },
1957                        status: (&cb.coinbase.status).into(),
1958                    },
1959                    new_accounts: cb
1960                        .new_accounts
1961                        .iter()
1962                        .map(TryInto::try_into)
1963                        .collect::<Result<_, _>>()?,
1964                    burned_tokens: cb.burned_tokens.clone().into(),
1965                })
1966            }
1967        };
1968
1969        Ok(result)
1970    }
1971}
1972
1973impl TryFrom<&TransactionSnarkScanStateTransactionWithWitnessStableV2> for TransactionWithWitness {
1974    type Error = InvalidBigInt;
1975
1976    fn try_from(
1977        value: &TransactionSnarkScanStateTransactionWithWitnessStableV2,
1978    ) -> Result<Self, Self::Error> {
1979        // use mina_p2p_messages::v2::TransactionSnarkPendingCoinbaseStackStateInitStackStableV1::{Base, Merge};
1980        use mina_p2p_messages::v2::MinaStateSnarkedLedgerStatePendingCoinbaseStackStateInitStackStableV1::{Base, Merge};
1981        use crate::scan_state::scan_state::transaction_snark::InitStack;
1982
1983        Ok(Self {
1984            transaction_with_info: TransactionApplied {
1985                previous_hash: value.transaction_with_info.previous_hash.to_field()?,
1986                varying: (&value.transaction_with_info.varying).try_into()?,
1987            },
1988            state_hash: {
1989                let (state, body) = &value.state_hash;
1990                (state.to_field()?, body.to_field()?)
1991            },
1992            statement: (&*value.statement).try_into()?,
1993            init_stack: match &value.init_stack {
1994                Base(base) => InitStack::Base(pending_coinbase::Stack {
1995                    data: pending_coinbase::CoinbaseStack(base.data.to_field()?),
1996                    state: pending_coinbase::StateStack {
1997                        init: base.state.init.to_field()?,
1998                        curr: base.state.curr.to_field()?,
1999                    },
2000                }),
2001                Merge => InitStack::Merge,
2002            },
2003            first_pass_ledger_witness: (&value.first_pass_ledger_witness).try_into()?,
2004            second_pass_ledger_witness: (&value.second_pass_ledger_witness).try_into()?,
2005            block_global_slot: Slot::from_u32(value.block_global_slot.as_u32()),
2006        })
2007    }
2008}
2009
2010impl From<&TokenId> for mina_p2p_messages::v2::TokenIdKeyHash {
2011    fn from(value: &TokenId) -> Self {
2012        let id: MinaBaseAccountIdDigestStableV1 = value.clone().into();
2013        id.into()
2014    }
2015}
2016
2017impl From<&Registers> for MinaStateBlockchainStateValueStableV2LedgerProofStatementSource {
2018    fn from(value: &Registers) -> Self {
2019        Self {
2020            first_pass_ledger: MinaBaseLedgerHash0StableV1(value.first_pass_ledger.into()).into(),
2021            second_pass_ledger: MinaBaseLedgerHash0StableV1(value.second_pass_ledger.into()).into(),
2022            pending_coinbase_stack: (&value.pending_coinbase_stack).into(),
2023            local_state: (&value.local_state).into(),
2024        }
2025    }
2026}
2027
2028impl From<&LocalState> for MinaTransactionLogicZkappCommandLogicLocalStateValueStableV1 {
2029    fn from(value: &LocalState) -> Self {
2030        Self {
2031            stack_frame: MinaBaseStackFrameStableV1(value.stack_frame.into()),
2032            call_stack: MinaBaseCallStackDigestStableV1(value.call_stack.into()),
2033            transaction_commitment: value.transaction_commitment.into(),
2034            full_transaction_commitment: value.full_transaction_commitment.into(),
2035            excess: SignedAmount {
2036                magnitude: (&value.excess.magnitude).into(),
2037                sgn: (&value.excess.sgn).into(),
2038            },
2039            supply_increase: SignedAmount {
2040                magnitude: (&value.supply_increase.magnitude).into(),
2041                sgn: (&value.supply_increase.sgn).into(),
2042            },
2043            ledger: {
2044                let hash = MinaBaseLedgerHash0StableV1(value.ledger.into());
2045                hash.into()
2046            },
2047            success: value.success,
2048            account_update_index: UnsignedExtendedUInt32StableV1(
2049                value.account_update_index.as_u32().into(),
2050            ),
2051            failure_status_tbl: MinaBaseTransactionStatusFailureCollectionStableV1(
2052                value
2053                    .failure_status_tbl
2054                    .iter()
2055                    .map(|s| s.iter().map(|s| s.into()).collect())
2056                    .collect(),
2057            ),
2058            will_succeed: value.will_succeed,
2059        }
2060    }
2061}
2062
2063impl From<&Statement<()>> for MinaStateBlockchainStateValueStableV2LedgerProofStatement {
2064    fn from(value: &Statement<()>) -> Self {
2065        Self {
2066            source: (&value.source).into(),
2067            target: (&value.target).into(),
2068            supply_increase: (&value.supply_increase).into(),
2069            fee_excess: (&value.fee_excess).into(),
2070            sok_digest: (),
2071            connecting_ledger_left: MinaBaseLedgerHash0StableV1(
2072                (&value.connecting_ledger_left).into(),
2073            )
2074            .into(),
2075            connecting_ledger_right: MinaBaseLedgerHash0StableV1(
2076                (&value.connecting_ledger_right).into(),
2077            )
2078            .into(),
2079        }
2080    }
2081}
2082
2083impl From<&Statement<()>> for MinaStateSnarkedLedgerStateStableV2 {
2084    fn from(value: &Statement<()>) -> Self {
2085        Self(value.into())
2086    }
2087}
2088
2089impl From<&transaction_logic::Coinbase> for MinaBaseCoinbaseStableV1 {
2090    fn from(value: &transaction_logic::Coinbase) -> Self {
2091        Self {
2092            receiver: (&value.receiver).into(),
2093            amount: value.amount.into(),
2094            fee_transfer: value.fee_transfer.as_ref().map(|ft| {
2095                MinaBaseCoinbaseFeeTransferStableV1 {
2096                    receiver_pk: (&ft.receiver_pk).into(),
2097                    fee: (&ft.fee).into(),
2098                }
2099            }),
2100        }
2101    }
2102}
2103
2104impl TryFrom<&MinaBaseCoinbaseStableV1> for transaction_logic::Coinbase {
2105    type Error = InvalidBigInt;
2106
2107    fn try_from(value: &MinaBaseCoinbaseStableV1) -> Result<Self, Self::Error> {
2108        Ok(Self {
2109            receiver: (&value.receiver).try_into()?,
2110            amount: value.amount.clone().into(),
2111            fee_transfer: match value.fee_transfer.as_ref() {
2112                Some(ft) => Some(CoinbaseFeeTransfer {
2113                    receiver_pk: (&ft.receiver_pk).try_into()?,
2114                    fee: (&ft.fee).into(),
2115                }),
2116                None => None,
2117            },
2118        })
2119    }
2120}
2121
2122pub fn to_ledger_hash(value: &Fp) -> mina_p2p_messages::v2::LedgerHash {
2123    let hash = MinaBaseLedgerHash0StableV1(value.into());
2124    hash.into()
2125}
2126
2127pub fn to_pending_coinbase_hash(value: &Fp) -> mina_p2p_messages::v2::PendingCoinbaseHash {
2128    let hash = MinaBasePendingCoinbaseHashVersionedStableV1(
2129        MinaBasePendingCoinbaseHashBuilderStableV1(value.into()),
2130    );
2131    hash.into()
2132}
2133
2134impl From<&AvailableJob> for AvailableJobMessage {
2135    fn from(value: &AvailableJob) -> Self {
2136        match value {
2137            AvailableJob::Base(v) => AvailableJobMessage::Base(v.as_ref().into()),
2138            AvailableJob::Merge { left, right } => AvailableJobMessage::Merge {
2139                left: left.as_ref().into(),
2140                right: right.as_ref().into(),
2141            },
2142        }
2143    }
2144}
2145
2146impl From<&TransactionWithWitness> for TransactionSnarkScanStateTransactionWithWitnessStableV2 {
2147    fn from(value: &TransactionWithWitness) -> Self {
2148        use super::scan_state::transaction_snark::InitStack;
2149        use mina_p2p_messages::v2::MinaStateSnarkedLedgerStatePendingCoinbaseStackStateInitStackStableV1::{Base, Merge};
2150
2151        Self {
2152            transaction_with_info: MinaTransactionLogicTransactionAppliedStableV2 {
2153                previous_hash: {
2154                    let hash = MinaBaseLedgerHash0StableV1(
2155                        value.transaction_with_info.previous_hash.into(),
2156                    );
2157                    hash.into()
2158                },
2159                varying: match &value.transaction_with_info.varying {
2160                    transaction_applied::Varying::Command(
2161                        transaction_applied::CommandApplied::SignedCommand(cmd),
2162                    ) => {
2163                        MinaTransactionLogicTransactionAppliedVaryingStableV2::Command(
2164                            MinaTransactionLogicTransactionAppliedCommandAppliedStableV2::SignedCommand(
2165                                MinaTransactionLogicTransactionAppliedSignedCommandAppliedStableV2 {
2166                                    common: MinaTransactionLogicTransactionAppliedSignedCommandAppliedCommonStableV2 {
2167                                        user_command: MinaTransactionLogicTransactionAppliedSignedCommandAppliedCommonStableV2UserCommand {
2168                                            data: (&cmd.common.user_command.data).into(),
2169                                            status: (&cmd.common.user_command.status).into(),
2170                                        },
2171                                    },
2172                                    body: match &cmd.body {
2173                                        transaction_applied::signed_command_applied::Body::Payments { new_accounts } =>
2174                                            MinaTransactionLogicTransactionAppliedSignedCommandAppliedBodyStableV2::Payment {
2175                                            new_accounts: new_accounts.iter().cloned().map(Into::into).collect(),
2176                                        },
2177                                        transaction_applied::signed_command_applied::Body::StakeDelegation { previous_delegate } =>
2178                                            MinaTransactionLogicTransactionAppliedSignedCommandAppliedBodyStableV2::StakeDelegation {
2179                                            previous_delegate: previous_delegate.as_ref().map(Into::into)
2180                                        },
2181                                        transaction_applied::signed_command_applied::Body::Failed =>
2182                                            MinaTransactionLogicTransactionAppliedSignedCommandAppliedBodyStableV2::Failed,
2183                                    },
2184                                }))
2185                    }
2186                    transaction_applied::Varying::Command(
2187                        transaction_applied::CommandApplied::ZkappCommand(cmd),
2188                    ) =>
2189                        MinaTransactionLogicTransactionAppliedVaryingStableV2::Command(
2190                            MinaTransactionLogicTransactionAppliedCommandAppliedStableV2::ZkappCommand(
2191                                MinaTransactionLogicTransactionAppliedZkappCommandAppliedStableV1 {
2192                                accounts: cmd.accounts.iter().map(|(id, account_opt)| {
2193                                    let id: MinaBaseAccountIdStableV2 = id.clone().into();
2194                                    let account_opt = account_opt.as_ref().map(|acc| (&**acc).into());
2195                                    (id, account_opt)
2196                                }).collect(),
2197                                command: MinaTransactionLogicTransactionAppliedZkappCommandAppliedStableV1Command {
2198                                    data: (&cmd.command.data).into(),
2199                                    status: (&cmd.command.status).into(),
2200                                },
2201                                new_accounts: cmd.new_accounts.iter().cloned().map(Into::into).collect(),
2202                            })
2203                        ),
2204                    transaction_applied::Varying::FeeTransfer(ft) =>
2205                        MinaTransactionLogicTransactionAppliedVaryingStableV2::FeeTransfer(
2206                            MinaTransactionLogicTransactionAppliedFeeTransferAppliedStableV2 {
2207                                fee_transfer: MinaTransactionLogicTransactionAppliedFeeTransferAppliedStableV2FeeTransfer {
2208                                    data: (&ft.fee_transfer.data).into(),
2209                                    status: (&ft.fee_transfer.status).into(),
2210                                },
2211                                new_accounts: ft.new_accounts.iter().cloned().map(Into::into).collect(),
2212                                burned_tokens: ft.burned_tokens.into(),
2213                            }),
2214                    transaction_applied::Varying::Coinbase(cb) =>
2215                        MinaTransactionLogicTransactionAppliedVaryingStableV2::Coinbase(
2216                            MinaTransactionLogicTransactionAppliedCoinbaseAppliedStableV2 {
2217                                coinbase: MinaTransactionLogicTransactionAppliedCoinbaseAppliedStableV2Coinbase {
2218                                    data: (&cb.coinbase.data).into(),
2219                                    status: (&cb.coinbase.status).into(),
2220                                },
2221                                new_accounts: cb.new_accounts.iter().cloned().map(Into::into).collect(),
2222                                burned_tokens: cb.burned_tokens.into(),
2223                            }
2224                        ),
2225                },
2226            },
2227            state_hash: {
2228                let (state, body) = &value.state_hash;
2229                let state = DataHashLibStateHashStableV1(state.into());
2230
2231                (state.into(), MinaBaseStateBodyHashStableV1(body.into()).into())
2232            },
2233            statement: (&value.statement).into(),
2234            init_stack: match &value.init_stack {
2235                InitStack::Base(base) => Base(MinaBasePendingCoinbaseStackVersionedStableV1 {
2236                    data: MinaBasePendingCoinbaseCoinbaseStackStableV1(base.data.0.into()).into(),
2237                    state: MinaBasePendingCoinbaseStateStackStableV1 {
2238                        init: MinaBasePendingCoinbaseStackHashStableV1(base.state.init.into()).into(),
2239                        curr: MinaBasePendingCoinbaseStackHashStableV1(base.state.curr.into()).into(),
2240                    },
2241                }),
2242                InitStack::Merge => Merge,
2243            },
2244            first_pass_ledger_witness: (&value.first_pass_ledger_witness).into(),
2245            second_pass_ledger_witness: (&value.second_pass_ledger_witness).into(),
2246            block_global_slot: (&value.block_global_slot).into(),
2247        }
2248    }
2249}
2250
2251impl binprot::BinProtWrite for TransactionWithWitness {
2252    fn binprot_write<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
2253        let p2p: TransactionSnarkScanStateTransactionWithWitnessStableV2 = self.into();
2254        p2p.binprot_write(w)
2255    }
2256}
2257
2258impl TryFrom<&TransactionSnarkStableV2> for TransactionSnark<SokDigest> {
2259    type Error = InvalidBigInt;
2260
2261    fn try_from(value: &TransactionSnarkStableV2) -> Result<Self, Self::Error> {
2262        Ok(Self {
2263            statement: (&value.statement).try_into()?,
2264            proof: Arc::new(value.proof.clone()),
2265        })
2266    }
2267}
2268
2269impl From<&TransactionSnark<SokDigest>> for TransactionSnarkStableV2 {
2270    fn from(value: &TransactionSnark<SokDigest>) -> Self {
2271        Self {
2272            statement: (&value.statement).into(),
2273            proof: (*value.proof).clone(),
2274        }
2275    }
2276}
2277
2278impl TryFrom<&LedgerProofProdStableV2> for LedgerProof {
2279    type Error = InvalidBigInt;
2280
2281    fn try_from(value: &LedgerProofProdStableV2) -> Result<Self, Self::Error> {
2282        Ok(Self((&value.0).try_into()?))
2283    }
2284}
2285
2286impl From<&LedgerProof> for LedgerProofProdStableV2 {
2287    fn from(value: &LedgerProof) -> Self {
2288        Self((&value.0).into())
2289    }
2290}
2291
2292// impl binprot::BinProtWrite for LedgerProof {
2293//     fn binprot_write<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
2294//         let p2p: LedgerProofProdStableV2 = self.into();
2295//         p2p.binprot_write(w)
2296//     }
2297// }
2298
2299impl TryFrom<&MinaBaseSokMessageStableV1> for SokMessage {
2300    type Error = InvalidBigInt;
2301
2302    fn try_from(value: &MinaBaseSokMessageStableV1) -> Result<Self, Self::Error> {
2303        Ok(Self {
2304            fee: (&value.fee).into(),
2305            prover: (&value.prover).try_into()?,
2306        })
2307    }
2308}
2309
2310impl From<&SokMessage> for MinaBaseSokMessageStableV1 {
2311    fn from(value: &SokMessage) -> Self {
2312        Self {
2313            fee: (&value.fee).into(),
2314            prover: (&value.prover).into(),
2315        }
2316    }
2317}
2318
2319impl From<&LedgerProofWithSokMessage>
2320    for TransactionSnarkScanStateLedgerProofWithSokMessageStableV2
2321{
2322    fn from(value: &LedgerProofWithSokMessage) -> Self {
2323        Self((&value.proof).into(), (&value.sok_message).into())
2324    }
2325}
2326
2327impl TryFrom<&TransactionSnarkScanStateLedgerProofWithSokMessageStableV2>
2328    for LedgerProofWithSokMessage
2329{
2330    type Error = InvalidBigInt;
2331
2332    fn try_from(
2333        value: &TransactionSnarkScanStateLedgerProofWithSokMessageStableV2,
2334    ) -> Result<Self, Self::Error> {
2335        let TransactionSnarkScanStateLedgerProofWithSokMessageStableV2(proof, msg) = value;
2336
2337        Ok(Self {
2338            proof: proof.try_into()?,
2339            sok_message: msg.try_into()?,
2340        })
2341    }
2342}
2343
2344impl binprot::BinProtWrite for LedgerProofWithSokMessage {
2345    fn binprot_write<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
2346        let p2p: TransactionSnarkScanStateLedgerProofWithSokMessageStableV2 = self.into();
2347        p2p.binprot_write(w)
2348    }
2349}
2350
2351impl TryFrom<MinaBaseUserCommandStableV2> for transaction_logic::valid::UserCommand {
2352    type Error = InvalidBigInt;
2353
2354    fn try_from(value: MinaBaseUserCommandStableV2) -> Result<Self, Self::Error> {
2355        (&value).try_into()
2356    }
2357}
2358
2359impl TryFrom<&MinaBaseUserCommandStableV2> for transaction_logic::valid::UserCommand {
2360    type Error = InvalidBigInt;
2361
2362    fn try_from(value: &MinaBaseUserCommandStableV2) -> Result<Self, Self::Error> {
2363        Ok(match value {
2364            MinaBaseUserCommandStableV2::ZkappCommand(cmd) => {
2365                Self::ZkAppCommand(Box::new(zkapp_command::valid::ZkAppCommand {
2366                    zkapp_command: cmd.try_into()?,
2367                }))
2368            }
2369            MinaBaseUserCommandStableV2::SignedCommand(cmd) => {
2370                Self::SignedCommand(Box::new(cmd.try_into()?))
2371            }
2372        })
2373    }
2374}
2375
2376impl From<transaction_logic::valid::UserCommand> for MinaBaseUserCommandStableV2 {
2377    fn from(value: transaction_logic::valid::UserCommand) -> Self {
2378        match value {
2379            transaction_logic::valid::UserCommand::SignedCommand(cmd) => {
2380                MinaBaseUserCommandStableV2::SignedCommand((&*cmd).into())
2381            }
2382            transaction_logic::valid::UserCommand::ZkAppCommand(cmd) => {
2383                let zkapp_command::valid::ZkAppCommand { zkapp_command } = &*cmd;
2384                MinaBaseUserCommandStableV2::ZkappCommand(zkapp_command.into())
2385            }
2386        }
2387    }
2388}
2389
2390impl From<&ParallelScanWeightStableV1> for super::parallel_scan::Weight {
2391    fn from(value: &ParallelScanWeightStableV1) -> Self {
2392        let ParallelScanWeightStableV1 { base, merge } = value;
2393
2394        Self {
2395            base: base.as_u64(),
2396            merge: merge.as_u64(),
2397        }
2398    }
2399}
2400
2401// Tuples are foreign types, we cannot use `From`
2402fn from_two_weights(
2403    value: &(ParallelScanWeightStableV1, ParallelScanWeightStableV1),
2404) -> (super::parallel_scan::Weight, super::parallel_scan::Weight) {
2405    let (first, second) = value;
2406    (first.into(), second.into())
2407}
2408
2409impl From<&ParallelScanSequenceNumberStableV1> for SequenceNumber {
2410    fn from(value: &ParallelScanSequenceNumberStableV1) -> Self {
2411        SequenceNumber::new(value.as_u64())
2412    }
2413}
2414
2415impl From<&ParallelScanJobStatusStableV1> for JobStatus {
2416    fn from(value: &ParallelScanJobStatusStableV1) -> Self {
2417        match value {
2418            ParallelScanJobStatusStableV1::Todo => Self::Todo,
2419            ParallelScanJobStatusStableV1::Done => Self::Done,
2420        }
2421    }
2422}
2423
2424impl TryFrom<&TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1>
2425    for super::parallel_scan::merge::Job<Arc<LedgerProofWithSokMessage>>
2426{
2427    type Error = InvalidBigInt;
2428
2429    fn try_from(
2430        value: &TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1,
2431    ) -> Result<Self, Self::Error> {
2432        Ok(match value {
2433            TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1::Empty => Self::Empty,
2434            TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1::Part(proof) => {
2435                Self::Part(Arc::new((&**proof).try_into()?))
2436            }
2437            TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1::Full(record) => {
2438                let TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1Full {
2439                    left,
2440                    right,
2441                    seq_no,
2442                    status,
2443                } = &**record;
2444
2445                Self::Full(super::parallel_scan::merge::Record {
2446                    left: Arc::new(left.try_into()?),
2447                    right: Arc::new(right.try_into()?),
2448                    seq_no: seq_no.into(),
2449                    state: status.into(),
2450                })
2451            }
2452        })
2453    }
2454}
2455
2456impl TryFrom<&TransactionSnarkScanStateStableV2ScanStateTreesABaseT1>
2457    for super::parallel_scan::base::Job<Arc<TransactionWithWitness>>
2458{
2459    type Error = InvalidBigInt;
2460
2461    fn try_from(
2462        value: &TransactionSnarkScanStateStableV2ScanStateTreesABaseT1,
2463    ) -> Result<Self, Self::Error> {
2464        Ok(match value {
2465            TransactionSnarkScanStateStableV2ScanStateTreesABaseT1::Empty => Self::Empty,
2466            TransactionSnarkScanStateStableV2ScanStateTreesABaseT1::Full(record) => {
2467                let TransactionSnarkScanStateStableV2ScanStateTreesABaseT1Full {
2468                    job,
2469                    seq_no,
2470                    status,
2471                } = &**record;
2472
2473                Self::Full(super::parallel_scan::base::Record {
2474                    job: Arc::new(job.try_into()?),
2475                    seq_no: seq_no.into(),
2476                    state: status.into(),
2477                })
2478            }
2479        })
2480    }
2481}
2482
2483impl TryFrom<&TransactionSnarkScanStateStableV2> for ScanState {
2484    type Error = InvalidBigInt;
2485
2486    fn try_from(value: &TransactionSnarkScanStateStableV2) -> Result<Self, Self::Error> {
2487        let TransactionSnarkScanStateStableV2 {
2488            scan_state,
2489            previous_incomplete_zkapp_updates,
2490        } = value;
2491
2492        Ok(Self {
2493            scan_state: {
2494                let TransactionSnarkScanStateStableV2ScanState {
2495                    trees,
2496                    acc,
2497                    curr_job_seq_no,
2498                    max_base_jobs,
2499                    delay,
2500                } = scan_state;
2501
2502                ParallelScan::<Arc<TransactionWithWitness>, Arc<LedgerProofWithSokMessage>> {
2503                    trees: {
2504                        use mina_p2p_messages::v2::TransactionSnarkScanStateStableV2ScanStateTreesA::{Leaf, Node};
2505                        use super::parallel_scan::Weight;
2506
2507                        let (first, rest) = trees;
2508
2509                        std::iter::once(first)
2510                            .chain(rest)
2511                            .map(|tree| {
2512                                let mut rust_tree = super::parallel_scan::Tree {
2513                                    values: Vec::with_capacity(255),
2514                                };
2515
2516                                let mut current = tree;
2517
2518                                // We iterator on the first "depths", those are nodes only
2519                                while let Node {
2520                                    depth,
2521                                    value,
2522                                    sub_tree,
2523                                } = current
2524                                {
2525                                    for (weights, job) in value.iter() {
2526                                        let weight: (Weight, Weight) = from_two_weights(weights);
2527                                        let job: super::parallel_scan::merge::Job<
2528                                            Arc<LedgerProofWithSokMessage>,
2529                                        > = job.try_into()?;
2530
2531                                        let merge =
2532                                            super::parallel_scan::merge::Merge { weight, job };
2533
2534                                        rust_tree
2535                                            .values
2536                                            .push(super::parallel_scan::Value::Node(merge));
2537                                    }
2538
2539                                    current = sub_tree;
2540                                }
2541
2542                                // Last depth is all leaves
2543                                let Leaf(leaves) = current else {
2544                                    panic!("Invalid tree")
2545                                };
2546
2547                                for (weight, job) in leaves {
2548                                    let weight: Weight = weight.into();
2549                                    let job: super::parallel_scan::base::Job<
2550                                        Arc<TransactionWithWitness>,
2551                                    > = job.try_into()?;
2552
2553                                    let base = super::parallel_scan::base::Base { weight, job };
2554
2555                                    rust_tree
2556                                        .values
2557                                        .push(super::parallel_scan::Value::Leaf(base))
2558                                }
2559
2560                                Ok(rust_tree)
2561                            })
2562                            .collect::<Result<_, _>>()?
2563                    },
2564                    acc: match acc.as_ref() {
2565                        Some((proof, txns)) => Some((
2566                            Arc::new(proof.try_into()?),
2567                            txns.iter()
2568                                .map(|t| Ok(Arc::new(t.try_into()?)))
2569                                .collect::<Result<_, _>>()?,
2570                        )),
2571                        None => None,
2572                    },
2573                    curr_job_seq_no: { SequenceNumber::new(curr_job_seq_no.as_u64()) },
2574                    max_base_jobs: max_base_jobs.as_u64(),
2575                    delay: delay.as_u64(),
2576                }
2577            },
2578            previous_incomplete_zkapp_updates: {
2579                let (txns, continue_next) = previous_incomplete_zkapp_updates;
2580
2581                let continue_next = match continue_next {
2582                    Border_block_continued_in_the_next_tree(continue_next) => {
2583                        BorderBlockContinuedInTheNextTree(*continue_next)
2584                    }
2585                };
2586
2587                (
2588                    txns.iter()
2589                        .map(
2590                            |t: &TransactionSnarkScanStateTransactionWithWitnessStableV2| {
2591                                Ok(Arc::new(t.try_into()?))
2592                            },
2593                        )
2594                        .collect::<Result<_, _>>()?,
2595                    continue_next,
2596                )
2597            },
2598        })
2599    }
2600}
2601
2602impl From<&parallel_scan::Weight> for ParallelScanWeightStableV1 {
2603    fn from(value: &parallel_scan::Weight) -> Self {
2604        let parallel_scan::Weight { base, merge } = value;
2605
2606        Self {
2607            base: (*base).into(),
2608            merge: (*merge).into(),
2609        }
2610    }
2611}
2612
2613impl From<&SequenceNumber> for ParallelScanSequenceNumberStableV1 {
2614    fn from(value: &SequenceNumber) -> Self {
2615        ParallelScanSequenceNumberStableV1(value.as_u64().into())
2616    }
2617}
2618
2619impl From<&JobStatus> for ParallelScanJobStatusStableV1 {
2620    fn from(value: &JobStatus) -> Self {
2621        match value {
2622            JobStatus::Todo => Self::Todo,
2623            JobStatus::Done => Self::Done,
2624        }
2625    }
2626}
2627
2628impl From<&super::parallel_scan::base::Job<Arc<TransactionWithWitness>>>
2629    for TransactionSnarkScanStateStableV2ScanStateTreesABaseT1
2630{
2631    fn from(value: &super::parallel_scan::base::Job<Arc<TransactionWithWitness>>) -> Self {
2632        match value {
2633            parallel_scan::base::Job::Empty => Self::Empty,
2634            parallel_scan::base::Job::Full(record) => {
2635                let parallel_scan::base::Record::<Arc<TransactionWithWitness>> {
2636                    job,
2637                    seq_no,
2638                    state,
2639                } = record;
2640
2641                Self::Full(Box::new(
2642                    TransactionSnarkScanStateStableV2ScanStateTreesABaseT1Full {
2643                        job: job.as_ref().into(),
2644                        seq_no: seq_no.into(),
2645                        status: state.into(),
2646                    },
2647                ))
2648            }
2649        }
2650    }
2651}
2652
2653impl From<&parallel_scan::merge::Job<Arc<LedgerProofWithSokMessage>>>
2654    for TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1
2655{
2656    fn from(value: &parallel_scan::merge::Job<Arc<LedgerProofWithSokMessage>>) -> Self {
2657        match value {
2658            parallel_scan::merge::Job::Empty => Self::Empty,
2659            parallel_scan::merge::Job::Part(part) => Self::Part(Box::new(part.as_ref().into())),
2660            parallel_scan::merge::Job::Full(record) => {
2661                let parallel_scan::merge::Record::<Arc<LedgerProofWithSokMessage>> {
2662                    left,
2663                    right,
2664                    seq_no,
2665                    state,
2666                } = record;
2667
2668                Self::Full(Box::new(
2669                    TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1Full {
2670                        left: left.as_ref().into(),
2671                        right: right.as_ref().into(),
2672                        seq_no: seq_no.into(),
2673                        status: state.into(),
2674                    },
2675                ))
2676            }
2677        }
2678    }
2679}
2680
2681impl From<&&parallel_scan::base::Base<Arc<TransactionWithWitness>>>
2682    for (
2683        ParallelScanWeightStableV1,
2684        TransactionSnarkScanStateStableV2ScanStateTreesABaseT1,
2685    )
2686{
2687    fn from(value: &&parallel_scan::base::Base<Arc<TransactionWithWitness>>) -> Self {
2688        let parallel_scan::base::Base::<Arc<TransactionWithWitness>> { weight, job } = value;
2689
2690        (weight.into(), job.into())
2691    }
2692}
2693
2694impl From<&&parallel_scan::merge::Merge<Arc<LedgerProofWithSokMessage>>>
2695    for TransactionSnarkScanStateStableV2TreesAMerge
2696{
2697    fn from(value: &&parallel_scan::merge::Merge<Arc<LedgerProofWithSokMessage>>) -> Self {
2698        let parallel_scan::merge::Merge::<Arc<LedgerProofWithSokMessage>> { weight, job } = value;
2699
2700        let (w1, w2) = weight;
2701        ((w1.into(), w2.into()), job.into())
2702    }
2703}
2704
2705impl From<&ScanState> for TransactionSnarkScanStateStableV2 {
2706    fn from(value: &ScanState) -> Self {
2707        let ScanState {
2708            scan_state,
2709            previous_incomplete_zkapp_updates,
2710        } = value;
2711
2712        Self {
2713            scan_state: {
2714                let ParallelScan {
2715                    trees,
2716                    acc,
2717                    curr_job_seq_no,
2718                    max_base_jobs,
2719                    delay,
2720                } = scan_state;
2721
2722                TransactionSnarkScanStateStableV2ScanState {
2723                    trees: {
2724                        use mina_p2p_messages::v2::TransactionSnarkScanStateStableV2ScanStateTreesA::{Leaf, Node};
2725
2726                        let mut trees: Vec<_> = trees
2727                            .iter()
2728                            .map(|tree| {
2729                                let values_by_depth = tree.values_by_depth();
2730
2731                                let mut previous = None;
2732
2733                                // rev to start from leaves
2734                                for (depth, values) in values_by_depth.iter().rev() {
2735                                    match values {
2736                                        crate::scan_state::parallel_scan::Value::Leaf(leaves) => {
2737                                            previous =
2738                                                Some(Leaf(leaves.iter().map(Into::into).collect()));
2739                                        }
2740                                        crate::scan_state::parallel_scan::Value::Node(nodes) => {
2741                                            let depth: u32 = (*depth).try_into().unwrap();
2742
2743                                            previous = Some(Node {
2744                                                depth: depth.into(),
2745                                                value: nodes.iter().map(Into::into).collect(),
2746                                                sub_tree: Box::new(previous.take().unwrap()),
2747                                            });
2748                                        }
2749                                    };
2750                                }
2751
2752                                previous.take().unwrap()
2753                            })
2754                            .collect();
2755
2756                        let first = trees.remove(0);
2757                        let rest = trees;
2758
2759                        (first, rest.into_iter().collect())
2760                    },
2761                    acc: acc.as_ref().map(|(proof, txns)| {
2762                        (
2763                            proof.as_ref().into(),
2764                            txns.iter().map(|t| t.as_ref().into()).collect(),
2765                        )
2766                    }),
2767                    curr_job_seq_no: curr_job_seq_no.as_u64().into(),
2768                    max_base_jobs: max_base_jobs.into(),
2769                    delay: delay.into(),
2770                }
2771            },
2772            previous_incomplete_zkapp_updates: {
2773                let (txns, continue_next) = previous_incomplete_zkapp_updates;
2774
2775                let continue_next = match continue_next {
2776                    BorderBlockContinuedInTheNextTree(continue_next) => {
2777                        Border_block_continued_in_the_next_tree(*continue_next)
2778                    }
2779                };
2780
2781                (
2782                    txns.iter().map(|t| t.as_ref().into()).collect(),
2783                    continue_next,
2784                )
2785            },
2786        }
2787    }
2788}
2789
2790impl From<&MinaBasePendingCoinbaseStackIdStableV1> for pending_coinbase::StackId {
2791    fn from(value: &MinaBasePendingCoinbaseStackIdStableV1) -> Self {
2792        Self::new(value.as_u64())
2793    }
2794}
2795
2796impl From<&pending_coinbase::StackId> for MinaBasePendingCoinbaseStackIdStableV1 {
2797    fn from(value: &pending_coinbase::StackId) -> Self {
2798        Self(value.as_u64().into())
2799    }
2800}
2801
2802impl TryFrom<&MinaBasePendingCoinbaseStableV2> for PendingCoinbase {
2803    type Error = InvalidBigInt;
2804
2805    fn try_from(value: &MinaBasePendingCoinbaseStableV2) -> Result<Self, Self::Error> {
2806        let MinaBasePendingCoinbaseStableV2 {
2807            tree,
2808            pos_list,
2809            new_pos,
2810        } = value;
2811
2812        Ok(Self {
2813            tree: {
2814                // NOTE: Same implementation than with `SparseLedger`
2815
2816                use MinaBasePendingCoinbaseMerkleTreeVersionedStableV2Tree::{Account, Hash, Node};
2817
2818                fn build_matrix(
2819                    matrix: &mut HashesMatrix,
2820                    addr: Address,
2821                    node: &MinaBasePendingCoinbaseMerkleTreeVersionedStableV2Tree,
2822                    values: &mut Vec<Stack>,
2823                ) -> Result<(), InvalidBigInt> {
2824                    match node {
2825                        Account(stack) => {
2826                            let stack: Stack = stack.try_into()?;
2827                            matrix.set(&addr, <StackHasher as pending_coinbase::merkle_tree::TreeHasher::<Stack>>::hash_value(&stack));
2828                            values.push(stack);
2829                        }
2830                        Hash(hash) => {
2831                            matrix.set(&addr, hash.to_field()?);
2832                        }
2833                        Node(hash, left, right) => {
2834                            matrix.set(&addr, hash.to_field()?);
2835                            build_matrix(matrix, addr.child_left(), left, values)?;
2836                            build_matrix(matrix, addr.child_right(), right, values)?;
2837                        }
2838                    }
2839                    Ok(())
2840                }
2841
2842                let MinaBasePendingCoinbaseMerkleTreeVersionedStableV2 {
2843                    indexes,
2844                    depth,
2845                    tree,
2846                } = tree;
2847
2848                let depth = depth.as_u64() as usize;
2849                let mut our_index = std::collections::HashMap::with_capacity(indexes.len());
2850                // let mut index_list = std::collections::VecDeque::with_capacity(indexes.len());
2851                let mut hashes_matrix = HashesMatrix::new(depth);
2852                let mut values = Vec::new();
2853
2854                for (stack_id, stack_index) in indexes.iter() {
2855                    let stack_id: pending_coinbase::StackId = stack_id.into();
2856                    let stack_index = crate::AccountIndex::from(stack_index.as_u64() as usize);
2857
2858                    let addr = Address::from_index(stack_index, depth);
2859
2860                    our_index.insert(stack_id, addr);
2861                    // index_list.push_back(stack_id);
2862                }
2863
2864                build_matrix(&mut hashes_matrix, Address::root(), tree, &mut values)?;
2865
2866                pending_coinbase::merkle_tree::MiniMerkleTree {
2867                    values,
2868                    indexes: our_index,
2869                    hashes_matrix,
2870                    depth,
2871                    _hasher: std::marker::PhantomData,
2872                }
2873            },
2874            pos_list: pos_list.iter().rev().map(Into::into).collect(),
2875            new_pos: new_pos.into(),
2876        })
2877    }
2878}
2879
2880impl From<&super::pending_coinbase::update::Update> for MinaBasePendingCoinbaseUpdateStableV1 {
2881    fn from(value: &super::pending_coinbase::update::Update) -> Self {
2882        Self {
2883            action: (&value.action).into(),
2884            coinbase_amount: (&value.coinbase_amount).into(),
2885        }
2886    }
2887}
2888
2889impl From<&MinaBasePendingCoinbaseUpdateStableV1> for super::pending_coinbase::update::Update {
2890    fn from(value: &MinaBasePendingCoinbaseUpdateStableV1) -> Self {
2891        Self {
2892            action: (&value.action).into(),
2893            coinbase_amount: value.coinbase_amount.clone().into(),
2894        }
2895    }
2896}
2897
2898impl From<&super::pending_coinbase::update::Action>
2899    for MinaBasePendingCoinbaseUpdateActionStableV1
2900{
2901    fn from(value: &super::pending_coinbase::update::Action) -> Self {
2902        use super::pending_coinbase::update::Action;
2903        match value {
2904            Action::None => Self::UpdateNone,
2905            Action::One => Self::UpdateOne,
2906            Action::TwoCoinbaseInFirst => Self::UpdateTwoCoinbaseInFirst,
2907            Action::TwoCoinbaseInSecond => Self::UpdateTwoCoinbaseInSecond,
2908        }
2909    }
2910}
2911
2912impl From<&MinaBasePendingCoinbaseUpdateActionStableV1>
2913    for super::pending_coinbase::update::Action
2914{
2915    fn from(value: &MinaBasePendingCoinbaseUpdateActionStableV1) -> Self {
2916        use MinaBasePendingCoinbaseUpdateActionStableV1::*;
2917        match value {
2918            UpdateNone => Self::None,
2919            UpdateOne => Self::One,
2920            UpdateTwoCoinbaseInFirst => Self::TwoCoinbaseInFirst,
2921            UpdateTwoCoinbaseInSecond => Self::TwoCoinbaseInSecond,
2922        }
2923    }
2924}
2925
2926impl From<&PendingCoinbase> for MinaBasePendingCoinbaseStableV2 {
2927    fn from(value: &PendingCoinbase) -> Self {
2928        let PendingCoinbase {
2929            tree,
2930            pos_list,
2931            new_pos,
2932        } = value;
2933
2934        // NOTE: Same implementation than with `SparseLedger`
2935
2936        MinaBasePendingCoinbaseStableV2 {
2937            tree: {
2938                let value = tree;
2939                assert!(value.hashes_matrix.get(&Address::root()).is_some());
2940
2941                let indexes: Vec<_> = value
2942                    .indexes
2943                    .iter()
2944                    .map(|(id, addr)| {
2945                        let addr = value.indexes.get(id).unwrap();
2946
2947                        let index = addr.to_index();
2948                        let index: mina_p2p_messages::number::UInt64 = index.as_u64().into();
2949
2950                        let id: MinaBasePendingCoinbaseStackIdStableV1 = id.into();
2951
2952                        (id, index)
2953                    })
2954                    .collect();
2955
2956                fn build_tree(
2957                    addr: Address,
2958                    matrix: &HashesMatrix,
2959                    ledger_depth: usize,
2960                    values: &Vec<Stack>,
2961                ) -> MinaBasePendingCoinbaseMerkleTreeVersionedStableV2Tree {
2962                    if addr.length() == ledger_depth {
2963                        let account_index = addr.to_index().as_u64() as usize;
2964
2965                        return match values.get(account_index).cloned() {
2966                            Some(account) => {
2967                                let account: MinaBasePendingCoinbaseStackVersionedStableV1 =
2968                                    (&account).into();
2969                                MinaBasePendingCoinbaseMerkleTreeVersionedStableV2Tree::Account(
2970                                    account,
2971                                )
2972                            }
2973                            None => {
2974                                let hash = matrix.get(&addr).unwrap();
2975                                MinaBasePendingCoinbaseMerkleTreeVersionedStableV2Tree::Hash(
2976                                    to_pending_coinbase_hash(hash),
2977                                )
2978                            }
2979                        };
2980                    }
2981
2982                    let child_left = addr.child_left();
2983                    let child_right = addr.child_right();
2984
2985                    let is_left = matrix.get(&child_left).is_some();
2986                    let is_right = matrix.get(&child_right).is_some();
2987
2988                    if is_left && is_right {
2989                        let hash = matrix.get(&addr).unwrap();
2990                        let left_node = build_tree(child_left, matrix, ledger_depth, values);
2991                        let right_node = build_tree(child_right, matrix, ledger_depth, values);
2992
2993                        MinaBasePendingCoinbaseMerkleTreeVersionedStableV2Tree::Node(
2994                            to_pending_coinbase_hash(hash),
2995                            Box::new(left_node),
2996                            Box::new(right_node),
2997                        )
2998                    } else {
2999                        assert!(!is_left && !is_right);
3000                        let hash = matrix.get(&addr).unwrap();
3001                        MinaBasePendingCoinbaseMerkleTreeVersionedStableV2Tree::Hash(
3002                            to_pending_coinbase_hash(hash),
3003                        )
3004                    }
3005                }
3006
3007                let tree = build_tree(
3008                    Address::root(),
3009                    &value.hashes_matrix,
3010                    value.depth,
3011                    &value.values,
3012                );
3013
3014                let depth: u64 = value.depth.try_into().unwrap();
3015
3016                MinaBasePendingCoinbaseMerkleTreeVersionedStableV2 {
3017                    indexes: indexes.into_iter().collect(),
3018                    depth: depth.into(),
3019                    tree,
3020                }
3021            },
3022            pos_list: pos_list.iter().rev().map(Into::into).collect(),
3023            new_pos: new_pos.into(),
3024        }
3025    }
3026}
3027
3028impl From<&NonStark> for MinaBaseStagedLedgerHashNonSnarkStableV1 {
3029    fn from(value: &NonStark) -> Self {
3030        let NonStark {
3031            ledger_hash,
3032            aux_hash,
3033            pending_coinbase_aux,
3034        } = value;
3035
3036        Self {
3037            ledger_hash: MinaBaseLedgerHash0StableV1(ledger_hash.into()).into(),
3038            aux_hash: mina_p2p_messages::string::ByteString::from(aux_hash.0.as_slice()).into(),
3039            pending_coinbase_aux: mina_p2p_messages::string::ByteString::from(
3040                pending_coinbase_aux.0.as_slice(),
3041            )
3042            .into(),
3043        }
3044    }
3045}
3046
3047impl<F: FieldWitness> From<&StagedLedgerHash<F>> for MinaBaseStagedLedgerHashStableV1 {
3048    fn from(value: &StagedLedgerHash<F>) -> Self {
3049        let StagedLedgerHash {
3050            non_snark,
3051            pending_coinbase_hash,
3052        } = value;
3053
3054        Self {
3055            non_snark: non_snark.into(),
3056            pending_coinbase_hash: MinaBasePendingCoinbaseHashVersionedStableV1(
3057                MinaBasePendingCoinbaseHashBuilderStableV1((*pending_coinbase_hash).into()),
3058            )
3059            .into(),
3060        }
3061    }
3062}
3063
3064impl TryFrom<&MinaBaseStagedLedgerHashNonSnarkStableV1> for NonStark {
3065    type Error = InvalidBigInt;
3066
3067    fn try_from(value: &MinaBaseStagedLedgerHashNonSnarkStableV1) -> Result<Self, Self::Error> {
3068        let MinaBaseStagedLedgerHashNonSnarkStableV1 {
3069            ledger_hash,
3070            aux_hash,
3071            pending_coinbase_aux,
3072        } = value;
3073
3074        Ok(Self {
3075            ledger_hash: ledger_hash.inner().to_field()?,
3076            aux_hash: AuxHash(aux_hash.as_slice().try_into().map_err(|_| InvalidBigInt)?), // TODO: Don't use `InvalidBigInt` here
3077            pending_coinbase_aux: PendingCoinbaseAux(
3078                pending_coinbase_aux
3079                    .as_slice()
3080                    .try_into()
3081                    .map_err(|_| InvalidBigInt)?, // TODO: Don't use `InvalidBigInt` here
3082            ),
3083        })
3084    }
3085}
3086
3087impl<F: FieldWitness> TryFrom<&MinaBaseStagedLedgerHashStableV1> for StagedLedgerHash<F> {
3088    type Error = InvalidBigInt;
3089
3090    fn try_from(value: &MinaBaseStagedLedgerHashStableV1) -> Result<Self, Self::Error> {
3091        let MinaBaseStagedLedgerHashStableV1 {
3092            non_snark,
3093            pending_coinbase_hash,
3094        } = value;
3095
3096        Ok(Self {
3097            non_snark: non_snark.try_into()?,
3098            pending_coinbase_hash: pending_coinbase_hash.inner().to_field()?,
3099        })
3100    }
3101}
3102
3103impl TryFrom<&MinaTransactionTransactionStableV2> for Transaction {
3104    type Error = InvalidBigInt;
3105
3106    fn try_from(value: &MinaTransactionTransactionStableV2) -> Result<Self, Self::Error> {
3107        Ok(match value {
3108            MinaTransactionTransactionStableV2::Command(cmd) => Self::Command(match &**cmd {
3109                MinaBaseUserCommandStableV2::SignedCommand(cmd) => {
3110                    UserCommand::SignedCommand(Box::new(cmd.try_into()?))
3111                }
3112                MinaBaseUserCommandStableV2::ZkappCommand(cmd) => {
3113                    UserCommand::ZkAppCommand(Box::new(cmd.try_into()?))
3114                }
3115            }),
3116            MinaTransactionTransactionStableV2::FeeTransfer(ft) => {
3117                Self::FeeTransfer(ft.try_into()?)
3118            }
3119            MinaTransactionTransactionStableV2::Coinbase(cb) => Self::Coinbase(cb.try_into()?),
3120        })
3121    }
3122}
3123
3124impl TryFrom<&TransactionSnarkWorkTStableV2> for super::scan_state::transaction_snark::work::Work {
3125    type Error = InvalidBigInt;
3126
3127    fn try_from(value: &TransactionSnarkWorkTStableV2) -> Result<Self, Self::Error> {
3128        let TransactionSnarkWorkTStableV2 {
3129            fee,
3130            proofs,
3131            prover,
3132        } = value;
3133
3134        Ok(Self {
3135            fee: fee.into(),
3136            proofs: proofs.try_into()?,
3137            prover: prover.try_into()?,
3138        })
3139    }
3140}
3141
3142impl From<&super::scan_state::transaction_snark::work::Work> for TransactionSnarkWorkTStableV2 {
3143    fn from(value: &super::scan_state::transaction_snark::work::Work) -> Self {
3144        let super::scan_state::transaction_snark::work::Work {
3145            fee,
3146            proofs,
3147            prover,
3148        } = value;
3149
3150        Self {
3151            fee: fee.into(),
3152            proofs: proofs.into(),
3153            prover: prover.into(),
3154        }
3155    }
3156}
3157
3158impl TryFrom<&TransactionSnarkWorkTStableV2Proofs>
3159    for super::scan_state::transaction_snark::OneOrTwo<LedgerProof>
3160{
3161    type Error = InvalidBigInt;
3162
3163    fn try_from(value: &TransactionSnarkWorkTStableV2Proofs) -> Result<Self, Self::Error> {
3164        use super::scan_state::transaction_snark::OneOrTwo::{One, Two};
3165        use TransactionSnarkWorkTStableV2Proofs as B;
3166
3167        Ok(match value {
3168            B::One(proof) => One(proof.try_into()?),
3169            B::Two((p1, p2)) => Two((p1.try_into()?, p2.try_into()?)),
3170        })
3171    }
3172}
3173
3174impl From<&super::scan_state::transaction_snark::OneOrTwo<LedgerProof>>
3175    for TransactionSnarkWorkTStableV2Proofs
3176{
3177    fn from(value: &super::scan_state::transaction_snark::OneOrTwo<LedgerProof>) -> Self {
3178        use super::scan_state::transaction_snark::OneOrTwo as B;
3179        use TransactionSnarkWorkTStableV2Proofs::{One, Two};
3180
3181        match value {
3182            B::One(proof) => One(proof.into()),
3183            B::Two((p1, p2)) => Two((p1.into(), p2.into())),
3184        }
3185    }
3186}
3187
3188impl TryFrom<&StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2B>
3189    for WithStatus<UserCommand>
3190{
3191    type Error = InvalidBigInt;
3192
3193    fn try_from(
3194        value: &StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2B,
3195    ) -> Result<Self, Self::Error> {
3196        let StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2B { data, status } = value;
3197
3198        Ok(Self {
3199            data: data.try_into()?,
3200            status: status.into(),
3201        })
3202    }
3203}
3204
3205impl From<&WithStatus<UserCommand>> for StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2B {
3206    fn from(value: &WithStatus<UserCommand>) -> Self {
3207        let WithStatus { data, status } = value;
3208
3209        Self {
3210            data: data.into(),
3211            status: status.into(),
3212        }
3213    }
3214}
3215
3216impl From<&WithStatus<transaction_logic::valid::UserCommand>>
3217    for StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2B
3218{
3219    fn from(value: &WithStatus<transaction_logic::valid::UserCommand>) -> Self {
3220        let WithStatus { data, status } = value;
3221
3222        Self {
3223            data: (&data.forget_check()).into(),
3224            status: status.into(),
3225        }
3226    }
3227}
3228
3229impl TryFrom<&StagedLedgerDiffDiffFtStableV1> for transaction_logic::CoinbaseFeeTransfer {
3230    type Error = InvalidBigInt;
3231
3232    fn try_from(value: &StagedLedgerDiffDiffFtStableV1) -> Result<Self, Self::Error> {
3233        let StagedLedgerDiffDiffFtStableV1(value) = value;
3234        let MinaBaseCoinbaseFeeTransferStableV1 { receiver_pk, fee } = value;
3235
3236        Ok(Self {
3237            receiver_pk: receiver_pk.try_into()?,
3238            fee: fee.into(),
3239        })
3240    }
3241}
3242
3243impl From<&transaction_logic::CoinbaseFeeTransfer> for StagedLedgerDiffDiffFtStableV1 {
3244    fn from(value: &transaction_logic::CoinbaseFeeTransfer) -> Self {
3245        let transaction_logic::CoinbaseFeeTransfer { receiver_pk, fee } = value;
3246
3247        Self(MinaBaseCoinbaseFeeTransferStableV1 {
3248            receiver_pk: receiver_pk.into(),
3249            fee: fee.into(),
3250        })
3251    }
3252}
3253
3254impl TryFrom<&StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2Coinbase>
3255    for crate::staged_ledger::diff::AtMostTwo<transaction_logic::CoinbaseFeeTransfer>
3256{
3257    type Error = InvalidBigInt;
3258
3259    fn try_from(
3260        value: &StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2Coinbase,
3261    ) -> Result<Self, Self::Error> {
3262        use crate::staged_ledger::diff::AtMostTwo::*;
3263        use StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2Coinbase as B;
3264
3265        let conv = |v: &Option<StagedLedgerDiffDiffFtStableV1>| -> Result<Option<transaction_logic::CoinbaseFeeTransfer>, _> {
3266            match v.as_ref() {
3267                Some(v) => Ok(Some(v.try_into()?)),
3268                None => Ok(None),
3269            }
3270        };
3271
3272        Ok(match value {
3273            B::Zero => Zero,
3274            B::One(one) => One(conv(one)?),
3275            B::Two(twos) => Two(match twos {
3276                Some((one, two)) => Some((one.try_into()?, conv(two)?)),
3277                None => None,
3278            }),
3279        })
3280    }
3281}
3282
3283impl From<&crate::staged_ledger::diff::AtMostTwo<transaction_logic::CoinbaseFeeTransfer>>
3284    for StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2Coinbase
3285{
3286    fn from(
3287        value: &crate::staged_ledger::diff::AtMostTwo<transaction_logic::CoinbaseFeeTransfer>,
3288    ) -> Self {
3289        use crate::staged_ledger::diff::AtMostTwo as B;
3290        use StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2Coinbase::*;
3291
3292        match value {
3293            B::Zero => Zero,
3294            B::One(one) => One(one.as_ref().map(Into::into)),
3295            B::Two(twos) => Two(twos
3296                .as_ref()
3297                .map(|(one, two)| (one.into(), two.as_ref().map(Into::into)))),
3298        }
3299    }
3300}
3301
3302impl TryFrom<&StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2>
3303    for crate::staged_ledger::diff::PreDiffWithAtMostTwoCoinbase
3304{
3305    type Error = InvalidBigInt;
3306
3307    fn try_from(
3308        value: &StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2,
3309    ) -> Result<Self, Self::Error> {
3310        let StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2 {
3311            completed_works,
3312            commands,
3313            coinbase,
3314            internal_command_statuses,
3315        } = value;
3316
3317        Ok(Self {
3318            completed_works: completed_works
3319                .iter()
3320                .map(TryInto::try_into)
3321                .collect::<Result<_, _>>()?,
3322            commands: commands
3323                .iter()
3324                .map(TryInto::try_into)
3325                .collect::<Result<_, _>>()?,
3326            coinbase: coinbase.try_into()?,
3327            internal_command_statuses: internal_command_statuses.iter().map(Into::into).collect(),
3328        })
3329    }
3330}
3331
3332impl From<&crate::staged_ledger::diff::PreDiffWithAtMostTwoCoinbase>
3333    for StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2
3334{
3335    fn from(value: &crate::staged_ledger::diff::PreDiffWithAtMostTwoCoinbase) -> Self {
3336        let crate::staged_ledger::diff::PreDiffWithAtMostTwoCoinbase {
3337            completed_works,
3338            commands,
3339            coinbase,
3340            internal_command_statuses,
3341        } = value;
3342
3343        Self {
3344            completed_works: completed_works.iter().map(Into::into).collect(),
3345            commands: commands.iter().map(Into::into).collect(),
3346            coinbase: coinbase.into(),
3347            internal_command_statuses: internal_command_statuses.iter().map(Into::into).collect(),
3348        }
3349    }
3350}
3351
3352impl
3353    From<
3354        &crate::staged_ledger::diff::PreDiffTwo<
3355            crate::scan_state::scan_state::transaction_snark::work::Work,
3356            WithStatus<transaction_logic::valid::UserCommand>,
3357        >,
3358    > for StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2
3359{
3360    fn from(
3361        value: &crate::staged_ledger::diff::PreDiffTwo<
3362            crate::scan_state::scan_state::transaction_snark::work::Work,
3363            WithStatus<transaction_logic::valid::UserCommand>,
3364        >,
3365    ) -> Self {
3366        let crate::staged_ledger::diff::PreDiffTwo {
3367            completed_works,
3368            commands,
3369            coinbase,
3370            internal_command_statuses,
3371        } = value;
3372
3373        Self {
3374            completed_works: completed_works.iter().map(Into::into).collect(),
3375            commands: commands.iter().map(Into::into).collect(),
3376            coinbase: coinbase.into(),
3377            internal_command_statuses: internal_command_statuses.iter().map(Into::into).collect(),
3378        }
3379    }
3380}
3381
3382impl TryFrom<&StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2Coinbase>
3383    for crate::staged_ledger::diff::AtMostOne<transaction_logic::CoinbaseFeeTransfer>
3384{
3385    type Error = InvalidBigInt;
3386
3387    fn try_from(
3388        value: &StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2Coinbase,
3389    ) -> Result<Self, Self::Error> {
3390        use crate::staged_ledger::diff::AtMostOne::*;
3391        use StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2Coinbase as B;
3392
3393        Ok(match value {
3394            B::Zero => Zero,
3395            B::One(one) => One(match one.as_ref() {
3396                Some(one) => Some(one.try_into()?),
3397                None => None,
3398            }),
3399        })
3400    }
3401}
3402
3403impl From<&crate::staged_ledger::diff::AtMostOne<transaction_logic::CoinbaseFeeTransfer>>
3404    for StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2Coinbase
3405{
3406    fn from(
3407        value: &crate::staged_ledger::diff::AtMostOne<transaction_logic::CoinbaseFeeTransfer>,
3408    ) -> Self {
3409        use crate::staged_ledger::diff::AtMostOne as B;
3410        use StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2Coinbase::*;
3411
3412        match value {
3413            B::Zero => Zero,
3414            B::One(one) => One(one.as_ref().map(Into::into)),
3415        }
3416    }
3417}
3418
3419impl TryFrom<&StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2>
3420    for crate::staged_ledger::diff::PreDiffWithAtMostOneCoinbase
3421{
3422    type Error = InvalidBigInt;
3423
3424    fn try_from(
3425        value: &StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2,
3426    ) -> Result<Self, Self::Error> {
3427        let StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2 {
3428            completed_works,
3429            commands,
3430            coinbase,
3431            internal_command_statuses,
3432        } = value;
3433
3434        Ok(Self {
3435            completed_works: completed_works
3436                .iter()
3437                .map(TryInto::try_into)
3438                .collect::<Result<_, _>>()?,
3439            commands: commands
3440                .iter()
3441                .map(TryInto::try_into)
3442                .collect::<Result<_, _>>()?,
3443            coinbase: coinbase.try_into()?,
3444            internal_command_statuses: internal_command_statuses.iter().map(Into::into).collect(),
3445        })
3446    }
3447}
3448
3449impl From<&crate::staged_ledger::diff::PreDiffWithAtMostOneCoinbase>
3450    for StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2
3451{
3452    fn from(value: &crate::staged_ledger::diff::PreDiffWithAtMostOneCoinbase) -> Self {
3453        let crate::staged_ledger::diff::PreDiffOne {
3454            completed_works,
3455            commands,
3456            coinbase,
3457            internal_command_statuses,
3458        } = value;
3459
3460        Self {
3461            completed_works: completed_works.iter().map(Into::into).collect(),
3462            commands: commands.iter().map(Into::into).collect(),
3463            coinbase: coinbase.into(),
3464            internal_command_statuses: internal_command_statuses.iter().map(Into::into).collect(),
3465        }
3466    }
3467}
3468
3469impl
3470    From<
3471        &crate::staged_ledger::diff::PreDiffOne<
3472            crate::scan_state::scan_state::transaction_snark::work::Work,
3473            WithStatus<transaction_logic::valid::UserCommand>,
3474        >,
3475    > for StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2
3476{
3477    fn from(
3478        value: &crate::staged_ledger::diff::PreDiffOne<
3479            crate::scan_state::scan_state::transaction_snark::work::Work,
3480            WithStatus<transaction_logic::valid::UserCommand>,
3481        >,
3482    ) -> Self {
3483        let crate::staged_ledger::diff::PreDiffOne {
3484            completed_works,
3485            commands,
3486            coinbase,
3487            internal_command_statuses,
3488        } = value;
3489
3490        Self {
3491            completed_works: completed_works.iter().map(Into::into).collect(),
3492            commands: commands.iter().map(Into::into).collect(),
3493            coinbase: coinbase.into(),
3494            internal_command_statuses: internal_command_statuses.iter().map(Into::into).collect(),
3495        }
3496    }
3497}
3498
3499impl TryFrom<&StagedLedgerDiffDiffStableV2> for crate::staged_ledger::diff::Diff {
3500    type Error = InvalidBigInt;
3501
3502    fn try_from(value: &StagedLedgerDiffDiffStableV2) -> Result<Self, Self::Error> {
3503        let StagedLedgerDiffDiffStableV2 { diff } = value;
3504        let StagedLedgerDiffDiffDiffStableV2(first, second) = diff;
3505
3506        Ok(Self {
3507            diff: (
3508                first.try_into()?,
3509                match second.as_ref() {
3510                    Some(second) => Some(second.try_into()?),
3511                    None => None,
3512                },
3513            ),
3514        })
3515    }
3516}
3517
3518impl From<&crate::staged_ledger::diff::with_valid_signatures_and_proofs::Diff>
3519    for StagedLedgerDiffDiffStableV2
3520{
3521    fn from(value: &crate::staged_ledger::diff::with_valid_signatures_and_proofs::Diff) -> Self {
3522        let (first, second) = &value.diff;
3523
3524        StagedLedgerDiffDiffStableV2 {
3525            diff: StagedLedgerDiffDiffDiffStableV2(first.into(), second.as_ref().map(Into::into)),
3526        }
3527    }
3528}
3529
3530impl From<&MinaNumbersGlobalSlotSinceGenesisMStableV1> for Slot {
3531    fn from(value: &MinaNumbersGlobalSlotSinceGenesisMStableV1) -> Self {
3532        let MinaNumbersGlobalSlotSinceGenesisMStableV1::SinceGenesis(slot) = value;
3533        Self(slot.as_u32())
3534    }
3535}
3536
3537impl From<&MinaNumbersGlobalSlotSinceHardForkMStableV1> for Slot {
3538    fn from(value: &MinaNumbersGlobalSlotSinceHardForkMStableV1) -> Self {
3539        let MinaNumbersGlobalSlotSinceHardForkMStableV1::SinceHardFork(slot) = value;
3540        Self(slot.as_u32())
3541    }
3542}
3543
3544impl From<&MinaNumbersGlobalSlotSpanStableV1> for SlotSpan {
3545    fn from(value: &MinaNumbersGlobalSlotSpanStableV1) -> Self {
3546        let MinaNumbersGlobalSlotSpanStableV1::GlobalSlotSpan(slot) = value;
3547        Self(slot.as_u32())
3548    }
3549}
3550
3551impl From<&Slot> for MinaNumbersGlobalSlotSinceGenesisMStableV1 {
3552    fn from(value: &Slot) -> Self {
3553        Self::SinceGenesis(value.as_u32().into())
3554    }
3555}
3556
3557impl From<&Slot> for MinaNumbersGlobalSlotSinceHardForkMStableV1 {
3558    fn from(value: &Slot) -> Self {
3559        Self::SinceHardFork(value.as_u32().into())
3560    }
3561}
3562
3563impl From<&SlotSpan> for MinaNumbersGlobalSlotSpanStableV1 {
3564    fn from(value: &SlotSpan) -> Self {
3565        Self::GlobalSlotSpan(value.as_u32().into())
3566    }
3567}
3568
3569impl From<&ZkappStatement> for v2::MinaBaseZkappStatementStableV2 {
3570    fn from(value: &ZkappStatement) -> Self {
3571        use transaction_logic::zkapp_statement::TransactionCommitment;
3572
3573        let ZkappStatement {
3574            account_update: TransactionCommitment(account_update),
3575            calls: TransactionCommitment(calls),
3576        } = value;
3577
3578        v2::MinaBaseZkappStatementStableV2 {
3579            account_update: account_update.into(),
3580            calls: calls.into(),
3581        }
3582    }
3583}
3584
3585impl TryFrom<&v2::MinaBaseZkappStatementStableV2> for ZkappStatement {
3586    type Error = InvalidBigInt;
3587
3588    fn try_from(value: &v2::MinaBaseZkappStatementStableV2) -> Result<Self, Self::Error> {
3589        use transaction_logic::zkapp_statement::TransactionCommitment;
3590
3591        let v2::MinaBaseZkappStatementStableV2 {
3592            account_update,
3593            calls,
3594        } = value;
3595
3596        Ok(ZkappStatement {
3597            account_update: TransactionCommitment(account_update.to_field()?),
3598            calls: TransactionCommitment(calls.to_field()?),
3599        })
3600    }
3601}