lotus/cmd/lotus-seed/seed/seed.go

161 lines
3.9 KiB
Go
Raw Normal View History

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"
2019-11-27 14:18:51 +00:00
"crypto/sha256"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
"github.com/ipfs/go-datastore"
"github.com/ipfs/go-datastore/namespace"
badger "github.com/ipfs/go-ds-badger2"
logging "github.com/ipfs/go-log/v2"
2019-11-27 14:18:51 +00:00
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
2019-11-28 22:50:58 +00:00
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
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")
func PreSeal(maddr address.Address, ssize uint64, offset uint64, sectors int, sbroot string, preimage []byte) (*genesis.GenesisMiner, error) {
2019-11-27 14:18:51 +00:00
cfg := &sectorbuilder.Config{
Miner: maddr,
SectorSize: ssize,
FallbackLastID: offset,
Dir: sbroot,
WorkerThreads: 2,
2019-11-27 14:18:51 +00:00
}
if err := os.MkdirAll(sbroot, 0775); err != nil {
return nil, err
2019-11-27 14:18:51 +00:00
}
mds, err := badger.NewDatastore(filepath.Join(sbroot, "badger"), nil)
if err != nil {
2019-11-29 03:38:18 +00:00
return nil, err
2019-11-27 14:18:51 +00:00
}
sb, err := sectorbuilder.New(cfg, namespace.Wrap(mds, datastore.NewKey("/sectorbuilder")))
2019-11-27 14:18:51 +00:00
if err != nil {
2019-11-29 03:38:18 +00:00
return nil, err
2019-11-27 14:18:51 +00:00
}
size := sectorbuilder.UserBytesForSectorSize(ssize)
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++ {
2019-11-27 14:18:51 +00:00
sid, err := sb.AcquireSectorId()
if err != nil {
2019-11-29 03:38:18 +00:00
return nil, err
2019-11-27 14:18:51 +00:00
}
2019-12-07 14:12:10 +00:00
pi, err := sb.AddPiece(size, sid, rand.Reader, nil)
2019-11-27 14:18:51 +00:00
if err != nil {
2019-11-29 03:38:18 +00:00
return nil, err
2019-11-27 14:18:51 +00:00
}
trand := sha256.Sum256(preimage)
ticket := sectorbuilder.SealTicket{
TicketBytes: trand,
}
fmt.Printf("sector-id: %d, piece info: %v", sid, pi)
2019-11-27 14:18:51 +00:00
pco, err := sb.SealPreCommit(context.TODO(), sid, ticket, []sectorbuilder.PublicPieceInfo{pi})
2019-11-27 14:18:51 +00:00
if err != nil {
2019-11-29 03:38:18 +00:00
return nil, xerrors.Errorf("commit: %w", err)
2019-11-27 14:18:51 +00:00
}
2019-12-06 21:15:06 +00:00
if err := sb.TrimCache(sid); err != nil {
return nil, xerrors.Errorf("trim cache: %w", err)
}
2019-11-30 23:17:50 +00:00
log.Warn("PreCommitOutput: ", sid, pco)
2019-11-28 22:50:58 +00:00
sealedSectors = append(sealedSectors, &genesis.PreSeal{
2019-11-27 14:18:51 +00:00
CommR: pco.CommR,
CommD: pco.CommD,
SectorID: sid,
})
}
2019-11-28 22:50:58 +00:00
minerAddr, err := wallet.GenerateKey(types.KTBLS)
if err != nil {
2019-11-29 03:38:18 +00:00
return nil, err
2019-11-28 22:50:58 +00:00
}
miner := &genesis.GenesisMiner{
Owner: minerAddr.Address,
Worker: minerAddr.Address,
SectorSize: ssize,
Sectors: sealedSectors,
Key: minerAddr.KeyInfo,
}
if err := createDeals(miner, minerAddr, maddr, ssize); err != nil {
2019-11-29 03:38:18 +00:00
return nil, xerrors.Errorf("creating deals: %w", err)
}
if err := mds.Close(); err != nil {
return nil, xerrors.Errorf("closing datastore: %w", err)
2019-11-28 22:50:58 +00:00
}
2019-11-29 03:38:18 +00:00
return miner, nil
}
func WriteGenesisMiner(maddr address.Address, sbroot string, gm *genesis.GenesisMiner) error {
2019-11-27 14:18:51 +00:00
output := map[string]genesis.GenesisMiner{
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
}
if err := ioutil.WriteFile(filepath.Join(sbroot, "pre-seal-"+maddr.String()+".json"), out, 0664); err != nil {
return err
}
return nil
}
2019-11-28 22:50:58 +00:00
func createDeals(m *genesis.GenesisMiner, k *wallet.Key, maddr address.Address, ssize uint64) error {
2019-11-28 22:50:58 +00:00
for _, sector := range m.Sectors {
2019-12-06 09:00:16 +00:00
pref := make([]byte, len(sector.CommD))
2019-12-06 09:19:17 +00:00
copy(pref, sector.CommD[:])
2019-11-28 22:50:58 +00:00
proposal := &actors.StorageDealProposal{
2019-12-06 09:00:16 +00:00
PieceRef: pref, // just one deal so this == CommP
PieceSize: sectorbuilder.UserBytesForSectorSize(ssize),
2019-11-28 22:50:58 +00:00
Client: k.Address,
Provider: maddr,
2019-11-28 22:50:58 +00:00
ProposalExpiration: 9000, // TODO: allow setting
Duration: 9000,
StoragePricePerEpoch: types.NewInt(0),
StorageCollateral: types.NewInt(0),
ProposerSignature: nil,
}
2019-12-07 14:12:10 +00:00
// TODO: pretty sure we don't even need to sign this
2019-11-28 22:50:58 +00:00
if err := api.SignWith(context.TODO(), wallet.KeyWallet(k).Sign, k.Address, proposal); err != nil {
return err
}
2019-12-07 14:12:10 +00:00
sector.Deal = *proposal
2019-11-28 22:50:58 +00:00
}
return nil
}