mina_tx_type/coinbase.rs
1//! Coinbase transaction types for Mina Protocol.
2//!
3//! This module defines the coinbase transaction structures used for
4//! block rewards and fee transfers in the Mina Protocol.
5//!
6//! # Overview
7//!
8//! In Mina, each block can include a coinbase transaction that:
9//! - Rewards the block producer with newly minted tokens
10//! - Optionally transfers a portion of the reward as a fee to a SNARK worker
11
12use crate::currency::{Amount, Fee, Magnitude};
13use mina_signer::CompressedPubKey;
14
15/// A fee transfer within a coinbase transaction.
16///
17/// When a SNARK worker contributes proofs to a block, they may receive
18/// a portion of the coinbase reward as compensation. This structure
19/// represents that fee transfer.
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct CoinbaseFeeTransfer {
22 receiver_pk: CompressedPubKey,
23 fee: Fee,
24}
25
26impl CoinbaseFeeTransfer {
27 /// Creates a new coinbase fee transfer.
28 ///
29 /// # Arguments
30 ///
31 /// * `receiver_pk` - The compressed public key of the fee recipient
32 /// * `fee` - The fee amount to transfer
33 #[must_use]
34 pub const fn new(receiver_pk: CompressedPubKey, fee: Fee) -> Self {
35 Self { receiver_pk, fee }
36 }
37
38 /// Returns the public key of the fee recipient.
39 #[must_use]
40 pub const fn receiver_pk(&self) -> &CompressedPubKey {
41 &self.receiver_pk
42 }
43
44 /// Returns the fee amount.
45 #[must_use]
46 pub const fn fee(&self) -> Fee {
47 self.fee
48 }
49}
50
51/// A coinbase transaction for block rewards.
52///
53/// The coinbase transaction is included in each block to:
54/// 1. Credit the block producer with the coinbase reward
55/// 2. Optionally transfer a fee to a SNARK worker who contributed proofs
56///
57/// The `amount` represents the total coinbase reward for the block.
58/// If a `fee_transfer` is present, the fee is deducted from the amount
59/// before crediting the receiver.
60#[derive(Debug, Clone, PartialEq, Eq)]
61pub struct Coinbase {
62 receiver: CompressedPubKey,
63 amount: Amount,
64 fee_transfer: Option<CoinbaseFeeTransfer>,
65}
66
67impl Coinbase {
68 /// Creates a new coinbase transaction without a fee transfer.
69 ///
70 /// # Arguments
71 ///
72 /// * `receiver` - The compressed public key of the block producer
73 /// * `amount` - The coinbase reward amount
74 #[must_use]
75 pub const fn new(receiver: CompressedPubKey, amount: Amount) -> Self {
76 Self {
77 receiver,
78 amount,
79 fee_transfer: None,
80 }
81 }
82
83 /// Creates a new coinbase transaction with a fee transfer.
84 ///
85 /// # Arguments
86 ///
87 /// * `receiver` - The compressed public key of the block producer
88 /// * `amount` - The coinbase reward amount
89 /// * `fee_transfer` - The fee transfer to a SNARK worker
90 #[must_use]
91 pub const fn with_fee_transfer(
92 receiver: CompressedPubKey,
93 amount: Amount,
94 fee_transfer: CoinbaseFeeTransfer,
95 ) -> Self {
96 Self {
97 receiver,
98 amount,
99 fee_transfer: Some(fee_transfer),
100 }
101 }
102
103 /// Returns the coinbase receiver (block producer).
104 #[must_use]
105 pub const fn receiver(&self) -> &CompressedPubKey {
106 &self.receiver
107 }
108
109 /// Returns the total coinbase amount.
110 #[must_use]
111 pub const fn amount(&self) -> Amount {
112 self.amount
113 }
114
115 /// Returns the optional fee transfer.
116 #[must_use]
117 pub const fn fee_transfer(&self) -> Option<&CoinbaseFeeTransfer> {
118 self.fee_transfer.as_ref()
119 }
120
121 /// Returns `true` if this coinbase has a fee transfer.
122 #[must_use]
123 pub const fn has_fee_transfer(&self) -> bool {
124 self.fee_transfer.is_some()
125 }
126
127 /// Returns the net amount credited to the block producer.
128 ///
129 /// This is the coinbase amount minus any fee transfer.
130 /// Returns `None` if the fee exceeds the amount (which should not
131 /// happen in valid transactions).
132 #[must_use]
133 pub fn net_amount(&self) -> Option<Amount> {
134 self.fee_transfer.as_ref().map_or(Some(self.amount), |ft| {
135 let fee_as_amount: Amount = ft.fee().into();
136 self.amount.checked_sub(fee_as_amount)
137 })
138 }
139}