@@ -25,7 +25,10 @@ use codec::{
25
25
Encode ,
26
26
} ;
27
27
use core:: marker:: PhantomData ;
28
- use frame_support:: Parameter ;
28
+ use frame_support:: {
29
+ traits:: LockIdentifier ,
30
+ Parameter ,
31
+ } ;
29
32
use sp_runtime:: traits:: {
30
33
AtLeast32Bit ,
31
34
MaybeSerialize ,
@@ -80,6 +83,47 @@ pub struct TotalIssuanceStore<T: Balances> {
80
83
pub _runtime : PhantomData < T > ,
81
84
}
82
85
86
+ /// The locks of the balances module.
87
+ #[ derive( Clone , Debug , Eq , PartialEq , Store , Encode , Decode ) ]
88
+ pub struct LocksStore < ' a , T : Balances > {
89
+ #[ store( returns = Vec <BalanceLock <T :: Balance >>) ]
90
+ /// Account to retrieve the balance locks for.
91
+ pub account_id : & ' a T :: AccountId ,
92
+ }
93
+
94
+ /// A single lock on a balance. There can be many of these on an account and they "overlap", so the
95
+ /// same balance is frozen by multiple locks.
96
+ #[ derive( Clone , PartialEq , Eq , Encode , Decode ) ]
97
+ pub struct BalanceLock < Balance > {
98
+ /// An identifier for this lock. Only one lock may be in existence for each identifier.
99
+ pub id : LockIdentifier ,
100
+ /// The amount which the free balance may not drop below when this lock is in effect.
101
+ pub amount : Balance ,
102
+ /// If true, then the lock remains in effect even for payment of transaction fees.
103
+ pub reasons : Reasons ,
104
+ }
105
+
106
+ impl < Balance : Debug > Debug for BalanceLock < Balance > {
107
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
108
+ f. debug_struct ( "BalanceLock" )
109
+ . field ( "id" , & String :: from_utf8_lossy ( & self . id ) )
110
+ . field ( "amount" , & self . amount )
111
+ . field ( "reasons" , & self . reasons )
112
+ . finish ( )
113
+ }
114
+ }
115
+
116
+ /// Simplified reasons for withdrawing balance.
117
+ #[ derive( Encode , Decode , Clone , Copy , PartialEq , Eq , Debug ) ]
118
+ pub enum Reasons {
119
+ /// Paying system transaction fees.
120
+ Fee ,
121
+ /// Any reason other than paying system transaction fees.
122
+ Misc ,
123
+ /// Any reason at all.
124
+ All ,
125
+ }
126
+
83
127
/// Transfer some liquid free balance to another account.
84
128
///
85
129
/// `transfer` will set the `FreeBalance` of the sender and receiver.
@@ -181,6 +225,47 @@ mod tests {
181
225
assert_ne ! ( info. data. free, 0 ) ;
182
226
}
183
227
228
+ #[ async_std:: test]
229
+ #[ cfg( feature = "integration-tests" ) ]
230
+ async fn test_state_balance_lock ( ) -> Result < ( ) , crate :: Error > {
231
+ use crate :: {
232
+ frame:: staking:: {
233
+ BondCallExt ,
234
+ RewardDestination ,
235
+ } ,
236
+ runtimes:: KusamaRuntime as RT ,
237
+ ClientBuilder ,
238
+ } ;
239
+
240
+ env_logger:: try_init ( ) . ok ( ) ;
241
+ let bob = PairSigner :: < RT , _ > :: new ( AccountKeyring :: Bob . pair ( ) ) ;
242
+ let client = ClientBuilder :: < RT > :: new ( ) . build ( ) . await ?;
243
+
244
+ client
245
+ . bond_and_watch (
246
+ & bob,
247
+ AccountKeyring :: Charlie . to_account_id ( ) ,
248
+ 100_000_000_000 ,
249
+ RewardDestination :: Stash ,
250
+ )
251
+ . await ?;
252
+
253
+ let locks = client
254
+ . locks ( & AccountKeyring :: Bob . to_account_id ( ) , None )
255
+ . await ?;
256
+
257
+ assert_eq ! (
258
+ locks,
259
+ vec![ BalanceLock {
260
+ id: * b"staking " ,
261
+ amount: 100_000_000_000 ,
262
+ reasons: Reasons :: All ,
263
+ } ]
264
+ ) ;
265
+
266
+ Ok ( ( ) )
267
+ }
268
+
184
269
#[ async_std:: test]
185
270
async fn test_transfer_error ( ) {
186
271
env_logger:: try_init ( ) . ok ( ) ;
0 commit comments