Commit 1ae720fe authored by vipwzw's avatar vipwzw Committed by mdj33

修改blockchain 模块的全局变量,尽量减少全局变量,防止多个实例启动后出问题

parent 3507c095
......@@ -24,20 +24,19 @@ import (
//var
var (
blockLastHeight = []byte("blockLastHeight")
bodyPerfix = []byte("Body:")
LastSequence = []byte("LastSequence")
headerPerfix = []byte("Header:")
heightToHeaderPerfix = []byte("HH:")
hashPerfix = []byte("Hash:")
tdPerfix = []byte("TD:")
heightToHashKeyPerfix = []byte("Height:")
seqToHashKey = []byte("Seq:")
HashToSeqPerfix = []byte("HashToSeq:")
seqCBPrefix = []byte("SCB:")
seqCBLastNumPrefix = []byte("SCBL:")
storeLog = chainlog.New("submodule", "store")
lastheaderlock sync.Mutex
blockLastHeight = []byte("blockLastHeight")
bodyPerfix = []byte("Body:")
LastSequence = []byte("LastSequence")
headerPerfix = []byte("Header:")
heightToHeaderPerfix = []byte("HH:")
hashPerfix = []byte("Hash:")
tdPerfix = []byte("TD:")
heightToHashKeyPerfix = []byte("Height:")
seqToHashKey = []byte("Seq:")
HashToSeqPerfix = []byte("HashToSeq:")
seqCBPrefix = []byte("SCB:")
seqCBLastNumPrefix = []byte("SCBL:")
storeLog = chainlog.New("submodule", "store")
AddBlock int64 = 1
DelBlock int64 = 2
)
......@@ -102,14 +101,16 @@ func calcHashToSequenceKey(hash []byte) []byte {
//BlockStore 区块存储
type BlockStore struct {
db dbm.DB
client queue.Client
height int64
lastBlock *types.Block
db dbm.DB
client queue.Client
height int64
lastBlock *types.Block
lastheaderlock sync.Mutex
chain *BlockChain
}
//NewBlockStore new
func NewBlockStore(db dbm.DB, client queue.Client) *BlockStore {
func NewBlockStore(chain *BlockChain, db dbm.DB, client queue.Client) *BlockStore {
height, err := LoadBlockStoreHeight(db)
if err != nil {
chainlog.Info("init::LoadBlockStoreHeight::database may be crash", "err", err.Error())
......@@ -121,6 +122,7 @@ func NewBlockStore(db dbm.DB, client queue.Client) *BlockStore {
height: height,
db: db,
client: client,
chain: chain,
}
if height == -1 {
chainlog.Info("load block height error, may be init database", "height", height)
......@@ -354,8 +356,8 @@ func (bs *BlockStore) UpdateHeight2(height int64) {
//LastHeader 返回BlockStore保存的当前blockheader
func (bs *BlockStore) LastHeader() *types.Header {
lastheaderlock.Lock()
defer lastheaderlock.Unlock()
bs.lastheaderlock.Lock()
defer bs.lastheaderlock.Unlock()
// 通过lastBlock获取lastheader
var blockheader = types.Header{}
......@@ -382,8 +384,8 @@ func (bs *BlockStore) UpdateLastBlock(hash []byte) {
storeLog.Error("UpdateLastBlock", "hash", common.ToHex(hash), "error", err)
return
}
lastheaderlock.Lock()
defer lastheaderlock.Unlock()
bs.lastheaderlock.Lock()
defer bs.lastheaderlock.Unlock()
if blockdetail != nil {
bs.lastBlock = blockdetail.Block
}
......@@ -392,16 +394,16 @@ func (bs *BlockStore) UpdateLastBlock(hash []byte) {
//UpdateLastBlock2 更新LastBlock到缓存中
func (bs *BlockStore) UpdateLastBlock2(block *types.Block) {
lastheaderlock.Lock()
defer lastheaderlock.Unlock()
bs.lastheaderlock.Lock()
defer bs.lastheaderlock.Unlock()
bs.lastBlock = block
storeLog.Debug("UpdateLastBlock", "UpdateLastBlock", block.Height, "LastHederhash", common.ToHex(block.Hash()))
}
//LastBlock 获取最新的block信息
func (bs *BlockStore) LastBlock() *types.Block {
lastheaderlock.Lock()
defer lastheaderlock.Unlock()
bs.lastheaderlock.Lock()
defer bs.lastheaderlock.Unlock()
if bs.lastBlock != nil {
return bs.lastBlock
}
......@@ -545,7 +547,7 @@ func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDe
//存储block height和block hash的对应关系,便于通过height查询block
storeBatch.Set(calcHeightToHashKey(height), hash)
if isRecordBlockSequence || isParaChain {
if bs.chain.isRecordBlockSequence || bs.chain.isParaChain {
//存储记录block序列执行的type add
lastSequence, err = bs.saveBlockSequence(storeBatch, hash, height, AddBlock, sequence)
if err != nil {
......@@ -574,7 +576,7 @@ func (bs *BlockStore) DelBlock(storeBatch dbm.Batch, blockdetail *types.BlockDet
storeBatch.Delete(calcHeightToHashKey(height))
storeBatch.Delete(calcHeightToBlockHeaderKey(height))
if isRecordBlockSequence || isParaChain {
if bs.chain.isRecordBlockSequence || bs.chain.isParaChain {
//存储记录block序列执行的type del
lastSequence, err := bs.saveBlockSequence(storeBatch, hash, height, DelBlock, sequence)
if err != nil {
......@@ -944,7 +946,7 @@ func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, heigh
var blockSequence types.BlockSequence
var newSequence int64
if isRecordBlockSequence {
if bs.chain.isRecordBlockSequence {
Sequence, err := bs.LoadBlockLastSequence()
if err != nil {
storeLog.Error("SaveBlockSequence", "LoadBlockLastSequence err", err)
......@@ -959,7 +961,7 @@ func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, heigh
storeLog.Error("isRecordBlockSequence is true must Synchronizing data from zero block", "height", height)
panic(errors.New("isRecordBlockSequence is true must Synchronizing data from zero block"))
}
} else if isParaChain {
} else if bs.chain.isParaChain {
newSequence = sequence
}
blockSequence.Hash = hash
......@@ -1091,7 +1093,7 @@ func (bs *BlockStore) SetUpgradeMeta(meta *types.UpgradeMeta) error {
}
//isRecordBlockSequence配置的合法性检测
func (bs *BlockStore) isRecordBlockSequenceValid() {
func (bs *BlockStore) isRecordBlockSequenceValid(chain *BlockChain) {
lastHeight := bs.Height()
lastSequence, err := bs.LoadBlockLastSequence()
if err != nil {
......@@ -1101,7 +1103,7 @@ func (bs *BlockStore) isRecordBlockSequenceValid() {
}
}
//使能isRecordBlockSequence时的检测
if isRecordBlockSequence {
if chain.isRecordBlockSequence {
//中途开启isRecordBlockSequence报错
if lastSequence == -1 && lastHeight != -1 {
storeLog.Error("isRecordBlockSequenceValid", "lastHeight", lastHeight, "lastSequence", lastSequence)
......
......@@ -8,7 +8,6 @@ import (
"bytes"
"math/big"
"sort"
"sync"
"sync/atomic"
"time"
......@@ -18,17 +17,6 @@ import (
//var
var (
synBlocklock sync.Mutex
peerMaxBlklock sync.Mutex
castlock sync.Mutex
ntpClockSynclock sync.Mutex
faultpeerlock sync.Mutex
bestpeerlock sync.Mutex
isNtpClockSync = true //ntp时间是否同步
MaxFetchBlockNum int64 = 128 * 6 //一次最多申请获取block个数
TimeoutSeconds int64 = 2
BackBlockNum int64 = 128 //节点高度不增加时向后取blocks的个数
BackwardBlockNum int64 = 16 //本节点高度不增加时并且落后peer的高度数
checkHeightNoIncSeconds int64 = 5 * 60 //高度不增长时的检测周期目前暂定5分钟
......@@ -36,7 +24,6 @@ var (
fetchPeerListSeconds int64 = 5 //5 秒获取一个peerlist
MaxRollBlockNum int64 = 10000 //最大回退block数量
//TODO
blockSynInterVal = time.Duration(TimeoutSeconds)
batchsyncblocknum int64 = 5000 //同步阶段,如果自己高度小于最大高度5000个时,saveblock到db时批量处理不刷盘
synlog = chainlog.New("submodule", "syn")
......@@ -101,7 +88,7 @@ func (chain *BlockChain) SynRoutine() {
fetchPeerListTicker := time.NewTicker(time.Duration(fetchPeerListSeconds) * time.Second)
//向peer请求同步block的定时器,默认2s
blockSynTicker := time.NewTicker(blockSynInterVal * time.Second)
blockSynTicker := time.NewTicker(chain.blockSynInterVal * time.Second)
//5分钟检测一次bestchain主链高度是否有增长,如果没有增长可能是目前主链在侧链上,
//需要从最高peer向后同步指定的headers用来获取分叉点,再后从指定peer获取分叉点以后的blocks
......@@ -131,7 +118,7 @@ func (chain *BlockChain) SynRoutine() {
return
case <-blockSynTicker.C:
//synlog.Info("blockSynTicker")
if !GetDownloadSyncStatus() {
if !chain.GetDownloadSyncStatus() {
go chain.SynBlocksFromPeers()
}
......@@ -153,7 +140,7 @@ func (chain *BlockChain) SynRoutine() {
//定时检查系统时间,如果系统时间有问题,那么会有一个报警
case <-checkClockDriftTicker.C:
// ntp可能存在一直没有回应的情况导致go线程不退出,暂时不在WaitGroup中处理
go checkClockDrift()
go chain.checkClockDrift()
//定时检查故障peer,如果执行出错高度的blockhash值有变化,说明故障peer已经纠正
case <-recoveryFaultPeerTicker.C:
......@@ -195,8 +182,8 @@ func (chain *BlockChain) FetchBlock(start int64, end int64, pid []string, syncOr
requestblock.Pid = pid
//同步block一次请求128个
if blockcount >= MaxFetchBlockNum {
requestblock.End = start + MaxFetchBlockNum - 1
if blockcount >= chain.MaxFetchBlockNum {
requestblock.End = start + chain.MaxFetchBlockNum - 1
} else {
requestblock.End = end
}
......@@ -209,7 +196,7 @@ func (chain *BlockChain) FetchBlock(start int64, end int64, pid []string, syncOr
}
chain.UpdateDownLoadStartHeight(requestblock.End + 1)
//快速下载时需要及时更新bestpeer,防止下载侧链的block
if GetDownloadSyncStatus() {
if chain.GetDownloadSyncStatus() {
chain.UpdateDownLoadPids()
}
} else { // 所有DownLoad block已请求结束,恢复DownLoadInfo为默认值
......@@ -304,9 +291,9 @@ func (chain *BlockChain) fetchPeerList() error {
subInfoList := peerInfoList
peerMaxBlklock.Lock()
chain.peerMaxBlklock.Lock()
chain.peerList = subInfoList
peerMaxBlklock.Unlock()
chain.peerMaxBlklock.Unlock()
//获取到peerlist之后,需要判断是否已经发起了最优链的检测。如果没有就触发一次最优链的检测
if atomic.LoadInt32(&chain.firstcheckbestchain) == 0 {
......@@ -318,36 +305,36 @@ func (chain *BlockChain) fetchPeerList() error {
//GetRcvLastCastBlkHeight 存储广播的block最新高度
func (chain *BlockChain) GetRcvLastCastBlkHeight() int64 {
castlock.Lock()
defer castlock.Unlock()
chain.castlock.Lock()
defer chain.castlock.Unlock()
return chain.rcvLastBlockHeight
}
//UpdateRcvCastBlkHeight 更新广播的block最新高度
func (chain *BlockChain) UpdateRcvCastBlkHeight(height int64) {
castlock.Lock()
defer castlock.Unlock()
chain.castlock.Lock()
defer chain.castlock.Unlock()
chain.rcvLastBlockHeight = height
}
//GetsynBlkHeight 存储已经同步到db的block高度
func (chain *BlockChain) GetsynBlkHeight() int64 {
synBlocklock.Lock()
defer synBlocklock.Unlock()
chain.synBlocklock.Lock()
defer chain.synBlocklock.Unlock()
return chain.synBlockHeight
}
//UpdatesynBlkHeight 更新已经同步到db的block高度
func (chain *BlockChain) UpdatesynBlkHeight(height int64) {
synBlocklock.Lock()
defer synBlocklock.Unlock()
chain.synBlocklock.Lock()
defer chain.synBlocklock.Unlock()
chain.synBlockHeight = height
}
//GetPeerMaxBlkHeight 获取peerlist中合法的最新block高度
func (chain *BlockChain) GetPeerMaxBlkHeight() int64 {
peerMaxBlklock.Lock()
defer peerMaxBlklock.Unlock()
chain.peerMaxBlklock.Lock()
defer chain.peerMaxBlklock.Unlock()
//获取peerlist中最高的高度,peerlist是已经按照高度排序了的。
if chain.peerList != nil {
......@@ -372,8 +359,8 @@ func (chain *BlockChain) GetPeerMaxBlkHeight() int64 {
//GetPeerInfo 通过peerid获取peerinfo
func (chain *BlockChain) GetPeerInfo(pid string) *PeerInfo {
peerMaxBlklock.Lock()
defer peerMaxBlklock.Unlock()
chain.peerMaxBlklock.Lock()
defer chain.peerMaxBlklock.Unlock()
//获取peerinfo
if chain.peerList != nil {
......@@ -388,8 +375,8 @@ func (chain *BlockChain) GetPeerInfo(pid string) *PeerInfo {
//GetMaxPeerInfo 获取peerlist中最高节点的peerinfo
func (chain *BlockChain) GetMaxPeerInfo() *PeerInfo {
peerMaxBlklock.Lock()
defer peerMaxBlklock.Unlock()
chain.peerMaxBlklock.Lock()
defer chain.peerMaxBlklock.Unlock()
//获取peerlist中高度最高的peer,peerlist是已经按照高度排序了的。
if chain.peerList != nil {
......@@ -414,8 +401,8 @@ func (chain *BlockChain) GetMaxPeerInfo() *PeerInfo {
//GetPeers 获取所有peers
func (chain *BlockChain) GetPeers() PeerInfoList {
peerMaxBlklock.Lock()
defer peerMaxBlklock.Unlock()
chain.peerMaxBlklock.Lock()
defer chain.peerMaxBlklock.Unlock()
//获取peerinfo
var peers PeerInfoList
......@@ -428,8 +415,8 @@ func (chain *BlockChain) GetPeers() PeerInfoList {
//GetPeersMap 获取peers的map列表方便查找
func (chain *BlockChain) GetPeersMap() map[string]bool {
peerMaxBlklock.Lock()
defer peerMaxBlklock.Unlock()
chain.peerMaxBlklock.Lock()
defer chain.peerMaxBlklock.Unlock()
peersmap := make(map[string]bool)
if chain.peerList != nil {
......@@ -442,16 +429,16 @@ func (chain *BlockChain) GetPeersMap() map[string]bool {
//IsFaultPeer 判断指定pid是否在故障faultPeerList中
func (chain *BlockChain) IsFaultPeer(pid string) bool {
faultpeerlock.Lock()
defer faultpeerlock.Unlock()
chain.faultpeerlock.Lock()
defer chain.faultpeerlock.Unlock()
return chain.faultPeerList[pid] != nil
}
//IsErrExecBlock 判断此block是否被记录在本节点执行错误。
func (chain *BlockChain) IsErrExecBlock(height int64, hash []byte) (bool, error) {
faultpeerlock.Lock()
defer faultpeerlock.Unlock()
chain.faultpeerlock.Lock()
defer chain.faultpeerlock.Unlock()
//循环遍历故障peerlist,尝试检测故障peer是否已经恢复
for _, faultpeer := range chain.faultPeerList {
......@@ -464,8 +451,8 @@ func (chain *BlockChain) IsErrExecBlock(height int64, hash []byte) (bool, error)
//GetFaultPeer 获取指定pid是否在故障faultPeerList中
func (chain *BlockChain) GetFaultPeer(pid string) *FaultPeerInfo {
faultpeerlock.Lock()
defer faultpeerlock.Unlock()
chain.faultpeerlock.Lock()
defer chain.faultpeerlock.Unlock()
return chain.faultPeerList[pid]
}
......@@ -473,8 +460,8 @@ func (chain *BlockChain) GetFaultPeer(pid string) *FaultPeerInfo {
//RecoveryFaultPeer 尝试恢复故障peer节点,定时从出错的peer获取出错block的头信息。
//看对应的block是否有更新。有更新就说明故障peer节点已经恢复ok
func (chain *BlockChain) RecoveryFaultPeer() {
faultpeerlock.Lock()
defer faultpeerlock.Unlock()
chain.faultpeerlock.Lock()
defer chain.faultpeerlock.Unlock()
defer chain.tickerwg.Done()
......@@ -501,8 +488,8 @@ func (chain *BlockChain) RecoveryFaultPeer() {
//AddFaultPeer 添加故障节点到故障FaultPeerList中
func (chain *BlockChain) AddFaultPeer(faultpeer *FaultPeerInfo) {
faultpeerlock.Lock()
defer faultpeerlock.Unlock()
chain.faultpeerlock.Lock()
defer chain.faultpeerlock.Unlock()
//此节点已经存在故障peerlist中打印信息
faultnode := chain.faultPeerList[faultpeer.Peer.Name]
......@@ -515,8 +502,8 @@ func (chain *BlockChain) AddFaultPeer(faultpeer *FaultPeerInfo) {
//RemoveFaultPeer 此pid对应的故障已经修复,将此pid从故障列表中移除
func (chain *BlockChain) RemoveFaultPeer(pid string) {
faultpeerlock.Lock()
defer faultpeerlock.Unlock()
chain.faultpeerlock.Lock()
defer chain.faultpeerlock.Unlock()
synlog.Debug("RemoveFaultPeer", "pid", pid)
delete(chain.faultPeerList, pid)
......@@ -524,8 +511,8 @@ func (chain *BlockChain) RemoveFaultPeer(pid string) {
//UpdateFaultPeer 更新此故障peer的请求标志位
func (chain *BlockChain) UpdateFaultPeer(pid string, reqFlag bool) {
faultpeerlock.Lock()
defer faultpeerlock.Unlock()
chain.faultpeerlock.Lock()
defer chain.faultpeerlock.Unlock()
faultpeer := chain.faultPeerList[pid]
if faultpeer != nil {
......@@ -554,8 +541,8 @@ func (chain *BlockChain) RecordFaultPeer(pid string, height int64, hash []byte,
//PrintFaultPeer 打印出错的节点
func (chain *BlockChain) PrintFaultPeer() {
faultpeerlock.Lock()
defer faultpeerlock.Unlock()
chain.faultpeerlock.Lock()
defer chain.faultpeerlock.Unlock()
//循环遍历故障peerlist,尝试检测故障peer是否已经恢复
for pid, faultpeer := range chain.faultPeerList {
......@@ -777,7 +764,7 @@ func (chain *BlockChain) ProcBlockHeaders(headers *types.Headers, pid string) er
return nil
}
//在快速下载block阶段不处理fork的处理
if !GetDownloadSyncStatus() {
if !chain.GetDownloadSyncStatus() {
go chain.ProcDownLoadBlocks(ForkHeight, peermaxheight, []string{pid})
}
return nil
......@@ -894,17 +881,17 @@ func (chain *BlockChain) IsCaughtUp() bool {
}
//GetNtpClockSyncStatus 获取ntp时间是否同步状态
func GetNtpClockSyncStatus() bool {
ntpClockSynclock.Lock()
defer ntpClockSynclock.Unlock()
return isNtpClockSync
func (chain *BlockChain) GetNtpClockSyncStatus() bool {
chain.ntpClockSynclock.Lock()
defer chain.ntpClockSynclock.Unlock()
return chain.isNtpClockSync
}
//UpdateNtpClockSyncStatus 定时更新ntp时间同步状态
func UpdateNtpClockSyncStatus(Sync bool) {
ntpClockSynclock.Lock()
defer ntpClockSynclock.Unlock()
isNtpClockSync = Sync
func (chain *BlockChain) UpdateNtpClockSyncStatus(Sync bool) {
chain.ntpClockSynclock.Lock()
defer chain.ntpClockSynclock.Unlock()
chain.isNtpClockSync = Sync
}
//CheckBestChain 定时确保本节点在最优链上,定时向peer请求指定高度的header
......@@ -924,8 +911,8 @@ func (chain *BlockChain) CheckBestChain(isFirst bool) {
tipheight := chain.bestChain.Height()
bestpeerlock.Lock()
defer bestpeerlock.Unlock()
chain.bestpeerlock.Lock()
defer chain.bestpeerlock.Unlock()
for _, peer := range peers {
bestpeer := chain.bestChainPeerList[peer.Name]
......@@ -958,16 +945,16 @@ func (chain *BlockChain) CheckBestChain(isFirst bool) {
//GetBestChainPeer 获取最优节点
func (chain *BlockChain) GetBestChainPeer(pid string) *BestPeerInfo {
bestpeerlock.Lock()
defer bestpeerlock.Unlock()
chain.bestpeerlock.Lock()
defer chain.bestpeerlock.Unlock()
return chain.bestChainPeerList[pid]
}
//GetBestChainPids 定时确保本节点在最优链上,定时向peer请求指定高度的header
func (chain *BlockChain) GetBestChainPids() []string {
var PeerPids []string
bestpeerlock.Lock()
defer bestpeerlock.Unlock()
chain.bestpeerlock.Lock()
defer chain.bestpeerlock.Unlock()
peersmap := chain.GetPeersMap()
for key, value := range chain.bestChainPeerList {
......@@ -997,8 +984,8 @@ func (chain *BlockChain) CheckBestChainProc(headers *types.Headers, pid string)
return
}
bestpeerlock.Lock()
defer bestpeerlock.Unlock()
chain.bestpeerlock.Lock()
defer chain.bestpeerlock.Unlock()
bestchainpeer := chain.bestChainPeerList[pid]
if bestchainpeer == nil {
......
......@@ -24,17 +24,11 @@ import (
//var
var (
//cache 存贮的block个数
DefCacheSize int64 = 128
MaxSeqCB int64 = 20
cachelock sync.Mutex
zeroHash [32]byte
InitBlockNum int64 = 10240 //节点刚启动时从db向index和bestchain缓存中添加的blocknode数,和blockNodeCacheLimit保持一致
isStrongConsistency = false
chainlog = log.New("module", "blockchain")
FutureBlockDelayTime int64 = 1
isRecordBlockSequence = false //是否记录add或者del block的序列,方便blcokchain的恢复通过记录的序列表
isParaChain = false //是否是平行链。平行链需要记录Sequence信息
MaxSeqCB int64 = 20
zeroHash [32]byte
InitBlockNum int64 = 10240 //节点刚启动时从db向index和bestchain缓存中添加的blocknode数,和blockNodeCacheLimit保持一致
chainlog = log.New("module", "blockchain")
FutureBlockDelayTime int64 = 1
)
const maxFutureBlocks = 256
......@@ -99,19 +93,45 @@ type BlockChain struct {
futureBlocks *lru.Cache // future blocks are broadcast later processing
//downLoad block info
downLoadInfo *DownLoadInfo
downLoadlock sync.Mutex
downLoadInfo *DownLoadInfo
isFastDownloadSync bool //当本节点落后很多时,可以先下载区块到db,启动单独的goroutine去执行block
isRecordBlockSequence bool //是否记录add或者del block的序列,方便blcokchain的恢复通过记录的序列表
isParaChain bool //是否是平行链。平行链需要记录Sequence信息
isStrongConsistency bool
//lock
cachelock sync.Mutex
synBlocklock sync.Mutex
peerMaxBlklock sync.Mutex
castlock sync.Mutex
ntpClockSynclock sync.Mutex
faultpeerlock sync.Mutex
bestpeerlock sync.Mutex
downLoadlock sync.Mutex
fastDownLoadSynLock sync.Mutex
isNtpClockSync bool //ntp时间是否同步
//cfg
MaxFetchBlockNum int64 //一次最多申请获取block个数
TimeoutSeconds int64
blockSynInterVal time.Duration
DefCacheSize int64
failed int32
}
//New new
func New(cfg *types.BlockChain) *BlockChain {
initConfig(cfg)
futureBlocks, err := lru.New(maxFutureBlocks)
if err != nil {
panic("when New BlockChain lru.New return err")
}
defCacheSize := int64(128)
if cfg.DefCacheSize > 0 {
defCacheSize = cfg.DefCacheSize
}
blockchain := &BlockChain{
cache: NewBlockCache(DefCacheSize),
cache: NewBlockCache(defCacheSize),
DefCacheSize: defCacheSize,
rcvLastBlockHeight: -1,
synBlockHeight: -1,
peerList: nil,
......@@ -134,30 +154,31 @@ func New(cfg *types.BlockChain) *BlockChain {
bestChainPeerList: make(map[string]*BestPeerInfo),
futureBlocks: futureBlocks,
downLoadInfo: &DownLoadInfo{},
isNtpClockSync: true,
MaxFetchBlockNum: 128 * 6, //一次最多申请获取block个数
TimeoutSeconds: 2,
isFastDownloadSync: true,
}
blockchain.initConfig(cfg)
return blockchain
}
func initConfig(cfg *types.BlockChain) {
if cfg.DefCacheSize > 0 {
DefCacheSize = cfg.DefCacheSize
}
if types.IsEnable("TxHeight") && DefCacheSize <= (types.LowAllowPackHeight+types.HighAllowPackHeight+1) {
func (chain *BlockChain) initConfig(cfg *types.BlockChain) {
if types.IsEnable("TxHeight") && chain.DefCacheSize <= (types.LowAllowPackHeight+types.HighAllowPackHeight+1) {
panic("when Enable TxHeight DefCacheSize must big than types.LowAllowPackHeight")
}
if cfg.MaxFetchBlockNum > 0 {
MaxFetchBlockNum = cfg.MaxFetchBlockNum
chain.MaxFetchBlockNum = cfg.MaxFetchBlockNum
}
if cfg.TimeoutSeconds > 0 {
TimeoutSeconds = cfg.TimeoutSeconds
chain.TimeoutSeconds = cfg.TimeoutSeconds
}
isStrongConsistency = cfg.IsStrongConsistency
isRecordBlockSequence = cfg.IsRecordBlockSequence
isParaChain = cfg.IsParaChain
chain.blockSynInterVal = time.Duration(chain.TimeoutSeconds)
chain.isStrongConsistency = cfg.IsStrongConsistency
chain.isRecordBlockSequence = cfg.IsRecordBlockSequence
chain.isParaChain = cfg.IsParaChain
types.S("quickIndex", cfg.EnableTxQuickIndex)
}
......@@ -193,7 +214,7 @@ func (chain *BlockChain) SetQueueClient(client queue.Client) {
chain.client.Sub("blockchain")
blockStoreDB := dbm.NewDB("blockchain", chain.cfg.Driver, chain.cfg.DbPath, chain.cfg.DbCache)
blockStore := NewBlockStore(blockStoreDB, client)
blockStore := NewBlockStore(chain, blockStoreDB, client)
chain.blockStore = blockStore
stateHash := chain.getStateHash()
chain.query = NewQuery(blockStoreDB, chain.client, stateHash)
......@@ -226,7 +247,7 @@ func (chain *BlockChain) GetOrphanPool() *OrphanPool {
func (chain *BlockChain) InitBlockChain() {
//isRecordBlockSequence配置的合法性检测
if !chain.cfg.IsParaChain {
chain.blockStore.isRecordBlockSequenceValid()
chain.blockStore.isRecordBlockSequenceValid(chain)
}
//先缓存最新的128个block信息到cache中
curheight := chain.GetBlockHeight()
......@@ -394,7 +415,7 @@ func (chain *BlockChain) InitCache(height int64) {
if height < 0 {
return
}
for i := height - DefCacheSize; i <= height; i++ {
for i := height - chain.DefCacheSize; i <= height; i++ {
if i < 0 {
i = 0
}
......
......@@ -6,7 +6,6 @@ package blockchain
import (
"fmt"
"sync"
"sync/atomic"
"time"
......@@ -17,10 +16,8 @@ import (
//var
var (
tempBlockKey = []byte("TB:")
lastTempBlockKey = []byte("LTB:")
isFastDownloadSync = true //当本节点落后很多时,可以先下载区块到db,启动单独的goroutine去执行block
fastDownLoadSynLock sync.Mutex
tempBlockKey = []byte("TB:")
lastTempBlockKey = []byte("LTB:")
)
//const
......@@ -56,17 +53,17 @@ func calcLastTempBlockHeightKey() []byte {
}
//GetDownloadSyncStatus 获取下载区块的同步模式
func GetDownloadSyncStatus() bool {
fastDownLoadSynLock.Lock()
defer fastDownLoadSynLock.Unlock()
return isFastDownloadSync
func (chain *BlockChain) GetDownloadSyncStatus() bool {
chain.fastDownLoadSynLock.Lock()
defer chain.fastDownLoadSynLock.Unlock()
return chain.isFastDownloadSync
}
//UpdateDownloadSyncStatus 更新下载区块的同步模式
func UpdateDownloadSyncStatus(Sync bool) {
fastDownLoadSynLock.Lock()
defer fastDownLoadSynLock.Unlock()
isFastDownloadSync = Sync
func (chain *BlockChain) UpdateDownloadSyncStatus(Sync bool) {
chain.fastDownLoadSynLock.Lock()
defer chain.fastDownLoadSynLock.Unlock()
chain.isFastDownloadSync = Sync
}
//FastDownLoadBlocks 开启快速下载区块的模式
......@@ -93,7 +90,7 @@ func (chain *BlockChain) FastDownLoadBlocks() {
pids := chain.GetBestChainPids()
//节点启动时只有落后最优链batchsyncblocknum个区块时才开启这种下载模式
if pids != nil && peerMaxBlkHeight != -1 && curheight+batchsyncblocknum >= peerMaxBlkHeight {
UpdateDownloadSyncStatus(false)
chain.UpdateDownloadSyncStatus(false)
synlog.Info("FastDownLoadBlocks:quit!", "curheight", curheight, "peerMaxBlkHeight", peerMaxBlkHeight)
break
} else if curheight+batchsyncblocknum < peerMaxBlkHeight && len(pids) >= bestPeerCount {
......@@ -102,7 +99,7 @@ func (chain *BlockChain) FastDownLoadBlocks() {
go chain.ReadBlockToExec(peerMaxBlkHeight, true)
break
} else if types.Since(startTime) > waitTimeDownLoad*time.Second || chain.cfg.SingleMode {
UpdateDownloadSyncStatus(false)
chain.UpdateDownloadSyncStatus(false)
synlog.Info("FastDownLoadBlocks:waitTimeDownLoad:quit!", "curheight", curheight, "peerMaxBlkHeight", peerMaxBlkHeight, "pids", pids)
break
} else {
......@@ -183,7 +180,7 @@ func (chain *BlockChain) ReadBlockToExec(height int64, isNewStart bool) {
//CancelFastDownLoadFlag 清除快速下载模式的一些标志
func (chain *BlockChain) cancelFastDownLoadFlag(isNewStart bool) {
if isNewStart {
UpdateDownloadSyncStatus(false)
chain.UpdateDownloadSyncStatus(false)
}
chain.DelLastTempBlockHeight()
synlog.Info("cancelFastDownLoadFlag", "isNewStart", isNewStart)
......
......@@ -21,12 +21,11 @@ const (
var (
ntpLog = chainlog.New("submodule", "ntp")
failed int32
)
// checkClockDrift queries an NTP server for clock drifts and warns the user if
// one large enough is detected.
func checkClockDrift() {
func (chain *BlockChain) checkClockDrift() {
realnow := common.GetRealTimeRetry(types.NtpHosts, 10)
if realnow.IsZero() {
ntpLog.Info("checkClockDrift", "sntpDrift err", "get ntptime error")
......@@ -42,14 +41,14 @@ func checkClockDrift() {
ntpLog.Warn(fmt.Sprint(warning))
ntpLog.Warn(fmt.Sprint(howtofix))
ntpLog.Warn(fmt.Sprint(separator))
atomic.AddInt32(&failed, 1)
if atomic.LoadInt32(&failed) == ntpChecks {
atomic.AddInt32(&chain.failed, 1)
if atomic.LoadInt32(&chain.failed) == ntpChecks {
ntpLog.Error("System clock seems ERROR")
UpdateNtpClockSyncStatus(false)
chain.UpdateNtpClockSyncStatus(false)
}
} else {
atomic.StoreInt32(&failed, 0)
UpdateNtpClockSyncStatus(true)
atomic.StoreInt32(&chain.failed, 0)
chain.UpdateNtpClockSyncStatus(true)
ntpLog.Info(fmt.Sprintf("Sanity NTP check reported %v drift, all ok", drift))
}
}
......@@ -61,7 +61,7 @@ func (chain *BlockChain) ProcRecvMsg() {
case types.EventIsSync:
go chain.processMsg(msg, reqnum, chain.isSync)
case types.EventIsNtpClockSync:
go chain.processMsg(msg, reqnum, chain.isNtpClockSync)
go chain.processMsg(msg, reqnum, chain.isNtpClockSyncFunc)
case types.EventGetLastBlockSequence:
go chain.processMsg(msg, reqnum, chain.getLastBlockSequence)
......@@ -161,7 +161,7 @@ func (chain *BlockChain) addBlock(msg *queue.Message) {
reply.IsOk = true
blockpid := msg.Data.(*types.BlockPid)
//chainlog.Error("addBlock", "height", blockpid.Block.Height, "pid", blockpid.Pid)
if GetDownloadSyncStatus() {
if chain.GetDownloadSyncStatus() {
//downLoadTask 运行时设置对应的blockdone
if chain.downLoadTask.InProgress() {
chain.downLoadTask.Done(blockpid.Block.GetHeight())
......@@ -366,8 +366,8 @@ func (chain *BlockChain) getLastBlock(msg *queue.Message) {
}
}
func (chain *BlockChain) isNtpClockSync(msg *queue.Message) {
ok := GetNtpClockSyncStatus()
func (chain *BlockChain) isNtpClockSyncFunc(msg *queue.Message) {
ok := chain.GetNtpClockSyncStatus()
msg.Reply(chain.client.NewMessage("", types.EventReplyIsNtpClockSync, &types.IsNtpClockSync{Isntpclocksync: ok}))
}
......
......@@ -402,7 +402,7 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai
}
}
//目前非平行链并开启isRecordBlockSequence功能
if isRecordBlockSequence && !isParaChain {
if b.isRecordBlockSequence && !b.isParaChain {
b.pushseq.updateSeq(lastSequence)
}
return blockdetail, nil
......@@ -471,7 +471,7 @@ func (b *BlockChain) disconnectBlock(node *blockNode, blockdetail *types.BlockDe
chainlog.Debug("disconnectBlock success", "newtipnode.hash", common.ToHex(newtipnode.hash), "delblock.parent.hash", common.ToHex(blockdetail.Block.GetParentHash()))
//目前非平行链并开启isRecordBlockSequence功能
if isRecordBlockSequence && !isParaChain {
if b.isRecordBlockSequence && !b.isParaChain {
b.pushseq.updateSeq(lastSequence)
}
return nil
......
......@@ -96,7 +96,7 @@ func (chain *BlockChain) ProcAddBlockSeqCB(cb *types.BlockSeqCB) error {
return types.ErrInvalidParam
}
if !isRecordBlockSequence {
if !chain.isRecordBlockSequence {
return types.ErrRecordBlockSequence
}
if chain.blockStore.seqCBNum() >= MaxSeqCB && !chain.blockStore.isSeqCBExist(cb.Name) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment