dpp/shielded/builder/
shield_from_asset_lock.rs1use crate::address_funds::OrchardAddress;
2use crate::prelude::AssetLockProof;
3use crate::state_transition::shield_from_asset_lock_transition::methods::ShieldFromAssetLockTransitionMethodsV0;
4use crate::state_transition::shield_from_asset_lock_transition::ShieldFromAssetLockTransition;
5use crate::state_transition::StateTransition;
6use crate::ProtocolError;
7use platform_version::version::PlatformVersion;
8
9use super::{build_output_only_bundle, serialize_authorized_bundle, OrchardProver};
10
11#[allow(clippy::too_many_arguments)]
25pub fn build_shield_from_asset_lock_transition<P: OrchardProver>(
26 recipient: &OrchardAddress,
27 shield_amount: u64,
28 asset_lock_proof: AssetLockProof,
29 asset_lock_private_key: &[u8],
30 prover: &P,
31 memo: [u8; 36],
32 platform_version: &PlatformVersion,
33) -> Result<StateTransition, ProtocolError> {
34 let bundle = build_output_only_bundle(recipient, shield_amount, memo, prover)?;
35 let sb = serialize_authorized_bundle(&bundle);
36
37 let value_balance = sb
40 .value_balance
41 .checked_neg()
42 .and_then(|v| u64::try_from(v).ok())
43 .ok_or_else(|| {
44 ProtocolError::ShieldedBuildError(
45 "shield_from_asset_lock: bundle value_balance is not negative".to_string(),
46 )
47 })?;
48
49 ShieldFromAssetLockTransition::try_from_asset_lock_with_bundle(
50 asset_lock_proof,
51 asset_lock_private_key,
52 sb.actions,
53 value_balance,
54 sb.anchor,
55 sb.proof,
56 sb.binding_signature,
57 platform_version,
58 )
59}
60
61#[cfg(test)]
62mod tests {
63 use super::super::{build_output_only_bundle, serialize_authorized_bundle};
64 use crate::shielded::builder::test_helpers::{test_orchard_address, TestProver};
65
66 #[test]
70 fn test_output_only_bundle_value_balance_is_negative() {
71 let recipient = test_orchard_address();
72 let amount = 50_000u64;
73
74 let bundle = build_output_only_bundle(&recipient, amount, [0u8; 36], &TestProver)
75 .expect("bundle should build successfully");
76 let sb = serialize_authorized_bundle(&bundle);
77
78 assert!(
80 sb.value_balance < 0,
81 "expected negative value_balance, got {}",
82 sb.value_balance
83 );
84
85 let abs_balance = sb
87 .value_balance
88 .checked_neg()
89 .and_then(|v| u64::try_from(v).ok())
90 .expect("value_balance should be safely negatable");
91 assert_eq!(abs_balance, amount);
92 }
93}