Skip to content

Commit

Permalink
Merge pull request #198 from covalenthq/develop
Browse files Browse the repository at this point in the history
Complete EIP-4844 blob export support (Ethereum Migration v1.5)
  • Loading branch information
noslav authored Apr 24, 2024
2 parents 82b1d1f + b720ac5 commit fd1af89
Show file tree
Hide file tree
Showing 11 changed files with 172 additions and 75 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,4 @@ logs/
coverage.out
coverage.txt
tests/spec-tests/
bin/
1 change: 1 addition & 0 deletions cmd/geth/chaincmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ if one is set. Otherwise it prints the genesis from the datadir.`,
utils.BlockReplicationTargetsFlag,
utils.ReplicaEnableSpecimenFlag,
utils.ReplicaEnableResultFlag,
utils.ReplicaEnableBlobFlag,
}, utils.DatabaseFlags),
Description: `
The import command imports blocks from an RLP-encoded form. The form can be one file
Expand Down
1 change: 1 addition & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ var (
utils.BlockReplicationTargetsFlag,
utils.ReplicaEnableResultFlag,
utils.ReplicaEnableSpecimenFlag,
utils.ReplicaEnableBlobFlag,
}, utils.NetworkFlags, utils.DatabaseFlags)

rpcFlags = []cli.Flag{
Expand Down
9 changes: 8 additions & 1 deletion cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,10 @@ var (
Name: "replica.result",
Usage: "Enables export of fields that comprise a block-result",
}
ReplicaEnableBlobFlag = &cli.BoolFlag{
Name: "replica.blob",
Usage: "Enables export of fields that comprise a block-blob",
}
BatchRequestLimit = &cli.IntFlag{
Name: "rpc.batch-request-limit",
Usage: "Maximum number of requests in a batch",
Expand Down Expand Up @@ -2188,8 +2192,11 @@ func setBlockReplicationTargets(ctx *cli.Context, cfg *eth.Config) {
if ctx.Bool(ReplicaEnableResultFlag.Name) {
cfg.ReplicaEnableResult = true
}
if ctx.Bool(ReplicaEnableBlobFlag.Name) {
cfg.ReplicaEnableBlob = true
}
} else {
Fatalf("--replication.targets flag is invalid without --replica.specimen and/or --replica.result")
Fatalf("--replication.targets flag is invalid without --replica.specimen and/or --replica.result, ONLY ADD --replica.blob with both replica.specimen AND replica.result flags for complete unified state capture)")
}
}

Expand Down
101 changes: 61 additions & 40 deletions core/block_replica.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,23 @@ type BlockReplicationEvent struct {
}

func (bc *BlockChain) createBlockReplica(block *types.Block, replicaConfig *ReplicaConfig, chainConfig *params.ChainConfig, stateSpecimen *types.StateSpecimen) error {
//block replica
exportBlockReplica, err := bc.createReplica(block, replicaConfig, chainConfig, stateSpecimen)

// blobs
var blobTxSidecars []*types.BlobTxSidecar
if replicaConfig.EnableBlob {
for sidecarData := range types.BlobTxSidecarChan {
if sidecarData.BlockNumber.Uint64() == block.NumberU64() {
log.Info("Consuming BlobTxSidecar Match From Chain Sync Channel", "Block Number:", sidecarData.BlockNumber.Uint64())
blobTxSidecars = append(blobTxSidecars, sidecarData.Blobs)
} else {
log.Info("Failing BlobTxSidecar Match from Chain Sync Channel", "Block Number:", sidecarData.BlockNumber.Uint64())
}
log.Info("BlobTxSidecar Header", "Block Number:", sidecarData.BlockNumber.Uint64())
log.Info("Chain Sync Sidecar Channel", "Length:", len(types.BlobTxSidecarChan))
}
}
//block replica with blobs
exportBlockReplica, err := bc.createReplica(block, replicaConfig, chainConfig, stateSpecimen, blobTxSidecars)
if err != nil {
return err
}
Expand Down Expand Up @@ -50,7 +65,7 @@ func (bc *BlockChain) createBlockReplica(block *types.Block, replicaConfig *Repl
}
}

func (bc *BlockChain) createReplica(block *types.Block, replicaConfig *ReplicaConfig, chainConfig *params.ChainConfig, stateSpecimen *types.StateSpecimen) (*types.ExportBlockReplica, error) {
func (bc *BlockChain) createReplica(block *types.Block, replicaConfig *ReplicaConfig, chainConfig *params.ChainConfig, stateSpecimen *types.StateSpecimen, blobSpecimen []*types.BlobTxSidecar) (*types.ExportBlockReplica, error) {
bHash := block.Hash()
bNum := block.NumberU64()

Expand Down Expand Up @@ -117,55 +132,58 @@ func (bc *BlockChain) createReplica(block *types.Block, replicaConfig *ReplicaCo
uncles := block.Uncles()

//block replica export
if replicaConfig.EnableSpecimen && replicaConfig.EnableResult {
if replicaConfig.EnableSpecimen && replicaConfig.EnableResult && replicaConfig.EnableBlob {
exportBlockReplica := &types.ExportBlockReplica{
Type: "block-replica",
NetworkId: chainConfig.ChainID.Uint64(),
Hash: bHash,
TotalDiff: td,
Header: header,
Transactions: txsRlp,
Uncles: uncles,
Receipts: receiptsRlp,
Senders: senders,
State: stateSpecimen,
Withdrawals: withdrawalsRlp,
Type: "block-replica",
NetworkId: chainConfig.ChainID.Uint64(),
Hash: bHash,
TotalDiff: td,
Header: header,
Transactions: txsRlp,
Uncles: uncles,
Receipts: receiptsRlp,
Senders: senders,
State: stateSpecimen,
Withdrawals: withdrawalsRlp,
BlobTxSidecars: blobSpecimen,
}
log.Debug("Exporting full block-replica")
log.Debug("Exporting full block-replica with blob-specimen")
return exportBlockReplica, nil
} else if replicaConfig.EnableSpecimen && !replicaConfig.EnableResult {
exportBlockReplica := &types.ExportBlockReplica{
Type: "block-specimen",
NetworkId: chainConfig.ChainID.Uint64(),
Hash: bHash,
TotalDiff: td,
Header: header,
Transactions: txsRlp,
Uncles: uncles,
Receipts: []*types.ReceiptExportRLP{},
Senders: senders,
State: stateSpecimen,
Withdrawals: withdrawalsRlp,
Type: "block-specimen",
NetworkId: chainConfig.ChainID.Uint64(),
Hash: bHash,
TotalDiff: td,
Header: header,
Transactions: txsRlp,
Uncles: uncles,
Receipts: []*types.ReceiptExportRLP{},
Senders: senders,
State: stateSpecimen,
Withdrawals: withdrawalsRlp,
BlobTxSidecars: []*types.BlobTxSidecar{},
}
log.Debug("Exporting block-specimen only")
log.Debug("Exporting block-specimen only (no blob specimens)")
return exportBlockReplica, nil
} else if !replicaConfig.EnableSpecimen && replicaConfig.EnableResult {
exportBlockReplica := &types.ExportBlockReplica{
Type: "block-result",
NetworkId: chainConfig.ChainID.Uint64(),
Hash: bHash,
TotalDiff: td,
Header: header,
Transactions: txsRlp,
Uncles: uncles,
Receipts: receiptsRlp,
Senders: senders,
State: &types.StateSpecimen{},
Type: "block-result",
NetworkId: chainConfig.ChainID.Uint64(),
Hash: bHash,
TotalDiff: td,
Header: header,
Transactions: txsRlp,
Uncles: uncles,
Receipts: receiptsRlp,
Senders: senders,
State: &types.StateSpecimen{},
BlobTxSidecars: []*types.BlobTxSidecar{},
}
log.Debug("Exporting block-result only")
log.Debug("Exporting block-result only (no blob specimens)")
return exportBlockReplica, nil
} else {
return nil, fmt.Errorf("--replication.targets flag is invalid without --replica.specimen and/or --replica.result")
return nil, fmt.Errorf("--replication.targets flag is invalid without --replica.specimen and/or --replica.result, ADD --replica.blob with both replica.specimen AND replica.result flags for complete unified state capture aka block-replica)")
}
}

Expand All @@ -181,5 +199,8 @@ func (bc *BlockChain) SetBlockReplicaExports(replicaConfig *ReplicaConfig) bool
if replicaConfig.EnableSpecimen {
bc.ReplicaConfig.EnableSpecimen = true
}
if replicaConfig.EnableBlob {
bc.ReplicaConfig.EnableBlob = true
}
return true
}
14 changes: 11 additions & 3 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ type BlockChain struct {
type ReplicaConfig struct {
EnableSpecimen bool
EnableResult bool
EnableBlob bool
HistoricalBlocksSynced *uint32
}

Expand Down Expand Up @@ -315,6 +316,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
ReplicaConfig: &ReplicaConfig{
EnableSpecimen: false,
EnableResult: false,
EnableBlob: false,
HistoricalBlocksSynced: new(uint32), // Always set 0 for historical mode at start
},
}
Expand Down Expand Up @@ -1851,7 +1853,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)

if !setHead {
// Export Block Specimen
bc.createBlockReplica(block, bc.ReplicaConfig, bc.chainConfig, statedb.TakeStateSpecimen())
if bc.ReplicaConfig.EnableSpecimen || bc.ReplicaConfig.EnableResult {
bc.createBlockReplica(block, bc.ReplicaConfig, bc.chainConfig, statedb.TakeStateSpecimen())
}
// After merge we expect few side chains. Simply count
// all blocks the CL gives us for GC processing time
bc.gcproc += proctime
Expand All @@ -1865,7 +1869,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
"elapsed", common.PrettyDuration(time.Since(start)),
"root", block.Root())
// Handle creation of block specimen for canonical blocks
bc.createBlockReplica(block, bc.ReplicaConfig, bc.chainConfig, statedb.TakeStateSpecimen())
if bc.ReplicaConfig.EnableSpecimen || bc.ReplicaConfig.EnableResult {
bc.createBlockReplica(block, bc.ReplicaConfig, bc.chainConfig, statedb.TakeStateSpecimen())
}
lastCanon = block

// Only count canonical blocks for GC processing time
Expand All @@ -1887,7 +1893,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
"txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()),
"root", block.Root())
// Is impossible but keeping in line to be nice to our future selves we add this for now
bc.createBlockReplica(block, bc.ReplicaConfig, bc.chainConfig, statedb.TakeStateSpecimen())
if bc.ReplicaConfig.EnableSpecimen || bc.ReplicaConfig.EnableResult {
bc.createBlockReplica(block, bc.ReplicaConfig, bc.chainConfig, statedb.TakeStateSpecimen())
}
}
}

