比特币全节点Go语言实现BTCD之区块与节点的几个问题

有一本书上写,每个节点要求连接的节点(node)数量至少为5,但是看代码是至少8个,代码如下:

func (cm *ConnManager) Start() {
   // Already started?
   if atomic.AddInt32(&cm.start, 1) != 1 {
      return
   }

   log.Trace("Connection manager started")
   cm.wg.Add(1)
   go cm.connHandler()

   // Start all the listeners so long as the caller requested them and
   // provided a callback to be invoked when connections are accepted.
   if cm.cfg.OnAccept != nil {
      for _, listner := range cm.cfg.Listeners {
         cm.wg.Add(1)
         go cm.listenHandler(listner)
      }
   }

   for i := atomic.LoadUint64(&cm.connReqCount); i < uint64(cm.cfg.TargetOutbound); i++ {
      go cm.NewConnReq()
   }
}
其中targetOutBound即是要求的数量。

// TargetOutbound is the number of outbound network connections to
// maintain. Defaults to 8.
TargetOutbound uint32

中位数和本地系统时间差别不超过70分钟,否则会提醒你更新本机的时间。代码:

func (m *medianTime) AddTimeSample(sourceID string, timeVal time.Time) {
   m.mtx.Lock()
   defer m.mtx.Unlock()

   now := time.Unix(time.Now().Unix(), 0)
   offsetSecs := int64(timeVal.Sub(now).Seconds())
   numOffsets := len(m.offsets)
   if numOffsets == maxMedianTimeEntries && maxMedianTimeEntries > 0 {
      m.offsets = m.offsets[1:]
      numOffsets--
   }
   m.offsets = append(m.offsets, offsetSecs)
   numOffsets++

   // Sort the offsets so the median can be obtained as needed later.
   sortedOffsets := make([]int64, numOffsets)
   copy(sortedOffsets, m.offsets)
   sort.Sort(int64Sorter(sortedOffsets))

   offsetDuration := time.Duration(offsetSecs) * time.Second
   log.Debugf("Added time sample of %v (total: %v)", offsetDuration,
      numOffsets)

   if math.Abs(float64(median)) < maxAllowedOffsetSecs {
      m.offsetSecs = median
   } else {
      // The median offset of all added time data is larger than the
      // maximum allowed offset, so don't use an offset.  This
      // effectively limits how far the local clock can be skewed.
      m.offsetSecs = 0

      if !m.invalidTimeChecked {
         m.invalidTimeChecked = true

         // Find if any time samples have a time that is close
         // to the local time.
         var remoteHasCloseTime bool
         for _, offset := range sortedOffsets {
            if math.Abs(float64(offset)) < similarTimeSecs {
               remoteHasCloseTime = true
               break
            }
         }

         // Warn if none of the time samples are close.
         if !remoteHasCloseTime {
            log.Warnf("Please check your date and time " +
               "are correct!  btcd will not work " +
               "properly with an invalid time")
         }
      }
   }

   medianDuration := time.Duration(m.offsetSecs) * time.Second
   log.Debugf("New time offset: %v", medianDuration)
}
if math.Abs(float64(median)) < maxAllowedOffsetSecs {

即是判断时间,

const (
   maxAllowedOffsetSecs = 70 * 60 // 1 hour 10 minutes

同时,在接收到新的block时会拒绝时间与自己差距+2小时和-(前11个block时间中位数)的block

这个逻辑在btcd中还未实现

A chain of blocks with each block referencing the block that preceded it. The most-difficult-to-recreate chain is the best block chain.

区块都引用自前一个区块,重新创建最困难的链就是最好的链。简略代码:

func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, flags BehaviorFlags) (bool, error) {
   ...
   if node.workSum.Cmp(b.bestChain.Tip().workSum) <= 0 {
      // Log information about how the block is forking the chain.
      fork := b.bestChain.FindFork(node)
      if fork.hash.IsEqual(parentHash) {
         log.Infof("FORK: Block %v forks the chain at height %d"+
            "/block %v, but does not cause a reorganize",
            node.hash, fork.height, fork.hash)
      } else {
         log.Infof("EXTEND FORK: Block %v extends a side chain "+
            "which forks the chain at height %d/block %v",
            node.hash, fork.height, fork.hash)
      }

      return false, nil
   }

   detachNodes, attachNodes := b.getReorganizeNodes(node)

   // Reorganize the chain.
   log.Infof("REORGANIZE: Block %v is causing a reorganize.", node.hash)
   err := b.reorganizeChain(detachNodes, attachNodes)

   if writeErr := b.index.flushToDB(); writeErr != nil {
      log.Warnf("Error flushing block index changes to disk: %v", writeErr)
   }

   return err == nil, err
}
if node.workSum.Cmp(b.bestChain.Tip().workSum) <= 0 {

这个就是比较工作量,这个节点的worksum是如何计算的呢?如下:

func CalcWork(bits uint32) *big.Int {

   difficultyNum := CompactToBig(bits)
   if difficultyNum.Sign() <= 0 {
      return big.NewInt(0)
   }

   // (1 << 256) / (difficultyNum + 1)
   denominator := new(big.Int).Add(difficultyNum, bigOne)
   return new(big.Int).Div(oneLsh256, denominator)
}

The block chain provides Bitcoin’s public ledger, an ordered and timestamped record of transactions. This system is used to protect against double spending and modification of previous transaction records.

比特币的区块链提供了公开账本,包含有序的带有时间戳的交易记录。每个区块的打包都会对区块交易检查是否存在双花,每个区块都有一个工作量,修改之前的一个交易记录需要大于原来区块的工作量,即51%问题。



猜你喜欢

转载自blog.csdn.net/vohyeah/article/details/80733857