Skip to content
This repository has been archived by the owner on Dec 4, 2024. It is now read-only.

Zero Integration #1775

Draft
wants to merge 21 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
83 changes: 64 additions & 19 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package blockchain

import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"math/big"
"path/filepath"
"sync"
"sync/atomic"

Expand Down Expand Up @@ -52,8 +55,8 @@ type Blockchain struct {
executor Executor
txSigner TxSigner

config *chain.Chain // Config containing chain information
genesis types.Hash // The hash of the genesis block
config *Config // Config containing chain information
genesis types.Hash // The hash of the genesis block

headersCache *lru.Cache // LRU cache for the headers
difficultyCache *lru.Cache // LRU cache for the difficulty
Expand Down Expand Up @@ -107,6 +110,7 @@ type BlockResult struct {
Root types.Hash
Receipts []*types.Receipt
TotalGas uint64
Trace *types.Trace
}

// updateGasPriceAvg updates the rolling average value of the gas price
Expand Down Expand Up @@ -191,7 +195,7 @@ func (b *Blockchain) GetAvgGasPrice() *big.Int {
func NewBlockchain(
logger hclog.Logger,
db storage.Storage,
config *chain.Chain,
config *Config,
consensus Verifier,
executor Executor,
txSigner TxSigner,
Expand Down Expand Up @@ -255,7 +259,7 @@ func (b *Blockchain) ComputeGenesis() error {
}

// validate that the genesis file in storage matches the chain.Genesis
if b.genesis != b.config.Genesis.Hash() {
if b.genesis != b.config.Chain.Genesis.Hash() {
return fmt.Errorf("genesis file does not match current genesis")
}

Expand All @@ -280,12 +284,12 @@ func (b *Blockchain) ComputeGenesis() error {
b.setCurrentHeader(header, diff)
} else {
// empty storage, write the genesis
if err := b.writeGenesis(b.config.Genesis); err != nil {
if err := b.writeGenesis(b.config.Chain.Genesis); err != nil {
return err
}
}

b.logger.Info("genesis", "hash", b.config.Genesis.Hash())
b.logger.Info("genesis", "hash", b.config.Chain.Genesis.Hash())

return nil
}
Expand Down Expand Up @@ -322,7 +326,7 @@ func (b *Blockchain) CurrentTD() *big.Int {

// Config returns the blockchain configuration
func (b *Blockchain) Config() *chain.Params {
return b.config.Params
return b.config.Chain.Params
}

// GetHeader returns the block header using the hash
Expand Down Expand Up @@ -612,17 +616,17 @@ func (b *Blockchain) VerifyFinalizedBlock(block *types.Block) (*types.FullBlock,
}

// Do the initial block verification
receipts, err := b.verifyBlock(block)
blockResult, err := b.verifyBlock(block)
if err != nil {
return nil, err
}

return &types.FullBlock{Block: block, Receipts: receipts}, nil
return &types.FullBlock{Block: block, Receipts: blockResult.Receipts, Trace: blockResult.Trace}, nil
}

// verifyBlock does the base (common) block verification steps by
// verifying the block body as well as the parent information
func (b *Blockchain) verifyBlock(block *types.Block) ([]*types.Receipt, error) {
func (b *Blockchain) verifyBlock(block *types.Block) (*BlockResult, error) {
// Make sure the block is present
if block == nil {
return nil, ErrNoBlock
Expand All @@ -633,8 +637,12 @@ func (b *Blockchain) verifyBlock(block *types.Block) ([]*types.Receipt, error) {
return nil, err
}

// Make sure the block body data is valid
return b.verifyBlockBody(block)
blockResult, err := b.verifyBlockBody(block)
if err != nil {
return nil, err
}

return blockResult, nil
}

// verifyBlockParent makes sure that the child block is in line
Expand Down Expand Up @@ -692,7 +700,7 @@ func (b *Blockchain) verifyBlockParent(childBlock *types.Block) error {
// - The trie roots match up (state, transactions, receipts, uncles)
// - The receipts match up
// - The execution result matches up
func (b *Blockchain) verifyBlockBody(block *types.Block) ([]*types.Receipt, error) {
func (b *Blockchain) verifyBlockBody(block *types.Block) (*BlockResult, error) {
// Make sure the Uncles root matches up
if hash := buildroot.CalculateUncleRoot(block.Uncles); hash != block.Header.Sha3Uncles {
b.logger.Error(fmt.Sprintf(
Expand Down Expand Up @@ -726,7 +734,7 @@ func (b *Blockchain) verifyBlockBody(block *types.Block) ([]*types.Receipt, erro
return nil, fmt.Errorf("unable to verify block execution result, %w", err)
}

return blockResult.Receipts, nil
return blockResult, nil
}

// verifyBlockResult verifies that the block transaction execution result
Expand Down Expand Up @@ -780,10 +788,11 @@ func (b *Blockchain) executeBlockTransactions(block *types.Block) (*BlockResult,
return nil, err
}

_, root, err := txn.Commit()
_, trace, root, err := txn.Commit()
if err != nil {
return nil, fmt.Errorf("failed to commit the state changes: %w", err)
}
trace.ParentStateRoot = parent.StateRoot

// Append the receipts to the receipts cache
b.receiptsCache.Add(header.Hash, txn.Receipts())
Expand All @@ -792,6 +801,7 @@ func (b *Blockchain) executeBlockTransactions(block *types.Block) (*BlockResult,
Root: root,
Receipts: txn.Receipts(),
TotalGas: txn.TotalGas(),
Trace: trace,
}, nil
}

Expand Down Expand Up @@ -832,6 +842,25 @@ func (b *Blockchain) WriteFullBlock(fblock *types.FullBlock, source string) erro
// but before it is written into the storage
batchWriter.PutReceipts(block.Hash(), fblock.Receipts)

// write the trace

// At this point we can loop through the traces and receipts, and generate intermediate tries
var rs types.Receipts

for _, tt := range fblock.Trace.TxnTraces {
for _, r := range fblock.Receipts {
if r.TxHash == tt.Hash {
rs = append(rs, r)
}
}

tt.ReceiptRoot = buildroot.CalculateReceiptsRoot(rs)
}

if err := b.writeTrace(fblock.Trace, header.Number); err != nil {
return err
}

// update snapshot
if err := b.consensus.ProcessHeaders([]*types.Header{header}); err != nil {
return err
Expand Down Expand Up @@ -1221,6 +1250,22 @@ func (b *Blockchain) getForksToWrite(header *types.Header) ([]types.Hash, error)
return append(newForks, header.Hash), nil
}

// writeTrace writes the block trace to the file
func (b *Blockchain) writeTrace(trace *types.Trace, blockNumber uint64) error {
raw, err := json.Marshal(trace)
if err != nil {
return err
}

consensusDir := filepath.Join(b.config.DataDir, "consensus")
if err := ioutil.WriteFile(
filepath.Join(consensusDir, fmt.Sprintf("trace_%d.json", blockNumber)), raw, 0600); err != nil {
return err
}

return nil
}

// handleReorg handles a reorganization event
func (b *Blockchain) handleReorg(
batchWriter *storage.BatchWriter,
Expand Down Expand Up @@ -1357,21 +1402,21 @@ func (b *Blockchain) Close() error {
// CalculateBaseFee calculates the basefee of the header.
func (b *Blockchain) CalculateBaseFee(parent *types.Header) uint64 {
// Return zero base fee is a london hardfork is not enabled
if !b.config.Params.Forks.IsActive(chain.London, parent.Number) {
if !b.config.Chain.Params.Forks.IsActive(chain.London, parent.Number) {
return 0
}

// Check if this is the first London hardfork block.
// Should return chain.GenesisBaseFee ins this case.
if parent.BaseFee == 0 {
if b.config.Genesis.BaseFee > 0 {
return b.config.Genesis.BaseFee
if b.config.Chain.Genesis.BaseFee > 0 {
return b.config.Chain.Genesis.BaseFee
}

return chain.GenesisBaseFee
}

parentGasTarget := parent.GasLimit / b.config.Genesis.BaseFeeEM
parentGasTarget := parent.GasLimit / b.config.Chain.Genesis.BaseFeeEM

// If the parent gasUsed is the same as the target, the baseFee remains unchanged.
if parent.GasUsed == parentGasTarget {
Expand Down
34 changes: 19 additions & 15 deletions blockchain/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ func TestCalculateGasLimit(t *testing.T) {
t.Fatalf("unable to construct the blockchain, %v", blockchainErr)
}

b.config.Params = &chain.Params{
b.config.Chain.Params = &chain.Params{
BlockGasTarget: tt.blockGasTarget,
}

Expand Down Expand Up @@ -1391,14 +1391,16 @@ func TestBlockchain_CalculateBaseFee(t *testing.T) {
t.Parallel()

blockchain := Blockchain{
config: &chain.Chain{
Params: &chain.Params{
Forks: &chain.Forks{
chain.London: chain.NewFork(5),
config: &Config{
Chain: &chain.Chain{
Params: &chain.Params{
Forks: &chain.Forks{
chain.London: chain.NewFork(5),
},
},
Genesis: &chain.Genesis{
BaseFeeEM: test.elasticityMultiplier,
},
},
Genesis: &chain.Genesis{
BaseFeeEM: test.elasticityMultiplier,
},
},
}
Expand Down Expand Up @@ -1443,14 +1445,16 @@ func TestBlockchain_WriteFullBlock(t *testing.T) {
logger: hclog.NewNullLogger(),
db: storageMock,
consensus: consensusMock,
config: &chain.Chain{
Params: &chain.Params{
Forks: &chain.Forks{
chain.London: chain.NewFork(5),
config: &Config{
Chain: &chain.Chain{
Params: &chain.Params{
Forks: &chain.Forks{
chain.London: chain.NewFork(5),
},
},
Genesis: &chain.Genesis{
BaseFeeEM: 4,
},
},
Genesis: &chain.Genesis{
BaseFeeEM: 4,
},
},
stream: &eventStream{},
Expand Down
9 changes: 9 additions & 0 deletions blockchain/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package blockchain

import "github.com/0xPolygon/polygon-edge/chain"

// Config is the configuration for the blockchain
type Config struct {
Chain *chain.Chain // the reference to the chain configuration
DataDir string // the base data directory for the client
}
8 changes: 4 additions & 4 deletions blockchain/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func NewMockBlockchain(
var (
mockVerifier = &MockVerifier{}
executor = &mockExecutor{}
config = &chain.Chain{
chainConfig = &chain.Chain{
Genesis: &chain.Genesis{
Number: 0,
GasLimit: 0,
Expand Down Expand Up @@ -191,7 +191,7 @@ func NewMockBlockchain(
return nil, errInvalidTypeAssertion
}

callback(config)
callback(chainConfig)
}

// Execute the storage callback
Expand All @@ -210,7 +210,7 @@ func NewMockBlockchain(
db: mockStorage,
consensus: mockVerifier,
executor: executor,
config: config,
config: &Config{Chain: chainConfig},
stream: &eventStream{},
gpAverage: &gasPriceAverage{
price: big.NewInt(0),
Expand Down Expand Up @@ -353,7 +353,7 @@ func newBlockChain(config *chain.Chain, executor Executor) (*Blockchain, error)
return nil, err
}

b, err := NewBlockchain(hclog.NewNullLogger(), db, config, &MockVerifier{}, executor, &mockSigner{})
b, err := NewBlockchain(hclog.NewNullLogger(), db, &Config{Chain: config}, &MockVerifier{}, executor, &mockSigner{})
if err != nil {
return nil, err
}
Expand Down
8 changes: 8 additions & 0 deletions chain/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ const (
EIP155 = "EIP155"
QuorumCalcAlignment = "quorumcalcalignment"
TxHashWithType = "txHashWithType"
EIP2929 = "EIP2929"
EIP2565 = "EIP2565"
LondonFix = "londonfix"
)

Expand Down Expand Up @@ -125,6 +127,8 @@ func (f *Forks) At(block uint64) ForksInTime {
EIP155: f.IsActive(EIP155, block),
QuorumCalcAlignment: f.IsActive(QuorumCalcAlignment, block),
TxHashWithType: f.IsActive(TxHashWithType, block),
EIP2929: f.IsActive(EIP2929, block),
EIP2565: f.IsActive(EIP2565, block),
LondonFix: f.IsActive(LondonFix, block),
}
}
Expand Down Expand Up @@ -155,6 +159,8 @@ type ForksInTime struct {
EIP155,
QuorumCalcAlignment,
TxHashWithType,
EIP2929,
EIP2565,
LondonFix bool
}

Expand All @@ -171,5 +177,7 @@ var AllForksEnabled = &Forks{
London: NewFork(0),
QuorumCalcAlignment: NewFork(0),
TxHashWithType: NewFork(0),
EIP2929: NewFork(0),
EIP2565: NewFork(0),
LondonFix: NewFork(0),
}
2 changes: 2 additions & 0 deletions command/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/0xPolygon/polygon-edge/command/rootchain"
"github.com/0xPolygon/polygon-edge/command/secrets"
"github.com/0xPolygon/polygon-edge/command/server"
"github.com/0xPolygon/polygon-edge/command/sidecar"
"github.com/0xPolygon/polygon-edge/command/status"
"github.com/0xPolygon/polygon-edge/command/txpool"
"github.com/0xPolygon/polygon-edge/command/version"
Expand Down Expand Up @@ -57,6 +58,7 @@ func (rc *RootCommand) registerSubCommands() {
genesis.GetCommand(),
server.GetCommand(),
license.GetCommand(),
sidecar.GetCommand(),
polybftsecrets.GetCommand(),
polybft.GetCommand(),
bridge.GetCommand(),
Expand Down
Loading
Loading