1// Copyright (c) 2015-2017 The btcsuite developers
2// Use of this source code is governed by an ISC
3// license that can be found in the LICENSE file.
4
5package blockchain
6
7import (
8	"math/big"
9	"sort"
10	"sync"
11	"time"
12
13	"github.com/btcsuite/btcd/chaincfg"
14	"github.com/btcsuite/btcd/chaincfg/chainhash"
15	"github.com/btcsuite/btcd/database"
16	"github.com/btcsuite/btcd/wire"
17)
18
19// blockStatus is a bit field representing the validation state of the block.
20type blockStatus byte
21
22const (
23	// statusDataStored indicates that the block's payload is stored on disk.
24	statusDataStored blockStatus = 1 << iota
25
26	// statusValid indicates that the block has been fully validated.
27	statusValid
28
29	// statusValidateFailed indicates that the block has failed validation.
30	statusValidateFailed
31
32	// statusInvalidAncestor indicates that one of the block's ancestors has
33	// has failed validation, thus the block is also invalid.
34	statusInvalidAncestor
35
36	// statusNone indicates that the block has no validation state flags set.
37	//
38	// NOTE: This must be defined last in order to avoid influencing iota.
39	statusNone blockStatus = 0
40)
41
42// HaveData returns whether the full block data is stored in the database. This
43// will return false for a block node where only the header is downloaded or
44// kept.
45func (status blockStatus) HaveData() bool {
46	return status&statusDataStored != 0
47}
48
49// KnownValid returns whether the block is known to be valid. This will return
50// false for a valid block that has not been fully validated yet.
51func (status blockStatus) KnownValid() bool {
52	return status&statusValid != 0
53}
54
55// KnownInvalid returns whether the block is known to be invalid. This may be
56// because the block itself failed validation or any of its ancestors is
57// invalid. This will return false for invalid blocks that have not been proven
58// invalid yet.
59func (status blockStatus) KnownInvalid() bool {
60	return status&(statusValidateFailed|statusInvalidAncestor) != 0
61}
62
63// blockNode represents a block within the block chain and is primarily used to
64// aid in selecting the best chain to be the main chain.  The main chain is
65// stored into the block database.
66type blockNode struct {
67	// NOTE: Additions, deletions, or modifications to the order of the
68	// definitions in this struct should not be changed without considering
69	// how it affects alignment on 64-bit platforms.  The current order is
70	// specifically crafted to result in minimal padding.  There will be
71	// hundreds of thousands of these in memory, so a few extra bytes of
72	// padding adds up.
73
74	// parent is the parent block for this node.
75	parent *blockNode
76
77	// hash is the double sha 256 of the block.
78	hash chainhash.Hash
79
80	// workSum is the total amount of work in the chain up to and including
81	// this node.
82	workSum *big.Int
83
84	// height is the position in the block chain.
85	height int32
86
87	// Some fields from block headers to aid in best chain selection and
88	// reconstructing headers from memory.  These must be treated as
89	// immutable and are intentionally ordered to avoid padding on 64-bit
90	// platforms.
91	version    int32
92	bits       uint32
93	nonce      uint32
94	timestamp  int64
95	merkleRoot chainhash.Hash
96
97	// status is a bitfield representing the validation state of the block. The
98	// status field, unlike the other fields, may be written to and so should
99	// only be accessed using the concurrent-safe NodeStatus method on
100	// blockIndex once the node has been added to the global index.
101	status blockStatus
102}
103
104// initBlockNode initializes a block node from the given header and parent node,
105// calculating the height and workSum from the respective fields on the parent.
106// This function is NOT safe for concurrent access.  It must only be called when
107// initially creating a node.
108func initBlockNode(node *blockNode, blockHeader *wire.BlockHeader, parent *blockNode) {
109	*node = blockNode{
110		hash:       blockHeader.BlockHash(),
111		workSum:    CalcWork(blockHeader.Bits),
112		version:    blockHeader.Version,
113		bits:       blockHeader.Bits,
114		nonce:      blockHeader.Nonce,
115		timestamp:  blockHeader.Timestamp.Unix(),
116		merkleRoot: blockHeader.MerkleRoot,
117	}
118	if parent != nil {
119		node.parent = parent
120		node.height = parent.height + 1
121		node.workSum = node.workSum.Add(parent.workSum, node.workSum)
122	}
123}
124
125// newBlockNode returns a new block node for the given block header and parent
126// node, calculating the height and workSum from the respective fields on the
127// parent. This function is NOT safe for concurrent access.
128func newBlockNode(blockHeader *wire.BlockHeader, parent *blockNode) *blockNode {
129	var node blockNode
130	initBlockNode(&node, blockHeader, parent)
131	return &node
132}
133
134// Header constructs a block header from the node and returns it.
135//
136// This function is safe for concurrent access.
137func (node *blockNode) Header() wire.BlockHeader {
138	// No lock is needed because all accessed fields are immutable.
139	prevHash := &zeroHash
140	if node.parent != nil {
141		prevHash = &node.parent.hash
142	}
143	return wire.BlockHeader{
144		Version:    node.version,
145		PrevBlock:  *prevHash,
146		MerkleRoot: node.merkleRoot,
147		Timestamp:  time.Unix(node.timestamp, 0),
148		Bits:       node.bits,
149		Nonce:      node.nonce,
150	}
151}
152
153// Ancestor returns the ancestor block node at the provided height by following
154// the chain backwards from this node.  The returned block will be nil when a
155// height is requested that is after the height of the passed node or is less
156// than zero.
157//
158// This function is safe for concurrent access.
159func (node *blockNode) Ancestor(height int32) *blockNode {
160	if height < 0 || height > node.height {
161		return nil
162	}
163
164	n := node
165	for ; n != nil && n.height != height; n = n.parent {
166		// Intentionally left blank
167	}
168
169	return n
170}
171
172// RelativeAncestor returns the ancestor block node a relative 'distance' blocks
173// before this node.  This is equivalent to calling Ancestor with the node's
174// height minus provided distance.
175//
176// This function is safe for concurrent access.
177func (node *blockNode) RelativeAncestor(distance int32) *blockNode {
178	return node.Ancestor(node.height - distance)
179}
180
181// CalcPastMedianTime calculates the median time of the previous few blocks
182// prior to, and including, the block node.
183//
184// This function is safe for concurrent access.
185func (node *blockNode) CalcPastMedianTime() time.Time {
186	// Create a slice of the previous few block timestamps used to calculate
187	// the median per the number defined by the constant medianTimeBlocks.
188	timestamps := make([]int64, medianTimeBlocks)
189	numNodes := 0
190	iterNode := node
191	for i := 0; i < medianTimeBlocks && iterNode != nil; i++ {
192		timestamps[i] = iterNode.timestamp
193		numNodes++
194
195		iterNode = iterNode.parent
196	}
197
198	// Prune the slice to the actual number of available timestamps which
199	// will be fewer than desired near the beginning of the block chain
200	// and sort them.
201	timestamps = timestamps[:numNodes]
202	sort.Sort(timeSorter(timestamps))
203
204	// NOTE: The consensus rules incorrectly calculate the median for even
205	// numbers of blocks.  A true median averages the middle two elements
206	// for a set with an even number of elements in it.   Since the constant
207	// for the previous number of blocks to be used is odd, this is only an
208	// issue for a few blocks near the beginning of the chain.  I suspect
209	// this is an optimization even though the result is slightly wrong for
210	// a few of the first blocks since after the first few blocks, there
211	// will always be an odd number of blocks in the set per the constant.
212	//
213	// This code follows suit to ensure the same rules are used, however, be
214	// aware that should the medianTimeBlocks constant ever be changed to an
215	// even number, this code will be wrong.
216	medianTimestamp := timestamps[numNodes/2]
217	return time.Unix(medianTimestamp, 0)
218}
219
220// blockIndex provides facilities for keeping track of an in-memory index of the
221// block chain.  Although the name block chain suggests a single chain of
222// blocks, it is actually a tree-shaped structure where any node can have
223// multiple children.  However, there can only be one active branch which does
224// indeed form a chain from the tip all the way back to the genesis block.
225type blockIndex struct {
226	// The following fields are set when the instance is created and can't
227	// be changed afterwards, so there is no need to protect them with a
228	// separate mutex.
229	db          database.DB
230	chainParams *chaincfg.Params
231
232	sync.RWMutex
233	index map[chainhash.Hash]*blockNode
234	dirty map[*blockNode]struct{}
235}
236
237// newBlockIndex returns a new empty instance of a block index.  The index will
238// be dynamically populated as block nodes are loaded from the database and
239// manually added.
240func newBlockIndex(db database.DB, chainParams *chaincfg.Params) *blockIndex {
241	return &blockIndex{
242		db:          db,
243		chainParams: chainParams,
244		index:       make(map[chainhash.Hash]*blockNode),
245		dirty:       make(map[*blockNode]struct{}),
246	}
247}
248
249// HaveBlock returns whether or not the block index contains the provided hash.
250//
251// This function is safe for concurrent access.
252func (bi *blockIndex) HaveBlock(hash *chainhash.Hash) bool {
253	bi.RLock()
254	_, hasBlock := bi.index[*hash]
255	bi.RUnlock()
256	return hasBlock
257}
258
259// LookupNode returns the block node identified by the provided hash.  It will
260// return nil if there is no entry for the hash.
261//
262// This function is safe for concurrent access.
263func (bi *blockIndex) LookupNode(hash *chainhash.Hash) *blockNode {
264	bi.RLock()
265	node := bi.index[*hash]
266	bi.RUnlock()
267	return node
268}
269
270// AddNode adds the provided node to the block index and marks it as dirty.
271// Duplicate entries are not checked so it is up to caller to avoid adding them.
272//
273// This function is safe for concurrent access.
274func (bi *blockIndex) AddNode(node *blockNode) {
275	bi.Lock()
276	bi.addNode(node)
277	bi.dirty[node] = struct{}{}
278	bi.Unlock()
279}
280
281// addNode adds the provided node to the block index, but does not mark it as
282// dirty. This can be used while initializing the block index.
283//
284// This function is NOT safe for concurrent access.
285func (bi *blockIndex) addNode(node *blockNode) {
286	bi.index[node.hash] = node
287}
288
289// NodeStatus provides concurrent-safe access to the status field of a node.
290//
291// This function is safe for concurrent access.
292func (bi *blockIndex) NodeStatus(node *blockNode) blockStatus {
293	bi.RLock()
294	status := node.status
295	bi.RUnlock()
296	return status
297}
298
299// SetStatusFlags flips the provided status flags on the block node to on,
300// regardless of whether they were on or off previously. This does not unset any
301// flags currently on.
302//
303// This function is safe for concurrent access.
304func (bi *blockIndex) SetStatusFlags(node *blockNode, flags blockStatus) {
305	bi.Lock()
306	node.status |= flags
307	bi.dirty[node] = struct{}{}
308	bi.Unlock()
309}
310
311// UnsetStatusFlags flips the provided status flags on the block node to off,
312// regardless of whether they were on or off previously.
313//
314// This function is safe for concurrent access.
315func (bi *blockIndex) UnsetStatusFlags(node *blockNode, flags blockStatus) {
316	bi.Lock()
317	node.status &^= flags
318	bi.dirty[node] = struct{}{}
319	bi.Unlock()
320}
321
322// flushToDB writes all dirty block nodes to the database. If all writes
323// succeed, this clears the dirty set.
324func (bi *blockIndex) flushToDB() error {
325	bi.Lock()
326	if len(bi.dirty) == 0 {
327		bi.Unlock()
328		return nil
329	}
330
331	err := bi.db.Update(func(dbTx database.Tx) error {
332		for node := range bi.dirty {
333			err := dbStoreBlockNode(dbTx, node)
334			if err != nil {
335				return err
336			}
337		}
338		return nil
339	})
340
341	// If write was successful, clear the dirty set.
342	if err == nil {
343		bi.dirty = make(map[*blockNode]struct{})
344	}
345
346	bi.Unlock()
347	return err
348}
349