2019-11-27 14:18:51 +00:00
|
|
|
package seed
|
|
|
|
|
|
|
|
import (
|
2019-11-28 22:50:58 +00:00
|
|
|
"context"
|
2019-12-07 14:12:10 +00:00
|
|
|
"crypto/rand"
|
2020-02-12 21:41:59 +00:00
|
|
|
"encoding/hex"
|
2019-11-27 14:18:51 +00:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
|
2020-03-03 22:19:22 +00:00
|
|
|
"github.com/google/uuid"
|
2020-01-08 19:10:57 +00:00
|
|
|
logging "github.com/ipfs/go-log/v2"
|
2020-04-17 16:22:17 +00:00
|
|
|
ic "github.com/libp2p/go-libp2p-core/crypto"
|
|
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
2020-05-27 20:53:20 +00:00
|
|
|
"github.com/minio/blake2b-simd"
|
2019-11-27 14:18:51 +00:00
|
|
|
"golang.org/x/xerrors"
|
|
|
|
|
2020-07-03 01:29:06 +00:00
|
|
|
ffi "github.com/filecoin-project/filecoin-ffi"
|
2019-12-19 20:13:17 +00:00
|
|
|
"github.com/filecoin-project/go-address"
|
2020-11-20 00:28:18 +00:00
|
|
|
"github.com/filecoin-project/go-commp-utils/zerocomm"
|
2020-09-07 03:49:10 +00:00
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
|
|
"github.com/filecoin-project/go-state-types/big"
|
2022-04-20 21:34:28 +00:00
|
|
|
market8 "github.com/filecoin-project/go-state-types/builtin/v8/market"
|
2022-06-14 15:00:51 +00:00
|
|
|
"github.com/filecoin-project/specs-storage/storage"
|
2020-02-08 02:18:32 +00:00
|
|
|
|
2019-11-28 22:50:58 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
|
|
"github.com/filecoin-project/lotus/chain/wallet"
|
2020-08-17 13:26:18 +00:00
|
|
|
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
|
|
|
|
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper/basicfs"
|
|
|
|
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
2020-09-30 17:32:19 +00:00
|
|
|
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
2019-11-27 14:18:51 +00:00
|
|
|
"github.com/filecoin-project/lotus/genesis"
|
|
|
|
)
|
|
|
|
|
2019-11-30 23:17:50 +00:00
|
|
|
var log = logging.Logger("preseal")
|
|
|
|
|
2020-07-03 01:29:06 +00:00
|
|
|
func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.SectorNumber, sectors int, sbroot string, preimage []byte, key *types.KeyInfo, fakeSectors bool) (*genesis.Miner, *types.KeyInfo, error) {
|
2020-03-17 20:19:52 +00:00
|
|
|
mid, err := address.IDFromAddress(maddr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
2020-05-27 23:15:19 +00:00
|
|
|
if err := os.MkdirAll(sbroot, 0775); err != nil { //nolint:gosec
|
2020-02-12 21:41:59 +00:00
|
|
|
return nil, nil, err
|
2019-11-27 14:18:51 +00:00
|
|
|
}
|
|
|
|
|
2020-03-06 05:30:47 +00:00
|
|
|
next := offset
|
|
|
|
|
2020-03-26 02:50:56 +00:00
|
|
|
sbfs := &basicfs.Provider{
|
2020-03-18 01:08:11 +00:00
|
|
|
Root: sbroot,
|
2020-03-03 22:19:22 +00:00
|
|
|
}
|
|
|
|
|
2020-11-04 20:29:08 +00:00
|
|
|
sb, err := ffiwrapper.New(sbfs)
|
2019-11-27 14:18:51 +00:00
|
|
|
if err != nil {
|
2020-02-12 21:41:59 +00:00
|
|
|
return nil, nil, err
|
2019-11-27 14:18:51 +00:00
|
|
|
}
|
|
|
|
|
2020-06-15 16:30:49 +00:00
|
|
|
ssize, err := spt.SectorSize()
|
2020-02-27 00:42:39 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
2019-11-28 22:50:58 +00:00
|
|
|
var sealedSectors []*genesis.PreSeal
|
2019-11-30 23:17:50 +00:00
|
|
|
for i := 0; i < sectors; i++ {
|
2020-03-17 20:19:52 +00:00
|
|
|
sid := abi.SectorID{Miner: abi.ActorID(mid), Number: next}
|
2020-11-05 05:31:19 +00:00
|
|
|
ref := storage.SectorRef{ID: sid, ProofType: spt}
|
2020-03-06 05:30:47 +00:00
|
|
|
next++
|
2019-11-27 14:18:51 +00:00
|
|
|
|
2020-07-03 01:29:06 +00:00
|
|
|
var preseal *genesis.PreSeal
|
|
|
|
if !fakeSectors {
|
2020-11-05 05:31:19 +00:00
|
|
|
preseal, err = presealSector(sb, sbfs, ref, ssize, preimage)
|
2020-07-03 01:29:06 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
} else {
|
2020-11-05 05:31:19 +00:00
|
|
|
preseal, err = presealSectorFake(sbfs, ref, ssize)
|
2020-07-03 01:29:06 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2020-06-16 22:35:51 +00:00
|
|
|
}
|
|
|
|
|
2020-07-03 00:47:33 +00:00
|
|
|
sealedSectors = append(sealedSectors, preseal)
|
2019-11-27 14:18:51 +00:00
|
|
|
}
|
|
|
|
|
2020-02-12 21:41:59 +00:00
|
|
|
var minerAddr *wallet.Key
|
|
|
|
if key != nil {
|
|
|
|
minerAddr, err = wallet.NewKey(*key)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
} else {
|
2020-10-11 18:12:01 +00:00
|
|
|
minerAddr, err = wallet.GenerateKey(types.KTBLS)
|
2020-02-12 21:41:59 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2019-11-28 22:50:58 +00:00
|
|
|
}
|
|
|
|
|
2020-04-17 16:22:17 +00:00
|
|
|
var pid peer.ID
|
|
|
|
{
|
|
|
|
log.Warn("PeerID not specified, generating dummy")
|
|
|
|
p, _, err := ic.GenerateEd25519Key(rand.Reader)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
pid, err = peer.IDFromPrivateKey(p)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-12 00:58:55 +00:00
|
|
|
miner := &genesis.Miner{
|
2020-08-19 19:54:33 +00:00
|
|
|
ID: maddr,
|
2020-02-14 20:33:41 +00:00
|
|
|
Owner: minerAddr.Address,
|
|
|
|
Worker: minerAddr.Address,
|
|
|
|
MarketBalance: big.Zero(),
|
|
|
|
PowerBalance: big.Zero(),
|
|
|
|
SectorSize: ssize,
|
|
|
|
Sectors: sealedSectors,
|
2020-04-17 16:22:17 +00:00
|
|
|
PeerId: pid,
|
2019-11-28 22:50:58 +00:00
|
|
|
}
|
|
|
|
|
2020-02-12 00:58:55 +00:00
|
|
|
if err := createDeals(miner, minerAddr, maddr, ssize); err != nil {
|
2020-02-12 21:41:59 +00:00
|
|
|
return nil, nil, xerrors.Errorf("creating deals: %w", err)
|
2019-11-29 03:38:18 +00:00
|
|
|
}
|
|
|
|
|
2020-03-03 22:19:22 +00:00
|
|
|
{
|
2020-03-19 15:10:19 +00:00
|
|
|
b, err := json.MarshalIndent(&stores.LocalStorageMeta{
|
2022-01-18 10:57:04 +00:00
|
|
|
ID: storiface.ID(uuid.New().String()),
|
2020-03-05 00:38:07 +00:00
|
|
|
Weight: 0, // read-only
|
|
|
|
CanSeal: false,
|
|
|
|
CanStore: false,
|
2020-03-04 02:24:08 +00:00
|
|
|
}, "", " ")
|
2020-03-03 22:19:22 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, xerrors.Errorf("marshaling storage config: %w", err)
|
|
|
|
}
|
|
|
|
|
2020-03-05 01:12:52 +00:00
|
|
|
if err := ioutil.WriteFile(filepath.Join(sbroot, "sectorstore.json"), b, 0644); err != nil {
|
2020-03-03 22:19:22 +00:00
|
|
|
return nil, nil, xerrors.Errorf("persisting storage metadata (%s): %w", filepath.Join(sbroot, "storage.json"), err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-12 21:41:59 +00:00
|
|
|
return miner, &minerAddr.KeyInfo, nil
|
2019-11-29 03:38:18 +00:00
|
|
|
}
|
|
|
|
|
2020-11-05 05:31:19 +00:00
|
|
|
func presealSector(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, sid storage.SectorRef, ssize abi.SectorSize, preimage []byte) (*genesis.PreSeal, error) {
|
2020-07-03 00:47:33 +00:00
|
|
|
pi, err := sb.AddPiece(context.TODO(), sid, nil, abi.PaddedPieceSize(ssize).Unpadded(), rand.Reader)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
trand := blake2b.Sum256(preimage)
|
|
|
|
ticket := abi.SealRandomness(trand[:])
|
|
|
|
|
|
|
|
fmt.Printf("sector-id: %d, piece info: %v\n", sid, pi)
|
|
|
|
|
|
|
|
in2, err := sb.SealPreCommit1(context.TODO(), sid, ticket, []abi.PieceInfo{pi})
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("commit: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
cids, err := sb.SealPreCommit2(context.TODO(), sid, in2)
|
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("commit: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := sb.FinalizeSector(context.TODO(), sid, nil); err != nil {
|
|
|
|
return nil, xerrors.Errorf("trim cache: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := cleanupUnsealed(sbfs, sid); err != nil {
|
|
|
|
return nil, xerrors.Errorf("remove unsealed file: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Warn("PreCommitOutput: ", sid, cids.Sealed, cids.Unsealed)
|
|
|
|
|
|
|
|
return &genesis.PreSeal{
|
|
|
|
CommR: cids.Sealed,
|
|
|
|
CommD: cids.Unsealed,
|
2020-11-05 05:31:19 +00:00
|
|
|
SectorID: sid.ID.Number,
|
|
|
|
ProofType: sid.ProofType,
|
2020-07-03 00:47:33 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2020-11-05 05:31:19 +00:00
|
|
|
func presealSectorFake(sbfs *basicfs.Provider, sid storage.SectorRef, ssize abi.SectorSize) (*genesis.PreSeal, error) {
|
2020-09-06 16:54:00 +00:00
|
|
|
paths, done, err := sbfs.AcquireSector(context.TODO(), sid, 0, storiface.FTSealed|storiface.FTCache, storiface.PathSealing)
|
2020-07-03 01:29:06 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("acquire unsealed sector: %w", err)
|
|
|
|
}
|
|
|
|
defer done()
|
|
|
|
|
|
|
|
if err := os.Mkdir(paths.Cache, 0755); err != nil {
|
|
|
|
return nil, xerrors.Errorf("mkdir cache: %w", err)
|
|
|
|
}
|
|
|
|
|
2020-11-05 05:31:19 +00:00
|
|
|
commr, err := ffi.FauxRep(sid.ProofType, paths.Cache, paths.Sealed)
|
2020-07-03 01:29:06 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, xerrors.Errorf("fauxrep: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &genesis.PreSeal{
|
|
|
|
CommR: commr,
|
|
|
|
CommD: zerocomm.ZeroPieceCommitment(abi.PaddedPieceSize(ssize).Unpadded()),
|
2020-11-05 05:31:19 +00:00
|
|
|
SectorID: sid.ID.Number,
|
|
|
|
ProofType: sid.ProofType,
|
2020-07-03 01:29:06 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2020-11-05 05:31:19 +00:00
|
|
|
func cleanupUnsealed(sbfs *basicfs.Provider, ref storage.SectorRef) error {
|
|
|
|
paths, done, err := sbfs.AcquireSector(context.TODO(), ref, storiface.FTUnsealed, storiface.FTNone, storiface.PathSealing)
|
2020-06-16 22:35:51 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer done()
|
|
|
|
|
|
|
|
return os.Remove(paths.Unsealed)
|
|
|
|
}
|
|
|
|
|
2020-02-12 21:41:59 +00:00
|
|
|
func WriteGenesisMiner(maddr address.Address, sbroot string, gm *genesis.Miner, key *types.KeyInfo) error {
|
2020-02-12 00:58:55 +00:00
|
|
|
output := map[string]genesis.Miner{
|
2019-11-29 03:38:18 +00:00
|
|
|
maddr.String(): *gm,
|
2019-11-27 14:18:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
out, err := json.MarshalIndent(output, "", " ")
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-02-21 20:56:30 +00:00
|
|
|
log.Infof("Writing preseal manifest to %s", filepath.Join(sbroot, "pre-seal-"+maddr.String()+".json"))
|
|
|
|
|
2019-11-27 14:18:51 +00:00
|
|
|
if err := ioutil.WriteFile(filepath.Join(sbroot, "pre-seal-"+maddr.String()+".json"), out, 0664); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-02-12 21:41:59 +00:00
|
|
|
if key != nil {
|
|
|
|
b, err := json.Marshal(key)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: allow providing key
|
|
|
|
if err := ioutil.WriteFile(filepath.Join(sbroot, "pre-seal-"+maddr.String()+".key"), []byte(hex.EncodeToString(b)), 0664); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-27 14:18:51 +00:00
|
|
|
return nil
|
|
|
|
}
|
2019-11-28 22:50:58 +00:00
|
|
|
|
2020-02-12 00:58:55 +00:00
|
|
|
func createDeals(m *genesis.Miner, k *wallet.Key, maddr address.Address, ssize abi.SectorSize) error {
|
2020-07-01 12:04:37 +00:00
|
|
|
for i, sector := range m.Sectors {
|
2022-03-12 18:07:35 +00:00
|
|
|
label, err := market8.NewLabelFromString(fmt.Sprintf("%d", i))
|
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("error creating deal label: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
proposal := &market8.DealProposal{
|
2020-02-27 00:42:39 +00:00
|
|
|
PieceCID: sector.CommD,
|
2020-02-08 02:18:32 +00:00
|
|
|
PieceSize: abi.PaddedPieceSize(ssize),
|
2019-11-28 22:50:58 +00:00
|
|
|
Client: k.Address,
|
2019-12-01 20:07:42 +00:00
|
|
|
Provider: maddr,
|
2022-03-12 18:07:35 +00:00
|
|
|
Label: label,
|
2020-02-11 20:48:03 +00:00
|
|
|
StartEpoch: 0,
|
2020-02-08 02:18:32 +00:00
|
|
|
EndEpoch: 9001,
|
|
|
|
StoragePricePerEpoch: big.Zero(),
|
2020-02-08 02:18:37 +00:00
|
|
|
ProviderCollateral: big.Zero(),
|
|
|
|
ClientCollateral: big.Zero(),
|
2019-11-28 22:50:58 +00:00
|
|
|
}
|
|
|
|
|
2022-05-15 19:26:52 +00:00
|
|
|
sector.DealClientKey = k
|
2019-12-07 14:12:10 +00:00
|
|
|
sector.Deal = *proposal
|
2019-11-28 22:50:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|