Adding support to serialize all witSPKs to bech32 addresses

This commit is contained in:
Chris Stewart 2017-10-30 09:24:04 -05:00
parent e3311b6694
commit 94c42d814f
5 changed files with 30 additions and 5 deletions

View file

@ -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))

View file

@ -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) =>

View file

@ -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. */

View file

@ -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
}
}
}

View file

@ -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
}
}
}