|
|
@ -17,6 +17,9 @@ import ( |
|
|
|
var ( |
|
|
|
var ( |
|
|
|
chainlogger = logger.NewLogger("CHAIN") |
|
|
|
chainlogger = logger.NewLogger("CHAIN") |
|
|
|
jsonlogger = logger.NewJsonLogger() |
|
|
|
jsonlogger = logger.NewJsonLogger() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
blockHashPre = []byte("block-hash-") |
|
|
|
|
|
|
|
blockNumPre = []byte("block-num-") |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
type StateQuery interface { |
|
|
|
type StateQuery interface { |
|
|
@ -165,9 +168,8 @@ func (self *ChainManager) setTransState(statedb *state.StateDB) { |
|
|
|
func (bc *ChainManager) setLastBlock() { |
|
|
|
func (bc *ChainManager) setLastBlock() { |
|
|
|
data, _ := bc.blockDb.Get([]byte("LastBlock")) |
|
|
|
data, _ := bc.blockDb.Get([]byte("LastBlock")) |
|
|
|
if len(data) != 0 { |
|
|
|
if len(data) != 0 { |
|
|
|
var block types.Block |
|
|
|
block := bc.GetBlock(data) |
|
|
|
rlp.Decode(bytes.NewReader(data), &block) |
|
|
|
bc.currentBlock = block |
|
|
|
bc.currentBlock = &block |
|
|
|
|
|
|
|
bc.lastBlockHash = block.Hash() |
|
|
|
bc.lastBlockHash = block.Hash() |
|
|
|
|
|
|
|
|
|
|
|
// Set the last know difficulty (might be 0x0 as initial value, Genesis)
|
|
|
|
// Set the last know difficulty (might be 0x0 as initial value, Genesis)
|
|
|
@ -220,7 +222,7 @@ func (bc *ChainManager) Reset() { |
|
|
|
defer bc.mu.Unlock() |
|
|
|
defer bc.mu.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
for block := bc.currentBlock; block != nil; block = bc.GetBlock(block.Header().ParentHash) { |
|
|
|
for block := bc.currentBlock; block != nil; block = bc.GetBlock(block.Header().ParentHash) { |
|
|
|
bc.blockDb.Delete(block.Hash()) |
|
|
|
bc.removeBlock(block) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Prepare the genesis block
|
|
|
|
// Prepare the genesis block
|
|
|
@ -231,12 +233,16 @@ func (bc *ChainManager) Reset() { |
|
|
|
bc.setTotalDifficulty(ethutil.Big("0")) |
|
|
|
bc.setTotalDifficulty(ethutil.Big("0")) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (bc *ChainManager) removeBlock(block *types.Block) { |
|
|
|
|
|
|
|
bc.blockDb.Delete(append(blockHashPre, block.Hash()...)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (bc *ChainManager) ResetWithGenesisBlock(gb *types.Block) { |
|
|
|
func (bc *ChainManager) ResetWithGenesisBlock(gb *types.Block) { |
|
|
|
bc.mu.Lock() |
|
|
|
bc.mu.Lock() |
|
|
|
defer bc.mu.Unlock() |
|
|
|
defer bc.mu.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
for block := bc.currentBlock; block != nil; block = bc.GetBlock(block.Header().ParentHash) { |
|
|
|
for block := bc.currentBlock; block != nil; block = bc.GetBlock(block.Header().ParentHash) { |
|
|
|
bc.blockDb.Delete(block.Hash()) |
|
|
|
bc.removeBlock(block) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Prepare the genesis block
|
|
|
|
// Prepare the genesis block
|
|
|
@ -261,15 +267,20 @@ func (self *ChainManager) Export() []byte { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (bc *ChainManager) insert(block *types.Block) { |
|
|
|
func (bc *ChainManager) insert(block *types.Block) { |
|
|
|
encodedBlock := ethutil.Encode(block) |
|
|
|
//encodedBlock := ethutil.Encode(block)
|
|
|
|
bc.blockDb.Put([]byte("LastBlock"), encodedBlock) |
|
|
|
bc.blockDb.Put([]byte("LastBlock"), block.Hash()) |
|
|
|
bc.currentBlock = block |
|
|
|
bc.currentBlock = block |
|
|
|
bc.lastBlockHash = block.Hash() |
|
|
|
bc.lastBlockHash = block.Hash() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
key := append(blockNumPre, block.Number().Bytes()...) |
|
|
|
|
|
|
|
bc.blockDb.Put(key, bc.lastBlockHash) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (bc *ChainManager) write(block *types.Block) { |
|
|
|
func (bc *ChainManager) write(block *types.Block) { |
|
|
|
encodedBlock := ethutil.Encode(block.RlpDataForStorage()) |
|
|
|
encodedBlock := ethutil.Encode(block.RlpDataForStorage()) |
|
|
|
bc.blockDb.Put(block.Hash(), encodedBlock) |
|
|
|
|
|
|
|
|
|
|
|
key := append(blockHashPre, block.Hash()...) |
|
|
|
|
|
|
|
bc.blockDb.Put(key, encodedBlock) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Accessors
|
|
|
|
// Accessors
|
|
|
@ -279,7 +290,7 @@ func (bc *ChainManager) Genesis() *types.Block { |
|
|
|
|
|
|
|
|
|
|
|
// Block fetching methods
|
|
|
|
// Block fetching methods
|
|
|
|
func (bc *ChainManager) HasBlock(hash []byte) bool { |
|
|
|
func (bc *ChainManager) HasBlock(hash []byte) bool { |
|
|
|
data, _ := bc.blockDb.Get(hash) |
|
|
|
data, _ := bc.blockDb.Get(append(blockHashPre, hash...)) |
|
|
|
return len(data) != 0 |
|
|
|
return len(data) != 0 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -307,7 +318,7 @@ func (self *ChainManager) GetBlockHashesFromHash(hash []byte, max uint64) (chain |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (self *ChainManager) GetBlock(hash []byte) *types.Block { |
|
|
|
func (self *ChainManager) GetBlock(hash []byte) *types.Block { |
|
|
|
data, _ := self.blockDb.Get(hash) |
|
|
|
data, _ := self.blockDb.Get(append(blockHashPre, hash...)) |
|
|
|
if len(data) == 0 { |
|
|
|
if len(data) == 0 { |
|
|
|
return nil |
|
|
|
return nil |
|
|
|
} |
|
|
|
} |
|
|
@ -320,6 +331,18 @@ func (self *ChainManager) GetBlock(hash []byte) *types.Block { |
|
|
|
return &block |
|
|
|
return &block |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block { |
|
|
|
|
|
|
|
self.mu.RLock() |
|
|
|
|
|
|
|
defer self.mu.RUnlock() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
key, _ := self.blockDb.Get(append(blockNumPre, big.NewInt(int64(num)).Bytes()...)) |
|
|
|
|
|
|
|
if len(key) == 0 { |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return self.GetBlock(key) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (self *ChainManager) GetUnclesInChain(block *types.Block, length int) (uncles []*types.Header) { |
|
|
|
func (self *ChainManager) GetUnclesInChain(block *types.Block, length int) (uncles []*types.Header) { |
|
|
|
for i := 0; block != nil && i < length; i++ { |
|
|
|
for i := 0; block != nil && i < length; i++ { |
|
|
|
uncles = append(uncles, block.Uncles()...) |
|
|
|
uncles = append(uncles, block.Uncles()...) |
|
|
@ -342,24 +365,6 @@ func (self *ChainManager) GetAncestors(block *types.Block, length int) (blocks [ |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block { |
|
|
|
|
|
|
|
self.mu.RLock() |
|
|
|
|
|
|
|
defer self.mu.RUnlock() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var block *types.Block |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if num <= self.currentBlock.Number().Uint64() { |
|
|
|
|
|
|
|
block = self.currentBlock |
|
|
|
|
|
|
|
for ; block != nil; block = self.GetBlock(block.Header().ParentHash) { |
|
|
|
|
|
|
|
if block.Header().Number.Uint64() == num { |
|
|
|
|
|
|
|
break |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return block |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (bc *ChainManager) setTotalDifficulty(td *big.Int) { |
|
|
|
func (bc *ChainManager) setTotalDifficulty(td *big.Int) { |
|
|
|
bc.blockDb.Put([]byte("LTD"), td.Bytes()) |
|
|
|
bc.blockDb.Put([]byte("LTD"), td.Bytes()) |
|
|
|
bc.td = td |
|
|
|
bc.td = td |
|
|
|