Skip to content

Commit

Permalink
Merge pull request ethereum#2455 from zsfelfoldi/chaindb
Browse files Browse the repository at this point in the history
core: improved chain db performance by using sequential keys
  • Loading branch information
obscuren authored Jun 13, 2016
2 parents 73c028c + f9917c8 commit a38be3e
Show file tree
Hide file tree
Showing 24 changed files with 840 additions and 360 deletions.
2 changes: 1 addition & 1 deletion cmd/geth/chaincmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func dump(ctx *cli.Context) error {
for _, arg := range ctx.Args() {
var block *types.Block
if hashish(arg) {
block = chain.GetBlock(common.HexToHash(arg))
block = chain.GetBlockByHash(common.HexToHash(arg))
} else {
num, _ := strconv.Atoi(arg)
block = chain.GetBlockByNumber(uint64(num))
Expand Down
2 changes: 1 addition & 1 deletion cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,7 @@ func MustMakeChainConfig(ctx *cli.Context) *core.ChainConfig {

// MustMakeChainConfigFromDb reads the chain configuration from the given database.
func MustMakeChainConfigFromDb(ctx *cli.Context, db ethdb.Database) *core.ChainConfig {
genesis := core.GetBlock(db, core.GetCanonicalHash(db, 0))
genesis := core.GetBlock(db, core.GetCanonicalHash(db, 0), 0)

if genesis != nil {
// Existing genesis block, use stored config if available.
Expand Down
119 changes: 119 additions & 0 deletions core/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,122 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
b.Fatalf("insert error (block %d): %v\n", i, err)
}
}

func BenchmarkChainRead_header_10k(b *testing.B) {
benchReadChain(b, false, 10000)
}
func BenchmarkChainRead_full_10k(b *testing.B) {
benchReadChain(b, true, 10000)
}
func BenchmarkChainRead_header_100k(b *testing.B) {
benchReadChain(b, false, 100000)
}
func BenchmarkChainRead_full_100k(b *testing.B) {
benchReadChain(b, true, 100000)
}
func BenchmarkChainRead_header_500k(b *testing.B) {
benchReadChain(b, false, 500000)
}
func BenchmarkChainRead_full_500k(b *testing.B) {
benchReadChain(b, true, 500000)
}
func BenchmarkChainWrite_header_10k(b *testing.B) {
benchWriteChain(b, false, 10000)
}
func BenchmarkChainWrite_full_10k(b *testing.B) {
benchWriteChain(b, true, 10000)
}
func BenchmarkChainWrite_header_100k(b *testing.B) {
benchWriteChain(b, false, 100000)
}
func BenchmarkChainWrite_full_100k(b *testing.B) {
benchWriteChain(b, true, 100000)
}
func BenchmarkChainWrite_header_500k(b *testing.B) {
benchWriteChain(b, false, 500000)
}
func BenchmarkChainWrite_full_500k(b *testing.B) {
benchWriteChain(b, true, 500000)
}

// makeChainForBench writes a given number of headers or empty blocks/receipts
// into a database.
func makeChainForBench(db ethdb.Database, full bool, count uint64) {
var hash common.Hash
for n := uint64(0); n < count; n++ {
header := &types.Header{
Coinbase: common.Address{},
Number: big.NewInt(int64(n)),
ParentHash: hash,
Difficulty: big.NewInt(1),
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
ReceiptHash: types.EmptyRootHash,
}
hash = header.Hash()
WriteHeader(db, header)
WriteCanonicalHash(db, hash, n)
WriteTd(db, hash, n, big.NewInt(int64(n+1)))
if full || n == 0 {
block := types.NewBlockWithHeader(header)
WriteBody(db, hash, n, block.Body())
WriteBlockReceipts(db, hash, n, nil)
}
}
}

func benchWriteChain(b *testing.B, full bool, count uint64) {
for i := 0; i < b.N; i++ {
dir, err := ioutil.TempDir("", "eth-chain-bench")
if err != nil {
b.Fatalf("cannot create temporary directory: %v", err)
}
db, err := ethdb.NewLDBDatabase(dir, 128, 1024)
if err != nil {
b.Fatalf("error opening database at %v: %v", dir, err)
}
makeChainForBench(db, full, count)
db.Close()
os.RemoveAll(dir)
}
}

func benchReadChain(b *testing.B, full bool, count uint64) {
dir, err := ioutil.TempDir("", "eth-chain-bench")
if err != nil {
b.Fatalf("cannot create temporary directory: %v", err)
}
defer os.RemoveAll(dir)

db, err := ethdb.NewLDBDatabase(dir, 128, 1024)
if err != nil {
b.Fatalf("error opening database at %v: %v", dir, err)
}
makeChainForBench(db, full, count)
db.Close()

b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
db, err := ethdb.NewLDBDatabase(dir, 128, 1024)
if err != nil {
b.Fatalf("error opening database at %v: %v", dir, err)
}
chain, err := NewBlockChain(db, testChainConfig(), FakePow{}, new(event.TypeMux))
if err != nil {
b.Fatalf("error creating chain: %v", err)
}

for n := uint64(0); n < count; n++ {
header := chain.GetHeaderByNumber(n)
if full {
hash := header.Hash()
GetBody(db, hash, n)
GetBlockReceipts(db, hash, n)
}
}

db.Close()
}
}
2 changes: 1 addition & 1 deletion core/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (v *BlockValidator) ValidateBlock(block *types.Block) error {
return &KnownBlockError{block.Number(), block.Hash()}
}
}
parent := v.bc.GetBlock(block.ParentHash())
parent := v.bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
if parent == nil {
return ParentError(block.ParentHash())
}
Expand Down
Loading

0 comments on commit a38be3e

Please sign in to comment.