-
Notifications
You must be signed in to change notification settings - Fork 699
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
vms/platformvm
: Remove double block building logic
#2380
Changes from 12 commits
b237933
cb81c85
03efd7e
7ba8155
df70afb
86a559b
1a2431f
a55ce38
8c794eb
f3f2fbb
776db3e
eeb97d9
5624df8
efbb751
903d83b
cd669b2
a25ef67
1d30f2b
58f08ee
ff0f319
df125d5
06b1bdc
240867b
980bd4d
cbb3868
9cd31a3
2266e7c
645b989
16160b7
5b70127
c1cff7a
5520c3e
8e19e4e
6361267
6970836
75de1aa
a3b7670
1a94ee0
58594db
7114174
c3dee45
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,7 +13,6 @@ import ( | |
|
||
"github.com/ava-labs/avalanchego/ids" | ||
"github.com/ava-labs/avalanchego/snow/consensus/snowman" | ||
"github.com/ava-labs/avalanchego/snow/engine/common" | ||
"github.com/ava-labs/avalanchego/utils/timer" | ||
"github.com/ava-labs/avalanchego/utils/timer/mockable" | ||
"github.com/ava-labs/avalanchego/utils/units" | ||
|
@@ -40,10 +39,12 @@ var ( | |
|
||
type Builder interface { | ||
mempool.Mempool | ||
mempool.BlockTimer | ||
|
||
// BuildBlock is called on timer clock to attempt to create | ||
// next block | ||
// ResetBlockTimer schedules a timer to notify the consensus engine once a | ||
// block needs to be built to process a staker change. | ||
ResetBlockTimer() | ||
|
||
// BuildBlock can be called to attempt to create a new block | ||
BuildBlock(context.Context) (snowman.Block, error) | ||
|
||
// Shutdown cleanly shuts Builder down | ||
|
@@ -58,28 +59,24 @@ type builder struct { | |
txExecutorBackend *txexecutor.Backend | ||
blkManager blockexecutor.Manager | ||
|
||
// channel to send messages to the consensus engine | ||
toEngine chan<- common.Message | ||
|
||
// This timer goes off when it is time for the next validator to add/leave | ||
// the validator set. When it goes off ResetTimer() is called, potentially | ||
// triggering creation of a new block. | ||
timer *timer.Timer | ||
// This timer goes off when it is time for the next staker to add/leave | ||
// the staking set. When it goes off, [setNextBlockBuildTime()] is called, | ||
// potentially triggering creation of a new block. | ||
timer *timer.Timer | ||
nextStakerChangeTime time.Time | ||
} | ||
|
||
func New( | ||
mempool mempool.Mempool, | ||
txBuilder txbuilder.Builder, | ||
txExecutorBackend *txexecutor.Backend, | ||
blkManager blockexecutor.Manager, | ||
toEngine chan<- common.Message, | ||
) Builder { | ||
builder := &builder{ | ||
Mempool: mempool, | ||
txBuilder: txBuilder, | ||
txExecutorBackend: txExecutorBackend, | ||
blkManager: blkManager, | ||
toEngine: toEngine, | ||
} | ||
|
||
builder.timer = timer.NewTimer(builder.setNextBuildBlockTime) | ||
|
@@ -94,28 +91,14 @@ func New( | |
func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { | ||
b.Mempool.DisableAdding() | ||
defer func() { | ||
b.Mempool.RequestBuildBlock(false /*=emptyBlockPermitted*/) | ||
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.
I think we can end up building an invalid block and not scheduling to build another block to advance the timestamp. 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. Addressed in #2447 |
||
b.Mempool.EnableAdding() | ||
b.ResetBlockTimer() | ||
}() | ||
|
||
ctx := b.txExecutorBackend.Ctx | ||
ctx.Log.Debug("starting to attempt to build a block") | ||
|
||
statelessBlk, err := b.buildBlock() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Remove selected txs from mempool now that we are returning the block to | ||
// the consensus engine. | ||
txs := statelessBlk.Txs() | ||
b.Mempool.Remove(txs) | ||
return b.blkManager.NewBlock(statelessBlk), nil | ||
} | ||
|
||
// Returns the block we want to build and issue. | ||
// Only modifies state to remove expired proposal txs. | ||
func (b *builder) buildBlock() (block.Block, error) { | ||
// Get the block to build on top of and retrieve the new block's context. | ||
preferredID := b.blkManager.Preferred() | ||
preferred, err := b.blkManager.GetBlock(preferredID) | ||
|
@@ -150,14 +133,23 @@ func (b *builder) buildBlock() (block.Block, error) { | |
} | ||
// [timestamp] = min(max(now, parentTime), nextStakerChangeTime) | ||
|
||
return buildBlock( | ||
statelessBlk, err := buildBlock( | ||
b, | ||
preferredID, | ||
nextHeight, | ||
timestamp, | ||
timeWasCapped, | ||
preferredState, | ||
) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Remove selected txs from mempool now that we are returning the block to | ||
// the consensus engine. | ||
txs := statelessBlk.Txs() | ||
b.Mempool.Remove(txs) | ||
return b.blkManager.NewBlock(statelessBlk), nil | ||
} | ||
|
||
func (b *builder) Shutdown() { | ||
|
@@ -190,10 +182,10 @@ func (b *builder) setNextBuildBlockTime() { | |
return | ||
} | ||
|
||
if _, err := b.buildBlock(); err == nil { | ||
// We can build a block now | ||
b.notifyBlockReady() | ||
return | ||
now := b.txExecutorBackend.Clk.Time() | ||
if !b.nextStakerChangeTime.After(now) { | ||
// Block needs to be issued to advance time. | ||
b.Mempool.RequestBuildBlock(true /*=emptyBlockPermitted*/) | ||
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. The PR description says: 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. Should we return here? The rest of the work we do in this method seems unnecessary because 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. Re-worked this function a bit and now return early |
||
} | ||
|
||
// Wake up when it's time to add/remove the next validator/delegator | ||
|
@@ -218,27 +210,17 @@ func (b *builder) setNextBuildBlockTime() { | |
return | ||
} | ||
|
||
now := b.txExecutorBackend.Clk.Time() | ||
waitTime := nextStakerChangeTime.Sub(now) | ||
ctx.Log.Debug("setting next scheduled event", | ||
zap.Time("nextEventTime", nextStakerChangeTime), | ||
zap.Duration("timeUntil", waitTime), | ||
) | ||
|
||
// Wake up when it's time to add/remove the next validator | ||
b.nextStakerChangeTime = nextStakerChangeTime | ||
b.timer.SetTimeoutIn(waitTime) | ||
} | ||
|
||
// notifyBlockReady tells the consensus engine that a new block is ready to be | ||
// created | ||
func (b *builder) notifyBlockReady() { | ||
select { | ||
case b.toEngine <- common.PendingTxs: | ||
default: | ||
b.txExecutorBackend.Ctx.Log.Debug("dropping message to consensus engine") | ||
} | ||
} | ||
|
||
// [timestamp] is min(max(now, parent timestamp), next staker change time) | ||
func buildBlock( | ||
builder *builder, | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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 do we do this?
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.
We may want to build another block immediately after building a block. For example, the mempool is so full that there are more txs in it that can fit in a single block