mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 01:40:55 +01:00
Pull over simple syntax changes for scala3 pt2 (#5720)
* Pull over simple syntax changes for {nodeTest,keyManager,keyManagerTest,chainTest,bitcoind,bitcoindRpcTest,appServer,appServerTest,tor,zmq} from #5713 * Fix tor/compile
This commit is contained in:
parent
ab6d3f5cb7
commit
602725174f
@ -88,7 +88,7 @@ class ScanBitcoind()(implicit
|
||||
val source: Source[Int, NotUsed] = Source(startHeight.to(endHeight))
|
||||
|
||||
// in this simple example, we are going to count the number of witness transactions
|
||||
val countSegwitTxs: Block => Int = { block: Block =>
|
||||
val countSegwitTxs: Block => Int = { (block: Block) =>
|
||||
block.transactions.count(_.isInstanceOf[WitnessTransaction])
|
||||
}
|
||||
val countsF: Future[Seq[Int]] = for {
|
||||
|
@ -1,12 +1,10 @@
|
||||
package org.bitcoins.server
|
||||
|
||||
import java.nio.file._
|
||||
import java.nio.file.*
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import org.bitcoins.core.config._
|
||||
import org.bitcoins.core.config.*
|
||||
import org.bitcoins.rpc.config.BitcoindRpcAppConfig
|
||||
import org.bitcoins.testkit.util.BitcoinSAsyncTest
|
||||
|
||||
import scala.reflect.io.Directory
|
||||
import org.bitcoins.testkit.util.{BitcoinSAsyncTest, FileUtil}
|
||||
|
||||
class BitcoindRpcAppConfigTest extends BitcoinSAsyncTest {
|
||||
|
||||
@ -17,7 +15,7 @@ class BitcoindRpcAppConfigTest extends BitcoinSAsyncTest {
|
||||
|
||||
override def afterAll(): Unit = {
|
||||
super.afterAll()
|
||||
new Directory(tempDir.toFile).deleteRecursively()
|
||||
FileUtil.deleteTmpDir(tempDir)
|
||||
()
|
||||
}
|
||||
|
||||
|
@ -1587,7 +1587,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
.expects(contractId, Vector(dummyOracleAttestment))
|
||||
.returning(Future.successful(Some(EmptyTransaction)))
|
||||
|
||||
(mockWalletApi.broadcastTransaction _)
|
||||
(mockWalletApi.broadcastTransaction)
|
||||
.expects(EmptyTransaction)
|
||||
.returning(FutureUtil.unit)
|
||||
.anyNumberOfTimes()
|
||||
@ -1642,7 +1642,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
.expects(contractId)
|
||||
.returning(Future.successful(EmptyTransaction))
|
||||
|
||||
(mockWalletApi.broadcastTransaction _)
|
||||
(mockWalletApi.broadcastTransaction)
|
||||
.expects(EmptyTransaction)
|
||||
.returning(FutureUtil.unit)
|
||||
.anyNumberOfTimes()
|
||||
@ -1698,7 +1698,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
Vector.empty)
|
||||
.returning(Future.successful(EmptyTransaction))
|
||||
|
||||
(mockWalletApi.broadcastTransaction _)
|
||||
(mockWalletApi.broadcastTransaction)
|
||||
.expects(EmptyTransaction)
|
||||
.returning(Future.unit)
|
||||
.anyNumberOfTimes()
|
||||
@ -1817,7 +1817,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
)
|
||||
.returning(Future.successful(EmptyTransaction))
|
||||
|
||||
(mockWalletApi.broadcastTransaction _)
|
||||
(mockWalletApi.broadcastTransaction)
|
||||
.expects(EmptyTransaction)
|
||||
.returning(Future.unit)
|
||||
.anyNumberOfTimes()
|
||||
@ -1936,7 +1936,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
.expects(Vector.empty, testAddress, fee)
|
||||
.returning(Future.successful(EmptyTransaction))
|
||||
|
||||
(mockWalletApi.broadcastTransaction _)
|
||||
(mockWalletApi.broadcastTransaction)
|
||||
.expects(EmptyTransaction)
|
||||
.returning(Future.unit)
|
||||
.anyNumberOfTimes()
|
||||
@ -1977,7 +1977,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
)
|
||||
.returning(Future.successful(EmptyTransaction))
|
||||
|
||||
(mockWalletApi.broadcastTransaction _)
|
||||
(mockWalletApi.broadcastTransaction)
|
||||
.expects(EmptyTransaction)
|
||||
.returning(Future.unit)
|
||||
.anyNumberOfTimes()
|
||||
@ -2122,7 +2122,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
.expects(message, false, *)
|
||||
.returning(Future.successful(EmptyTransaction))
|
||||
|
||||
(mockWalletApi.broadcastTransaction _)
|
||||
(mockWalletApi.broadcastTransaction)
|
||||
.expects(EmptyTransaction)
|
||||
.returning(Future.unit)
|
||||
.anyNumberOfTimes()
|
||||
@ -2151,7 +2151,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
.expects(DoubleSha256DigestBE.empty, SatoshisPerVirtualByte.one)
|
||||
.returning(Future.successful(EmptyTransaction))
|
||||
|
||||
(mockWalletApi.broadcastTransaction _)
|
||||
(mockWalletApi.broadcastTransaction)
|
||||
.expects(EmptyTransaction)
|
||||
.returning(Future.unit)
|
||||
.anyNumberOfTimes()
|
||||
@ -2182,7 +2182,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
.expects(DoubleSha256DigestBE.empty, SatoshisPerVirtualByte.one)
|
||||
.returning(Future.successful(EmptyTransaction))
|
||||
|
||||
(mockWalletApi.broadcastTransaction _)
|
||||
(mockWalletApi.broadcastTransaction)
|
||||
.expects(EmptyTransaction)
|
||||
.returning(Future.unit)
|
||||
.anyNumberOfTimes()
|
||||
|
@ -22,7 +22,7 @@ class ServerRunTest extends BitcoinSAsyncTest {
|
||||
// this should cause an exception in startBitcoinSBackend()
|
||||
val noPeersConfig =
|
||||
ConfigFactory.parseString(s"""bitcoin-s.node.peers=[]""")
|
||||
implicit val config =
|
||||
implicit val config: BitcoinSAppConfig =
|
||||
BitcoinSTestAppConfig.getNeutrinoTestConfig(noPeersConfig)
|
||||
val datadir = config.chainConf.datadir
|
||||
|
||||
|
@ -187,7 +187,7 @@ class WalletRoutesSpec
|
||||
val cmd = ServerCommand(
|
||||
"createnewaccount",
|
||||
ujson.Arr(
|
||||
upickle.default.writeJs(HDPurpose.default)(Picklers.hdPurpose))
|
||||
upickle.default.writeJs(HDPurpose.default)(using Picklers.hdPurpose))
|
||||
)
|
||||
val route = walletRoutes.handleCommand(cmd)
|
||||
|
||||
|
@ -52,27 +52,27 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
|
||||
behavior of "Websocket Tests"
|
||||
|
||||
val endSink: Sink[WsNotification[_], Future[Seq[WsNotification[_]]]] =
|
||||
Sink.seq[WsNotification[_]]
|
||||
val endSink: Sink[WsNotification[?], Future[Seq[WsNotification[?]]]] =
|
||||
Sink.seq[WsNotification[?]]
|
||||
|
||||
val sink: Sink[Message, Future[Seq[WsNotification[_]]]] = Flow[Message]
|
||||
val sink: Sink[Message, Future[Seq[WsNotification[?]]]] = Flow[Message]
|
||||
.map {
|
||||
case message: TextMessage.Strict =>
|
||||
// we should be able to parse the address message
|
||||
val text = message.text
|
||||
val dlcNodeNotificationOpt: Option[DLCNodeNotification[_]] = Try(
|
||||
upickle.default.read[DLCNodeNotification[_]](text)(
|
||||
WsPicklers.dlcNodeNotificationPickler
|
||||
val dlcNodeNotificationOpt: Option[DLCNodeNotification[?]] = Try(
|
||||
upickle.default.read[DLCNodeNotification[?]](text)(
|
||||
using WsPicklers.dlcNodeNotificationPickler
|
||||
)
|
||||
).toOption
|
||||
val walletNotificationOpt: Option[WalletNotification[_]] = Try(
|
||||
upickle.default.read[WalletNotification[_]](text)(
|
||||
WsPicklers.walletNotificationPickler
|
||||
val walletNotificationOpt: Option[WalletNotification[?]] = Try(
|
||||
upickle.default.read[WalletNotification[?]](text)(
|
||||
using WsPicklers.walletNotificationPickler
|
||||
)
|
||||
).toOption
|
||||
val chainNotificationOpt: Option[ChainNotification[_]] = Try(
|
||||
upickle.default.read[ChainNotification[_]](text)(
|
||||
WsPicklers.chainNotificationPickler
|
||||
val chainNotificationOpt: Option[ChainNotification[?]] = Try(
|
||||
upickle.default.read[ChainNotification[?]](text)(
|
||||
using WsPicklers.chainNotificationPickler
|
||||
)
|
||||
).toOption
|
||||
walletNotificationOpt.getOrElse(
|
||||
@ -104,7 +104,7 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
val websocketFlow: Flow[
|
||||
Message,
|
||||
Message,
|
||||
(Future[Seq[WsNotification[_]]], Promise[Option[Message]])
|
||||
(Future[Seq[WsNotification[?]]], Promise[Option[Message]])
|
||||
] = {
|
||||
Flow
|
||||
.fromSinkAndSourceCoupledMat(sink, Source.maybe[Message])(Keep.both)
|
||||
@ -174,13 +174,13 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
val req = buildReq(server.conf)
|
||||
val notificationsF: (
|
||||
Future[WebSocketUpgradeResponse],
|
||||
(Future[Seq[WsNotification[_]]], Promise[Option[Message]])
|
||||
(Future[Seq[WsNotification[?]]], Promise[Option[Message]])
|
||||
) = {
|
||||
Http()
|
||||
.singleWebSocketRequest(req, websocketFlow)
|
||||
}
|
||||
|
||||
val walletNotificationsF: Future[Seq[WsNotification[_]]] =
|
||||
val walletNotificationsF: Future[Seq[WsNotification[?]]] =
|
||||
notificationsF._2._1
|
||||
|
||||
val promise: Promise[Option[Message]] = notificationsF._2._2
|
||||
@ -210,7 +210,7 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
val req = buildReq(server.conf)
|
||||
val tuple: (
|
||||
Future[WebSocketUpgradeResponse],
|
||||
(Future[Seq[WsNotification[_]]], Promise[Option[Message]])
|
||||
(Future[Seq[WsNotification[?]]], Promise[Option[Message]])
|
||||
) = {
|
||||
Http()
|
||||
.singleWebSocketRequest(req, websocketFlow)
|
||||
@ -253,7 +253,7 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
val req = buildReq(server.conf)
|
||||
val tuple: (
|
||||
Future[WebSocketUpgradeResponse],
|
||||
(Future[Seq[WsNotification[_]]], Promise[Option[Message]])
|
||||
(Future[Seq[WsNotification[?]]], Promise[Option[Message]])
|
||||
) = {
|
||||
Http()
|
||||
.singleWebSocketRequest(req, websocketFlow)
|
||||
@ -295,7 +295,7 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
val req = buildReq(server.conf)
|
||||
val tuple: (
|
||||
Future[WebSocketUpgradeResponse],
|
||||
(Future[Seq[WsNotification[_]]], Promise[Option[Message]])
|
||||
(Future[Seq[WsNotification[?]]], Promise[Option[Message]])
|
||||
) = {
|
||||
Http()
|
||||
.singleWebSocketRequest(req, websocketFlow)
|
||||
@ -313,7 +313,7 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
cmd = GetBlockHeader(hash = hashes.head)
|
||||
getBlockHeaderResultStr = ConsoleCli.exec(cmd, cliConfig)
|
||||
getBlockHeaderResult = upickle.default.read(getBlockHeaderResultStr.get)(
|
||||
Picklers.getBlockHeaderResultPickler
|
||||
using Picklers.getBlockHeaderResultPickler
|
||||
)
|
||||
_ <- PekkoUtil.nonBlockingSleep(timeout)
|
||||
_ = promise.success(None)
|
||||
@ -337,13 +337,13 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
val req = buildReq(server.conf)
|
||||
val tuple: (
|
||||
Future[WebSocketUpgradeResponse],
|
||||
(Future[Seq[WsNotification[_]]], Promise[Option[Message]])
|
||||
(Future[Seq[WsNotification[?]]], Promise[Option[Message]])
|
||||
) = {
|
||||
Http()
|
||||
.singleWebSocketRequest(req, websocketFlow)
|
||||
}
|
||||
|
||||
val notificationsF: Future[Seq[WsNotification[_]]] = tuple._2._1
|
||||
val notificationsF: Future[Seq[WsNotification[?]]] = tuple._2._1
|
||||
val promise = tuple._2._2
|
||||
|
||||
// lock all utxos
|
||||
@ -375,13 +375,13 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
val req = buildReq(server.conf)
|
||||
val notificationsF: (
|
||||
Future[WebSocketUpgradeResponse],
|
||||
(Future[Seq[WsNotification[_]]], Promise[Option[Message]])
|
||||
(Future[Seq[WsNotification[?]]], Promise[Option[Message]])
|
||||
) = {
|
||||
Http()
|
||||
.singleWebSocketRequest(req, websocketFlow)
|
||||
}
|
||||
|
||||
val walletNotificationsF: Future[Seq[WsNotification[_]]] =
|
||||
val walletNotificationsF: Future[Seq[WsNotification[?]]] =
|
||||
notificationsF._2._1
|
||||
|
||||
val promise: Promise[Option[Message]] = notificationsF._2._2
|
||||
@ -428,7 +428,7 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
val req = buildReq(server.conf)
|
||||
val tuple: (
|
||||
Future[WebSocketUpgradeResponse],
|
||||
(Future[Seq[WsNotification[_]]], Promise[Option[Message]])
|
||||
(Future[Seq[WsNotification[?]]], Promise[Option[Message]])
|
||||
) = {
|
||||
Http()
|
||||
.singleWebSocketRequest(req, websocketFlow)
|
||||
@ -446,7 +446,8 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
for {
|
||||
_ <- AsyncUtil.retryUntilSatisfied({
|
||||
val walletInfoStr = ConsoleCli.exec(WalletInfo, cliConfig)
|
||||
val i = upickle.default.read(walletInfoStr.get)(Picklers.walletInfo)
|
||||
val i =
|
||||
upickle.default.read(walletInfoStr.get)(using Picklers.walletInfo)
|
||||
!i.rescan
|
||||
})
|
||||
_ = promise.success(None)
|
||||
@ -463,7 +464,7 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
val req = buildReq(server.conf)
|
||||
val tuple: (
|
||||
Future[WebSocketUpgradeResponse],
|
||||
(Future[Seq[WsNotification[_]]], Promise[Option[Message]])
|
||||
(Future[Seq[WsNotification[?]]], Promise[Option[Message]])
|
||||
) = {
|
||||
Http()
|
||||
.singleWebSocketRequest(req, websocketFlow)
|
||||
@ -489,7 +490,7 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
val req = buildReq(server.conf)
|
||||
val tuple: (
|
||||
Future[WebSocketUpgradeResponse],
|
||||
(Future[Seq[WsNotification[_]]], Promise[Option[Message]])
|
||||
(Future[Seq[WsNotification[?]]], Promise[Option[Message]])
|
||||
) = {
|
||||
Http()
|
||||
.singleWebSocketRequest(req, websocketFlow)
|
||||
@ -517,14 +518,14 @@ class WebsocketTests extends BitcoinSServerMainBitcoindFixture {
|
||||
val req = buildReq(server.conf)
|
||||
val notificationsF: (
|
||||
Future[WebSocketUpgradeResponse],
|
||||
(Future[Seq[WsNotification[_]]], Promise[Option[Message]])
|
||||
(Future[Seq[WsNotification[?]]], Promise[Option[Message]])
|
||||
) = {
|
||||
Http()
|
||||
.singleWebSocketRequest(req, websocketFlow)
|
||||
}
|
||||
|
||||
val setupF = notificationsF._1
|
||||
val walletNotificationsF: Future[Seq[WsNotification[_]]] =
|
||||
val walletNotificationsF: Future[Seq[WsNotification[?]]] =
|
||||
notificationsF._2._1
|
||||
|
||||
val promise: Promise[Option[Message]] = notificationsF._2._2
|
||||
|
@ -80,7 +80,7 @@ case class BitcoinSAppConfig(
|
||||
val nonTorConfigs = Vector(kmConf, chainConf, walletConf, dlcConf)
|
||||
|
||||
val torConfig = torConf.start()
|
||||
val torDependentConfigs =
|
||||
val torDependentConfigs: Vector[AppConfig] =
|
||||
Vector(nodeConf, bitcoindRpcConf, dlcNodeConf)
|
||||
|
||||
val dbConfigsDependentOnTor: Vector[DbManagement] =
|
||||
@ -244,7 +244,7 @@ object BitcoinSAppConfig extends BitcoinSLogger {
|
||||
confs: Vector[Config] = Vector.empty
|
||||
)(implicit system: ActorSystem): BitcoinSAppConfig = {
|
||||
val baseConf: BitcoinSAppConfig =
|
||||
fromDatadir(datadir, confs: _*)
|
||||
fromDatadir(datadir, confs*)
|
||||
|
||||
// Grab saved bundle config
|
||||
val bundleConfFile =
|
||||
|
@ -202,8 +202,8 @@ class BitcoinSServerMain(override val serverArgParser: ServerArgParser)(implicit
|
||||
|
||||
val tuple = buildWsSource
|
||||
|
||||
val wsQueue: SourceQueueWithComplete[WsNotification[_]] = tuple._1
|
||||
val wsSource: Source[WsNotification[_], NotUsed] = tuple._2
|
||||
val wsQueue: SourceQueueWithComplete[WsNotification[?]] = tuple._1
|
||||
val wsSource: Source[WsNotification[?], NotUsed] = tuple._2
|
||||
|
||||
val torCallbacks = WebsocketUtil.buildTorCallbacks(wsQueue)
|
||||
torConf.addCallbacks(torCallbacks)
|
||||
@ -289,7 +289,7 @@ class BitcoinSServerMain(override val serverArgParser: ServerArgParser)(implicit
|
||||
}
|
||||
|
||||
private def buildNeutrinoCallbacks(
|
||||
wsQueue: SourceQueueWithComplete[WsNotification[_]],
|
||||
wsQueue: SourceQueueWithComplete[WsNotification[?]],
|
||||
chainApi: ChainApi,
|
||||
walletConf: WalletAppConfig,
|
||||
dlcConf: DLCAppConfig
|
||||
@ -345,11 +345,11 @@ class BitcoinSServerMain(override val serverArgParser: ServerArgParser)(implicit
|
||||
}
|
||||
|
||||
/** The wallet loader that is being used for our wallet. */
|
||||
private[this] var walletLoaderApiOpt: Option[DLCWalletLoaderApi] = None
|
||||
private var walletLoaderApiOpt: Option[DLCWalletLoaderApi] = None
|
||||
|
||||
private[this] var bitcoindSyncStateOpt: Option[BitcoindSyncState] = None
|
||||
private var bitcoindSyncStateOpt: Option[BitcoindSyncState] = None
|
||||
|
||||
private[this] var nodeOpt: Option[Node] = None
|
||||
private var nodeOpt: Option[Node] = None
|
||||
|
||||
/** Start the bitcoin-s wallet server with a bitcoind backend
|
||||
* @param startedTorConfigF
|
||||
@ -368,8 +368,8 @@ class BitcoinSServerMain(override val serverArgParser: ServerArgParser)(implicit
|
||||
client
|
||||
}
|
||||
val tuple = buildWsSource
|
||||
val wsQueue: SourceQueueWithComplete[WsNotification[_]] = tuple._1
|
||||
val wsSource: Source[WsNotification[_], NotUsed] = tuple._2
|
||||
val wsQueue: SourceQueueWithComplete[WsNotification[?]] = tuple._1
|
||||
val wsSource: Source[WsNotification[?], NotUsed] = tuple._2
|
||||
val torCallbacks = WebsocketUtil.buildTorCallbacks(wsQueue)
|
||||
val _ = torConf.addCallbacks(torCallbacks)
|
||||
val isTorStartedF = if (torConf.torProvided) {
|
||||
@ -507,7 +507,7 @@ class BitcoinSServerMain(override val serverArgParser: ServerArgParser)(implicit
|
||||
dlcNodeF: Future[DLCNode],
|
||||
torConfStarted: Future[Unit],
|
||||
serverCmdLineArgs: ServerArgParser,
|
||||
wsSource: Source[WsNotification[_], NotUsed]
|
||||
wsSource: Source[WsNotification[?], NotUsed]
|
||||
)(implicit system: ActorSystem, conf: BitcoinSAppConfig): Future[Server] = {
|
||||
implicit val nodeConf: NodeAppConfig = conf.nodeConf
|
||||
implicit val walletConf: WalletAppConfig = conf.walletConf
|
||||
@ -675,8 +675,8 @@ class BitcoinSServerMain(override val serverArgParser: ServerArgParser)(implicit
|
||||
* emits websocket messages
|
||||
*/
|
||||
private def buildWsSource: (
|
||||
SourceQueueWithComplete[WsNotification[_]],
|
||||
Source[WsNotification[_], NotUsed]
|
||||
SourceQueueWithComplete[WsNotification[?]],
|
||||
Source[WsNotification[?], NotUsed]
|
||||
) = {
|
||||
val maxBufferSize: Int = 25
|
||||
|
||||
@ -688,7 +688,7 @@ class BitcoinSServerMain(override val serverArgParser: ServerArgParser)(implicit
|
||||
// the BroadcastHub.sink is needed to avoid these errors
|
||||
// 'Websocket handler failed with Processor actor'
|
||||
Source
|
||||
.queue[WsNotification[_]](maxBufferSize, OverflowStrategy.dropHead)
|
||||
.queue[WsNotification[?]](maxBufferSize, OverflowStrategy.dropHead)
|
||||
.toMat(BroadcastHub.sink)(Keep.both)
|
||||
.run()
|
||||
}
|
||||
|
@ -61,7 +61,8 @@ case class ChainRoutes(
|
||||
results <- resultsF
|
||||
} yield {
|
||||
val json = upickle.default
|
||||
.writeJs(results.head)(Picklers.getBlockHeaderResultPickler)
|
||||
.writeJs(results.head)(
|
||||
using Picklers.getBlockHeaderResultPickler)
|
||||
Server.httpSuccess(json)
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ case class CoreRoutes()(implicit system: ActorSystem, config: BitcoinSAppConfig)
|
||||
case DecodeContractInfo(contractInfo) =>
|
||||
complete {
|
||||
Server.httpSuccess(
|
||||
writeJs(contractInfo)(contractInfoV0TLVJsonWriter)
|
||||
writeJs(contractInfo)(using contractInfoV0TLVJsonWriter)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -182,7 +182,7 @@ case class CoreRoutes()(implicit system: ActorSystem, config: BitcoinSAppConfig)
|
||||
case DecodeAnnouncement(announcement) =>
|
||||
complete {
|
||||
Server.httpSuccess(
|
||||
writeJs(announcement)(oracleAnnouncementTLVJsonWriter)
|
||||
writeJs(announcement)(using oracleAnnouncementTLVJsonWriter)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -191,7 +191,8 @@ case class CoreRoutes()(implicit system: ActorSystem, config: BitcoinSAppConfig)
|
||||
withValidServerCommand(DecodeAttestations.fromJsArr(arr)) {
|
||||
case DecodeAttestations(attestments) =>
|
||||
complete {
|
||||
Server.httpSuccess(writeJs(attestments)(oracleAttestmentV0Writer))
|
||||
Server.httpSuccess(
|
||||
writeJs(attestments)(using oracleAttestmentV0Writer))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,8 @@ case class DLCRoutes(dlcNode: DLCNodeApi)(implicit system: ActorSystem)
|
||||
complete {
|
||||
dlcNode.incomingOfferHandling.listDLCContacts().map { contacts =>
|
||||
val json = contacts
|
||||
.map(c => upickle.default.writeJs(c)(Picklers.contactDbPickler))
|
||||
.map(c =>
|
||||
upickle.default.writeJs(c)(using Picklers.contactDbPickler))
|
||||
Server.httpSuccess(json)
|
||||
}
|
||||
}
|
||||
|
@ -133,8 +133,7 @@ sealed trait DLCWalletLoaderApi
|
||||
/** Store a rescan state for the wallet that is currently loaded This is
|
||||
* needed because we don't save rescan state anywhere else.
|
||||
*/
|
||||
@volatile private[this] var rescanStateOpt
|
||||
: Option[RescanState.RescanStarted] = None
|
||||
@volatile private var rescanStateOpt: Option[RescanState.RescanStarted] = None
|
||||
|
||||
def setRescanState(rescanState: RescanState): Unit = {
|
||||
rescanState match {
|
||||
@ -190,10 +189,10 @@ sealed trait DLCWalletLoaderApi
|
||||
()
|
||||
}
|
||||
|
||||
@volatile private[this] var currentWalletAppConfigOpt
|
||||
: Option[WalletAppConfig] = None
|
||||
@volatile private var currentWalletAppConfigOpt: Option[WalletAppConfig] =
|
||||
None
|
||||
|
||||
@volatile private[this] var currentDLCAppConfigOpt: Option[DLCAppConfig] =
|
||||
@volatile private var currentDLCAppConfigOpt: Option[DLCAppConfig] =
|
||||
None
|
||||
|
||||
protected def stopOldWalletAppConfig(
|
||||
|
@ -44,7 +44,7 @@ case class WalletRoutes(loadWalletApi: DLCWalletLoaderApi)(implicit
|
||||
import system.dispatcher
|
||||
|
||||
/** The loaded wallet that requests should be directed against */
|
||||
private[this] val wallet: WalletHolder = loadWalletApi.walletHolder
|
||||
private val wallet: WalletHolder = loadWalletApi.walletHolder
|
||||
|
||||
implicit private val kmConf: KeyManagerAppConfig = walletConf.kmConf
|
||||
|
||||
@ -881,7 +881,8 @@ case class WalletRoutes(loadWalletApi: DLCWalletLoaderApi)(implicit
|
||||
} yield {
|
||||
val xpubs = accounts.map(_.xpub)
|
||||
val json =
|
||||
xpubs.map(upickle.default.writeJs(_)(Picklers.extPubKeyPickler))
|
||||
xpubs.map(
|
||||
upickle.default.writeJs(_)(using Picklers.extPubKeyPickler))
|
||||
Server.httpSuccess(Arr.from(json))
|
||||
}
|
||||
}
|
||||
@ -1099,7 +1100,7 @@ case class WalletRoutes(loadWalletApi: DLCWalletLoaderApi)(implicit
|
||||
for {
|
||||
info <- wallet.getInfo()
|
||||
} yield {
|
||||
upickle.default.writeJs(info)(Picklers.walletInfo)
|
||||
upickle.default.writeJs(info)(using Picklers.walletInfo)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ import scala.concurrent.Future
|
||||
object CallbackUtil extends BitcoinSLogger {
|
||||
|
||||
def createNeutrinoNodeCallbacksForWallet(
|
||||
wallet: WalletApi with NeutrinoWalletApi
|
||||
wallet: WalletApi & NeutrinoWalletApi
|
||||
)(implicit system: ActorSystem): Future[NodeCallbackStreamManager] = {
|
||||
import system.dispatcher
|
||||
val txSink = Sink.foreachAsync[Transaction](1) { case tx: Transaction =>
|
||||
|
@ -68,8 +68,8 @@ import scala.concurrent.{ExecutionContext, Future}
|
||||
object WebsocketUtil extends BitcoinSLogger {
|
||||
|
||||
private def sendHeadersToWs(
|
||||
notifications: Vector[ChainNotification[_]],
|
||||
queue: SourceQueueWithComplete[WsNotification[_]]
|
||||
notifications: Vector[ChainNotification[?]],
|
||||
queue: SourceQueueWithComplete[WsNotification[?]]
|
||||
)(implicit ec: ExecutionContext): Future[Unit] = {
|
||||
for {
|
||||
_ <- FutureUtil.sequentially(notifications) { case msg =>
|
||||
@ -82,7 +82,7 @@ object WebsocketUtil extends BitcoinSLogger {
|
||||
}
|
||||
|
||||
def buildChainCallbacks(
|
||||
queue: SourceQueueWithComplete[WsNotification[_]],
|
||||
queue: SourceQueueWithComplete[WsNotification[?]],
|
||||
chainApi: ChainApi
|
||||
)(implicit
|
||||
ec: ExecutionContext,
|
||||
@ -175,7 +175,7 @@ object WebsocketUtil extends BitcoinSLogger {
|
||||
|
||||
/** Builds websocket callbacks for the wallet */
|
||||
def buildWalletCallbacks(
|
||||
walletQueue: SourceQueueWithComplete[WsNotification[_]],
|
||||
walletQueue: SourceQueueWithComplete[WsNotification[?]],
|
||||
walletName: String
|
||||
)(implicit system: ActorSystem): WalletCallbackStreamManager = {
|
||||
import system.dispatcher
|
||||
@ -234,7 +234,7 @@ object WebsocketUtil extends BitcoinSLogger {
|
||||
}
|
||||
|
||||
def buildTorCallbacks(
|
||||
queue: SourceQueueWithComplete[WsNotification[_]]
|
||||
queue: SourceQueueWithComplete[WsNotification[?]]
|
||||
)(implicit ec: ExecutionContext): TorCallbacks = {
|
||||
val onTorStarted: OnTorStarted = { _ =>
|
||||
val notification = TorStartedNotification
|
||||
@ -248,7 +248,7 @@ object WebsocketUtil extends BitcoinSLogger {
|
||||
private def buildTxNotification(
|
||||
wsType: WalletWsType,
|
||||
tx: Transaction,
|
||||
walletQueue: SourceQueueWithComplete[WsNotification[_]]
|
||||
walletQueue: SourceQueueWithComplete[WsNotification[?]]
|
||||
)(implicit ec: ExecutionContext): Future[Unit] = {
|
||||
val notification = wsType match {
|
||||
case WalletWsType.TxProcessed =>
|
||||
@ -267,7 +267,7 @@ object WebsocketUtil extends BitcoinSLogger {
|
||||
}
|
||||
|
||||
def buildDLCWalletCallbacks(
|
||||
walletQueue: SourceQueueWithComplete[WsNotification[_]]
|
||||
walletQueue: SourceQueueWithComplete[WsNotification[?]]
|
||||
)(implicit system: ActorSystem): DLCWalletCallbackStreamManager = {
|
||||
import system.dispatcher
|
||||
val onStateChange: OnDLCStateChange = { (status: DLCStatus) =>
|
||||
@ -299,7 +299,7 @@ object WebsocketUtil extends BitcoinSLogger {
|
||||
}
|
||||
|
||||
def buildDLCNodeCallbacks(
|
||||
walletQueue: SourceQueueWithComplete[WsNotification[_]]
|
||||
walletQueue: SourceQueueWithComplete[WsNotification[?]]
|
||||
)(implicit ec: ExecutionContext): DLCNodeCallbacks = {
|
||||
|
||||
val onConnectionInitiated: OnPeerConnectionInitiated = { payload =>
|
||||
|
@ -28,7 +28,7 @@ class TestRpcUtilTest extends BitcoindFixturesCachedPairNewest {
|
||||
behavior of "BitcoindRpcUtil"
|
||||
|
||||
it should "create a temp bitcoin directory when creating a DaemonInstance, and then delete it" in {
|
||||
_: NodePair[BitcoindRpcClient] =>
|
||||
_ =>
|
||||
val instance =
|
||||
BitcoindRpcTestUtil.instance(RpcUtil.randomPort, RpcUtil.randomPort)
|
||||
val dir = instance.datadir
|
||||
@ -42,7 +42,7 @@ class TestRpcUtilTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
|
||||
it should "be able to generate and sync blocks" in {
|
||||
nodes: NodePair[BitcoindRpcClient] =>
|
||||
(nodes: NodePair[BitcoindRpcClient]) =>
|
||||
val NodePair(first, second) = nodes
|
||||
for {
|
||||
address <- second.getNewAddress
|
||||
@ -58,7 +58,7 @@ class TestRpcUtilTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
|
||||
it should "ble able to generate blocks with multiple clients and sync inbetween" in {
|
||||
nodes: NodePair[BitcoindRpcClient] =>
|
||||
(nodes: NodePair[BitcoindRpcClient]) =>
|
||||
val blocksToGenerate = 10
|
||||
val NodePair(first, second) = nodes
|
||||
val allClients = nodes.toVector
|
||||
@ -80,7 +80,7 @@ class TestRpcUtilTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
|
||||
it should "be able to find outputs of previous transactions" in {
|
||||
nodes: NodePair[BitcoindRpcClient] =>
|
||||
(nodes: NodePair[BitcoindRpcClient]) =>
|
||||
val NodePair(first, second) = nodes
|
||||
for {
|
||||
address <- second.getNewAddress
|
||||
|
@ -34,7 +34,7 @@ class MempoolRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
behavior of "MempoolRpc"
|
||||
|
||||
it should "be able to find a transaction sent to the mem pool" in {
|
||||
nodePair: FixtureParam =>
|
||||
nodePair =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
@ -48,7 +48,7 @@ class MempoolRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
|
||||
it should "be able to find a verbose transaction in the mem pool" in {
|
||||
nodePair: FixtureParam =>
|
||||
nodePair =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
@ -62,7 +62,7 @@ class MempoolRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to find a mem pool entry" in { nodePair: FixtureParam =>
|
||||
it should "be able to find a mem pool entry" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
@ -72,7 +72,7 @@ class MempoolRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
} yield succeed
|
||||
}
|
||||
|
||||
it must "fail to find a mempool entry" in { nodePair: FixtureParam =>
|
||||
it must "fail to find a mempool entry" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val txid = DoubleSha256Digest.empty
|
||||
val resultF = for {
|
||||
@ -85,18 +85,17 @@ class MempoolRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
recoverToSucceededIf[BitcoindException](resultF)
|
||||
}
|
||||
|
||||
it must "fail to find a mempool entry and return None" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
val txid = DoubleSha256Digest.empty
|
||||
val resultF = for {
|
||||
result <- client.getMemPoolEntryOpt(txid)
|
||||
} yield {
|
||||
assert(result.isEmpty)
|
||||
}
|
||||
resultF
|
||||
it must "fail to find a mempool entry and return None" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val txid = DoubleSha256Digest.empty
|
||||
val resultF = for {
|
||||
result <- client.getMemPoolEntryOpt(txid)
|
||||
} yield {
|
||||
assert(result.isEmpty)
|
||||
}
|
||||
resultF
|
||||
}
|
||||
it should "be able to get mem pool info" in { nodePair: FixtureParam =>
|
||||
it should "be able to get mem pool info" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
@ -118,28 +117,27 @@ class MempoolRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to prioritise a mem pool transaction" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
address <- otherClient.getNewAddress
|
||||
txid <-
|
||||
BitcoindRpcTestUtil
|
||||
.fundMemPoolTransaction(client, address, Bitcoins(3.2))
|
||||
tt <- client.prioritiseTransaction(txid, Bitcoins.one.satoshis)
|
||||
txs <- client.getPrioritisedTransactions()
|
||||
} yield {
|
||||
assert(tt)
|
||||
assert(txs.exists(_._1 == txid))
|
||||
val p = txs(txid)
|
||||
assert(p.in_mempool)
|
||||
assert(p.fee_delta == Bitcoins.one)
|
||||
}
|
||||
it should "be able to prioritise a mem pool transaction" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
address <- otherClient.getNewAddress
|
||||
txid <-
|
||||
BitcoindRpcTestUtil
|
||||
.fundMemPoolTransaction(client, address, Bitcoins(3.2))
|
||||
tt <- client.prioritiseTransaction(txid, Bitcoins.one.satoshis)
|
||||
txs <- client.getPrioritisedTransactions()
|
||||
} yield {
|
||||
assert(tt)
|
||||
assert(txs.exists(_._1 == txid))
|
||||
val p = txs(txid)
|
||||
assert(p.in_mempool)
|
||||
assert(p.fee_delta == Bitcoins.one)
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to find mem pool ancestors and descendants" in {
|
||||
nodePair: FixtureParam =>
|
||||
nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
_ <- client.generate(1)
|
||||
@ -189,23 +187,22 @@ class MempoolRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to save the mem pool to disk" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
val localInstance = client.getDaemon match {
|
||||
case _: BitcoindInstanceRemote =>
|
||||
sys.error(s"Cannot have remote bitcoind instance in tests")
|
||||
case local: BitcoindInstanceLocal => local
|
||||
}
|
||||
val regTest =
|
||||
new File(localInstance.datadir.getAbsolutePath + "/regtest")
|
||||
assert(regTest.isDirectory)
|
||||
assert(!regTest.list().contains("mempool.dat"))
|
||||
for {
|
||||
_ <- client.saveMemPool()
|
||||
mempoolPath = regTest.toPath.resolve("mempool.dat")
|
||||
_ <- client.importMempool(mempoolPath)
|
||||
} yield assert(regTest.list().contains("mempool.dat"))
|
||||
it should "be able to save the mem pool to disk" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val localInstance = client.getDaemon match {
|
||||
case _: BitcoindInstanceRemote =>
|
||||
sys.error(s"Cannot have remote bitcoind instance in tests")
|
||||
case local: BitcoindInstanceLocal => local
|
||||
}
|
||||
val regTest =
|
||||
new File(localInstance.datadir.getAbsolutePath + "/regtest")
|
||||
assert(regTest.isDirectory)
|
||||
assert(!regTest.list().contains("mempool.dat"))
|
||||
for {
|
||||
_ <- client.saveMemPool()
|
||||
mempoolPath = regTest.toPath.resolve("mempool.dat")
|
||||
_ <- client.importMempool(mempoolPath)
|
||||
} yield assert(regTest.list().contains("mempool.dat"))
|
||||
}
|
||||
|
||||
it should "get tx spending prev out" in { nodePair =>
|
||||
@ -219,7 +216,7 @@ class MempoolRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
} yield assert(spending.spendingtxid.contains(txid))
|
||||
}
|
||||
|
||||
it must "getrawmempool verbose" in { case nodePair =>
|
||||
it must "getrawmempool verbose" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
// generate block to clear out mempool for test
|
||||
|
@ -95,7 +95,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
|
||||
behavior of "WalletRpc"
|
||||
|
||||
it should "be able to list wallets" in { nodePair: FixtureParam =>
|
||||
it should "be able to list wallets" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
wallets <- client.listWallets
|
||||
@ -106,7 +106,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to backup the wallet" in { nodePair: FixtureParam =>
|
||||
it should "be able to backup the wallet" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val localInstance = client.getDaemon match {
|
||||
case _: BitcoindInstanceRemote =>
|
||||
@ -127,7 +127,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to lock and unlock the wallet" in { _: FixtureParam =>
|
||||
it should "be able to lock and unlock the wallet" in { _ =>
|
||||
for {
|
||||
walletClient <- walletClientF
|
||||
_ <- walletClient.walletLock()
|
||||
@ -143,42 +143,40 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
} yield assert(newInfo.unlocked_until.contains(0))
|
||||
}
|
||||
|
||||
it should "be able to get an address from bitcoind" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
_ <- {
|
||||
val addrFuts =
|
||||
List(
|
||||
client.getNewAddress,
|
||||
client.getNewAddress(AddressType.Bech32),
|
||||
client.getNewAddress(AddressType.P2SHSegwit),
|
||||
client.getNewAddress(AddressType.Legacy)
|
||||
)
|
||||
Future.sequence(addrFuts)
|
||||
}
|
||||
} yield succeed
|
||||
it should "be able to get an address from bitcoind" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
_ <- {
|
||||
val addrFuts =
|
||||
List(
|
||||
client.getNewAddress,
|
||||
client.getNewAddress(AddressType.Bech32),
|
||||
client.getNewAddress(AddressType.P2SHSegwit),
|
||||
client.getNewAddress(AddressType.Legacy)
|
||||
)
|
||||
Future.sequence(addrFuts)
|
||||
}
|
||||
} yield succeed
|
||||
}
|
||||
|
||||
it should "be able to get a new raw change address" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
_ <- {
|
||||
val addrFuts =
|
||||
List(
|
||||
client.getRawChangeAddress,
|
||||
client.getRawChangeAddress(AddressType.Legacy),
|
||||
client.getRawChangeAddress(AddressType.Bech32),
|
||||
client.getRawChangeAddress(AddressType.P2SHSegwit)
|
||||
)
|
||||
Future.sequence(addrFuts)
|
||||
}
|
||||
} yield succeed
|
||||
it should "be able to get a new raw change address" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
_ <- {
|
||||
val addrFuts =
|
||||
List(
|
||||
client.getRawChangeAddress,
|
||||
client.getRawChangeAddress(AddressType.Legacy),
|
||||
client.getRawChangeAddress(AddressType.Bech32),
|
||||
client.getRawChangeAddress(AddressType.P2SHSegwit)
|
||||
)
|
||||
Future.sequence(addrFuts)
|
||||
}
|
||||
} yield succeed
|
||||
}
|
||||
|
||||
it should "be able to get the amount recieved by some address" in {
|
||||
nodePair: FixtureParam =>
|
||||
nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
address <- client.getNewAddress
|
||||
@ -186,23 +184,22 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
} yield assert(amount == Bitcoins(0))
|
||||
}
|
||||
|
||||
it should "be able to get the unconfirmed balance" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
balance <- client.getUnconfirmedBalance
|
||||
transaction <- BitcoindRpcTestUtil.sendCoinbaseTransaction(
|
||||
client,
|
||||
client
|
||||
)
|
||||
newBalance <- client.getUnconfirmedBalance
|
||||
} yield {
|
||||
assert(balance == Bitcoins(0))
|
||||
assert(newBalance == transaction.amount)
|
||||
}
|
||||
it should "be able to get the unconfirmed balance" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
balance <- client.getUnconfirmedBalance
|
||||
transaction <- BitcoindRpcTestUtil.sendCoinbaseTransaction(
|
||||
client,
|
||||
client
|
||||
)
|
||||
newBalance <- client.getUnconfirmedBalance
|
||||
} yield {
|
||||
assert(balance == Bitcoins(0))
|
||||
assert(newBalance == transaction.amount)
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to get the wallet info" in { nodePair: FixtureParam =>
|
||||
it should "be able to get the wallet info" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
info <- client.getWalletInfo
|
||||
@ -214,7 +211,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to refill the keypool" ignore { nodePair: FixtureParam =>
|
||||
it should "be able to refill the keypool" ignore { nodePair =>
|
||||
// ignore until: https://github.com/bitcoin/bitcoin/issues/29924
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
@ -224,7 +221,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
} yield assert(newInfo.keypoolsize == info.keypoolsize + 1)
|
||||
}
|
||||
|
||||
it should "be able to change the wallet password" in { _: FixtureParam =>
|
||||
it should "be able to change the wallet password" in { _ =>
|
||||
val newPass = "new_password"
|
||||
|
||||
for {
|
||||
@ -247,7 +244,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to list address groupings" in { nodePair: FixtureParam =>
|
||||
it should "be able to list address groupings" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
val amount = Bitcoins(1.25)
|
||||
@ -318,7 +315,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to send to an address" in { nodePair: FixtureParam =>
|
||||
it should "be able to send to an address" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
@ -331,22 +328,21 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to send btc to many addresses" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
address1 <- otherClient.getNewAddress
|
||||
address2 <- otherClient.getNewAddress
|
||||
txid <-
|
||||
client
|
||||
.sendMany(Map(address1 -> Bitcoins(1), address2 -> Bitcoins(2)))
|
||||
transaction <- client.getTransaction(txid)
|
||||
} yield {
|
||||
assert(transaction.amount == Bitcoins(-3))
|
||||
assert(transaction.details.exists(_.address.contains(address1)))
|
||||
assert(transaction.details.exists(_.address.contains(address2)))
|
||||
}
|
||||
it should "be able to send btc to many addresses" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
address1 <- otherClient.getNewAddress
|
||||
address2 <- otherClient.getNewAddress
|
||||
txid <-
|
||||
client
|
||||
.sendMany(Map(address1 -> Bitcoins(1), address2 -> Bitcoins(2)))
|
||||
transaction <- client.getTransaction(txid)
|
||||
} yield {
|
||||
assert(transaction.amount == Bitcoins(-3))
|
||||
assert(transaction.details.exists(_.address.contains(address1)))
|
||||
assert(transaction.details.exists(_.address.contains(address2)))
|
||||
}
|
||||
}
|
||||
|
||||
it should "generate a bech32m address" in { nodePair =>
|
||||
@ -359,7 +355,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
|
||||
it should "be able to list transactions by receiving addresses" in {
|
||||
nodePair: FixtureParam =>
|
||||
nodePair =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
@ -385,7 +381,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to list transactions" in { nodePair: FixtureParam =>
|
||||
it should "be able to list transactions" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
@ -405,7 +401,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to get the balance" in { nodePair: FixtureParam =>
|
||||
it should "be able to get the balance" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
balance <- client.getBalance
|
||||
@ -417,7 +413,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to load a wallet" in { nodePair: FixtureParam =>
|
||||
it should "be able to load a wallet" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val name = "tmp_wallet"
|
||||
val localInstance = client.getDaemon match {
|
||||
@ -440,7 +436,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to set the tx fee" in { nodePair: FixtureParam =>
|
||||
it should "be able to set the tx fee" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
success <- client.setTxFee(Bitcoins(0.01))
|
||||
@ -451,7 +447,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to bump a mem pool tx fee" in { nodePair: FixtureParam =>
|
||||
it should "be able to bump a mem pool tx fee" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
@ -484,101 +480,99 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
} yield assert(tx.fee.get < bumpedTx.fee)
|
||||
}
|
||||
|
||||
it should "be able to sign a raw transaction with the wallet" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
address <- otherClient.getNewAddress
|
||||
transactionWithoutFunds <-
|
||||
client
|
||||
.createRawTransaction(Vector.empty, Map(address -> Bitcoins(1)))
|
||||
transactionResult <- client.fundRawTransaction(transactionWithoutFunds)
|
||||
transaction = transactionResult.hex
|
||||
singedTx <- client.signRawTransactionWithWallet(transaction).map(_.hex)
|
||||
it should "be able to sign a raw transaction with the wallet" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
for {
|
||||
address <- otherClient.getNewAddress
|
||||
transactionWithoutFunds <-
|
||||
client
|
||||
.createRawTransaction(Vector.empty, Map(address -> Bitcoins(1)))
|
||||
transactionResult <- client.fundRawTransaction(transactionWithoutFunds)
|
||||
transaction = transactionResult.hex
|
||||
singedTx <- client.signRawTransactionWithWallet(transaction).map(_.hex)
|
||||
|
||||
// Will throw error if invalid
|
||||
_ <- client.sendRawTransaction(singedTx)
|
||||
} yield {
|
||||
assert(
|
||||
transaction.outputs.contains(
|
||||
TransactionOutput(Bitcoins(1), address.scriptPubKey)
|
||||
)
|
||||
// Will throw error if invalid
|
||||
_ <- client.sendRawTransaction(singedTx)
|
||||
} yield {
|
||||
assert(
|
||||
transaction.outputs.contains(
|
||||
TransactionOutput(Bitcoins(1), address.scriptPubKey)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
it should "generate the same (low R) signatures as bitcoin-s" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
val privKey = ECPrivateKey.freshPrivateKey
|
||||
val np = RegTest
|
||||
val descriptor = P2WPKHDescriptor(privKey, np)
|
||||
val spk = P2WPKHWitnessSPKV0(privKey.publicKey)
|
||||
val importedAddress = Bech32Address.fromScriptPubKey(spk, np)
|
||||
for {
|
||||
fundingTxId <- otherClient.sendToAddress(
|
||||
importedAddress,
|
||||
Bitcoins(1.01)
|
||||
it should "generate the same (low R) signatures as bitcoin-s" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val otherClient = nodePair.node2
|
||||
val privKey = ECPrivateKey.freshPrivateKey
|
||||
val np = RegTest
|
||||
val descriptor = P2WPKHDescriptor(privKey, np)
|
||||
val spk = P2WPKHWitnessSPKV0(privKey.publicKey)
|
||||
val importedAddress = Bech32Address.fromScriptPubKey(spk, np)
|
||||
for {
|
||||
fundingTxId <- otherClient.sendToAddress(
|
||||
importedAddress,
|
||||
Bitcoins(1.01)
|
||||
)
|
||||
_ <- otherClient.generate(1)
|
||||
vout <- otherClient
|
||||
.getRawTransactionRaw(fundingTxId)
|
||||
.map(
|
||||
_.outputs.zipWithIndex
|
||||
.find(_._1.scriptPubKey == descriptor.scriptPubKey)
|
||||
)
|
||||
_ <- otherClient.generate(1)
|
||||
vout <- otherClient
|
||||
.getRawTransactionRaw(fundingTxId)
|
||||
.map(
|
||||
_.outputs.zipWithIndex
|
||||
.find(_._1.scriptPubKey == descriptor.scriptPubKey)
|
||||
.map(_.get._2)
|
||||
fundingPrevOut = TransactionOutPoint(fundingTxId, vout)
|
||||
fundingInput = TransactionInput(
|
||||
fundingPrevOut,
|
||||
ScriptSignature.empty,
|
||||
TransactionConstants.sequence
|
||||
)
|
||||
address <- otherClient.getNewAddress
|
||||
transaction <-
|
||||
client
|
||||
.createRawTransaction(
|
||||
inputs = Vector(fundingInput),
|
||||
outputs = Map(address -> Bitcoins.one)
|
||||
)
|
||||
.map(_.get._2)
|
||||
fundingPrevOut = TransactionOutPoint(fundingTxId, vout)
|
||||
fundingInput = TransactionInput(
|
||||
fundingPrevOut,
|
||||
ScriptSignature.empty,
|
||||
TransactionConstants.sequence
|
||||
)
|
||||
address <- otherClient.getNewAddress
|
||||
transaction <-
|
||||
client
|
||||
.createRawTransaction(
|
||||
inputs = Vector(fundingInput),
|
||||
outputs = Map(address -> Bitcoins.one)
|
||||
)
|
||||
signedTx <- client
|
||||
.signRawTransactionWithKey(transaction, Vector(privKey))
|
||||
.map(_.hex)
|
||||
_ <- client.broadcastTransaction(signedTx)
|
||||
// Validate signature against bitcoin-s generated one
|
||||
outPoint = transaction.inputs.head.previousOutput
|
||||
prevTx <- client.getRawTransactionRaw(outPoint.txIdBE)
|
||||
output = prevTx.outputs(outPoint.vout.toInt)
|
||||
_ = BitcoinAddress.fromScriptPubKey(output.scriptPubKey, RegTest)
|
||||
} yield {
|
||||
val partialSig = BitcoinSigner.signSingle(
|
||||
ECSignatureParams(
|
||||
P2WPKHV0InputInfo(outPoint, output.value, privKey.publicKey),
|
||||
prevTx,
|
||||
privKey,
|
||||
HashType.sigHashAll
|
||||
),
|
||||
transaction,
|
||||
isDummySignature = false
|
||||
)
|
||||
signedTx <- client
|
||||
.signRawTransactionWithKey(transaction, Vector(privKey))
|
||||
.map(_.hex)
|
||||
_ <- client.broadcastTransaction(signedTx)
|
||||
// Validate signature against bitcoin-s generated one
|
||||
outPoint = transaction.inputs.head.previousOutput
|
||||
prevTx <- client.getRawTransactionRaw(outPoint.txIdBE)
|
||||
output = prevTx.outputs(outPoint.vout.toInt)
|
||||
_ = BitcoinAddress.fromScriptPubKey(output.scriptPubKey, RegTest)
|
||||
} yield {
|
||||
val partialSig = BitcoinSigner.signSingle(
|
||||
ECSignatureParams(
|
||||
P2WPKHV0InputInfo(outPoint, output.value, privKey.publicKey),
|
||||
prevTx,
|
||||
privKey,
|
||||
HashType.sigHashAll
|
||||
),
|
||||
transaction,
|
||||
isDummySignature = false
|
||||
)
|
||||
|
||||
signedTx match {
|
||||
case btx: NonWitnessTransaction =>
|
||||
assert(
|
||||
btx.inputs.head.scriptSignature.signatures.head == partialSig.signature
|
||||
)
|
||||
case wtx: WitnessTransaction =>
|
||||
wtx.witness.head match {
|
||||
case p2wpkh: P2WPKHWitnessV0 =>
|
||||
assert(p2wpkh.pubKey == partialSig.pubKey)
|
||||
assert(p2wpkh.signature == partialSig.signature)
|
||||
case _: P2WSHWitnessV0 | EmptyScriptWitness | _: TaprootWitness =>
|
||||
fail("Expected P2WPKH")
|
||||
}
|
||||
}
|
||||
signedTx match {
|
||||
case btx: NonWitnessTransaction =>
|
||||
assert(
|
||||
btx.inputs.head.scriptSignature.signatures.head == partialSig.signature
|
||||
)
|
||||
case wtx: WitnessTransaction =>
|
||||
wtx.witness.head match {
|
||||
case p2wpkh: P2WPKHWitnessV0 =>
|
||||
assert(p2wpkh.pubKey == partialSig.pubKey)
|
||||
assert(p2wpkh.signature == partialSig.signature)
|
||||
case _: P2WSHWitnessV0 | EmptyScriptWitness | _: TaprootWitness =>
|
||||
fail("Expected P2WPKH")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to set the wallet flag 'avoid_reuse'" in { nodePair =>
|
||||
@ -656,7 +650,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "create a descriptor wallet" in { nodePair: FixtureParam =>
|
||||
it should "create a descriptor wallet" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
_ <- client.unloadWallet(BitcoindRpcClient.DEFAULT_WALLET_NAME)
|
||||
@ -672,21 +666,20 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "create a wallet with private keys disabled" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
_ <- client.unloadWallet(BitcoindRpcClient.DEFAULT_WALLET_NAME)
|
||||
_ <- client.createWallet("privKeyWallet", disablePrivateKeys = true)
|
||||
walletPriv <- client.getWalletInfo("privKeyWallet")
|
||||
_ <- client.unloadWallet("privKeyWallet")
|
||||
_ <- client.loadWallet(BitcoindRpcClient.DEFAULT_WALLET_NAME)
|
||||
} yield {
|
||||
walletPriv match {
|
||||
case walletInfoPostV22: GetWalletInfoResultPostV22 =>
|
||||
assert(!walletInfoPostV22.private_keys_enabled)
|
||||
}
|
||||
it should "create a wallet with private keys disabled" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
_ <- client.unloadWallet(BitcoindRpcClient.DEFAULT_WALLET_NAME)
|
||||
_ <- client.createWallet("privKeyWallet", disablePrivateKeys = true)
|
||||
walletPriv <- client.getWalletInfo("privKeyWallet")
|
||||
_ <- client.unloadWallet("privKeyWallet")
|
||||
_ <- client.loadWallet(BitcoindRpcClient.DEFAULT_WALLET_NAME)
|
||||
} yield {
|
||||
walletPriv match {
|
||||
case walletInfoPostV22: GetWalletInfoResultPostV22 =>
|
||||
assert(!walletInfoPostV22.private_keys_enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
it should "return a list of wallets" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
@ -698,7 +691,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to create a multi sig address" in { case nodePair =>
|
||||
it should "be able to create a multi sig address" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val ecPrivKey1 = ECPrivateKey.freshPrivateKey
|
||||
val ecPrivKey2 = ECPrivateKey.freshPrivateKey
|
||||
@ -715,7 +708,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
} yield succeed
|
||||
}
|
||||
|
||||
it should "be able to decode a reedem script" in { case nodePair =>
|
||||
it should "be able to decode a reedem script" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val walletName = "decodeRWallet"
|
||||
|
||||
@ -759,7 +752,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
} // 1 bitcoin + fees
|
||||
}
|
||||
|
||||
it should "be able to validate a bitcoin address" in { case nodePair =>
|
||||
it should "be able to validate a bitcoin address" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
address <- client.getNewAddress
|
||||
@ -767,7 +760,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
} yield assert(validation.isvalid)
|
||||
}
|
||||
|
||||
it should "have extra address information" in { case nodePair =>
|
||||
it should "have extra address information" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
address <- client.getNewAddress
|
||||
@ -780,7 +773,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
}
|
||||
|
||||
it should "analyze a descriptor" in { case nodePair =>
|
||||
it should "analyze a descriptor" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val descriptor =
|
||||
Descriptor.fromString(
|
||||
@ -829,7 +822,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
||||
}
|
||||
|
||||
it should "be able to get the address info for a given address" in {
|
||||
case nodePair =>
|
||||
nodePair =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
addr <- client.getNewAddress
|
||||
|
@ -2,7 +2,6 @@ package org.bitcoins.rpc.v18
|
||||
|
||||
import org.bitcoins.core.currency.Bitcoins
|
||||
import org.bitcoins.core.psbt.PSBT
|
||||
import org.bitcoins.rpc.client.common.BitcoindRpcClient
|
||||
import org.bitcoins.testkit.rpc.BitcoindFixturesFundedCachedNewest
|
||||
|
||||
import scala.concurrent.Future
|
||||
@ -15,40 +14,38 @@ class PsbtRpcTest extends BitcoindFixturesFundedCachedNewest {
|
||||
|
||||
behavior of "PsbtRpc"
|
||||
|
||||
it should "return something when analyzePsbt is called" in {
|
||||
client: BitcoindRpcClient =>
|
||||
// PSBT with one P2PKH input and one P2SH-P2WPKH input both with non-final scriptSigs. P2SH-P2WPKH input's redeemScript is available. Outputs filled.
|
||||
val psbt =
|
||||
"cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEA3wIAAAABJoFxNx7f8oXpN63upLN7eAAMBWbLs61kZBcTykIXG/YAAAAAakcwRAIgcLIkUSPmv0dNYMW1DAQ9TGkaXSQ18Jo0p2YqncJReQoCIAEynKnazygL3zB0DsA5BCJCLIHLRYOUV663b8Eu3ZWzASECZX0RjTNXuOD0ws1G23s59tnDjZpwq8ubLeXcjb/kzjH+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA="
|
||||
it should "return something when analyzePsbt is called" in { client =>
|
||||
// PSBT with one P2PKH input and one P2SH-P2WPKH input both with non-final scriptSigs. P2SH-P2WPKH input's redeemScript is available. Outputs filled.
|
||||
val psbt =
|
||||
"cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEA3wIAAAABJoFxNx7f8oXpN63upLN7eAAMBWbLs61kZBcTykIXG/YAAAAAakcwRAIgcLIkUSPmv0dNYMW1DAQ9TGkaXSQ18Jo0p2YqncJReQoCIAEynKnazygL3zB0DsA5BCJCLIHLRYOUV663b8Eu3ZWzASECZX0RjTNXuOD0ws1G23s59tnDjZpwq8ubLeXcjb/kzjH+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA="
|
||||
|
||||
val resultF = client.analyzePsbt(PSBT.fromBase64(psbt))
|
||||
resultF.map { result =>
|
||||
val inputs = result.inputs
|
||||
assert(inputs.nonEmpty)
|
||||
}
|
||||
val resultF = client.analyzePsbt(PSBT.fromBase64(psbt))
|
||||
resultF.map { result =>
|
||||
val inputs = result.inputs
|
||||
assert(inputs.nonEmpty)
|
||||
}
|
||||
}
|
||||
it should "analyze a PSBT and return a non-empty result" in {
|
||||
client: BitcoindRpcClient =>
|
||||
// PSBT with one P2PKH input and one P2SH-P2WPKH input both with non-final scriptSigs. P2SH-P2WPKH input's redeemScript is available. Outputs filled.
|
||||
it should "analyze a PSBT and return a non-empty result" in { client =>
|
||||
// PSBT with one P2PKH input and one P2SH-P2WPKH input both with non-final scriptSigs. P2SH-P2WPKH input's redeemScript is available. Outputs filled.
|
||||
|
||||
val psbt =
|
||||
"cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEA3wIAAAABJoFxNx7f8oXpN63upLN7eAAMBWbLs61kZBcTykIXG/YAAAAAakcwRAIgcLIkUSPmv0dNYMW1DAQ9TGkaXSQ18Jo0p2YqncJReQoCIAEynKnazygL3zB0DsA5BCJCLIHLRYOUV663b8Eu3ZWzASECZX0RjTNXuOD0ws1G23s59tnDjZpwq8ubLeXcjb/kzjH+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA="
|
||||
val analyzedF = client.analyzePsbt(PSBT.fromBase64(psbt))
|
||||
val psbt =
|
||||
"cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEA3wIAAAABJoFxNx7f8oXpN63upLN7eAAMBWbLs61kZBcTykIXG/YAAAAAakcwRAIgcLIkUSPmv0dNYMW1DAQ9TGkaXSQ18Jo0p2YqncJReQoCIAEynKnazygL3zB0DsA5BCJCLIHLRYOUV663b8Eu3ZWzASECZX0RjTNXuOD0ws1G23s59tnDjZpwq8ubLeXcjb/kzjH+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA="
|
||||
val analyzedF = client.analyzePsbt(PSBT.fromBase64(psbt))
|
||||
|
||||
analyzedF.map { result =>
|
||||
assert(result.inputs.exists(_.next.isDefined))
|
||||
assert(result.inputs.exists(_.missing.head.pubkeys.head.nonEmpty))
|
||||
assert(result.inputs.exists(_.missing.head.signatures.isEmpty))
|
||||
assert(result.inputs.exists(_.missing.head.redeemscript.isEmpty))
|
||||
assert(result.inputs.exists(_.missing.head.witnessscript.isEmpty))
|
||||
assert(result.inputs.exists(_.is_final) == false)
|
||||
assert(result.estimated_feerate.isDefined == false)
|
||||
assert(result.estimated_vsize.isDefined == false)
|
||||
assert(result.fee.isDefined)
|
||||
assert(result.next.nonEmpty)
|
||||
}
|
||||
analyzedF.map { result =>
|
||||
assert(result.inputs.exists(_.next.isDefined))
|
||||
assert(result.inputs.exists(_.missing.head.pubkeys.head.nonEmpty))
|
||||
assert(result.inputs.exists(_.missing.head.signatures.isEmpty))
|
||||
assert(result.inputs.exists(_.missing.head.redeemscript.isEmpty))
|
||||
assert(result.inputs.exists(_.missing.head.witnessscript.isEmpty))
|
||||
assert(result.inputs.exists(_.is_final) == false)
|
||||
assert(result.estimated_feerate.isDefined == false)
|
||||
assert(result.estimated_vsize.isDefined == false)
|
||||
assert(result.fee.isDefined)
|
||||
assert(result.next.nonEmpty)
|
||||
}
|
||||
}
|
||||
it should "correctly analyze a psbt " in { client: BitcoindRpcClient =>
|
||||
it should "correctly analyze a psbt " in { client =>
|
||||
val psbt =
|
||||
// PSBT with one P2PKH input and one P2SH-P2WPKH input both with non-final scriptSigs. P2SH-P2WPKH input's redeemScript is available. Outputs filled.
|
||||
"cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEA3wIAAAABJoFxNx7f8oXpN63upLN7eAAMBWbLs61kZBcTykIXG/YAAAAAakcwRAIgcLIkUSPmv0dNYMW1DAQ9TGkaXSQ18Jo0p2YqncJReQoCIAEynKnazygL3zB0DsA5BCJCLIHLRYOUV663b8Eu3ZWzASECZX0RjTNXuOD0ws1G23s59tnDjZpwq8ubLeXcjb/kzjH+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA="
|
||||
@ -75,7 +72,7 @@ class PsbtRpcTest extends BitcoindFixturesFundedCachedNewest {
|
||||
|
||||
// Todo: figure out how to implement a test here
|
||||
it should "check to see if the utxoUpdate input has been updated" in {
|
||||
client: BitcoindRpcClient =>
|
||||
client =>
|
||||
val psbt =
|
||||
PSBT.fromBase64(
|
||||
"cHNidP8BACoCAAAAAAFAQg8AAAAAABepFG6Rty1Vk+fUOR4v9E6R6YXDFkHwhwAAAAAAAA=="
|
||||
@ -93,7 +90,7 @@ class PsbtRpcTest extends BitcoindFixturesFundedCachedNewest {
|
||||
* resulting PSBT represented as a string is very different so we can't just
|
||||
* search for parts of either PSBT.
|
||||
*/
|
||||
it should "joinpsbts" in { client: BitcoindRpcClient =>
|
||||
it should "joinpsbts" in { client =>
|
||||
val seqofpsbts = Vector(
|
||||
PSBT.fromBase64(
|
||||
"cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAAAA"
|
||||
|
@ -22,7 +22,7 @@ import scala.concurrent.Future
|
||||
|
||||
/** RPC calls related to mining
|
||||
*/
|
||||
trait MiningRpc { self: Client with BlockchainRpc =>
|
||||
trait MiningRpc { self: Client & BlockchainRpc =>
|
||||
|
||||
def generateToAddress(
|
||||
blocks: Int,
|
||||
|
@ -30,7 +30,7 @@ class BitcoindChainHandlerViaZmqTest extends ChainDbUnitTest {
|
||||
bitcoindCount <- bitcoindBlockCountF
|
||||
_ = assert(bitcoindCount == bitcoinSBlockCount)
|
||||
address <- bitcoind.getNewAddress
|
||||
hash +: _ <- bitcoind.generateToAddress(1, address)
|
||||
case hash +: _ <- bitcoind.generateToAddress(1, address)
|
||||
_ <- {
|
||||
// test case is totally async since we
|
||||
// can't monitor processing flow for zmq
|
||||
|
@ -58,207 +58,200 @@ class WalletStorageTest extends BitcoinSWalletTest with BeforeAndAfterEach {
|
||||
decryptedExtPrivKey
|
||||
}
|
||||
|
||||
it must "write and read an encrypted mnemonic to disk" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
it must "write and read an encrypted mnemonic to disk" in { walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
|
||||
val writtenMnemonic = getAndWriteMnemonic(walletConf)
|
||||
val writtenMnemonic = getAndWriteMnemonic(walletConf)
|
||||
|
||||
// should have been written by now
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, passphrase)
|
||||
read match {
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
assert(writtenMnemonic.mnemonicCode == readMnemonic.mnemonicCode)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenMnemonic.creationTime.getEpochSecond == readMnemonic.creationTime.getEpochSecond
|
||||
)
|
||||
assert(writtenMnemonic.backupTimeOpt.isEmpty)
|
||||
case Right(xprv: DecryptedExtPrivKey) =>
|
||||
fail(s"Parsed unexpected type of seed $xprv")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
// should have been written by now
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, passphrase)
|
||||
read match {
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
assert(writtenMnemonic.mnemonicCode == readMnemonic.mnemonicCode)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenMnemonic.creationTime.getEpochSecond == readMnemonic.creationTime.getEpochSecond
|
||||
)
|
||||
assert(writtenMnemonic.backupTimeOpt.isEmpty)
|
||||
case Right(xprv: DecryptedExtPrivKey) =>
|
||||
fail(s"Parsed unexpected type of seed $xprv")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
}
|
||||
|
||||
it must "write and read an encrypted seed to disk" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
it must "write and read an encrypted seed to disk" in { walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
|
||||
val writtenXprv = getAndWriteXprv(walletConf)
|
||||
val writtenXprv = getAndWriteXprv(walletConf)
|
||||
|
||||
// should have been written by now
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, passphrase)
|
||||
read match {
|
||||
case Right(readXprv: DecryptedExtPrivKey) =>
|
||||
assert(writtenXprv.xprv == readXprv.xprv)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenXprv.creationTime.getEpochSecond == readXprv.creationTime.getEpochSecond
|
||||
)
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
fail(s"Parsed unexpected type of seed $readMnemonic")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
// should have been written by now
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, passphrase)
|
||||
read match {
|
||||
case Right(readXprv: DecryptedExtPrivKey) =>
|
||||
assert(writtenXprv.xprv == readXprv.xprv)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenXprv.creationTime.getEpochSecond == readXprv.creationTime.getEpochSecond
|
||||
)
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
fail(s"Parsed unexpected type of seed $readMnemonic")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
}
|
||||
|
||||
it must "write and read an unencrypted mnemonic to disk" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val mnemonicCode = CryptoGenerators.mnemonicCode.sampleSome
|
||||
val writtenMnemonic =
|
||||
DecryptedMnemonic(mnemonicCode, TimeUtil.now, None, false)
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
WalletStorage.writeSeedToDisk(seedPath, writtenMnemonic)
|
||||
it must "write and read an unencrypted mnemonic to disk" in { walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val mnemonicCode = CryptoGenerators.mnemonicCode.sampleSome
|
||||
val writtenMnemonic =
|
||||
DecryptedMnemonic(mnemonicCode, TimeUtil.now, None, false)
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
WalletStorage.writeSeedToDisk(seedPath, writtenMnemonic)
|
||||
|
||||
// should have been written by now
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, None)
|
||||
read match {
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
assert(writtenMnemonic.mnemonicCode == readMnemonic.mnemonicCode)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenMnemonic.creationTime.getEpochSecond == readMnemonic.creationTime.getEpochSecond
|
||||
)
|
||||
case Right(xprv: DecryptedExtPrivKey) =>
|
||||
fail(s"Parsed unexpected type of seed $xprv")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
// should have been written by now
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, None)
|
||||
read match {
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
assert(writtenMnemonic.mnemonicCode == readMnemonic.mnemonicCode)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenMnemonic.creationTime.getEpochSecond == readMnemonic.creationTime.getEpochSecond
|
||||
)
|
||||
case Right(xprv: DecryptedExtPrivKey) =>
|
||||
fail(s"Parsed unexpected type of seed $xprv")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
}
|
||||
|
||||
it must "write and read an unencrypted xprv to disk" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val xprv = CryptoGenerators.extPrivateKey.sampleSome
|
||||
val writtenXprv = DecryptedExtPrivKey(xprv, TimeUtil.now, None, false)
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
WalletStorage.writeSeedToDisk(seedPath, writtenXprv)
|
||||
it must "write and read an unencrypted xprv to disk" in { walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val xprv = CryptoGenerators.extPrivateKey.sampleSome
|
||||
val writtenXprv = DecryptedExtPrivKey(xprv, TimeUtil.now, None, false)
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
WalletStorage.writeSeedToDisk(seedPath, writtenXprv)
|
||||
|
||||
// should have been written by now
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, None)
|
||||
read match {
|
||||
case Right(readXprv: DecryptedExtPrivKey) =>
|
||||
assert(writtenXprv.xprv == readXprv.xprv)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenXprv.creationTime.getEpochSecond == readXprv.creationTime.getEpochSecond
|
||||
)
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
fail(s"Parsed unexpected type of seed $readMnemonic")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
// should have been written by now
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, None)
|
||||
read match {
|
||||
case Right(readXprv: DecryptedExtPrivKey) =>
|
||||
assert(writtenXprv.xprv == readXprv.xprv)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenXprv.creationTime.getEpochSecond == readXprv.creationTime.getEpochSecond
|
||||
)
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
fail(s"Parsed unexpected type of seed $readMnemonic")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
}
|
||||
|
||||
it must "change the password of an encrypted mnemonic" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
it must "change the password of an encrypted mnemonic" in { walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
|
||||
val writtenMnemonic = getAndWriteMnemonic(walletConf)
|
||||
val writtenMnemonic = getAndWriteMnemonic(walletConf)
|
||||
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
|
||||
WalletStorage.changeAesPassword(
|
||||
seedPath = seedPath,
|
||||
oldPasswordOpt = passphrase,
|
||||
newPasswordOpt = badPassphrase
|
||||
)
|
||||
WalletStorage.changeAesPassword(
|
||||
seedPath = seedPath,
|
||||
oldPasswordOpt = passphrase,
|
||||
newPasswordOpt = badPassphrase
|
||||
)
|
||||
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, badPassphrase)
|
||||
read match {
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
assert(writtenMnemonic.mnemonicCode == readMnemonic.mnemonicCode)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenMnemonic.creationTime.getEpochSecond == readMnemonic.creationTime.getEpochSecond
|
||||
)
|
||||
case Right(xprv: DecryptedExtPrivKey) =>
|
||||
fail(s"Parsed unexpected type of seed $xprv")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, badPassphrase)
|
||||
read match {
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
assert(writtenMnemonic.mnemonicCode == readMnemonic.mnemonicCode)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenMnemonic.creationTime.getEpochSecond == readMnemonic.creationTime.getEpochSecond
|
||||
)
|
||||
case Right(xprv: DecryptedExtPrivKey) =>
|
||||
fail(s"Parsed unexpected type of seed $xprv")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
}
|
||||
|
||||
it must "change the password of an unencrypted mnemonic" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val mnemonicCode = CryptoGenerators.mnemonicCode.sampleSome
|
||||
val writtenMnemonic =
|
||||
DecryptedMnemonic(mnemonicCode, TimeUtil.now, None, false)
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
WalletStorage.writeSeedToDisk(seedPath, writtenMnemonic)
|
||||
it must "change the password of an unencrypted mnemonic" in { walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val mnemonicCode = CryptoGenerators.mnemonicCode.sampleSome
|
||||
val writtenMnemonic =
|
||||
DecryptedMnemonic(mnemonicCode, TimeUtil.now, None, false)
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
WalletStorage.writeSeedToDisk(seedPath, writtenMnemonic)
|
||||
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
|
||||
WalletStorage.changeAesPassword(
|
||||
seedPath = seedPath,
|
||||
oldPasswordOpt = None,
|
||||
newPasswordOpt = badPassphrase
|
||||
)
|
||||
WalletStorage.changeAesPassword(
|
||||
seedPath = seedPath,
|
||||
oldPasswordOpt = None,
|
||||
newPasswordOpt = badPassphrase
|
||||
)
|
||||
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, badPassphrase)
|
||||
read match {
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
assert(writtenMnemonic.mnemonicCode == readMnemonic.mnemonicCode)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenMnemonic.creationTime.getEpochSecond == readMnemonic.creationTime.getEpochSecond
|
||||
)
|
||||
case Right(xprv: DecryptedExtPrivKey) =>
|
||||
fail(s"Parsed unexpected type of seed $xprv")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, badPassphrase)
|
||||
read match {
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
assert(writtenMnemonic.mnemonicCode == readMnemonic.mnemonicCode)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenMnemonic.creationTime.getEpochSecond == readMnemonic.creationTime.getEpochSecond
|
||||
)
|
||||
case Right(xprv: DecryptedExtPrivKey) =>
|
||||
fail(s"Parsed unexpected type of seed $xprv")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
}
|
||||
|
||||
it must "remove the password from an encrypted mnemonic" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
it must "remove the password from an encrypted mnemonic" in { walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
|
||||
val writtenMnemonic = getAndWriteMnemonic(walletConf)
|
||||
val writtenMnemonic = getAndWriteMnemonic(walletConf)
|
||||
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
assert(walletConf.kmConf.seedExists())
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
|
||||
WalletStorage.changeAesPassword(
|
||||
seedPath = seedPath,
|
||||
oldPasswordOpt = passphrase,
|
||||
newPasswordOpt = None
|
||||
)
|
||||
WalletStorage.changeAesPassword(
|
||||
seedPath = seedPath,
|
||||
oldPasswordOpt = passphrase,
|
||||
newPasswordOpt = None
|
||||
)
|
||||
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, None)
|
||||
read match {
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
assert(writtenMnemonic.mnemonicCode == readMnemonic.mnemonicCode)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenMnemonic.creationTime.getEpochSecond == readMnemonic.creationTime.getEpochSecond
|
||||
)
|
||||
case Right(xprv: DecryptedExtPrivKey) =>
|
||||
fail(s"Parsed unexpected type of seed $xprv")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
val read =
|
||||
WalletStorage.decryptSeedFromDisk(seedPath, None)
|
||||
read match {
|
||||
case Right(readMnemonic: DecryptedMnemonic) =>
|
||||
assert(writtenMnemonic.mnemonicCode == readMnemonic.mnemonicCode)
|
||||
// Need to compare using getEpochSecond because when reading an epoch second
|
||||
// it will not include the milliseconds that writtenMnemonic will have
|
||||
assert(
|
||||
writtenMnemonic.creationTime.getEpochSecond == readMnemonic.creationTime.getEpochSecond
|
||||
)
|
||||
case Right(xprv: DecryptedExtPrivKey) =>
|
||||
fail(s"Parsed unexpected type of seed $xprv")
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
}
|
||||
|
||||
it must "fail to change the aes password when given the wrong password" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
|
||||
getAndWriteMnemonic(walletConf)
|
||||
@ -276,7 +269,7 @@ class WalletStorageTest extends BitcoinSWalletTest with BeforeAndAfterEach {
|
||||
}
|
||||
|
||||
it must "fail to change the aes password when given no password" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
|
||||
getAndWriteMnemonic(walletConf)
|
||||
@ -294,7 +287,7 @@ class WalletStorageTest extends BitcoinSWalletTest with BeforeAndAfterEach {
|
||||
}
|
||||
|
||||
it must "fail to set the aes password when given an oldPassword" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val mnemonicCode = CryptoGenerators.mnemonicCode.sampleSome
|
||||
val writtenMnemonic =
|
||||
@ -627,7 +620,7 @@ class WalletStorageTest extends BitcoinSWalletTest with BeforeAndAfterEach {
|
||||
}
|
||||
|
||||
it must "write and read an encrypted ExtPrivateKey from disk" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
|
||||
val password = getBIP39PasswordOpt().getOrElse(BIP39Seed.EMPTY_PASSWORD)
|
||||
@ -657,7 +650,7 @@ class WalletStorageTest extends BitcoinSWalletTest with BeforeAndAfterEach {
|
||||
}
|
||||
|
||||
it must "write and read an unencrypted ExtPrivateKey from disk" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val mnemonicCode = CryptoGenerators.mnemonicCode.sampleSome
|
||||
val writtenMnemonic =
|
||||
@ -690,7 +683,7 @@ class WalletStorageTest extends BitcoinSWalletTest with BeforeAndAfterEach {
|
||||
}
|
||||
|
||||
it must "fail to read unencrypted ExtPrivateKey from disk that doesn't exist" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
val keyVersion = SegWitMainNetPriv
|
||||
@ -701,45 +694,44 @@ class WalletStorageTest extends BitcoinSWalletTest with BeforeAndAfterEach {
|
||||
|
||||
}
|
||||
|
||||
it must "safely create 2 seeds in the seed folder" in {
|
||||
(walletConfA: WalletAppConfig) =>
|
||||
assert(!walletConfA.kmConf.seedExists())
|
||||
getAndWriteMnemonic(walletConfA)
|
||||
assert(walletConfA.kmConf.seedExists())
|
||||
it must "safely create 2 seeds in the seed folder" in { walletConfA =>
|
||||
assert(!walletConfA.kmConf.seedExists())
|
||||
getAndWriteMnemonic(walletConfA)
|
||||
assert(walletConfA.kmConf.seedExists())
|
||||
|
||||
val otherWalletName = UUID.randomUUID().toString.replace("-", "")
|
||||
val otherWalletName = UUID.randomUUID().toString.replace("-", "")
|
||||
|
||||
val walletConfB = walletConfA.withOverrides(
|
||||
ConfigFactory.parseString(
|
||||
s"bitcoin-s.wallet.walletName = $otherWalletName"
|
||||
)
|
||||
val walletConfB = walletConfA.withOverrides(
|
||||
ConfigFactory.parseString(
|
||||
s"bitcoin-s.wallet.walletName = $otherWalletName"
|
||||
)
|
||||
)
|
||||
|
||||
assert(!walletConfB.kmConf.seedExists())
|
||||
getAndWriteXprv(walletConfB)
|
||||
assert(walletConfB.kmConf.seedExists())
|
||||
assert(!walletConfB.kmConf.seedExists())
|
||||
getAndWriteXprv(walletConfB)
|
||||
assert(walletConfB.kmConf.seedExists())
|
||||
|
||||
val expectedParentDir =
|
||||
walletConfA.baseDatadir.resolve(WalletStorage.SEED_FOLDER_NAME)
|
||||
assert(walletConfA.seedPath.getParent == expectedParentDir)
|
||||
assert(walletConfB.seedPath.getParent == expectedParentDir)
|
||||
assert(walletConfA.seedPath.getParent == walletConfB.seedPath.getParent)
|
||||
assert(walletConfA.seedPath != walletConfB.seedPath)
|
||||
val expectedParentDir =
|
||||
walletConfA.baseDatadir.resolve(WalletStorage.SEED_FOLDER_NAME)
|
||||
assert(walletConfA.seedPath.getParent == expectedParentDir)
|
||||
assert(walletConfB.seedPath.getParent == expectedParentDir)
|
||||
assert(walletConfA.seedPath.getParent == walletConfB.seedPath.getParent)
|
||||
assert(walletConfA.seedPath != walletConfB.seedPath)
|
||||
|
||||
val mnemonicAE =
|
||||
WalletStorage.decryptSeedFromDisk(walletConfA.seedPath, passphrase)
|
||||
val mnemonicBE =
|
||||
WalletStorage.decryptSeedFromDisk(walletConfB.seedPath, passphrase)
|
||||
val mnemonicAE =
|
||||
WalletStorage.decryptSeedFromDisk(walletConfA.seedPath, passphrase)
|
||||
val mnemonicBE =
|
||||
WalletStorage.decryptSeedFromDisk(walletConfB.seedPath, passphrase)
|
||||
|
||||
(mnemonicAE, mnemonicBE) match {
|
||||
case (Left(_), Left(_)) | (Right(_), Left(_)) | (Left(_), Right(_)) =>
|
||||
fail() // if any of them error, then fail
|
||||
case (Right(mnemonicA), Right(mnemonicB)) =>
|
||||
assert(mnemonicA != mnemonicB)
|
||||
}
|
||||
(mnemonicAE, mnemonicBE) match {
|
||||
case (Left(_), Left(_)) | (Right(_), Left(_)) | (Left(_), Right(_)) =>
|
||||
fail() // if any of them error, then fail
|
||||
case (Right(mnemonicA), Right(mnemonicB)) =>
|
||||
assert(mnemonicA != mnemonicB)
|
||||
}
|
||||
}
|
||||
|
||||
it must "backup an unencrypted seed" in { (walletConf: WalletAppConfig) =>
|
||||
it must "backup an unencrypted seed" in { walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val mnemonicCode = CryptoGenerators.mnemonicCode.sampleSome
|
||||
val writtenMnemonic =
|
||||
@ -768,7 +760,7 @@ class WalletStorageTest extends BitcoinSWalletTest with BeforeAndAfterEach {
|
||||
)
|
||||
}
|
||||
|
||||
it must "backup an encrypted seed" in { (walletConf: WalletAppConfig) =>
|
||||
it must "backup an encrypted seed" in { walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val mnemonicCode = CryptoGenerators.mnemonicCode.sampleSome
|
||||
val writtenMnemonic =
|
||||
@ -798,61 +790,59 @@ class WalletStorageTest extends BitcoinSWalletTest with BeforeAndAfterEach {
|
||||
)
|
||||
}
|
||||
|
||||
it must "set imported flag for an encrypted seed" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
val mnemonicCode = CryptoGenerators.mnemonicCode.sampleSome
|
||||
it must "set imported flag for an encrypted seed" in { walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
val mnemonicCode = CryptoGenerators.mnemonicCode.sampleSome
|
||||
|
||||
val writtenMnemonic =
|
||||
DecryptedMnemonic(mnemonicCode, TimeUtil.now, None, false).encrypt(
|
||||
passphrase.get
|
||||
)
|
||||
val writtenMnemonic =
|
||||
DecryptedMnemonic(mnemonicCode, TimeUtil.now, None, false).encrypt(
|
||||
passphrase.get
|
||||
)
|
||||
|
||||
WalletStorage.writeSeedToDisk(seedPath, writtenMnemonic)
|
||||
WalletStorage.decryptSeedFromDisk(walletConf.seedPath, passphrase) match {
|
||||
case Right(seed) => assert(!seed.imported)
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
WalletStorage.writeSeedToDisk(seedPath, writtenMnemonic)
|
||||
WalletStorage.decryptSeedFromDisk(walletConf.seedPath, passphrase) match {
|
||||
case Right(seed) => assert(!seed.imported)
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
|
||||
seedPath.toFile.delete()
|
||||
seedPath.toFile.delete()
|
||||
|
||||
val importedWrittenMnemonic =
|
||||
DecryptedMnemonic(mnemonicCode, TimeUtil.now, None, true).encrypt(
|
||||
passphrase.get
|
||||
)
|
||||
val importedWrittenMnemonic =
|
||||
DecryptedMnemonic(mnemonicCode, TimeUtil.now, None, true).encrypt(
|
||||
passphrase.get
|
||||
)
|
||||
|
||||
WalletStorage.writeSeedToDisk(seedPath, importedWrittenMnemonic)
|
||||
WalletStorage.decryptSeedFromDisk(walletConf.seedPath, passphrase) match {
|
||||
case Right(seed) => assert(seed.imported)
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
WalletStorage.writeSeedToDisk(seedPath, importedWrittenMnemonic)
|
||||
WalletStorage.decryptSeedFromDisk(walletConf.seedPath, passphrase) match {
|
||||
case Right(seed) => assert(seed.imported)
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
}
|
||||
|
||||
it must "set imported flag for an unencrypted seed" in {
|
||||
(walletConf: WalletAppConfig) =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
val mnemonicCode = CryptoGenerators.mnemonicCode.sampleSome
|
||||
it must "set imported flag for an unencrypted seed" in { walletConf =>
|
||||
assert(!walletConf.kmConf.seedExists())
|
||||
val seedPath = getSeedPath(walletConf)
|
||||
val mnemonicCode = CryptoGenerators.mnemonicCode.sampleSome
|
||||
|
||||
val writtenMnemonic =
|
||||
DecryptedMnemonic(mnemonicCode, TimeUtil.now, None, false)
|
||||
val writtenMnemonic =
|
||||
DecryptedMnemonic(mnemonicCode, TimeUtil.now, None, false)
|
||||
|
||||
WalletStorage.writeSeedToDisk(seedPath, writtenMnemonic)
|
||||
WalletStorage.decryptSeedFromDisk(walletConf.seedPath, None) match {
|
||||
case Right(seed) => assert(!seed.imported)
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
WalletStorage.writeSeedToDisk(seedPath, writtenMnemonic)
|
||||
WalletStorage.decryptSeedFromDisk(walletConf.seedPath, None) match {
|
||||
case Right(seed) => assert(!seed.imported)
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
|
||||
seedPath.toFile.delete()
|
||||
seedPath.toFile.delete()
|
||||
|
||||
val importedWrittenMnemonic =
|
||||
DecryptedMnemonic(mnemonicCode, TimeUtil.now, None, true)
|
||||
val importedWrittenMnemonic =
|
||||
DecryptedMnemonic(mnemonicCode, TimeUtil.now, None, true)
|
||||
|
||||
WalletStorage.writeSeedToDisk(seedPath, importedWrittenMnemonic)
|
||||
WalletStorage.decryptSeedFromDisk(walletConf.seedPath, None) match {
|
||||
case Right(seed) => assert(seed.imported)
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
WalletStorage.writeSeedToDisk(seedPath, importedWrittenMnemonic)
|
||||
WalletStorage.decryptSeedFromDisk(walletConf.seedPath, None) match {
|
||||
case Right(seed) => assert(seed.imported)
|
||||
case Left(err) => fail(err.toString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ import scala.util.{Failure, Success, Try}
|
||||
* https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
|
||||
*/
|
||||
class BIP39KeyManager(
|
||||
private[this] val rootExtPrivKey: ExtPrivateKey,
|
||||
private val rootExtPrivKey: ExtPrivateKey,
|
||||
val kmParams: KeyManagerParams,
|
||||
val creationTime: Instant,
|
||||
val imported: Boolean
|
||||
|
@ -48,12 +48,12 @@ class TorProtocolHandler(
|
||||
|
||||
import TorProtocolHandler._
|
||||
|
||||
private var receiver: ActorRef = _
|
||||
private var receiverOpt: Option[ActorRef] = None
|
||||
|
||||
private var address: Option[InetSocketAddress] = None
|
||||
|
||||
override def receive: Receive = { case Connected(_, _) =>
|
||||
receiver = sender()
|
||||
receiverOpt = Some(sender())
|
||||
sendCommand("PROTOCOLINFO 1")
|
||||
context.become(protocolInfo)
|
||||
}
|
||||
@ -202,7 +202,7 @@ class TorProtocolHandler(
|
||||
}
|
||||
|
||||
private def sendCommand(cmd: String): Unit = {
|
||||
receiver ! ByteString(s"$cmd\r\n")
|
||||
receiverOpt.foreach(_ ! ByteString(s"$cmd\r\n"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,19 +17,19 @@ class ZMQSubscriberTest extends AsyncFlatSpec with BitcoinSLogger {
|
||||
behavior of "ZMQSubscriber"
|
||||
|
||||
val rawBlockListener: Option[Block => Unit] = Some {
|
||||
{ block: Block =>
|
||||
{ block =>
|
||||
logger.debug(s"received raw block ${block.hex}")
|
||||
}
|
||||
}
|
||||
|
||||
val hashBlockListener: Option[DoubleSha256DigestBE => Unit] = Some {
|
||||
{ hash: DoubleSha256DigestBE =>
|
||||
{ hash =>
|
||||
logger.debug(s"received raw block hash ${hash.hex}")
|
||||
}
|
||||
}
|
||||
|
||||
val rawTxListener: Option[Transaction => Unit] = Some {
|
||||
{ tx: Transaction =>
|
||||
{ tx =>
|
||||
logger.debug(s"received raw tx ${tx.hex}")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user