280 lines
7.6 KiB
Go
280 lines
7.6 KiB
Go
package sealing_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/ipfs/go-cid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
commcid "github.com/filecoin-project/go-fil-commcid"
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
"github.com/filecoin-project/go-state-types/big"
|
|
"github.com/filecoin-project/go-state-types/crypto"
|
|
"github.com/filecoin-project/go-state-types/network"
|
|
|
|
"github.com/filecoin-project/lotus/api"
|
|
"github.com/filecoin-project/lotus/build"
|
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
|
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
|
"github.com/filecoin-project/lotus/chain/actors/policy"
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
|
pipeline "github.com/filecoin-project/lotus/storage/pipeline"
|
|
"github.com/filecoin-project/lotus/storage/pipeline/piece"
|
|
"github.com/filecoin-project/lotus/storage/pipeline/sealiface"
|
|
)
|
|
|
|
type fakeChain struct {
|
|
h abi.ChainEpoch
|
|
}
|
|
|
|
type fakeConfigStub struct {
|
|
CCSectorLifetime time.Duration
|
|
}
|
|
|
|
func fakeConfigGetter(stub *fakeConfigStub) dtypes.GetSealingConfigFunc {
|
|
return func() (sealiface.Config, error) {
|
|
if stub == nil {
|
|
return sealiface.Config{}, nil
|
|
}
|
|
|
|
return sealiface.Config{
|
|
CommittedCapacitySectorLifetime: stub.CCSectorLifetime,
|
|
}, nil
|
|
}
|
|
}
|
|
|
|
func (f *fakeChain) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) {
|
|
return build.TestNetworkVersion, nil
|
|
}
|
|
|
|
func makeBFTs(t *testing.T, basefee abi.TokenAmount, h abi.ChainEpoch) *types.TipSet {
|
|
dummyCid, _ := cid.Parse("bafkqaaa")
|
|
|
|
var ts, err = types.NewTipSet([]*types.BlockHeader{
|
|
{
|
|
Height: h,
|
|
Miner: builtin.SystemActorAddr,
|
|
|
|
Parents: []cid.Cid{},
|
|
|
|
Ticket: &types.Ticket{VRFProof: []byte{byte(h % 2)}},
|
|
|
|
ParentStateRoot: dummyCid,
|
|
Messages: dummyCid,
|
|
ParentMessageReceipts: dummyCid,
|
|
|
|
BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS},
|
|
BLSAggregate: &crypto.Signature{Type: crypto.SigTypeBLS},
|
|
|
|
ParentBaseFee: basefee,
|
|
},
|
|
})
|
|
if t != nil {
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
return ts
|
|
}
|
|
|
|
func makeTs(t *testing.T, h abi.ChainEpoch) *types.TipSet {
|
|
return makeBFTs(t, big.NewInt(0), h)
|
|
}
|
|
|
|
func (f *fakeChain) ChainHead(ctx context.Context) (*types.TipSet, error) {
|
|
return makeTs(nil, f.h), nil
|
|
}
|
|
|
|
func fakePieceCid(t *testing.T) cid.Cid {
|
|
comm := [32]byte{1, 2, 3}
|
|
fakePieceCid, err := commcid.ReplicaCommitmentV1ToCID(comm[:])
|
|
require.NoError(t, err)
|
|
return fakePieceCid
|
|
}
|
|
|
|
func cidPtr(c cid.Cid) *cid.Cid {
|
|
return &c
|
|
}
|
|
|
|
func TestBasicPolicyEmptySector(t *testing.T) {
|
|
cfg := fakeConfigGetter(nil)
|
|
h := abi.ChainEpoch(55)
|
|
pBuffer := abi.ChainEpoch(2)
|
|
pcp := pipeline.NewBasicPreCommitPolicy(&fakeChain{h: h}, cfg, pBuffer)
|
|
exp, err := pcp.Expiration(context.Background())
|
|
|
|
require.NoError(t, err)
|
|
|
|
// as set when there are no deal pieces
|
|
maxExtension, err := policy.GetMaxSectorExpirationExtension(build.TestNetworkVersion)
|
|
assert.NoError(t, err)
|
|
expected := h + maxExtension - pBuffer
|
|
assert.Equal(t, int(expected), int(exp))
|
|
}
|
|
|
|
func TestCustomCCSectorConfig(t *testing.T) {
|
|
customLifetime := 200 * 24 * time.Hour
|
|
customLifetimeEpochs := abi.ChainEpoch(int64(customLifetime.Seconds()) / builtin.EpochDurationSeconds)
|
|
cfgStub := fakeConfigStub{CCSectorLifetime: customLifetime}
|
|
cfg := fakeConfigGetter(&cfgStub)
|
|
h := abi.ChainEpoch(55)
|
|
pBuffer := abi.ChainEpoch(2)
|
|
pcp := pipeline.NewBasicPreCommitPolicy(&fakeChain{h: h}, cfg, pBuffer)
|
|
exp, err := pcp.Expiration(context.Background())
|
|
|
|
require.NoError(t, err)
|
|
|
|
// as set when there are no deal pieces
|
|
expected := h + customLifetimeEpochs - pBuffer
|
|
assert.Equal(t, int(expected), int(exp))
|
|
}
|
|
|
|
func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) {
|
|
cfg := fakeConfigGetter(nil)
|
|
policy := pipeline.NewBasicPreCommitPolicy(&fakeChain{
|
|
h: abi.ChainEpoch(55),
|
|
}, cfg, 2)
|
|
longestDealEpochEnd := abi.ChainEpoch(547300)
|
|
pieces := []pipeline.SafeSectorPiece{
|
|
pipeline.SafePiece(api.SectorPiece{
|
|
Piece: abi.PieceInfo{
|
|
Size: abi.PaddedPieceSize(1024),
|
|
PieceCID: fakePieceCid(t),
|
|
},
|
|
DealInfo: &piece.PieceDealInfo{
|
|
PublishCid: cidPtr(fakePieceCid(t)), // pretend this is a valid builtin-market deal
|
|
DealID: abi.DealID(42),
|
|
DealSchedule: piece.DealSchedule{
|
|
StartEpoch: abi.ChainEpoch(70),
|
|
EndEpoch: abi.ChainEpoch(547275),
|
|
},
|
|
},
|
|
}),
|
|
pipeline.SafePiece(api.SectorPiece{
|
|
Piece: abi.PieceInfo{
|
|
Size: abi.PaddedPieceSize(1024),
|
|
PieceCID: fakePieceCid(t),
|
|
},
|
|
DealInfo: &piece.PieceDealInfo{
|
|
PublishCid: cidPtr(fakePieceCid(t)), // pretend this is a valid builtin-market deal
|
|
DealID: abi.DealID(43),
|
|
DealSchedule: piece.DealSchedule{
|
|
StartEpoch: abi.ChainEpoch(80),
|
|
EndEpoch: longestDealEpochEnd,
|
|
},
|
|
},
|
|
}),
|
|
}
|
|
|
|
exp, err := policy.Expiration(context.Background(), pieces...)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, int(longestDealEpochEnd), int(exp))
|
|
}
|
|
|
|
func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) {
|
|
cfg := fakeConfigGetter(nil)
|
|
pcp := pipeline.NewBasicPreCommitPolicy(&fakeChain{
|
|
h: abi.ChainEpoch(55),
|
|
}, cfg, 0)
|
|
|
|
pieces := []pipeline.SafeSectorPiece{
|
|
pipeline.SafePiece(api.SectorPiece{
|
|
Piece: abi.PieceInfo{
|
|
Size: abi.PaddedPieceSize(1024),
|
|
PieceCID: fakePieceCid(t),
|
|
},
|
|
DealInfo: &piece.PieceDealInfo{
|
|
PublishCid: cidPtr(fakePieceCid(t)), // pretend this is a valid builtin-market deal
|
|
DealID: abi.DealID(44),
|
|
DealSchedule: piece.DealSchedule{
|
|
StartEpoch: abi.ChainEpoch(1),
|
|
EndEpoch: abi.ChainEpoch(10),
|
|
},
|
|
},
|
|
}),
|
|
}
|
|
|
|
exp, err := pcp.Expiration(context.Background(), pieces...)
|
|
require.NoError(t, err)
|
|
|
|
maxLifetime, err := policy.GetMaxSectorExpirationExtension(build.TestNetworkVersion)
|
|
require.NoError(t, err)
|
|
|
|
// Treated as a CC sector, so expiration becomes currEpoch + maxLifetime = 55 + 1555200
|
|
assert.Equal(t, 55+maxLifetime, exp)
|
|
}
|
|
|
|
func TestMissingDealIsIgnored(t *testing.T) {
|
|
cfg := fakeConfigGetter(nil)
|
|
policy := pipeline.NewBasicPreCommitPolicy(&fakeChain{
|
|
h: abi.ChainEpoch(55),
|
|
}, cfg, 0)
|
|
|
|
pieces := []pipeline.SafeSectorPiece{
|
|
pipeline.SafePiece(api.SectorPiece{
|
|
Piece: abi.PieceInfo{
|
|
Size: abi.PaddedPieceSize(1024),
|
|
PieceCID: fakePieceCid(t),
|
|
},
|
|
DealInfo: &piece.PieceDealInfo{
|
|
PublishCid: cidPtr(fakePieceCid(t)), // pretend this is a valid builtin-market deal
|
|
DealID: abi.DealID(44),
|
|
DealSchedule: piece.DealSchedule{
|
|
StartEpoch: abi.ChainEpoch(1),
|
|
EndEpoch: abi.ChainEpoch(547300),
|
|
},
|
|
},
|
|
}),
|
|
pipeline.SafePiece(api.SectorPiece{
|
|
Piece: abi.PieceInfo{
|
|
Size: abi.PaddedPieceSize(1024),
|
|
PieceCID: fakePieceCid(t),
|
|
},
|
|
DealInfo: nil,
|
|
}),
|
|
}
|
|
|
|
exp, err := policy.Expiration(context.Background(), pieces...)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, 547300, int(exp))
|
|
}
|
|
|
|
func TestBasicPolicyDDO(t *testing.T) {
|
|
cfg := fakeConfigGetter(nil)
|
|
pcp := pipeline.NewBasicPreCommitPolicy(&fakeChain{
|
|
h: abi.ChainEpoch(55),
|
|
}, cfg, 0)
|
|
|
|
pieces := []pipeline.SafeSectorPiece{
|
|
pipeline.SafePiece(api.SectorPiece{
|
|
Piece: abi.PieceInfo{
|
|
Size: abi.PaddedPieceSize(1024),
|
|
PieceCID: fakePieceCid(t),
|
|
},
|
|
DealInfo: &piece.PieceDealInfo{
|
|
PublishCid: nil,
|
|
DealID: abi.DealID(44),
|
|
DealSchedule: piece.DealSchedule{
|
|
StartEpoch: abi.ChainEpoch(100_000),
|
|
EndEpoch: abi.ChainEpoch(1500_000),
|
|
},
|
|
PieceActivationManifest: &miner.PieceActivationManifest{
|
|
Size: 0,
|
|
VerifiedAllocationKey: nil,
|
|
Notify: nil,
|
|
},
|
|
},
|
|
}),
|
|
}
|
|
|
|
exp, err := pcp.Expiration(context.Background(), pieces...)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, abi.ChainEpoch(1500_000), exp)
|
|
}
|