@@ -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+
406452func (ctx * rollDPoSCtx ) WaitUntilRoundStart () time.Duration {
407453 ctx .mutex .RLock ()
408454 defer ctx .mutex .RUnlock ()
0 commit comments