diff --git a/blockchain/chain.go b/blockchain/chain.go index 2b286f7a..70f1b7ea 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2016 The btcsuite developers +// Copyright (c) 2013-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -62,7 +62,7 @@ type blockNode struct { // Some fields from block headers to aid in best chain selection. version int32 bits uint32 - timestamp time.Time + timestamp int64 } // newBlockNode returns a new block node for the given block header. It is @@ -81,7 +81,7 @@ func newBlockNode(blockHeader *wire.BlockHeader, blockHash *chainhash.Hash, heig height: height, version: blockHeader.Version, bits: blockHeader.Bits, - timestamp: blockHeader.Timestamp, + timestamp: blockHeader.Timestamp.Unix(), } return &node } @@ -666,7 +666,7 @@ func (b *BlockChain) calcPastMedianTime(startNode *blockNode) (time.Time, error) // Create a slice of the previous few block timestamps used to calculate // the median per the number defined by the constant medianTimeBlocks. - timestamps := make([]time.Time, medianTimeBlocks) + timestamps := make([]int64, medianTimeBlocks) numNodes := 0 iterNode := startNode for i := 0; i < medianTimeBlocks && iterNode != nil; i++ { @@ -705,7 +705,7 @@ func (b *BlockChain) calcPastMedianTime(startNode *blockNode) (time.Time, error) // 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 medianTimestamp, nil + return time.Unix(medianTimestamp, 0), nil } // CalcPastMedianTime calculates the median time of the previous few blocks @@ -1581,8 +1581,8 @@ func (b *BlockChain) isCurrent() bool { // // The chain appears to be current if none of the checks reported // otherwise. - minus24Hours := b.timeSource.AdjustedTime().Add(-24 * time.Hour) - return !b.bestNode.timestamp.Before(minus24Hours) + minus24Hours := b.timeSource.AdjustedTime().Add(-24 * time.Hour).Unix() + return b.bestNode.timestamp >= minus24Hours } // IsCurrent returns whether or not the chain believes it is current. Several @@ -1716,8 +1716,8 @@ func New(config *Config) (*BlockChain, error) { } params := config.ChainParams - targetTimespan := int64(params.TargetTimespan) - targetTimePerBlock := int64(params.TargetTimePerBlock) + targetTimespan := int64(params.TargetTimespan / time.Second) + targetTimePerBlock := int64(params.TargetTimePerBlock / time.Second) adjustmentFactor := params.RetargetAdjustmentFactor b := BlockChain{ checkpoints: config.Checkpoints, diff --git a/blockchain/chainio.go b/blockchain/chainio.go index e510fd5d..cc9c0303 100644 --- a/blockchain/chainio.go +++ b/blockchain/chainio.go @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2016 The btcsuite developers +// Copyright (c) 2015-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -10,6 +10,7 @@ import ( "fmt" "math/big" "sort" + "time" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" @@ -1092,7 +1093,7 @@ func (b *BlockChain) createChainState() error { numTxns := uint64(len(genesisBlock.MsgBlock().Transactions)) blockSize := uint64(genesisBlock.MsgBlock().SerializeSize()) b.stateSnapshot = newBestState(b.bestNode, blockSize, numTxns, numTxns, - b.bestNode.timestamp) + time.Unix(b.bestNode.timestamp, 0)) // Create the initial the database chain state including creating the // necessary index buckets and inserting the genesis block. diff --git a/blockchain/difficulty.go b/blockchain/difficulty.go index 2b8dd5f5..f6a0689e 100644 --- a/blockchain/difficulty.go +++ b/blockchain/difficulty.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2016 The btcsuite developers +// Copyright (c) 2013-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -158,14 +158,16 @@ func CalcWork(bits uint32) *big.Int { // known good checkpoint. func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 { // Convert types used in the calculations below. - durationVal := int64(duration) + durationVal := int64(duration / time.Second) adjustmentFactor := big.NewInt(b.chainParams.RetargetAdjustmentFactor) // The test network rules allow minimum difficulty blocks after more // than twice the desired amount of time needed to generate a block has // elapsed. if b.chainParams.ReduceMinDifficulty { - if durationVal > int64(b.chainParams.MinDiffReductionTime) { + reductionTime := int64(b.chainParams.MinDiffReductionTime / + time.Second) + if durationVal > reductionTime { return b.chainParams.PowLimitBits } } @@ -243,9 +245,10 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim if b.chainParams.ReduceMinDifficulty { // Return minimum difficulty when more than the desired // amount of time has elapsed without mining a block. - reductionTime := b.chainParams.MinDiffReductionTime - allowMinTime := lastNode.timestamp.Add(reductionTime) - if newBlockTime.After(allowMinTime) { + reductionTime := int64(b.chainParams.MinDiffReductionTime / + time.Second) + allowMinTime := lastNode.timestamp + reductionTime + if newBlockTime.Unix() > allowMinTime { return b.chainParams.PowLimitBits, nil } @@ -286,7 +289,7 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim // Limit the amount of adjustment that can occur to the previous // difficulty. - actualTimespan := lastNode.timestamp.UnixNano() - firstNode.timestamp.UnixNano() + actualTimespan := lastNode.timestamp - firstNode.timestamp adjustedTimespan := actualTimespan if actualTimespan < b.minRetargetTimespan { adjustedTimespan = b.minRetargetTimespan @@ -301,7 +304,8 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim // result. oldTarget := CompactToBig(lastNode.bits) newTarget := new(big.Int).Mul(oldTarget, big.NewInt(adjustedTimespan)) - newTarget.Div(newTarget, big.NewInt(int64(b.chainParams.TargetTimespan))) + targetTimeSpan := int64(b.chainParams.TargetTimespan / time.Second) + newTarget.Div(newTarget, big.NewInt(targetTimeSpan)) // Limit new value to the proof of work limit. if newTarget.Cmp(b.chainParams.PowLimit) > 0 { @@ -317,7 +321,8 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim log.Debugf("Old target %08x (%064x)", lastNode.bits, oldTarget) log.Debugf("New target %08x (%064x)", newTargetBits, CompactToBig(newTargetBits)) log.Debugf("Actual timespan %v, adjusted timespan %v, target timespan %v", - time.Duration(actualTimespan), time.Duration(adjustedTimespan), + time.Duration(actualTimespan)*time.Second, + time.Duration(adjustedTimespan)*time.Second, b.chainParams.TargetTimespan) return newTargetBits, nil diff --git a/blockchain/internal_test.go b/blockchain/internal_test.go index 1508b4dd..e7432adb 100644 --- a/blockchain/internal_test.go +++ b/blockchain/internal_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2016 The btcsuite developers +// Copyright (c) 2013-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -14,7 +14,6 @@ package blockchain import ( "sort" - "time" ) // TstSetCoinbaseMaturity makes the ability to set the coinbase maturity @@ -25,7 +24,7 @@ func (b *BlockChain) TstSetCoinbaseMaturity(maturity uint16) { // TstTimeSorter makes the internal timeSorter type available to the test // package. -func TstTimeSorter(times []time.Time) sort.Interface { +func TstTimeSorter(times []int64) sort.Interface { return timeSorter(times) } diff --git a/blockchain/timesorter.go b/blockchain/timesorter.go index 516fe4fd..d0288e1d 100644 --- a/blockchain/timesorter.go +++ b/blockchain/timesorter.go @@ -1,16 +1,12 @@ -// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2013-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. package blockchain -import ( - "time" -) - // timeSorter implements sort.Interface to allow a slice of timestamps to // be sorted. -type timeSorter []time.Time +type timeSorter []int64 // Len returns the number of timestamps in the slice. It is part of the // sort.Interface implementation. @@ -27,5 +23,5 @@ func (s timeSorter) Swap(i, j int) { // Less returns whether the timstamp with index i should sort before the // timestamp with index j. It is part of the sort.Interface implementation. func (s timeSorter) Less(i, j int) bool { - return s[i].Before(s[j]) + return s[i] < s[j] } diff --git a/blockchain/timesorter_test.go b/blockchain/timesorter_test.go index ca1b4afb..e1516557 100644 --- a/blockchain/timesorter_test.go +++ b/blockchain/timesorter_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2013-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -8,7 +8,6 @@ import ( "reflect" "sort" "testing" - "time" "github.com/btcsuite/btcd/blockchain" ) @@ -16,31 +15,29 @@ import ( // TestTimeSorter tests the timeSorter implementation. func TestTimeSorter(t *testing.T) { tests := []struct { - in []time.Time - want []time.Time + in []int64 + want []int64 }{ { - in: []time.Time{ - time.Unix(1351228575, 0), // Fri Oct 26 05:16:15 UTC 2012 (Block #205000) - time.Unix(1351228575, 1), // Fri Oct 26 05:16:15 UTC 2012 (+1 nanosecond) - time.Unix(1348310759, 0), // Sat Sep 22 10:45:59 UTC 2012 (Block #200000) - time.Unix(1305758502, 0), // Wed May 18 22:41:42 UTC 2011 (Block #125000) - time.Unix(1347777156, 0), // Sun Sep 16 06:32:36 UTC 2012 (Block #199000) - time.Unix(1349492104, 0), // Sat Oct 6 02:55:04 UTC 2012 (Block #202000) + in: []int64{ + 1351228575, // Fri Oct 26 05:16:15 UTC 2012 (Block #205000) + 1348310759, // Sat Sep 22 10:45:59 UTC 2012 (Block #200000) + 1305758502, // Wed May 18 22:41:42 UTC 2011 (Block #125000) + 1347777156, // Sun Sep 16 06:32:36 UTC 2012 (Block #199000) + 1349492104, // Sat Oct 6 02:55:04 UTC 2012 (Block #202000) }, - want: []time.Time{ - time.Unix(1305758502, 0), // Wed May 18 22:41:42 UTC 2011 (Block #125000) - time.Unix(1347777156, 0), // Sun Sep 16 06:32:36 UTC 2012 (Block #199000) - time.Unix(1348310759, 0), // Sat Sep 22 10:45:59 UTC 2012 (Block #200000) - time.Unix(1349492104, 0), // Sat Oct 6 02:55:04 UTC 2012 (Block #202000) - time.Unix(1351228575, 0), // Fri Oct 26 05:16:15 UTC 2012 (Block #205000) - time.Unix(1351228575, 1), // Fri Oct 26 05:16:15 UTC 2012 (+1 nanosecond) + want: []int64{ + 1305758502, // Wed May 18 22:41:42 UTC 2011 (Block #125000) + 1347777156, // Sun Sep 16 06:32:36 UTC 2012 (Block #199000) + 1348310759, // Sat Sep 22 10:45:59 UTC 2012 (Block #200000) + 1349492104, // Sat Oct 6 02:55:04 UTC 2012 (Block #202000) + 1351228575, // Fri Oct 26 05:16:15 UTC 2012 (Block #205000) }, }, } for i, test := range tests { - result := make([]time.Time, len(test.in)) + result := make([]int64, len(test.in)) copy(result, test.in) sort.Sort(blockchain.TstTimeSorter(result)) if !reflect.DeepEqual(result, test.want) { diff --git a/blockchain/validate.go b/blockchain/validate.go index 48451787..822c1791 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2016 The btcsuite developers +// Copyright (c) 2013-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -1011,7 +1011,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block, vi // "standard" type. The rules for this BIP only apply to transactions // after the timestamp defined by txscript.Bip16Activation. See // https://en.bitcoin.it/wiki/BIP_0016 for more details. - enforceBIP0016 := node.timestamp.After(txscript.Bip16Activation) + enforceBIP0016 := node.timestamp >= txscript.Bip16Activation.Unix() // The number of signature operations must be less than the maximum // allowed per block. Note that the preliminary sanity checks on a