mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-23 14:50:42 +01:00
Fixing bug with serialization of UInt64s, wasn't being padded correctly perviously
This commit is contained in:
parent
45bbacd857
commit
deeea0c304
3 changed files with 32 additions and 14 deletions
|
@ -1 +1 @@
|
|||
import AssemblyKeys._
test in assembly := {}
testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-verbosity", "3")
|
||||
import AssemblyKeys._
//test in assembly := {}
testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-verbosity", "3")
|
|
@ -94,6 +94,8 @@ sealed trait UInt32 extends UnsignedNumber with NumberOperations[UInt32] {
|
|||
*/
|
||||
sealed trait UInt64 extends UnsignedNumber with NumberOperations[UInt64] {
|
||||
override type A = BigInt
|
||||
override def hex = encodeHex(underlying)
|
||||
|
||||
override def + (num : UInt64): UInt64 = {
|
||||
val sum = underlying + num.underlying
|
||||
val result = Try(UInt64(sum))
|
||||
|
@ -130,6 +132,19 @@ sealed trait UInt64 extends UnsignedNumber with NumberOperations[UInt64] {
|
|||
case Success(number) => number
|
||||
case Failure(exception) => throw exception
|
||||
}
|
||||
|
||||
/**
|
||||
* The converts a [[BigInt]] to a 8 byte hex representation
|
||||
* [[BigInt]] will only allocate 1 byte for numbers like 1 which require 1 byte, giving us the hex representation 01
|
||||
* this function pads the hex chars to be 0000000000000001
|
||||
* @param bigInt
|
||||
* @return
|
||||
*/
|
||||
private def encodeHex(bigInt : BigInt): String = {
|
||||
val hex = BitcoinSUtil.encodeHex(bigInt)
|
||||
val padding = for { _ <- 0 until 16 - hex.length} yield "0"
|
||||
padding.mkString ++ hex
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -272,13 +287,13 @@ object UInt32 extends Factory[UInt32] with BitcoinSLogger with BaseNumbers[UInt3
|
|||
|
||||
|
||||
object UInt64 extends Factory[UInt64] with BitcoinSLogger with BaseNumbers[UInt64] {
|
||||
private case class UInt64Impl(underlying : BigInt, hex : String) extends UInt64 {
|
||||
private case class UInt64Impl(underlying : BigInt) extends UInt64 {
|
||||
require(underlying >= 0, "We cannot have a negative number in an unsigned number: " + underlying)
|
||||
require(underlying <= BigInt("18446744073709551615"), "We cannot have a number larger than 2^64 -1 in UInt32, got: " + underlying)
|
||||
}
|
||||
|
||||
lazy val zero = UInt64(0)
|
||||
lazy val one = UInt64(1)
|
||||
lazy val zero = UInt64(BigInt(0))
|
||||
lazy val one = UInt64(BigInt(1))
|
||||
|
||||
lazy val min = zero
|
||||
lazy val max = fromBytes(Seq(0xff.toByte, 0xff.toByte, 0xff.toByte, 0xff.toByte,
|
||||
|
@ -289,18 +304,14 @@ object UInt64 extends Factory[UInt64] with BitcoinSLogger with BaseNumbers[UInt6
|
|||
(byte,index) <- bytes.reverse.zipWithIndex
|
||||
} yield NumberUtil.calculateUnsignedNumberFromByte(index, byte)
|
||||
logger.debug("Individual bytes values: " + individualByteValues)
|
||||
UInt64Impl(individualByteValues.sum, BitcoinSUtil.encodeHex(bytes))
|
||||
UInt64Impl(individualByteValues.sum)
|
||||
}
|
||||
|
||||
def apply(num : BigInt): UInt64 = {
|
||||
if (num >= (BigInt(1) << 63)) {
|
||||
//since Scala uses twos complement, it will add a padding byte
|
||||
//if the number is > 2^63. We can remove this since we want to
|
||||
//represent this number as unsigned
|
||||
val bytes = num.toByteArray.tail
|
||||
UInt64Impl(num, BitcoinSUtil.encodeHex(bytes))
|
||||
} else UInt64Impl(num, BitcoinSUtil.encodeHex(num))
|
||||
}
|
||||
def apply(num : BigInt): UInt64 = UInt64Impl(num)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,16 @@ class UInt64Test extends FlatSpec with MustMatchers {
|
|||
|
||||
"UInt64" must "hold the number 0" in {
|
||||
val uInt64 = UInt64(Seq(0.toByte))
|
||||
uInt64.hex must be ("0000000000000000")
|
||||
uInt64.underlying must be (0)
|
||||
}
|
||||
|
||||
it must "encode the number 1" in {
|
||||
val uInt64 = UInt64(1)
|
||||
uInt64.underlying must be (1)
|
||||
uInt64.hex must be ("0000000000000001")
|
||||
}
|
||||
|
||||
it must "hold the max for a uint32_t" in {
|
||||
//this is UInt32_t's max value
|
||||
val uInt64 = UInt64(Seq(0xff.toByte, 0xff.toByte, 0xff.toByte, 0xff.toByte))
|
||||
|
|
Loading…
Add table
Reference in a new issue