mining: get pending messages early
This commit is contained in:
parent
6127d82c7b
commit
9c6e9212a2
@ -261,13 +261,17 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
|
||||
VRFProof: vrfout,
|
||||
}
|
||||
|
||||
win, eproof, err := IsRoundWinner(ctx, pts, round, m, cg.eppProvs[m], &mca{w: cg.w, sm: cg.sm})
|
||||
win, eproofin, err := IsRoundWinner(ctx, pts, round, m, cg.eppProvs[m], &mca{w: cg.w, sm: cg.sm})
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("checking round winner failed: %w", err)
|
||||
}
|
||||
if !win {
|
||||
return nil, tick, nil
|
||||
}
|
||||
eproof, err := ComputeProof(ctx, cg.eppProvs[m], eproofin)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("computing proof: %w", err)
|
||||
}
|
||||
|
||||
return eproof, tick, nil
|
||||
}
|
||||
@ -466,7 +470,14 @@ func (epp *eppProvider) ComputeProof(ctx context.Context, _ sectorbuilder.Sorted
|
||||
return []byte("valid proof"), nil
|
||||
}
|
||||
|
||||
func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner address.Address, epp ElectionPoStProver, a MiningCheckAPI) (bool, *types.EPostProof, error) {
|
||||
type ProofInput struct {
|
||||
sectors sectorbuilder.SortedPublicSectorInfo
|
||||
hvrf []byte
|
||||
winners []sectorbuilder.EPostCandidate
|
||||
vrfout []byte
|
||||
}
|
||||
|
||||
func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner address.Address, epp ElectionPoStProver, a MiningCheckAPI) (bool, *ProofInput, error) {
|
||||
r, err := a.ChainGetRandomness(ctx, ts.Key(), round-build.EcRandomnessLookback)
|
||||
if err != nil {
|
||||
return false, nil, xerrors.Errorf("chain get randomness: %w", err)
|
||||
@ -529,16 +540,25 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner add
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
proof, err := epp.ComputeProof(ctx, sectors, hvrf[:], winners)
|
||||
return true, &ProofInput{
|
||||
sectors: sectors,
|
||||
hvrf: hvrf[:],
|
||||
winners: winners,
|
||||
vrfout: vrfout,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ComputeProof(ctx context.Context, epp ElectionPoStProver, pi *ProofInput) (*types.EPostProof, error) {
|
||||
proof, err := epp.ComputeProof(ctx, pi.sectors, pi.hvrf, pi.winners)
|
||||
if err != nil {
|
||||
return false, nil, xerrors.Errorf("failed to compute snark for election proof: %w", err)
|
||||
return nil, xerrors.Errorf("failed to compute snark for election proof: %w", err)
|
||||
}
|
||||
|
||||
ept := types.EPostProof{
|
||||
Proof: proof,
|
||||
PostRand: vrfout,
|
||||
PostRand: pi.vrfout,
|
||||
}
|
||||
for _, win := range winners {
|
||||
for _, win := range pi.winners {
|
||||
ept.Candidates = append(ept.Candidates, types.EPostTicket{
|
||||
Partial: win.PartialTicket[:],
|
||||
SectorID: win.SectorID,
|
||||
@ -546,7 +566,7 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round int64, miner add
|
||||
})
|
||||
}
|
||||
|
||||
return true, &ept, nil
|
||||
return &ept, nil
|
||||
}
|
||||
|
||||
type SignFunc func(context.Context, address.Address, []byte) (*types.Signature, error)
|
||||
|
@ -265,7 +265,7 @@ func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningB
|
||||
return nil, xerrors.Errorf("scratching ticket failed: %w", err)
|
||||
}
|
||||
|
||||
win, proof, err := gen.IsRoundWinner(ctx, base.ts, int64(base.ts.Height()+base.nullRounds+1), addr, m.epp, m.api)
|
||||
win, proofin, err := gen.IsRoundWinner(ctx, base.ts, int64(base.ts.Height()+base.nullRounds+1), addr, m.epp, m.api)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to check if we win next round: %w", err)
|
||||
}
|
||||
@ -275,7 +275,18 @@ func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningB
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
b, err := m.createBlock(base, addr, ticket, proof)
|
||||
// get pending messages early,
|
||||
pending, err := m.api.MpoolPending(context.TODO(), base.ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get pending messages: %w", err)
|
||||
}
|
||||
|
||||
proof, err := gen.ComputeProof(ctx, m.epp, proofin)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("computing election proof: %w", err)
|
||||
}
|
||||
|
||||
b, err := m.createBlock(base, addr, ticket, proof, pending)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to create block: %w", err)
|
||||
}
|
||||
@ -372,12 +383,7 @@ func (m *Miner) actorLookup(ctx context.Context, addr address.Address, ts *types
|
||||
return curnonce, &balance, nil
|
||||
}
|
||||
|
||||
func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *types.Ticket, proof *types.EPostProof) (*types.BlockMsg, error) {
|
||||
pending, err := m.api.MpoolPending(context.TODO(), base.ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get pending messages: %w", err)
|
||||
}
|
||||
|
||||
func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *types.Ticket, proof *types.EPostProof, pending []*types.SignedMessage) (*types.BlockMsg, error) {
|
||||
msgs, err := selectMessages(context.TODO(), m.actorLookup, base, pending)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("message filtering failed: %w", err)
|
||||
@ -393,10 +399,24 @@ func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *type
|
||||
|
||||
type actorLookup func(context.Context, address.Address, *types.TipSet) (uint64, *types.BigInt, error)
|
||||
|
||||
func countFrom(msgs []*types.SignedMessage, from address.Address) (out int) {
|
||||
for _, msg := range msgs {
|
||||
if msg.Message.From == from {
|
||||
out++
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func selectMessages(ctx context.Context, al actorLookup, base *MiningBase, msgs []*types.SignedMessage) ([]*types.SignedMessage, error) {
|
||||
out := make([]*types.SignedMessage, 0, len(msgs))
|
||||
inclNonces := make(map[address.Address]uint64)
|
||||
inclBalances := make(map[address.Address]types.BigInt)
|
||||
|
||||
sort.Slice(msgs, func(i, j int) bool { // TODO: is this actually needed?
|
||||
return msgs[i].Message.Nonce < msgs[j].Message.Nonce
|
||||
})
|
||||
|
||||
for _, msg := range msgs {
|
||||
if msg.Message.To == address.Undef {
|
||||
log.Warnf("message in mempool had bad 'To' address")
|
||||
@ -421,12 +441,12 @@ func selectMessages(ctx context.Context, al actorLookup, base *MiningBase, msgs
|
||||
}
|
||||
|
||||
if msg.Message.Nonce > inclNonces[from] {
|
||||
log.Warnf("message in mempool has too high of a nonce (%d > %d) %s", msg.Message.Nonce, inclNonces[from], msg.Cid())
|
||||
log.Warnf("message in mempool has too high of a nonce (%d > %d) %s (%d pending for orig)", msg.Message.Nonce, inclNonces[from], msg.Cid(), countFrom(msgs, from))
|
||||
continue
|
||||
}
|
||||
|
||||
if msg.Message.Nonce < inclNonces[from] {
|
||||
log.Warnf("message in mempool has already used nonce (%d < %d), from %s, to %s, %s", msg.Message.Nonce, inclNonces[from], msg.Message.From, msg.Message.To, msg.Cid())
|
||||
log.Warnf("message in mempool has already used nonce (%d < %d), from %s, to %s, %s (%d pending for)", msg.Message.Nonce, inclNonces[from], msg.Message.From, msg.Message.To, msg.Cid(), countFrom(msgs, from))
|
||||
continue
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user