@@ -23,9 +23,9 @@ extern crate alloc;
23
23
24
24
#[ cfg( feature = "std" ) ]
25
25
use serde:: Serialize ;
26
- use codec:: { Encode , Decode , Codec } ;
26
+ use codec:: { Encode , Decode , Input , Codec } ;
27
27
use sr_primitives:: { ConsensusEngineId , RuntimeDebug } ;
28
- use client :: decl_runtime_apis ;
28
+ use rstd :: borrow :: Cow ;
29
29
use rstd:: vec:: Vec ;
30
30
31
31
mod app {
@@ -46,6 +46,10 @@ pub type AuthoritySignature = app::Signature;
46
46
/// The `ConsensusEngineId` of GRANDPA.
47
47
pub const GRANDPA_ENGINE_ID : ConsensusEngineId = * b"FRNK" ;
48
48
49
+ /// The storage key for the current set of weighted Grandpa authorities.
50
+ /// The value stored is an encoded VersionedAuthorityList.
51
+ pub const GRANDPA_AUTHORITIES_KEY : & ' static [ u8 ] = b":grandpa_authorities" ;
52
+
49
53
/// The weight of an authority.
50
54
pub type AuthorityWeight = u64 ;
51
55
@@ -58,12 +62,15 @@ pub type SetId = u64;
58
62
/// The round indicator.
59
63
pub type RoundNumber = u64 ;
60
64
65
+ /// A list of Grandpa authorities with associated weights.
66
+ pub type AuthorityList = Vec < ( AuthorityId , AuthorityWeight ) > ;
67
+
61
68
/// A scheduled change of authority set.
62
69
#[ cfg_attr( feature = "std" , derive( Serialize ) ) ]
63
70
#[ derive( Clone , Eq , PartialEq , Encode , Decode , RuntimeDebug ) ]
64
71
pub struct ScheduledChange < N > {
65
72
/// The new authorities after the change, along with their respective weights.
66
- pub next_authorities : Vec < ( AuthorityId , AuthorityWeight ) > ,
73
+ pub next_authorities : AuthorityList ,
67
74
/// The number of blocks to delay.
68
75
pub delay : N ,
69
76
}
@@ -154,24 +161,51 @@ pub const PENDING_CHANGE_CALL: &str = "grandpa_pending_change";
154
161
/// WASM function call to get current GRANDPA authorities.
155
162
pub const AUTHORITIES_CALL : & str = "grandpa_authorities" ;
156
163
157
- decl_runtime_apis ! {
158
- /// APIs for integrating the GRANDPA finality gadget into runtimes.
159
- /// This should be implemented on the runtime side.
160
- ///
161
- /// This is primarily used for negotiating authority-set changes for the
162
- /// gadget. GRANDPA uses a signaling model of changing authority sets:
163
- /// changes should be signaled with a delay of N blocks, and then automatically
164
- /// applied in the runtime after those N blocks have passed.
165
- ///
166
- /// The consensus protocol will coordinate the handoff externally.
167
- #[ api_version( 2 ) ]
168
- pub trait GrandpaApi {
169
- /// Get the current GRANDPA authorities and weights. This should not change except
170
- /// for when changes are scheduled and the corresponding delay has passed.
171
- ///
172
- /// When called at block B, it will return the set of authorities that should be
173
- /// used to finalize descendants of this block (B+1, B+2, ...). The block B itself
174
- /// is finalized by the authorities from block B-1.
175
- fn grandpa_authorities( ) -> Vec <( AuthorityId , AuthorityWeight ) >;
164
+ /// The current version of the stored AuthorityList type. The encoding version MUST be updated any
165
+ /// time the AuthorityList type changes.
166
+ const AUTHORITIES_VERISON : u8 = 1 ;
167
+
168
+ /// An AuthorityList that is encoded with a version specifier. The encoding version is updated any
169
+ /// time the AuthorityList type changes. This ensures that encodings of different versions of an
170
+ /// AuthorityList are differentiable. Attempting to decode an authority list with an unknown
171
+ /// version will fail.
172
+ #[ derive( Default ) ]
173
+ pub struct VersionedAuthorityList < ' a > ( Cow < ' a , AuthorityList > ) ;
174
+
175
+ impl < ' a > From < AuthorityList > for VersionedAuthorityList < ' a > {
176
+ fn from ( authorities : AuthorityList ) -> Self {
177
+ VersionedAuthorityList ( Cow :: Owned ( authorities) )
178
+ }
179
+ }
180
+
181
+ impl < ' a > From < & ' a AuthorityList > for VersionedAuthorityList < ' a > {
182
+ fn from ( authorities : & ' a AuthorityList ) -> Self {
183
+ VersionedAuthorityList ( Cow :: Borrowed ( authorities) )
184
+ }
185
+ }
186
+
187
+ impl < ' a > Into < AuthorityList > for VersionedAuthorityList < ' a > {
188
+ fn into ( self ) -> AuthorityList {
189
+ self . 0 . into_owned ( )
190
+ }
191
+ }
192
+
193
+ impl < ' a > Encode for VersionedAuthorityList < ' a > {
194
+ fn size_hint ( & self ) -> usize {
195
+ ( AUTHORITIES_VERISON , self . 0 . as_ref ( ) ) . size_hint ( )
196
+ }
197
+
198
+ fn using_encoded < R , F : FnOnce ( & [ u8 ] ) -> R > ( & self , f : F ) -> R {
199
+ ( AUTHORITIES_VERISON , self . 0 . as_ref ( ) ) . using_encoded ( f)
200
+ }
201
+ }
202
+
203
+ impl < ' a > Decode for VersionedAuthorityList < ' a > {
204
+ fn decode < I : Input > ( value : & mut I ) -> Result < Self , codec:: Error > {
205
+ let ( version, authorities) : ( u8 , AuthorityList ) = Decode :: decode ( value) ?;
206
+ if version != AUTHORITIES_VERISON {
207
+ return Err ( "unknown Grandpa authorities version" . into ( ) ) ;
208
+ }
209
+ Ok ( authorities. into ( ) )
176
210
}
177
211
}
0 commit comments