-
Notifications
You must be signed in to change notification settings - Fork 350
Prepare next proposal #4594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prepare next proposal #4594
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ import ( | |
"github.com/facebookgo/clock" | ||
fsm "github.com/iotexproject/go-fsm" | ||
"github.com/iotexproject/go-pkgs/crypto" | ||
"github.com/iotexproject/go-pkgs/hash" | ||
"github.com/pkg/errors" | ||
"github.com/prometheus/client_golang/prometheus" | ||
"go.uber.org/zap" | ||
|
@@ -405,6 +406,37 @@ func (ctx *rollDPoSCtx) Proposal() (interface{}, error) { | |
return ctx.mintNewBlock(privateKey) | ||
} | ||
|
||
func (ctx *rollDPoSCtx) prepareNextProposal(prevHeight uint64, prevHash hash.Hash256) error { | ||
var ( | ||
height = prevHeight + 1 | ||
interval = ctx.BlockInterval(height) | ||
startTime = ctx.round.StartTime().Add(interval) | ||
err error | ||
) | ||
fork, err := ctx.chain.Fork(prevHash) | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to check fork at block %d, hash %x", prevHeight, prevHash[:]) | ||
} | ||
roundCalc := ctx.roundCalc.Fork(fork) | ||
// check if the current node is the next proposer | ||
nextProposer := roundCalc.Proposer(height, interval, startTime) | ||
idx := slices.Index(ctx.encodedAddrs, nextProposer) | ||
if idx < 0 { | ||
return nil | ||
} | ||
privateKey := ctx.priKeys[idx] | ||
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)) | ||
go func() { | ||
blk, err := fork.MintNewBlock(startTime, privateKey, prevHash) | ||
if err != nil { | ||
ctx.logger().Error("failed to mint new block", zap.Error(err)) | ||
return | ||
} | ||
ctx.logger().Debug("prepared a new block", zap.Uint64("height", blk.Height()), zap.Time("timestamp", blk.Timestamp())) | ||
}() | ||
return nil | ||
} | ||
|
||
func (ctx *rollDPoSCtx) WaitUntilRoundStart() time.Duration { | ||
ctx.mutex.RLock() | ||
defer ctx.mutex.RUnlock() | ||
|
@@ -454,9 +486,16 @@ func (ctx *rollDPoSCtx) NewProposalEndorsement(msg interface{}) (interface{}, er | |
if err := ctx.round.AddBlock(proposal.block); err != nil { | ||
return nil, err | ||
} | ||
if err := ctx.prepareNextProposal(proposal.block.Height(), blkHash); err != nil { | ||
ctx.loggerWithStats().Warn("failed to prepare next proposal", zap.Error(err), zap.Uint64("prevHeight", proposal.block.Height())) | ||
} | ||
ctx.loggerWithStats().Debug("accept block proposal", log.Hex("block", blockHash)) | ||
} else if ctx.round.IsLocked() { | ||
blockHash = ctx.round.HashOfBlockInLock() | ||
} else { | ||
if err := ctx.prepareNextProposal(ctx.round.Height()-1, ctx.round.PrevHash()); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why now need to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. msg == nil means that the proposal for this round was not received in time; in this case, it's possible to mint the proposal for round +1 in advance. |
||
ctx.loggerWithStats().Warn("failed to prepare next proposal", zap.Error(err), zap.Uint64("prevHeight", ctx.round.Height()-1)) | ||
} | ||
} | ||
// TODO: prepare next block if the current node will be a proposer | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why use
go func()
hereThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor:
if fork.MintNewBlock() errs out, the error won't be captured and handled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MintNewBlock
keep mint result in memory, and will return it if mint same block. Here is to just to start the next proposal mint in advance, which can be run in background.