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"
|
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-02-08 02:18:32 +00:00
|
|
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
|
|
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
|
|
|
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
|
|
|
"github.com/ipfs/go-cid"
|
2020-01-09 13:23:44 +00:00
|
|
|
"github.com/ipfs/go-datastore"
|
|
|
|
"github.com/ipfs/go-datastore/namespace"
|
2020-01-08 18:56:45 +00:00
|
|
|
badger "github.com/ipfs/go-ds-badger2"
|
2020-01-08 19:10:57 +00:00
|
|
|
logging "github.com/ipfs/go-log/v2"
|
2020-02-08 02:18:32 +00:00
|
|
|
"github.com/multiformats/go-multihash"
|
2019-11-27 14:18:51 +00:00
|
|
|
"golang.org/x/xerrors"
|
|
|
|
|
2020-02-08 02:18:32 +00:00
|
|
|
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
|
|
|
|
|
2019-12-19 20:13:17 +00:00
|
|
|
"github.com/filecoin-project/go-address"
|
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"
|
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-02-12 21:41:59 +00:00
|
|
|
func PreSeal(maddr address.Address, ssize abi.SectorSize, offset abi.SectorNumber, sectors int, sbroot string, preimage []byte, key *types.KeyInfo) (*genesis.Miner, *types.KeyInfo, error) {
|
2019-11-27 14:18:51 +00:00
|
|
|
cfg := §orbuilder.Config{
|
2020-02-11 20:48:03 +00:00
|
|
|
Miner: maddr,
|
|
|
|
SectorSize: ssize,
|
2020-02-11 01:10:50 +00:00
|
|
|
FallbackLastNum: offset,
|
2020-02-11 20:48:03 +00:00
|
|
|
Paths: sectorbuilder.SimplePath(sbroot),
|
|
|
|
WorkerThreads: 2,
|
2019-11-27 14:18:51 +00:00
|
|
|
}
|
|
|
|
|
2019-12-16 13:49:58 +00:00
|
|
|
if err := os.MkdirAll(sbroot, 0775); err != nil {
|
2020-02-12 21:41:59 +00:00
|
|
|
return nil, nil, err
|
2019-11-27 14:18:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mds, err := badger.NewDatastore(filepath.Join(sbroot, "badger"), nil)
|
|
|
|
if err != nil {
|
2020-02-12 21:41:59 +00:00
|
|
|
return nil, nil, err
|
2019-11-27 14:18:51 +00:00
|
|
|
}
|
|
|
|
|
2020-01-09 13:23:44 +00:00
|
|
|
sb, err := sectorbuilder.New(cfg, namespace.Wrap(mds, datastore.NewKey("/sectorbuilder")))
|
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
|
|
|
}
|
|
|
|
|
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-02-11 01:10:50 +00:00
|
|
|
sid, err := sb.AcquireSectorNumber()
|
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-02-08 02:18:32 +00:00
|
|
|
pi, err := sb.AddPiece(context.TODO(), abi.PaddedPieceSize(ssize).Unpadded(), sid, rand.Reader, nil)
|
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
|
|
|
}
|
|
|
|
|
|
|
|
trand := sha256.Sum256(preimage)
|
|
|
|
ticket := sectorbuilder.SealTicket{
|
|
|
|
TicketBytes: trand,
|
|
|
|
}
|
|
|
|
|
2019-12-06 18:47:55 +00:00
|
|
|
fmt.Printf("sector-id: %d, piece info: %v", sid, pi)
|
2019-11-27 14:18:51 +00:00
|
|
|
|
2020-01-09 20:50:45 +00:00
|
|
|
pco, err := sb.SealPreCommit(context.TODO(), sid, ticket, []sectorbuilder.PublicPieceInfo{pi})
|
2019-11-27 14:18:51 +00:00
|
|
|
if err != nil {
|
2020-02-12 21:41:59 +00:00
|
|
|
return nil, nil, xerrors.Errorf("commit: %w", err)
|
2019-11-27 14:18:51 +00:00
|
|
|
}
|
|
|
|
|
2020-01-28 23:08:02 +00:00
|
|
|
if err := sb.TrimCache(context.TODO(), sid); err != nil {
|
2020-02-12 21:41:59 +00:00
|
|
|
return nil, nil, xerrors.Errorf("trim cache: %w", err)
|
2019-12-06 21:15:06 +00:00
|
|
|
}
|
|
|
|
|
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,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
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 {
|
|
|
|
minerAddr, err = wallet.GenerateKey(types.KTBLS)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2019-11-28 22:50:58 +00:00
|
|
|
}
|
|
|
|
|
2020-02-12 00:58:55 +00:00
|
|
|
miner := &genesis.Miner{
|
2019-11-28 22:50:58 +00:00
|
|
|
Owner: minerAddr.Address,
|
|
|
|
Worker: minerAddr.Address,
|
|
|
|
|
|
|
|
SectorSize: ssize,
|
|
|
|
|
|
|
|
Sectors: sealedSectors,
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
if err := mds.Close(); err != nil {
|
2020-02-12 21:41:59 +00:00
|
|
|
return nil, nil, xerrors.Errorf("closing datastore: %w", err)
|
2019-11-28 22:50:58 +00:00
|
|
|
}
|
|
|
|
|
2020-02-12 21:41:59 +00:00
|
|
|
return miner, &minerAddr.KeyInfo, nil
|
2019-11-29 03:38:18 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
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-08 02:18:32 +00:00
|
|
|
func commDCID(commd []byte) cid.Cid {
|
|
|
|
d, err := cid.Prefix{
|
|
|
|
Version: 1,
|
|
|
|
Codec: cid.Raw,
|
|
|
|
MhType: multihash.IDENTITY,
|
|
|
|
MhLength: len(commd),
|
|
|
|
}.Sum(commd)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return d
|
|
|
|
}
|
|
|
|
|
2020-02-12 00:58:55 +00:00
|
|
|
func createDeals(m *genesis.Miner, k *wallet.Key, maddr address.Address, ssize abi.SectorSize) 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[:])
|
2020-02-08 02:18:32 +00:00
|
|
|
proposal := &market.DealProposal{
|
|
|
|
PieceCID: commDCID(pref), // just one deal so this == CommP
|
|
|
|
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,
|
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
|
|
|
}
|
|
|
|
|
2019-12-07 14:12:10 +00:00
|
|
|
sector.Deal = *proposal
|
2019-11-28 22:50:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|