Merge pull request #1801 from fjl/ethdb

all: move common.Database to ethdb and add NewBatch
pull/1813/head
Jeffrey Wilcke 9 years ago
commit 985b5f29ed
  1. 3
      cmd/geth/blocktestcmd.go
  2. 3
      cmd/geth/chaincmd.go
  3. 2
      cmd/geth/js_test.go
  4. 2
      cmd/utils/flags.go
  5. 2
      common/natspec/natspec_e2e_test.go
  6. 2
      core/bench_test.go
  7. 5
      core/block_processor.go
  8. 7
      core/chain_makers.go
  9. 5
      core/chain_manager.go
  10. 4
      core/chain_manager_test.go
  11. 45
      core/chain_util.go
  12. 9
      core/genesis.go
  13. 6
      core/helper_test.go
  14. 6
      core/manager.go
  15. 7
      core/state/state_object.go
  16. 5
      core/state/statedb.go
  17. 10
      core/transaction_util.go
  18. 51
      eth/backend.go
  19. 5
      eth/handler.go
  20. 41
      ethdb/database.go
  21. 10
      ethdb/interface.go
  22. 24
      ethdb/memory_database.go
  23. 3
      miner/agent.go
  24. 3
      miner/worker.go
  25. 2
      tests/block_test_util.go
  26. 3
      tests/util.go

@ -22,7 +22,6 @@ import (
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/tests" "github.com/ethereum/go-ethereum/tests"
@ -103,7 +102,7 @@ func runBlockTest(ctx *cli.Context) {
func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, error) { func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, error) {
cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx) cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx)
cfg.NewDB = func(path string) (common.Database, error) { return ethdb.NewMemDatabase() } cfg.NewDB = func(path string) (ethdb.Database, error) { return ethdb.NewMemDatabase() }
cfg.MaxPeers = 0 // disable network cfg.MaxPeers = 0 // disable network
cfg.Shh = false // disable whisper cfg.Shh = false // disable whisper
cfg.NAT = nil // disable port mapping cfg.NAT = nil // disable port mapping

