Skip to content

Commit 62db532

Browse files
authored
Support Volta hard fork(#277)
feat: support volta hard fork
2 parents b7c61bf + 446fa03 commit 62db532

File tree

20 files changed

+134
-53
lines changed

20 files changed

+134
-53
lines changed

beacon/engine/types.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package engine
1818

1919
import (
2020
"fmt"
21+
"github.com/holiman/uint256"
2122
"math/big"
2223

2324
"github.com/ethereum/go-ethereum/common"
@@ -26,6 +27,11 @@ import (
2627
"github.com/ethereum/go-ethereum/trie"
2728
)
2829

30+
var (
31+
OldBlockMillisecondsInterval uint64 = 1000
32+
NewBlockMillisecondsInterval uint64 = 500
33+
)
34+
2935
// PayloadVersion denotes the version of PayloadAttributes used to request the
3036
// building of the payload to commence.
3137
type PayloadVersion byte
@@ -58,12 +64,22 @@ type PayloadAttributes struct {
5864

5965
// JSON type overrides for PayloadAttributes.
6066
type payloadAttributesMarshaling struct {
61-
Timestamp hexutil.Uint64
67+
TempTimestamp hexutil.Uint64 // temp change 'Timestamp' to 'TempTimestamp' for debugging
68+
Random hexutil.Bytes // Random store the milliseconds
6269

6370
Transactions []hexutil.Bytes
6471
GasLimit *hexutil.Uint64
6572
}
6673

74+
func (p *PayloadAttributes) millisecondes() uint64 {
75+
if p.Random == (common.Hash{}) {
76+
return 0
77+
}
78+
return uint256.NewInt(0).SetBytes2(p.Random[:2]).Uint64()
79+
}
80+
81+
func (p *PayloadAttributes) MilliTimestamp() uint64 { return p.Timestamp*1000 + p.millisecondes() }
82+
6783
//go:generate go run github.com/fjl/gencodec -type ExecutableData -field-override executableDataMarshaling -out gen_ed.go
6884

6985
// ExecutableData is the data necessary to execute an EL payload.
@@ -93,6 +109,7 @@ type executableDataMarshaling struct {
93109
GasLimit hexutil.Uint64
94110
GasUsed hexutil.Uint64
95111
Timestamp hexutil.Uint64
112+
Random hexutil.Bytes // Random store the milliseconds
96113
BaseFeePerGas *hexutil.Big
97114
ExtraData hexutil.Bytes
98115
LogsBloom hexutil.Bytes

consensus/beacon/consensus.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, pa
255255
return errInvalidUncleHash
256256
}
257257
// Verify the timestamp
258-
if header.Time <= parent.Time {
258+
if header.MilliTimestamp() <= parent.MilliTimestamp() {
259259
return errInvalidTimestamp
260260
}
261261
// Verify the block's difficulty to ensure it's the default constant

consensus/ethash/consensus.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa
230230
return consensus.ErrFutureBlock
231231
}
232232
}
233-
if header.Time <= parent.Time {
233+
if header.MilliTimestamp() <= parent.MilliTimestamp() {
234234
return errOlderBlockTime
235235
}
236236
// Verify the block's difficulty based on its timestamp and parent's difficulty
@@ -539,6 +539,7 @@ func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) {
539539
header.GasLimit,
540540
header.GasUsed,
541541
header.Time,
542+
header.MixDigest,
542543
header.Extra,
543544
}
544545
if header.BaseFee != nil {

core/blockchain.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -683,16 +683,16 @@ func (bc *BlockChain) loadLastState() error {
683683
blockTd = bc.GetTd(headBlock.Hash(), headBlock.NumberU64())
684684
)
685685
if headHeader.Hash() != headBlock.Hash() {
686-
log.Info("Loaded most recent local header", "number", headHeader.Number, "hash", headHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(headHeader.Time), 0)))
686+
log.Info("Loaded most recent local header", "number", headHeader.Number, "hash", headHeader.Hash(), "td", headerTd, "age", common.PrettyAge(time.Unix(int64(headHeader.MilliTimestamp()), 0)))
687687
}
688-
log.Info("Loaded most recent local block", "number", headBlock.Number(), "hash", headBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(headBlock.Time()), 0)))
688+
log.Info("Loaded most recent local block", "number", headBlock.Number(), "hash", headBlock.Hash(), "td", blockTd, "age", common.PrettyAge(time.Unix(int64(headBlock.MilliTimestamp()), 0)))
689689
if headBlock.Hash() != currentSnapBlock.Hash() {
690690
snapTd := bc.GetTd(currentSnapBlock.Hash(), currentSnapBlock.Number.Uint64())
691-
log.Info("Loaded most recent local snap block", "number", currentSnapBlock.Number, "hash", currentSnapBlock.Hash(), "td", snapTd, "age", common.PrettyAge(time.Unix(int64(currentSnapBlock.Time), 0)))
691+
log.Info("Loaded most recent local snap block", "number", currentSnapBlock.Number, "hash", currentSnapBlock.Hash(), "td", snapTd, "age", common.PrettyAge(time.Unix(int64(currentSnapBlock.MilliTimestamp()), 0)))
692692
}
693693
if currentFinalBlock != nil {
694694
finalTd := bc.GetTd(currentFinalBlock.Hash(), currentFinalBlock.Number.Uint64())
695-
log.Info("Loaded most recent local finalized block", "number", currentFinalBlock.Number, "hash", currentFinalBlock.Hash(), "td", finalTd, "age", common.PrettyAge(time.Unix(int64(currentFinalBlock.Time), 0)))
695+
log.Info("Loaded most recent local finalized block", "number", currentFinalBlock.Number, "hash", currentFinalBlock.Hash(), "td", finalTd, "age", common.PrettyAge(time.Unix(int64(currentFinalBlock.MilliTimestamp()), 0)))
696696
}
697697
if pivot := rawdb.ReadLastPivotNumber(bc.db); pivot != nil {
698698
log.Info("Loaded last snap-sync pivot marker", "number", *pivot)
@@ -1505,7 +1505,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
15051505
head = blockChain[len(blockChain)-1]
15061506
context = []interface{}{
15071507
"count", stats.processed, "elapsed", common.PrettyDuration(time.Since(start)),
1508-
"number", head.Number(), "hash", head.Hash(), "age", common.PrettyAge(time.Unix(int64(head.Time()), 0)),
1508+
"number", head.Number(), "hash", head.Hash(), "age", common.PrettyAge(time.Unix(int64(head.MilliTimestamp()), 0)),
15091509
"size", common.StorageSize(size),
15101510
}
15111511
)
@@ -1728,7 +1728,7 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types
17281728
func (bc *BlockChain) addFutureBlock(block *types.Block) error {
17291729
max := uint64(time.Now().Unix() + maxTimeFutureBlocks)
17301730
if block.Time() > max {
1731-
return fmt.Errorf("future block timestamp %v > allowed %v", block.Time(), max)
1731+
return fmt.Errorf("future block timestamp %v > allowed %v", block.MilliTimestamp(), max)
17321732
}
17331733
if block.Difficulty().Cmp(common.Big0) == 0 {
17341734
// Never add PoS blocks into the future queue
@@ -2251,6 +2251,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
22512251
if bc.snaps != nil {
22522252
snapDiffItems, snapBufItems = bc.snaps.Size()
22532253
}
2254+
22542255
trieDiffNodes, trieBufNodes, trieImmutableBufNodes, _ := bc.triedb.Size()
22552256
stats.report(chain, it.index, snapDiffItems, snapBufItems, trieDiffNodes, trieBufNodes, trieImmutableBufNodes, setHead)
22562257
blockGasUsedGauge.Update(int64(block.GasUsed()) / 1000000)

core/chain_makers.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ func (b *BlockGen) TxNonce(addr common.Address) uint64 {
217217
func (b *BlockGen) AddUncle(h *types.Header) {
218218
// The uncle will have the same timestamp and auto-generated difficulty
219219
h.Time = b.header.Time
220+
h.MixDigest = b.header.MixDigest
220221

221222
var parent *types.Header
222223
for i := b.i - 1; i >= 0; i-- {

core/headerchain.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ import (
3838
)
3939

4040
const (
41-
headerCacheLimit = 512
42-
tdCacheLimit = 1024
41+
headerCacheLimit = 1280
42+
tdCacheLimit = 1280
4343
numberCacheLimit = 2048
4444
)
4545

core/txpool/blobpool/blobpool.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserve txpool.Addres
401401
p.recheck(addr, nil)
402402
}
403403
var (
404-
basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), p.head, p.head.Time+1))
404+
basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), p.head, p.head.NextSecondsTimestamp()))
405405
blobfee = uint256.NewInt(params.BlobTxMinBlobGasprice)
406406
)
407407
if p.head.ExcessBlobGas != nil {
@@ -822,7 +822,7 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) {
822822
}
823823
// Reset the price heap for the new set of basefee/blobfee pairs
824824
var (
825-
basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), newHead, newHead.Time+1))
825+
basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), newHead, newHead.NextSecondsTimestamp()))
826826
blobfee = uint256.MustFromBig(big.NewInt(params.BlobTxMinBlobGasprice))
827827
)
828828
if newHead.ExcessBlobGas != nil {

core/txpool/legacypool/legacypool.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1465,7 +1465,7 @@ func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest,
14651465
var pendingBaseFee = pool.priced.urgent.baseFee
14661466
if reset.newHead != nil {
14671467
if pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) {
1468-
pendingBaseFee = eip1559.CalcBaseFee(pool.chainconfig, reset.newHead, reset.newHead.Time+1)
1468+
pendingBaseFee = eip1559.CalcBaseFee(pool.chainconfig, reset.newHead, reset.newHead.NextSecondsTimestamp())
14691469
pool.priced.SetBaseFee(pendingBaseFee)
14701470
}
14711471
}

