52261fb814
While the previous version "worked", this version nicely separates out the state for the separate stages. Hopefully, we'll be able to use this to build different pipelines with different configs.
72 lines
2.3 KiB
Go
72 lines
2.3 KiB
Go
package simulation
|
|
|
|
import (
|
|
"context"
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
"github.com/filecoin-project/lotus/cmd/lotus-sim/simulation/blockbuilder"
|
|
)
|
|
|
|
// Step steps the simulation forward one step. This may move forward by more than one epoch.
|
|
func (sim *Simulation) Step(ctx context.Context) (*types.TipSet, error) {
|
|
log.Infow("step", "epoch", sim.head.Height()+1)
|
|
messages, err := sim.popNextMessages(ctx)
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("failed to select messages for block: %w", err)
|
|
}
|
|
head, err := sim.makeTipSet(ctx, messages)
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("failed to make tipset: %w", err)
|
|
}
|
|
if err := sim.SetHead(head); err != nil {
|
|
return nil, xerrors.Errorf("failed to update head: %w", err)
|
|
}
|
|
return head, nil
|
|
}
|
|
|
|
// popNextMessages generates/picks a set of messages to be included in the next block.
|
|
//
|
|
// - This function is destructive and should only be called once per epoch.
|
|
// - This function does not store anything in the repo.
|
|
// - This function handles all gas estimation. The returned messages should all fit in a single
|
|
// block.
|
|
func (sim *Simulation) popNextMessages(ctx context.Context) ([]*types.Message, error) {
|
|
parentTs := sim.head
|
|
|
|
// First we make sure we don't have an upgrade at this epoch. If we do, we return no
|
|
// messages so we can just create an empty block at that epoch.
|
|
//
|
|
// This isn't what the network does, but it makes things easier. Otherwise, we'd need to run
|
|
// migrations before this epoch and I'd rather not deal with that.
|
|
nextHeight := parentTs.Height() + 1
|
|
prevVer := sim.StateManager.GetNtwkVersion(ctx, nextHeight-1)
|
|
nextVer := sim.StateManager.GetNtwkVersion(ctx, nextHeight)
|
|
if nextVer != prevVer {
|
|
log.Warnw("packing no messages for version upgrade block",
|
|
"old", prevVer,
|
|
"new", nextVer,
|
|
"epoch", nextHeight,
|
|
)
|
|
return nil, nil
|
|
}
|
|
|
|
bb, err := blockbuilder.NewBlockBuilder(
|
|
ctx, log.With("simulation", sim.name),
|
|
sim.StateManager, parentTs,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, stage := range sim.stages {
|
|
// We're intentionally ignoring the "full" signal so we can try to pack a few more
|
|
// messages.
|
|
if err := stage.PackMessages(ctx, bb); err != nil && !blockbuilder.IsOutOfGas(err) {
|
|
return nil, xerrors.Errorf("when packing messages with %s: %w", stage.Name(), err)
|
|
}
|
|
}
|
|
return bb.Messages(), nil
|
|
}
|