Skip to content
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

4844 on bsc #2279

Merged
merged 28 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
286bbb8
ci: temp enable blobtx branch ci run;
galaio Feb 19, 2024
595efc3
Switch ON blobpool & ensure Cancun hardfork can occur (#2223)
emailtovamos Feb 21, 2024
ab8a8fd
feat: support blob storage & miscs; (#2229)
galaio Mar 4, 2024
989bc66
blockchian: support to import block with blob & blobGasFee; (#2260)
galaio Mar 12, 2024
49e78bb
blobTx: mining + brodcasting (#2253)
emailtovamos Mar 13, 2024
8063efd
blobtx mining pass (#2282)
buddh0 Mar 13, 2024
e29c386
Sidecar fetching changes for 4844 (#2283)
emailtovamos Mar 14, 2024
38a2404
Implement eth_getBlobSidecars && eth_getBlobSidecarByTxHash (#2286)
zlacfzy Mar 15, 2024
59a6552
execution: add blob gas fee reward to system;
galaio Mar 12, 2024
7afc260
syncing: support blob syncing & DA checking;
galaio Mar 13, 2024
832e1fc
naming: rename blobs to sidecars;
galaio Mar 15, 2024
e5d81b8
core: build fix (#2294)
emailtovamos Mar 16, 2024
24b6fc7
fix the semantics of WithXXX (#2293)
buddh0 Mar 16, 2024
dd6550d
config: reduce sidecar cache to 1024 and rename (#2297)
zzzckck Mar 18, 2024
cb56d54
fix: Withdrawals turn into empty from nil when BlockBody has Sidecars…
buddh0 Mar 18, 2024
7b94187
internal/api_test: add test case for eth_getBlobSidecars && eth_getBl…
zlacfzy Mar 18, 2024
4f7c26c
consensus/misc: rollback CalcBlobFee (#2306)
buddh0 Mar 19, 2024
da48fc8
flags: add new flags to override blobs' params;
galaio Mar 20, 2024
6552451
freezer: fix blob ancient save error;
galaio Mar 20, 2024
420147c
fix: fix som failed UTs;
galaio Mar 20, 2024
352bfd2
fix: fix some validation issues & ancient reset; (#2316)
galaio Mar 21, 2024
2313e2c
blobsidecar: add new sidecar struct with metadata; (#2315)
galaio Mar 21, 2024
7fc9e28
core/rawdb: optimize write block with sidecars (#2318)
buddh0 Mar 22, 2024
8e6835b
mev: add TxIndex for mev bid (#2325)
buddh0 Mar 22, 2024
96605e4
remove useless Config() (#2326)
buddh0 Mar 22, 2024
0800afd
fix WithSidecars (#2327)
buddh0 Mar 22, 2024
a85b134
fix: fix mined block sidecar issue; (#2328)
galaio Mar 22, 2024
5560375
fix WithSidecars (#2329)
buddh0 Mar 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion beacon/engine/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ func ExecutableDataToBlock(params ExecutableData, versionedHashes []common.Hash,

// BlockToExecutableData constructs the ExecutableData structure by filling the
// fields from the given block. It assumes the given block is post-merge block.
func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.BlobTxSidecar) *ExecutionPayloadEnvelope {
func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars types.BlobSidecars) *ExecutionPayloadEnvelope {
data := &ExecutableData{
BlockHash: block.Hash(),
ParentHash: block.ParentHash(),
Expand Down
12 changes: 12 additions & 0 deletions cmd/geth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"strings"
"unicode"

"github.com/ethereum/go-ethereum/eth/downloader"

"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/external"
"github.com/ethereum/go-ethereum/accounts/keystore"
Expand Down Expand Up @@ -199,6 +201,16 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
v := ctx.Uint64(utils.OverrideFeynmanFix.Name)
cfg.Eth.OverrideFeynmanFix = &v
}
if ctx.IsSet(utils.OverrideFullImmutabilityThreshold.Name) {
params.FullImmutabilityThreshold = ctx.Uint64(utils.OverrideFullImmutabilityThreshold.Name)
downloader.FullMaxForkAncestry = ctx.Uint64(utils.OverrideFullImmutabilityThreshold.Name)
}
if ctx.IsSet(utils.OverrideMinBlocksForBlobRequests.Name) {
params.MinBlocksForBlobRequests = ctx.Uint64(utils.OverrideMinBlocksForBlobRequests.Name)
}
if ctx.IsSet(utils.OverrideDefaultExtraReserveForBlobRequests.Name) {
params.DefaultExtraReserveForBlobRequests = ctx.Uint64(utils.OverrideDefaultExtraReserveForBlobRequests.Name)
}
if ctx.IsSet(utils.SeparateDBFlag.Name) && !stack.IsSeparatedDB() {
utils.Fatalf("Failed to locate separate database subdirectory when separatedb parameter has been set")
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ var (
utils.OverrideVerkle,
utils.OverrideFeynman,
utils.OverrideFeynmanFix,
utils.OverrideFullImmutabilityThreshold,
utils.OverrideMinBlocksForBlobRequests,
utils.OverrideDefaultExtraReserveForBlobRequests,
utils.EnablePersonal,
utils.TxPoolLocalsFlag,
utils.TxPoolNoLocalsFlag,
Expand Down Expand Up @@ -171,6 +174,7 @@ var (
utils.VoteJournalDirFlag,
utils.LogDebugFlag,
utils.LogBacktraceAtFlag,
utils.BlobExtraReserveFlag,
}, utils.NetworkFlags, utils.DatabaseFlags)

rpcFlags = []cli.Flag{
Expand Down
41 changes: 39 additions & 2 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,25 @@ var (
Category: flags.EthCategory,
}
OverrideFeynmanFix = &cli.Uint64Flag{
Name: "override.feynmanfix",
Usage: "Manually specify the FeynmanFix fork timestamp, overriding the bundled setting",
Name: "override.feynmanfix",
Usage: "Manually specify the FeynmanFix fork timestamp, overriding the bundled setting",
}
OverrideFullImmutabilityThreshold = &cli.Uint64Flag{
Name: "override.immutabilitythreshold",
Usage: "It is the number of blocks after which a chain segment is considered immutable, only for testing purpose",
Value: params.FullImmutabilityThreshold,
Category: flags.EthCategory,
}
OverrideMinBlocksForBlobRequests = &cli.Uint64Flag{
Name: "override.minforblobrequest",
Usage: "It keeps blob data available for min blocks in local, only for testing purpose",
Value: params.MinBlocksForBlobRequests,
Category: flags.EthCategory,
}
OverrideDefaultExtraReserveForBlobRequests = &cli.Uint64Flag{
Name: "override.defaultextrareserve",
Usage: "It adds more extra time for expired blobs for some request cases, only for testing purpose",
Value: params.DefaultExtraReserveForBlobRequests,
Category: flags.EthCategory,
}
SyncModeFlag = &flags.TextMarshalerFlag{
Expand Down Expand Up @@ -1095,6 +1112,14 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.
Usage: "Path for the voteJournal dir in fast finality feature (default = inside the datadir)",
Category: flags.FastFinalityCategory,
}

// Blob setting
BlobExtraReserveFlag = &cli.Uint64Flag{
Name: "blob.extra-reserve",
Usage: "Extra reserve threshold for blob, blob never expires when 0 is set, default 28800",
Value: params.DefaultExtraReserveForBlobRequests,
Category: flags.MiscCategory,
}
buddh0 marked this conversation as resolved.
Show resolved Hide resolved
)

var (
Expand Down Expand Up @@ -2117,6 +2142,18 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
if err := kzg4844.UseCKZG(ctx.String(CryptoKZGFlag.Name) == "ckzg"); err != nil {
Fatalf("Failed to set KZG library implementation to %s: %v", ctx.String(CryptoKZGFlag.Name), err)
}

// blob setting
if ctx.IsSet(OverrideDefaultExtraReserveForBlobRequests.Name) {
cfg.BlobExtraReserve = ctx.Uint64(OverrideDefaultExtraReserveForBlobRequests.Name)
}
if ctx.IsSet(BlobExtraReserveFlag.Name) {
extraReserve := ctx.Uint64(BlobExtraReserveFlag.Name)
if extraReserve > 0 && extraReserve < params.DefaultExtraReserveForBlobRequests {
extraReserve = params.DefaultExtraReserveForBlobRequests
}
cfg.BlobExtraReserve = extraReserve
}
}

// SetDNSDiscoveryDefaults configures DNS discovery with the given URL if
Expand Down
2 changes: 1 addition & 1 deletion consensus/clique/clique.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ func (c *Clique) snapshot(chain consensus.ChainHeaderReader, number uint64, hash
// at a checkpoint block without a parent (light client CHT), or we have piled
// up more headers than allowed to be reorged (chain reinit from a freezer),
// consider the checkpoint trusted and snapshot it.
if number == 0 || (number%c.config.Epoch == 0 && (len(headers) > params.FullImmutabilityThreshold || chain.GetHeaderByNumber(number-1) == nil)) {
if number == 0 || (number%c.config.Epoch == 0 && (len(headers) > int(params.FullImmutabilityThreshold) || chain.GetHeaderByNumber(number-1) == nil)) {
checkpoint := chain.GetHeaderByNumber(number)
if checkpoint != nil {
hash := checkpoint.Hash()
Expand Down
3 changes: 3 additions & 0 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ type ChainHeaderReader interface {

// GetHighestVerifiedHeader retrieves the highest header verified.
GetHighestVerifiedHeader() *types.Header

// ChasingHead return the best chain head of peers.
ChasingHead() *types.Header
}

type VotePool interface {
Expand Down
22 changes: 13 additions & 9 deletions consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -583,23 +583,27 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H
return err
}

// Verify existence / non-existence of withdrawalsHash.
if header.WithdrawalsHash != nil {
return fmt.Errorf("invalid withdrawalsHash: have %x, expected nil", header.WithdrawalsHash)
}
// Verify the existence / non-existence of cancun-specific header fields
if header.ParentBeaconRoot != nil {
return fmt.Errorf("invalid parentBeaconRoot, have %#x, expected nil", header.ParentBeaconRoot)
}
cancun := chain.Config().IsCancun(header.Number, header.Time)
if !cancun {
switch {
case header.ExcessBlobGas != nil:
return fmt.Errorf("invalid excessBlobGas: have %d, expected nil", header.ExcessBlobGas)
case header.BlobGasUsed != nil:
return fmt.Errorf("invalid blobGasUsed: have %d, expected nil", header.BlobGasUsed)
case header.ParentBeaconRoot != nil:
return fmt.Errorf("invalid parentBeaconRoot, have %#x, expected nil", header.ParentBeaconRoot)
case header.WithdrawalsHash != nil:
return fmt.Errorf("invalid WithdrawalsHash, have %#x, expected nil", header.WithdrawalsHash)
}
} else {
switch {
case header.ParentBeaconRoot != nil:
return fmt.Errorf("invalid parentBeaconRoot, have %#x, expected nil", header.ParentBeaconRoot)
// types.EmptyWithdrawalsHash represents a empty value when EIP-4895 enabled,
// here, EIP-4895 still be disabled, value expected to be `common.Hash{}` is only to feet the demand of rlp encode/decode
case header.WithdrawalsHash == nil || *header.WithdrawalsHash != common.Hash{}:
zzzckck marked this conversation as resolved.
Show resolved Hide resolved
return errors.New("header has wrong WithdrawalsHash")
}
if err := eip4844.VerifyEIP4844Header(parent, header); err != nil {
return err
}
Expand Down Expand Up @@ -700,7 +704,7 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash
// If we're at the genesis, snapshot the initial state. Alternatively if we have
// piled up more headers than allowed to be reorged (chain reinit from a freezer),
// consider the checkpoint trusted and snapshot it.
if number == 0 || (number%p.config.Epoch == 0 && (len(headers) > params.FullImmutabilityThreshold/10)) {
if number == 0 || (number%p.config.Epoch == 0 && (len(headers) > int(params.FullImmutabilityThreshold)/10)) {
checkpoint := chain.GetHeaderByNumber(number)
if checkpoint != nil {
// get checkpoint data
Expand Down
4 changes: 2 additions & 2 deletions core/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
},
func() error {
// Withdrawals are present after the Shanghai fork.
if header.WithdrawalsHash != nil {
if !header.EmptyWithdrawalsHash() {
// Withdrawals list must be present in body after Shanghai.
if block.Withdrawals() == nil {
return errors.New("missing withdrawals in block body")
}
if hash := types.DeriveSha(block.Withdrawals(), trie.NewStackTrie(nil)); hash != *header.WithdrawalsHash {
return fmt.Errorf("withdrawals root hash mismatch (header value %x, calculated %x)", *header.WithdrawalsHash, hash)
}
} else if block.Withdrawals() != nil {
} else if len(block.Withdrawals()) != 0 { // Withdrawals turn into empty from nil when BlockBody has Sidecars
// Withdrawals are not allowed prior to shanghai fork
return errors.New("withdrawals present in block body")
}
Expand Down
56 changes: 55 additions & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ const (
blockCacheLimit = 256
diffLayerCacheLimit = 1024
receiptsCacheLimit = 10000
sidecarsCacheLimit = 1024
txLookupCacheLimit = 1024
maxBadBlockLimit = 16
maxFutureBlocks = 256
Expand Down Expand Up @@ -271,12 +272,14 @@ type BlockChain struct {
highestVerifiedHeader atomic.Pointer[types.Header]
currentBlock atomic.Pointer[types.Header] // Current head of the chain
currentSnapBlock atomic.Pointer[types.Header] // Current head of snap-sync
chasingHead atomic.Pointer[types.Header]

bodyCache *lru.Cache[common.Hash, *types.Body]
bodyRLPCache *lru.Cache[common.Hash, rlp.RawValue]
receiptsCache *lru.Cache[common.Hash, []*types.Receipt]
blockCache *lru.Cache[common.Hash, *types.Block]
txLookupCache *lru.Cache[common.Hash, txLookup]
sidecarsCache *lru.Cache[common.Hash, types.BlobSidecars]

// future blocks are blocks added for later processing
futureBlocks *lru.Cache[common.Hash, *types.Block]
Expand Down Expand Up @@ -359,6 +362,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit),
bodyRLPCache: lru.NewCache[common.Hash, rlp.RawValue](bodyCacheLimit),
receiptsCache: lru.NewCache[common.Hash, []*types.Receipt](receiptsCacheLimit),
sidecarsCache: lru.NewCache[common.Hash, types.BlobSidecars](sidecarsCacheLimit),
blockCache: lru.NewCache[common.Hash, *types.Block](blockCacheLimit),
txLookupCache: lru.NewCache[common.Hash, txLookup](txLookupCacheLimit),
futureBlocks: lru.NewCache[common.Hash, *types.Block](maxFutureBlocks),
Expand Down Expand Up @@ -390,6 +394,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
bc.highestVerifiedHeader.Store(nil)
bc.currentBlock.Store(nil)
bc.currentSnapBlock.Store(nil)
bc.chasingHead.Store(nil)

// Update chain info data metrics
chainInfoGauge.Update(metrics.GaugeInfoValue{"chain_id": bc.chainConfig.ChainID.String()})
Expand Down Expand Up @@ -646,6 +651,9 @@ func (bc *BlockChain) cacheDiffLayer(diffLayer *types.DiffLayer, diffLayerCh cha

func (bc *BlockChain) cacheBlock(hash common.Hash, block *types.Block) {
bc.blockCache.Add(hash, block)
if bc.chainConfig.IsCancun(block.Number(), block.Time()) {
bc.sidecarsCache.Add(hash, block.Sidecars())
}
}

// empty returns an indicator whether the blockchain is empty.
Expand Down Expand Up @@ -990,6 +998,7 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
bc.bodyCache.Purge()
bc.bodyRLPCache.Purge()
bc.receiptsCache.Purge()
bc.sidecarsCache.Purge()
bc.blockCache.Purge()
bc.txLookupCache.Purge()
bc.futureBlocks.Purge()
Expand Down Expand Up @@ -1034,6 +1043,16 @@ func (bc *BlockChain) SnapSyncCommitHead(hash common.Hash) error {
return nil
}

// UpdateChasingHead update remote best chain head, used by DA check now.
func (bc *BlockChain) UpdateChasingHead(head *types.Header) {
bc.chasingHead.Store(head)
}

// ChasingHead return the best chain head of peers.
func (bc *BlockChain) ChasingHead() *types.Header {
return bc.chasingHead.Load()
}

// Reset purges the entire blockchain, restoring it to its genesis state.
func (bc *BlockChain) Reset() error {
return bc.ResetWithGenesisBlock(bc.genesisBlock)
Expand Down Expand Up @@ -1317,6 +1336,14 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
}
}

// check DA after cancun
lastBlk := blockChain[len(blockChain)-1]
if bc.chainConfig.Parlia != nil && bc.chainConfig.IsCancun(lastBlk.Number(), lastBlk.Time()) {
if _, err := CheckDataAvailableInBatch(bc, blockChain); err != nil {
return 0, err
}
}

var (
stats = struct{ processed, ignored int32 }{}
start = time.Now()
Expand Down Expand Up @@ -1378,6 +1405,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
// Write all chain data to ancients.
td := bc.GetTd(first.Hash(), first.NumberU64())
writeSize, err := rawdb.WriteAncientBlocks(bc.db, blockChain, receiptChain, td)

if err != nil {
log.Error("Error importing chain data to ancients", "err", err)
return 0, err
Expand Down Expand Up @@ -1455,6 +1483,9 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
// Write all the data out into the database
rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body())
rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receiptChain[i])
if bc.chainConfig.IsCancun(block.Number(), block.Time()) {
rawdb.WriteBlobSidecars(batch, block.Hash(), block.NumberU64(), block.Sidecars())
}

// Write everything belongs to the blocks into the database. So that
// we can ensure all components of body is completed(body, receipts)
Expand Down Expand Up @@ -1524,6 +1555,10 @@ func (bc *BlockChain) writeBlockWithoutState(block *types.Block, td *big.Int) (e
batch := bc.db.NewBatch()
rawdb.WriteTd(batch, block.Hash(), block.NumberU64(), td)
rawdb.WriteBlock(batch, block)
// if cancun is enabled, here need to write sidecars too
if bc.chainConfig.IsCancun(block.Number(), block.Time()) {
rawdb.WriteBlobSidecars(batch, block.Hash(), block.NumberU64(), block.Sidecars())
}
if err := batch.Write(); err != nil {
log.Crit("Failed to write block into disk", "err", err)
}
Expand Down Expand Up @@ -1566,6 +1601,10 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd)
rawdb.WriteBlock(blockBatch, block)
rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts)
// if cancun is enabled, here need to write sidecars too
if bc.chainConfig.IsCancun(block.Number(), block.Time()) {
rawdb.WriteBlobSidecars(blockBatch, block.Hash(), block.NumberU64(), block.Sidecars())
}
rawdb.WritePreimages(blockBatch, state.Preimages())
if err := blockBatch.Write(); err != nil {
log.Crit("Failed to write block into disk", "err", err)
Expand Down Expand Up @@ -1828,6 +1867,14 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
}
}
}()

// check block data available first
if bc.chainConfig.Parlia != nil {
if index, err := CheckDataAvailableInBatch(bc, chain); err != nil {
return index, err
}
}

// Start the parallel header verifier
headers := make([]*types.Header, len(chain))
for i, block := range chain {
Expand Down Expand Up @@ -1985,6 +2032,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
if parent == nil {
parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
}

statedb, err := state.NewWithSharedPool(parent.Root, bc.stateCache, bc.snaps)
if err != nil {
return it.index, err
Expand Down Expand Up @@ -2286,7 +2334,9 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (i
if block == nil {
log.Crit("Importing heavy sidechain block is nil", "hash", hashes[i], "number", numbers[i])
}

if bc.chainConfig.IsCancun(block.Number(), block.Time()) {
block = block.WithSidecars(bc.GetSidecarsByHash(hashes[i]))
}
blocks = append(blocks, block)
memory += block.Size()

Expand Down Expand Up @@ -2358,6 +2408,9 @@ func (bc *BlockChain) recoverAncestors(block *types.Block) (common.Hash, error)
} else {
b = bc.GetBlock(hashes[i], numbers[i])
}
if bc.chainConfig.IsCancun(b.Number(), b.Time()) {
b = b.WithSidecars(bc.GetSidecarsByHash(b.Hash()))
}
if _, err := bc.insertChain(types.Blocks{b}, false); err != nil {
return b.ParentHash(), err
}
Expand Down Expand Up @@ -2804,6 +2857,7 @@ func (bc *BlockChain) isCachedBadBlock(block *types.Block) bool {
}

// reportBlock logs a bad block error.
// bad block need not save receipts & sidecars.
func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, err error) {
rawdb.WriteBadBlock(bc.db, block)
log.Error(summarizeBadBlock(block, receipts, bc.Config(), err))
Expand Down
Loading
Loading