@@ -2,6 +2,7 @@ package itests
2
2
3
3
import (
4
4
"context"
5
+ "reflect"
5
6
"sync"
6
7
"testing"
7
8
"time"
@@ -14,10 +15,12 @@ import (
14
15
"golang.org/x/sync/errgroup"
15
16
16
17
"github.com/filecoin-project/go-address"
18
+ "github.com/filecoin-project/go-f3/certs"
17
19
"github.com/filecoin-project/go-f3/gpbft"
18
20
"github.com/filecoin-project/go-f3/manifest"
19
21
"github.com/filecoin-project/go-state-types/abi"
20
22
23
+ "github.com/filecoin-project/lotus/api"
21
24
lotus_api "github.com/filecoin-project/lotus/api"
22
25
"github.com/filecoin-project/lotus/chain/lf3"
23
26
"github.com/filecoin-project/lotus/chain/types"
@@ -57,6 +60,129 @@ func TestF3_Enabled(t *testing.T) {
57
60
e .requireAllMinersParticipate ()
58
61
}
59
62
63
+ // TestF3_Disabled tests the return values and errors of the F3 API when F3 is
64
+ // disabled or is not yet running.
65
+ func TestF3_InactiveModes (t * testing.T ) {
66
+ kit .QuietMiningLogs ()
67
+
68
+ testCases := []struct {
69
+ mode string
70
+ expectedErrors map [string ]any
71
+ expectedValues map [string ]any
72
+ customValidateReturn map [string ]func (t * testing.T , ret []reflect.Value )
73
+ }{
74
+ {
75
+ mode : "disabled" ,
76
+ expectedErrors : map [string ]any {
77
+ "F3GetOrRenewParticipationTicket" : lotus_api .ErrF3Disabled ,
78
+ "F3Participate" : lotus_api .ErrF3Disabled ,
79
+ "F3GetCertificate" : lotus_api .ErrF3Disabled ,
80
+ "F3GetLatestCertificate" : lotus_api .ErrF3Disabled ,
81
+ "F3GetManifest" : lotus_api .ErrF3Disabled ,
82
+ "F3GetECPowerTable" : lotus_api .ErrF3Disabled ,
83
+ "F3GetF3PowerTable" : lotus_api .ErrF3Disabled ,
84
+ "F3IsRunning" : lotus_api .ErrF3Disabled ,
85
+ },
86
+ expectedValues : map [string ]any {
87
+ "F3GetOrRenewParticipationTicket" : (api .F3ParticipationTicket )(nil ),
88
+ "F3Participate" : api.F3ParticipationLease {},
89
+ "F3GetCertificate" : (* certs .FinalityCertificate )(nil ),
90
+ "F3GetLatestCertificate" : (* certs .FinalityCertificate )(nil ),
91
+ "F3GetManifest" : (* manifest .Manifest )(nil ),
92
+ "F3GetECPowerTable" : (gpbft .PowerEntries )(nil ),
93
+ "F3GetF3PowerTable" : (gpbft .PowerEntries )(nil ),
94
+ "F3IsRunning" : false ,
95
+ },
96
+ },
97
+ {
98
+ mode : "not running" ,
99
+ expectedErrors : map [string ]any {
100
+ "F3GetOrRenewParticipationTicket" : api .ErrF3NotReady ,
101
+ "F3Participate" : api .ErrF3NotReady ,
102
+ "F3GetCertificate" : "F3 is not running" ,
103
+ "F3GetLatestCertificate" : "F3 is not running" ,
104
+ "F3GetManifest" : "no known network manifest" ,
105
+ "F3GetF3PowerTable" : "no known network manifest" ,
106
+ },
107
+ expectedValues : map [string ]any {
108
+ "F3GetOrRenewParticipationTicket" : (api .F3ParticipationTicket )(nil ),
109
+ "F3Participate" : api.F3ParticipationLease {},
110
+ "F3GetCertificate" : (* certs .FinalityCertificate )(nil ),
111
+ "F3GetLatestCertificate" : (* certs .FinalityCertificate )(nil ),
112
+ "F3GetManifest" : (* manifest .Manifest )(nil ),
113
+ "F3GetF3PowerTable" : (gpbft .PowerEntries )(nil ),
114
+ "F3IsRunning" : false ,
115
+ },
116
+ customValidateReturn : map [string ]func (t * testing.T , ret []reflect.Value ){
117
+ "F3GetECPowerTable" : func (t * testing.T , ret []reflect.Value ) {
118
+ // special case because it simply returns power table from EC which is not F3 dependent
119
+ require .NotNil (t , ret [0 ].Interface (), "unexpected return value" )
120
+ },
121
+ },
122
+ },
123
+ }
124
+
125
+ for _ , tc := range testCases {
126
+ t .Run (tc .mode , func (t * testing.T ) {
127
+ ctx , cancel := context .WithTimeout (context .Background (), time .Minute )
128
+ defer cancel ()
129
+
130
+ opts := []any {kit .MockProofs ()}
131
+ if tc .mode == "disabled" {
132
+ opts = append (opts , kit .F3Enabled (nil ))
133
+ }
134
+
135
+ client , miner , ens := kit .EnsembleMinimal (t , opts ... )
136
+ ens .InterconnectAll ().BeginMining (2 * time .Millisecond )
137
+ ens .Start ()
138
+
139
+ head := client .WaitTillChain (ctx , kit .HeightAtLeast (10 ))
140
+
141
+ rctx := reflect .ValueOf (ctx )
142
+ rtsk := reflect .ValueOf (head .Key ())
143
+ rminer := reflect .ValueOf (miner .ActorAddr )
144
+ rticket := reflect .ValueOf ([]byte ("fish" ))
145
+ rone := reflect .ValueOf (uint64 (1 ))
146
+
147
+ calls := map [string ][]reflect.Value {
148
+ "F3GetOrRenewParticipationTicket" : {rctx , rminer , rticket , rone },
149
+ "F3Participate" : {rctx , rticket },
150
+ "F3GetCertificate" : {rctx , rone },
151
+ "F3GetLatestCertificate" : {rctx },
152
+ "F3GetManifest" : {rctx },
153
+ "F3GetECPowerTable" : {rctx , rtsk },
154
+ "F3GetF3PowerTable" : {rctx , rtsk },
155
+ "F3IsRunning" : {rctx },
156
+ }
157
+
158
+ for fn , args := range calls {
159
+ t .Run (fn , func (t * testing.T ) {
160
+ ret := reflect .ValueOf (client ).MethodByName (fn ).Call (args )
161
+
162
+ if expectedValue , hasExpectedValue := tc .expectedValues [fn ]; hasExpectedValue {
163
+ require .Equal (t , expectedValue , ret [0 ].Interface (), "unexpected return value" )
164
+ }
165
+
166
+ if expectedError , hasExpectedError := tc .expectedErrors [fn ]; hasExpectedError {
167
+ switch err := expectedError .(type ) {
168
+ case error :
169
+ require .ErrorIs (t , ret [1 ].Interface ().(error ), err , "unexpected error" )
170
+ case string :
171
+ require .ErrorContains (t , ret [1 ].Interface ().(error ), err , "unexpected error" )
172
+ }
173
+ } else {
174
+ require .Nil (t , ret [1 ].Interface (), "unexpected error" )
175
+ }
176
+
177
+ if validate , hasValidate := tc .customValidateReturn [fn ]; hasValidate {
178
+ validate (t , ret )
179
+ }
180
+ })
181
+ }
182
+ })
183
+ }
184
+ }
185
+
60
186
// TestF3_Rebootstrap tests F3 can be rebootsrapped by changing the manifest
61
187
// without disrupting miner participation.
62
188
func TestF3_Rebootstrap (t * testing.T ) {
@@ -227,7 +353,9 @@ func (e *testEnv) waitTillF3Instance(i uint64, timeout time.Duration) {
227
353
func (e * testEnv ) waitTillManifestChange (newManifest * manifest.Manifest , timeout time.Duration ) {
228
354
e .waitFor (func (n * kit.TestFullNode ) bool {
229
355
m , err := n .F3GetManifest (e .testCtx )
230
- require .NoError (e .t , err )
356
+ if err != nil || m == nil {
357
+ return false
358
+ }
231
359
return newManifest .Equal (m )
232
360
}, timeout )
233
361
}
0 commit comments