Skip to content

Commit 6f40e51

Browse files
authored
Prefetch Transactions from Pool & PIP-66 Back (#2031)
* enabling pip-66 back and wait moved from seal to prepare * bring subsecond extra time * prefetch from pool * more prefetch metrics * address early announcement for rio blocks * separate worker cache metrics * optinal flag to disable prefetch * prefetch gas limit flag * tests and lint * small fixes * remove logs * address duplicates * small fix on integration test * prefetch coverage histogram and fmt * verify headers coverage and bor test resiliency * address duplicates * duplicates and lint * addressing comments * small fix * address comments * fix push tx for rpc nodes * rename meter and intermediateroot prefetch * address lint * address succession number check * fixing concurrency issues and tests for prefetch state being thrown away by gc * make lint * e2e worker tests * benchmark tests * worker tests fixed and interrupt watch while waiting * remove parallel from tests
1 parent 94da0a6 commit 6f40e51

29 files changed

+2988
-238
lines changed

accounts/abi/bind/v2/dep_tree_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ func TestContractLinking(t *testing.T) {
287287
},
288288
},
289289
// test two contracts can be deployed which don't share deps
290-
linkTestCaseInput{
290+
{
291291
map[rune][]rune{
292292
'a': {'b', 'c', 'd', 'e'},
293293
'f': {'g', 'h', 'i', 'j'}},
@@ -297,7 +297,7 @@ func TestContractLinking(t *testing.T) {
297297
},
298298
},
299299
// test two contracts can be deployed which share deps
300-
linkTestCaseInput{
300+
{
301301
map[rune][]rune{
302302
'a': {'b', 'c', 'd', 'e'},
303303
'f': {'g', 'c', 'd', 'h'}},
@@ -307,31 +307,31 @@ func TestContractLinking(t *testing.T) {
307307
},
308308
},
309309
// test one contract with overrides for all lib deps
310-
linkTestCaseInput{
310+
{
311311
map[rune][]rune{
312312
'a': {'b', 'c', 'd', 'e'}},
313313
map[rune]struct{}{'b': {}, 'c': {}, 'd': {}, 'e': {}},
314314
map[rune]struct{}{
315315
'a': {}},
316316
},
317317
// test one contract with overrides for some lib deps
318-
linkTestCaseInput{
318+
{
319319
map[rune][]rune{
320320
'a': {'b', 'c'}},
321321
map[rune]struct{}{'b': {}, 'c': {}},
322322
map[rune]struct{}{
323323
'a': {}},
324324
},
325325
// test deployment of a contract with overrides
326-
linkTestCaseInput{
326+
{
327327
map[rune][]rune{
328328
'a': {}},
329329
map[rune]struct{}{'a': {}},
330330
map[rune]struct{}{},
331331
},
332332
// two contracts ('a' and 'f') share some dependencies. contract 'a' is marked as an override. expect that any of
333333
// its dependencies that aren't shared with 'f' are not deployed.
334-
linkTestCaseInput{map[rune][]rune{
334+
{map[rune][]rune{
335335
'a': {'b', 'c', 'd', 'e'},
336336
'f': {'g', 'c', 'd', 'h'}},
337337
map[rune]struct{}{'a': {}},

cmd/utils/flags.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,6 @@ var (
598598
Usage: "0x prefixed public address for the pending block producer (not used for actual block production)",
599599
Category: flags.MinerCategory,
600600
}
601-
602601
// Account settings
603602
PasswordFileFlag = &cli.PathFlag{
604603
Name: "password",

consensus/beacon/consensus.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,14 +336,14 @@ func (beacon *Beacon) verifyHeaders(chain consensus.ChainHeaderReader, headers [
336336

337337
// Prepare implements consensus.Engine, initializing the difficulty field of a
338338
// header to conform to the beacon protocol. The changes are done inline.
339-
func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error {
339+
func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header, waitOnPrepare bool) error {
340340
// Transition isn't triggered yet, use the legacy rules for preparation.
341341
reached, err := IsTTDReached(chain, header.ParentHash, header.Number.Uint64()-1)
342342
if err != nil {
343343
return err
344344
}
345345
if !reached {
346-
return beacon.ethone.Prepare(chain, header)
346+
return beacon.ethone.Prepare(chain, header, waitOnPrepare)
347347
}
348348
header.Difficulty = beaconDifficulty
349349
return nil

consensus/bor/bor.go

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -402,13 +402,30 @@ func (c *Bor) verifyHeader(chain consensus.ChainHeaderReader, header *types.Head
402402
number := header.Number.Uint64()
403403
now := uint64(time.Now().Unix())
404404

405-
// Allow early blocks if Bhilai HF is enabled
406-
if c.config.IsBhilai(header.Number) {
405+
if c.config.IsRio(header.Number) {
406+
// Rio HF introduced flexible blocktime (can be set larger than consensus without approval).
407+
// Using strict CalcProducerDelay would reject valid blocks, so we just ensure announcement
408+
// time comes after parent time to allow for flexible blocktime.
409+
var parent *types.Header
410+
411+
if len(parents) > 0 {
412+
parent = parents[len(parents)-1]
413+
} else {
414+
parent = chain.GetHeader(header.ParentHash, number-1)
415+
}
416+
if parent == nil || now < parent.Time {
417+
log.Error("Block announced too early post rio", "number", number, "headerTime", header.Time, "now", now)
418+
return consensus.ErrFutureBlock
419+
}
420+
} else if c.config.IsBhilai(header.Number) {
421+
// Allow early blocks if Bhilai HF is enabled
407422
// Don't waste time checking blocks from the future but allow a buffer of block time for
408423
// early block announcements. Note that this is a loose check and would allow early blocks
409424
// from non-primary producer. Such blocks will be rejected later when we know the succession
410425
// number of the signer in the current sprint.
411-
if header.Time-c.config.CalculatePeriod(number) > now {
426+
// Uses CalcProducerDelay instead of block period to account for producer delay on sprint start blocks.
427+
// We assume succession 0 (primary producer) to not be much restrictive for early block announcements.
428+
if header.Time-CalcProducerDelay(number, 0, c.config) > now {
412429
log.Error("Block announced too early post bhilai", "number", number, "headerTime", header.Time, "now", now)
413430
return consensus.ErrFutureBlock
414431
}
@@ -476,7 +493,18 @@ func (c *Bor) verifyHeader(chain consensus.ChainHeaderReader, header *types.Head
476493
return err
477494
}
478495

479-
c.recentVerifiedHeaders.Set(header.Hash(), header, ttlcache.DefaultTTL)
496+
// Calculate TTL for the header cache entry
497+
// If the header time is in the future (early announced block), add extra time to TTL
498+
cacheTTL := veblopBlockTimeout
499+
nowTime := time.Now()
500+
headerTime := time.Unix(int64(header.Time), 0)
501+
if headerTime.After(nowTime) {
502+
// Add the time from now until header time as extra to the base timeout
503+
extraTime := headerTime.Sub(nowTime)
504+
cacheTTL = veblopBlockTimeout + extraTime
505+
}
506+
507+
c.recentVerifiedHeaders.Set(header.Hash(), header, cacheTTL)
480508
return nil
481509
}
482510

@@ -928,7 +956,7 @@ func IsBlockEarly(parent *types.Header, header *types.Header, number uint64, suc
928956

929957
// Prepare implements consensus.Engine, preparing all the consensus fields of the
930958
// header for running the transactions on top.
931-
func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error {
959+
func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header, waitOnPrepare bool) error {
932960
// If the block isn't a checkpoint, cast a random vote (good enough for now)
933961
header.Coinbase = common.Address{}
934962
header.Nonce = types.BlockNonce{}
@@ -1026,6 +1054,8 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) e
10261054
return fmt.Errorf("the floor of custom mining block time (%v) is less than the consensus block time: %v < %v", c.blockTime, c.blockTime.Seconds(), c.config.CalculatePeriod(number))
10271055
}
10281056

1057+
var delay time.Duration
1058+
10291059
if c.blockTime > 0 && c.config.IsRio(header.Number) {
10301060
// Only enable custom block time for Rio and later
10311061

@@ -1043,14 +1073,16 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) e
10431073
actualNewBlockTime := parentActualBlockTime.Add(c.blockTime)
10441074
header.Time = uint64(actualNewBlockTime.Unix())
10451075
header.ActualTime = actualNewBlockTime
1076+
delay = time.Until(parentActualBlockTime)
10461077
} else {
10471078
header.Time = parent.Time + CalcProducerDelay(number, succession, c.config)
1079+
delay = time.Until(time.Unix(int64(parent.Time), 0))
10481080
}
10491081

10501082
now := time.Now()
10511083
if header.Time < uint64(now.Unix()) {
10521084
additionalBlockTime := time.Duration(c.config.CalculatePeriod(number)) * time.Second
1053-
if c.blockTime > 0 {
1085+
if c.blockTime > 0 && c.config.IsRio(header.Number) {
10541086
additionalBlockTime = c.blockTime
10551087
}
10561088
header.Time = uint64(now.Add(additionalBlockTime).Unix())
@@ -1059,6 +1091,22 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) e
10591091
}
10601092
}
10611093

1094+
// Wait before start the block production if needed (previsously this wait was on Seal)
1095+
if c.config.IsBhilai(header.Number) && waitOnPrepare {
1096+
var successionNumber int
1097+
// if signer is not empty (RPC nodes have empty signer)
1098+
if currentSigner.signer != (common.Address{}) {
1099+
var err error
1100+
successionNumber, err = snap.GetSignerSuccessionNumber(currentSigner.signer)
1101+
if err != nil {
1102+
return err
1103+
}
1104+
if successionNumber == 0 {
1105+
<-time.After(delay)
1106+
}
1107+
}
1108+
}
1109+
10621110
return nil
10631111
}
10641112

@@ -1323,14 +1371,8 @@ func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, witnes
13231371
var delay time.Duration
13241372

13251373
// Sweet, the protocol permits us to sign the block, wait for our time
1326-
if c.config.IsBhilai(header.Number) {
1327-
delay = time.Until(header.GetActualTime()) // Wait until we reach header time for non-primary validators
1328-
// Disable early block announcement
1329-
// if successionNumber == 0 {
1330-
// // For primary producers, set the delay to `header.Time - block time` instead of `header.Time`
1331-
// // for early block announcement instead of waiting for full block time.
1332-
// delay = time.Until(time.Unix(int64(header.Time-c.config.CalculatePeriod(number)), 0))
1333-
// }
1374+
if c.config.IsBhilai(header.Number) && successionNumber == 0 {
1375+
delay = 0 // delay was moved to Prepare for bhilai and later
13341376
} else {
13351377
delay = time.Until(header.GetActualTime()) // Wait until we reach header time
13361378
}

0 commit comments

Comments
 (0)