Rought PoST method

License: MIT
Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
This commit is contained in:
Jakub Sztandera 2019-09-18 17:10:03 +02:00
parent f3854a4826
commit 9c02f7f839
5 changed files with 127 additions and 16 deletions

View File

@ -12,10 +12,13 @@ import (
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/libp2p/go-libp2p-core/peer"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
)
var ProvingPeriodDuration = uint64(2 * 60) // an hour, for now
var PoSTChallangeTime = uint64(1 * 60)
const POST_SECTORS_COUNT = 8192
type StorageMinerActor struct{}
@ -118,9 +121,10 @@ type maMethods struct {
IsLate uint64
PaymentVerifyInclusion uint64
PaymentVerifySector uint64
AddFaults uint64
}
var MAMethods = maMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}
var MAMethods = maMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
func (sma StorageMinerActor) Exports() []interface{} {
return []interface{}{
@ -142,6 +146,7 @@ func (sma StorageMinerActor) Exports() []interface{} {
//16: sma.IsLate,
17: sma.PaymentVerifyInclusion,
18: sma.PaymentVerifySector,
19: nil,
}
}
@ -247,11 +252,6 @@ func (sma StorageMinerActor) CommitSector(act *types.Actor, vmctx types.VMContex
return nil, aerrors.New(3, "not enough collateral")
}
// ensure that the miner cannot commit more sectors than can be proved with a single PoSt
if self.SectorSetSize >= POST_SECTORS_COUNT {
return nil, aerrors.New(4, "too many sectors")
}
// Note: There must exist a unique index in the miner's sector set for each
// sector ID. The `faults`, `recovered`, and `done` parameters of the
// SubmitPoSt method express indices into this sector set.
@ -287,6 +287,8 @@ func (sma StorageMinerActor) CommitSector(act *types.Actor, vmctx types.VMContex
}
type SubmitPoStParams struct {
Proof []byte
DoneSet types.BitField
// TODO: once the spec changes finish, we have more work to do here...
}
@ -307,13 +309,99 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext,
return nil, aerrors.New(1, "not authorized to submit post for miner")
}
oldProvingSetSize := self.ProvingSetSize
feesRequired := types.NewInt(0)
nextProvingPeriodEnd := self.ProvingPeriodEnd + ProvingPeriodDuration
if vmctx.BlockHeight() > nextProvingPeriodEnd {
return nil, aerrors.New(1, "PoSt submited too late")
}
self.ProvingSet = self.Sectors
self.ProvingSetSize = self.SectorSetSize
var lateSubmission bool
if vmctx.BlockHeight() > self.ProvingPeriodEnd {
//TODO late fee calc
lateSubmission = true
feesRequired = types.BigAdd(feesRequired, types.NewInt(1000))
}
//TODO temporary sector failure fees
msgVal := vmctx.Message().Value
if types.BigCmp(msgVal, feesRequired) < 0 {
return nil, aerrors.New(2, "not enough funds to pay post submission fees")
}
if types.BigCmp(msgVal, feesRequired) > 0 {
_, err := vmctx.Send(vmctx.Message().From, 0,
types.BigSub(msgVal, feesRequired), nil)
if err != nil {
return nil, aerrors.Wrap(err, "could not refund excess fees")
}
}
var seed [sectorbuilder.CommLen]byte
//TODO
if !lateSubmission {
//GetChainRandom(self.ProvingPeriodEnd-PoSTChallangeTime)
} else {
//GetChainRandom(nextProvingPeriodEnd-PoSTChallangeTime)
}
pss, lerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
if lerr != nil {
return nil, aerrors.Escalate(lerr, "could not load sector set node")
}
var sectorInfos []sectorbuilder.SectorInfo
if err := pss.ForEach(func(id uint64, v *cbg.Deferred) error {
var comms [][]byte
if err := cbor.DecodeInto(v.Raw, &comms); err != nil {
return xerrors.New("could not decode comms")
}
si := sectorbuilder.SectorInfo{
SectorID: id,
}
commR := comms[0]
if len(commR) != len(si.CommR) {
return xerrors.Errorf("commR length is wrong: %d", len(commR))
}
copy(si.CommR[:], commR)
sectorInfos = append(sectorInfos, si)
return nil
}); err != nil {
return nil, aerrors.Absorb(err, 3, "could not decode sectorset")
}
faults := self.CurrentFaultSet.All()
if ok, lerr := sectorbuilder.VerifyPost(mi.SectorSize.Uint64(),
sectorbuilder.NewSortedSectorInfo(sectorInfos), seed, params.Proof,
faults); !ok || lerr != nil {
if !ok {
return nil, aerrors.New(4, "PoST invalid")
}
if lerr != nil {
return nil, aerrors.Absorb(lerr, 4, "PoST error")
}
}
self.CurrentFaultSet = self.NextFaultSet
self.NextFaultSet = types.NewBitField()
ss, lerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
if lerr != nil {
return nil, aerrors.Escalate(lerr, "could not load sector set node")
}
_ = ss
//TODO: Remove done sectors from SectorSet
self.ProvingSet, lerr = ss.Flush()
if lerr != nil {
return nil, aerrors.Escalate(lerr, "could not flish AMT")
}
oldPower := self.Power
self.Power = types.BigMul(types.NewInt(oldProvingSetSize), mi.SectorSize)
self.Power = types.BigMul(types.NewInt(self.ProvingSetSize-uint64(len(faults))),
mi.SectorSize)
enc, err := SerializeParams(&UpdateStorageParams{Delta: types.BigSub(self.Power, oldPower)})
if err != nil {
@ -325,6 +413,10 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext,
return nil, err
}
self.ProvingSet = self.Sectors
self.ProvingSetSize = self.SectorSetSize
self.NextDoneSet = params.DoneSet
c, err := vmctx.Storage().Put(self)
if err != nil {
return nil, err

View File

@ -13,6 +13,10 @@ type BitField struct {
bits map[uint64]struct{}
}
func NewBitField() BitField {
return BitField{bits: make(map[uint64]struct{})}
}
// Set ...s bit in the BitField
func (bf BitField) Set(bit uint64) {
bf.bits[bit] = struct{}{}
@ -29,6 +33,15 @@ func (bf BitField) Has(bit uint64) bool {
return ok
}
// All returns all set bits, in random order
func (bf BitField) All() []uint64 {
res := make([]uint64, 0, len(bf.bits))
for i := range bf.bits {
res = append(res, i)
}
return res
}
func (bf BitField) MarshalCBOR(w io.Writer) error {
ints := make([]uint64, 0, len(bf.bits))
for i := range bf.bits {

2
go.mod
View File

@ -6,7 +6,7 @@ require (
contrib.go.opencensus.io/exporter/jaeger v0.1.0
github.com/BurntSushi/toml v0.3.1
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
github.com/filecoin-project/go-amt-ipld v0.0.0-20190917010905-40ffeec492ae
github.com/filecoin-project/go-amt-ipld v0.0.0-20190917221444-2ed85149c65d
github.com/filecoin-project/go-bls-sigs v0.0.0-20190718224239-4bc4b8a7bbf8
github.com/filecoin-project/go-leb128 v0.0.0-20190212224330-8d79a5489543
github.com/filecoin-project/go-sectorbuilder v0.0.0-00010101000000-000000000000

4
go.sum
View File

@ -68,8 +68,8 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/filecoin-project/go-amt-ipld v0.0.0-20190917010905-40ffeec492ae h1:rSg6wenxKdXby0piY57Vv5gOJR6Eibqq/4PxEk6KjvE=
github.com/filecoin-project/go-amt-ipld v0.0.0-20190917010905-40ffeec492ae/go.mod h1:lKjJYPg2kwbav5f78i5YA8kGccnZn18IySbpneXvaQs=
github.com/filecoin-project/go-amt-ipld v0.0.0-20190917221444-2ed85149c65d h1:fAJ40dcN0kpSFfdTssa1kLxlDImSEZy8e1d7a32tyBY=
github.com/filecoin-project/go-amt-ipld v0.0.0-20190917221444-2ed85149c65d/go.mod h1:lKjJYPg2kwbav5f78i5YA8kGccnZn18IySbpneXvaQs=
github.com/filecoin-project/go-leb128 v0.0.0-20190212224330-8d79a5489543 h1:aMJGfgqe1QDhAVwxRg5fjCRF533xHidiKsugk7Vvzug=
github.com/filecoin-project/go-leb128 v0.0.0-20190212224330-8d79a5489543/go.mod h1:mjrHv1cDGJWDlGmC0eDc1E5VJr8DmL9XMUcaFwiuKg8=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=

View File

@ -107,7 +107,13 @@ func VerifyPieceInclusionProof(sectorSize uint64, pieceSize uint64, commP []byte
return sectorbuilder.VerifyPieceInclusionProof(sectorSize, pieceSize, commPa, commDa, proof)
}
func VerifyPost(sectorSize uint64, sortedCommRs [][CommLen]byte, challengeSeed [CommLen]byte, proofs [][]byte, faults []uint64) (bool, error) {
// sectorbuilder.VerifyPost()
panic("no")
type SortedSectorInfo = sectorbuilder.SortedSectorInfo
type SectorInfo = sectorbuilder.SectorInfo
func NewSortedSectorInfo(sectors []SectorInfo) SortedSectorInfo {
return sectorbuilder.NewSortedSectorInfo(sectors...)
}
func VerifyPost(sectorSize uint64, sectorInfo SortedSectorInfo, challengeSeed [CommLen]byte, proof []byte, faults []uint64) (bool, error) {
return sectorbuilder.VerifyPoSt(sectorSize, sectorInfo, challengeSeed, proof, faults)
}