@@ -11,6 +11,7 @@ import (
1111 reward18 "github.com/filecoin-project/go-state-types/builtin/v18/reward"
1212 smoothing18 "github.com/filecoin-project/go-state-types/builtin/v18/util/smoothing"
1313 reward19 "github.com/filecoin-project/go-state-types/builtin/v19/reward"
14+ adt19 "github.com/filecoin-project/go-state-types/builtin/v19/util/adt"
1415 "github.com/filecoin-project/go-state-types/migration"
1516 "github.com/ipfs/go-cid"
1617 cbor "github.com/ipfs/go-ipld-cbor"
@@ -28,6 +29,7 @@ func validRewardMigrationConfig(t *testing.T, activationEpoch abi.ChainEpoch) Re
2829 t .Helper ()
2930 pct := reward19 .Denom / 100
3031 return RewardMigrationConfig {
32+ ActivationEpoch : activationEpoch ,
3133 SWATimelockEpochs : 20_160 ,
3234 SWAActor : migrationIDAddress (t , 100 ),
3335 Streams : []reward19.RegisterStreamParams {
@@ -74,7 +76,7 @@ func TestRewardMigration(t *testing.T) {
7476 activationEpoch := abi .ChainEpoch (100 )
7577 config := validRewardMigrationConfig (t , activationEpoch )
7678 outCodeCID := cid .MustParse ("bafy2bzaca4aaaaaaaaaqk" )
77- migrator , err := newRewardMigrator (config , activationEpoch , outCodeCID )
79+ migrator , err := newRewardMigrator (config , outCodeCID )
7880 req .NoError (err )
7981 result , err := migrator .MigrateState (ctx , store , migration.ActorMigrationInput {Address : address .TestAddress , Head : inHead })
8082 req .NoError (err )
@@ -98,18 +100,90 @@ func TestRewardMigration(t *testing.T) {
98100 req .Equal (config .SWATimelockEpochs , outState .SWATimelockEpochs )
99101 req .Equal (config .SWAActor , outState .SWAActor )
100102
101- var streams reward19. StreamsState
102- req .NoError (store . Get ( ctx , outState . StreamsRoot , & streams ) )
103+ streams , err := outState . LoadStreams ( adt19 . WrapStore ( ctx , store ))
104+ req .NoError (err )
103105 req .Len (streams .Streams , 2 )
104106 req .Equal (reward19 .StreamID (1 ), streams .Streams [0 ].ID )
107+ req .Equal (config .Streams [0 ].Weight , streams .Streams [0 ].Weight )
105108 req .Nil (streams .Streams [0 ].Distribution )
106109 req .Equal (reward19 .StreamID (2 ), streams .Streams [1 ].ID )
110+ req .Equal (config .Streams [1 ].Weight , streams .Streams [1 ].Weight )
107111 req .Equal (config .Streams [1 ].Distribution .Writer , streams .Streams [1 ].Distribution .Writer )
108112 req .Equal (config .Streams [1 ].Distribution .Shares , streams .Streams [1 ].Distribution .Shares )
109113 req .Empty (streams .Tombstones )
110114 req .Empty (streams .PendingWrites )
111115}
112116
117+ func TestRewardMigrationDropsStoredRewardTotals (t * testing.T ) {
118+ ctx , cancel := context .WithTimeout (context .Background (), time .Second )
119+ defer cancel ()
120+ req := require .New (t )
121+ store := cbor .NewMemCborStore ()
122+ activationEpoch := abi .ChainEpoch (100 )
123+ migrator , err := newRewardMigrator (
124+ validRewardMigrationConfig (t , activationEpoch ),
125+ cid .MustParse ("bafy2bzaca4aaaaaaaaaqk" ),
126+ )
127+ req .NoError (err )
128+
129+ base := reward18.State {
130+ CumsumBaseline : big .NewInt (1 ),
131+ CumsumRealized : big .NewInt (2 ),
132+ EffectiveNetworkTime : 3 ,
133+ EffectiveBaselinePower : big .NewInt (4 ),
134+ ThisEpochReward : abi .NewTokenAmount (5 ),
135+ ThisEpochRewardSmoothed : smoothing18 .NewEstimate (big .NewInt (6 ), big .NewInt (7 )),
136+ ThisEpochBaselinePower : big .NewInt (8 ),
137+ Epoch : 9 ,
138+ TotalStoragePowerReward : abi .NewTokenAmount (10 ),
139+ SimpleTotal : abi .NewTokenAmount (11 ),
140+ BaselineTotal : abi .NewTokenAmount (12 ),
141+ }
142+ alternate := base
143+ alternate .SimpleTotal = abi .NewTokenAmount (13 )
144+ alternate .BaselineTotal = abi .NewTokenAmount (14 )
145+ req .NotEqual (base .SimpleTotal , alternate .SimpleTotal )
146+ req .NotEqual (base .BaselineTotal , alternate .BaselineTotal )
147+
148+ migrate := func (input reward18.State ) reward19.State {
149+ head , err := store .Put (ctx , & input )
150+ req .NoError (err )
151+ result , err := migrator .MigrateState (ctx , store , migration.ActorMigrationInput {
152+ Address : address .TestAddress ,
153+ Head : head ,
154+ })
155+ req .NoError (err )
156+ var output reward19.State
157+ req .NoError (store .Get (ctx , result .NewHead , & output ))
158+ return output
159+ }
160+
161+ req .Equal (migrate (base ), migrate (alternate ))
162+ }
163+
164+ func TestNewRewardMigratorAcceptsAlternativeBootstrapWeights (t * testing.T ) {
165+ activationEpoch := abi .ChainEpoch (100 )
166+ pct := reward19 .Denom / 100
167+ config := validRewardMigrationConfig (t , activationEpoch )
168+ config .Streams [0 ].Weight = reward19.WeightRecord {
169+ VStart : 80 * pct ,
170+ Slope : - 1 ,
171+ TStart : activationEpoch ,
172+ Floor : 60 * pct ,
173+ Cap : 80 * pct ,
174+ }
175+ config .Streams [1 ].Weight = reward19.WeightRecord {
176+ VStart : 20 * pct ,
177+ Slope : 1 ,
178+ TStart : activationEpoch ,
179+ Floor : 10 * pct ,
180+ Cap : 20 * pct ,
181+ }
182+
183+ _ , err := newRewardMigrator (config , cid .MustParse ("bafy2bzaca4aaaaaaaaaqk" ))
184+ require .NoError (t , err )
185+ }
186+
113187func TestNewRewardMigratorRejectsInvalidConfig (t * testing.T ) {
114188 activationEpoch := abi .ChainEpoch (100 )
115189 outCodeCID := cid .MustParse ("bafy2bzaca4aaaaaaaaaqk" )
@@ -140,11 +214,11 @@ func TestNewRewardMigratorRejectsInvalidConfig(t *testing.T) {
140214 expected : "requires exactly two streams" ,
141215 },
142216 {
143- name : "wrong bootstrap weight " ,
217+ name : "starting weights under-sum " ,
144218 mutate : func (config * RewardMigrationConfig ) {
145- config .Streams [0 ].Weight .VStart --
219+ config .Streams [1 ].Weight .VStart --
146220 },
147- expected : "consensus bootstrap weight is invalid " ,
221+ expected : "bootstrap starting weights must sum to denominator " ,
148222 },
149223 {
150224 name : "unequal slopes" ,
@@ -176,13 +250,31 @@ func TestNewRewardMigratorRejectsInvalidConfig(t *testing.T) {
176250 },
177251 expected : "SWA actor is not an ID address" ,
178252 },
253+ {
254+ name : "non-ID SRA actor" ,
255+ mutate : func (config * RewardMigrationConfig ) {
256+ addr , err := address .NewDelegatedAddress (10 , []byte {1 })
257+ require .NoError (t , err )
258+ config .Streams [1 ].Distribution .Writer = addr
259+ },
260+ expected : "distribution writer" ,
261+ },
262+ {
263+ name : "non-ID initial orchestrator" ,
264+ mutate : func (config * RewardMigrationConfig ) {
265+ addr , err := address .NewDelegatedAddress (10 , []byte {1 })
266+ require .NoError (t , err )
267+ config .Streams [1 ].Distribution .Shares [0 ].Recipient = addr
268+ },
269+ expected : "share recipient" ,
270+ },
179271 }
180272
181273 for _ , tc := range testCases {
182274 t .Run (tc .name , func (t * testing.T ) {
183275 config := validRewardMigrationConfig (t , activationEpoch )
184276 tc .mutate (& config )
185- _ , err := newRewardMigrator (config , activationEpoch , outCodeCID )
277+ _ , err := newRewardMigrator (config , outCodeCID )
186278 require .ErrorContains (t , err , tc .expected )
187279 })
188280 }
0 commit comments