More unified randomness handling

This commit is contained in:
Łukasz Magiera 2020-02-23 21:00:47 +01:00
parent a82d156ccb
commit 917df9a5b8
21 changed files with 125 additions and 132 deletions

View File

@ -31,7 +31,7 @@ type FullNode interface {
// First message is guaranteed to be of len == 1, and type == 'current'
ChainNotify(context.Context) (<-chan []*store.HeadChange, error)
ChainHead(context.Context) (*types.TipSet, error)
ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error)
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
ChainGetTipSet(context.Context, types.TipSetKey) (*types.TipSet, error)
ChainGetBlockMessages(context.Context, cid.Cid) (*BlockMessages, error)

View File

@ -44,24 +44,24 @@ type FullNodeStruct struct {
CommonStruct
Internal struct {
ChainNotify func(context.Context) (<-chan []*store.HeadChange, error) `perm:"read"`
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
ChainGetRandomness func(context.Context, types.TipSetKey, int64) ([]byte, error) `perm:"read"`
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"`
ChainGetBlockMessages func(context.Context, cid.Cid) (*api.BlockMessages, error) `perm:"read"`
ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"`
ChainGetParentMessages func(context.Context, cid.Cid) ([]api.Message, error) `perm:"read"`
ChainGetTipSetByHeight func(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) `perm:"read"`
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
ChainHasObj func(context.Context, cid.Cid) (bool, error) `perm:"read"`
ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"`
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
ChainGetNode func(ctx context.Context, p string) (interface{}, error) `perm:"read"`
ChainGetMessage func(context.Context, cid.Cid) (*types.Message, error) `perm:"read"`
ChainGetPath func(context.Context, types.TipSetKey, types.TipSetKey) ([]*store.HeadChange, error) `perm:"read"`
ChainExport func(context.Context, *types.TipSet) (<-chan []byte, error) `perm:"read"`
ChainNotify func(context.Context) (<-chan []*store.HeadChange, error) `perm:"read"`
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
ChainGetRandomness func(context.Context, types.TipSetKey, crypto.DomainSeparationTag, abi.ChainEpoch, []byte) (abi.Randomness, error) `perm:"read"`
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"`
ChainGetBlockMessages func(context.Context, cid.Cid) (*api.BlockMessages, error) `perm:"read"`
ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"`
ChainGetParentMessages func(context.Context, cid.Cid) ([]api.Message, error) `perm:"read"`
ChainGetTipSetByHeight func(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error) `perm:"read"`
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
ChainHasObj func(context.Context, cid.Cid) (bool, error) `perm:"read"`
ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"`
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
ChainGetNode func(ctx context.Context, p string) (interface{}, error) `perm:"read"`
ChainGetMessage func(context.Context, cid.Cid) (*types.Message, error) `perm:"read"`
ChainGetPath func(context.Context, types.TipSetKey, types.TipSetKey) ([]*store.HeadChange, error) `perm:"read"`
ChainExport func(context.Context, *types.TipSet) (<-chan []byte, error) `perm:"read"`
SyncState func(context.Context) (*api.SyncState, error) `perm:"read"`
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
@ -266,8 +266,8 @@ func (c *FullNodeStruct) ChainHead(ctx context.Context) (*types.TipSet, error) {
return c.Internal.ChainHead(ctx)
}
func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, round int64) ([]byte, error) {
return c.Internal.ChainGetRandomness(ctx, pts, round)
func (c *FullNodeStruct) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
return c.Internal.ChainGetRandomness(ctx, tsk, personalization, randEpoch, entropy)
}
func (c *FullNodeStruct) ChainGetTipSetByHeight(ctx context.Context, h abi.ChainEpoch, ts *types.TipSet) (*types.TipSet, error) {

View File

@ -28,9 +28,6 @@ const FallbackPoStDelay = miner.ProvingPeriod
// Epochs
const SlashablePowerDelay = miner.ProvingPeriod * 3 // TODO: remove
// Epochs
const InteractivePoRepDelay = 8
// Epochs
const InteractivePoRepConfidence = 6

View File

@ -130,7 +130,7 @@ func (e *calledEvents) checkNewCalls(ts *types.TipSet) {
for _, matchFn := range matchFns {
ok, err := matchFn(msg)
if err != nil {
log.Warnf("event matcher failed: %s")
log.Warnf("event matcher failed: %s", err)
continue
}
matched = ok

View File

@ -4,13 +4,13 @@ import (
"bytes"
"context"
"crypto/sha256"
"encoding/binary"
"fmt"
format "github.com/ipfs/go-ipld-format"
"io/ioutil"
"sync/atomic"
"github.com/filecoin-project/go-address"
commcid "github.com/filecoin-project/go-fil-commcid"
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
block "github.com/ipfs/go-block-format"
@ -19,12 +19,10 @@ import (
"github.com/ipfs/go-cid"
blockstore "github.com/ipfs/go-ipfs-blockstore"
offline "github.com/ipfs/go-ipfs-exchange-offline"
format "github.com/ipfs/go-ipld-format"
logging "github.com/ipfs/go-log/v2"
"github.com/ipfs/go-merkledag"
"github.com/filecoin-project/go-address"
sectorbuilder "github.com/filecoin-project/go-sectorbuilder"
ffi "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
@ -276,8 +274,13 @@ func CarWalkFunc(nd format.Node) (out []*format.Link, err error) {
}
func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m address.Address, round int64) (*types.EPostProof, *types.Ticket, error) {
mc := &mca{w: cg.w, sm: cg.sm}
lastTicket := pts.MinTicket()
// TODO: REVIEW: Am I doing this correctly?
ticketRand, err := mc.ChainGetRandomness(ctx, pts.Key(), crypto.DomainSeparationTag_TicketProduction, pts.Height(), m.Bytes())
if err != nil {
return nil, nil, err
}
st := pts.ParentState()
@ -286,7 +289,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
return nil, nil, xerrors.Errorf("get miner worker: %w", err)
}
vrfout, err := ComputeVRF(ctx, cg.w.Sign, worker, m, DSepTicket, lastTicket.VRFProof)
vrfout, err := ComputeVRF(ctx, cg.w.Sign, worker, ticketRand)
if err != nil {
return nil, nil, xerrors.Errorf("compute VRF: %w", err)
}
@ -295,7 +298,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
VRFProof: vrfout,
}
eproofin, err := IsRoundWinner(ctx, pts, round, m, cg.eppProvs[m], &mca{w: cg.w, sm: cg.sm})
eproofin, err := IsRoundWinner(ctx, pts, round, m, cg.eppProvs[m], mc)
if err != nil {
return nil, nil, xerrors.Errorf("checking round winner failed: %w", err)
}
@ -439,7 +442,7 @@ func (cg *ChainGen) YieldRepo() (repo.Repo, error) {
}
type MiningCheckAPI interface {
ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error)
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
StateMinerPower(context.Context, address.Address, *types.TipSet) (api.MinerPower, error)
@ -457,8 +460,13 @@ type mca struct {
sm *stmgr.StateManager
}
func (mca mca) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, lb int64) ([]byte, error) {
return mca.sm.ChainStore().GetRandomness(ctx, pts.Cids(), int64(lb))
func (mca mca) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
pts, err := mca.sm.ChainStore().LoadTipSet(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset key: %w", err)
}
return mca.sm.ChainStore().GetRandomness(ctx, pts.Cids(), personalization, int64(randEpoch), entropy)
}
func (mca mca) StateMinerPower(ctx context.Context, maddr address.Address, ts *types.TipSet) (api.MinerPower, error) {
@ -520,7 +528,7 @@ type ProofInput struct {
}
func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner address.Address, epp ElectionPoStProver, a MiningCheckAPI) (*ProofInput, error) {
r, err := a.ChainGetRandomness(ctx, ts.Key(), round-build.EcRandomnessLookback)
epostRand, err := a.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_ElectionPoStChallengeSeed, abi.ChainEpoch(round-build.EcRandomnessLookback), miner.Bytes())
if err != nil {
return nil, xerrors.Errorf("chain get randomness: %w", err)
}
@ -530,7 +538,7 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner add
return nil, xerrors.Errorf("failed to get miner worker: %w", err)
}
vrfout, err := ComputeVRF(ctx, a.WalletSign, mworker, miner, DSepElectionPost, r)
vrfout, err := ComputeVRF(ctx, a.WalletSign, mworker, epostRand)
if err != nil {
return nil, xerrors.Errorf("failed to compute VRF: %w", err)
}
@ -619,38 +627,10 @@ func ComputeProof(ctx context.Context, epp ElectionPoStProver, pi *ProofInput) (
type SignFunc func(context.Context, address.Address, []byte) (*crypto.Signature, error)
const (
DSepTicket = 1
DSepElectionPost = 2
)
func hashVRFBase(personalization uint64, miner address.Address, input []byte) ([]byte, error) {
if miner.Protocol() != address.ID {
return nil, xerrors.Errorf("miner address for compute VRF must be an ID address")
}
var persbuf [8]byte
binary.LittleEndian.PutUint64(persbuf[:], personalization)
h := sha256.New()
h.Write(persbuf[:])
h.Write([]byte{0})
h.Write(input)
h.Write([]byte{0})
h.Write(miner.Bytes())
return h.Sum(nil), nil
}
func VerifyVRF(ctx context.Context, worker, miner address.Address, p uint64, input, vrfproof []byte) error {
func VerifyVRF(ctx context.Context, worker address.Address, vrfBase, vrfproof []byte) error {
_, span := trace.StartSpan(ctx, "VerifyVRF")
defer span.End()
vrfBase, err := hashVRFBase(p, miner, input)
if err != nil {
return xerrors.Errorf("computing vrf base failed: %w", err)
}
sig := &crypto.Signature{
Type: crypto.SigTypeBLS,
Data: vrfproof,
@ -663,12 +643,7 @@ func VerifyVRF(ctx context.Context, worker, miner address.Address, p uint64, inp
return nil
}
func ComputeVRF(ctx context.Context, sign SignFunc, worker, miner address.Address, p uint64, input []byte) ([]byte, error) {
sigInput, err := hashVRFBase(p, miner, input)
if err != nil {
return nil, err
}
func ComputeVRF(ctx context.Context, sign SignFunc, worker address.Address, sigInput []byte) ([]byte, error) {
sig, err := sign(ctx, worker, sigInput)
if err != nil {
return nil, err

View File

@ -260,8 +260,8 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
// TODO: copied from actors test harness, deduplicate or remove from here
type fakeRand struct{}
func (fr *fakeRand) GetRandomness(ctx context.Context, h int64) ([]byte, error) {
func (fr *fakeRand) GetRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch int64, entropy []byte) ([]byte, error) {
out := make([]byte, 32)
rand.New(rand.NewSource(h)).Read(out)
rand.New(rand.NewSource(randEpoch)).Read(out)
return out, nil
}

View File

@ -3,9 +3,10 @@ package store
import (
"bytes"
"context"
"crypto/sha256"
"encoding/binary"
"encoding/json"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/minio/blake2b-simd"
"io"
"sync"
@ -888,22 +889,30 @@ func (cs *ChainStore) TryFillTipSet(ts *types.TipSet) (*FullTipSet, error) {
return NewFullTipSet(out), nil
}
func drawRandomness(t *types.Ticket, round int64) []byte {
h := sha256.New()
var buf [8]byte
binary.LittleEndian.PutUint64(buf[:], uint64(round))
func drawRandomness(t *types.Ticket, pers crypto.DomainSeparationTag, round int64, entropy []byte) ([]byte, error) {
// TODO: Make this spec compliant
h := blake2b.New256()
if err := binary.Write(h, binary.BigEndian, int64(pers)); err != nil {
return nil, xerrors.Errorf("deriving randomness: %w", err)
}
h.Write(t.VRFProof)
h.Write(buf[:])
if err := binary.Write(h, binary.BigEndian, round); err != nil {
return nil, xerrors.Errorf("deriving randomness: %w", err)
}
h.Write(entropy)
return h.Sum(nil)
return h.Sum(nil), nil
}
func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, round int64) ([]byte, error) {
func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round int64, entropy []byte) (out []byte, err error) {
_, span := trace.StartSpan(ctx, "store.GetRandomness")
defer span.End()
span.AddAttributes(trace.Int64Attribute("round", round))
defer func() {
log.Warnf("getRand %v %d %d %x -> %x", blks, pers, round, entropy, out)
}()
for {
nts, err := cs.LoadTipSet(types.NewTipSetKey(blks...))
if err != nil {
@ -913,7 +922,7 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, round i
mtb := nts.MinTicketBlock()
if int64(nts.Height()) <= round {
return drawRandomness(nts.MinTicketBlock().Ticket, round), nil
return drawRandomness(nts.MinTicketBlock().Ticket, pers, round, entropy)
}
// special case for lookback behind genesis block
@ -921,10 +930,13 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, round i
if mtb.Height == 0 {
// round is negative
thash := drawRandomness(mtb.Ticket, round*-1)
thash, err := drawRandomness(mtb.Ticket, pers, round*-1, entropy)
if err != nil {
return nil, err
}
// for negative lookbacks, just use the hash of the positive tickethash value
h := sha256.Sum256(thash)
h := blake2b.Sum256(thash)
return h[:], nil
}
@ -1051,6 +1063,6 @@ func NewChainRand(cs *ChainStore, blks []cid.Cid, bheight abi.ChainEpoch) vm.Ran
}
}
func (cr *chainRand) GetRandomness(ctx context.Context, round int64) ([]byte, error) {
return cr.cs.GetRandomness(ctx, cr.blks, round)
func (cr *chainRand) GetRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round int64, entropy []byte) ([]byte, error) {
return cr.cs.GetRandomness(ctx, cr.blks, pers, round, entropy)
}

View File

@ -609,10 +609,12 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
})
tktsCheck := async.Err(func() error {
vrfBase := baseTs.MinTicket().VRFProof
err := gen.VerifyVRF(ctx, waddr, h.Miner, gen.DSepTicket, vrfBase, h.Ticket.VRFProof)
vrfBase, err := syncer.sm.ChainStore().GetRandomness(ctx, baseTs.Cids(), crypto.DomainSeparationTag_TicketProduction, int64(baseTs.Height()), h.Miner.Bytes())
if err != nil {
return xerrors.Errorf("failed to get randomness for verifying election proof: %w", err)
}
err = gen.VerifyVRF(ctx, waddr, vrfBase, h.Ticket.VRFProof)
if err != nil {
return xerrors.Errorf("validating block tickets failed: %w", err)
}
@ -646,12 +648,12 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
}
func (syncer *Syncer) VerifyElectionPoStProof(ctx context.Context, h *types.BlockHeader, baseTs *types.TipSet, waddr address.Address) error {
rand, err := syncer.sm.ChainStore().GetRandomness(ctx, baseTs.Cids(), int64(h.Height-build.EcRandomnessLookback))
rand, err := syncer.sm.ChainStore().GetRandomness(ctx, baseTs.Cids(), crypto.DomainSeparationTag_ElectionPoStChallengeSeed, int64(h.Height-build.EcRandomnessLookback), h.Miner.Bytes())
if err != nil {
return xerrors.Errorf("failed to get randomness for verifying election proof: %w", err)
}
if err := VerifyElectionPoStVRF(ctx, h.EPostProof.PostRand, rand, waddr, h.Miner); err != nil {
if err := VerifyElectionPoStVRF(ctx, h.EPostProof.PostRand, rand, waddr); err != nil {
return xerrors.Errorf("checking eproof failed: %w", err)
}
@ -1170,8 +1172,8 @@ func (syncer *Syncer) collectChain(ctx context.Context, ts *types.TipSet) error
return nil
}
func VerifyElectionPoStVRF(ctx context.Context, evrf []byte, rand []byte, worker, miner address.Address) error {
if err := gen.VerifyVRF(ctx, worker, miner, gen.DSepElectionPost, rand, evrf); err != nil {
func VerifyElectionPoStVRF(ctx context.Context, evrf []byte, rand []byte, worker address.Address) error {
if err := gen.VerifyVRF(ctx, worker, rand, evrf); err != nil {
return xerrors.Errorf("failed to verify post_randomness vrf: %w", err)
}

View File

@ -43,7 +43,7 @@ type VMContext interface {
LookupID(address.Address) (address.Address, error)
VerifySignature(sig *crypto.Signature, from address.Address, data []byte) aerrors.ActorError
ChargeGas(uint64) aerrors.ActorError
GetRandomness(height abi.ChainEpoch) ([]byte, aerrors.ActorError)
GetRandomness(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, aerrors.ActorError)
GetBalance(address.Address) (BigInt, aerrors.ActorError)
Sys() runtime.Syscalls

View File

@ -15,7 +15,6 @@ import (
vmr "github.com/filecoin-project/specs-actors/actors/runtime"
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
"github.com/ipfs/go-cid"
"github.com/minio/blake2b-simd"
cbg "github.com/whyrusleeping/cbor-gen"
"github.com/filecoin-project/lotus/chain/actors/aerrors"
@ -125,19 +124,12 @@ func (rs *runtimeShim) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bo
}
func (rs *runtimeShim) GetRandomness(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
r, err := rs.vmctx.GetRandomness(randEpoch)
r, err := rs.vmctx.GetRandomness(personalization, randEpoch, entropy)
if err != nil {
rs.Abortf(exitcode.SysErrInternal, "getting randomness: %v", err)
}
h := blake2b.New256()
if err := binary.Write(h, binary.BigEndian, int64(personalization)); err != nil {
rs.Abortf(exitcode.SysErrInternal, "deriving randomness: %v", err)
}
h.Write(r)
h.Write(entropy)
return h.Sum(nil)
return r
}
func (rs *runtimeShim) Store() vmr.Store {

View File

@ -79,9 +79,8 @@ func (vmc *VMContext) Message() *types.Message {
return vmc.msg
}
func (vmc *VMContext) GetRandomness(height abi.ChainEpoch) ([]byte, aerrors.ActorError) {
res, err := vmc.vm.rand.GetRandomness(vmc.ctx, int64(height))
func (vmc *VMContext) GetRandomness(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, aerrors.ActorError) {
res, err := vmc.vm.rand.GetRandomness(vmc.ctx, personalization, int64(randEpoch), entropy)
if err != nil {
return nil, aerrors.Escalate(err, "could not get randomness")
}
@ -352,7 +351,7 @@ func NewVM(base cid.Cid, height abi.ChainEpoch, r Rand, maddr address.Address, c
}
type Rand interface {
GetRandomness(ctx context.Context, h int64) ([]byte, error)
GetRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round int64, entropy []byte) ([]byte, error)
}
type ApplyRet struct {

2
go.mod
View File

@ -23,7 +23,7 @@ require (
github.com/filecoin-project/go-paramfetch v0.0.1
github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200210220012-eb75ec747d6b
github.com/filecoin-project/go-statestore v0.1.0
github.com/filecoin-project/specs-actors v0.0.0-20200221171119-030c8eaad3ba
github.com/filecoin-project/specs-actors v0.0.0-20200223194852-39976038b18d
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/google/uuid v1.1.1

6
go.sum
View File

@ -131,6 +131,12 @@ github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.m
github.com/filecoin-project/specs-actors v0.0.0-20200220011005-b2a2fbf40362/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA=
github.com/filecoin-project/specs-actors v0.0.0-20200221171119-030c8eaad3ba h1:KXxG0UblgNdQeAxdQZNXdECYV4FCJC/noXrIjvElO/0=
github.com/filecoin-project/specs-actors v0.0.0-20200221171119-030c8eaad3ba/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
github.com/filecoin-project/specs-actors v0.0.0-20200223193531-f9e06ceb423b h1:E19WAsPkbYgle7f5RwTutpc+Ijzk/PXN+V66BaCfQuk=
github.com/filecoin-project/specs-actors v0.0.0-20200223193531-f9e06ceb423b/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
github.com/filecoin-project/specs-actors v0.0.0-20200223194434-40d9fd965c67 h1:vpjeC/VS2TyqRCgjJ0ehhIHPaWUqJiKqLC2TAEJuOw0=
github.com/filecoin-project/specs-actors v0.0.0-20200223194434-40d9fd965c67/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
github.com/filecoin-project/specs-actors v0.0.0-20200223194852-39976038b18d h1:vukVHqbLQnXc+ZfhK+Cor3kaQx9SQbSZISqSeGjhYcE=
github.com/filecoin-project/specs-actors v0.0.0-20200223194852-39976038b18d/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 h1:EzDjxMg43q1tA2c0MV3tNbaontnHLplHyFF6M5KiVP0=

View File

@ -8,6 +8,7 @@ import (
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
lru "github.com/hashicorp/golang-lru"
"github.com/filecoin-project/lotus/api"
@ -341,20 +342,18 @@ func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningB
return b, nil
}
func (m *Miner) computeVRF(ctx context.Context, addr address.Address, input []byte) ([]byte, error) {
func (m *Miner) computeTicket(ctx context.Context, addr address.Address, base *MiningBase) (*types.Ticket, error) {
w, err := m.api.StateMinerWorker(ctx, addr, nil)
if err != nil {
return nil, err
}
return gen.ComputeVRF(ctx, m.api.WalletSign, w, addr, gen.DSepTicket, input)
}
input, err := m.api.ChainGetRandomness(ctx, base.ts.Key(), crypto.DomainSeparationTag_TicketProduction, base.ts.Height(), addr.Bytes())
if err != nil {
return nil, err
}
func (m *Miner) computeTicket(ctx context.Context, addr address.Address, base *MiningBase) (*types.Ticket, error) {
vrfBase := base.ts.MinTicket().VRFProof
vrfOut, err := m.computeVRF(ctx, addr, vrfBase)
vrfOut, err := gen.ComputeVRF(ctx, m.api.WalletSign, w, input)
if err != nil {
return nil, err
}

View File

@ -9,6 +9,7 @@ import (
"github.com/filecoin-project/go-amt-ipld/v2"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/ipfs/go-blockservice"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-hamt-ipld"
@ -47,8 +48,13 @@ func (a *ChainAPI) ChainHead(context.Context) (*types.TipSet, error) {
return a.Chain.GetHeaviestTipSet(), nil
}
func (a *ChainAPI) ChainGetRandomness(ctx context.Context, pts types.TipSetKey, round int64) ([]byte, error) {
return a.Chain.GetRandomness(ctx, pts.Cids(), round)
func (a *ChainAPI) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
pts, err := a.Chain.LoadTipSet(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset key: %w", err)
}
return a.Chain.GetRandomness(ctx, pts.Cids(), personalization, int64(randEpoch), entropy)
}
func (a *ChainAPI) ChainGetBlock(ctx context.Context, msg cid.Cid) (*types.BlockHeader, error) {

View File

@ -20,6 +20,7 @@ import (
"github.com/filecoin-project/go-sectorbuilder"
"github.com/filecoin-project/go-sectorbuilder/fs"
"github.com/filecoin-project/go-statestore"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/ipfs/go-bitswap"
"github.com/ipfs/go-bitswap/network"
"github.com/ipfs/go-blockservice"
@ -272,7 +273,7 @@ func SealTicketGen(api api.FullNode) sealing.TicketFn {
return nil, xerrors.Errorf("getting head ts for SealTicket failed: %w", err)
}
r, err := api.ChainGetRandomness(ctx, ts.Key(), int64(ts.Height())-build.SealRandomnessLookback)
r, err := api.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_SealRandomness, ts.Height()-build.SealRandomnessLookback, nil)
if err != nil {
return nil, xerrors.Errorf("getting randomness for SealTicket failed: %w", err)
}
@ -283,7 +284,7 @@ func SealTicketGen(api api.FullNode) sealing.TicketFn {
}
return &sectorbuilder.SealTicket{
BlockHeight: uint64(ts.Height()),
BlockHeight: uint64(ts.Height() - build.SealRandomnessLookback),
TicketBytes: tkt,
}, nil
}

View File

@ -427,7 +427,7 @@ func TestAPIRPC(t *testing.T) {
func TestAPIDealFlow(t *testing.T) {
logging.SetLogLevel("miner", "ERROR")
logging.SetLogLevel("chainstore", "ERROR")
//logging.SetLogLevel("chainstore", "ERROR")
logging.SetLogLevel("chain", "ERROR")
logging.SetLogLevel("sub", "ERROR")
logging.SetLogLevel("storageminer", "ERROR")

View File

@ -2,6 +2,7 @@ package storage
import (
"context"
"github.com/filecoin-project/specs-actors/actors/crypto"
"time"
ffi "github.com/filecoin-project/filecoin-ffi"
@ -142,9 +143,9 @@ func (s *FPoStScheduler) runPost(ctx context.Context, eps abi.ChainEpoch, ts *ty
ctx, span := trace.StartSpan(ctx, "storage.runPost")
defer span.End()
challengeRound := int64(eps + build.FallbackPoStDelay)
challengeRound := eps + build.FallbackPoStDelay
rand, err := s.api.ChainGetRandomness(ctx, ts.Key(), challengeRound)
rand, err := s.api.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_WindowedPoStChallengeSeed, challengeRound, s.actor.Bytes())
if err != nil {
return nil, xerrors.Errorf("failed to get chain randomness for fpost (ts=%d; eps=%d): %w", ts.Height(), eps, err)
}

View File

@ -15,6 +15,7 @@ import (
"github.com/filecoin-project/go-sectorbuilder"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
@ -58,7 +59,7 @@ type storageMinerApi interface {
ChainHead(context.Context) (*types.TipSet, error)
ChainNotify(context.Context) (<-chan []*store.HeadChange, error)
ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error)
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error)
ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error)
ChainReadObj(context.Context, cid.Cid) ([]byte, error)

View File

@ -15,6 +15,7 @@ import (
"github.com/filecoin-project/go-sectorbuilder"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/specs-actors/actors/crypto"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/events"
@ -46,7 +47,7 @@ type sealingApi interface { // TODO: trim down
ChainHead(context.Context) (*types.TipSet, error)
ChainNotify(context.Context) (<-chan []*store.HeadChange, error)
ChainGetRandomness(context.Context, types.TipSetKey, int64) ([]byte, error)
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, *types.TipSet) (*types.TipSet, error)
ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error)
ChainReadObj(context.Context, cid.Cid) ([]byte, error)

View File

@ -2,6 +2,7 @@ package sealing
import (
"context"
"github.com/filecoin-project/specs-actors/actors/crypto"
commcid "github.com/filecoin-project/go-fil-commcid"
"github.com/filecoin-project/go-sectorbuilder/fs"
@ -146,11 +147,11 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er
}
log.Info("precommit message landed on chain: ", sector.SectorID)
randHeight := mw.TipSet.Height() + build.InteractivePoRepDelay - 1 // -1 because of how the messages are applied
randHeight := mw.TipSet.Height() + miner.PreCommitChallengeDelay - 1 // -1 because of how the messages are applied
log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight)
err = m.events.ChainAt(func(ectx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error {
rand, err := m.api.ChainGetRandomness(ectx, ts.Key(), int64(randHeight))
rand, err := m.api.ChainGetRandomness(ectx, ts.Key(), crypto.DomainSeparationTag_InteractiveSealChallengeSeed, randHeight, nil)
if err != nil {
err = xerrors.Errorf("failed to get randomness for computing seal proof: %w", err)
@ -168,7 +169,7 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er
log.Warn("revert in interactive commit sector step")
// TODO: need to cancel running process and restart...
return nil
}, build.InteractivePoRepConfidence, mw.TipSet.Height()+build.InteractivePoRepDelay)
}, build.InteractivePoRepConfidence, mw.TipSet.Height()+miner.PreCommitChallengeDelay)
if err != nil {
log.Warn("waitForPreCommitMessage ChainAt errored: ", err)
}