@@ -20,20 +20,45 @@ import (
2020 "net/http"
2121
2222 "github.com/ChainSafe/gossamer/lib/common"
23+ "github.com/ChainSafe/gossamer/lib/crypto/ed25519"
2324)
2425
2526// GrandpaModule init parameters
2627type GrandpaModule struct {
27- blockAPI BlockAPI
28+ blockAPI BlockAPI
29+ blockFinalityAPI BlockFinalityAPI
2830}
2931
3032// NewGrandpaModule creates a new Grandpa rpc module.
31- func NewGrandpaModule (api BlockAPI ) * GrandpaModule {
33+ func NewGrandpaModule (api BlockAPI , finalityAPI BlockFinalityAPI ) * GrandpaModule {
3234 return & GrandpaModule {
33- blockAPI : api ,
35+ blockAPI : api ,
36+ blockFinalityAPI : finalityAPI ,
3437 }
3538}
3639
40+ // Votes struct formats rpc call
41+ type Votes struct {
42+ CurrentWeight uint32 `json:"currentWeight"`
43+ Missing []string `json:"missing"`
44+ }
45+
46+ // RoundState json format for roundState RPC call
47+ type RoundState struct {
48+ Round uint32 `json:"round"`
49+ TotalWeight uint32 `json:"totalWeight"`
50+ ThresholdWeight uint32 `json:"thresholdWeight"`
51+ Prevotes Votes `json:"prevotes"`
52+ Precommits Votes `json:"precommits"`
53+ }
54+
55+ // RoundStateResponse response to roundState RPC call
56+ type RoundStateResponse struct {
57+ SetID uint32 `json:"setId"`
58+ Best RoundState `json:"best"`
59+ Background []RoundState `json:"background"`
60+ }
61+
3762// ProveFinalityRequest request struct
3863type ProveFinalityRequest struct {
3964 blockHashStart common.Hash
@@ -71,3 +96,84 @@ func (gm *GrandpaModule) ProveFinality(r *http.Request, req *ProveFinalityReques
7196
7297 return nil
7398}
99+
100+ // RoundState returns the state of the current best round state as well as the ongoing background rounds.
101+ func (gm * GrandpaModule ) RoundState (r * http.Request , req * EmptyRequest , res * RoundStateResponse ) error {
102+ voters := gm .blockFinalityAPI .GetVoters ()
103+ votersPkBytes := make ([]ed25519.PublicKeyBytes , len (voters ))
104+ for i , v := range voters {
105+ votersPkBytes [i ] = v .PublicKeyBytes ()
106+ }
107+
108+ votes := gm .blockFinalityAPI .PreVotes ()
109+ commits := gm .blockFinalityAPI .PreCommits ()
110+
111+ missingPrevotes , err := toAddress (difference (votersPkBytes , votes ))
112+ if err != nil {
113+ return err
114+ }
115+
116+ missingPrecommits , err := toAddress (difference (votersPkBytes , commits ))
117+ if err != nil {
118+ return err
119+ }
120+
121+ totalWeight := uint32 (len (voters ))
122+ roundstate := RoundStateResponse {
123+ SetID : uint32 (gm .blockFinalityAPI .GetSetID ()),
124+ Best : RoundState {
125+ Round : uint32 (gm .blockFinalityAPI .GetRound ()),
126+ ThresholdWeight : thresholdWeight (totalWeight ),
127+ TotalWeight : totalWeight ,
128+ Prevotes : Votes {
129+ CurrentWeight : uint32 (len (votes )),
130+ Missing : missingPrevotes ,
131+ },
132+ Precommits : Votes {
133+ CurrentWeight : uint32 (len (commits )),
134+ Missing : missingPrecommits ,
135+ },
136+ },
137+ Background : []RoundState {},
138+ }
139+
140+ * res = roundstate
141+ return nil
142+ }
143+
144+ func thresholdWeight (totalWeight uint32 ) uint32 {
145+ return totalWeight * 2 / 3
146+ }
147+
148+ // difference get the values representing the difference, i.e., the values that are in voters but not in pre.
149+ // this function returns the authorities that haven't voted yet
150+ func difference (voters , equivocations []ed25519.PublicKeyBytes ) []ed25519.PublicKeyBytes {
151+ diff := make ([]ed25519.PublicKeyBytes , 0 )
152+ diffmap := make (map [ed25519.PublicKeyBytes ]bool , len (voters ))
153+
154+ for _ , eq := range equivocations {
155+ diffmap [eq ] = true
156+ }
157+
158+ for _ , v := range voters {
159+ if _ , ok := diffmap [v ]; ! ok {
160+ diff = append (diff , v )
161+ }
162+ }
163+
164+ return diff
165+ }
166+
167+ func toAddress (pkb []ed25519.PublicKeyBytes ) ([]string , error ) {
168+ addrs := make ([]string , len (pkb ))
169+ for i , b := range pkb {
170+ pk , err := ed25519 .NewPublicKey (b [:])
171+ if err != nil {
172+ return nil , err
173+ }
174+
175+ addrs [i ] = string (pk .Address ())
176+ }
177+
178+ return addrs , nil
179+ }
0 commit comments