@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
) )
@ -191,7 +192,7 @@ func hashish(x string) bool {
return err != nil return err != nil
} }
func closeAll(dbs ...common.Database) { func closeAll(dbs ...ethdb.Database) {
for _, db := range dbs { for _, db := range dbs {
db.Close() db.Close()
} }

@ -103,7 +103,7 @@ func testREPL(t *testing.T, config func(*eth.Config)) (string, *testjethre, *eth
Name: "test", Name: "test",
SolcPath: testSolcPath, SolcPath: testSolcPath,
PowTest: true, PowTest: true,
NewDB: func(path string) (common.Database, error) { return db, nil }, NewDB: func(path string) (ethdb.Database, error) { return db, nil },
} }
if config != nil { if config != nil {
config(conf) config(conf)

@ -508,7 +508,7 @@ func SetupEth(ctx *cli.Context) {
} }
// MakeChain creates a chain manager from set command line flags. // MakeChain creates a chain manager from set command line flags.
func MakeChain(ctx *cli.Context) (chain *core.ChainManager, chainDb common.Database) { func MakeChain(ctx *cli.Context) (chain *core.ChainManager, chainDb ethdb.Database) {
datadir := ctx.GlobalString(DataDirFlag.Name) datadir := ctx.GlobalString(DataDirFlag.Name)
cache := ctx.GlobalInt(CacheFlag.Name) cache := ctx.GlobalInt(CacheFlag.Name)

@ -143,7 +143,7 @@ func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) {
MaxPeers: 0, MaxPeers: 0,
PowTest: true, PowTest: true,
Etherbase: common.HexToAddress(testAddress), Etherbase: common.HexToAddress(testAddress),
NewDB: func(path string) (common.Database, error) { return db, nil }, NewDB: func(path string) (ethdb.Database, error) { return db, nil },
}) })
if err != nil { if err != nil {

@ -144,7 +144,7 @@ func genUncles(i int, gen *BlockGen) {
func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
// Create the database in memory or in a temporary directory. // Create the database in memory or in a temporary directory.
var db common.Database var db ethdb.Database
if !disk { if !disk {
db, _ = ethdb.NewMemDatabase() db, _ = ethdb.NewMemDatabase()
} else { } else {

@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
@ -41,7 +42,7 @@ const (
) )
type BlockProcessor struct { type BlockProcessor struct {
chainDb common.Database chainDb ethdb.Database
// Mutex for locking the block processor. Blocks can only be handled one at a time // Mutex for locking the block processor. Blocks can only be handled one at a time
mutex sync.Mutex mutex sync.Mutex
// Canonical block chain // Canonical block chain
@ -68,7 +69,7 @@ type GasPool interface {
SubGas(gas, price *big.Int) error SubGas(gas, price *big.Int) error
} }
func NewBlockProcessor(db common.Database, pow pow.PoW, chainManager *ChainManager, eventMux *event.TypeMux) *BlockProcessor { func NewBlockProcessor(db ethdb.Database, pow pow.PoW, chainManager *ChainManager, eventMux *event.TypeMux) *BlockProcessor {
sm := &BlockProcessor{ sm := &BlockProcessor{
chainDb: db, chainDb: db,
mem: make(map[string]*big.Int), mem: make(map[string]*big.Int),

@ -22,6 +22,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/pow" "github.com/ethereum/go-ethereum/pow"
) )
@ -142,7 +143,7 @@ func (b *BlockGen) PrevBlock(index int) *types.Block {
// Blocks created by GenerateChain do not contain valid proof of work // Blocks created by GenerateChain do not contain valid proof of work
// values. Inserting them into ChainManager requires use of FakePow or // values. Inserting them into ChainManager requires use of FakePow or
// a similar non-validating proof of work implementation. // a similar non-validating proof of work implementation.
func GenerateChain(parent *types.Block, db common.Database, n int, gen func(int, *BlockGen)) []*types.Block { func GenerateChain(parent *types.Block, db ethdb.Database, n int, gen func(int, *BlockGen)) []*types.Block {
statedb := state.New(parent.Root(), db) statedb := state.New(parent.Root(), db)
blocks := make(types.Blocks, n) blocks := make(types.Blocks, n)
genblock := func(i int, h *types.Header) *types.Block { genblock := func(i int, h *types.Header) *types.Block {
@ -185,7 +186,7 @@ func makeHeader(parent *types.Block, state *state.StateDB) *types.Header {
// newCanonical creates a new deterministic canonical chain by running // newCanonical creates a new deterministic canonical chain by running
// InsertChain on the result of makeChain. // InsertChain on the result of makeChain.
func newCanonical(n int, db common.Database) (*BlockProcessor, error) { func newCanonical(n int, db ethdb.Database) (*BlockProcessor, error) {
evmux := &event.TypeMux{} evmux := &event.TypeMux{}
WriteTestNetGenesisBlock(db, 0) WriteTestNetGenesisBlock(db, 0)
@ -201,7 +202,7 @@ func newCanonical(n int, db common.Database) (*BlockProcessor, error) {
return bman, err return bman, err
} }
func makeChain(parent *types.Block, n int, db common.Database, seed int) []*types.Block { func makeChain(parent *types.Block, n int, db ethdb.Database, seed int) []*types.Block {
return GenerateChain(parent, db, n, func(i int, b *BlockGen) { return GenerateChain(parent, db, n, func(i int, b *BlockGen) {
b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)}) b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)})
}) })

@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
@ -60,7 +61,7 @@ const (
type ChainManager struct { type ChainManager struct {
//eth EthManager //eth EthManager
chainDb common.Database chainDb ethdb.Database
processor types.BlockProcessor processor types.BlockProcessor
eventMux *event.TypeMux eventMux *event.TypeMux
genesisBlock *types.Block genesisBlock *types.Block
@ -90,7 +91,7 @@ type ChainManager struct {
pow pow.PoW pow pow.PoW
} }
func NewChainManager(chainDb common.Database, pow pow.PoW, mux *event.TypeMux) (*ChainManager, error) { func NewChainManager(chainDb ethdb.Database, pow pow.PoW, mux *event.TypeMux) (*ChainManager, error) {
headerCache, _ := lru.New(headerCacheLimit) headerCache, _ := lru.New(headerCacheLimit)
bodyCache, _ := lru.New(bodyCacheLimit) bodyCache, _ := lru.New(bodyCacheLimit)
bodyRLPCache, _ := lru.New(bodyCacheLimit) bodyRLPCache, _ := lru.New(bodyCacheLimit)

@ -46,7 +46,7 @@ func thePow() pow.PoW {
return pow return pow
} }
func theChainManager(db common.Database, t *testing.T) *ChainManager { func theChainManager(db ethdb.Database, t *testing.T) *ChainManager {
var eventMux event.TypeMux var eventMux event.TypeMux
WriteTestNetGenesisBlock(db, 0) WriteTestNetGenesisBlock(db, 0)
chainMan, err := NewChainManager(db, thePow(), &eventMux) chainMan, err := NewChainManager(db, thePow(), &eventMux)
@ -380,7 +380,7 @@ func makeChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Block
return chain return chain
} }
func chm(genesis *types.Block, db common.Database) *ChainManager { func chm(genesis *types.Block, db ethdb.Database) *ChainManager {
var eventMux event.TypeMux var eventMux event.TypeMux
bc := &ChainManager{chainDb: db, genesisBlock: genesis, eventMux: &eventMux, pow: FakePow{}} bc := &ChainManager{chainDb: db, genesisBlock: genesis, eventMux: &eventMux, pow: FakePow{}}
bc.headerCache, _ = lru.New(100) bc.headerCache, _ = lru.New(100)

@ -22,6 +22,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
@ -111,7 +112,7 @@ func CalcGasLimit(parent *types.Block) *big.Int {
} }
// GetCanonicalHash retrieves a hash assigned to a canonical block number. // GetCanonicalHash retrieves a hash assigned to a canonical block number.
func GetCanonicalHash(db common.Database, number uint64) common.Hash { func GetCanonicalHash(db ethdb.Database, number uint64) common.Hash {
data, _ := db.Get(append(blockNumPrefix, big.NewInt(int64(number)).Bytes()...)) data, _ := db.Get(append(blockNumPrefix, big.NewInt(int64(number)).Bytes()...))
if len(data) == 0 { if len(data) == 0 {
return common.Hash{} return common.Hash{}
@ -124,7 +125,7 @@ func GetCanonicalHash(db common.Database, number uint64) common.Hash {
// last block hash is only updated upon a full block import, the last header // last block hash is only updated upon a full block import, the last header
// hash is updated already at header import, allowing head tracking for the // hash is updated already at header import, allowing head tracking for the
// fast synchronization mechanism. // fast synchronization mechanism.
func GetHeadHeaderHash(db common.Database) common.Hash { func GetHeadHeaderHash(db ethdb.Database) common.Hash {
data, _ := db.Get(headHeaderKey) data, _ := db.Get(headHeaderKey)
if len(data) == 0 { if len(data) == 0 {
return common.Hash{} return common.Hash{}
@ -133,7 +134,7 @@ func GetHeadHeaderHash(db common.Database) common.Hash {
} }
// GetHeadBlockHash retrieves the hash of the current canonical head block. // GetHeadBlockHash retrieves the hash of the current canonical head block.
func GetHeadBlockHash(db common.Database) common.Hash { func GetHeadBlockHash(db ethdb.Database) common.Hash {
data, _ := db.Get(headBlockKey) data, _ := db.Get(headBlockKey)
if len(data) == 0 { if len(data) == 0 {
return common.Hash{} return common.Hash{}
@ -143,14 +144,14 @@ func GetHeadBlockHash(db common.Database) common.Hash {
// GetHeaderRLP retrieves a block header in its raw RLP database encoding, or nil // GetHeaderRLP retrieves a block header in its raw RLP database encoding, or nil
// if the header's not found. // if the header's not found.
func GetHeaderRLP(db common.Database, hash common.Hash) rlp.RawValue { func GetHeaderRLP(db ethdb.Database, hash common.Hash) rlp.RawValue {
data, _ := db.Get(append(append(blockPrefix, hash[:]...), headerSuffix...)) data, _ := db.Get(append(append(blockPrefix, hash[:]...), headerSuffix...))
return data return data
} }
// GetHeader retrieves the block header corresponding to the hash, nil if none // GetHeader retrieves the block header corresponding to the hash, nil if none
// found. // found.
func GetHeader(db common.Database, hash common.Hash) *types.Header { func GetHeader(db ethdb.Database, hash common.Hash) *types.Header {
data := GetHeaderRLP(db, hash) data := GetHeaderRLP(db, hash)
if len(data) == 0 { if len(data) == 0 {
return nil return nil
@ -164,14 +165,14 @@ func GetHeader(db common.Database, hash common.Hash) *types.Header {
} }
// GetBodyRLP retrieves the block body (transactions and uncles) in RLP encoding. // GetBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
func GetBodyRLP(db common.Database, hash common.Hash) rlp.RawValue { func GetBodyRLP(db ethdb.Database, hash common.Hash) rlp.RawValue {
data, _ := db.Get(append(append(blockPrefix, hash[:]...), bodySuffix...)) data, _ := db.Get(append(append(blockPrefix, hash[:]...), bodySuffix...))
return data return data
} }
// GetBody retrieves the block body (transactons, uncles) corresponding to the // GetBody retrieves the block body (transactons, uncles) corresponding to the
// hash, nil if none found. // hash, nil if none found.
func GetBody(db common.Database, hash common.Hash) *types.Body { func GetBody(db ethdb.Database, hash common.Hash) *types.Body {
data := GetBodyRLP(db, hash) data := GetBodyRLP(db, hash)
if len(data) == 0 { if len(data) == 0 {
return nil return nil
@ -186,7 +187,7 @@ func GetBody(db common.Database, hash common.Hash) *types.Body {
// GetTd retrieves a block's total difficulty corresponding to the hash, nil if // GetTd retrieves a block's total difficulty corresponding to the hash, nil if
// none found. // none found.
func GetTd(db common.Database, hash common.Hash) *big.Int { func GetTd(db ethdb.Database, hash common.Hash) *big.Int {
data, _ := db.Get(append(append(blockPrefix, hash.Bytes()...), tdSuffix...)) data, _ := db.Get(append(append(blockPrefix, hash.Bytes()...), tdSuffix...))
if len(data) == 0 { if len(data) == 0 {
return nil return nil
@ -201,7 +202,7 @@ func GetTd(db common.Database, hash common.Hash) *big.Int {
// GetBlock retrieves an entire block corresponding to the hash, assembling it // GetBlock retrieves an entire block corresponding to the hash, assembling it
// back from the stored header and body. // back from the stored header and body.
func GetBlock(db common.Database, hash common.Hash) *types.Block { func GetBlock(db ethdb.Database, hash common.Hash) *types.Block {
// Retrieve the block header and body contents // Retrieve the block header and body contents
header := GetHeader(db, hash) header := GetHeader(db, hash)
if header == nil { if header == nil {
@ -216,7 +217,7 @@ func GetBlock(db common.Database, hash common.Hash) *types.Block {
} }
// WriteCanonicalHash stores the canonical hash for the given block number. // WriteCanonicalHash stores the canonical hash for the given block number.
func WriteCanonicalHash(db common.Database, hash common.Hash, number uint64) error { func WriteCanonicalHash(db ethdb.Database, hash common.Hash, number uint64) error {
key := append(blockNumPrefix, big.NewInt(int64(number)).Bytes()...) key := append(blockNumPrefix, big.NewInt(int64(number)).Bytes()...)
if err := db.Put(key, hash.Bytes()); err != nil { if err := db.Put(key, hash.Bytes()); err != nil {
glog.Fatalf("failed to store number to hash mapping into database: %v", err) glog.Fatalf("failed to store number to hash mapping into database: %v", err)
@ -226,7 +227,7 @@ func WriteCanonicalHash(db common.Database, hash common.Hash, number uint64) err
} }
// WriteHeadHeaderHash stores the head header's hash. // WriteHeadHeaderHash stores the head header's hash.
func WriteHeadHeaderHash(db common.Database, hash common.Hash) error { func WriteHeadHeaderHash(db ethdb.Database, hash common.Hash) error {
if err := db.Put(headHeaderKey, hash.Bytes()); err != nil { if err := db.Put(headHeaderKey, hash.Bytes()); err != nil {
glog.Fatalf("failed to store last header's hash into database: %v", err) glog.Fatalf("failed to store last header's hash into database: %v", err)
return err return err
@ -235,7 +236,7 @@ func WriteHeadHeaderHash(db common.Database, hash common.Hash) error {
} }
// WriteHeadBlockHash stores the head block's hash. // WriteHeadBlockHash stores the head block's hash.
func WriteHeadBlockHash(db common.Database, hash common.Hash) error { func WriteHeadBlockHash(db ethdb.Database, hash common.Hash) error {
if err := db.Put(headBlockKey, hash.Bytes()); err != nil { if err := db.Put(headBlockKey, hash.Bytes()); err != nil {
glog.Fatalf("failed to store last block's hash into database: %v", err) glog.Fatalf("failed to store last block's hash into database: %v", err)
return err return err
@ -244,7 +245,7 @@ func WriteHeadBlockHash(db common.Database, hash common.Hash) error {
} }
// WriteHeader serializes a block header into the database. // WriteHeader serializes a block header into the database.
func WriteHeader(db common.Database, header *types.Header) error { func WriteHeader(db ethdb.Database, header *types.Header) error {
data, err := rlp.EncodeToBytes(header) data, err := rlp.EncodeToBytes(header)
if err != nil { if err != nil {
return err return err
@ -259,7 +260,7 @@ func WriteHeader(db common.Database, header *types.Header) error {
} }
// WriteBody serializes the body of a block into the database. // WriteBody serializes the body of a block into the database.
func WriteBody(db common.Database, hash common.Hash, body *types.Body) error { func WriteBody(db ethdb.Database, hash common.Hash, body *types.Body) error {
data, err := rlp.EncodeToBytes(body) data, err := rlp.EncodeToBytes(body)
if err != nil { if err != nil {
return err return err
@ -274,7 +275,7 @@ func WriteBody(db common.Database, hash common.Hash, body *types.Body) error {
} }
// WriteTd serializes the total difficulty of a block into the database. // WriteTd serializes the total difficulty of a block into the database.
func WriteTd(db common.Database, hash common.Hash, td *big.Int) error { func WriteTd(db ethdb.Database, hash common.Hash, td *big.Int) error {
data, err := rlp.EncodeToBytes(td) data, err := rlp.EncodeToBytes(td)
if err != nil { if err != nil {
return err return err
@ -289,7 +290,7 @@ func WriteTd(db common.Database, hash common.Hash, td *big.Int) error {
} }
// WriteBlock serializes a block into the database, header and body separately. // WriteBlock serializes a block into the database, header and body separately.
func WriteBlock(db common.Database, block *types.Block) error { func WriteBlock(db ethdb.Database, block *types.Block) error {
// Store the body first to retain database consistency // Store the body first to retain database consistency
if err := WriteBody(db, block.Hash(), &types.Body{block.Transactions(), block.Uncles()}); err != nil { if err := WriteBody(db, block.Hash(), &types.Body{block.Transactions(), block.Uncles()}); err != nil {
return err return err
@ -302,27 +303,27 @@ func WriteBlock(db common.Database, block *types.Block) error {
} }
// DeleteCanonicalHash removes the number to hash canonical mapping. // DeleteCanonicalHash removes the number to hash canonical mapping.
func DeleteCanonicalHash(db common.Database, number uint64) { func DeleteCanonicalHash(db ethdb.Database, number uint64) {
db.Delete(append(blockNumPrefix, big.NewInt(int64(number)).Bytes()...)) db.Delete(append(blockNumPrefix, big.NewInt(int64(number)).Bytes()...))
} }
// DeleteHeader removes all block header data associated with a hash. // DeleteHeader removes all block header data associated with a hash.
func DeleteHeader(db common.Database, hash common.Hash) { func DeleteHeader(db ethdb.Database, hash common.Hash) {
db.Delete(append(append(blockPrefix, hash.Bytes()...), headerSuffix...)) db.Delete(append(append(blockPrefix, hash.Bytes()...), headerSuffix...))
} }
// DeleteBody removes all block body data associated with a hash. // DeleteBody removes all block body data associated with a hash.
func DeleteBody(db common.Database, hash common.Hash) { func DeleteBody(db ethdb.Database, hash common.Hash) {
db.Delete(append(append(blockPrefix, hash.Bytes()...), bodySuffix...)) db.Delete(append(append(blockPrefix, hash.Bytes()...), bodySuffix...))
} }
// DeleteTd removes all block total difficulty data associated with a hash. // DeleteTd removes all block total difficulty data associated with a hash.
func DeleteTd(db common.Database, hash common.Hash) { func DeleteTd(db ethdb.Database, hash common.Hash) {
db.Delete(append(append(blockPrefix, hash.Bytes()...), tdSuffix...)) db.Delete(append(append(blockPrefix, hash.Bytes()...), tdSuffix...))
} }
// DeleteBlock removes all block data associated with a hash. // DeleteBlock removes all block data associated with a hash.
func DeleteBlock(db common.Database, hash common.Hash) { func DeleteBlock(db ethdb.Database, hash common.Hash) {
DeleteHeader(db, hash) DeleteHeader(db, hash)
DeleteBody(db, hash) DeleteBody(db, hash)
DeleteTd(db, hash) DeleteTd(db, hash)
@ -333,7 +334,7 @@ func DeleteBlock(db common.Database, hash common.Hash) {
// or nil if not found. This method is only used by the upgrade mechanism to // or nil if not found. This method is only used by the upgrade mechanism to
// access the old combined block representation. It will be dropped after the // access the old combined block representation. It will be dropped after the
// network transitions to eth/63. // network transitions to eth/63.
func GetBlockByHashOld(db common.Database, hash common.Hash) *types.Block { func GetBlockByHashOld(db ethdb.Database, hash common.Hash) *types.Block {
data, _ := db.Get(append(blockHashPre, hash[:]...)) data, _ := db.Get(append(blockHashPre, hash[:]...))
if len(data) == 0 { if len(data) == 0 {
return nil return nil

@ -27,13 +27,14 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
) )
// WriteGenesisBlock writes the genesis block to the database as block number 0 // WriteGenesisBlock writes the genesis block to the database as block number 0
func WriteGenesisBlock(chainDb common.Database, reader io.Reader) (*types.Block, error) { func WriteGenesisBlock(chainDb ethdb.Database, reader io.Reader) (*types.Block, error) {
contents, err := ioutil.ReadAll(reader) contents, err := ioutil.ReadAll(reader)
if err != nil { if err != nil {
return nil, err return nil, err
@ -110,7 +111,7 @@ func WriteGenesisBlock(chainDb common.Database, reader io.Reader) (*types.Block,
// GenesisBlockForTesting creates a block in which addr has the given wei balance. // GenesisBlockForTesting creates a block in which addr has the given wei balance.
// The state trie of the block is written to db. // The state trie of the block is written to db.
func GenesisBlockForTesting(db common.Database, addr common.Address, balance *big.Int) *types.Block { func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
statedb := state.New(common.Hash{}, db) statedb := state.New(common.Hash{}, db)
obj := statedb.GetOrNewStateObject(addr) obj := statedb.GetOrNewStateObject(addr)
obj.SetBalance(balance) obj.SetBalance(balance)
@ -124,7 +125,7 @@ func GenesisBlockForTesting(db common.Database, addr common.Address, balance *bi
return block return block
} }
func WriteGenesisBlockForTesting(db common.Database, addr common.Address, balance *big.Int) *types.Block { func WriteGenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
testGenesis := fmt.Sprintf(`{ testGenesis := fmt.Sprintf(`{
"nonce":"0x%x", "nonce":"0x%x",
"gasLimit":"0x%x", "gasLimit":"0x%x",
@ -137,7 +138,7 @@ func WriteGenesisBlockForTesting(db common.Database, addr common.Address, balanc
return block return block
} }
func WriteTestNetGenesisBlock(chainDb common.Database, nonce uint64) (*types.Block, error) { func WriteTestNetGenesisBlock(chainDb ethdb.Database, nonce uint64) (*types.Block, error) {
testGenesis := fmt.Sprintf(`{ testGenesis := fmt.Sprintf(`{
"nonce":"0x%x", "nonce":"0x%x",
"gasLimit":"0x%x", "gasLimit":"0x%x",

@ -22,7 +22,7 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
// "github.com/ethereum/go-ethereum/crypto" // "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
) )
@ -32,7 +32,7 @@ type TestManager struct {
// stateManager *StateManager // stateManager *StateManager
eventMux *event.TypeMux eventMux *event.TypeMux
db common.Database db ethdb.Database
txPool *TxPool txPool *TxPool
blockChain *ChainManager blockChain *ChainManager
Blocks []*types.Block Blocks []*types.Block
@ -74,7 +74,7 @@ func (tm *TestManager) EventMux() *event.TypeMux {
// return nil // return nil
// } // }
func (tm *TestManager) Db() common.Database { func (tm *TestManager) Db() ethdb.Database {
return tm.db return tm.db
} }

@ -18,7 +18,7 @@ package core
import ( import (
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
) )
@ -28,7 +28,7 @@ type Backend interface {
BlockProcessor() *BlockProcessor BlockProcessor() *BlockProcessor
ChainManager() *ChainManager ChainManager() *ChainManager
TxPool() *TxPool TxPool() *TxPool
ChainDb() common.Database ChainDb() ethdb.Database
DappDb() common.Database DappDb() ethdb.Database
EventMux() *event.TypeMux EventMux() *event.TypeMux
} }

@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
@ -56,7 +57,7 @@ func (self Storage) Copy() Storage {
type StateObject struct { type StateObject struct {
// State database for storing state changes // State database for storing state changes
db common.Database db ethdb.Database
trie *trie.SecureTrie trie *trie.SecureTrie
// Address belonging to this account // Address belonging to this account
@ -87,7 +88,7 @@ type StateObject struct {
dirty bool dirty bool
} }
func NewStateObject(address common.Address, db common.Database) *StateObject { func NewStateObject(address common.Address, db ethdb.Database) *StateObject {
object := &StateObject{db: db, address: address, balance: new(big.Int), gasPool: new(big.Int), dirty: true} object := &StateObject{db: db, address: address, balance: new(big.Int), gasPool: new(big.Int), dirty: true}
object.trie = trie.NewSecure((common.Hash{}).Bytes(), db) object.trie = trie.NewSecure((common.Hash{}).Bytes(), db)
object.storage = make(Storage) object.storage = make(Storage)
@ -96,7 +97,7 @@ func NewStateObject(address common.Address, db common.Database) *StateObject {
return object return object
} }
func NewStateObjectFromBytes(address common.Address, data []byte, db common.Database) *StateObject { func NewStateObjectFromBytes(address common.Address, data []byte, db ethdb.Database) *StateObject {
// TODO clean me up // TODO clean me up
var extobject struct { var extobject struct {
Nonce uint64 Nonce uint64

@ -21,6 +21,7 @@ import (
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
@ -32,7 +33,7 @@ import (
// * Contracts // * Contracts
// * Accounts // * Accounts
type StateDB struct { type StateDB struct {
db common.Database db ethdb.Database
trie *trie.SecureTrie trie *trie.SecureTrie
root common.Hash root common.Hash
@ -47,7 +48,7 @@ type StateDB struct {
} }
// Create a new state from a given trie // Create a new state from a given trie
func New(root common.Hash, db common.Database) *StateDB { func New(root common.Hash, db ethdb.Database) *StateDB {
trie := trie.NewSecure(root[:], db) trie := trie.NewSecure(root[:], db)
return &StateDB{root: root, db: db, trie: trie, stateObjects: make(map[string]*StateObject), refund: new(big.Int), logs: make(map[common.Hash]Logs)} return &StateDB{root: root, db: db, trie: trie, stateObjects: make(map[string]*StateObject), refund: new(big.Int), logs: make(map[common.Hash]Logs)}
} }

@ -32,7 +32,7 @@ var (
) )
// PutTransactions stores the transactions in the given database // PutTransactions stores the transactions in the given database
func PutTransactions(db common.Database, block *types.Block, txs types.Transactions) { func PutTransactions(db ethdb.Database, block *types.Block, txs types.Transactions) {
batch := new(leveldb.Batch) batch := new(leveldb.Batch)
_, batchWrite := db.(*ethdb.LDBDatabase) _, batchWrite := db.(*ethdb.LDBDatabase)
@ -78,7 +78,7 @@ func PutTransactions(db common.Database, block *types.Block, txs types.Transacti
} }
// PutReceipts stores the receipts in the current database // PutReceipts stores the receipts in the current database
func PutReceipts(db common.Database, receipts types.Receipts) error { func PutReceipts(db ethdb.Database, receipts types.Receipts) error {
batch := new(leveldb.Batch) batch := new(leveldb.Batch)
_, batchWrite := db.(*ethdb.LDBDatabase) _, batchWrite := db.(*ethdb.LDBDatabase)
@ -108,7 +108,7 @@ func PutReceipts(db common.Database, receipts types.Receipts) error {
} }
// GetReceipt returns a receipt by hash // GetReceipt returns a receipt by hash
func GetReceipt(db common.Database, txHash common.Hash) *types.Receipt { func GetReceipt(db ethdb.Database, txHash common.Hash) *types.Receipt {
data, _ := db.Get(append(receiptsPre, txHash[:]...)) data, _ := db.Get(append(receiptsPre, txHash[:]...))
if len(data) == 0 { if len(data) == 0 {
return nil return nil
@ -124,7 +124,7 @@ func GetReceipt(db common.Database, txHash common.Hash) *types.Receipt {
// GetBlockReceipts returns the receipts generated by the transactions // GetBlockReceipts returns the receipts generated by the transactions
// included in block's given hash. // included in block's given hash.
func GetBlockReceipts(db common.Database, hash common.Hash) types.Receipts { func GetBlockReceipts(db ethdb.Database, hash common.Hash) types.Receipts {
data, _ := db.Get(append(blockReceiptsPre, hash[:]...)) data, _ := db.Get(append(blockReceiptsPre, hash[:]...))
if len(data) == 0 { if len(data) == 0 {
return nil return nil
@ -141,7 +141,7 @@ func GetBlockReceipts(db common.Database, hash common.Hash) types.Receipts {
// PutBlockReceipts stores the block's transactions associated receipts // PutBlockReceipts stores the block's transactions associated receipts
// and stores them by block hash in a single slice. This is required for // and stores them by block hash in a single slice. This is required for
// forks and chain reorgs // forks and chain reorgs
func PutBlockReceipts(db common.Database, block *types.Block, receipts types.Receipts) error { func PutBlockReceipts(db ethdb.Database, block *types.Block, receipts types.Receipts) error {
rs := make([]*types.ReceiptForStorage, len(receipts)) rs := make([]*types.ReceiptForStorage, len(receipts))
for i, receipt := range receipts { for i, receipt := range receipts {
rs[i] = (*types.ReceiptForStorage)(receipt) rs[i] = (*types.ReceiptForStorage)(receipt)

@ -128,7 +128,7 @@ type Config struct {
// NewDB is used to create databases. // NewDB is used to create databases.
// If nil, the default is to create leveldb databases on disk. // If nil, the default is to create leveldb databases on disk.
NewDB func(path string) (common.Database, error) NewDB func(path string) (ethdb.Database, error)
} }
func (cfg *Config) parseBootNodes() []*discover.Node { func (cfg *Config) parseBootNodes() []*discover.Node {
@ -210,11 +210,8 @@ type Ethereum struct {
shutdownChan chan bool shutdownChan chan bool
// DB interfaces // DB interfaces
chainDb common.Database // Block chain databe chainDb ethdb.Database // Block chain database
dappDb common.Database // Dapp database dappDb ethdb.Database // Dapp database
// Closed when databases are flushed and closed
databasesClosed chan bool
//*** SERVICES *** //*** SERVICES ***
// State manager for processing new blocks and managing the over all states // State manager for processing new blocks and managing the over all states
@ -267,7 +264,7 @@ func New(config *Config) (*Ethereum, error) {
newdb := config.NewDB newdb := config.NewDB
if newdb == nil { if newdb == nil {
newdb = func(path string) (common.Database, error) { return ethdb.NewLDBDatabase(path, config.DatabaseCache) } newdb = func(path string) (ethdb.Database, error) { return ethdb.NewLDBDatabase(path, config.DatabaseCache) }
} }
// Open the chain database and perform any upgrades needed // Open the chain database and perform any upgrades needed
@ -337,7 +334,6 @@ func New(config *Config) (*Ethereum, error) {
eth := &Ethereum{ eth := &Ethereum{
shutdownChan: make(chan bool), shutdownChan: make(chan bool),
databasesClosed: make(chan bool),
chainDb: chainDb, chainDb: chainDb,
dappDb: dappDb, dappDb: dappDb,
eventMux: &event.TypeMux{}, eventMux: &event.TypeMux{},
@ -527,8 +523,8 @@ func (s *Ethereum) BlockProcessor() *core.BlockProcessor { return s.blockProcess
func (s *Ethereum) TxPool() *core.TxPool { return s.txPool } func (s *Ethereum) TxPool() *core.TxPool { return s.txPool }
func (s *Ethereum) Whisper() *whisper.Whisper { return s.whisper } func (s *Ethereum) Whisper() *whisper.Whisper { return s.whisper }
func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux }
func (s *Ethereum) ChainDb() common.Database { return s.chainDb } func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb }
func (s *Ethereum) DappDb() common.Database { return s.dappDb } func (s *Ethereum) DappDb() ethdb.Database { return s.dappDb }
func (s *Ethereum) IsListening() bool { return true } // Always listening func (s *Ethereum) IsListening() bool { return true } // Always listening
func (s *Ethereum) PeerCount() int { return s.net.PeerCount() } func (s *Ethereum) PeerCount() int { return s.net.PeerCount() }
func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() } func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() }
@ -549,8 +545,6 @@ func (s *Ethereum) Start() error {
if err != nil { if err != nil {
return err return err
} }
// periodically flush databases
go s.syncDatabases()
if s.AutoDAG { if s.AutoDAG {
s.StartAutoDAG() s.StartAutoDAG()
@ -566,32 +560,6 @@ func (s *Ethereum) Start() error {
return nil return nil
} }
// sync databases every minute. If flushing fails we exit immediatly. The system
// may not continue under any circumstances.
func (s *Ethereum) syncDatabases() {
ticker := time.NewTicker(1 * time.Minute)
done:
for {
select {
case <-ticker.C:
// don't change the order of database flushes
if err := s.dappDb.Flush(); err != nil {
glog.Fatalf("fatal error: flush dappDb: %v (Restart your node. We are aware of this issue)\n", err)
}
if err := s.chainDb.Flush(); err != nil {
glog.Fatalf("fatal error: flush chainDb: %v (Restart your node. We are aware of this issue)\n", err)
}
case <-s.shutdownChan:
break done
}
}
s.chainDb.Close()
s.dappDb.Close()
close(s.databasesClosed)
}
func (s *Ethereum) StartForTest() { func (s *Ethereum) StartForTest() {
jsonlogger.LogJson(&logger.LogStarting{ jsonlogger.LogJson(&logger.LogStarting{
ClientString: s.net.Name, ClientString: s.net.Name,
@ -622,12 +590,13 @@ func (s *Ethereum) Stop() {
} }
s.StopAutoDAG() s.StopAutoDAG()
s.chainDb.Close()
s.dappDb.Close()
close(s.shutdownChan) close(s.shutdownChan)
} }
// This function will wait for a shutdown and resumes main thread execution // This function will wait for a shutdown and resumes main thread execution
func (s *Ethereum) WaitForShutdown() { func (s *Ethereum) WaitForShutdown() {
<-s.databasesClosed
<-s.shutdownChan <-s.shutdownChan
} }
@ -717,7 +686,7 @@ func dagFiles(epoch uint64) (string, string) {
return dag, "full-R" + dag return dag, "full-R" + dag
} }
func saveBlockchainVersion(db common.Database, bcVersion int) { func saveBlockchainVersion(db ethdb.Database, bcVersion int) {
d, _ := db.Get([]byte("BlockchainVersion")) d, _ := db.Get([]byte("BlockchainVersion"))
blockchainVersion := common.NewValue(d).Uint() blockchainVersion := common.NewValue(d).Uint()
@ -728,7 +697,7 @@ func saveBlockchainVersion(db common.Database, bcVersion int) {
// upgradeChainDatabase ensures that the chain database stores block split into // upgradeChainDatabase ensures that the chain database stores block split into
// separate header and body entries. // separate header and body entries.
func upgradeChainDatabase(db common.Database) error { func upgradeChainDatabase(db ethdb.Database) error {
// Short circuit if the head block is stored already as separate header and body // Short circuit if the head block is stored already as separate header and body
data, err := db.Get([]byte("LastBlock")) data, err := db.Get([]byte("LastBlock"))
if err != nil { if err != nil {

@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/eth/fetcher" "github.com/ethereum/go-ethereum/eth/fetcher"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
@ -61,7 +62,7 @@ func (ep extProt) GetBlock(hashes []common.Hash) error { return ep.getBlocks(has
type ProtocolManager struct { type ProtocolManager struct {
txpool txPool txpool txPool
chainman *core.ChainManager chainman *core.ChainManager
chaindb common.Database chaindb ethdb.Database
downloader *downloader.Downloader downloader *downloader.Downloader
fetcher *fetcher.Fetcher fetcher *fetcher.Fetcher
@ -86,7 +87,7 @@ type ProtocolManager struct {
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable // NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
// with the ethereum network. // with the ethereum network.
func NewProtocolManager(networkId int, mux *event.TypeMux, txpool txPool, pow pow.PoW, chainman *core.ChainManager, chaindb common.Database) *ProtocolManager { func NewProtocolManager(networkId int, mux *event.TypeMux, txpool txPool, pow pow.PoW, chainman *core.ChainManager, chaindb ethdb.Database) *ProtocolManager {
// Create the protocol manager with the base fields // Create the protocol manager with the base fields
manager := &ProtocolManager{ manager := &ProtocolManager{
eventMux: mux, eventMux: mux,

@ -61,9 +61,7 @@ type LDBDatabase struct {
quitChan chan chan error // Quit channel to stop the metrics collection before closing the database quitChan chan chan error // Quit channel to stop the metrics collection before closing the database
} }
// NewLDBDatabase returns a LevelDB wrapped object. LDBDatabase does not persist data by // NewLDBDatabase returns a LevelDB wrapped object.
// it self but requires a background poller which syncs every X. `Flush` should be called
// when data needs to be stored and written to disk.
func NewLDBDatabase(file string, cache int) (*LDBDatabase, error) { func NewLDBDatabase(file string, cache int) (*LDBDatabase, error) {
// Calculate the cache allowance for this particular database // Calculate the cache allowance for this particular database
cache = int(float64(cache) * cacheRatio[filepath.Base(file)]) cache = int(float64(cache) * cacheRatio[filepath.Base(file)])
@ -142,11 +140,6 @@ func (self *LDBDatabase) NewIterator() iterator.Iterator {
return self.db.NewIterator(nil, nil) return self.db.NewIterator(nil, nil)
} }
// Flush flushes out the queue to leveldb
func (self *LDBDatabase) Flush() error {
return nil
}
func (self *LDBDatabase) Close() { func (self *LDBDatabase) Close() {
// Stop the metrics collection to avoid internal database races // Stop the metrics collection to avoid internal database races
self.quitLock.Lock() self.quitLock.Lock()
@ -159,12 +152,14 @@ func (self *LDBDatabase) Close() {
glog.V(logger.Error).Infof("metrics failure in '%s': %v\n", self.fn, err) glog.V(logger.Error).Infof("metrics failure in '%s': %v\n", self.fn, err)
} }
} }
// Flush and close the database err := self.db.Close()
if err := self.Flush(); err != nil { if glog.V(logger.Error) {
glog.V(logger.Error).Infof("flushing '%s' failed: %v\n", self.fn, err) if err == nil {
glog.Infoln("closed db:", self.fn)
} else {
glog.Errorf("error closing db %s: %v", self.fn, err)
}
} }
self.db.Close()
glog.V(logger.Error).Infoln("flushed and closed db:", self.fn)
} }
func (self *LDBDatabase) LDB() *leveldb.DB { func (self *LDBDatabase) LDB() *leveldb.DB {
@ -268,3 +263,23 @@ func (self *LDBDatabase) meter(refresh time.Duration) {
} }
} }
} }
// TODO: remove this stuff and expose leveldb directly
func (db *LDBDatabase) NewBatch() Batch {
return &ldbBatch{db: db.db, b: new(leveldb.Batch)}
}
type ldbBatch struct {
db *leveldb.DB
b *leveldb.Batch
}
func (b *ldbBatch) Put(key, value []byte) error {
b.b.Put(key, value)
return nil
}
func (b *ldbBatch) Write() error {
return b.db.Write(b.b, nil)
}

@ -14,13 +14,17 @@
// You should have received a copy of the GNU Lesser General Public License // You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package common package ethdb
// Database interface
type Database interface { type Database interface {
Put(key []byte, value []byte) error Put(key []byte, value []byte) error
Get(key []byte) ([]byte, error) Get(key []byte) ([]byte, error)
Delete(key []byte) error Delete(key []byte) error
Close() Close()
Flush() error NewBatch() Batch
}
type Batch interface {
Put(key, value []byte) error
Write() error
} }

@ -36,8 +36,7 @@ func NewMemDatabase() (*MemDatabase, error) {
} }
func (db *MemDatabase) Put(key []byte, value []byte) error { func (db *MemDatabase) Put(key []byte, value []byte) error {
db.db[string(key)] = value db.db[string(key)] = common.CopyBytes(value)
return nil return nil
} }
@ -92,6 +91,25 @@ func (db *MemDatabase) LastKnownTD() []byte {
return data return data
} }
func (db *MemDatabase) Flush() error { func (db *MemDatabase) NewBatch() Batch {
return &memBatch{db: db}
}
type kv struct{ k, v []byte }
type memBatch struct {
db *MemDatabase
writes []kv
}
func (w *memBatch) Put(key, value []byte) error {
w.writes = append(w.writes, kv{key, common.CopyBytes(value)})
return nil
}
func (w *memBatch) Write() error {
for _, kv := range w.writes {
w.db.db[string(kv.k)] = kv.v
}
return nil return nil
} }

@ -19,11 +19,12 @@ package miner
import ( import (
"sync" "sync"
"sync/atomic"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/pow" "github.com/ethereum/go-ethereum/pow"
"sync/atomic"
) )
type CpuAgent struct { type CpuAgent struct {

@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/logger/glog"
@ -100,7 +101,7 @@ type worker struct {
eth core.Backend eth core.Backend
chain *core.ChainManager chain *core.ChainManager
proc *core.BlockProcessor proc *core.BlockProcessor
chainDb common.Database chainDb ethdb.Database
coinbase common.Address coinbase common.Address
gasPrice *big.Int gasPrice *big.Int

@ -197,7 +197,7 @@ func (test *BlockTest) makeEthConfig() *eth.Config {
Verbosity: 5, Verbosity: 5,
Etherbase: common.Address{}, Etherbase: common.Address{},
AccountManager: accounts.NewManager(ks), AccountManager: accounts.NewManager(ks),
NewDB: func(path string) (common.Database, error) { return ethdb.NewMemDatabase() }, NewDB: func(path string) (ethdb.Database, error) { return ethdb.NewMemDatabase() },
} }
} }

@ -27,6 +27,7 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
) )
func checkLogs(tlog []Log, logs state.Logs) error { func checkLogs(tlog []Log, logs state.Logs) error {
@ -87,7 +88,7 @@ func (self Log) Topics() [][]byte {
return t return t
} }
func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject { func StateObjectFromAccount(db ethdb.Database, addr string, account Account) *state.StateObject {
obj := state.NewStateObject(common.HexToAddress(addr), db) obj := state.NewStateObject(common.HexToAddress(addr), db)
obj.SetBalance(common.Big(account.Balance)) obj.SetBalance(common.Big(account.Balance))

Loading…
Cancel
Save