core/types/block.go

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package types
2020
import (
2121
"encoding/binary"
2222
"fmt"
23+
"github.com/holiman/uint256"
2324
"io"
2425
"math/big"
2526
"reflect"
@@ -31,6 +32,11 @@ import (
3132
"github.com/ethereum/go-ethereum/rlp"
3233
)
3334

35+
var (
36+
OldBlockMillisecondsInterval uint64 = 1000
37+
NewBlockMillisecondsInterval uint64 = 500
38+
)
39+
3440
// A BlockNonce is a 64-bit hash which proves (combined with the
3541
// mix-hash) that a sufficient amount of computation has been carried
3642
// out on a block.
@@ -101,14 +107,33 @@ type headerMarshaling struct {
101107
Number *hexutil.Big
102108
GasLimit hexutil.Uint64
103109
GasUsed hexutil.Uint64
104-
Time hexutil.Uint64
110+
Time hexutil.Uint64 // temp change 'Time' to 'TempTime' for debugging
111+
MixDigest hexutil.Bytes // MixDigest store the milliseconds
105112
Extra hexutil.Bytes
106113
BaseFee *hexutil.Big
107114
Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
108115
BlobGasUsed *hexutil.Uint64
109116
ExcessBlobGas *hexutil.Uint64
110117
}
111118

119+
func (h *Header) millisecondes() uint64 {
120+
if h.MixDigest == (common.Hash{}) {
121+
return 0
122+
}
123+
return uint256.NewInt(0).SetBytes2(h.MixDigest[:2]).Uint64()
124+
}
125+
126+
func (h *Header) MilliTimestamp() uint64 { return h.Time*1000 + h.millisecondes() }
127+
128+
func (h *Header) NextMilliTimestamp() uint64 {
129+
if h.MixDigest == (common.Hash{}) {
130+
return h.Time*1000 + OldBlockMillisecondsInterval
131+
}
132+
return h.MilliTimestamp() + NewBlockMillisecondsInterval
133+
}
134+
135+
func (h *Header) NextSecondsTimestamp() uint64 { return h.NextMilliTimestamp() / 1000 }
136+
112137
// Hash returns the block hash of the header, which is simply the keccak256 hash of its
113138
// RLP encoding.
114139
func (h *Header) Hash() common.Hash {
@@ -358,11 +383,12 @@ func (b *Block) Header() *Header {
358383

359384
// Header value accessors. These do copy!
360385

361-
func (b *Block) Number() *big.Int { return new(big.Int).Set(b.header.Number) }
362-
func (b *Block) GasLimit() uint64 { return b.header.GasLimit }
363-
func (b *Block) GasUsed() uint64 { return b.header.GasUsed }
364-
func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) }
365-
func (b *Block) Time() uint64 { return b.header.Time }
386+
func (b *Block) Number() *big.Int { return new(big.Int).Set(b.header.Number) }
387+
func (b *Block) GasLimit() uint64 { return b.header.GasLimit }
388+
func (b *Block) GasUsed() uint64 { return b.header.GasUsed }
389+
func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) }
390+
func (b *Block) Time() uint64 { return b.header.Time }
391+
func (b *Block) MilliTimestamp() uint64 { return b.header.MilliTimestamp() }
366392

