# BIP113(Median Time Past)

Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

# BIP113(Median Time Past)

## 1 BIP地址

```BIP: 113
Layer: Consensus (soft fork)
Title: Median time-past as endpoint for lock-time calculations
Author: Thomas Kerin <[email protected]>
Mark Friedenbach <[email protected]>
Status: Final
Type: Standards Track
Created: 2015-08-10
```

## 2 原因和目的

BIP113定义了Block的Median time-past(MTP)：该Block之前的11个Block的timestamp的中位值。

BIP113重新定义了有时间锁定（time-locked）的交易（Transactions）被是否能被包含到一个区块（Block）条件。

Transaction 的 `lock_time` 字段 定义了该交易可被包含到Block的限制（到一定时间或者block的到一定的高度后才可以被包含到block）。 这里到达一定的时间由block的timestamp决定，这会造成一个问题，因为目前的共识机制并没有强制限制block的timestamp的顺序，所以为了获得更多的挖矿奖励，miner会倾向将timestamp往后设定来包含更多的transactions，而这些transacts本不应该被包含。

btcd的实现 这里的node是Block的上一个Block, medianTimeBlocks是常量11，该方法从Block的上一个Block开始，向前找11个Block的timestamp

```// https://github.com/btcsuite/btcd/blob/7d2daa5bfef28c5e282571bc06416516936115ee/blockchain/blockindex.go#L185

// CalcPastMedianTime calculates the median time of the previous few blocks
// prior to, and including, the block node.
//
// This function is safe for concurrent access.
func (node *blockNode) CalcPastMedianTime() time.Time {
// Create a slice of the previous few block timestamps used to calculate
// the median per the number defined by the constant medianTimeBlocks.
timestamps := make([]int64, medianTimeBlocks)
numNodes := 0
iterNode := node
for i := 0; i < medianTimeBlocks && iterNode != nil; i++ {
timestamps[i] = iterNode.timestamp
numNodes++

iterNode = iterNode.parent
}

// Prune the slice to the actual number of available timestamps which
// will be fewer than desired near the beginning of the block chain
// and sort them.
timestamps = timestamps[:numNodes]
sort.Sort(timeSorter(timestamps))

// NOTE: The consensus rules incorrectly calculate the median for even
// numbers of blocks.  A true median averages the middle two elements
// for a set with an even number of elements in it.   Since the constant
// for the previous number of blocks to be used is odd, this is only an
// issue for a few blocks near the beginning of the chain.  I suspect
// this is an optimization even though the result is slightly wrong for
// a few of the first blocks since after the first few blocks, there
// will always be an odd number of blocks in the set per the constant.
//
// This code follows suit to ensure the same rules are used, however, be
// aware that should the medianTimeBlocks constant ever be changed to an
// even number, this code will be wrong.
medianTimestamp := timestamps[numNodes/2]
return time.Unix(medianTimestamp, 0)

```