-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rought PoST method #207
Rought PoST method #207
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,9 @@ package actors | |
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/filecoin-project/go-lotus/build" | ||
"github.com/filecoin-project/go-lotus/chain/actors/aerrors" | ||
"github.com/filecoin-project/go-lotus/chain/address" | ||
"github.com/filecoin-project/go-lotus/chain/types" | ||
|
@@ -12,10 +14,10 @@ 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 | ||
const POST_SECTORS_COUNT = 8192 | ||
|
||
type StorageMinerActor struct{} | ||
|
@@ -118,9 +120,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 +145,7 @@ func (sma StorageMinerActor) Exports() []interface{} { | |
//16: sma.IsLate, | ||
17: sma.PaymentVerifyInclusion, | ||
18: sma.PaymentVerifySector, | ||
19: nil, | ||
} | ||
} | ||
|
||
|
@@ -247,11 +251,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. | ||
|
@@ -272,7 +271,7 @@ func (sma StorageMinerActor) CommitSector(act *types.Actor, vmctx types.VMContex | |
if self.ProvingSetSize == 0 { | ||
self.ProvingSet = self.Sectors | ||
self.ProvingSetSize = self.SectorSetSize | ||
self.ProvingPeriodEnd = vmctx.BlockHeight() + ProvingPeriodDuration | ||
self.ProvingPeriodEnd = vmctx.BlockHeight() + build.ProvingPeriodDuration | ||
} | ||
|
||
nstate, err := vmctx.Storage().Put(self) | ||
|
@@ -287,6 +286,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 +308,116 @@ 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 + build.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)) | ||
Kubuxu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
//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") | ||
Kubuxu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
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 | ||
{ | ||
var rand []byte | ||
var err ActorError | ||
if !lateSubmission { | ||
rand, err = vmctx.GetRandomness(self.ProvingPeriodEnd - build.PoSTChallangeTime) | ||
} else { | ||
rand, err = vmctx.GetRandomness(nextProvingPeriodEnd - build.PoSTChallangeTime) | ||
} | ||
if err != nil { | ||
return nil, aerrors.Wrap(err, "could not get randomness for PoST") | ||
} | ||
if len(rand) < len(seed) { | ||
return nil, aerrors.Escalate(fmt.Errorf("randomness too small (%d < %d)", | ||
len(rand), len(seed)), "improper randomness") | ||
} | ||
copy(seed[:], rand) | ||
} | ||
|
||
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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd pull this out into a separate function. Maybe we can dedupe some code with #205, can also do that later too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Problem is: either api or actor code (or both) would then have to convert types. API wants to use |
||
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 lerr != nil { | ||
Kubuxu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// TODO: study PoST errors | ||
return nil, aerrors.Absorb(lerr, 4, "PoST error") | ||
} | ||
if !ok { | ||
return nil, aerrors.New(4, "PoST invalid") | ||
} | ||
} | ||
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") | ||
} | ||
|
||
if err := ss.BatchDelete(params.DoneSet.All()); err != nil { | ||
// TODO: this could fail for system reasons (block not found) or for | ||
// bad user input reasons (e.g. bad doneset). The latter should be a | ||
// non-fatal error | ||
return nil, aerrors.Escalate(err, "failed to delete sectors in done set") | ||
} | ||
|
||
self.ProvingSet, lerr = ss.Flush() | ||
if lerr != nil { | ||
return nil, aerrors.Escalate(lerr, "could not flush 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 +429,10 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext, | |
return nil, err | ||
} | ||
|
||
self.ProvingSet = self.Sectors | ||
self.ProvingSetSize = self.SectorSetSize | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, we can drop the Size fields, the AMT tracks its own cardinality (the HAMT didnt) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the |
||
self.NextDoneSet = params.DoneSet | ||
|
||
c, err := vmctx.Storage().Put(self) | ||
if err != nil { | ||
return nil, err | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why remove this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was removed from spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, i chatted with @dignifiedquire.
This was removed from the spec because technically, rational post can handle an unlimited number of sectors. We agreed though that for practical purposes, there should be some limit (otherwise there are dos vectors with 'infinite' sized arrays of sectors being passed around, and other such nonsense).
Let's keep this code in for now, and file some spec issues to fix it up
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my take: there should be none with current construction, however we shouldn't assume so for future construction and backward compatibility, so we should pick a number