Add address type to createmultisig bitcoind rpc (#4828)

* Add address type to createmultisig rpc

* Fix tests

* Fix UtilRpcTests
This commit is contained in:
Chris Stewart 2022-10-13 15:55:00 -05:00 committed by GitHub
parent 994ee25733
commit 9f53b4e572
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 42 additions and 20 deletions

View File

@ -348,6 +348,7 @@ class MultiWalletRpcTest extends BitcoindFixturesCachedPairV19 {
client client
.createMultiSig(2, .createMultiSig(2,
Vector(privKey1.publicKey, privKey2.publicKey), Vector(privKey1.publicKey, privKey2.publicKey),
AddressType.Bech32,
walletNameOpt = Some(walletName)) walletNameOpt = Some(walletName))
address2 = firstResult.address address2 = firstResult.address

View File

@ -30,7 +30,9 @@ class MultisigRpcTest extends BitcoindRpcTest {
for { for {
client <- clientF client <- clientF
_ <- client.createMultiSig(2, Vector(pubKey1, pubKey2)) _ <- client.createMultiSig(2,
Vector(pubKey1, pubKey2),
AddressType.Bech32)
} yield succeed } yield succeed
} }

View File

@ -5,7 +5,6 @@ import org.bitcoins.commons.jsonmodels.bitcoind.{
DecodeScriptResultV22 DecodeScriptResultV22
} }
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddressType import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddressType
import org.bitcoins.core.protocol.P2PKHAddress
import org.bitcoins.core.script.ScriptType import org.bitcoins.core.script.ScriptType
import org.bitcoins.crypto.ECPrivateKey import org.bitcoins.crypto.ECPrivateKey
import org.bitcoins.rpc.client.common.BitcoindRpcClient import org.bitcoins.rpc.client.common.BitcoindRpcClient
@ -17,7 +16,7 @@ import scala.concurrent.Future
class UtilRpcTest extends BitcoindRpcTest { class UtilRpcTest extends BitcoindRpcTest {
lazy val clientsF: Future[(BitcoindRpcClient, BitcoindRpcClient)] = lazy val clientsF: Future[(BitcoindRpcClient, BitcoindRpcClient)] =
BitcoindRpcTestUtil.createNodePairV21(clientAccum = clientAccum) BitcoindRpcTestUtil.createNodePair(clientAccum = clientAccum)
behavior of "RpcUtilTest" behavior of "RpcUtilTest"
@ -31,22 +30,22 @@ class UtilRpcTest extends BitcoindRpcTest {
it should "be able to decode a reedem script" in { it should "be able to decode a reedem script" in {
val ecPrivKey1 = ECPrivateKey.freshPrivateKey val ecPrivKey1 = ECPrivateKey.freshPrivateKey
val ecPrivKey2 = ECPrivateKey.freshPrivateKey
val pubKey1 = ecPrivKey1.publicKey val pubKey1 = ecPrivKey1.publicKey
val pubKey2 = ecPrivKey2.publicKey
for { for {
(client, _) <- clientsF (client, _) <- clientsF
address <- client.getNewAddress(addressType = AddressType.Legacy) address <- client.getNewAddress(addressType = AddressType.Legacy)
multisig <- multisig <-
client client
.addMultiSigAddress( .createMultiSig(2, Vector(pubKey1, pubKey2), AddressType.Legacy)
2,
Vector(Left(pubKey1), Right(address.asInstanceOf[P2PKHAddress])))
decoded <- client.decodeScript(multisig.redeemScript) decoded <- client.decodeScript(multisig.redeemScript)
} yield { } yield {
decoded match { decoded match {
case decodedPreV22: DecodeScriptResultPreV22 => case decodedPreV22: DecodeScriptResultPreV22 =>
assert(decodedPreV22.reqSigs.contains(2)) assert(decodedPreV22.reqSigs.exists(_ == 2))
assert(decoded.typeOfScript.contains(ScriptType.MULTISIG)) assert(decoded.typeOfScript.exists(_ == ScriptType.MULTISIG))
assert(decodedPreV22.addresses.get.contains(address)) assert(decodedPreV22.addresses.get.exists(_ == address))
case decodedV22: DecodeScriptResultV22 => case decodedV22: DecodeScriptResultV22 =>
assert(decodedV22.typeOfScript.contains(ScriptType.MULTISIG)) assert(decodedV22.typeOfScript.contains(ScriptType.MULTISIG))
} }

View File

@ -477,7 +477,9 @@ class WalletRpcTest extends BitcoindFixturesCachedPairV21 {
for { for {
firstResult <- firstResult <-
client client
.createMultiSig(2, Vector(privKey1.publicKey, privKey2.publicKey)) .createMultiSig(2,
Vector(privKey1.publicKey, privKey2.publicKey),
AddressType.Bech32)
address2 = firstResult.address address2 = firstResult.address
secondResult <- secondResult <-

View File

@ -1,6 +1,9 @@
package org.bitcoins.rpc.v20 package org.bitcoins.rpc.v20
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.WalletFlag import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.{
AddressType,
WalletFlag
}
import org.bitcoins.commons.jsonmodels.bitcoind._ import org.bitcoins.commons.jsonmodels.bitcoind._
import org.bitcoins.core.config.RegTest import org.bitcoins.core.config.RegTest
import org.bitcoins.core.gcs.{BlockFilter, FilterType} import org.bitcoins.core.gcs.{BlockFilter, FilterType}
@ -129,13 +132,15 @@ class BitcoindV20RpcClientTest extends BitcoindFixturesFundedCachedV20 {
val pubKey2 = ECPublicKey.freshPublicKey val pubKey2 = ECPublicKey.freshPublicKey
for { for {
multiSigResult <- client.createMultiSig(2, Vector(pubKey1, pubKey2)) multiSigResult <- client.createMultiSig(2,
Vector(pubKey1, pubKey2),
AddressType.Bech32)
} yield { } yield {
// just validate we are able to receive a sane descriptor // just validate we are able to receive a sane descriptor
// no need to check checksum // no need to check checksum
assert( assert(
multiSigResult.descriptor.startsWith( multiSigResult.descriptor.startsWith(
s"sh(multi(2,${pubKey1.hex},${pubKey2.hex}))#")) s"wsh(multi(2,${pubKey1.hex},${pubKey2.hex}))#"))
} }
} }

View File

@ -1,7 +1,10 @@
package org.bitcoins.rpc.v21 package org.bitcoins.rpc.v21
import org.bitcoins.asyncutil.AsyncUtil import org.bitcoins.asyncutil.AsyncUtil
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.WalletFlag import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.{
AddressType,
WalletFlag
}
import org.bitcoins.commons.jsonmodels.bitcoind._ import org.bitcoins.commons.jsonmodels.bitcoind._
import org.bitcoins.core.config.RegTest import org.bitcoins.core.config.RegTest
import org.bitcoins.core.gcs.{BlockFilter, FilterType} import org.bitcoins.core.gcs.{BlockFilter, FilterType}
@ -169,13 +172,15 @@ class BitcoindV21RpcClientTest extends BitcoindFixturesFundedCachedV21 {
val pubKey2 = ECPublicKey.freshPublicKey val pubKey2 = ECPublicKey.freshPublicKey
for { for {
multiSigResult <- client.createMultiSig(2, Vector(pubKey1, pubKey2)) multiSigResult <- client.createMultiSig(2,
Vector(pubKey1, pubKey2),
AddressType.Bech32)
} yield { } yield {
// just validate we are able to receive a sane descriptor // just validate we are able to receive a sane descriptor
// no need to check checksum // no need to check checksum
assert( assert(
multiSigResult.descriptor.startsWith( multiSigResult.descriptor.startsWith(
s"sh(multi(2,${pubKey1.hex},${pubKey2.hex}))#")) s"wsh(multi(2,${pubKey1.hex},${pubKey2.hex}))#"))
} }
} }

View File

@ -81,13 +81,17 @@ trait MultisigRpc { self: Client =>
def createMultiSig( def createMultiSig(
minSignatures: Int, minSignatures: Int,
keys: Vector[ECPublicKey], keys: Vector[ECPublicKey],
addressType: AddressType,
walletNameOpt: Option[String] = None): Future[MultiSigResult] = { walletNameOpt: Option[String] = None): Future[MultiSigResult] = {
self.version.flatMap { self.version.flatMap {
case V23 | V22 | V21 | V20 | Unknown => case V23 | V22 | V21 | V20 | Unknown =>
bitcoindCall[MultiSigResultPostV20]( bitcoindCall[MultiSigResultPostV20](
"createmultisig", "createmultisig",
List(JsNumber(minSignatures), Json.toJson(keys.map(_.hex))), List(JsNumber(minSignatures),
uriExtensionOpt = walletNameOpt.map(walletExtension)) Json.toJson(keys.map(_.hex)),
Json.toJson(addressType)),
uriExtensionOpt = walletNameOpt.map(walletExtension)
)
case V17 | V18 | V19 => case V17 | V18 | V19 =>
bitcoindCall[MultiSigResultPreV20]( bitcoindCall[MultiSigResultPreV20](
"createmultisig", "createmultisig",

View File

@ -73,13 +73,17 @@ trait V20MultisigRpc extends MultisigRpc { self: Client =>
override def createMultiSig( override def createMultiSig(
minSignatures: Int, minSignatures: Int,
keys: Vector[ECPublicKey], keys: Vector[ECPublicKey],
addressType: AddressType,
walletNameOpt: Option[String] = None): Future[MultiSigResultPostV20] = { walletNameOpt: Option[String] = None): Future[MultiSigResultPostV20] = {
self.version.flatMap { self.version.flatMap {
case V20 | V21 | V22 | V23 | Unknown => case V20 | V21 | V22 | V23 | Unknown =>
bitcoindCall[MultiSigResultPostV20]( bitcoindCall[MultiSigResultPostV20](
"createmultisig", "createmultisig",
List(JsNumber(minSignatures), Json.toJson(keys.map(_.hex))), List(JsNumber(minSignatures),
uriExtensionOpt = walletNameOpt.map(walletExtension)) Json.toJson(keys.map(_.hex)),
Json.toJson(addressType)),
uriExtensionOpt = walletNameOpt.map(walletExtension)
)
case version @ (V17 | V18 | V19) => case version @ (V17 | V18 | V19) =>
throw new RuntimeException( throw new RuntimeException(
s"Cannot use v20MultisigRpc on an older version, got $version") s"Cannot use v20MultisigRpc on an older version, got $version")