mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
core, core/state: WIP cache all teh things
This commit is contained in:
parent
08aeea24ba
commit
d010b982ae
6 changed files with 46 additions and 29 deletions
|
|
@ -136,6 +136,7 @@ participating.
|
||||||
utils.OlympicFlag,
|
utils.OlympicFlag,
|
||||||
utils.FastSyncFlag,
|
utils.FastSyncFlag,
|
||||||
utils.CacheFlag,
|
utils.CacheFlag,
|
||||||
|
utils.StateCacheFlag,
|
||||||
utils.LightKDFFlag,
|
utils.LightKDFFlag,
|
||||||
utils.JSpathFlag,
|
utils.JSpathFlag,
|
||||||
utils.ListenPortFlag,
|
utils.ListenPortFlag,
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ var AppHelpFlagGroups = []flagGroup{
|
||||||
utils.FastSyncFlag,
|
utils.FastSyncFlag,
|
||||||
utils.LightKDFFlag,
|
utils.LightKDFFlag,
|
||||||
utils.CacheFlag,
|
utils.CacheFlag,
|
||||||
|
utils.StateCacheFlag,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,10 @@ var (
|
||||||
Usage: "Megabytes of memory allocated to internal caching (min 16MB / database forced)",
|
Usage: "Megabytes of memory allocated to internal caching (min 16MB / database forced)",
|
||||||
Value: 128,
|
Value: 128,
|
||||||
}
|
}
|
||||||
|
StateCacheFlag = cli.BoolFlag{
|
||||||
|
Name: "statecache",
|
||||||
|
Usage: "Caches the last known state before syncing with the network. Uses significantly more memory.",
|
||||||
|
}
|
||||||
FastSyncFlag = cli.BoolFlag{
|
FastSyncFlag = cli.BoolFlag{
|
||||||
Name: "fast",
|
Name: "fast",
|
||||||
Usage: "Enable fast syncing through state downloads",
|
Usage: "Enable fast syncing through state downloads",
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,8 @@ type BlockChain struct {
|
||||||
pow pow.PoW
|
pow pow.PoW
|
||||||
processor Processor // block processor interface
|
processor Processor // block processor interface
|
||||||
validator Validator // block and state validator interface
|
validator Validator // block and state validator interface
|
||||||
|
|
||||||
|
canonState *state.State
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBlockChain returns a fully initialised block chain using information
|
// NewBlockChain returns a fully initialised block chain using information
|
||||||
|
|
@ -205,8 +207,13 @@ func (self *BlockChain) loadLastState() error {
|
||||||
glog.V(logger.Info).Infof("Last block: #%d [%x…] TD=%v", self.currentBlock.Number(), self.currentBlock.Hash().Bytes()[:4], blockTd)
|
glog.V(logger.Info).Infof("Last block: #%d [%x…] TD=%v", self.currentBlock.Number(), self.currentBlock.Hash().Bytes()[:4], blockTd)
|
||||||
glog.V(logger.Info).Infof("Fast block: #%d [%x…] TD=%v", self.currentFastBlock.Number(), self.currentFastBlock.Hash().Bytes()[:4], fastTd)
|
glog.V(logger.Info).Infof("Fast block: #%d [%x…] TD=%v", self.currentFastBlock.Number(), self.currentFastBlock.Hash().Bytes()[:4], fastTd)
|
||||||
|
|
||||||
/*
|
return nil
|
||||||
st, err := state.New(currentHeader.Root, self.chainDb)
|
}
|
||||||
|
|
||||||
|
func (bc *BlockChain) PreloadState() error {
|
||||||
|
currentHeader := bc.currentBlock.Header()
|
||||||
|
|
||||||
|
st, err := state.New(currentHeader.Root, bc.chainDb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -215,9 +222,8 @@ func (self *BlockChain) loadLastState() error {
|
||||||
if err := st.LoadAll(); err != nil {
|
if err := st.LoadAll(); err != nil {
|
||||||
return fmt.Errorf("core: could not pre-load account data: %v", err)
|
return fmt.Errorf("core: could not pre-load account data: %v", err)
|
||||||
}
|
}
|
||||||
self.canonState = st
|
bc.canonState = st
|
||||||
glog.V(logger.Info).Infoln("cached", len(st.StateObjects), "in", time.Since(tstart))
|
glog.V(logger.Info).Infoln("cached", len(st.StateObjects), "in", time.Since(tstart))
|
||||||
*/
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -905,12 +911,17 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parent := self.GetBlock(block.ParentHash(), block.NumberU64()-1)
|
||||||
// Create a new statedb using the parent block and report an
|
// Create a new statedb using the parent block and report an
|
||||||
// error if it fails.
|
// error if it fails.
|
||||||
if st == nil {
|
if st == nil {
|
||||||
st, err = state.New(self.GetBlock(block.ParentHash(), block.NumberU64()-1).Root(), self.chainDb)
|
if self.canonState != nil && parent.Root() == common.BytesToHash(self.canonState.Trie.Root()) {
|
||||||
|
st = self.canonState
|
||||||
} else {
|
} else {
|
||||||
err = st.Reset(chain[i-1].Root())
|
st, err = state.New(parent.Root(), self.chainDb)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = st.Reset(parent.Root())
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reportBlock(block, err)
|
reportBlock(block, err)
|
||||||
|
|
@ -928,10 +939,8 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
|
||||||
reportBlock(block, err)
|
reportBlock(block, err)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
tstart := time.Now()
|
|
||||||
// flatten the state before committing.
|
// flatten the state before committing.
|
||||||
st = state.Flatten(st)
|
st = state.Flatten(st)
|
||||||
fmt.Println("reduce took", time.Since(tstart))
|
|
||||||
// Write state changes to database
|
// Write state changes to database
|
||||||
_, err = state.Commit(st)
|
_, err = state.Commit(st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -972,6 +981,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (int, error) {
|
||||||
if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil {
|
if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil {
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
self.canonState = st
|
||||||
case SideStatTy:
|
case SideStatTy:
|
||||||
if glog.V(logger.Detail) {
|
if glog.V(logger.Detail) {
|
||||||
glog.Infof("inserted forked block #%d (TD=%v) (%d TXs %d UNCs) (%x...). Took %v\n", block.Number(), block.Difficulty(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4], time.Since(bstart))
|
glog.Infof("inserted forked block #%d (TD=%v) (%d TXs %d UNCs) (%x...). Took %v\n", block.Number(), block.Difficulty(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4], time.Since(bstart))
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ type State struct {
|
||||||
parent *State
|
parent *State
|
||||||
|
|
||||||
StateObjects map[common.Address]*StateObject
|
StateObjects map[common.Address]*StateObject
|
||||||
ownedStateObjects map[common.Address]bool
|
localStateObjects map[common.Address]bool
|
||||||
refund *big.Int
|
refund *big.Int
|
||||||
|
|
||||||
logIdx uint
|
logIdx uint
|
||||||
|
|
@ -49,7 +49,7 @@ func New(root common.Hash, db ethdb.Database) (*State, error) {
|
||||||
Db: db,
|
Db: db,
|
||||||
Trie: tr,
|
Trie: tr,
|
||||||
StateObjects: make(map[common.Address]*StateObject),
|
StateObjects: make(map[common.Address]*StateObject),
|
||||||
ownedStateObjects: make(map[common.Address]bool),
|
localStateObjects: make(map[common.Address]bool),
|
||||||
refund: new(big.Int),
|
refund: new(big.Int),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
@ -128,10 +128,10 @@ func (s *State) loadStateObject(stateObject *StateObject) {
|
||||||
func (s *State) GetOrNewStateObject(address common.Address) *StateObject {
|
func (s *State) GetOrNewStateObject(address common.Address) *StateObject {
|
||||||
stateObject, inCache := s.Read(address)
|
stateObject, inCache := s.Read(address)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
if !inCache || !s.ownedStateObjects[address] {
|
if !inCache || !s.localStateObjects[address] {
|
||||||
stateObject = stateObject.Copy()
|
stateObject = stateObject.Copy()
|
||||||
s.StateObjects[address] = stateObject
|
s.StateObjects[address] = stateObject
|
||||||
s.ownedStateObjects[address] = true
|
s.localStateObjects[address] = true
|
||||||
}
|
}
|
||||||
return stateObject
|
return stateObject
|
||||||
}
|
}
|
||||||
|
|
@ -141,7 +141,7 @@ func (s *State) GetOrNewStateObject(address common.Address) *StateObject {
|
||||||
stateObject.SetNonce(StartingNonce)
|
stateObject.SetNonce(StartingNonce)
|
||||||
|
|
||||||
s.StateObjects[address] = stateObject
|
s.StateObjects[address] = stateObject
|
||||||
s.ownedStateObjects[address] = true
|
s.localStateObjects[address] = true
|
||||||
}
|
}
|
||||||
return stateObject
|
return stateObject
|
||||||
}
|
}
|
||||||
|
|
@ -372,9 +372,8 @@ func (s *State) Reset(root common.Hash) error {
|
||||||
Db: s.Db,
|
Db: s.Db,
|
||||||
Trie: tr,
|
Trie: tr,
|
||||||
StateObjects: s.StateObjects,
|
StateObjects: s.StateObjects,
|
||||||
ownedStateObjects: s.ownedStateObjects,
|
localStateObjects: make(map[common.Address]bool),
|
||||||
//StateObjects: make(map[common.Address]*StateObject),
|
//StateObjects: make(map[common.Address]*StateObject),
|
||||||
//ownedStateObjects: make(map[common.Address]bool),
|
|
||||||
refund: new(big.Int),
|
refund: new(big.Int),
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -415,7 +414,7 @@ func Fork(parent *State) *State {
|
||||||
|
|
||||||
parent: parent,
|
parent: parent,
|
||||||
StateObjects: make(map[common.Address]*StateObject),
|
StateObjects: make(map[common.Address]*StateObject),
|
||||||
ownedStateObjects: make(map[common.Address]bool),
|
localStateObjects: make(map[common.Address]bool),
|
||||||
refund: new(big.Int),
|
refund: new(big.Int),
|
||||||
logIdx: parent.logIdx,
|
logIdx: parent.logIdx,
|
||||||
logs: nil,
|
logs: nil,
|
||||||
|
|
@ -435,8 +434,8 @@ func Flatten(s *State) *State {
|
||||||
|
|
||||||
for address, object := range s.StateObjects {
|
for address, object := range s.StateObjects {
|
||||||
flattenedState.StateObjects[address] = object
|
flattenedState.StateObjects[address] = object
|
||||||
if s.ownedStateObjects[address] {
|
if s.localStateObjects[address] {
|
||||||
flattenedState.ownedStateObjects[address] = true
|
flattenedState.localStateObjects[address] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -447,7 +446,7 @@ func Flatten(s *State) *State {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *State) String() string {
|
func (s *State) String() string {
|
||||||
return fmt.Sprintf("objects: %d owned: %d", len(s.StateObjects), len(s.ownedStateObjects))
|
return fmt.Sprintf("objects: %d owned: %d", len(s.StateObjects), len(s.localStateObjects))
|
||||||
}
|
}
|
||||||
|
|
||||||
func IntermediateRoot(state *State) common.Hash {
|
func IntermediateRoot(state *State) common.Hash {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,9 @@ func CommitBatch(state *State) (common.Hash, ethdb.Batch) {
|
||||||
func stateCommit(state *State, db trie.DatabaseWriter) (common.Hash, error) {
|
func stateCommit(state *State, db trie.DatabaseWriter) (common.Hash, error) {
|
||||||
// make sure the state is flattened before committing
|
// make sure the state is flattened before committing
|
||||||
state = Flatten(state)
|
state = Flatten(state)
|
||||||
for _, stateObject := range state.StateObjects {
|
for address, _ := range state.localStateObjects {
|
||||||
|
stateObject := state.StateObjects[address]
|
||||||
|
//for _, stateObject := range state.StateObjects {
|
||||||
if stateObject.remove {
|
if stateObject.remove {
|
||||||
// If the object has been removed, don't bother syncing it
|
// If the object has been removed, don't bother syncing it
|
||||||
// and just mark it for deletion in the trie.
|
// and just mark it for deletion in the trie.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue