From 94c42d814f49bd0e739cf8ea32122d80a2217e68 Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Mon, 30 Oct 2017 09:24:04 -0500 Subject: [PATCH] Adding support to serialize all witSPKs to bech32 addresses --- .../scala/org/bitcoins/core/number/NumberType.scala | 6 +++--- .../scala/org/bitcoins/core/protocol/Address.scala | 2 +- .../scala/org/bitcoins/core/util/BitcoinSUtil.scala | 8 ++++++++ .../scala/org/bitcoins/core/number/UInt32Spec.scala | 13 ++++++++++++- .../scala/org/bitcoins/core/number/UInt8Spec.scala | 6 ++++++ 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/main/scala/org/bitcoins/core/number/NumberType.scala b/src/main/scala/org/bitcoins/core/number/NumberType.scala index 36eb0ec5a2..604040451f 100644 --- a/src/main/scala/org/bitcoins/core/number/NumberType.scala +++ b/src/main/scala/org/bitcoins/core/number/NumberType.scala @@ -93,7 +93,7 @@ sealed abstract class UInt8 extends UnsignedNumber with NumberOperations[UInt8] val r = underlying << i checkResult(r) } - override def hex = BitcoinSUtil.encodeHex(underlying).slice(12,16) + override def hex = BitcoinSUtil.encodeHex(underlying).slice(2,4) override def toInt: Int = { require(underlying <= Int.MaxValue, "Overflow error when casting " + this + " to an integer.") @@ -168,8 +168,8 @@ sealed trait UInt32 extends UnsignedNumber with NumberOperations[UInt32] { //since we are going to shift left we can lose precision by converting .toInt //TODO: There is a bug here wrt comparing shiftNoSignBit & (1 << 31) will always evaluate to false val int = underlying.toInt - val shiftNoSignBit = (int << l) & (Int.MaxValue >> 1) - val shift = if ((shiftNoSignBit & (1 << 31)) == (1 << 31)) { + val shiftNoSignBit = (int << l) & 0xffffffffL + val shift = if (((shiftNoSignBit & (1 << 31)) == (1 << 31))) { shiftNoSignBit + (1 << 31) } else shiftNoSignBit val r = Try(UInt32(shift)) diff --git a/src/main/scala/org/bitcoins/core/protocol/Address.scala b/src/main/scala/org/bitcoins/core/protocol/Address.scala index 84e63915aa..523a2bc566 100644 --- a/src/main/scala/org/bitcoins/core/protocol/Address.scala +++ b/src/main/scala/org/bitcoins/core/protocol/Address.scala @@ -444,7 +444,7 @@ object Address extends Factory[Address] { def fromScriptPubKey(spk: ScriptPubKey, network: NetworkParameters): Try[BitcoinAddress] = spk match { case p2pkh: P2PKHScriptPubKey => Success(P2PKHAddress(p2pkh,network)) case p2sh: P2SHScriptPubKey => Success(P2SHAddress(p2sh,network)) - case witSPK: WitnessScriptPubKeyV0 => Bech32Address(witSPK,network) + case witSPK: WitnessScriptPubKey => Bech32Address(witSPK,network) case x @ (_: P2PKScriptPubKey | _: MultiSignatureScriptPubKey | _: LockTimeScriptPubKey | _: EscrowTimeoutScriptPubKey | _: NonStandardScriptPubKey | _: WitnessCommitment | _: UnassignedWitnessScriptPubKey | EmptyScriptPubKey) => diff --git a/src/main/scala/org/bitcoins/core/util/BitcoinSUtil.scala b/src/main/scala/org/bitcoins/core/util/BitcoinSUtil.scala index 1f4b8cc57c..c2a14deaaa 100644 --- a/src/main/scala/org/bitcoins/core/util/BitcoinSUtil.scala +++ b/src/main/scala/org/bitcoins/core/util/BitcoinSUtil.scala @@ -33,6 +33,14 @@ trait BitcoinSUtil { addPadding(8,hex) } + def encodeHex(short: Short): String = { + val hex = short.toHexString.length % 2 match { + case 1 => "0" + short.toHexString + case _ : Int => short.toHexString + } + addPadding(4,hex) + } + def encodeHex(bigInt : BigInt) : String = BitcoinSUtil.encodeHex(bigInt.toByteArray) /** Tests if a given string is a hexadecimal string. */ diff --git a/src/test/scala/org/bitcoins/core/number/UInt32Spec.scala b/src/test/scala/org/bitcoins/core/number/UInt32Spec.scala index 45965ef59d..5fd5c28165 100644 --- a/src/test/scala/org/bitcoins/core/number/UInt32Spec.scala +++ b/src/test/scala/org/bitcoins/core/number/UInt32Spec.scala @@ -10,7 +10,7 @@ import scala.util.Try * Created by chris on 6/16/16. */ class UInt32Spec extends Properties("UInt32") { - + private val logger = BitcoinSLogger.logger property("serialization symmetry") = { Prop.forAll(NumberGenerator.uInt32s) { uInt32 : UInt32 => @@ -96,4 +96,15 @@ class UInt32Spec extends Properties("UInt32") { Prop.forAll(NumberGenerator.uInt32s, NumberGenerator.uInt32s) { (num1: UInt32, num2: UInt32) => UInt32(num1.underlying & num2.underlying) == (num1 & num2) } + + property("<<") = + Prop.forAllNoShrink(NumberGenerator.uInt32s, Gen.choose(0,32)) { case (u32, shift) => + val r = Try(u32 << shift) + val expected = (u32.underlying << shift) & 0xffffffffL + if (expected <= UInt32.max.underlying) { + r.get == UInt32(expected) + } else { + r.isFailure + } + } } diff --git a/src/test/scala/org/bitcoins/core/number/UInt8Spec.scala b/src/test/scala/org/bitcoins/core/number/UInt8Spec.scala index b059e5fe9b..3fd44012a0 100644 --- a/src/test/scala/org/bitcoins/core/number/UInt8Spec.scala +++ b/src/test/scala/org/bitcoins/core/number/UInt8Spec.scala @@ -10,4 +10,10 @@ class UInt8Spec extends Properties("UInt8Spec") { UInt8(UInt8.toByte(u8)) == u8 } } + + property("serialization symmetry") = { + Prop.forAll(NumberGenerator.uInt8) { u8 => + UInt8(u8.hex) == u8 + } + } }