Skip to content

Commit f7a636c

Browse files
authored
Prepare next proposal (#4594)
* prepare next proposal * address comment * address comment
1 parent 2eb4ffa commit f7a636c

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

consensus/consensusfsm/fsm.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,6 @@ func (m *ConsensusFSM) onReceiveBlock(evt fsm.Event) (fsm.State, error) {
466466
m.ctx.Logger().Debug("Failed to generate proposal endorsement", zap.Error(err))
467467
return sAcceptBlockProposal, nil
468468
}
469-
470469
return sAcceptProposalEndorsement, nil
471470
}
472471

consensus/scheme/rolldpos/rolldposctx.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/facebookgo/clock"
1414
fsm "github.com/iotexproject/go-fsm"
1515
"github.com/iotexproject/go-pkgs/crypto"
16+
"github.com/iotexproject/go-pkgs/hash"
1617
"github.com/pkg/errors"
1718
"github.com/prometheus/client_golang/prometheus"
1819
"go.uber.org/zap"
@@ -405,6 +406,37 @@ func (ctx *rollDPoSCtx) Proposal() (interface{}, error) {
405406
return ctx.mintNewBlock(privateKey)
406407
}
407408

409+
func (ctx *rollDPoSCtx) prepareNextProposal(prevHeight uint64, prevHash hash.Hash256) error {
410+
var (
411+
height = prevHeight + 1
412+
interval = ctx.BlockInterval(height)
413+
startTime = ctx.round.StartTime().Add(interval)
414+
err error
415+
)
416+
fork, err := ctx.chain.Fork(prevHash)
417+
if err != nil {
418+
return errors.Wrapf(err, "failed to check fork at block %d, hash %x", prevHeight, prevHash[:])
419+
}
420+
roundCalc := ctx.roundCalc.Fork(fork)
421+
// check if the current node is the next proposer
422+
nextProposer := roundCalc.Proposer(height, interval, startTime)
423+
idx := slices.Index(ctx.encodedAddrs, nextProposer)
424+
if idx < 0 {
425+
return nil
426+
}
427+
privateKey := ctx.priKeys[idx]
428+
ctx.logger().Debug("prepare next proposal", log.Hex("prevHash", prevHash[:]), zap.Uint64("height", ctx.round.height+1), zap.Time("timestamp", startTime), zap.String("nextproposer", nextProposer))
429+
go func() {
430+
blk, err := fork.MintNewBlock(startTime, privateKey, prevHash)
431+
if err != nil {
432+
ctx.logger().Error("failed to mint new block", zap.Error(err))
433+
return
434+
}
435+
ctx.logger().Debug("prepared a new block", zap.Uint64("height", blk.Height()), zap.Time("timestamp", blk.Timestamp()))
436+
}()
437+
return nil
438+
}
439+
408440
func (ctx *rollDPoSCtx) WaitUntilRoundStart() time.Duration {
409441
ctx.mutex.RLock()
410442
defer ctx.mutex.RUnlock()
@@ -454,9 +486,16 @@ func (ctx *rollDPoSCtx) NewProposalEndorsement(msg interface{}) (interface{}, er
454486
if err := ctx.round.AddBlock(proposal.block); err != nil {
455487
return nil, err
456488
}
489+
if err := ctx.prepareNextProposal(proposal.block.Height(), blkHash); err != nil {
490+
ctx.loggerWithStats().Warn("failed to prepare next proposal", zap.Error(err), zap.Uint64("prevHeight", proposal.block.Height()))
491+
}
457492
ctx.loggerWithStats().Debug("accept block proposal", log.Hex("block", blockHash))
458493
} else if ctx.round.IsLocked() {
459494
blockHash = ctx.round.HashOfBlockInLock()
495+
} else {
496+
if err := ctx.prepareNextProposal(ctx.round.Height()-1, ctx.round.PrevHash()); err != nil {
497+
ctx.loggerWithStats().Warn("failed to prepare next proposal", zap.Error(err), zap.Uint64("prevHeight", ctx.round.Height()-1))
498+
}
460499
}
461500
// TODO: prepare next block if the current node will be a proposer
462501

0 commit comments

Comments
 (0)