Almost working new post code
This commit is contained in:
parent
1024812559
commit
fe8e1fe1e4
@ -28,7 +28,7 @@ const MaxVouchersPerDeal = 768 // roughly one voucher per 10h over a year
|
||||
// Consensus / Network
|
||||
|
||||
// Seconds
|
||||
const BlockDelay = 6
|
||||
const BlockDelay = 4
|
||||
|
||||
// Seconds
|
||||
const AllowableClockDrift = BlockDelay * 2
|
||||
@ -43,10 +43,10 @@ const ForkLengthThreshold = 20
|
||||
const RandomnessLookback = 20
|
||||
|
||||
// Blocks
|
||||
const ProvingPeriodDuration = 40
|
||||
const ProvingPeriodDuration = 10
|
||||
|
||||
// Blocks
|
||||
const PoSTChallangeTime = 20
|
||||
const PoSTChallangeTime = 5
|
||||
|
||||
const PowerCollateralProportion = 20
|
||||
const PerCapitaCollateralProportion = 5
|
||||
|
@ -420,7 +420,7 @@ func (c *wsConn) handleWsConn(ctx context.Context) {
|
||||
case r, ok := <-c.incoming:
|
||||
if !ok {
|
||||
if c.incomingErr != nil {
|
||||
log.Debugf("websocket error", "error", c.incomingErr)
|
||||
log.Warnw("websocket error", "error", c.incomingErr)
|
||||
}
|
||||
return // remote closed
|
||||
}
|
||||
@ -443,7 +443,7 @@ func (c *wsConn) handleWsConn(ctx context.Context) {
|
||||
c.sendRequest(req.req)
|
||||
case <-c.stop:
|
||||
if err := c.conn.Close(); err != nil {
|
||||
log.Debugf("websocket close error", "error", err)
|
||||
log.Warnw("websocket close error", "error", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ func MakeGenesis(outFile string) func(bs dtypes.ChainBlockstore, w *wallet.Walle
|
||||
}
|
||||
|
||||
addrs := map[address.Address]types.BigInt{
|
||||
minerAddr: types.NewInt(5000000000000000000),
|
||||
minerAddr: types.FromFil(100000),
|
||||
}
|
||||
|
||||
b, err := gen.MakeGenesisBlock(bs, addrs, gmc, 100000)
|
||||
|
161
storage/miner.go
161
storage/miner.go
@ -2,14 +2,13 @@ package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"sync"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-datastore"
|
||||
logging "github.com/ipfs/go-log"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/xerrors"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/api"
|
||||
"github.com/filecoin-project/go-lotus/build"
|
||||
@ -173,162 +172,6 @@ func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSeal
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Miner) beginPosting(ctx context.Context) {
|
||||
ts, err := m.api.ChainHead(context.TODO())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
ppe, err := m.api.StateMinerProvingPeriodEnd(ctx, m.maddr, ts)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get proving period end for miner: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if ppe == 0 {
|
||||
log.Errorf("Proving period end == 0")
|
||||
return
|
||||
}
|
||||
|
||||
m.schedLk.Lock()
|
||||
if m.schedPost >= 0 {
|
||||
log.Warnf("PoSts already running %d", m.schedPost)
|
||||
m.schedLk.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
provingPeriodOffset := ppe % build.ProvingPeriodDuration
|
||||
provingPeriod := (ts.Height()-provingPeriodOffset-1)/build.ProvingPeriodDuration + 1
|
||||
m.schedPost = provingPeriod*build.ProvingPeriodDuration + provingPeriodOffset
|
||||
|
||||
m.schedLk.Unlock()
|
||||
|
||||
log.Infof("Scheduling post at height %d", ppe-build.PoSTChallangeTime)
|
||||
err = m.events.ChainAt(m.computePost(m.schedPost), func(ts *types.TipSet) error { // Revert
|
||||
// TODO: Cancel post
|
||||
log.Errorf("TODO: Cancel PoSt, re-run")
|
||||
return nil
|
||||
}, PoStConfidence, ppe-build.PoSTChallangeTime)
|
||||
if err != nil {
|
||||
// TODO: This is BAD, figure something out
|
||||
log.Errorf("scheduling PoSt failed: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Miner) scheduleNextPost(ppe uint64) {
|
||||
ts, err := m.api.ChainHead(context.TODO())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
// TODO: retry
|
||||
return
|
||||
}
|
||||
|
||||
provingPeriodOffset := ppe % build.ProvingPeriodDuration
|
||||
provingPeriod := (ts.Height()-provingPeriodOffset-1)/build.ProvingPeriodDuration + 1
|
||||
headPPE := provingPeriod*build.ProvingPeriodDuration + provingPeriodOffset
|
||||
if headPPE > ppe {
|
||||
log.Warn("PoSt computation running behind chain")
|
||||
ppe = headPPE
|
||||
}
|
||||
|
||||
m.schedLk.Lock()
|
||||
if m.schedPost >= ppe {
|
||||
// this probably can't happen
|
||||
log.Error("PoSt already scheduled: %d >= %d", m.schedPost, ppe)
|
||||
m.schedLk.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
m.schedPost = ppe
|
||||
m.schedLk.Unlock()
|
||||
|
||||
log.Infof("Scheduling post at height %d", ppe-build.PoSTChallangeTime)
|
||||
err = m.events.ChainAt(m.computePost(ppe), func(ts *types.TipSet) error { // Revert
|
||||
// TODO: Cancel post
|
||||
log.Errorf("TODO: Cancel PoSt, re-run")
|
||||
return nil
|
||||
}, PoStConfidence, ppe-build.PoSTChallangeTime)
|
||||
if err != nil {
|
||||
// TODO: This is BAD, figure something out
|
||||
log.Errorf("scheduling PoSt failed: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Miner) computePost(ppe uint64) func(ts *types.TipSet, curH uint64) error {
|
||||
return func(ts *types.TipSet, curH uint64) error {
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
sset, err := m.api.StateMinerProvingSet(ctx, m.maddr, ts)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get proving set for miner: %w", err)
|
||||
}
|
||||
|
||||
r, err := m.api.ChainGetRandomness(ctx, ts, nil, int(int64(ts.Height())-int64(ppe)+int64(build.PoSTChallangeTime))) // TODO: review: check math
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get chain randomness for post: %w", err)
|
||||
}
|
||||
|
||||
log.Infof("running PoSt computation, rh=%d r=%s, ppe=%d, h=%d", ts.Height()-(ts.Height()-ppe+build.PoSTChallangeTime), base64.StdEncoding.EncodeToString(r), ppe, ts.Height())
|
||||
var faults []uint64
|
||||
proof, err := m.secst.RunPoSt(ctx, sset, r, faults)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("running post failed: %w", err)
|
||||
}
|
||||
|
||||
log.Infof("submitting PoSt pLen=%d", len(proof))
|
||||
|
||||
params := &actors.SubmitPoStParams{
|
||||
Proof: proof,
|
||||
DoneSet: types.BitFieldFromSet(sectorIdList(sset)),
|
||||
}
|
||||
|
||||
enc, aerr := actors.SerializeParams(params)
|
||||
if aerr != nil {
|
||||
return xerrors.Errorf("could not serialize submit post parameters: %w", err)
|
||||
}
|
||||
|
||||
msg := &types.Message{
|
||||
To: m.maddr,
|
||||
From: m.worker,
|
||||
Method: actors.MAMethods.SubmitPoSt,
|
||||
Params: enc,
|
||||
Value: types.NewInt(1000), // currently hard-coded late fee in actor, returned if not late
|
||||
GasLimit: types.NewInt(100000 /* i dont know help */),
|
||||
GasPrice: types.NewInt(1),
|
||||
}
|
||||
|
||||
smsg, err := m.api.MpoolPushMessage(ctx, msg)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("pushing message to mpool: %w", err)
|
||||
}
|
||||
|
||||
// make sure it succeeds...
|
||||
rec, err := m.api.ChainWaitMsg(ctx, smsg.Cid())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rec.Receipt.ExitCode != 0 {
|
||||
log.Warnf("SubmitPoSt EXIT: %d", rec.Receipt.ExitCode)
|
||||
// TODO: Do something
|
||||
}
|
||||
|
||||
m.scheduleNextPost(ppe + build.ProvingPeriodDuration)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func sectorIdList(si []*api.SectorInfo) []uint64 {
|
||||
out := make([]uint64, len(si))
|
||||
for i, s := range si {
|
||||
out[i] = s.SectorID
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (m *Miner) runPreflightChecks(ctx context.Context) error {
|
||||
worker, err := m.api.StateMinerWorker(ctx, m.maddr, nil)
|
||||
if err != nil {
|
||||
|
173
storage/post.go
Normal file
173
storage/post.go
Normal file
@ -0,0 +1,173 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/api"
|
||||
"github.com/filecoin-project/go-lotus/build"
|
||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
)
|
||||
|
||||
func (m *Miner) beginPosting(ctx context.Context) {
|
||||
ts, err := m.api.ChainHead(context.TODO())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
ppe, err := m.api.StateMinerProvingPeriodEnd(ctx, m.maddr, ts)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get proving period end for miner: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if ppe == 0 {
|
||||
log.Errorf("Proving period end == 0")
|
||||
return
|
||||
}
|
||||
|
||||
m.schedLk.Lock()
|
||||
if m.schedPost > 0 {
|
||||
log.Warnf("PoSts already running %d", m.schedPost)
|
||||
m.schedLk.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
provingPeriodOffset := ppe % build.ProvingPeriodDuration
|
||||
provingPeriod := (ts.Height()-provingPeriodOffset)/build.ProvingPeriodDuration + 1
|
||||
m.schedPost = provingPeriod*build.ProvingPeriodDuration + provingPeriodOffset
|
||||
|
||||
m.schedLk.Unlock()
|
||||
|
||||
log.Infof("Scheduling post at height %d", ppe-build.PoSTChallangeTime)
|
||||
err = m.events.ChainAt(m.computePost(m.schedPost), func(ts *types.TipSet) error { // Revert
|
||||
// TODO: Cancel post
|
||||
log.Errorf("TODO: Cancel PoSt, re-run")
|
||||
return nil
|
||||
}, PoStConfidence, ppe-build.PoSTChallangeTime)
|
||||
if err != nil {
|
||||
// TODO: This is BAD, figure something out
|
||||
log.Errorf("scheduling PoSt failed: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Miner) scheduleNextPost(ppe uint64) {
|
||||
ts, err := m.api.ChainHead(context.TODO())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
// TODO: retry
|
||||
return
|
||||
}
|
||||
|
||||
provingPeriodOffset := ppe % build.ProvingPeriodDuration
|
||||
provingPeriod := (ts.Height()-provingPeriodOffset-1)/build.ProvingPeriodDuration + 1
|
||||
headPPE := provingPeriod*build.ProvingPeriodDuration + provingPeriodOffset
|
||||
if headPPE > ppe {
|
||||
log.Warn("PoSt computation running behind chain")
|
||||
ppe = headPPE
|
||||
}
|
||||
|
||||
m.schedLk.Lock()
|
||||
if m.schedPost >= ppe {
|
||||
// this probably can't happen
|
||||
log.Error("PoSt already scheduled: %d >= %d", m.schedPost, ppe)
|
||||
m.schedLk.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
m.schedPost = ppe
|
||||
m.schedLk.Unlock()
|
||||
|
||||
log.Infof("Scheduling post at height %d", ppe-build.PoSTChallangeTime)
|
||||
err = m.events.ChainAt(m.computePost(ppe), func(ts *types.TipSet) error { // Revert
|
||||
// TODO: Cancel post
|
||||
log.Errorf("TODO: Cancel PoSt, re-run")
|
||||
return nil
|
||||
}, PoStConfidence, ppe-build.PoSTChallangeTime)
|
||||
if err != nil {
|
||||
// TODO: This is BAD, figure something out
|
||||
log.Errorf("scheduling PoSt failed: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Miner) computePost(ppe uint64) func(ts *types.TipSet, curH uint64) error {
|
||||
return func(ts *types.TipSet, curH uint64) error {
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
sset, err := m.api.StateMinerProvingSet(ctx, m.maddr, ts)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get proving set for miner: %w", err)
|
||||
}
|
||||
|
||||
r, err := m.api.ChainGetRandomness(ctx, ts, nil, int(int64(ts.Height())-int64(ppe)+int64(build.PoSTChallangeTime))) // TODO: review: check math
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get chain randomness for post: %w", err)
|
||||
}
|
||||
|
||||
log.Infof("running PoSt computation, rh=%d r=%s, ppe=%d, h=%d", int64(ts.Height())-int64(ppe)+int64(build.PoSTChallangeTime), base64.StdEncoding.EncodeToString(r), ppe, ts.Height())
|
||||
var faults []uint64
|
||||
proof, err := m.secst.RunPoSt(ctx, sset, r, faults)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("running post failed: %w", err)
|
||||
}
|
||||
|
||||
log.Infof("submitting PoSt pLen=%d", len(proof))
|
||||
|
||||
params := &actors.SubmitPoStParams{
|
||||
Proof: proof,
|
||||
DoneSet: types.BitFieldFromSet(sectorIdList(sset)),
|
||||
}
|
||||
|
||||
enc, aerr := actors.SerializeParams(params)
|
||||
if aerr != nil {
|
||||
return xerrors.Errorf("could not serialize submit post parameters: %w", err)
|
||||
}
|
||||
|
||||
msg := &types.Message{
|
||||
To: m.maddr,
|
||||
From: m.worker,
|
||||
Method: actors.MAMethods.SubmitPoSt,
|
||||
Params: enc,
|
||||
Value: types.NewInt(1000), // currently hard-coded late fee in actor, returned if not late
|
||||
GasLimit: types.NewInt(100000 /* i dont know help */),
|
||||
GasPrice: types.NewInt(1),
|
||||
}
|
||||
|
||||
log.Info("mpush")
|
||||
|
||||
smsg, err := m.api.MpoolPushMessage(ctx, msg)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("pushing message to mpool: %w", err)
|
||||
}
|
||||
|
||||
log.Info("Waiting for post %s to appear on chain", smsg.Cid())
|
||||
|
||||
// make sure it succeeds...
|
||||
rec, err := m.api.ChainWaitMsg(ctx, smsg.Cid())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rec.Receipt.ExitCode != 0 {
|
||||
log.Warnf("SubmitPoSt EXIT: %d", rec.Receipt.ExitCode)
|
||||
// TODO: Do something
|
||||
}
|
||||
|
||||
m.scheduleNextPost(ppe + build.ProvingPeriodDuration)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func sectorIdList(si []*api.SectorInfo) []uint64 {
|
||||
out := make([]uint64, len(si))
|
||||
for i, s := range si {
|
||||
out[i] = s.SectorID
|
||||
}
|
||||
return out
|
||||
}
|
Loading…
Reference in New Issue
Block a user