Skip to content
This repository has been archived by the owner on Oct 18, 2023. It is now read-only.

Commit

Permalink
Fix hash mismatch at block 76328 (erigontech#467)
Browse files Browse the repository at this point in the history
  • Loading branch information
mandrigin authored Apr 18, 2020
1 parent a380d57 commit 33d18f3
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 10 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ profile.cov
/dashboard/assets/package-lock.json

**/yarn-error.log
/timings.txt
right_*.txt
root_*.txt
10 changes: 5 additions & 5 deletions cmd/state/stateless/stateless.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,11 @@ func Stateless(
chainConfig := params.MainnetChainConfig
vmConfig := vm.Config{}
engine := ethash.NewFullFaker()
bcb2, err := core.NewBlockChain(stateDb, nil, chainConfig, engine, vm.Config{}, nil)
check(err)

if blockNum > 1 {
block := bcb2.GetBlockByNumber(blockNum - 1)
bc, errBc := core.NewBlockChain(stateDb, nil, chainConfig, engine, vm.Config{}, nil)
check(errBc)
block := bc.GetBlockByNumber(blockNum - 1)
fmt.Printf("Block number: %d\n", blockNum-1)
fmt.Printf("Block root hash: %x\n", block.Root())
preRoot = block.Root()
Expand Down Expand Up @@ -296,7 +296,7 @@ func Stateless(
for i, tx := range block.Transactions() {
statedb.Prepare(tx.Hash(), block.Hash(), i)
var receipt *types.Receipt
receipt, err = core.ApplyTransaction(chainConfig, bcb2, nil, gp, statedb, tds.TrieStateWriter(), header, tx, usedGas, vmConfig)
receipt, err = core.ApplyTransaction(chainConfig, blockProvider, nil, gp, statedb, tds.TrieStateWriter(), header, tx, usedGas, vmConfig)
if err != nil {
fmt.Printf("tx %x failed: %v\n", tx.Hash(), err)
return
Expand Down Expand Up @@ -393,7 +393,7 @@ func Stateless(
ibs := state.New(s)
ibs.SetTrace(trace)
s.SetBlockNr(blockNum)
if err = runBlock(ibs, s, s, chainConfig, bcb2, block); err != nil {
if err = runBlock(ibs, s, s, chainConfig, blockProvider, block); err != nil {
fmt.Printf("Error running block %d through stateless2: %v\n", blockNum, err)
finalRootFail = true
} else if !binary {
Expand Down
80 changes: 75 additions & 5 deletions cmd/state/stateless/stateless_block_providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@ package stateless

import (
"compress/gzip"
"context"
"fmt"
"io"
"io/ioutil"
"net/url"
"os"
"strings"

"github.com/ledgerwatch/turbo-geth/common"
"github.com/ledgerwatch/turbo-geth/consensus"
"github.com/ledgerwatch/turbo-geth/consensus/ethash"
"github.com/ledgerwatch/turbo-geth/core"
"github.com/ledgerwatch/turbo-geth/core/rawdb"
"github.com/ledgerwatch/turbo-geth/core/types"
"github.com/ledgerwatch/turbo-geth/core/vm"
"github.com/ledgerwatch/turbo-geth/ethdb"
Expand All @@ -23,6 +28,7 @@ const (
)

type BlockProvider interface {
core.ChainContext
io.Closer
FastFwd(uint64) error
NextBlock() (*types.Block, error)
Expand Down Expand Up @@ -65,9 +71,18 @@ func NewBlockProviderFromDb(path string, createDbFunc CreateDbFunc) (BlockProvid

return &BlockChainBlockProvider{
bc: chain,
db: ethDb,
}, nil
}

func (p *BlockChainBlockProvider) Engine() consensus.Engine {
return p.bc.Engine()
}

func (p *BlockChainBlockProvider) GetHeader(h common.Hash, i uint64) *types.Header {
return p.bc.GetHeader(h, i)
}

func (p *BlockChainBlockProvider) Close() error {
p.db.Close()
return nil
Expand All @@ -85,8 +100,11 @@ func (p *BlockChainBlockProvider) NextBlock() (*types.Block, error) {
}

type ExportFileBlockProvider struct {
stream *rlp.Stream
fh io.Closer
stream *rlp.Stream
engine consensus.Engine
headersDb ethdb.Database
batch ethdb.DbWithPendingMutations
fh io.Closer
}

func NewBlockProviderFromExportFile(fn string) (BlockProvider, error) {
Expand All @@ -103,22 +121,61 @@ func NewBlockProviderFromExportFile(fn string) (BlockProvider, error) {
}
}
stream := rlp.NewStream(reader, 0)
return &ExportFileBlockProvider{stream, fh}, nil
engine := ethash.NewFullFaker()
// keeping all the past block headers in memory
headersDb := mustCreateTempDatabase()
return &ExportFileBlockProvider{stream, engine, headersDb, nil, fh}, nil
}

func getTempFileName() string {
tmpfile, err := ioutil.TempFile("", "headers.bolt")
if err != nil {
panic(fmt.Errorf("failed to create a temp file: %w", err))
}
tmpfile.Close()
fmt.Printf("creating a temp headers db @ %s\n", tmpfile.Name())
return tmpfile.Name()
}

func mustCreateTempDatabase() ethdb.Database {
db, err := ethdb.NewBoltDatabase(getTempFileName())
if err != nil {
panic(fmt.Errorf("failed to create a temp db for headers: %w", err))
}
return db
}

func (p *ExportFileBlockProvider) Close() error {
return p.fh.Close()
}

func (p *ExportFileBlockProvider) WriteHeader(h *types.Header) {
if p.batch == nil {
p.batch = p.headersDb.NewBatch()
}

rawdb.WriteHeader(context.TODO(), p.batch, h)

if p.batch.BatchSize() > 1000 {
if _, err := p.batch.Commit(); err != nil {
panic(fmt.Errorf("error writing headers: %w", err))
}
p.batch = nil
}
}

func (p *ExportFileBlockProvider) FastFwd(to uint64) error {
var b types.Block
for {
if err := p.stream.Decode(&b); err == io.EOF {
return nil
} else if err != nil {
return fmt.Errorf("error fast fwd: %v", err)
} else if b.NumberU64() >= to-1 {
return nil
} else {
p.WriteHeader(b.Header())
if b.NumberU64() >= to-1 {
return nil
}
}
}
}
Expand All @@ -130,5 +187,18 @@ func (p *ExportFileBlockProvider) NextBlock() (*types.Block, error) {
} else if err != nil {
return nil, fmt.Errorf("error fast fwd: %v", err)
}

p.WriteHeader(b.Header())
return &b, nil
}

func (p *ExportFileBlockProvider) Engine() consensus.Engine {
return p.engine
}

func (p *ExportFileBlockProvider) GetHeader(h common.Hash, i uint64) *types.Header {
if p.batch != nil {
return rawdb.ReadHeader(p.batch, h, i)
}
return rawdb.ReadHeader(p.headersDb, h, i)
}

0 comments on commit 33d18f3

Please sign in to comment.