Expand Down
91 changes: 64 additions & 27 deletions core/types/block_export.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@ import (
)

type ExportBlockReplica struct {
Type string
NetworkId uint64
Hash common.Hash
TotalDiff *big.Int
Header *Header
Transactions []*TransactionExportRLP
Uncles []*Header
Receipts []*ReceiptExportRLP
Senders []common.Address
State *StateSpecimen
Withdrawals []*WithdrawalExportRLP
Type string
NetworkId uint64
Hash common.Hash
TotalDiff *big.Int
Header *Header
Transactions []*TransactionExportRLP
Uncles []*Header
Receipts []*ReceiptExportRLP
Senders []common.Address
State *StateSpecimen
Withdrawals []*WithdrawalExportRLP
BlobTxSidecars []*BlobTxSidecar
}

type LogsExportRLP struct {
Expand Down Expand Up @@ -71,8 +72,18 @@ type TransactionExportRLP struct {
V *big.Int `json:"v" rlp:"nil"`
R *big.Int `json:"r" rlp:"nil"`
S *big.Int `json:"s" rlp:"nil"`
BlobFeeCap *big.Int `json:"blobFeeCap" rlp:"optional"`
BlobHashes []common.Hash `json:"blobHashes" rlp:"optional"`
BlobGas uint64 `json:"blobGas" rlp:"optional"`
}

type BlobTxSidecarData struct {
Blobs *BlobTxSidecar
BlockNumber *big.Int
}

var BlobTxSidecarChan = make(chan *BlobTxSidecarData, 100)

func (r *ReceiptForExport) ExportReceipt() *ReceiptExportRLP {
enc := &ReceiptExportRLP{
PostStateOrStatus: (*Receipt)(r).statusEncoding(),
Expand Down Expand Up @@ -105,21 +116,47 @@ func (tx *TransactionForExport) ExportTx(chainConfig *params.ChainConfig, blockN

txData := tx.inner

return &TransactionExportRLP{
AccountNonce: txData.nonce(),
Price: txData.effectiveGasPrice(&big.Int{}, baseFee),
GasLimit: txData.gas(),
Sender: &from,
Recipient: txData.to(),
Amount: txData.value(),
Payload: txData.data(),
Type: txData.txType(),
ChainId: txData.chainID(),
AccessList: txData.accessList(),
GasTipCap: txData.gasTipCap(),
GasFeeCap: txData.gasFeeCap(),
V: v,
R: r,
S: s,
if inner_tx.Type() == BlobTxType {
return &TransactionExportRLP{
AccountNonce: txData.nonce(),
Price: txData.effectiveGasPrice(&big.Int{}, baseFee),
GasLimit: txData.gas(),
Sender: &from,
Recipient: txData.to(),
Amount: txData.value(),
Payload: txData.data(),
Type: txData.txType(),
ChainId: txData.chainID(),
AccessList: txData.accessList(),
GasTipCap: txData.gasTipCap(),
GasFeeCap: txData.gasFeeCap(),
V: v,
R: r,
S: s,
BlobFeeCap: inner_tx.BlobGasFeeCap(),
BlobHashes: inner_tx.BlobHashes(),
BlobGas: inner_tx.BlobGas(),
}
} else {
return &TransactionExportRLP{
AccountNonce: txData.nonce(),
Price: txData.effectiveGasPrice(&big.Int{}, baseFee),
GasLimit: txData.gas(),
Sender: &from,
Recipient: txData.to(),
Amount: txData.value(),
Payload: txData.data(),
Type: txData.txType(),
ChainId: txData.chainID(),
AccessList: txData.accessList(),
GasTipCap: txData.gasTipCap(),
GasFeeCap: txData.gasFeeCap(),
V: v,
R: r,
S: s,
BlobFeeCap: &big.Int{},
BlobHashes: make([]common.Hash, 0),
BlobGas: 0,
}
}
}
3 changes: 2 additions & 1 deletion eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
ReplicaConfig: &core.ReplicaConfig{
EnableSpecimen: config.ReplicaEnableSpecimen,
EnableResult: config.ReplicaEnableResult,
EnableBlob: config.ReplicaEnableBlob,
HistoricalBlocksSynced: new(uint32), // Always set 0 for historical mode at start
},
}
Expand All @@ -186,7 +187,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
if err != nil {
return nil, err
}
log.Info("Block replication started", "targets", targets, "network ID", config.NetworkId, "export block-specimen", eth.ReplicaConfig.EnableSpecimen, "export block-result", eth.ReplicaConfig.EnableResult)
log.Info("Block replication started", "targets", targets, "network ID", config.NetworkId, "export block-specimen", eth.ReplicaConfig.EnableSpecimen, "export block-result", eth.ReplicaConfig.EnableResult, "export blob-specimen", eth.ReplicaConfig.EnableBlob)
eth.blockReplicators = append(eth.blockReplicators, replicator)
}
bcVersion := rawdb.ReadDatabaseVersion(chainDb)
Expand Down
1 change: 1 addition & 0 deletions eth/ethconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ type Config struct {
// Bools that make explicit types being exported
ReplicaEnableResult bool
ReplicaEnableSpecimen bool
ReplicaEnableBlob bool

// OverrideCancun (TODO: remove after the fork)
OverrideCancun *uint64 `toml:",omitempty"`
Expand Down
Loading

0 comments on commit fd1af89

Please sign in to comment.