Skip to content

Commit aba9583

Browse files
committed
prepare next proposal
1 parent 4fe70bc commit aba9583

File tree

5 files changed

+65
-1
lines changed

5 files changed

+65
-1
lines changed

consensus/consensusfsm/context.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type Context interface {
3434
Prepare() error
3535
HasDelegate() bool
3636
Proposal() (interface{}, error)
37+
PrepareNextProposal(any) error
3738
WaitUntilRoundStart() time.Duration
3839
PreCommitEndorsement() interface{}
3940
NewProposalEndorsement(interface{}) (interface{}, error)

consensus/consensusfsm/fsm.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,9 @@ 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-
469+
if err := m.ctx.PrepareNextProposal(cEvt.Data()); err != nil {
470+
m.ctx.Logger().Warn("Failed to prepare next proposal", zap.Error(err))
471+
}
470472
return sAcceptProposalEndorsement, nil
471473
}
472474

consensus/consensusfsm/fsm_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ func TestStateTransitionFunctions(t *testing.T) {
240240
t.Run("success", func(t *testing.T) {
241241
mockCtx.EXPECT().NewProposalEndorsement(gomock.Any()).Return(NewMockEndorsement(ctrl), nil).Times(1)
242242
mockCtx.EXPECT().Broadcast(gomock.Any()).Return().Times(1)
243+
mockCtx.EXPECT().PrepareNextProposal(gomock.Any()).Return(nil).Times(1)
243244
state, err := cfsm.onReceiveBlock(&ConsensusEvent{data: NewMockEndorsement(ctrl)})
244245
require.NoError(err)
245246
require.Equal(sAcceptProposalEndorsement, state)

consensus/consensusfsm/mock_context_test.go

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

consensus/scheme/rolldpos/rolldposctx.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,52 @@ func (ctx *rollDPoSCtx) Proposal() (interface{}, error) {
403403
return ctx.mintNewBlock(privateKey)
404404
}
405405

406+
func (ctx *rollDPoSCtx) PrepareNextProposal(msg any) error {
407+
// retrieve the block from the message
408+
ecm, ok := msg.(*EndorsedConsensusMessage)
409+
if !ok {
410+
return errors.New("invalid endorsed block")
411+
}
412+
proposal, ok := ecm.Document().(*blockProposal)
413+
if !ok {
414+
return errors.New("invalid endorsed block")
415+
}
416+
var (
417+
blk = proposal.block
418+
height = blk.Height() + 1
419+
interval = ctx.BlockInterval(height)
420+
startTime = blk.Timestamp().Add(interval)
421+
prevHash = blk.HashBlock()
422+
err error
423+
)
424+
fork, err := ctx.chain.Fork(prevHash)
425+
if err != nil {
426+
return errors.Wrapf(err, "failed to check fork at block %d, hash %x", blk.Height(), prevHash[:])
427+
}
428+
roundCalc, err := ctx.roundCalc.Fork(prevHash)
429+
if err != nil {
430+
return errors.Wrapf(err, "failed to fork at block %d, hash %x", blk.Height(), prevHash[:])
431+
}
432+
// check if the current node is the next proposer
433+
nextProposer := roundCalc.Proposer(height, interval, startTime)
434+
var privateKey crypto.PrivateKey = nil
435+
if idx := slices.Index(ctx.encodedAddrs, nextProposer); idx < 0 {
436+
return nil
437+
} else {
438+
privateKey = ctx.priKeys[idx]
439+
}
440+
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))
441+
go func() {
442+
blk, err := fork.MintNewBlock(startTime, privateKey, prevHash)
443+
if err != nil {
444+
ctx.logger().Error("failed to mint new block", zap.Error(err))
445+
return
446+
}
447+
ctx.logger().Debug("prepared a new block", zap.Uint64("height", blk.Height()), zap.Time("timestamp", blk.Timestamp()))
448+
}()
449+
return nil
450+
}
451+
406452
func (ctx *rollDPoSCtx) WaitUntilRoundStart() time.Duration {
407453
ctx.mutex.RLock()
408454
defer ctx.mutex.RUnlock()

0 commit comments

Comments
 (0)