367393
func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() }
368394
func (b *Block) MixDigest() common.Hash { return b.header.MixDigest }

core/vm/evm.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,12 @@ type BlockContext struct {
8888
Coinbase common.Address // Provides information for COINBASE
8989
GasLimit uint64 // Provides information for GASLIMIT
9090
BlockNumber *big.Int // Provides information for NUMBER
91-
Time uint64 // Provides information for TIME
92-
Difficulty *big.Int // Provides information for DIFFICULTY
93-
BaseFee *big.Int // Provides information for BASEFEE (0 if vm runs with NoBaseFee flag and 0 gas price)
94-
BlobBaseFee *big.Int // Provides information for BLOBBASEFEE (0 if vm runs with NoBaseFee flag and 0 blob gas price)
95-
Random *common.Hash // Provides information for PREVRANDAO
91+
// Time is used for checking fork, so the seconds timestamp is enough.
92+
Time uint64 // Provides information for TIME
93+
Difficulty *big.Int // Provides information for DIFFICULTY
94+
BaseFee *big.Int // Provides information for BASEFEE (0 if vm runs with NoBaseFee flag and 0 gas price)
95+
BlobBaseFee *big.Int // Provides information for BLOBBASEFEE (0 if vm runs with NoBaseFee flag and 0 blob gas price)
96+
Random *common.Hash // Provides information for PREVRANDAO
9697
}
9798

9899
// TxContext provides the EVM with information about a transaction.

0 commit comments

Comments
 (0)