+++ /dev/null
-package wire
-
-import (
- "bytes"
- "io"
- "time"
-
- "github.com/blockchain/rpc/chainhash"
-)
-
-// MaxBlockHeaderPayload is the maximum number of bytes a block header can be.
-// Version 4 bytes + Timestamp 4 bytes + Bits 4 bytes + Nonce 4 bytes +
-// PrevBlock and MerkleRoot hashes.
-const MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 2)
-
-type uint32Time time.Time
-
-// BlockHeader defines information about a block and is used in the bitcoin
-// block (MsgBlock) and headers (MsgHeaders) messages.
-type BlockHeader struct {
- // Version of the block. This is not the same as the protocol version.
- Version int32
-
- // Hash of the previous block in the block chain.
- PrevBlock chainhash.Hash
-
- // Merkle tree reference to hash of all transactions for the block.
- MerkleRoot chainhash.Hash
-
- // Time the block was created. This is, unfortunately, encoded as a
- // uint32 on the wire and therefore is limited to 2106.
- Timestamp time.Time
-
- // Difficulty target for the block.
- Bits uint32
-
- // Nonce used to generate the block.
- Nonce uint32
-}
-
-// blockHeaderLen is a constant that represents the number of bytes for a block
-// header.
-const blockHeaderLen = 80
-
-// BlockHash computes the block identifier hash for the given block header.
-func (h *BlockHeader) BlockHash() chainhash.Hash {
- // Encode the header and double sha256 everything prior to the number of
- // transactions. Ignore the error returns since there is no way the
- // encode could fail except being out of memory which would cause a
- // run-time panic.
- buf := bytes.NewBuffer(make([]byte, 0, MaxBlockHeaderPayload))
- _ = writeBlockHeader(buf, 0, h)
-
- return chainhash.DoubleHashH(buf.Bytes())
-}
-
-// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
-// This is part of the Message interface implementation.
-// See Deserialize for decoding block headers stored to disk, such as in a
-// database, as opposed to decoding block headers from the wire.
-func (h *BlockHeader) BtcDecode(r io.Reader, pver uint32) error {
- return readBlockHeader(r, pver, h)
-}
-
-// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
-// This is part of the Message interface implementation.
-// See Serialize for encoding block headers to be stored to disk, such as in a
-// database, as opposed to encoding block headers for the wire.
-func (h *BlockHeader) BtcEncode(w io.Writer, pver uint32) error {
- return writeBlockHeader(w, pver, h)
-}
-
-// Deserialize decodes a block header from r into the receiver using a format
-// that is suitable for long-term storage such as a database while respecting
-// the Version field.
-func (h *BlockHeader) Deserialize(r io.Reader) error {
- // At the current time, there is no difference between the wire encoding
- // at protocol version 0 and the stable long-term storage format. As
- // a result, make use of readBlockHeader.
- return readBlockHeader(r, 0, h)
-}
-
-// Serialize encodes a block header from r into the receiver using a format
-// that is suitable for long-term storage such as a database while respecting
-// the Version field.
-func (h *BlockHeader) Serialize(w io.Writer) error {
- // At the current time, there is no difference between the wire encoding
- // at protocol version 0 and the stable long-term storage format. As
- // a result, make use of writeBlockHeader.
- return writeBlockHeader(w, 0, h)
-}
-
-// NewBlockHeader returns a new BlockHeader using the provided version, previous
-// block hash, merkle root hash, difficulty bits, and nonce used to generate the
-// block with defaults for the remaining fields.
-func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash,
- bits uint32, nonce uint32) *BlockHeader {
-
- // Limit the timestamp to one second precision since the protocol
- // doesn't support better.
- return &BlockHeader{
- Version: version,
- PrevBlock: *prevHash,
- MerkleRoot: *merkleRootHash,
- Timestamp: time.Unix(time.Now().Unix(), 0),
- Bits: bits,
- Nonce: nonce,
- }
-}
-
-// readBlockHeader reads a bitcoin block header from r. See Deserialize for
-// decoding block headers stored to disk, such as in a database, as opposed to
-// decoding from the wire.
-func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error {
- return readElements(r, &bh.Version, &bh.PrevBlock, &bh.MerkleRoot,
- (*uint32Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce)
-}
-// writeBlockHeader writes a bitcoin block header to w. See Serialize for
-// encoding block headers to be stored to disk, such as in a database, as
-// opposed to encoding for the wire.
-func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error {
- sec := uint32(bh.Timestamp.Unix())
- return writeElements(w, bh.Version, &bh.PrevBlock, &bh.MerkleRoot,
- sec, bh.Bits, bh.Nonce)
-}
-
-func writeElements(w io.Writer, elements ...interface{}) error {
- /*
- for _, element := range elements {
- err := writeElement(w, element)
- if err != nil {
- return err
- }
- }
-*/
- return nil
-}
-
-func readElements(r io.Reader, elements ...interface{}) error {
-/*
- for _, element := range elements {
- err := readElement(r, element)
- if err != nil {
- return err
- }
- }
-*/
- return nil
-}
+++ /dev/null
-// Copyright (c) 2013-2017 The btcsuite developers\r
-// Use of this source code is governed by an ISC\r
-// license that can be found in the LICENSE file.\r
-\r
-package wire\r
-\r
-import (\r
- "math/big"\r
- //"time"\r
-\r
- "github.com/blockchain/rpc/chainhash"\r
-\r
-)\r
-\r
-var (\r
- // bigOne is 1 represented as a big.Int. It is defined here to avoid\r
- // the overhead of creating it multiple times.\r
- bigOne = big.NewInt(1)\r
-\r
- // oneLsh256 is 1 shifted left 256 bits. It is defined here to avoid\r
- // the overhead of creating it multiple times.\r
- oneLsh256 = new(big.Int).Lsh(bigOne, 256)\r
-)\r
-\r
-// HashToBig converts a chainhash.Hash into a big.Int that can be used to\r
-// perform math comparisons.\r
-func HashToBig(hash *chainhash.Hash) *big.Int {\r
- // A Hash is in little-endian, but the big package wants the bytes in\r
- // big-endian, so reverse them.\r
- buf := *hash\r
- blen := len(buf)\r
- for i := 0; i < blen/2; i++ {\r
- buf[i], buf[blen-1-i] = buf[blen-1-i], buf[i]\r
- }\r
-\r
- return new(big.Int).SetBytes(buf[:])\r
-}\r
-/*\r
-// CompactToBig converts a compact representation of a whole number N to an\r
-// unsigned 32-bit number. The representation is similar to IEEE754 floating\r
-// point numbers.\r
-//\r
-// Like IEEE754 floating point, there are three basic components: the sign,\r
-// the exponent, and the mantissa. They are broken out as follows:\r
-//\r
-// * the most significant 8 bits represent the unsigned base 256 exponent\r
-// * bit 23 (the 24th bit) represents the sign bit\r
-// * the least significant 23 bits represent the mantissa\r
-//\r
-// -------------------------------------------------\r
-// | Exponent | Sign | Mantissa |\r
-// -------------------------------------------------\r
-// | 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] |\r
-// -------------------------------------------------\r
-//\r
-// The formula to calculate N is:\r
-// N = (-1^sign) * mantissa * 256^(exponent-3)\r
-//\r
-// This compact form is only used in bitcoin to encode unsigned 256-bit numbers\r
-// which represent difficulty targets, thus there really is not a need for a\r
-// sign bit, but it is implemented here to stay consistent with bitcoind.\r
-func CompactToBig(compact uint32) *big.Int {\r
- // Extract the mantissa, sign bit, and exponent.\r
- mantissa := compact & 0x007fffff\r
- isNegative := compact&0x00800000 != 0\r
- exponent := uint(compact >> 24)\r
-\r
- // Since the base for the exponent is 256, the exponent can be treated\r
- // as the number of bytes to represent the full 256-bit number. So,\r
- // treat the exponent as the number of bytes and shift the mantissa\r
- // right or left accordingly. This is equivalent to:\r
- // N = mantissa * 256^(exponent-3)\r
- var bn *big.Int\r
- if exponent <= 3 {\r
- mantissa >>= 8 * (3 - exponent)\r
- bn = big.NewInt(int64(mantissa))\r
- } else {\r
- bn = big.NewInt(int64(mantissa))\r
- bn.Lsh(bn, 8*(exponent-3))\r
- }\r
-\r
- // Make it negative if the sign bit is set.\r
- if isNegative {\r
- bn = bn.Neg(bn)\r
- }\r
-\r
- return bn\r
-}\r
-\r
-// BigToCompact converts a whole number N to a compact representation using\r
-// an unsigned 32-bit number. The compact representation only provides 23 bits\r
-// of precision, so values larger than (2^23 - 1) only encode the most\r
-// significant digits of the number. See CompactToBig for details.\r
-func BigToCompact(n *big.Int) uint32 {\r
- // No need to do any work if it's zero.\r
- if n.Sign() == 0 {\r
- return 0\r
- }\r
-\r
- // Since the base for the exponent is 256, the exponent can be treated\r
- // as the number of bytes. So, shift the number right or left\r
- // accordingly. This is equivalent to:\r
- // mantissa = mantissa / 256^(exponent-3)\r
- var mantissa uint32\r
- exponent := uint(len(n.Bytes()))\r
- if exponent <= 3 {\r
- mantissa = uint32(n.Bits()[0])\r
- mantissa <<= 8 * (3 - exponent)\r
- } else {\r
- // Use a copy to avoid modifying the caller's original number.\r
- tn := new(big.Int).Set(n)\r
- mantissa = uint32(tn.Rsh(tn, 8*(exponent-3)).Bits()[0])\r
- }\r
-\r
- // When the mantissa already has the sign bit set, the number is too\r
- // large to fit into the available 23-bits, so divide the number by 256\r
- // and increment the exponent accordingly.\r
- if mantissa&0x00800000 != 0 {\r
- mantissa >>= 8\r
- exponent++\r
- }\r
-\r
- // Pack the exponent, sign bit, and mantissa into an unsigned 32-bit\r
- // int and return it.\r
- compact := uint32(exponent<<24) | mantissa\r
- if n.Sign() < 0 {\r
- compact |= 0x00800000\r
- }\r
- return compact\r
-}\r
-\r
-// CalcWork calculates a work value from difficulty bits. Bitcoin increases\r
-// the difficulty for generating a block by decreasing the value which the\r
-// generated hash must be less than. This difficulty target is stored in each\r
-// block header using a compact representation as described in the documentation\r
-// for CompactToBig. The main chain is selected by choosing the chain that has\r
-// the most proof of work (highest difficulty). Since a lower target difficulty\r
-// value equates to higher actual difficulty, the work value which will be\r
-// accumulated must be the inverse of the difficulty. Also, in order to avoid\r
-// potential division by zero and really small floating point numbers, the\r
-// result adds 1 to the denominator and multiplies the numerator by 2^256.\r
-func CalcWork(bits uint32) *big.Int {\r
- // Return a work value of zero if the passed difficulty bits represent\r
- // a negative number. Note this should not happen in practice with valid\r
- // blocks, but an invalid block could trigger it.\r
- difficultyNum := CompactToBig(bits)\r
- if difficultyNum.Sign() <= 0 {\r
- return big.NewInt(0)\r
- }\r
-\r
- // (1 << 256) / (difficultyNum + 1)\r
- denominator := new(big.Int).Add(difficultyNum, bigOne)\r
- return new(big.Int).Div(oneLsh256, denominator)\r
-}\r
-\r
-// calcEasiestDifficulty calculates the easiest possible difficulty that a block\r
-// can have given starting difficulty bits and a duration. It is mainly used to\r
-// verify that claimed proof of work by a block is sane as compared to a\r
-// known good checkpoint.\r
-func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 {\r
- // Convert types used in the calculations below.\r
- durationVal := int64(duration / time.Second)\r
- adjustmentFactor := big.NewInt(b.chainParams.RetargetAdjustmentFactor)\r
-\r
- // The test network rules allow minimum difficulty blocks after more\r
- // than twice the desired amount of time needed to generate a block has\r
- // elapsed.\r
- if b.chainParams.ReduceMinDifficulty {\r
- reductionTime := int64(b.chainParams.MinDiffReductionTime /\r
- time.Second)\r
- if durationVal > reductionTime {\r
- return b.chainParams.PowLimitBits\r
- }\r
- }\r
-\r
- // Since easier difficulty equates to higher numbers, the easiest\r
- // difficulty for a given duration is the largest value possible given\r
- // the number of retargets for the duration and starting difficulty\r
- // multiplied by the max adjustment factor.\r
- newTarget := CompactToBig(bits)\r
- for durationVal > 0 && newTarget.Cmp(b.chainParams.PowLimit) < 0 {\r
- newTarget.Mul(newTarget, adjustmentFactor)\r
- durationVal -= b.maxRetargetTimespan\r
- }\r
-\r
- // Limit new value to the proof of work limit.\r
- if newTarget.Cmp(b.chainParams.PowLimit) > 0 {\r
- newTarget.Set(b.chainParams.PowLimit)\r
- }\r
-\r
- return BigToCompact(newTarget)\r
-}\r
-\r
-// findPrevTestNetDifficulty returns the difficulty of the previous block which\r
-// did not have the special testnet minimum difficulty rule applied.\r
-//\r
-// This function MUST be called with the chain state lock held (for writes).\r
-func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, error) {\r
- // Search backwards through the chain for the last block without\r
- // the special rule applied.\r
- iterNode := startNode\r
- for iterNode != nil && iterNode.height%b.blocksPerRetarget != 0 &&\r
- iterNode.bits == b.chainParams.PowLimitBits {\r
-\r
- // Get the previous block node. This function is used over\r
- // simply accessing iterNode.parent directly as it will\r
- // dynamically create previous block nodes as needed. This\r
- // helps allow only the pieces of the chain that are needed\r
- // to remain in memory.\r
- var err error\r
- iterNode, err = b.index.PrevNodeFromNode(iterNode)\r
- if err != nil {\r
- log.Errorf("PrevNodeFromNode: %v", err)\r
- return 0, err\r
- }\r
- }\r
-\r
- // Return the found difficulty or the minimum difficulty if no\r
- // appropriate block was found.\r
- lastBits := b.chainParams.PowLimitBits\r
- if iterNode != nil {\r
- lastBits = iterNode.bits\r
- }\r
- return lastBits, nil\r
-}\r
-\r
-// calcNextRequiredDifficulty calculates the required difficulty for the block\r
-// after the passed previous block node based on the difficulty retarget rules.\r
-// This function differs from the exported CalcNextRequiredDifficulty in that\r
-// the exported version uses the current best chain as the previous block node\r
-// while this function accepts any block node.\r
-//\r
-// This function MUST be called with the chain state lock held (for writes).\r
-func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTime time.Time) (uint32, error) {\r
- // Genesis block.\r
- if lastNode == nil {\r
- return b.chainParams.PowLimitBits, nil\r
- }\r
-\r
- // Return the previous block's difficulty requirements if this block\r
- // is not at a difficulty retarget interval.\r
- if (lastNode.height+1)%b.blocksPerRetarget != 0 {\r
- // For networks that support it, allow special reduction of the\r
- // required difficulty once too much time has elapsed without\r
- // mining a block.\r
- if b.chainParams.ReduceMinDifficulty {\r
- // Return minimum difficulty when more than the desired\r
- // amount of time has elapsed without mining a block.\r
- reductionTime := int64(b.chainParams.MinDiffReductionTime /\r
- time.Second)\r
- allowMinTime := lastNode.timestamp + reductionTime\r
- if newBlockTime.Unix() > allowMinTime {\r
- return b.chainParams.PowLimitBits, nil\r
- }\r
-\r
- // The block was mined within the desired timeframe, so\r
- // return the difficulty for the last block which did\r
- // not have the special minimum difficulty rule applied.\r
- prevBits, err := b.findPrevTestNetDifficulty(lastNode)\r
- if err != nil {\r
- return 0, err\r
- }\r
- return prevBits, nil\r
- }\r
-\r
- // For the main network (or any unrecognized networks), simply\r
- // return the previous block's difficulty requirements.\r
- return lastNode.bits, nil\r
- }\r
-\r
- // Get the block node at the previous retarget (targetTimespan days\r
- // worth of blocks).\r
- firstNode := lastNode\r
- for i := int32(0); i < b.blocksPerRetarget-1 && firstNode != nil; i++ {\r
- // Get the previous block node. This function is used over\r
- // simply accessing firstNode.parent directly as it will\r
- // dynamically create previous block nodes as needed. This\r
- // helps allow only the pieces of the chain that are needed\r
- // to remain in memory.\r
- var err error\r
- firstNode, err = b.index.PrevNodeFromNode(firstNode)\r
- if err != nil {\r
- return 0, err\r
- }\r
- }\r
-\r
- if firstNode == nil {\r
- return 0, AssertError("unable to obtain previous retarget block")\r
- }\r
-\r
- // Limit the amount of adjustment that can occur to the previous\r
- // difficulty.\r
- actualTimespan := lastNode.timestamp - firstNode.timestamp\r
- adjustedTimespan := actualTimespan\r
- if actualTimespan < b.minRetargetTimespan {\r
- adjustedTimespan = b.minRetargetTimespan\r
- } else if actualTimespan > b.maxRetargetTimespan {\r
- adjustedTimespan = b.maxRetargetTimespan\r
- }\r
-\r
- // Calculate new target difficulty as:\r
- // currentDifficulty * (adjustedTimespan / targetTimespan)\r
- // The result uses integer division which means it will be slightly\r
- // rounded down. Bitcoind also uses integer division to calculate this\r
- // result.\r
- oldTarget := CompactToBig(lastNode.bits)\r
- newTarget := new(big.Int).Mul(oldTarget, big.NewInt(adjustedTimespan))\r
- targetTimeSpan := int64(b.chainParams.TargetTimespan / time.Second)\r
- newTarget.Div(newTarget, big.NewInt(targetTimeSpan))\r
-\r
- // Limit new value to the proof of work limit.\r
- if newTarget.Cmp(b.chainParams.PowLimit) > 0 {\r
- newTarget.Set(b.chainParams.PowLimit)\r
- }\r
-\r
- // Log new target difficulty and return it. The new target logging is\r
- // intentionally converting the bits back to a number instead of using\r
- // newTarget since conversion to the compact representation loses\r
- // precision.\r
- newTargetBits := BigToCompact(newTarget)\r
- log.Debugf("Difficulty retarget at block height %d", lastNode.height+1)\r
- log.Debugf("Old target %08x (%064x)", lastNode.bits, oldTarget)\r
- log.Debugf("New target %08x (%064x)", newTargetBits, CompactToBig(newTargetBits))\r
- log.Debugf("Actual timespan %v, adjusted timespan %v, target timespan %v",\r
- time.Duration(actualTimespan)*time.Second,\r
- time.Duration(adjustedTimespan)*time.Second,\r
- b.chainParams.TargetTimespan)\r
-\r
- return newTargetBits, nil\r
-}\r
-\r
-// CalcNextRequiredDifficulty calculates the required difficulty for the block\r
-// after the end of the current best chain based on the difficulty retarget\r
-// rules.\r
-//\r
-// This function is safe for concurrent access.\r
-func (b *BlockChain) CalcNextRequiredDifficulty(timestamp time.Time) (uint32, error) {\r
- b.chainLock.Lock()\r
- difficulty, err := b.calcNextRequiredDifficulty(b.bestNode, timestamp)\r
- b.chainLock.Unlock()\r
- return difficulty, err\r
-}\r
-*/\r