Almost working new post code

This commit is contained in:
Łukasz Magiera 2019-09-27 01:07:40 +02:00
parent 1024812559
commit fe8e1fe1e4
5 changed files with 181 additions and 165 deletions

View File

@ -28,7 +28,7 @@ const MaxVouchersPerDeal = 768 // roughly one voucher per 10h over a year
// Consensus / Network // Consensus / Network
// Seconds // Seconds
const BlockDelay = 6 const BlockDelay = 4
// Seconds // Seconds
const AllowableClockDrift = BlockDelay * 2 const AllowableClockDrift = BlockDelay * 2
@ -43,10 +43,10 @@ const ForkLengthThreshold = 20
const RandomnessLookback = 20 const RandomnessLookback = 20
// Blocks // Blocks
const ProvingPeriodDuration = 40 const ProvingPeriodDuration = 10
// Blocks // Blocks
const PoSTChallangeTime = 20 const PoSTChallangeTime = 5
const PowerCollateralProportion = 20 const PowerCollateralProportion = 20
const PerCapitaCollateralProportion = 5 const PerCapitaCollateralProportion = 5

View File

@ -420,7 +420,7 @@ func (c *wsConn) handleWsConn(ctx context.Context) {
case r, ok := <-c.incoming: case r, ok := <-c.incoming:
if !ok { if !ok {
if c.incomingErr != nil { if c.incomingErr != nil {
log.Debugf("websocket error", "error", c.incomingErr) log.Warnw("websocket error", "error", c.incomingErr)
} }
return // remote closed return // remote closed
} }
@ -443,7 +443,7 @@ func (c *wsConn) handleWsConn(ctx context.Context) {
c.sendRequest(req.req) c.sendRequest(req.req)
case <-c.stop: case <-c.stop:
if err := c.conn.Close(); err != nil { if err := c.conn.Close(); err != nil {
log.Debugf("websocket close error", "error", err) log.Warnw("websocket close error", "error", err)
} }
return return
} }

View File

@ -76,7 +76,7 @@ func MakeGenesis(outFile string) func(bs dtypes.ChainBlockstore, w *wallet.Walle
} }
addrs := map[address.Address]types.BigInt{ addrs := map[address.Address]types.BigInt{
minerAddr: types.NewInt(5000000000000000000), minerAddr: types.FromFil(100000),
} }
b, err := gen.MakeGenesisBlock(bs, addrs, gmc, 100000) b, err := gen.MakeGenesisBlock(bs, addrs, gmc, 100000)

View File

@ -2,14 +2,13 @@ package storage
import ( import (
"context" "context"
"encoding/base64" "sync"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/host"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/xerrors"
"sync"
"github.com/filecoin-project/go-lotus/api" "github.com/filecoin-project/go-lotus/api"
"github.com/filecoin-project/go-lotus/build" "github.com/filecoin-project/go-lotus/build"
@ -173,162 +172,6 @@ func (m *Miner) commitSector(ctx context.Context, sinfo sectorbuilder.SectorSeal
return nil 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 { func (m *Miner) runPreflightChecks(ctx context.Context) error {
worker, err := m.api.StateMinerWorker(ctx, m.maddr, nil) worker, err := m.api.StateMinerWorker(ctx, m.maddr, nil)
if err != nil { if err != nil {

173
storage/post.go Normal file
View 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
}