diff --git a/api/api_full.go b/api/api_full.go index b794b7091..de91be283 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -390,6 +390,7 @@ type MiningBaseInfo struct { WorkerKey address.Address SectorSize abi.SectorSize PrevBeaconEntry types.BeaconEntry + BeaconEntries []types.BeaconEntry } type BlockTemplate struct { diff --git a/chain/gen/gen.go b/chain/gen/gen.go index 1f45147dc..50c8632ce 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -277,7 +277,7 @@ func CarWalkFunc(nd format.Node) (out []*format.Link, err error) { } func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m address.Address, round abi.ChainEpoch) ([]types.BeaconEntry, *types.ElectionProof, *types.Ticket, error) { - mc := &mca{w: cg.w, sm: cg.sm, pv: ffiwrapper.ProofVerifier} + mc := &mca{w: cg.w, sm: cg.sm, pv: ffiwrapper.ProofVerifier, bcn: cg.beacon} mbi, err := mc.MinerGetBaseInfo(ctx, m, round, pts.Key()) if err != nil { @@ -485,9 +485,10 @@ type MiningCheckAPI interface { } type mca struct { - w *wallet.Wallet - sm *stmgr.StateManager - pv ffiwrapper.Verifier + w *wallet.Wallet + sm *stmgr.StateManager + pv ffiwrapper.Verifier + bcn beacon.RandomBeacon } func (mca mca) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) { @@ -500,7 +501,7 @@ func (mca mca) ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, pers } func (mca mca) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoch abi.ChainEpoch, tsk types.TipSetKey) (*api.MiningBaseInfo, error) { - return stmgr.MinerGetBaseInfo(ctx, mca.sm, tsk, epoch, maddr, mca.pv) + return stmgr.MinerGetBaseInfo(ctx, mca.sm, mca.bcn, tsk, epoch, maddr, mca.pv) } func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*crypto.Signature, error) { diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 2c54a2939..0780a4710 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -1,6 +1,7 @@ package stmgr import ( + "bytes" "context" "os" @@ -24,6 +25,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -421,12 +423,31 @@ func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types. return lbts, nil } -func MinerGetBaseInfo(ctx context.Context, sm *StateManager, tsk types.TipSetKey, round abi.ChainEpoch, maddr address.Address, pv ffiwrapper.Verifier) (*api.MiningBaseInfo, error) { +func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcn beacon.RandomBeacon, tsk types.TipSetKey, round abi.ChainEpoch, maddr address.Address, pv ffiwrapper.Verifier) (*api.MiningBaseInfo, error) { ts, err := sm.ChainStore().LoadTipSet(tsk) if err != nil { return nil, xerrors.Errorf("failed to load tipset for mining base: %w", err) } + prev, err := sm.ChainStore().GetLatestBeaconEntry(ts) + if err != nil { + if os.Getenv("LOTUS_IGNORE_DRAND") != "_yes_" { + return nil, xerrors.Errorf("failed to get latest beacon entry: %w", err) + } + + prev = &types.BeaconEntry{} + } + + entries, err := beacon.BeaconEntriesForBlock(ctx, bcn, round, *prev) + if err != nil { + return nil, err + } + + rbase := *prev + if len(entries) > 0 { + rbase = entries[len(entries)-1] + } + lbts, err := GetLookbackTipSetForRound(ctx, sm, ts, round) if err != nil { return nil, xerrors.Errorf("getting lookback miner actor state: %w", err) @@ -442,8 +463,13 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, tsk types.TipSetKey return nil, err } + buf := new(bytes.Buffer) + if err := maddr.MarshalCBOR(buf); err != nil { + return nil, xerrors.Errorf("failed to marshal miner address: %w", err) + } + // TODO: use the right dst, also NB: not using any 'entropy' in this call because nicola really didnt want it - prand, err := sm.cs.GetRandomness(ctx, ts.Cids(), crypto.DomainSeparationTag_WinningPoStChallengeSeed, round-1, nil) + prand, err := store.DrawRandomness(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, round-1, buf.Bytes()) if err != nil { return nil, xerrors.Errorf("failed to get randomness for winning post: %w", err) } @@ -462,15 +488,6 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, tsk types.TipSetKey return nil, xerrors.Errorf("failed to get power: %w", err) } - prev, err := sm.ChainStore().GetLatestBeaconEntry(ts) - if err != nil { - if os.Getenv("LOTUS_IGNORE_DRAND") != "_yes_" { - return nil, xerrors.Errorf("failed to get latest beacon entry: %w", err) - } - - prev = &types.BeaconEntry{} - } - worker, err := sm.ResolveToKeyAddress(ctx, mas.GetWorker(), ts) if err != nil { return nil, xerrors.Errorf("resolving worker address: %w", err) @@ -483,5 +500,6 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, tsk types.TipSetKey WorkerKey: worker, SectorSize: mas.Info.SectorSize, PrevBeaconEntry: *prev, + BeaconEntries: entries, }, nil } diff --git a/miner/miner.go b/miner/miner.go index 96b33aaa4..4543af22a 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -362,7 +362,7 @@ func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningB } buf := new(bytes.Buffer) - if err := m.addresses[0].MarshalCBOR(buf); err != nil { + if err := addr.MarshalCBOR(buf); err != nil { return nil, xerrors.Errorf("failed to marshal miner address: %w", err) } diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 5e80af2a3..51ac6e82b 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -17,6 +17,7 @@ import ( "github.com/filecoin-project/go-amt-ipld/v2" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/stmgr" @@ -46,6 +47,7 @@ type StateAPI struct { ProofVerifier ffiwrapper.Verifier StateManager *stmgr.StateManager Chain *store.ChainStore + Beacon beacon.RandomBeacon } func (a *StateAPI) StateNetworkName(ctx context.Context) (dtypes.NetworkName, error) { @@ -272,7 +274,7 @@ func (a *StateAPI) StateReadState(ctx context.Context, act *types.Actor, tsk typ // This is on StateAPI because miner.Miner requires this, and MinerAPI requires miner.Miner func (a *StateAPI) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoch abi.ChainEpoch, tsk types.TipSetKey) (*api.MiningBaseInfo, error) { - return stmgr.MinerGetBaseInfo(ctx, a.StateManager, tsk, epoch, maddr, a.ProofVerifier) + return stmgr.MinerGetBaseInfo(ctx, a.StateManager, a.Beacon, tsk, epoch, maddr, a.ProofVerifier) } func (a *StateAPI) MinerCreateBlock(ctx context.Context, bt *api.BlockTemplate) (*types.BlockMsg, error) {