Fix server parsing for send to address (#1819)

This commit is contained in:
Ben Carman 2020-08-17 09:49:50 -05:00 committed by GitHub
parent 4d46094d72
commit cfd6f4fa79
3 changed files with 29 additions and 11 deletions

View File

@ -650,7 +650,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
val route = walletRoutes.handleCommand(
ServerCommand("sendtoaddress",
Arr(Str(testAddressStr), Num(100), Num(4))))
Arr(Str(testAddressStr), Num(100), Num(4), Bool(true))))
Post() ~> route ~> check {
contentType == `application/json`
@ -660,7 +660,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
// negative cases
val route1 = walletRoutes.handleCommand(
ServerCommand("sendtoaddress", Arr(Null, Null, Null)))
ServerCommand("sendtoaddress", Arr(Null, Null, Null, Bool(false))))
Post() ~> route1 ~> check {
rejection == ValidationRejection(
@ -669,7 +669,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
}
val route2 = walletRoutes.handleCommand(
ServerCommand("sendtoaddress", Arr("Null", Null, Null)))
ServerCommand("sendtoaddress", Arr("Null", Null, Null, Bool(false))))
Post() ~> route2 ~> check {
rejection == ValidationRejection(
@ -678,7 +678,8 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
}
val route3 = walletRoutes.handleCommand(
ServerCommand("sendtoaddress", Arr(Str(testAddressStr), Null, Null)))
ServerCommand("sendtoaddress",
Arr(Str(testAddressStr), Null, Null, Bool(false))))
Post() ~> route3 ~> check {
rejection == ValidationRejection(
@ -688,7 +689,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
val route4 = walletRoutes.handleCommand(
ServerCommand("sendtoaddress",
Arr(Str(testAddressStr), Str("abc"), Null)))
Arr(Str(testAddressStr), Str("abc"), Null, Bool(false))))
Post() ~> route4 ~> check {
rejection == ValidationRejection(

View File

@ -325,7 +325,8 @@ object Rescan extends ServerJsonModels {
case class SendToAddress(
address: BitcoinAddress,
amount: Bitcoins,
satoshisPerVirtualByte: Option[SatoshisPerVirtualByte])
satoshisPerVirtualByte: Option[SatoshisPerVirtualByte],
noBroadcast: Boolean)
object SendToAddress extends ServerJsonModels {
@ -333,14 +334,15 @@ object SendToAddress extends ServerJsonModels {
// custom akka-http directive?
def fromJsArr(jsArr: ujson.Arr): Try[SendToAddress] = {
jsArr.arr.toList match {
case addrJs :: bitcoinsJs :: satsPerVBytesJs :: Nil =>
case addrJs :: bitcoinsJs :: satsPerVBytesJs :: noBroadcastJs :: Nil =>
Try {
val address = jsToBitcoinAddress(addrJs)
val bitcoins = Bitcoins(bitcoinsJs.num)
val satoshisPerVirtualByte =
nullToOpt(satsPerVBytesJs).map(satsPerVBytes =>
SatoshisPerVirtualByte(Satoshis(satsPerVBytes.num.toLong)))
SendToAddress(address, bitcoins, satoshisPerVirtualByte)
val noBroadcast = noBroadcastJs.bool
SendToAddress(address, bitcoins, satoshisPerVirtualByte, noBroadcast)
}
case Nil =>
Failure(
@ -350,7 +352,7 @@ object SendToAddress extends ServerJsonModels {
case other =>
Failure(
new IllegalArgumentException(
s"Bad number of arguments: ${other.length}. Expected: 3"))
s"Bad number of arguments: ${other.length}. Expected: 4"))
}
}

View File

@ -5,7 +5,9 @@ import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server._
import org.bitcoins.commons.serializers.Picklers._
import org.bitcoins.core.currency._
import org.bitcoins.core.protocol.transaction.Transaction
import org.bitcoins.core.wallet.utxo.AddressLabelTagType
import org.bitcoins.crypto.NetworkElement
import org.bitcoins.node.Node
import org.bitcoins.wallet.api.AnyHDWalletApi
@ -17,6 +19,16 @@ case class WalletRoutes(wallet: AnyHDWalletApi, node: Node)(implicit
extends ServerRoute {
import system.dispatcher
private def handleBroadcastable(
tx: Transaction,
noBroadcast: Boolean): Future[NetworkElement] = {
if (noBroadcast) {
Future.successful(tx)
} else {
node.broadcastTransaction(tx).map(_ => tx.txIdBE)
}
}
def handleCommand: PartialFunction[ServerCommand, StandardRoute] = {
case ServerCommand("isempty", _) =>
@ -157,13 +169,16 @@ case class WalletRoutes(wallet: AnyHDWalletApi, node: Node)(implicit
case Failure(exception) =>
reject(ValidationRejection("failure", Some(exception)))
case Success(
SendToAddress(address, bitcoins, satoshisPerVirtualByteOpt)) =>
SendToAddress(address,
bitcoins,
satoshisPerVirtualByteOpt,
noBroadcast)) =>
complete {
for {
tx <- wallet.sendToAddress(address,
bitcoins,
satoshisPerVirtualByteOpt)
_ <- wallet.broadcastTransaction(tx)
_ <- handleBroadcastable(tx, noBroadcast)
} yield {
Server.httpSuccess(tx.txIdBE)
}