mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-16 00:43:46 +00:00
feat(worker): seal block early if we're over target block time (#706)
* feat(worker): seal block early if we're over target block time * use current.header.Time * typo * break instead of return
This commit is contained in:
parent
d81a3308b1
commit
62926d4649
3 changed files with 77 additions and 1 deletions
|
|
@ -251,6 +251,7 @@ type worker struct {
|
||||||
skipSealHook func(*task) bool // Method to decide whether skipping the sealing.
|
skipSealHook func(*task) bool // Method to decide whether skipping the sealing.
|
||||||
fullTaskHook func() // Method to call before pushing the full sealing task.
|
fullTaskHook func() // Method to call before pushing the full sealing task.
|
||||||
resubmitHook func(time.Duration, time.Duration) // Method to call upon updating resubmitting interval.
|
resubmitHook func(time.Duration, time.Duration) // Method to call upon updating resubmitting interval.
|
||||||
|
beforeTxHook func() // Method to call before processing a transaction.
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, isLocalBlock func(*types.Block) bool, init bool) *worker {
|
func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, isLocalBlock func(*types.Block) bool, init bool) *worker {
|
||||||
|
|
@ -1034,6 +1035,10 @@ func (w *worker) commitTransactions(txs types.OrderedTransactionSet, coinbase co
|
||||||
var loops int64
|
var loops int64
|
||||||
loop:
|
loop:
|
||||||
for {
|
for {
|
||||||
|
if w.beforeTxHook != nil {
|
||||||
|
w.beforeTxHook()
|
||||||
|
}
|
||||||
|
|
||||||
loops++
|
loops++
|
||||||
// In the following three cases, we will interrupt the execution of the transaction.
|
// In the following three cases, we will interrupt the execution of the transaction.
|
||||||
// (1) new head block event arrival, the interrupt signal is 1
|
// (1) new head block event arrival, the interrupt signal is 1
|
||||||
|
|
@ -1055,6 +1060,12 @@ loop:
|
||||||
}
|
}
|
||||||
return atomic.LoadInt32(interrupt) == commitInterruptNewHead, circuitCapacityReached
|
return atomic.LoadInt32(interrupt) == commitInterruptNewHead, circuitCapacityReached
|
||||||
}
|
}
|
||||||
|
// seal block early if we're over time
|
||||||
|
// note: current.header.Time = max(parent.Time + cliquePeriod, now())
|
||||||
|
if w.current.tcount > 0 && w.chainConfig.Clique != nil && uint64(time.Now().Unix()) > w.current.header.Time {
|
||||||
|
circuitCapacityReached = true // skip subsequent invocations of commitTransactions
|
||||||
|
break
|
||||||
|
}
|
||||||
// If we don't have enough gas for any further transactions then we're done
|
// If we don't have enough gas for any further transactions then we're done
|
||||||
if w.current.gasPool.Gas() < params.TxGas {
|
if w.current.gasPool.Gas() < params.TxGas {
|
||||||
log.Trace("Not enough gas for further transactions", "have", w.current.gasPool, "want", params.TxGas)
|
log.Trace("Not enough gas for further transactions", "have", w.current.gasPool, "want", params.TxGas)
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ func newTestWorkerBackend(t *testing.T, chainConfig *params.ChainConfig, engine
|
||||||
switch e := engine.(type) {
|
switch e := engine.(type) {
|
||||||
case *clique.Clique:
|
case *clique.Clique:
|
||||||
gspec.ExtraData = make([]byte, 32+common.AddressLength+crypto.SignatureLength)
|
gspec.ExtraData = make([]byte, 32+common.AddressLength+crypto.SignatureLength)
|
||||||
|
gspec.Timestamp = uint64(time.Now().Unix())
|
||||||
copy(gspec.ExtraData[32:32+common.AddressLength], testBankAddress.Bytes())
|
copy(gspec.ExtraData[32:32+common.AddressLength], testBankAddress.Bytes())
|
||||||
e.Authorize(testBankAddress, func(account accounts.Account, s string, data []byte) ([]byte, error) {
|
e.Authorize(testBankAddress, func(account accounts.Account, s string, data []byte) ([]byte, error) {
|
||||||
return crypto.Sign(crypto.Keccak256(data), testBankKey)
|
return crypto.Sign(crypto.Keccak256(data), testBankKey)
|
||||||
|
|
@ -1253,3 +1254,67 @@ func TestSkippedTransactionDatabaseEntries(t *testing.T) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSealBlockAfterCliquePeriod(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
var (
|
||||||
|
engine consensus.Engine
|
||||||
|
chainConfig *params.ChainConfig
|
||||||
|
db = rawdb.NewMemoryDatabase()
|
||||||
|
)
|
||||||
|
chainConfig = params.AllCliqueProtocolChanges
|
||||||
|
chainConfig.Clique = ¶ms.CliqueConfig{Period: 1, Epoch: 30000}
|
||||||
|
engine = clique.New(chainConfig.Clique, db)
|
||||||
|
w, b := newTestWorker(t, chainConfig, engine, db, 0)
|
||||||
|
defer w.close()
|
||||||
|
|
||||||
|
// This test chain imports the mined blocks.
|
||||||
|
b.genesis.MustCommit(db)
|
||||||
|
chain, _ := core.NewBlockChain(db, nil, b.chain.Config(), engine, vm.Config{
|
||||||
|
Debug: true,
|
||||||
|
Tracer: vm.NewStructLogger(&vm.LogConfig{EnableMemory: true, EnableReturnData: true})}, nil, nil)
|
||||||
|
defer chain.Stop()
|
||||||
|
|
||||||
|
// Ignore empty commit here for less noise.
|
||||||
|
w.skipSealHook = func(task *task) bool {
|
||||||
|
return len(task.receipts) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add artificial delay to transaction processing.
|
||||||
|
w.beforeTxHook = func() {
|
||||||
|
time.Sleep(time.Duration(chainConfig.Clique.Period) * 1 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for mined blocks.
|
||||||
|
sub := w.mux.Subscribe(core.NewMinedBlockEvent{})
|
||||||
|
defer sub.Unsubscribe()
|
||||||
|
|
||||||
|
// Insert 2 non-l1msg txs
|
||||||
|
b.txPool.AddLocal(b.newRandomTx(true))
|
||||||
|
b.txPool.AddLocal(b.newRandomTx(false))
|
||||||
|
|
||||||
|
// Start mining!
|
||||||
|
w.start()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case ev := <-sub.Chan():
|
||||||
|
block := ev.Data.(core.NewMinedBlockEvent).Block
|
||||||
|
if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
|
||||||
|
t.Fatalf("failed to insert new mined block %d: %v", block.NumberU64(), err)
|
||||||
|
}
|
||||||
|
assert.Equal(1, len(block.Transactions())) // only packed 1 tx, not 2
|
||||||
|
case <-time.After(5 * time.Second):
|
||||||
|
t.Fatalf("timeout")
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case ev := <-sub.Chan():
|
||||||
|
block := ev.Data.(core.NewMinedBlockEvent).Block
|
||||||
|
if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
|
||||||
|
t.Fatalf("failed to insert new mined block %d: %v", block.NumberU64(), err)
|
||||||
|
}
|
||||||
|
assert.Equal(1, len(block.Transactions()))
|
||||||
|
case <-time.After(5 * time.Second):
|
||||||
|
t.Fatalf("timeout")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import (
|
||||||
const (
|
const (
|
||||||
VersionMajor = 5 // Major version component of the current release
|
VersionMajor = 5 // Major version component of the current release
|
||||||
VersionMinor = 2 // Minor version component of the current release
|
VersionMinor = 2 // Minor version component of the current release
|
||||||
VersionPatch = 4 // Patch version component of the current release
|
VersionPatch = 5 // Patch version component of the current release
|
||||||
VersionMeta = "mainnet" // Version metadata to append to the version string
|
VersionMeta = "mainnet" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue