mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-20 10:13:26 +01:00
refactor numbers in BlockHeader and Block
This commit is contained in:
parent
e6fff6a7c8
commit
efc3d41437
@ -1,6 +1,7 @@
|
||||
package org.bitcoins.core.protocol.blockchain
|
||||
|
||||
import org.bitcoins.core.crypto.DoubleSha256Digest
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.NetworkElement
|
||||
import org.bitcoins.core.serializers.blockchain.RawBlockHeaderSerializer
|
||||
import org.bitcoins.core.util.{BitcoinSUtil, CryptoUtil, BitcoinSLogger, Factory}
|
||||
@ -29,7 +30,7 @@ sealed trait BlockHeader extends NetworkElement with BitcoinSLogger {
|
||||
*
|
||||
* @return the version number for this block
|
||||
*/
|
||||
def version : Long
|
||||
def version : UInt32
|
||||
|
||||
|
||||
/**
|
||||
@ -59,7 +60,7 @@ sealed trait BlockHeader extends NetworkElement with BitcoinSLogger {
|
||||
*
|
||||
* @return the time when the miner started solving the block
|
||||
*/
|
||||
def time : Long
|
||||
def time : UInt32
|
||||
|
||||
/**
|
||||
* An encoded version of the target threshold this block’s header hash must be less than or equal to.
|
||||
@ -68,7 +69,7 @@ sealed trait BlockHeader extends NetworkElement with BitcoinSLogger {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def nBits : Long
|
||||
def nBits : UInt32
|
||||
|
||||
/**
|
||||
* An arbitrary number miners change to modify the header hash in order to produce a hash below the target threshold.
|
||||
@ -77,10 +78,11 @@ sealed trait BlockHeader extends NetworkElement with BitcoinSLogger {
|
||||
*
|
||||
* @return the nonce used to try and solve a block
|
||||
*/
|
||||
def nonce : Long
|
||||
def nonce : UInt32
|
||||
|
||||
/**
|
||||
* Returns the block's hash
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def hash : DoubleSha256Digest = CryptoUtil.doubleSHA256(bytes)
|
||||
@ -95,11 +97,11 @@ sealed trait BlockHeader extends NetworkElement with BitcoinSLogger {
|
||||
*/
|
||||
object BlockHeader extends Factory[BlockHeader] {
|
||||
|
||||
private sealed case class BlockHeaderImpl(version : Long, previousBlockHash : DoubleSha256Digest,
|
||||
merkleRootHash : DoubleSha256Digest, time : Long, nBits : Long, nonce : Long) extends BlockHeader
|
||||
private sealed case class BlockHeaderImpl(version : UInt32, previousBlockHash : DoubleSha256Digest,
|
||||
merkleRootHash : DoubleSha256Digest, time : UInt32, nBits : UInt32, nonce : UInt32) extends BlockHeader
|
||||
|
||||
def apply(version : Long, previousBlockHash : DoubleSha256Digest, merkleRootHash : DoubleSha256Digest,
|
||||
time : Long, nBits : Long, nonce : Long) : BlockHeader = {
|
||||
def apply(version : UInt32, previousBlockHash : DoubleSha256Digest, merkleRootHash : DoubleSha256Digest,
|
||||
time : UInt32, nBits : UInt32, nonce : UInt32) : BlockHeader = {
|
||||
BlockHeaderImpl(version,previousBlockHash,merkleRootHash,time,nBits,nonce)
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ package org.bitcoins.core.protocol.blockchain
|
||||
import org.bitcoins.core.consensus.Merkle
|
||||
import org.bitcoins.core.crypto.DoubleSha256Digest
|
||||
import org.bitcoins.core.currency.{CurrencyUnit, Satoshis}
|
||||
import org.bitcoins.core.number.Int64
|
||||
import org.bitcoins.core.number.{UInt32, Int64}
|
||||
import org.bitcoins.core.protocol.CompactSizeUInt
|
||||
import org.bitcoins.core.protocol.script.{ScriptPubKey, ScriptSignature}
|
||||
import org.bitcoins.core.protocol.transaction.{Transaction, TransactionConstants, TransactionInput, TransactionOutput}
|
||||
@ -71,7 +71,7 @@ sealed trait ChainParams {
|
||||
* @param amount the block reward for the gensis block (50 BTC in Bitcoin)
|
||||
* @return the newly minted genesis block
|
||||
*/
|
||||
def createGenesisBlock(time : Long, nonce : Long, nBits : Long, version : Int, amount : CurrencyUnit) : Block = {
|
||||
def createGenesisBlock(time : UInt32, nonce : UInt32, nBits : UInt32, version : UInt32, amount : CurrencyUnit) : Block = {
|
||||
val timestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"
|
||||
val asm = Seq(BytesToPushOntoStack(65), ScriptConstant("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"), OP_CHECKSIG)
|
||||
val genesisOutputScript = ScriptPubKey.fromAsm(asm)
|
||||
@ -88,8 +88,8 @@ sealed trait ChainParams {
|
||||
* @param amount the block reward for the genesis block (50 BTC in Bitcoin)
|
||||
* @return the newly minted genesis block
|
||||
*/
|
||||
def createGenesisBlock(timestamp : String, scriptPubKey : ScriptPubKey, time : Long, nonce : Long, nBits : Long,
|
||||
version : Int, amount : CurrencyUnit) : Block = {
|
||||
def createGenesisBlock(timestamp : String, scriptPubKey : ScriptPubKey, time : UInt32, nonce : UInt32, nBits : UInt32,
|
||||
version : UInt32, amount : CurrencyUnit) : Block = {
|
||||
|
||||
val timestampHex = timestamp.toCharArray.map(_.toByte)
|
||||
//see https://bitcoin.stackexchange.com/questions/13122/scriptsig-coinbase-structure-of-the-genesis-block
|
||||
@ -115,7 +115,7 @@ object MainNetChainParams extends ChainParams {
|
||||
|
||||
override def networkId = "main"
|
||||
|
||||
override def genesisBlock = createGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, Satoshis(Int64(5000000000L)))
|
||||
override def genesisBlock = createGenesisBlock(UInt32(1231006505), UInt32(2083236893), UInt32(0x1d00ffff), UInt32.one, Satoshis(Int64(5000000000L)))
|
||||
|
||||
override def requireStandardTransaction = true
|
||||
|
||||
@ -138,7 +138,7 @@ object TestNetChainParams extends ChainParams {
|
||||
|
||||
override def networkId = "test"
|
||||
|
||||
override def genesisBlock = createGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, Satoshis(Int64(5000000000L)))
|
||||
override def genesisBlock = createGenesisBlock(UInt32(1296688602), UInt32(414098458), UInt32(0x1d00ffff), UInt32.one, Satoshis(Int64(5000000000L)))
|
||||
|
||||
override def requireStandardTransaction = true
|
||||
|
||||
@ -160,7 +160,7 @@ object TestNetChainParams extends ChainParams {
|
||||
|
||||
object RegTestNetChainParams extends ChainParams {
|
||||
override def networkId = "regtest"
|
||||
override def genesisBlock = createGenesisBlock(1296688602, 2, 0x207fffff, 1, Satoshis(Int64(5000000000L)))
|
||||
override def genesisBlock = createGenesisBlock(UInt32(1296688602), UInt32(2), UInt32(0x207fffff), UInt32.one, Satoshis(Int64(5000000000L)))
|
||||
override def requireStandardTransaction = TestNetChainParams.requireStandardTransaction
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.bitcoins.core.serializers.blockchain
|
||||
|
||||
import org.bitcoins.core.crypto.DoubleSha256Digest
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.blockchain.BlockHeader
|
||||
import org.bitcoins.core.serializers.RawBitcoinSerializer
|
||||
import org.bitcoins.core.util.{CryptoUtil, BitcoinSUtil}
|
||||
@ -22,7 +23,7 @@ trait RawBlockHeaderSerializer extends RawBitcoinSerializer[BlockHeader] {
|
||||
//version first 4 bytes
|
||||
val versionBytes = bytes.slice(0,4)
|
||||
val versionHex = BitcoinSUtil.encodeHex(versionBytes.reverse)
|
||||
val version = java.lang.Long.parseLong(versionHex, 16)
|
||||
val version = UInt32(versionHex)
|
||||
//previous header hash next 32 bytes
|
||||
val prevBlockHashBytes = bytes.slice(4, 36)
|
||||
val prevBlockHash : DoubleSha256Digest = DoubleSha256Digest(prevBlockHashBytes)
|
||||
@ -32,15 +33,15 @@ trait RawBlockHeaderSerializer extends RawBitcoinSerializer[BlockHeader] {
|
||||
//time 4 bytes
|
||||
val timeBytes = bytes.slice(68,72)
|
||||
val timeHex = BitcoinSUtil.encodeHex(timeBytes.reverse)
|
||||
val time = java.lang.Long.parseLong(timeHex, 16)
|
||||
val time = UInt32(timeHex)
|
||||
//nbits 4 bytes
|
||||
val nBitsBytes = bytes.slice(72,76)
|
||||
val nBitsHex = BitcoinSUtil.encodeHex(nBitsBytes.reverse)
|
||||
val nBits = java.lang.Long.parseLong(nBitsHex, 16)
|
||||
val nBits = UInt32(nBitsHex)
|
||||
//nonce 4 bytes
|
||||
val nonceBytes = bytes.slice(76,80)
|
||||
val nonceHex = BitcoinSUtil.encodeHex(nonceBytes.reverse)
|
||||
val nonce = java.lang.Long.parseLong(nonceHex, 16)
|
||||
val nonce = UInt32(nonceHex)
|
||||
BlockHeader(version,prevBlockHash, merkleRoot, time, nBits, nonce)
|
||||
}
|
||||
|
||||
@ -53,16 +54,16 @@ trait RawBlockHeaderSerializer extends RawBitcoinSerializer[BlockHeader] {
|
||||
def write(blockHeader: BlockHeader) : String = {
|
||||
//TODO: By happenstance, flipEndianess function adds a leading '0' if we have hex number less than 10.
|
||||
//We need to explicitly handle this case in our write function in the future.
|
||||
val headerVersion = BitcoinSUtil.flipEndianess(blockHeader.version.toHexString)
|
||||
val headerVersion = BitcoinSUtil.flipEndianess(blockHeader.version.hex)
|
||||
val versionSubPadding = addPrecedingZero(headerVersion)
|
||||
val version = addPadding(8,versionSubPadding)
|
||||
|
||||
val prevHash = blockHeader.previousBlockHash.hex
|
||||
val merkleRoot = blockHeader.merkleRootHash.hex
|
||||
|
||||
val time = addPadding(8,BitcoinSUtil.flipEndianess(blockHeader.time.toHexString))
|
||||
val nBits = addPadding(8,BitcoinSUtil.flipEndianess(blockHeader.nBits.toHexString))
|
||||
val nonce = addPadding(8,BitcoinSUtil.flipEndianess(blockHeader.nonce.toHexString))
|
||||
val time = addPadding(8,BitcoinSUtil.flipEndianess(blockHeader.time.hex))
|
||||
val nBits = addPadding(8,BitcoinSUtil.flipEndianess(blockHeader.nBits.hex))
|
||||
val nonce = addPadding(8,BitcoinSUtil.flipEndianess(blockHeader.nonce.hex))
|
||||
|
||||
version + prevHash + merkleRoot + time + nBits + nonce
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.bitcoins.core.serializers.blockchain
|
||||
|
||||
import org.bitcoins.core.crypto.DoubleSha256Digest
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.util.BitcoinSUtil
|
||||
import org.scalatest.{FlatSpec, MustMatchers}
|
||||
|
||||
@ -23,12 +24,12 @@ class RawBlockHeaderSerializerTest extends FlatSpec with MustMatchers{
|
||||
val hex = version + prevBlockHash + merkleRoot + timeStamp + nBits + nonce
|
||||
"BlockHeader" must "parse genesis block header" in {
|
||||
val blockHeader = RawBlockHeaderSerializer.read(hex)
|
||||
blockHeader.version must be (java.lang.Long.parseLong(BitcoinSUtil.flipEndianess(version), 16))
|
||||
blockHeader.version must be (UInt32(BitcoinSUtil.flipEndianess(version)))
|
||||
blockHeader.previousBlockHash must be (DoubleSha256Digest(prevBlockHash))
|
||||
blockHeader.merkleRootHash must be (DoubleSha256Digest(merkleRoot))
|
||||
blockHeader.time must be (java.lang.Long.parseLong(BitcoinSUtil.flipEndianess(timeStamp), 16))
|
||||
blockHeader.nBits must be (java.lang.Long.parseLong(BitcoinSUtil.flipEndianess(nBits), 16))
|
||||
blockHeader.nonce must be (java.lang.Long.parseLong(BitcoinSUtil.flipEndianess(nonce), 16))
|
||||
blockHeader.time must be (UInt32(BitcoinSUtil.flipEndianess(timeStamp)))
|
||||
blockHeader.nBits must be (UInt32(BitcoinSUtil.flipEndianess(nBits)))
|
||||
blockHeader.nonce must be (UInt32(BitcoinSUtil.flipEndianess(nonce)))
|
||||
}
|
||||
|
||||
it must "properly hash genesis block header to return genesis block hash" in {
|
||||
@ -54,11 +55,11 @@ class RawBlockHeaderSerializerTest extends FlatSpec with MustMatchers{
|
||||
val hex2 = version2 + prevBlockHash2 + merkleRoot2 + timeStamp2 + nBits2 + nonce2
|
||||
val hash = "2837af674e81436b09e0c937e94d96fe32e5c872391ba1090000000000000000"
|
||||
val blockHeader = RawBlockHeaderSerializer.read(hex2)
|
||||
blockHeader.version must be (2)
|
||||
blockHeader.version must be (UInt32(2))
|
||||
blockHeader.previousBlockHash must be (DoubleSha256Digest(prevBlockHash2))
|
||||
blockHeader.merkleRootHash must be (DoubleSha256Digest(merkleRoot2))
|
||||
blockHeader.time must be (1415239972)
|
||||
blockHeader.nonce must be (1678286846)
|
||||
blockHeader.time must be (UInt32(1415239972))
|
||||
blockHeader.nonce must be (UInt32(1678286846))
|
||||
blockHeader.hash must be (DoubleSha256Digest(hash))
|
||||
}
|
||||
|
||||
@ -73,12 +74,12 @@ class RawBlockHeaderSerializerTest extends FlatSpec with MustMatchers{
|
||||
val hex = version + prevBlockHash + merkleRoot + timeStamp + nBits + nonce
|
||||
val hash = "c5a764eb61db336edb17be9c49dc07dcae0219bc51a2efe681df9f0000000000"
|
||||
val blockHeader = RawBlockHeaderSerializer.read(hex)
|
||||
blockHeader.version must be (536870912)
|
||||
blockHeader.version must be (UInt32(536870912))
|
||||
blockHeader.previousBlockHash must be (DoubleSha256Digest(prevBlockHash))
|
||||
blockHeader.merkleRootHash must be (DoubleSha256Digest(merkleRoot))
|
||||
blockHeader.time must be (1465247498)
|
||||
blockHeader.nBits must be (486604799)
|
||||
blockHeader.nonce must be (2667504451L)
|
||||
blockHeader.time must be (UInt32(1465247498))
|
||||
blockHeader.nBits must be (UInt32(486604799))
|
||||
blockHeader.nonce must be (UInt32(2667504451L))
|
||||
blockHeader.hash must be (DoubleSha256Digest(hash))
|
||||
RawBlockHeaderSerializer.write(blockHeader) must be (hex)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.bitcoins.core.serializers.blockchain
|
||||
|
||||
import org.bitcoins.core.crypto.DoubleSha256Digest
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.CompactSizeUInt
|
||||
import org.bitcoins.core.protocol.transaction.Transaction
|
||||
import org.bitcoins.core.util.{BitcoinSLogger, BitcoinSUtil}
|
||||
@ -105,11 +106,11 @@ class RawBlockSerializerTest extends FlatSpec with MustMatchers with BitcoinSLog
|
||||
|
||||
val block = RawBlockSerializer.read(hex)
|
||||
block.blockHeader.hash.hex must be ("5f3d49113e7bf838a061a1661c672053deb90891edf3ecfa9e18000000000000")
|
||||
block.blockHeader.version must be (536870912)
|
||||
block.blockHeader.version must be (UInt32(536870912))
|
||||
block.blockHeader.previousBlockHash must be (DoubleSha256Digest(prevBlockHash))
|
||||
block.blockHeader.merkleRootHash must be (DoubleSha256Digest(merkleRoot))
|
||||
block.blockHeader.time must be (1465354640)
|
||||
block.blockHeader.nBits must be (437875042)
|
||||
block.blockHeader.time must be (UInt32(1465354640))
|
||||
block.blockHeader.nBits must be (UInt32(437875042))
|
||||
block.blockHeader must be (RawBlockHeaderSerializer.read(header))
|
||||
block.txCount.num must be (txSeq.size)
|
||||
block.hex must be (hex)
|
||||
|
Loading…
Reference in New Issue
Block a user