@@ -7,10 +7,13 @@ import (
7
7
8
8
"github.com/filecoin-project/go-bitfield"
9
9
rlepluslazy "github.com/filecoin-project/go-bitfield/rle"
10
+ "github.com/filecoin-project/go-f3/certs"
10
11
"github.com/filecoin-project/go-f3/gpbft"
11
12
"github.com/ipfs/go-cid"
12
13
)
13
14
15
+ const maxSingers = 1 << 16
16
+
14
17
var emptyCommitments [32 ]byte
15
18
16
19
type Message struct {
@@ -50,6 +53,23 @@ type TipSet struct {
50
53
PowerTable string `json:"PowerTable"`
51
54
}
52
55
56
+ type FinalityCertificate struct {
57
+ Timestamp time.Time `json:"Timestamp"`
58
+ NetworkName string `json:"NetworkName"`
59
+ Instance uint64 `json:"Instance"`
60
+ ECChain []TipSet `json:"Value"`
61
+ SupplementalData SupplementalData `json:"SupplementalData"`
62
+ Signers []uint64 `json:"Signers"`
63
+ Signature []byte `json:"Signature"`
64
+ PowerTableDelta []PowerTableDelta `json:"PowerTableDelta"`
65
+ }
66
+
67
+ type PowerTableDelta struct {
68
+ ParticipantID uint64 `json:"ParticipantID"`
69
+ PowerDelta int64 `json:"PowerDelta"`
70
+ SigningKey []byte `json:"SigningKey"`
71
+ }
72
+
53
73
func newMessage (timestamp time.Time , nn string , msg gpbft.PartialGMessage ) (* Message , error ) {
54
74
j , err := newJustification (msg .Justification )
55
75
if err != nil {
@@ -71,7 +91,6 @@ func newJustification(gj *gpbft.Justification) (*Justification, error) {
71
91
if gj == nil {
72
92
return nil , nil
73
93
}
74
- const maxSingers = 1 << 16
75
94
signers , err := gj .Signers .All (maxSingers )
76
95
if err != nil {
77
96
return nil , err
@@ -84,15 +103,18 @@ func newJustification(gj *gpbft.Justification) (*Justification, error) {
84
103
}
85
104
86
105
func newPayload (gp gpbft.Payload ) Payload {
87
- var commitments []byte
88
- if gp .SupplementalData .Commitments != emptyCommitments {
89
- // Currently, all Commitments are always empty. For completeness and reducing
90
- // future schema changes include them anyway when they are non-empty.
91
- commitments = gp .SupplementalData .Commitments [:]
106
+ return Payload {
107
+ Instance : gp .Instance ,
108
+ Round : gp .Round ,
109
+ Phase : gp .Phase .String (),
110
+ SupplementalData : supplementalDataFromGpbft (gp .SupplementalData ),
111
+ Value : tipsetsFromGpbft (gp .Value ),
92
112
}
113
+ }
93
114
94
- value := make ([]TipSet , gp .Value .Len ())
95
- for i , v := range gp .Value .TipSets {
115
+ func tipsetsFromGpbft (chain * gpbft.ECChain ) []TipSet {
116
+ value := make ([]TipSet , chain .Len ())
117
+ for i , v := range chain .TipSets {
96
118
value [i ] = TipSet {
97
119
Epoch : v .Epoch ,
98
120
Key : v .Key ,
@@ -102,15 +124,19 @@ func newPayload(gp gpbft.Payload) Payload {
102
124
value [i ].Commitments = v .Commitments [:]
103
125
}
104
126
}
105
- return Payload {
106
- Instance : gp .Instance ,
107
- Round : gp .Round ,
108
- Phase : gp .Phase .String (),
109
- SupplementalData : SupplementalData {
110
- Commitments : commitments ,
111
- PowerTable : gp .SupplementalData .PowerTable .String (),
112
- },
113
- Value : value ,
127
+ return value
128
+ }
129
+
130
+ func supplementalDataFromGpbft (sd gpbft.SupplementalData ) SupplementalData {
131
+ var commitments []byte
132
+ if sd .Commitments != emptyCommitments {
133
+ // Currently, all Commitments are always empty. For completeness and reducing
134
+ // future schema changes include them anyway when they are non-empty.
135
+ commitments = sd .Commitments [:]
136
+ }
137
+ return SupplementalData {
138
+ Commitments : commitments ,
139
+ PowerTable : sd .PowerTable .String (),
114
140
}
115
141
}
116
142
@@ -249,3 +275,43 @@ func phaseFromString(phase string) (gpbft.Phase, error) {
249
275
return 0 , fmt .Errorf ("unknown phase: %s" , phase )
250
276
}
251
277
}
278
+
279
+ func newFinalityCertificate (timestamp time.Time , nn gpbft.NetworkName , cert * certs.FinalityCertificate ) (* FinalityCertificate , error ) {
280
+ if cert == nil {
281
+ return nil , fmt .Errorf ("cannot create FinalityCertificate with nil cert" )
282
+ }
283
+
284
+ signers , err := cert .Signers .All (maxSingers )
285
+ if err != nil {
286
+ return nil , fmt .Errorf ("failed to list finality certificate signers: %w" , err )
287
+ }
288
+
289
+ deltas , err := powerTableDeltaFromGpbft (cert .PowerTableDelta )
290
+ if err != nil {
291
+ return nil , fmt .Errorf ("failed to convert finality certificate power table delta: %w" , err )
292
+ }
293
+
294
+ return & FinalityCertificate {
295
+ Timestamp : timestamp ,
296
+ NetworkName : string (nn ),
297
+ Instance : cert .GPBFTInstance ,
298
+ ECChain : tipsetsFromGpbft (cert .ECChain ),
299
+ SupplementalData : supplementalDataFromGpbft (cert .SupplementalData ),
300
+ Signers : signers ,
301
+ Signature : cert .Signature ,
302
+ PowerTableDelta : deltas ,
303
+ }, nil
304
+ }
305
+
306
+ func powerTableDeltaFromGpbft (ptd certs.PowerTableDiff ) ([]PowerTableDelta , error ) {
307
+
308
+ deltas := make ([]PowerTableDelta , len (ptd ))
309
+ for i , delta := range ptd {
310
+ deltas [i ] = PowerTableDelta {
311
+ ParticipantID : uint64 (delta .ParticipantID ),
312
+ PowerDelta : delta .PowerDelta .Int64 (),
313
+ SigningKey : delta .SigningKey ,
314
+ }
315
+ }
316
+ return deltas , nil
317
+ }
0 commit comments