1use alloc::vec::Vec;
24use sp_runtime::BoundedVec;
25
26pub const MAX_BUDGET_KEY_LEN: u32 = 32;
28
29pub type BudgetKey = BoundedVec<u8, sp_core::ConstU32<MAX_BUDGET_KEY_LEN>>;
34
35pub trait IssuanceCurve<Balance> {
40 fn issue(total_issuance: Balance, elapsed_millis: u64) -> Balance;
42}
43
44impl<Balance: Default> IssuanceCurve<Balance> for () {
45 fn issue(_total_issuance: Balance, _elapsed_millis: u64) -> Balance {
46 Default::default()
47 }
48}
49
50pub trait BudgetRecipient<AccountId> {
55 fn budget_key() -> BudgetKey;
57 fn pot_account() -> AccountId;
59}
60
61pub trait BudgetRecipientList<AccountId> {
68 fn recipients() -> Vec<(BudgetKey, AccountId)>;
70}
71
72impl<AccountId> BudgetRecipientList<AccountId> for () {
73 fn recipients() -> Vec<(BudgetKey, AccountId)> {
74 Vec::new()
75 }
76}
77
78#[impl_trait_for_tuples::impl_for_tuples(1, 10)]
79#[tuple_types_custom_trait_bound(BudgetRecipient<AccountId>)]
80impl<AccountId> BudgetRecipientList<AccountId> for Tuple {
81 fn recipients() -> Vec<(BudgetKey, AccountId)> {
82 let mut v = Vec::new();
83 for_tuples!( #( v.push((Tuple::budget_key(), Tuple::pot_account())); )* );
84 debug_assert!(
85 {
86 let mut keys: Vec<_> = v.iter().map(|(k, _)| k.clone()).collect();
87 keys.sort();
88 keys.windows(2).all(|w| w[0] != w[1])
89 },
90 "Duplicate BudgetRecipient key detected"
91 );
92 v
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 struct RecipientA;
101 impl BudgetRecipient<u64> for RecipientA {
102 fn budget_key() -> BudgetKey {
103 BudgetKey::truncate_from(b"alpha".to_vec())
104 }
105 fn pot_account() -> u64 {
106 1
107 }
108 }
109
110 struct RecipientB;
111 impl BudgetRecipient<u64> for RecipientB {
112 fn budget_key() -> BudgetKey {
113 BudgetKey::truncate_from(b"beta".to_vec())
114 }
115 fn pot_account() -> u64 {
116 2
117 }
118 }
119
120 struct RecipientDuplicate;
122 impl BudgetRecipient<u64> for RecipientDuplicate {
123 fn budget_key() -> BudgetKey {
124 BudgetKey::truncate_from(b"alpha".to_vec())
125 }
126 fn pot_account() -> u64 {
127 3
128 }
129 }
130
131 #[test]
132 fn unique_keys_work() {
133 let recipients = <(RecipientA, RecipientB) as BudgetRecipientList<u64>>::recipients();
134 assert_eq!(recipients.len(), 2);
135 }
136
137 #[test]
138 #[should_panic(expected = "Duplicate BudgetRecipient key detected")]
139 fn duplicate_keys_panics() {
140 let _ = <(RecipientA, RecipientDuplicate) as BudgetRecipientList<u64>>::recipients();
141 }
142}