@@ -8,7 +8,7 @@ use frame_support::traits::Currency;
88use frame_system:: { self as system} ;
99use scale_info:: TypeInfo ;
1010use sp_runtime:: RuntimeDebug ;
11- use sp_std:: { collections:: btree_map:: BTreeMap , prelude:: * } ;
11+ use sp_std:: { collections:: btree_map:: BTreeMap , ops :: Add , prelude:: * } ;
1212
1313pub mod pallet;
1414pub mod traits;
@@ -17,6 +17,7 @@ pub use traits::*;
1717
1818#[ cfg( any( feature = "runtime-benchmarks" ) ) ]
1919pub mod benchmarking;
20+ pub mod migrations;
2021#[ cfg( test) ]
2122mod mock;
2223#[ cfg( test) ]
@@ -58,10 +59,12 @@ impl Default for Forcing {
5859
5960/// A record for total rewards and total amount staked for an era
6061#[ derive( PartialEq , Eq , Clone , Default , Encode , Decode , RuntimeDebug , TypeInfo ) ]
61- pub struct EraRewardAndStake < Balance > {
62+ pub struct EraRewardAndStake < Balance : HasCompact > {
6263 /// Total amount of rewards for an era
64+ #[ codec( compact) ]
6365 rewards : Balance ,
6466 /// Total staked amount for an era
67+ #[ codec( compact) ]
6568 staked : Balance ,
6669}
6770
@@ -71,11 +74,134 @@ pub struct EraRewardAndStake<Balance> {
7174#[ derive( Clone , PartialEq , Encode , Decode , Default , RuntimeDebug , TypeInfo ) ]
7275pub struct EraStakingPoints < AccountId : Ord , Balance : HasCompact > {
7376 /// Total staked amount.
77+ #[ codec( compact) ]
7478 total : Balance ,
7579 /// The map of stakers and the amount they staked.
7680 stakers : BTreeMap < AccountId , Balance > ,
77- // TODO: Get rid of this
78- _former_staked_era : EraIndex ,
7981 /// Accrued and claimed rewards on this contract both for stakers and the developer
82+ #[ codec( compact) ]
8083 claimed_rewards : Balance ,
8184}
85+
86+ /// Storage value representing the current Dapps staking pallet storage version.
87+ /// Used by `on_runtime_upgrade` to determine whether a storage migration is needed or not.
88+ #[ derive( Encode , Decode , Clone , Copy , PartialEq , Eq , RuntimeDebug , TypeInfo ) ]
89+ pub enum Version {
90+ V1_0_0 ,
91+ V2_0_0 ,
92+ }
93+
94+ impl Default for Version {
95+ fn default ( ) -> Self {
96+ Version :: V1_0_0
97+ }
98+ }
99+
100+ /// Represents an balance amount undergoing the unbonding process.
101+ /// Since unbonding takes time, it's important to keep track of when and how much was unbonded.
102+ #[ derive( Clone , Copy , PartialEq , Encode , Decode , Default , RuntimeDebug , TypeInfo ) ]
103+ pub struct UnlockingChunk < Balance > {
104+ /// Amount being unlocked
105+ #[ codec( compact) ]
106+ amount : Balance ,
107+ /// Era in which the amount will become unlocked and can be withdrawn.
108+ #[ codec( compact) ]
109+ unlock_era : EraIndex ,
110+ }
111+
112+ impl < Balance > UnlockingChunk < Balance >
113+ where
114+ Balance : Add < Output = Balance > + Copy ,
115+ {
116+ // Adds the specified amount to this chunk
117+ fn add_amount ( & mut self , amount : Balance ) {
118+ self . amount = self . amount + amount
119+ }
120+ }
121+
122+ /// Contains unlocking chunks.
123+ /// This is a convenience struct that provides various utility methods to help with unbonding handling.
124+ #[ derive( Clone , PartialEq , Encode , Decode , Default , RuntimeDebug , TypeInfo ) ]
125+ pub struct UnbondingInfo < Balance > {
126+ // Vector of unlocking chunks. Sorted in ascending order in respect to unlock_era.
127+ unlocking_chunks : Vec < UnlockingChunk < Balance > > ,
128+ }
129+
130+ impl < Balance > UnbondingInfo < Balance >
131+ where
132+ Balance : Add < Output = Balance > + Default + Copy ,
133+ {
134+ /// Returns total number of unlocking chunks.
135+ fn len ( & self ) -> u32 {
136+ self . unlocking_chunks . len ( ) as u32
137+ }
138+
139+ /// True if no unlocking chunks exist, false otherwise.
140+ fn is_empty ( & self ) -> bool {
141+ self . unlocking_chunks . is_empty ( )
142+ }
143+
144+ /// Returns sum of all unlocking chunks.
145+ fn sum ( & self ) -> Balance {
146+ self . unlocking_chunks
147+ . iter ( )
148+ . map ( |chunk| chunk. amount )
149+ . reduce ( |c1, c2| c1 + c2)
150+ . unwrap_or_default ( )
151+ }
152+
153+ /// Adds a new unlocking chunk to the vector, preserving the unlock_era based ordering.
154+ fn add ( & mut self , chunk : UnlockingChunk < Balance > ) {
155+ // It is possible that the unbonding period changes so we need to account for that
156+ match self
157+ . unlocking_chunks
158+ . binary_search_by ( |x| x. unlock_era . cmp ( & chunk. unlock_era ) )
159+ {
160+ // Merge with existing chunk if unlock_eras match
161+ Ok ( pos) => self . unlocking_chunks [ pos] . add_amount ( chunk. amount ) ,
162+ // Otherwise insert where it should go. Note that this will in almost all cases return the last index.
163+ Err ( pos) => self . unlocking_chunks . insert ( pos, chunk) ,
164+ }
165+ }
166+
167+ /// Partitions the unlocking chunks into two groups:
168+ ///
169+ /// First group includes all chunks which have unlock era lesser or equal to the specified era.
170+ /// Second group includes all the rest.
171+ ///
172+ /// Order of chunks is preserved in the two new structs.
173+ fn partition ( self , era : EraIndex ) -> ( Self , Self ) {
174+ let ( matching_chunks, other_chunks) : (
175+ Vec < UnlockingChunk < Balance > > ,
176+ Vec < UnlockingChunk < Balance > > ,
177+ ) = self
178+ . unlocking_chunks
179+ . iter ( )
180+ . partition ( |chunk| chunk. unlock_era <= era) ;
181+
182+ (
183+ Self {
184+ unlocking_chunks : matching_chunks,
185+ } ,
186+ Self {
187+ unlocking_chunks : other_chunks,
188+ } ,
189+ )
190+ }
191+
192+ #[ cfg( test) ]
193+ /// Return clone of the internal vector. Should only be used for testing.
194+ fn vec ( & self ) -> Vec < UnlockingChunk < Balance > > {
195+ self . unlocking_chunks . clone ( )
196+ }
197+ }
198+
199+ /// Contains information about account's locked & unbonding balances.
200+ #[ derive( Clone , PartialEq , Encode , Decode , Default , RuntimeDebug , TypeInfo ) ]
201+ pub struct AccountLedger < Balance : HasCompact > {
202+ /// Total balance locked.
203+ #[ codec( compact) ]
204+ locked : Balance ,
205+ /// Information about unbonding chunks.
206+ unbonding_info : UnbondingInfo < Balance > ,
207+ }
0 commit comments