github.com/filecoin-project/specs-actors/v4@v4.0.2/support/agent/cases_test.go (about) 1 package agent_test 2 3 import ( 4 "context" 5 "fmt" 6 "math/rand" 7 "strings" 8 "testing" 9 10 "github.com/filecoin-project/go-state-types/abi" 11 "github.com/filecoin-project/go-state-types/big" 12 "github.com/filecoin-project/go-state-types/rt" 13 power2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/power" 14 states2 "github.com/filecoin-project/specs-actors/v2/actors/states" 15 vm_test2 "github.com/filecoin-project/specs-actors/v2/support/vm" 16 states3 "github.com/filecoin-project/specs-actors/v3/actors/states" 17 vm_test3 "github.com/filecoin-project/specs-actors/v3/support/vm" 18 cid "github.com/ipfs/go-cid" 19 cbor "github.com/ipfs/go-ipld-cbor" 20 "github.com/stretchr/testify/assert" 21 "github.com/stretchr/testify/require" 22 23 "github.com/filecoin-project/specs-actors/v4/actors/builtin" 24 "github.com/filecoin-project/specs-actors/v4/actors/builtin/exported" 25 "github.com/filecoin-project/specs-actors/v4/actors/builtin/power" 26 "github.com/filecoin-project/specs-actors/v4/actors/migration/nv10" 27 "github.com/filecoin-project/specs-actors/v4/actors/states" 28 "github.com/filecoin-project/specs-actors/v4/actors/util/adt" 29 "github.com/filecoin-project/specs-actors/v4/support/agent" 30 "github.com/filecoin-project/specs-actors/v4/support/ipld" 31 vm_test "github.com/filecoin-project/specs-actors/v4/support/vm" 32 ) 33 34 func TestCreate20Miners(t *testing.T) { 35 ctx := context.Background() 36 initialBalance := big.Mul(big.NewInt(1000), big.NewInt(1e18)) 37 minerCount := 20 38 39 rnd := rand.New(rand.NewSource(42)) 40 41 sim := agent.NewSim(ctx, t, newBlockStore, agent.SimConfig{Seed: rnd.Int63()}) 42 accounts := vm_test.CreateAccounts(ctx, t, getV3VM(t, sim), minerCount, initialBalance, rnd.Int63()) 43 sim.AddAgent(agent.NewMinerGenerator( 44 accounts, 45 agent.MinerAgentConfig{ 46 PrecommitRate: 2.5, 47 ProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1, 48 StartingBalance: initialBalance, 49 MinMarketBalance: big.Zero(), 50 MaxMarketBalance: big.Zero(), 51 }, 52 1.0, // create miner probability of 1 means a new miner is created every tick 53 rnd.Int63(), 54 )) 55 56 // give it twice the number of ticks to account for variation in the rate 57 for i := 0; i < 2*minerCount; i++ { 58 require.NoError(t, sim.Tick()) 59 } 60 61 // add 1 agent for miner generator 62 assert.Equal(t, minerCount+1, len(sim.Agents)) 63 64 for _, a := range sim.Agents { 65 miner, ok := a.(*agent.MinerAgent) 66 if ok { 67 actor, found, err := sim.GetVM().GetActor(miner.IDAddress) 68 require.NoError(t, err) 69 require.True(t, found) 70 71 // demonstrate actor is created and has correct balance 72 assert.Equal(t, initialBalance, actor.Balance) 73 } 74 } 75 } 76 77 // This test covers all the simulation functionality. 78 // 500 epochs is long enough for most, not all, important processes to take place, but runs fast enough 79 // to keep in CI. 80 func Test500Epochs(t *testing.T) { 81 ctx := context.Background() 82 initialBalance := big.Mul(big.NewInt(1e8), big.NewInt(1e18)) 83 cumulativeStats := make(vm_test.StatsByCall) 84 minerCount := 10 85 clientCount := 9 86 87 // set up sim 88 rnd := rand.New(rand.NewSource(42)) 89 sim := agent.NewSim(ctx, t, newBlockStore, agent.SimConfig{ 90 Seed: rnd.Int63(), 91 CheckpointEpochs: 1000, 92 }) 93 94 // create miners 95 workerAccounts := vm_test.CreateAccounts(ctx, t, getV3VM(t, sim), minerCount, initialBalance, rnd.Int63()) 96 sim.AddAgent(agent.NewMinerGenerator( 97 workerAccounts, 98 agent.MinerAgentConfig{ 99 PrecommitRate: 2.0, 100 FaultRate: 0.0001, 101 RecoveryRate: 0.0001, 102 UpgradeSectors: true, 103 ProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1, 104 StartingBalance: big.Div(initialBalance, big.NewInt(2)), 105 MinMarketBalance: big.NewInt(1e18), 106 MaxMarketBalance: big.NewInt(2e18), 107 }, 108 1.0, // create miner probability of 1 means a new miner is created every tick 109 rnd.Int63(), 110 )) 111 112 clientAccounts := vm_test.CreateAccounts(ctx, t, getV3VM(t, sim), clientCount, initialBalance, rnd.Int63()) 113 dealAgents := agent.AddDealClientsForAccounts(sim, clientAccounts, rnd.Int63(), agent.DealClientConfig{ 114 DealRate: .05, 115 MinPieceSize: 1 << 29, 116 MaxPieceSize: 32 << 30, 117 MinStoragePrice: big.Zero(), 118 MaxStoragePrice: abi.NewTokenAmount(200_000_000), 119 MinMarketBalance: big.NewInt(1e18), 120 MaxMarketBalance: big.NewInt(2e18), 121 }) 122 123 var pwrSt power.State 124 for i := 0; i < 500; i++ { 125 require.NoError(t, sim.Tick()) 126 127 epoch := sim.GetVM().GetEpoch() 128 if epoch%100 == 0 { 129 // compute number of deals 130 deals := 0 131 for _, da := range dealAgents { 132 deals += da.DealCount 133 } 134 135 stateTree, err := getV3VM(t, sim).GetStateTree() 136 require.NoError(t, err) 137 138 totalBalance, err := getV3VM(t, sim).GetTotalActorBalance() 139 require.NoError(t, err) 140 141 acc, err := states.CheckStateInvariants(stateTree, totalBalance, sim.GetVM().GetEpoch()-1) 142 require.NoError(t, err) 143 require.True(t, acc.IsEmpty(), strings.Join(acc.Messages(), "\n")) 144 145 require.NoError(t, sim.GetVM().GetState(builtin.StoragePowerActorAddr, &pwrSt)) 146 147 // assume each sector is 32Gb 148 sectorCount := big.Div(pwrSt.TotalBytesCommitted, big.NewInt(32<<30)) 149 150 fmt.Printf("Power at %d: raw: %v cmtRaw: %v cmtSecs: %d msgs: %d deals: %d gets: %d puts: %d write bytes: %d read bytes: %d\n", 151 epoch, pwrSt.TotalRawBytePower, pwrSt.TotalBytesCommitted, sectorCount.Uint64(), 152 sim.MessageCount, deals, getV3VM(t, sim).StoreReads(), getV3VM(t, sim).StoreWrites(), 153 getV3VM(t, sim).StoreReadBytes(), getV3VM(t, sim).StoreWriteBytes()) 154 } 155 156 cumulativeStats.MergeAllStats(sim.GetCallStats()) 157 } 158 } 159 160 func TestCommitPowerAndCheckInvariants(t *testing.T) { 161 t.Skip("this is slow") 162 ctx := context.Background() 163 initialBalance := big.Mul(big.NewInt(1e9), big.NewInt(1e18)) 164 minerCount := 1 165 166 rnd := rand.New(rand.NewSource(42)) 167 sim := agent.NewSim(ctx, t, newBlockStore, agent.SimConfig{Seed: rnd.Int63()}) 168 accounts := vm_test.CreateAccounts(ctx, t, getV3VM(t, sim), minerCount, initialBalance, rnd.Int63()) 169 sim.AddAgent(agent.NewMinerGenerator( 170 accounts, 171 agent.MinerAgentConfig{ 172 PrecommitRate: 0.1, 173 FaultRate: 0.00001, 174 RecoveryRate: 0.0001, 175 ProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1, 176 StartingBalance: initialBalance, 177 MinMarketBalance: big.Zero(), 178 MaxMarketBalance: big.Zero(), 179 }, 180 1.0, // create miner probability of 1 means a new miner is created every tick 181 rnd.Int63(), 182 )) 183 184 var pwrSt power.State 185 for i := 0; i < 100_000; i++ { 186 require.NoError(t, sim.Tick()) 187 188 epoch := sim.GetVM().GetEpoch() 189 if epoch%100 == 0 { 190 stateTree, err := getV3VM(t, sim).GetStateTree() 191 require.NoError(t, err) 192 193 totalBalance, err := getV3VM(t, sim).GetTotalActorBalance() 194 require.NoError(t, err) 195 196 acc, err := states.CheckStateInvariants(stateTree, totalBalance, sim.GetVM().GetEpoch()-1) 197 require.NoError(t, err) 198 require.True(t, acc.IsEmpty(), strings.Join(acc.Messages(), "\n")) 199 200 require.NoError(t, sim.GetVM().GetState(builtin.StoragePowerActorAddr, &pwrSt)) 201 202 // assume each sector is 32Gb 203 sectorCount := big.Div(pwrSt.TotalBytesCommitted, big.NewInt(32<<30)) 204 205 fmt.Printf("Power at %d: raw: %v cmtRaw: %v cmtSecs: %d cnsMnrs: %d avgWins: %.3f msgs: %d\n", 206 epoch, pwrSt.TotalRawBytePower, pwrSt.TotalBytesCommitted, sectorCount.Uint64(), 207 pwrSt.MinerAboveMinPowerCount, float64(sim.WinCount)/float64(epoch), sim.MessageCount) 208 } 209 } 210 } 211 212 func TestMigration(t *testing.T) { 213 t.Skip("slow") 214 ctx, cancel := context.WithCancel(context.Background()) 215 defer cancel() 216 initialBalance := big.Mul(big.NewInt(1e8), big.NewInt(1e18)) 217 minerCount := 10 218 clientCount := 9 219 220 blkStore := newBlockStore() 221 v := vm_test2.NewVMWithSingletons(ctx, t, blkStore) 222 v2VMFactory := func(ctx context.Context, impl vm_test2.ActorImplLookup, store adt.Store, stateRoot cid.Cid, epoch abi.ChainEpoch) (agent.SimVM, error) { 223 return vm_test2.NewVMAtEpoch(ctx, impl, store, stateRoot, epoch) 224 } 225 v2MinerFactory := func(ctx context.Context, root cid.Cid) (agent.SimMinerState, error) { 226 return &agent.MinerStateV2{ 227 Ctx: ctx, 228 Root: root, 229 }, nil 230 } 231 232 // set up sim 233 rnd := rand.New(rand.NewSource(42)) 234 sim := agent.NewSimWithVM(ctx, t, v, v2VMFactory, agent.ComputePowerTableV2, blkStore, newBlockStore, v2MinerFactory, agent.SimConfig{ 235 Seed: rnd.Int63(), 236 CheckpointEpochs: 1000, 237 }, agent.CreateMinerParamsV2) 238 239 // create miners 240 workerAccounts := vm_test2.CreateAccounts(ctx, t, v, minerCount, initialBalance, rnd.Int63()) 241 sim.AddAgent(agent.NewMinerGenerator( 242 workerAccounts, 243 agent.MinerAgentConfig{ 244 PrecommitRate: 2.0, 245 FaultRate: 0.00001, 246 RecoveryRate: 0.0001, 247 UpgradeSectors: true, 248 ProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1, 249 StartingBalance: big.Div(initialBalance, big.NewInt(2)), 250 MinMarketBalance: big.NewInt(1e18), 251 MaxMarketBalance: big.NewInt(2e18), 252 }, 253 1.0, // create miner probability of 1 means a new miner is created every tick 254 rnd.Int63(), 255 )) 256 257 clientAccounts := vm_test2.CreateAccounts(ctx, t, v, clientCount, initialBalance, rnd.Int63()) 258 agent.AddDealClientsForAccounts(sim, clientAccounts, rnd.Int63(), agent.DealClientConfig{ 259 DealRate: .05, 260 MinPieceSize: 1 << 29, 261 MaxPieceSize: 32 << 30, 262 MinStoragePrice: big.Zero(), 263 MaxStoragePrice: abi.NewTokenAmount(200_000_000), 264 MinMarketBalance: big.NewInt(1e18), 265 MaxMarketBalance: big.NewInt(2e18), 266 }) 267 268 // Run v2 for 5000 epochs 269 var pwrSt power2.State 270 for i := 0; i < 5000; i++ { 271 require.NoError(t, sim.Tick()) 272 epoch := sim.GetVM().GetEpoch() 273 if epoch%100 == 0 { 274 stateTree, err := states2.LoadTree(sim.GetVM().Store(), sim.GetVM().StateRoot()) 275 require.NoError(t, err) 276 277 totalBalance, err := sim.GetVM().GetTotalActorBalance() 278 require.NoError(t, err) 279 280 acc, err := states2.CheckStateInvariants(stateTree, totalBalance, sim.GetVM().GetEpoch()-1) 281 require.NoError(t, err) 282 require.True(t, acc.IsEmpty(), strings.Join(acc.Messages(), "\n")) 283 284 require.NoError(t, sim.GetVM().GetState(builtin.StoragePowerActorAddr, &pwrSt)) 285 286 // assume each sector is 32Gb 287 sectorCount := big.Div(pwrSt.TotalBytesCommitted, big.NewInt(32<<30)) 288 289 fmt.Printf("Power at %d: raw: %v cmtRaw: %v cmtSecs: %d cnsMnrs: %d avgWins: %.3f msgs: %d\n", 290 epoch, pwrSt.TotalRawBytePower, pwrSt.TotalBytesCommitted, sectorCount.Uint64(), 291 pwrSt.MinerAboveMinPowerCount, float64(sim.WinCount)/float64(epoch), sim.MessageCount) 292 } 293 } 294 295 // Migrate 296 v2 := sim.GetVM() 297 log := nv10.TestLogger{TB: t} 298 priorEpoch := v2.GetEpoch() - 1 // on tick sim internally creates new vm with epoch set to the next one 299 nextRoot, err := nv10.MigrateStateTree(ctx, v2.Store(), v2.StateRoot(), priorEpoch, nv10.Config{MaxWorkers: 1}, log, nv10.NewMemMigrationCache()) 300 require.NoError(t, err) 301 302 lookup := map[cid.Cid]rt.VMActor{} 303 for _, ba := range exported.BuiltinActors() { 304 lookup[ba.Code()] = ba 305 } 306 307 v3, err := vm_test3.NewVMAtEpoch(ctx, lookup, v2.Store(), nextRoot, priorEpoch+1) 308 require.NoError(t, err) 309 310 stateTree, err := v3.GetStateTree() 311 require.NoError(t, err) 312 totalBalance, err := v3.GetTotalActorBalance() 313 require.NoError(t, err) 314 msgs, err := states3.CheckStateInvariants(stateTree, totalBalance, priorEpoch) 315 require.NoError(t, err) 316 assert.Zero(t, len(msgs.Messages()), strings.Join(msgs.Messages(), "\n")) 317 318 v3VMFactory := func(ctx context.Context, impl vm_test2.ActorImplLookup, store adt.Store, stateRoot cid.Cid, epoch abi.ChainEpoch) (agent.SimVM, error) { 319 return vm_test.NewVMAtEpoch(ctx, vm_test.ActorImplLookup(impl), store, stateRoot, epoch) 320 } 321 v3MinerFactory := func(ctx context.Context, root cid.Cid) (agent.SimMinerState, error) { 322 return &agent.MinerStateV3{ 323 Ctx: ctx, 324 Root: root, 325 }, nil 326 } 327 sim.SwapVM(v3, agent.VMFactoryFunc(v3VMFactory), v3MinerFactory, agent.ComputePowerTableV3, agent.CreateMinerParamsV3) 328 329 // Run v3 for 5000 epochs 330 for i := 0; i < 5000; i++ { 331 require.NoError(t, sim.Tick()) 332 epoch := sim.GetVM().GetEpoch() 333 if epoch%100 == 0 { 334 stateTree, err := states.LoadTree(sim.GetVM().Store(), sim.GetVM().StateRoot()) 335 require.NoError(t, err) 336 337 totalBalance, err := sim.GetVM().GetTotalActorBalance() 338 require.NoError(t, err) 339 340 acc, err := states.CheckStateInvariants(stateTree, totalBalance, sim.GetVM().GetEpoch()-1) 341 require.NoError(t, err) 342 require.True(t, acc.IsEmpty(), strings.Join(acc.Messages(), "\n")) 343 344 require.NoError(t, sim.GetVM().GetState(builtin.StoragePowerActorAddr, &pwrSt)) 345 346 // assume each sector is 32Gb 347 sectorCount := big.Div(pwrSt.TotalBytesCommitted, big.NewInt(32<<30)) 348 349 fmt.Printf("Power at %d: raw: %v cmtRaw: %v cmtSecs: %d cnsMnrs: %d avgWins: %.3f msgs: %d\n", 350 epoch, pwrSt.TotalRawBytePower, pwrSt.TotalBytesCommitted, sectorCount.Uint64(), 351 pwrSt.MinerAboveMinPowerCount, float64(sim.WinCount)/float64(epoch), sim.MessageCount) 352 } 353 } 354 355 } 356 357 func TestCommitAndCheckReadWriteStats(t *testing.T) { 358 t.Skip("this is slow") 359 ctx := context.Background() 360 initialBalance := big.Mul(big.NewInt(1e8), big.NewInt(1e18)) 361 cumulativeStats := make(vm_test.StatsByCall) 362 minerCount := 10 363 clientCount := 9 364 365 // set up sim 366 rnd := rand.New(rand.NewSource(42)) 367 sim := agent.NewSim(ctx, t, newBlockStore, agent.SimConfig{ 368 Seed: rnd.Int63(), 369 CheckpointEpochs: 1000, 370 }) 371 372 // create miners 373 workerAccounts := vm_test.CreateAccounts(ctx, t, getV3VM(t, sim), minerCount, initialBalance, rnd.Int63()) 374 sim.AddAgent(agent.NewMinerGenerator( 375 workerAccounts, 376 agent.MinerAgentConfig{ 377 PrecommitRate: 2.0, 378 FaultRate: 0.00001, 379 RecoveryRate: 0.0001, 380 UpgradeSectors: true, 381 ProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1, 382 StartingBalance: big.Div(initialBalance, big.NewInt(2)), 383 MinMarketBalance: big.NewInt(1e18), 384 MaxMarketBalance: big.NewInt(2e18), 385 }, 386 1.0, // create miner probability of 1 means a new miner is created every tick 387 rnd.Int63(), 388 )) 389 390 clientAccounts := vm_test.CreateAccounts(ctx, t, getV3VM(t, sim), clientCount, initialBalance, rnd.Int63()) 391 dealAgents := agent.AddDealClientsForAccounts(sim, clientAccounts, rnd.Int63(), agent.DealClientConfig{ 392 DealRate: .05, 393 MinPieceSize: 1 << 29, 394 MaxPieceSize: 32 << 30, 395 MinStoragePrice: big.Zero(), 396 MaxStoragePrice: abi.NewTokenAmount(200_000_000), 397 MinMarketBalance: big.NewInt(1e18), 398 MaxMarketBalance: big.NewInt(2e18), 399 }) 400 401 var pwrSt power.State 402 for i := 0; i < 20_000; i++ { 403 require.NoError(t, sim.Tick()) 404 405 epoch := sim.GetVM().GetEpoch() 406 if epoch%100 == 0 { 407 // compute number of deals 408 deals := 0 409 for _, da := range dealAgents { 410 deals += da.DealCount 411 } 412 413 require.NoError(t, sim.GetVM().GetState(builtin.StoragePowerActorAddr, &pwrSt)) 414 415 // assume each sector is 32Gb 416 sectorCount := big.Div(pwrSt.TotalBytesCommitted, big.NewInt(32<<30)) 417 418 fmt.Printf("Power at %d: raw: %v cmtRaw: %v cmtSecs: %d msgs: %d deals: %d gets: %d puts: %d write bytes: %d read bytes: %d\n", 419 epoch, pwrSt.TotalRawBytePower, pwrSt.TotalBytesCommitted, sectorCount.Uint64(), 420 sim.MessageCount, deals, getV3VM(t, sim).StoreReads(), getV3VM(t, sim).StoreWrites(), 421 getV3VM(t, sim).StoreReadBytes(), getV3VM(t, sim).StoreWriteBytes()) 422 } 423 424 cumulativeStats.MergeAllStats(sim.GetCallStats()) 425 426 if sim.GetVM().GetEpoch()%1000 == 0 { 427 for method, stats := range cumulativeStats { 428 printCallStats(method, stats, "") 429 } 430 cumulativeStats = make(vm_test.StatsByCall) 431 } 432 } 433 } 434 435 func TestCreateDeals(t *testing.T) { 436 t.Skip("this is slow") 437 ctx := context.Background() 438 initialBalance := big.Mul(big.NewInt(1e9), big.NewInt(1e18)) 439 minerCount := 3 440 clientCount := 9 441 442 // set up sim 443 rnd := rand.New(rand.NewSource(42)) 444 sim := agent.NewSim(ctx, t, newBlockStore, agent.SimConfig{Seed: rnd.Int63()}) 445 446 // create miners 447 workerAccounts := vm_test.CreateAccounts(ctx, t, getV3VM(t, sim), minerCount, initialBalance, rnd.Int63()) 448 sim.AddAgent(agent.NewMinerGenerator( 449 workerAccounts, 450 agent.MinerAgentConfig{ 451 PrecommitRate: 0.1, 452 FaultRate: 0.0001, 453 RecoveryRate: 0.0001, 454 ProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1, 455 StartingBalance: big.Div(initialBalance, big.NewInt(2)), 456 MinMarketBalance: big.NewInt(1e18), 457 MaxMarketBalance: big.NewInt(2e18), 458 }, 459 1.0, // create miner probability of 1 means a new miner is created every tick 460 rnd.Int63(), 461 )) 462 463 clientAccounts := vm_test.CreateAccounts(ctx, t, getV3VM(t, sim), clientCount, initialBalance, rnd.Int63()) 464 dealAgents := agent.AddDealClientsForAccounts(sim, clientAccounts, rnd.Int63(), agent.DealClientConfig{ 465 DealRate: .01, 466 MinPieceSize: 1 << 29, 467 MaxPieceSize: 32 << 30, 468 MinStoragePrice: big.Zero(), 469 MaxStoragePrice: abi.NewTokenAmount(200_000_000), 470 MinMarketBalance: big.NewInt(1e18), 471 MaxMarketBalance: big.NewInt(2e18), 472 }) 473 474 var pwrSt power.State 475 for i := 0; i < 100_000; i++ { 476 require.NoError(t, sim.Tick()) 477 478 epoch := sim.GetVM().GetEpoch() 479 if epoch%100 == 0 { 480 stateTree, err := getV3VM(t, sim).GetStateTree() 481 require.NoError(t, err) 482 483 totalBalance, err := getV3VM(t, sim).GetTotalActorBalance() 484 require.NoError(t, err) 485 486 acc, err := states.CheckStateInvariants(stateTree, totalBalance, sim.GetVM().GetEpoch()-1) 487 require.NoError(t, err) 488 require.True(t, acc.IsEmpty(), strings.Join(acc.Messages(), "\n")) 489 490 require.NoError(t, sim.GetVM().GetState(builtin.StoragePowerActorAddr, &pwrSt)) 491 492 // assume each sector is 32Gb 493 sectorCount := big.Div(pwrSt.TotalBytesCommitted, big.NewInt(32<<30)) 494 495 // compute number of deals 496 deals := 0 497 for _, da := range dealAgents { 498 deals += da.DealCount 499 } 500 501 fmt.Printf("Power at %d: raw: %v cmtRaw: %v cmtSecs: %d cnsMnrs: %d avgWins: %.3f msgs: %d deals: %d\n", 502 epoch, pwrSt.TotalRawBytePower, pwrSt.TotalBytesCommitted, sectorCount.Uint64(), 503 pwrSt.MinerAboveMinPowerCount, float64(sim.WinCount)/float64(epoch), sim.MessageCount, deals) 504 } 505 } 506 } 507 508 func TestCCUpgrades(t *testing.T) { 509 t.Skip("this is slow") 510 ctx := context.Background() 511 initialBalance := big.Mul(big.NewInt(1e10), big.NewInt(1e18)) 512 minerCount := 10 513 clientCount := 9 514 515 // set up sim 516 rnd := rand.New(rand.NewSource(42)) 517 sim := agent.NewSim(ctx, t, newBlockStore, agent.SimConfig{Seed: rnd.Int63()}) 518 519 // create miners 520 workerAccounts := vm_test.CreateAccounts(ctx, t, getV3VM(t, sim), minerCount, initialBalance, rnd.Int63()) 521 sim.AddAgent(agent.NewMinerGenerator( 522 workerAccounts, 523 agent.MinerAgentConfig{ 524 PrecommitRate: 2.0, 525 FaultRate: 0.00001, 526 RecoveryRate: 0.0001, 527 UpgradeSectors: true, 528 ProofType: abi.RegisteredSealProof_StackedDrg32GiBV1_1, 529 StartingBalance: big.Div(initialBalance, big.NewInt(2)), 530 MinMarketBalance: big.NewInt(1e18), 531 MaxMarketBalance: big.NewInt(2e18), 532 }, 533 1.0, // create miner probability of 1 means a new miner is created every tick 534 rnd.Int63(), 535 )) 536 537 clientAccounts := vm_test.CreateAccounts(ctx, t, getV3VM(t, sim), clientCount, initialBalance, rnd.Int63()) 538 agent.AddDealClientsForAccounts(sim, clientAccounts, rnd.Int63(), agent.DealClientConfig{ 539 DealRate: .01, 540 MinPieceSize: 1 << 29, 541 MaxPieceSize: 32 << 30, 542 MinStoragePrice: big.Zero(), 543 MaxStoragePrice: abi.NewTokenAmount(200_000_000), 544 MinMarketBalance: big.NewInt(1e18), 545 MaxMarketBalance: big.NewInt(2e18), 546 }) 547 548 var pwrSt power.State 549 for i := 0; i < 100_000; i++ { 550 require.NoError(t, sim.Tick()) 551 552 epoch := sim.GetVM().GetEpoch() 553 if epoch%100 == 0 { 554 stateTree, err := getV3VM(t, sim).GetStateTree() 555 require.NoError(t, err) 556 557 totalBalance, err := getV3VM(t, sim).GetTotalActorBalance() 558 require.NoError(t, err) 559 560 acc, err := states.CheckStateInvariants(stateTree, totalBalance, sim.GetVM().GetEpoch()-1) 561 require.NoError(t, err) 562 require.True(t, acc.IsEmpty(), strings.Join(acc.Messages(), "\n")) 563 564 require.NoError(t, sim.GetVM().GetState(builtin.StoragePowerActorAddr, &pwrSt)) 565 566 // assume each sector is 32Gb 567 sectorCount := big.Div(pwrSt.TotalBytesCommitted, big.NewInt(32<<30)) 568 569 // compute stats 570 deals := 0 571 upgrades := uint64(0) 572 for _, a := range sim.Agents { 573 switch agnt := a.(type) { 574 case *agent.MinerAgent: 575 upgrades += agnt.UpgradedSectors 576 case *agent.DealClientAgent: 577 deals += agnt.DealCount 578 } 579 } 580 581 // compute upgrades 582 583 fmt.Printf("Power at %d: raw: %v cmtRaw: %v cmtSecs: %d msgs: %d deals: %d upgrades: %d\n", 584 epoch, pwrSt.TotalRawBytePower, pwrSt.TotalBytesCommitted, sectorCount.Uint64(), 585 sim.MessageCount, deals, upgrades) 586 } 587 } 588 } 589 590 func newBlockStore() cbor.IpldBlockstore { 591 return ipld.NewBlockStoreInMemory() 592 } 593 594 func printCallStats(method vm_test.MethodKey, stats *vm_test.CallStats, indent string) { // nolint:unused 595 fmt.Printf("%s%v:%d: calls: %d gets: %d puts: %d read: %d written: %d avg gets: %.2f, avg puts: %.2f\n", 596 indent, builtin.ActorNameByCode(method.Code), method.Method, stats.Calls, stats.Reads, stats.Writes, 597 stats.ReadBytes, stats.WriteBytes, float32(stats.Reads)/float32(stats.Calls), 598 float32(stats.Writes)/float32(stats.Calls)) 599 600 if stats.SubStats == nil { 601 return 602 } 603 604 for m, s := range stats.SubStats { 605 printCallStats(m, s, indent+" ") 606 } 607 } 608 609 func getV3VM(t *testing.T, sim *agent.Sim) *vm_test.VM { 610 vm, ok := sim.GetVM().(*vm_test.VM) 611 require.True(t, ok) 612 return vm 613 }