Separated block db from state db. Partial fix for #416
This commit is contained in:
		
							parent
							
								
									ed84b58af5
								
							
						
					
					
						commit
						cd856cb213
					
				| @ -229,7 +229,7 @@ func (self *repl) dump(call otto.FunctionCall) otto.Value { | ||||
| 		block = self.ethereum.ChainManager().CurrentBlock() | ||||
| 	} | ||||
| 
 | ||||
| 	statedb := state.New(block.Root(), self.ethereum.Db()) | ||||
| 	statedb := state.New(block.Root(), self.ethereum.StateDb()) | ||||
| 
 | ||||
| 	v, _ := self.re.Vm.ToValue(statedb.RawDump()) | ||||
| 
 | ||||
|  | ||||
| @ -171,7 +171,7 @@ func importchain(ctx *cli.Context) { | ||||
| 	if len(ctx.Args()) != 1 { | ||||
| 		utils.Fatalf("This command requires an argument.") | ||||
| 	} | ||||
| 	chain, _ := utils.GetChain(ctx) | ||||
| 	chain, _, _ := utils.GetChain(ctx) | ||||
| 	start := time.Now() | ||||
| 	err := utils.ImportChain(chain, ctx.Args().First()) | ||||
| 	if err != nil { | ||||
| @ -182,7 +182,7 @@ func importchain(ctx *cli.Context) { | ||||
| } | ||||
| 
 | ||||
| func dump(ctx *cli.Context) { | ||||
| 	chain, db := utils.GetChain(ctx) | ||||
| 	chain, _, stateDb := utils.GetChain(ctx) | ||||
| 	for _, arg := range ctx.Args() { | ||||
| 		var block *types.Block | ||||
| 		if hashish(arg) { | ||||
| @ -195,7 +195,7 @@ func dump(ctx *cli.Context) { | ||||
| 			fmt.Println("{}") | ||||
| 			utils.Fatalf("block not found") | ||||
| 		} else { | ||||
| 			statedb := state.New(block.Root(), db) | ||||
| 			statedb := state.New(block.Root(), stateDb) | ||||
| 			fmt.Printf("%s\n", statedb.Dump()) | ||||
| 			// fmt.Println(block)
 | ||||
| 		} | ||||
|  | ||||
| @ -113,7 +113,7 @@ func (self *Gui) DumpState(hash, path string) { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		stateDump = state.New(block.Root(), self.eth.Db()).Dump() | ||||
| 		stateDump = state.New(block.Root(), self.eth.StateDb()).Dump() | ||||
| 	} | ||||
| 
 | ||||
| 	file, err := os.OpenFile(path[7:], os.O_CREATE|os.O_RDWR, os.ModePerm) | ||||
|  | ||||
| @ -197,7 +197,7 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error { | ||||
| 
 | ||||
| 	parent := ethereum.ChainManager().GetBlock(block.ParentHash()) | ||||
| 
 | ||||
| 	statedb := state.New(parent.Root(), ethereum.Db()) | ||||
| 	statedb := state.New(parent.Root(), ethereum.StateDb()) | ||||
| 	_, err := ethereum.BlockProcessor().TransitionState(statedb, parent, block, true) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
|  | ||||
| @ -175,11 +175,16 @@ func GetEthereum(clientID, version string, ctx *cli.Context) *eth.Ethereum { | ||||
| 	return ethereum | ||||
| } | ||||
| 
 | ||||
| func GetChain(ctx *cli.Context) (*core.ChainManager, ethutil.Database) { | ||||
| func GetChain(ctx *cli.Context) (*core.ChainManager, ethutil.Database, ethutil.Database) { | ||||
| 	dataDir := ctx.GlobalString(DataDirFlag.Name) | ||||
| 	db, err := ethdb.NewLDBDatabase(path.Join(dataDir, "blockchain")) | ||||
| 	blockDb, err := ethdb.NewLDBDatabase(path.Join(dataDir, "blockchain")) | ||||
| 	if err != nil { | ||||
| 		Fatalf("Could not open database: %v", err) | ||||
| 	} | ||||
| 	return core.NewChainManager(db, new(event.TypeMux)), db | ||||
| 
 | ||||
| 	stateDb, err := ethdb.NewLDBDatabase(path.Join(dataDir, "state")) | ||||
| 	if err != nil { | ||||
| 		Fatalf("Could not open database: %v", err) | ||||
| 	} | ||||
| 	return core.NewChainManager(blockDb, stateDb, new(event.TypeMux)), blockDb, stateDb | ||||
| } | ||||
|  | ||||
| @ -108,7 +108,7 @@ func makeChain(bman *BlockProcessor, parent *types.Block, max int, db ethutil.Da | ||||
| // Create a new chain manager starting from given block
 | ||||
| // Effectively a fork factory
 | ||||
| func newChainManager(block *types.Block, eventMux *event.TypeMux, db ethutil.Database) *ChainManager { | ||||
| 	bc := &ChainManager{db: db, genesisBlock: GenesisBlock(db), eventMux: eventMux} | ||||
| 	bc := &ChainManager{blockDb: db, stateDb: db, genesisBlock: GenesisBlock(db), eventMux: eventMux} | ||||
| 	if block == nil { | ||||
| 		bc.Reset() | ||||
| 	} else { | ||||
|  | ||||
| @ -75,7 +75,8 @@ func CalcGasLimit(parent, block *types.Block) *big.Int { | ||||
| 
 | ||||
| type ChainManager struct { | ||||
| 	//eth          EthManager
 | ||||
| 	db           ethutil.Database | ||||
| 	blockDb      ethutil.Database | ||||
| 	stateDb      ethutil.Database | ||||
| 	processor    types.BlockProcessor | ||||
| 	eventMux     *event.TypeMux | ||||
| 	genesisBlock *types.Block | ||||
| @ -92,8 +93,8 @@ type ChainManager struct { | ||||
| 	quit chan struct{} | ||||
| } | ||||
| 
 | ||||
| func NewChainManager(db ethutil.Database, mux *event.TypeMux) *ChainManager { | ||||
| 	bc := &ChainManager{db: db, genesisBlock: GenesisBlock(db), eventMux: mux, quit: make(chan struct{})} | ||||
| func NewChainManager(blockDb, stateDb ethutil.Database, mux *event.TypeMux) *ChainManager { | ||||
| 	bc := &ChainManager{blockDb: blockDb, stateDb: stateDb, genesisBlock: GenesisBlock(stateDb), eventMux: mux, quit: make(chan struct{})} | ||||
| 	bc.setLastBlock() | ||||
| 	bc.transState = bc.State().Copy() | ||||
| 	bc.txState = bc.State().Copy() | ||||
| @ -135,7 +136,7 @@ func (self *ChainManager) SetProcessor(proc types.BlockProcessor) { | ||||
| } | ||||
| 
 | ||||
| func (self *ChainManager) State() *state.StateDB { | ||||
| 	return state.New(self.CurrentBlock().Root(), self.db) | ||||
| 	return state.New(self.CurrentBlock().Root(), self.stateDb) | ||||
| } | ||||
| 
 | ||||
| func (self *ChainManager) TransState() *state.StateDB { | ||||
| @ -163,7 +164,7 @@ func (self *ChainManager) setTransState(statedb *state.StateDB) { | ||||
| } | ||||
| 
 | ||||
| func (bc *ChainManager) setLastBlock() { | ||||
| 	data, _ := bc.db.Get([]byte("LastBlock")) | ||||
| 	data, _ := bc.blockDb.Get([]byte("LastBlock")) | ||||
| 	if len(data) != 0 { | ||||
| 		var block types.Block | ||||
| 		rlp.Decode(bytes.NewReader(data), &block) | ||||
| @ -171,7 +172,7 @@ func (bc *ChainManager) setLastBlock() { | ||||
| 		bc.lastBlockHash = block.Hash() | ||||
| 
 | ||||
| 		// Set the last know difficulty (might be 0x0 as initial value, Genesis)
 | ||||
| 		bc.td = ethutil.BigD(bc.db.LastKnownTD()) | ||||
| 		bc.td = ethutil.BigD(bc.blockDb.LastKnownTD()) | ||||
| 	} else { | ||||
| 		bc.Reset() | ||||
| 	} | ||||
| @ -220,7 +221,7 @@ func (bc *ChainManager) Reset() { | ||||
| 	defer bc.mu.Unlock() | ||||
| 
 | ||||
| 	for block := bc.currentBlock; block != nil; block = bc.GetBlock(block.Header().ParentHash) { | ||||
| 		bc.db.Delete(block.Hash()) | ||||
| 		bc.blockDb.Delete(block.Hash()) | ||||
| 	} | ||||
| 
 | ||||
| 	// Prepare the genesis block
 | ||||
| @ -236,7 +237,7 @@ func (bc *ChainManager) ResetWithGenesisBlock(gb *types.Block) { | ||||
| 	defer bc.mu.Unlock() | ||||
| 
 | ||||
| 	for block := bc.currentBlock; block != nil; block = bc.GetBlock(block.Header().ParentHash) { | ||||
| 		bc.db.Delete(block.Hash()) | ||||
| 		bc.blockDb.Delete(block.Hash()) | ||||
| 	} | ||||
| 
 | ||||
| 	// Prepare the genesis block
 | ||||
| @ -262,14 +263,14 @@ func (self *ChainManager) Export() []byte { | ||||
| 
 | ||||
| func (bc *ChainManager) insert(block *types.Block) { | ||||
| 	encodedBlock := ethutil.Encode(block) | ||||
| 	bc.db.Put([]byte("LastBlock"), encodedBlock) | ||||
| 	bc.blockDb.Put([]byte("LastBlock"), encodedBlock) | ||||
| 	bc.currentBlock = block | ||||
| 	bc.lastBlockHash = block.Hash() | ||||
| } | ||||
| 
 | ||||
| func (bc *ChainManager) write(block *types.Block) { | ||||
| 	encodedBlock := ethutil.Encode(block.RlpDataForStorage()) | ||||
| 	bc.db.Put(block.Hash(), encodedBlock) | ||||
| 	bc.blockDb.Put(block.Hash(), encodedBlock) | ||||
| } | ||||
| 
 | ||||
| // Accessors
 | ||||
| @ -279,7 +280,7 @@ func (bc *ChainManager) Genesis() *types.Block { | ||||
| 
 | ||||
| // Block fetching methods
 | ||||
| func (bc *ChainManager) HasBlock(hash []byte) bool { | ||||
| 	data, _ := bc.db.Get(hash) | ||||
| 	data, _ := bc.blockDb.Get(hash) | ||||
| 	return len(data) != 0 | ||||
| } | ||||
| 
 | ||||
| @ -307,7 +308,7 @@ func (self *ChainManager) GetBlockHashesFromHash(hash []byte, max uint64) (chain | ||||
| } | ||||
| 
 | ||||
| func (self *ChainManager) GetBlock(hash []byte) *types.Block { | ||||
| 	data, _ := self.db.Get(hash) | ||||
| 	data, _ := self.blockDb.Get(hash) | ||||
| 	if len(data) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| @ -361,7 +362,7 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block { | ||||
| } | ||||
| 
 | ||||
| func (bc *ChainManager) setTotalDifficulty(td *big.Int) { | ||||
| 	bc.db.Put([]byte("LTD"), td.Bytes()) | ||||
| 	bc.blockDb.Put([]byte("LTD"), td.Bytes()) | ||||
| 	bc.td = td | ||||
| } | ||||
| 
 | ||||
| @ -448,7 +449,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { | ||||
| 					}) | ||||
| 				*/ | ||||
| 
 | ||||
| 				self.setTransState(state.New(block.Root(), self.db)) | ||||
| 				self.setTransState(state.New(block.Root(), self.stateDb)) | ||||
| 				queue[i] = ChainEvent{block} | ||||
| 				queueEvent.canonicalCount++ | ||||
| 			} else { | ||||
| @ -487,7 +488,7 @@ out: | ||||
| 						// On chain splits we need to reset the transaction state. We can't be sure whether the actual
 | ||||
| 						// state of the accounts are still valid.
 | ||||
| 						if i == ev.splitCount { | ||||
| 							self.setTxState(state.New(event.Block.Root(), self.db)) | ||||
| 							self.setTxState(state.New(event.Block.Root(), self.stateDb)) | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
|  | ||||
| @ -15,6 +15,7 @@ type Backend interface { | ||||
| 	IsListening() bool | ||||
| 	Peers() []*p2p.Peer | ||||
| 	KeyManager() *crypto.KeyManager | ||||
| 	Db() ethutil.Database | ||||
| 	BlockDb() ethutil.Database | ||||
| 	StateDb() ethutil.Database | ||||
| 	EventMux() *event.TypeMux | ||||
| } | ||||
|  | ||||
| @ -111,7 +111,8 @@ type Ethereum struct { | ||||
| 	shutdownChan chan bool | ||||
| 
 | ||||
| 	// DB interface
 | ||||
| 	db ethutil.Database | ||||
| 	blockDb ethutil.Database | ||||
| 	stateDb ethutil.Database | ||||
| 
 | ||||
| 	//*** SERVICES ***
 | ||||
| 	// State manager for processing new blocks and managing the over all states
 | ||||
| @ -140,13 +141,17 @@ func New(config *Config) (*Ethereum, error) { | ||||
| 	// Boostrap database
 | ||||
| 	ethlogger := logger.New(config.DataDir, config.LogFile, config.LogLevel, config.LogFormat) | ||||
| 
 | ||||
| 	db, err := ethdb.NewLDBDatabase(path.Join(config.DataDir, "blockchain")) | ||||
| 	blockDb, err := ethdb.NewLDBDatabase(path.Join(config.DataDir, "blockchain")) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	stateDb, err := ethdb.NewLDBDatabase(path.Join(config.DataDir, "state")) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	// Perform database sanity checks
 | ||||
| 	d, _ := db.Get([]byte("ProtocolVersion")) | ||||
| 	d, _ := blockDb.Get([]byte("ProtocolVersion")) | ||||
| 	protov := ethutil.NewValue(d).Uint() | ||||
| 	if protov != ProtocolVersion && protov != 0 { | ||||
| 		path := path.Join(config.DataDir, "blockchain") | ||||
| @ -157,7 +162,7 @@ func New(config *Config) (*Ethereum, error) { | ||||
| 	var keyManager *crypto.KeyManager | ||||
| 	switch config.KeyStore { | ||||
| 	case "db": | ||||
| 		keyManager = crypto.NewDBKeyManager(db) | ||||
| 		keyManager = crypto.NewDBKeyManager(blockDb) | ||||
| 	case "file": | ||||
| 		keyManager = crypto.NewFileKeyManager(config.DataDir) | ||||
| 	default: | ||||
| @ -166,23 +171,24 @@ func New(config *Config) (*Ethereum, error) { | ||||
| 	// Initialise the keyring
 | ||||
| 	keyManager.Init(config.KeyRing, 0, false) | ||||
| 
 | ||||
| 	saveProtocolVersion(db) | ||||
| 	saveProtocolVersion(blockDb) | ||||
| 	//ethutil.Config.Db = db
 | ||||
| 
 | ||||
| 	eth := &Ethereum{ | ||||
| 		shutdownChan: make(chan bool), | ||||
| 		db:           db, | ||||
| 		blockDb:      blockDb, | ||||
| 		stateDb:      stateDb, | ||||
| 		keyManager:   keyManager, | ||||
| 		eventMux:     &event.TypeMux{}, | ||||
| 		logger:       ethlogger, | ||||
| 		DataDir:      config.DataDir, | ||||
| 	} | ||||
| 
 | ||||
| 	eth.chainManager = core.NewChainManager(db, eth.EventMux()) | ||||
| 	eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux()) | ||||
| 	pow := ethash.New(eth.chainManager) | ||||
| 
 | ||||
| 	eth.txPool = core.NewTxPool(eth.EventMux()) | ||||
| 	eth.blockProcessor = core.NewBlockProcessor(db, pow, eth.txPool, eth.chainManager, eth.EventMux()) | ||||
| 	eth.blockProcessor = core.NewBlockProcessor(stateDb, pow, eth.txPool, eth.chainManager, eth.EventMux()) | ||||
| 	eth.chainManager.SetProcessor(eth.blockProcessor) | ||||
| 	eth.whisper = whisper.New() | ||||
| 	eth.miner = miner.New(keyManager.Address(), eth, pow, config.MinerThreads) | ||||
| @ -228,7 +234,8 @@ func (s *Ethereum) TxPool() *core.TxPool                 { return s.txPool } | ||||
| func (s *Ethereum) BlockPool() *blockpool.BlockPool      { return s.blockPool } | ||||
| func (s *Ethereum) Whisper() *whisper.Whisper            { return s.whisper } | ||||
| func (s *Ethereum) EventMux() *event.TypeMux             { return s.eventMux } | ||||
| func (s *Ethereum) Db() ethutil.Database                 { return s.db } | ||||
| func (s *Ethereum) BlockDb() ethutil.Database            { return s.blockDb } | ||||
| func (s *Ethereum) StateDb() ethutil.Database            { return s.stateDb } | ||||
| func (s *Ethereum) Miner() *miner.Miner                  { return s.miner } | ||||
| func (s *Ethereum) IsListening() bool                    { return true } // Always listening
 | ||||
| func (s *Ethereum) PeerCount() int                       { return s.net.PeerCount() } | ||||
| @ -279,7 +286,8 @@ func (self *Ethereum) SuggestPeer(nodeURL string) error { | ||||
| 
 | ||||
| func (s *Ethereum) Stop() { | ||||
| 	// Close the database
 | ||||
| 	defer s.db.Close() | ||||
| 	defer s.blockDb.Close() | ||||
| 	defer s.stateDb.Close() | ||||
| 
 | ||||
| 	s.txSub.Unsubscribe()    // quits txBroadcastLoop
 | ||||
| 	s.blockSub.Unsubscribe() // quits blockBroadcastLoop
 | ||||
|  | ||||
| @ -30,7 +30,7 @@ type environment struct { | ||||
| } | ||||
| 
 | ||||
| func env(block *types.Block, eth core.Backend) *environment { | ||||
| 	state := state.New(block.Root(), eth.Db()) | ||||
| 	state := state.New(block.Root(), eth.StateDb()) | ||||
| 	env := &environment{ | ||||
| 		totalUsedGas: new(big.Int), | ||||
| 		state:        state, | ||||
|  | ||||
| @ -83,7 +83,7 @@ func (self *EthereumApi) setStateByBlockNumber(num int64) { | ||||
| 	block = chain.GetBlockByNumber(uint64(num)) | ||||
| 
 | ||||
| 	if block != nil { | ||||
| 		self.useState(state.New(block.Root(), self.xeth().Backend().Db())) | ||||
| 		self.useState(state.New(block.Root(), self.xeth().Backend().StateDb())) | ||||
| 	} else { | ||||
| 		self.useState(chain.State()) | ||||
| 	} | ||||
|  | ||||
| @ -26,7 +26,7 @@ func (self *State) SafeGet(addr string) *Object { | ||||
| func (self *State) safeGet(addr string) *state.StateObject { | ||||
| 	object := self.state.GetStateObject(fromHex(addr)) | ||||
| 	if object == nil { | ||||
| 		object = state.NewStateObject(fromHex(addr), self.xeth.eth.Db()) | ||||
| 		object = state.NewStateObject(fromHex(addr), self.xeth.eth.StateDb()) | ||||
| 	} | ||||
| 
 | ||||
| 	return object | ||||
|  | ||||
| @ -32,7 +32,8 @@ type Backend interface { | ||||
| 	IsListening() bool | ||||
| 	Peers() []*p2p.Peer | ||||
| 	KeyManager() *crypto.KeyManager | ||||
| 	Db() ethutil.Database | ||||
| 	BlockDb() ethutil.Database | ||||
| 	StateDb() ethutil.Database | ||||
| 	EventMux() *event.TypeMux | ||||
| 	Whisper() *whisper.Whisper | ||||
| 	Miner() *miner.Miner | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user