mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-13 03:12:06 +01:00
2019 09 05 scalafmt update (#735)
* Update scalafmt to 2.0.1 * Scalafmt In this commit we 1) Reconfigure the .scalafmt.conf file 2) Add a scalafmt binary (same version as specified in conf file) 3) Use said binary on CI to check that everything is formatted correctly * Ran scalafmt * Update scalafmt ignore * Add scalafmt plugin to project/plugins.sbt, run it * run scalafmt
This commit is contained in:
parent
7197dd8f24
commit
46681e08d7
68 changed files with 581 additions and 521 deletions
|
@ -1,18 +1,46 @@
|
|||
version = "1.5.1"
|
||||
version = "2.0.1"
|
||||
# See Documentation at https://scalameta.org/scalafmt/#Configuration
|
||||
maxColumn=80
|
||||
docstrings=ScalaDoc
|
||||
continuationIndent.callSite=2
|
||||
continuationIndent.defnSite=4
|
||||
align=some
|
||||
align.openParenDefnSite=false
|
||||
newlines.alwaysBeforeTopLevelStatements=true
|
||||
newlines.sometimesBeforeColonInMethodReturnType=false
|
||||
newlines.alwaysBeforeCurlyBraceLambdaParams=false
|
||||
#newlines.alwaysBeforeMultilineDef=false
|
||||
trailingCommas = never
|
||||
maxColumn = 80
|
||||
docstrings = ScalaDoc
|
||||
continuationIndent {
|
||||
callSite = 2
|
||||
defnSite = 4
|
||||
}
|
||||
|
||||
align = some
|
||||
align {
|
||||
openParenDefnSite = false
|
||||
openParenCallSite = true
|
||||
}
|
||||
|
||||
danglingParentheses {
|
||||
callSite = false
|
||||
defnSite = false
|
||||
}
|
||||
|
||||
newlines {
|
||||
alwaysBeforeTopLevelStatements = true
|
||||
sometimesBeforeColonInMethodReturnType = false
|
||||
alwaysBeforeCurlyBraceLambdaParams = false
|
||||
}
|
||||
|
||||
assumeStandardLibraryStripMargin = true
|
||||
|
||||
rewrite.rules = [
|
||||
SortModifiers
|
||||
SortModifiers,
|
||||
RedundantParens,
|
||||
SortImports
|
||||
]
|
||||
|
||||
binPack.literalArgumentLists = true
|
||||
|
||||
project {
|
||||
excludeFilters = [
|
||||
.bloop,
|
||||
.metals,
|
||||
target
|
||||
]
|
||||
}
|
||||
|
||||
# Consider Rewrite Rules
|
||||
|
|
|
@ -53,8 +53,10 @@ matrix:
|
|||
|
||||
# compile website, to check for documentation regressions
|
||||
- stage: test
|
||||
name: Compile website
|
||||
script: sbt docs/mdoc
|
||||
name: Compile website and check formatting
|
||||
script:
|
||||
- sbt docs/mdoc
|
||||
- ./binaries/scalafmt --test --non-interactive
|
||||
|
||||
# Release snapshots/versions of all libraries
|
||||
# run ci-release only if previous stages passed
|
||||
|
|
|
@ -199,7 +199,9 @@ object Cli extends App {
|
|||
}
|
||||
|
||||
val js = ujson.read(rawBody)
|
||||
val jsObj = try { js.obj } catch {
|
||||
val jsObj = try {
|
||||
js.obj
|
||||
} catch {
|
||||
case _: Throwable =>
|
||||
error(s"Response was not a JSON object! Got: $rawBody")
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ object CliReaders {
|
|||
val msg =
|
||||
s"$str is not a valid network! Valid networks: $networks"
|
||||
sys.error(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
implicit val bitcoinAddressReads: Read[BitcoinAddress] =
|
||||
|
|
|
@ -22,7 +22,7 @@ import akka.http.scaladsl.model.MediaType
|
|||
import akka.http.scaladsl.model.MediaTypes.`application/json`
|
||||
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
|
||||
import akka.util.ByteString
|
||||
import upickle.default.{Reader, Writer, read, write}
|
||||
import upickle.default.{read, write, Reader, Writer}
|
||||
import scala.collection.immutable.Seq
|
||||
|
||||
/**
|
||||
|
|
BIN
binaries/scalafmt
Executable file
BIN
binaries/scalafmt
Executable file
Binary file not shown.
|
@ -58,10 +58,10 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
|
|||
|
||||
it should "start a bitcoind with cookie based authentication" in {
|
||||
val confStr = s"""
|
||||
|regtest=1
|
||||
|daemon=1
|
||||
|port=${RpcUtil.randomPort}
|
||||
|rpcport=${RpcUtil.randomPort}
|
||||
|regtest=1
|
||||
|daemon=1
|
||||
|port=${RpcUtil.randomPort}
|
||||
|rpcport=${RpcUtil.randomPort}
|
||||
""".stripMargin
|
||||
|
||||
val conf = BitcoindConfig(confStr, BitcoindRpcTestUtil.tmpDir())
|
||||
|
@ -76,12 +76,12 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
|
|||
|
||||
it should "start a bitcoind with user and password based authentication" in {
|
||||
val confStr = s"""
|
||||
|daemon=1
|
||||
|regtest=1
|
||||
|rpcuser=foobar
|
||||
|rpcpassword=barfoo
|
||||
|port=${RpcUtil.randomPort}
|
||||
|rpcport=${RpcUtil.randomPort}
|
||||
|daemon=1
|
||||
|regtest=1
|
||||
|rpcuser=foobar
|
||||
|rpcpassword=barfoo
|
||||
|port=${RpcUtil.randomPort}
|
||||
|rpcport=${RpcUtil.randomPort}
|
||||
""".stripMargin
|
||||
|
||||
val conf = BitcoindConfig(confStr, BitcoindRpcTestUtil.tmpDir())
|
||||
|
@ -104,11 +104,11 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
|
|||
val port = RpcUtil.randomPort
|
||||
val rpcPort = RpcUtil.randomPort
|
||||
val confStr = s"""
|
||||
|daemon=1
|
||||
|rpcauth=bitcoin-s:6d7580be1deb4ae52bc4249871845b09$$82b282e7c6493f6982a5a7af9fbb1b671bab702e2f31bbb1c016bb0ea1cc27ca
|
||||
|regtest=1
|
||||
|port=${RpcUtil.randomPort}
|
||||
|rpcport=${RpcUtil.randomPort}
|
||||
|daemon=1
|
||||
|rpcauth=bitcoin-s:6d7580be1deb4ae52bc4249871845b09$$82b282e7c6493f6982a5a7af9fbb1b671bab702e2f31bbb1c016bb0ea1cc27ca
|
||||
|regtest=1
|
||||
|port=${RpcUtil.randomPort}
|
||||
|rpcport=${RpcUtil.randomPort}
|
||||
""".stripMargin
|
||||
|
||||
val conf = BitcoindConfig(confStr, BitcoindRpcTestUtil.tmpDir())
|
||||
|
|
|
@ -3,7 +3,11 @@ package org.bitcoins.rpc.common
|
|||
import java.io.File
|
||||
import java.util.Scanner
|
||||
|
||||
import org.bitcoins.core.crypto.{DoubleSha256DigestBE, ECPrivateKey, ECPublicKey}
|
||||
import org.bitcoins.core.crypto.{
|
||||
DoubleSha256DigestBE,
|
||||
ECPrivateKey,
|
||||
ECPublicKey
|
||||
}
|
||||
import org.bitcoins.core.currency.{Bitcoins, CurrencyUnit, Satoshis}
|
||||
import org.bitcoins.core.number.{Int64, UInt32}
|
||||
import org.bitcoins.core.protocol.script.ScriptSignature
|
||||
|
@ -249,7 +253,10 @@ class WalletRpcTest extends BitcoindRpcTest {
|
|||
|
||||
val amount = Bitcoins(1.25)
|
||||
|
||||
def getChangeAddressAndAmount(client: BitcoindRpcClient, address: BitcoinAddress, txid: DoubleSha256DigestBE): Future[(BitcoinAddress, CurrencyUnit)] = {
|
||||
def getChangeAddressAndAmount(
|
||||
client: BitcoindRpcClient,
|
||||
address: BitcoinAddress,
|
||||
txid: DoubleSha256DigestBE): Future[(BitcoinAddress, CurrencyUnit)] = {
|
||||
for {
|
||||
rawTx <- client.getRawTransactionRaw(txid)
|
||||
} yield {
|
||||
|
@ -271,9 +278,14 @@ class WalletRpcTest extends BitcoindRpcTest {
|
|||
|
||||
address <- client.getNewAddress
|
||||
|
||||
txid <- BitcoindRpcTestUtil.fundBlockChainTransaction(client, otherClient, address, amount)
|
||||
txid <- BitcoindRpcTestUtil.fundBlockChainTransaction(client,
|
||||
otherClient,
|
||||
address,
|
||||
amount)
|
||||
|
||||
(changeAddress, changeAmount) <- getChangeAddressAndAmount(client, address, txid)
|
||||
(changeAddress, changeAmount) <- getChangeAddressAndAmount(client,
|
||||
address,
|
||||
txid)
|
||||
|
||||
groupingsAfter <- client.listAddressGroupings
|
||||
} yield {
|
||||
|
@ -281,20 +293,24 @@ class WalletRpcTest extends BitcoindRpcTest {
|
|||
// the address should appear in a new address grouping
|
||||
assert(!groupingsBefore.exists(vec => vec.exists(_.address == address)))
|
||||
|
||||
val rpcAddress = groupingsAfter.find(vec => vec.exists(_.address == address)).get.head
|
||||
val rpcAddress =
|
||||
groupingsAfter.find(vec => vec.exists(_.address == address)).get.head
|
||||
assert(rpcAddress.address == address)
|
||||
assert(rpcAddress.balance == amount)
|
||||
|
||||
// the change address should be added to an exiting address grouping
|
||||
assert(!groupingsBefore.exists(vec => vec.exists(_.address == changeAddress)))
|
||||
assert(
|
||||
!groupingsBefore.exists(vec => vec.exists(_.address == changeAddress)))
|
||||
|
||||
val changeGroupingOpt = groupingsAfter.find(vec => vec.exists(_.address == changeAddress))
|
||||
val changeGroupingOpt =
|
||||
groupingsAfter.find(vec => vec.exists(_.address == changeAddress))
|
||||
assert(changeGroupingOpt.nonEmpty)
|
||||
|
||||
val changeGrouping = changeGroupingOpt.get
|
||||
assert(changeGrouping.size > 1)
|
||||
|
||||
val rpcChangeAddress = changeGrouping.find(addr => addr.address == changeAddress).get
|
||||
val rpcChangeAddress =
|
||||
changeGrouping.find(addr => addr.address == changeAddress).get
|
||||
assert(rpcChangeAddress.address == changeAddress)
|
||||
assert(rpcChangeAddress.balance == changeAmount)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
|||
class BitcoindAuthCredentialsTest extends BitcoinSUnitTest {
|
||||
it must "handle cookie based auth" in {
|
||||
val confStr = """
|
||||
|regtest=1
|
||||
|regtest=1
|
||||
""".stripMargin
|
||||
val conf = BitcoindConfig(confStr, BitcoindRpcTestUtil.tmpDir())
|
||||
val auth = BitcoindAuthCredentials.fromConfig(conf)
|
||||
|
@ -25,9 +25,9 @@ class BitcoindAuthCredentialsTest extends BitcoinSUnitTest {
|
|||
|
||||
it must "default to password based auth" in {
|
||||
val confStr = """
|
||||
|regtest=1
|
||||
|rpcuser=foo
|
||||
|rpcpassword=bar
|
||||
|regtest=1
|
||||
|rpcuser=foo
|
||||
|rpcpassword=bar
|
||||
""".stripMargin
|
||||
val conf = BitcoindConfig(confStr, BitcoindRpcTestUtil.tmpDir())
|
||||
val auth = BitcoindAuthCredentials.fromConfig(conf)
|
||||
|
@ -44,9 +44,9 @@ class BitcoindAuthCredentialsTest extends BitcoinSUnitTest {
|
|||
|
||||
it must "handle password based auth" in {
|
||||
val confStr = """
|
||||
|regtest=1
|
||||
|rpcuser=foo
|
||||
|rpcpassword=bar
|
||||
|regtest=1
|
||||
|rpcuser=foo
|
||||
|rpcpassword=bar
|
||||
""".stripMargin
|
||||
|
||||
val conf = BitcoindConfig(confStr, BitcoindRpcTestUtil.tmpDir())
|
||||
|
|
|
@ -20,7 +20,7 @@ class BitcoindConfigTest extends BitcoinSUnitTest {
|
|||
|
||||
it must "parse networks" in {
|
||||
val conf = BitcoindConfig("""
|
||||
|regtest=1
|
||||
|regtest=1
|
||||
""".stripMargin,
|
||||
tmpDir)
|
||||
assert(conf.network == RegTest)
|
||||
|
@ -28,13 +28,13 @@ class BitcoindConfigTest extends BitcoinSUnitTest {
|
|||
|
||||
it must "prioritize a prefixed option" in {
|
||||
val confStr = """
|
||||
|regtest=1
|
||||
|
|
||||
|rpcport=2000
|
||||
|regtest.rpcport=3000
|
||||
|
|
||||
|[regtest]
|
||||
|rpcport=4000
|
||||
|regtest=1
|
||||
|
|
||||
|rpcport=2000
|
||||
|regtest.rpcport=3000
|
||||
|
|
||||
|[regtest]
|
||||
|rpcport=4000
|
||||
""".stripMargin.split("\n")
|
||||
|
||||
val conf = BitcoindConfig(confStr, tmpDir)
|
||||
|
@ -44,14 +44,14 @@ class BitcoindConfigTest extends BitcoinSUnitTest {
|
|||
|
||||
it must "avoid to get prefixed options in section headers" in {
|
||||
val confStr = """
|
||||
|regtest=1
|
||||
|
|
||||
|rpcport=2000
|
||||
|
|
||||
|[regtest]
|
||||
|rpcport=4000
|
||||
|
|
||||
|regtest.rpcport=3000
|
||||
|regtest=1
|
||||
|
|
||||
|rpcport=2000
|
||||
|
|
||||
|[regtest]
|
||||
|rpcport=4000
|
||||
|
|
||||
|regtest.rpcport=3000
|
||||
""".stripMargin.split("\n")
|
||||
|
||||
val conf = BitcoindConfig(confStr, tmpDir)
|
||||
|
@ -61,12 +61,12 @@ class BitcoindConfigTest extends BitcoinSUnitTest {
|
|||
|
||||
it must "avoid getting options for the wrong network" in {
|
||||
val confStr = """
|
||||
|testnet=1
|
||||
|
|
||||
|[regtest]
|
||||
|rpcport=4000
|
||||
|
|
||||
|regtest.rpcport=3000
|
||||
|testnet=1
|
||||
|
|
||||
|[regtest]
|
||||
|rpcport=4000
|
||||
|
|
||||
|regtest.rpcport=3000
|
||||
""".stripMargin.split("\n")
|
||||
|
||||
val conf = BitcoindConfig(confStr, tmpDir)
|
||||
|
@ -76,17 +76,17 @@ class BitcoindConfigTest extends BitcoinSUnitTest {
|
|||
|
||||
it must "get options with multiple header sections" in {
|
||||
val confStr = """
|
||||
|testnet=1
|
||||
|
|
||||
|[test]
|
||||
|rpcuser=username
|
||||
|rpcport=3000
|
||||
|
|
||||
|[regtest]
|
||||
|rpcport=4000
|
||||
|
|
||||
|[main]
|
||||
|rpcport=1000
|
||||
|testnet=1
|
||||
|
|
||||
|[test]
|
||||
|rpcuser=username
|
||||
|rpcport=3000
|
||||
|
|
||||
|[regtest]
|
||||
|rpcport=4000
|
||||
|
|
||||
|[main]
|
||||
|rpcport=1000
|
||||
""".stripMargin.split("\n")
|
||||
|
||||
val conf = BitcoindConfig(confStr, tmpDir)
|
||||
|
@ -105,17 +105,17 @@ class BitcoindConfigTest extends BitcoinSUnitTest {
|
|||
|
||||
it must "get options with multiple header sections when our section is the last" in {
|
||||
val confStr = """
|
||||
|regtest=1
|
||||
|
|
||||
|[test]
|
||||
|rpcport=3000
|
||||
|
|
||||
|[main]
|
||||
|rpcport=1000
|
||||
|regtest=1
|
||||
|
|
||||
|[test]
|
||||
|rpcport=3000
|
||||
|
|
||||
|[main]
|
||||
|rpcport=1000
|
||||
|
||||
|[regtest]
|
||||
|rpcport=4000
|
||||
|rpcuser=username
|
||||
|[regtest]
|
||||
|rpcport=4000
|
||||
|rpcuser=username
|
||||
""".stripMargin.split("\n")
|
||||
|
||||
val conf = BitcoindConfig(confStr, tmpDir)
|
||||
|
|
|
@ -113,9 +113,8 @@ class BitcoindV17RpcClientTest extends BitcoindRpcTest {
|
|||
(client, _) <- clientsF
|
||||
addr <- client.getNewAddress
|
||||
info <- client.getAddressInfo(addr)
|
||||
} yield
|
||||
assert(
|
||||
info.timestamp.exists(_.getDayOfYear == LocalDateTime.now.getDayOfYear))
|
||||
} yield assert(
|
||||
info.timestamp.exists(_.getDayOfYear == LocalDateTime.now.getDayOfYear))
|
||||
}
|
||||
|
||||
it should "be able to get the address info for a given P2SHSegwit address" in {
|
||||
|
@ -123,9 +122,8 @@ class BitcoindV17RpcClientTest extends BitcoindRpcTest {
|
|||
(client, _) <- clientsF
|
||||
addr <- client.getNewAddress(addressType = AddressType.P2SHSegwit)
|
||||
info <- client.getAddressInfo(addr)
|
||||
} yield
|
||||
assert(
|
||||
info.timestamp.exists(_.getDayOfYear == LocalDateTime.now.getDayOfYear))
|
||||
} yield assert(
|
||||
info.timestamp.exists(_.getDayOfYear == LocalDateTime.now.getDayOfYear))
|
||||
}
|
||||
|
||||
it should "be able to get the address info for a given Legacy address" in {
|
||||
|
@ -133,9 +131,8 @@ class BitcoindV17RpcClientTest extends BitcoindRpcTest {
|
|||
(client, _) <- clientsF
|
||||
addr <- client.getNewAddress(addressType = AddressType.Legacy)
|
||||
info <- client.getAddressInfo(addr)
|
||||
} yield
|
||||
assert(
|
||||
info.timestamp.exists(_.getDayOfYear == LocalDateTime.now.getDayOfYear))
|
||||
} yield assert(
|
||||
info.timestamp.exists(_.getDayOfYear == LocalDateTime.now.getDayOfYear))
|
||||
}
|
||||
|
||||
// needs #360 to be merged
|
||||
|
@ -180,7 +177,7 @@ class BitcoindV17RpcClientTest extends BitcoindRpcTest {
|
|||
case exc =>
|
||||
logger.error(s"throwing $exc")
|
||||
throw exc
|
||||
}
|
||||
}
|
||||
|
||||
def importTx(n: Int): Future[Unit] =
|
||||
for {
|
||||
|
|
|
@ -73,11 +73,10 @@ class PsbtRpcTest extends BitcoindRpcTest {
|
|||
Map(newAddr -> Bitcoins(0.5)))
|
||||
processed <- client.walletProcessPsbt(psbt)
|
||||
finalized <- client.finalizePsbt(processed.psbt)
|
||||
} yield
|
||||
finalized match {
|
||||
case _: FinalizedPsbt => succeed
|
||||
case _: NonFinalizedPsbt => fail
|
||||
}
|
||||
} yield finalized match {
|
||||
case _: FinalizedPsbt => succeed
|
||||
case _: NonFinalizedPsbt => fail
|
||||
}
|
||||
}
|
||||
|
||||
// copies this test from Core: https://github.com/bitcoin/bitcoin/blob/master/test/functional/rpc_psbt.py#L158
|
||||
|
|
|
@ -86,8 +86,6 @@ sealed trait BitcoindVersion
|
|||
|
||||
object BitcoindVersion {
|
||||
|
||||
|
||||
|
||||
/** The newest version of `bitcoind` we support */
|
||||
val newest = V18
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ import java.nio.file.Files
|
|||
|
||||
import scala.util.Properties
|
||||
|
||||
|
||||
/**
|
||||
* Created by chris on 4/29/17.
|
||||
*/
|
||||
|
|
|
@ -442,10 +442,9 @@ object JsonReaders {
|
|||
pubkey <- (json \ "pubkey").validate[ECPublicKey]
|
||||
masterFingerprint <- (json \ "master_fingerprint").validate[String]
|
||||
path <- (json \ "path").validate[String]
|
||||
} yield
|
||||
PsbtBIP32Deriv(pubkey = pubkey,
|
||||
masterFingerprint = masterFingerprint,
|
||||
path = path)
|
||||
} yield PsbtBIP32Deriv(pubkey = pubkey,
|
||||
masterFingerprint = masterFingerprint,
|
||||
path = path)
|
||||
}
|
||||
|
||||
implicit object RpcPsbtScriptReads extends Reads[RpcPsbtScript] {
|
||||
|
@ -455,11 +454,10 @@ object JsonReaders {
|
|||
hex <- (json \ "hex").validate[ScriptPubKey]
|
||||
scriptType <- (json \ "type").validateOpt[ScriptType]
|
||||
address <- (json \ "address").validateOpt[BitcoinAddress]
|
||||
} yield
|
||||
RpcPsbtScript(asm = asm,
|
||||
hex = hex,
|
||||
scriptType = scriptType,
|
||||
address = address)
|
||||
} yield RpcPsbtScript(asm = asm,
|
||||
hex = hex,
|
||||
scriptType = scriptType,
|
||||
address = address)
|
||||
}
|
||||
|
||||
implicit object MapPubKeySignatureReads
|
||||
|
|
20
build.sbt
20
build.sbt
|
@ -74,7 +74,7 @@ lazy val `bitcoin-s` = project
|
|||
import scala.collection.JavaConverters._
|
||||
val logger = streams.value.log
|
||||
|
||||
def cleanPath(path: Path, isRoot: Boolean = true): Unit = {
|
||||
def cleanPath(path: Path, isRoot: Boolean = true): Unit =
|
||||
if (Files.isDirectory(path)) {
|
||||
path.toFile.list().map { file =>
|
||||
val toClean = path.resolve(file)
|
||||
|
@ -89,7 +89,6 @@ lazy val `bitcoin-s` = project
|
|||
} else {
|
||||
Files.deleteIfExists(path)
|
||||
}
|
||||
}
|
||||
|
||||
val websiteScaladocDir =
|
||||
Paths.get("website", "static", "api").toAbsolutePath
|
||||
|
@ -111,14 +110,17 @@ lazy val `bitcoin-s` = project
|
|||
.drop(1) // skip the root directory
|
||||
.foreach { child =>
|
||||
val pathDiff = generatedDir.toPath.relativize(child)
|
||||
Files.copy(child,
|
||||
websiteScaladocDir.resolve(pathDiff),
|
||||
StandardCopyOption.REPLACE_EXISTING)
|
||||
Files.copy(
|
||||
child,
|
||||
websiteScaladocDir.resolve(pathDiff),
|
||||
StandardCopyOption.REPLACE_EXISTING
|
||||
)
|
||||
}
|
||||
} catch {
|
||||
case e: Throwable =>
|
||||
logger.err(
|
||||
"Error when copying Scaladocs to website folder: ${e.toString}")
|
||||
"Error when copying Scaladocs to website folder: ${e.toString}"
|
||||
)
|
||||
throw e
|
||||
}
|
||||
Seq(generatedDir)
|
||||
|
@ -294,8 +296,10 @@ lazy val bench = project
|
|||
lazy val eclairRpcTest = project
|
||||
.in(file("eclair-rpc-test"))
|
||||
.settings(CommonSettings.testSettings: _*)
|
||||
.settings(libraryDependencies ++= Deps.eclairRpcTest,
|
||||
name := "bitcoin-s-eclair-rpc-test")
|
||||
.settings(
|
||||
libraryDependencies ++= Deps.eclairRpcTest,
|
||||
name := "bitcoin-s-eclair-rpc-test"
|
||||
)
|
||||
.dependsOn(core % testAndCompile, testkit)
|
||||
|
||||
lazy val nodeDbSettings = dbFlywaySettings("nodedb")
|
||||
|
|
|
@ -2,7 +2,7 @@ package org.bitcoins.chain.blockchain
|
|||
|
||||
import org.bitcoins.chain.models.BlockHeaderDb
|
||||
|
||||
import scala.collection.{IndexedSeqLike, mutable}
|
||||
import scala.collection.{mutable, IndexedSeqLike}
|
||||
|
||||
/** @inheritdoc */
|
||||
case class Blockchain(headers: Vector[BlockHeaderDb])
|
||||
|
|
|
@ -2,7 +2,7 @@ package org.bitcoins.chain.blockchain
|
|||
|
||||
import org.bitcoins.chain.models.BlockHeaderDb
|
||||
|
||||
import scala.collection.{IndexedSeqLike, mutable}
|
||||
import scala.collection.{mutable, IndexedSeqLike}
|
||||
|
||||
/** @inheritdoc */
|
||||
case class Blockchain(headers: Vector[BlockHeaderDb])
|
||||
|
|
|
@ -50,12 +50,11 @@ trait ChainApi {
|
|||
for {
|
||||
hash <- getBestBlockHash
|
||||
headerOpt <- getHeader(hash)
|
||||
} yield
|
||||
headerOpt match {
|
||||
case None =>
|
||||
throw new RuntimeException(
|
||||
s"We found best hash=${hash.hex} but could not retrieve the full header!!!")
|
||||
case Some(header) => header
|
||||
}
|
||||
} yield headerOpt match {
|
||||
case None =>
|
||||
throw new RuntimeException(
|
||||
s"We found best hash=${hash.hex} but could not retrieve the full header!!!")
|
||||
case Some(header) => header
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import scala.util.{Failure, Try}
|
|||
class BIP39SeedTest extends BitcoinSUnitTest {
|
||||
behavior of "BIP39Seed"
|
||||
|
||||
override implicit val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
generatorDrivenConfigNewCode
|
||||
|
||||
it must "have serialization symmetry - with password" in {
|
||||
|
|
|
@ -9,7 +9,7 @@ import scodec.bits.ByteVector
|
|||
*/
|
||||
class ECDigitalSignatureTest extends BitcoinSUnitTest {
|
||||
|
||||
override implicit val generatorDrivenConfig = generatorDrivenConfigNewCode
|
||||
implicit override val generatorDrivenConfig = generatorDrivenConfigNewCode
|
||||
|
||||
"ECDigitalSignature" must "say that empty signature is a valid DER encoded signature" in {
|
||||
val emptySiganture = ECDigitalSignature(ByteVector.empty)
|
||||
|
|
|
@ -15,7 +15,7 @@ import scala.util.{Failure, Success, Try}
|
|||
|
||||
class ExtKeyTest extends BitcoinSUnitTest {
|
||||
|
||||
override implicit val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
generatorDrivenConfigNewCode
|
||||
|
||||
behavior of "ExtKey"
|
||||
|
|
|
@ -13,7 +13,7 @@ import scala.util.{Failure, Try}
|
|||
|
||||
class MnemonicCodeTest extends BitcoinSUnitTest {
|
||||
|
||||
override implicit val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
generatorDrivenConfigNewCode
|
||||
|
||||
behavior of "MnemonicCode"
|
||||
|
|
|
@ -16,7 +16,7 @@ import org.bitcoins.core.crypto.ExtPrivateKey
|
|||
|
||||
class BIP32PathTest extends BitcoinSUnitTest {
|
||||
|
||||
override implicit val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
generatorDrivenConfigNewCode
|
||||
|
||||
behavior of "BIP32Child"
|
||||
|
|
|
@ -63,15 +63,14 @@ class BlockFilterTest extends BitcoinSUnitTest {
|
|||
header <- array(6).validate[String].map(DoubleSha256DigestBE.fromHex)
|
||||
|
||||
notes <- array(7).validate[String]
|
||||
} yield
|
||||
Bip158TestCase(height,
|
||||
blockHash,
|
||||
block,
|
||||
scripts,
|
||||
prevHeader,
|
||||
filter,
|
||||
header,
|
||||
notes)
|
||||
} yield Bip158TestCase(height,
|
||||
blockHash,
|
||||
block,
|
||||
scripts,
|
||||
prevHeader,
|
||||
filter,
|
||||
header,
|
||||
notes)
|
||||
|
||||
parseResult.get
|
||||
}
|
||||
|
|
|
@ -240,7 +240,10 @@ class GCSTest extends BitcoinSUnitTest {
|
|||
}
|
||||
|
||||
def genKey: Gen[SipHashKey] =
|
||||
Gen.listOfN(16, NumberGenerator.byte).map(ByteVector(_)).map(SipHashKey(_))
|
||||
Gen
|
||||
.listOfN(16, NumberGenerator.byte)
|
||||
.map(ByteVector(_))
|
||||
.map(SipHashKey(_))
|
||||
|
||||
forAll(genPM, genItems, genKey) {
|
||||
case ((p, m), items, k) =>
|
||||
|
|
|
@ -12,7 +12,10 @@ class GolombFilterTest extends BitcoinSUnitTest {
|
|||
|
||||
it must "match encoded data for arbitrary GCS parameters" in {
|
||||
def genKey: Gen[SipHashKey] =
|
||||
Gen.listOfN(16, NumberGenerator.byte).map(ByteVector(_)).map(SipHashKey(_))
|
||||
Gen
|
||||
.listOfN(16, NumberGenerator.byte)
|
||||
.map(ByteVector(_))
|
||||
.map(SipHashKey(_))
|
||||
|
||||
def genPMRand: Gen[(UInt8, UInt64, UInt64)] = NumberGenerator.genP.flatMap {
|
||||
p =>
|
||||
|
@ -49,7 +52,10 @@ class GolombFilterTest extends BitcoinSUnitTest {
|
|||
|
||||
it must "match arbitrary encoded data for bip 158 GCS parameters" in {
|
||||
val genKey: Gen[SipHashKey] =
|
||||
Gen.listOfN(16, NumberGenerator.byte).map(ByteVector(_)).map(SipHashKey(_))
|
||||
Gen
|
||||
.listOfN(16, NumberGenerator.byte)
|
||||
.map(ByteVector(_))
|
||||
.map(SipHashKey(_))
|
||||
|
||||
val genData: Gen[Vector[ByteVector]] = Gen.chooseNum(1, 10000).flatMap {
|
||||
size =>
|
||||
|
|
|
@ -112,7 +112,7 @@ class UInt32Spec extends Properties("UInt32") {
|
|||
Prop.forAllNoShrink(NumberGenerator.uInt32s, Gen.choose(0, 32)) {
|
||||
case (u32, shift) =>
|
||||
val r = Try(u32 << shift)
|
||||
val expected = (u32.toLong << shift) & 0xffffffffL
|
||||
val expected = (u32.toLong << shift) & 0xFFFFFFFFL
|
||||
if (r.isSuccess && expected <= UInt32.max.toLong) {
|
||||
r.get == UInt32(expected)
|
||||
} else {
|
||||
|
|
|
@ -25,7 +25,7 @@ class UInt8Spec extends Properties("UInt8Spec") {
|
|||
Prop.forAllNoShrink(NumberGenerator.uInt8, Gen.choose(0, 8)) {
|
||||
case (u8: UInt8, shift: Int) =>
|
||||
val r = Try(u8 << shift)
|
||||
val expected = (u8.toLong << shift) & 0xffL
|
||||
val expected = (u8.toLong << shift) & 0xFFL
|
||||
if (expected <= UInt8.max.toLong) {
|
||||
r.get == UInt8(expected.toShort)
|
||||
} else {
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.bitcoins.testkit.util.BitcoinSUnitTest
|
|||
import scala.util.{Failure, Success}
|
||||
|
||||
class Bech32Test extends BitcoinSUnitTest {
|
||||
override implicit val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
generatorDrivenConfigNewCode
|
||||
|
||||
behavior of "Bech32"
|
||||
|
|
|
@ -7,7 +7,7 @@ import org.bitcoins.testkit.util.BitcoinSUnitTest
|
|||
|
||||
class LnInvoiceSignatureTest extends BitcoinSUnitTest {
|
||||
|
||||
override implicit val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
generatorDrivenConfigNewCode
|
||||
|
||||
behavior of "LnInvoiceSignature"
|
||||
|
|
|
@ -25,7 +25,7 @@ import scodec.bits.ByteVector
|
|||
class LnInvoiceUnitTest extends BitcoinSUnitTest {
|
||||
behavior of "LnInvoice"
|
||||
|
||||
override implicit val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
generatorDrivenConfigNewCode
|
||||
|
||||
val hrpEmpty = LnHumanReadablePart(LnBitcoinMainNet)
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.bitcoins.core.protocol.ln.util.LnUtil
|
|||
import org.bitcoins.testkit.util.BitcoinSUnitTest
|
||||
|
||||
class LnUtilTest extends BitcoinSUnitTest {
|
||||
override implicit val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
|
||||
generatorDrivenConfigNewCode
|
||||
|
||||
behavior of "LnUtil"
|
||||
|
|
|
@ -6,27 +6,40 @@ class ShortChannelIdTest extends FlatSpec with MustMatchers {
|
|||
|
||||
it must "convert short channel id to and from human readable form" in {
|
||||
// BOLT example
|
||||
ShortChannelId.fromHumanReadableString("539268x845x1") must be (ShortChannelId.fromHex("83a8400034d0001"))
|
||||
ShortChannelId.fromHex("83a8400034d0001").toHumanReadableString must be ("539268x845x1")
|
||||
ShortChannelId.fromHumanReadableString("539268x845x1") must be(
|
||||
ShortChannelId.fromHex("83a8400034d0001"))
|
||||
ShortChannelId.fromHex("83a8400034d0001").toHumanReadableString must be(
|
||||
"539268x845x1")
|
||||
|
||||
// min value
|
||||
ShortChannelId.fromHumanReadableString("0x0x0") must be (ShortChannelId.fromHex("0"))
|
||||
ShortChannelId.fromHex("0").toHumanReadableString must be ("0x0x0")
|
||||
ShortChannelId.fromHumanReadableString("0x0x0") must be(
|
||||
ShortChannelId.fromHex("0"))
|
||||
ShortChannelId.fromHex("0").toHumanReadableString must be("0x0x0")
|
||||
|
||||
// max value
|
||||
ShortChannelId.fromHumanReadableString("16777215x16777215x65535") must be (ShortChannelId.fromHex("ffffffffffffffff"))
|
||||
ShortChannelId.fromHex("ffffffffffffffff").toHumanReadableString must be ("16777215x16777215x65535")
|
||||
ShortChannelId.fromHumanReadableString("16777215x16777215x65535") must be(
|
||||
ShortChannelId.fromHex("ffffffffffffffff"))
|
||||
ShortChannelId.fromHex("ffffffffffffffff").toHumanReadableString must be(
|
||||
"16777215x16777215x65535")
|
||||
}
|
||||
|
||||
it must "validate short channel id components" in {
|
||||
an [IllegalArgumentException] must be thrownBy ShortChannelId.fromHumanReadableString("16777216x0x0")
|
||||
an [IllegalArgumentException] must be thrownBy ShortChannelId.fromHumanReadableString("-1x0x0")
|
||||
an [IllegalArgumentException] must be thrownBy ShortChannelId.fromHumanReadableString("0x16777216x0")
|
||||
an [IllegalArgumentException] must be thrownBy ShortChannelId.fromHumanReadableString("0x-1x0")
|
||||
an [IllegalArgumentException] must be thrownBy ShortChannelId.fromHumanReadableString("0x0x65536")
|
||||
an [IllegalArgumentException] must be thrownBy ShortChannelId.fromHumanReadableString("0x0x-1")
|
||||
an [NoSuchElementException] must be thrownBy ShortChannelId.fromHumanReadableString("1x1x1x1")
|
||||
ShortChannelId.fromHumanReadableString("cafebabe") must be (ShortChannelId.fromHex("cafebabe"))
|
||||
an[IllegalArgumentException] must be thrownBy ShortChannelId
|
||||
.fromHumanReadableString("16777216x0x0")
|
||||
an[IllegalArgumentException] must be thrownBy ShortChannelId
|
||||
.fromHumanReadableString("-1x0x0")
|
||||
an[IllegalArgumentException] must be thrownBy ShortChannelId
|
||||
.fromHumanReadableString("0x16777216x0")
|
||||
an[IllegalArgumentException] must be thrownBy ShortChannelId
|
||||
.fromHumanReadableString("0x-1x0")
|
||||
an[IllegalArgumentException] must be thrownBy ShortChannelId
|
||||
.fromHumanReadableString("0x0x65536")
|
||||
an[IllegalArgumentException] must be thrownBy ShortChannelId
|
||||
.fromHumanReadableString("0x0x-1")
|
||||
an[NoSuchElementException] must be thrownBy ShortChannelId
|
||||
.fromHumanReadableString("1x1x1x1")
|
||||
ShortChannelId.fromHumanReadableString("cafebabe") must be(
|
||||
ShortChannelId.fromHex("cafebabe"))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -173,10 +173,10 @@ class TransactionTest extends BitcoinSUnitTest {
|
|||
assert(
|
||||
outPoint.txId == input.previousOutput.txId,
|
||||
s"""
|
||||
|OutPoint txId not the same as input prevout txid
|
||||
|outPoint.txId: ${outPoint.txId}
|
||||
|input prevout txid: ${input.previousOutput.txId}
|
||||
|""".stripMargin
|
||||
|OutPoint txId not the same as input prevout txid
|
||||
|outPoint.txId: ${outPoint.txId}
|
||||
|input prevout txid: ${input.previousOutput.txId}
|
||||
|""".stripMargin
|
||||
)
|
||||
val txSigComponent = amountOpt match {
|
||||
case Some(amount) =>
|
||||
|
|
|
@ -62,10 +62,10 @@ sealed abstract class TransactionSignatureSerializer {
|
|||
val inputSigsRemoved = for {
|
||||
input <- spendingTransaction.inputs
|
||||
s = input.scriptSignature
|
||||
} yield
|
||||
TransactionInput(input.previousOutput,
|
||||
NonStandardScriptSignature(s.compactSizeUInt.hex),
|
||||
input.sequence)
|
||||
} yield TransactionInput(
|
||||
input.previousOutput,
|
||||
NonStandardScriptSignature(s.compactSizeUInt.hex),
|
||||
input.sequence)
|
||||
|
||||
//make sure all scriptSigs have empty asm
|
||||
inputSigsRemoved.map(
|
||||
|
|
|
@ -4,7 +4,7 @@ import org.bitcoins.core.number.{UInt64, UInt8}
|
|||
import org.bitcoins.core.protocol.CompactSizeUInt
|
||||
import org.bouncycastle.crypto.macs.SipHash
|
||||
import org.bouncycastle.crypto.params.KeyParameter
|
||||
import scodec.bits.{BitVector, BinStringSyntax, ByteVector}
|
||||
import scodec.bits.{BinStringSyntax, BitVector, ByteVector}
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ sealed abstract class UInt32 extends UnsignedNumber[UInt32] {
|
|||
override def apply: A => UInt32 = UInt32(_)
|
||||
override def hex: String = BitcoinSUtil.encodeHex(toLong).slice(8, 16)
|
||||
|
||||
override def andMask = 0xffffffffL
|
||||
override def andMask = 0xFFFFFFFFL
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,7 +142,7 @@ sealed abstract class UInt32 extends UnsignedNumber[UInt32] {
|
|||
sealed abstract class UInt64 extends UnsignedNumber[UInt64] {
|
||||
override def hex: String = encodeHex(underlying)
|
||||
override def apply: A => UInt64 = UInt64(_)
|
||||
override def andMask = 0xffffffffffffffffL
|
||||
override def andMask = 0xFFFFFFFFFFFFFFFFL
|
||||
|
||||
/**
|
||||
* Converts a [[BigInt]] to a 8 byte hex representation.
|
||||
|
@ -178,7 +178,7 @@ sealed abstract class Int32 extends SignedNumber[Int32] {
|
|||
*/
|
||||
sealed abstract class Int64 extends SignedNumber[Int64] {
|
||||
override def apply: A => Int64 = Int64(_)
|
||||
override def andMask = 0xffffffffffffffffL
|
||||
override def andMask = 0xFFFFFFFFFFFFFFFFL
|
||||
override def hex: String = BitcoinSUtil.encodeHex(toLong)
|
||||
}
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ object CompactSizeUInt extends Factory[CompactSizeUInt] {
|
|||
CompactSizeUInt(UInt64(script.bytes.size), 1)
|
||||
} else if (script.bytes.size <= 0xffff) {
|
||||
CompactSizeUInt(UInt64(script.bytes.size), 3)
|
||||
} else if (script.bytes.size <= 0xffffffffL) {
|
||||
} else if (script.bytes.size <= 0xFFFFFFFFL) {
|
||||
CompactSizeUInt(UInt64(script.bytes.size), 5)
|
||||
} else CompactSizeUInt(UInt64(script.bytes.size), 9)
|
||||
}
|
||||
|
|
|
@ -22,4 +22,4 @@ object PaymentPreimage extends Factory[PaymentPreimage] {
|
|||
|
||||
def random: PaymentPreimage = fromBytes(ECPrivateKey.freshPrivateKey.bytes)
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,9 @@ case class ShortChannelId(u64: UInt64) extends NetworkElement {
|
|||
* }}}
|
||||
*/
|
||||
def toHumanReadableString: String = {
|
||||
val blockHeight = (u64 >> 40) & UInt64(0xFFFFFF)
|
||||
val txIndex = (u64 >> 16) & UInt64(0xFFFFFF)
|
||||
val outputIndex = u64 & UInt64(0xFFFF)
|
||||
val blockHeight = (u64 >> 40) & UInt64(0xFFFFFF)
|
||||
val txIndex = (u64 >> 16) & UInt64(0xFFFFFF)
|
||||
val outputIndex = u64 & UInt64(0xFFFF)
|
||||
s"${blockHeight.toInt}x${txIndex.toInt}x${outputIndex.toInt}"
|
||||
}
|
||||
|
||||
|
@ -42,19 +42,24 @@ object ShortChannelId extends Factory[ShortChannelId] {
|
|||
new ShortChannelId(UInt64.fromBytes(byteVector))
|
||||
}
|
||||
|
||||
def fromHumanReadableString(str: String): ShortChannelId = str.split("x") match {
|
||||
case Array(_blockHeight, _txIndex, _outputIndex) =>
|
||||
val blockHeight = BigInt(_blockHeight)
|
||||
require(blockHeight >= 0 && blockHeight <= 0xffffff, "ShortChannelId: invalid block height")
|
||||
def fromHumanReadableString(str: String): ShortChannelId =
|
||||
str.split("x") match {
|
||||
case Array(_blockHeight, _txIndex, _outputIndex) =>
|
||||
val blockHeight = BigInt(_blockHeight)
|
||||
require(blockHeight >= 0 && blockHeight <= 0xffffff,
|
||||
"ShortChannelId: invalid block height")
|
||||
|
||||
val txIndex = _txIndex.toInt
|
||||
require(txIndex >= 0 && txIndex <= 0xffffff, "ShortChannelId:invalid tx index")
|
||||
val txIndex = _txIndex.toInt
|
||||
require(txIndex >= 0 && txIndex <= 0xffffff,
|
||||
"ShortChannelId:invalid tx index")
|
||||
|
||||
val outputIndex = _outputIndex.toInt
|
||||
require(outputIndex >= 0 && outputIndex <= 0xffff, "ShortChannelId: invalid output index")
|
||||
val outputIndex = _outputIndex.toInt
|
||||
require(outputIndex >= 0 && outputIndex <= 0xffff,
|
||||
"ShortChannelId: invalid output index")
|
||||
|
||||
val u64 = UInt64(((blockHeight & 0xffffffL) << 40) | ((txIndex & 0xffffffL) << 16) | (outputIndex & 0xffffL))
|
||||
ShortChannelId(u64)
|
||||
case _: Array[String] => fromHex(str)
|
||||
}
|
||||
val u64 = UInt64(
|
||||
((blockHeight & 0xFFFFFFL) << 40) | ((txIndex & 0xFFFFFFL) << 16) | (outputIndex & 0xFFFFL))
|
||||
ShortChannelId(u64)
|
||||
case _: Array[String] => fromHex(str)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ sealed abstract class ArithmeticInterpreter {
|
|||
x match {
|
||||
case ScriptNumber.zero => ScriptNumber.zero
|
||||
case _: ScriptNumber => ScriptNumber(x.toLong.abs)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/** Negates the stack top. */
|
||||
|
|
|
@ -59,7 +59,8 @@ sealed abstract class ScriptNumber
|
|||
def *(that: ScriptNumber): ScriptNumber =
|
||||
ScriptNumber(underlying * that.underlying)
|
||||
|
||||
override def compare(that: ScriptNumber): Int = underlying compare that.underlying
|
||||
override def compare(that: ScriptNumber): Int =
|
||||
underlying compare that.underlying
|
||||
|
||||
def <(that: Int64): Boolean = underlying < that.toLong
|
||||
|
||||
|
|
|
@ -790,7 +790,7 @@ sealed abstract class ScriptInterpreter {
|
|||
//since this is not a coinbase tx we cannot have any empty previous outs inside of inputs
|
||||
!transaction.inputs.exists(_.previousOutput == EmptyTransactionOutPoint)
|
||||
}
|
||||
inputOutputsNotZero && txNotLargerThanBlock && outputsSpendValidAmountsOfMoney &&
|
||||
inputOutputsNotZero && txNotLargerThanBlock && outputsSpendValidAmountsOfMoney &&
|
||||
allOutputsValidMoneyRange && noDuplicateInputs && isValidScriptSigForCoinbaseTx
|
||||
}
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ sealed abstract class StackInterpreter {
|
|||
logger.error(
|
||||
"The index for OP_ROLL would have caused an index out of bounds exception")
|
||||
ScriptProgram(program, ScriptErrorInvalidStackOperation)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -197,7 +197,7 @@ sealed abstract class ScriptParser extends Factory[List[ScriptToken]] {
|
|||
ScriptNumber(g.group(1))
|
||||
} else {
|
||||
ScriptConstant(g.group(1))
|
||||
}))
|
||||
}))
|
||||
scriptConstants.toList
|
||||
}
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ sealed abstract class NumberUtil extends BitcoinSLogger {
|
|||
|
||||
nWordNotZero && ((nSize > 34) ||
|
||||
(nWord > UInt8.max.toBigInt && nSize > 33) ||
|
||||
(nWord > UInt32(0xffffL).toBigInt && nSize > 32))
|
||||
(nWord > UInt32(0xFFFFL).toBigInt && nSize > 32))
|
||||
}
|
||||
|
||||
BlockHeader.TargetDifficultyHelper(result.abs(), isNegative, isOverflow)
|
||||
|
@ -273,14 +273,14 @@ sealed abstract class NumberUtil extends BitcoinSLogger {
|
|||
}
|
||||
|
||||
//~0x007fffff = 0xff800000
|
||||
require((compact & UInt32(0xff800000L)) == UInt32.zero,
|
||||
require((compact & UInt32(0xFF800000L)) == UInt32.zero,
|
||||
s"Exponent/sign bit must not be set yet in compact encoding")
|
||||
require(size < 256, "Size of compact encoding can't be more than 2^256")
|
||||
|
||||
compact = compact | UInt32(size << 24)
|
||||
|
||||
compact = {
|
||||
if (isNegative && ((compact & UInt32(0x007fffffL)) != UInt32.zero)) {
|
||||
if (isNegative && ((compact & UInt32(0x007FFFFFL)) != UInt32.zero)) {
|
||||
compact | negativeFlag
|
||||
} else {
|
||||
compact | UInt32.zero
|
||||
|
|
|
@ -54,7 +54,7 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
sys.error {
|
||||
val msg =
|
||||
s""""Eclair binary directory (${BitcoindRpcTestUtil.binaryDirectory}) is empty.
|
||||
|Run 'sbt downloadEclair' to fetch needed binaries""".stripMargin
|
||||
|Run 'sbt downloadEclair' to fetch needed binaries""".stripMargin
|
||||
msg
|
||||
}
|
||||
}
|
||||
|
@ -988,7 +988,7 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
ourUpdates.flatMap(our =>
|
||||
allUpdates.map { all =>
|
||||
our != all
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
val checkedUpatesF: Future[Unit] =
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
package org.bitcoins.eclair.rpc.json
|
||||
|
||||
import org.bitcoins.core.crypto.{DoubleSha256Digest, DoubleSha256DigestBE, ECDigitalSignature, Sha256Digest}
|
||||
import org.bitcoins.core.crypto.{
|
||||
DoubleSha256Digest,
|
||||
DoubleSha256DigestBE,
|
||||
ECDigitalSignature,
|
||||
Sha256Digest
|
||||
}
|
||||
import org.bitcoins.core.currency.Satoshis
|
||||
import org.bitcoins.core.protocol.ln.channel.{ChannelState, FundedChannelId}
|
||||
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
|
||||
import org.bitcoins.core.protocol.ln.fee.FeeProportionalMillionths
|
||||
import org.bitcoins.core.protocol.ln.node.NodeId
|
||||
import org.bitcoins.core.protocol.ln.{LnHumanReadablePart, LnInvoiceSignature, PaymentPreimage, ShortChannelId}
|
||||
import org.bitcoins.core.protocol.ln.{
|
||||
LnHumanReadablePart,
|
||||
LnInvoiceSignature,
|
||||
PaymentPreimage,
|
||||
ShortChannelId
|
||||
}
|
||||
import org.bitcoins.eclair.rpc.network.PeerState
|
||||
import play.api.libs.json.JsObject
|
||||
|
||||
|
@ -265,19 +275,20 @@ case class ChannelResult(
|
|||
feeProportionalMillionths: Option[FeeProportionalMillionths],
|
||||
data: JsObject) {
|
||||
import JsonReaders._
|
||||
lazy val shortChannelId: Option[ShortChannelId] = (data \ "shortChannelId").validate[ShortChannelId].asOpt
|
||||
lazy val shortChannelId: Option[ShortChannelId] =
|
||||
(data \ "shortChannelId").validate[ShortChannelId].asOpt
|
||||
}
|
||||
|
||||
// ChannelResult ends here
|
||||
|
||||
case class InvoiceResult(
|
||||
prefix: LnHumanReadablePart,
|
||||
timestamp: FiniteDuration,
|
||||
nodeId: NodeId,
|
||||
serialized: String,
|
||||
description: String,
|
||||
paymentHash: Sha256Digest,
|
||||
expiry: FiniteDuration)
|
||||
prefix: LnHumanReadablePart,
|
||||
timestamp: FiniteDuration,
|
||||
nodeId: NodeId,
|
||||
serialized: String,
|
||||
description: String,
|
||||
paymentHash: Sha256Digest,
|
||||
expiry: FiniteDuration)
|
||||
|
||||
case class PaymentRequest(
|
||||
prefix: LnHumanReadablePart,
|
||||
|
@ -288,30 +299,33 @@ case class PaymentRequest(
|
|||
signature: LnInvoiceSignature)
|
||||
|
||||
case class PaymentResult(
|
||||
id: String,
|
||||
paymentHash: Sha256Digest,
|
||||
preimage: Option[PaymentPreimage],
|
||||
amountMsat: MilliSatoshis,
|
||||
createdAt: FiniteDuration,
|
||||
completedAt: Option[FiniteDuration],
|
||||
status: PaymentStatus)
|
||||
id: String,
|
||||
paymentHash: Sha256Digest,
|
||||
preimage: Option[PaymentPreimage],
|
||||
amountMsat: MilliSatoshis,
|
||||
createdAt: FiniteDuration,
|
||||
completedAt: Option[FiniteDuration],
|
||||
status: PaymentStatus)
|
||||
|
||||
case class ReceivedPaymentResult(
|
||||
paymentHash: Sha256Digest,
|
||||
amountMsat: MilliSatoshis,
|
||||
receivedAt: FiniteDuration)
|
||||
paymentHash: Sha256Digest,
|
||||
amountMsat: MilliSatoshis,
|
||||
receivedAt: FiniteDuration)
|
||||
|
||||
sealed trait PaymentStatus
|
||||
|
||||
object PaymentStatus {
|
||||
case object PENDING extends PaymentStatus
|
||||
case object SUCCEEDED extends PaymentStatus
|
||||
case object FAILED extends PaymentStatus
|
||||
|
||||
def apply(s: String): PaymentStatus = s match {
|
||||
case "PENDING" => PENDING
|
||||
case "PENDING" => PENDING
|
||||
case "SUCCEEDED" => SUCCEEDED
|
||||
case "FAILED" => FAILED
|
||||
case err => throw new IllegalArgumentException(s"Unknown payment status code `${err}`")
|
||||
case "FAILED" => FAILED
|
||||
case err =>
|
||||
throw new IllegalArgumentException(
|
||||
s"Unknown payment status code `${err}`")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,29 +333,28 @@ case class PaymentId(value: String) {
|
|||
override def toString: String = value
|
||||
}
|
||||
|
||||
|
||||
sealed trait WebSocketEvent
|
||||
|
||||
object WebSocketEvent {
|
||||
|
||||
|
||||
case class PaymentRelayed(
|
||||
amountIn: MilliSatoshis,
|
||||
amountOut: MilliSatoshis,
|
||||
paymentHash: Sha256Digest,
|
||||
fromChannelId: FundedChannelId,
|
||||
toChannelId: FundedChannelId,
|
||||
timestamp: FiniteDuration) extends WebSocketEvent
|
||||
timestamp: FiniteDuration)
|
||||
extends WebSocketEvent
|
||||
|
||||
case class PaymentReceived(
|
||||
amount: MilliSatoshis,
|
||||
paymentHash: Sha256Digest,
|
||||
fromChannelId: FundedChannelId,
|
||||
timestamp: FiniteDuration) extends WebSocketEvent
|
||||
timestamp: FiniteDuration)
|
||||
extends WebSocketEvent
|
||||
|
||||
case class PaymentFailed(
|
||||
paymentHash: Sha256Digest,
|
||||
failures: Vector[String]) extends WebSocketEvent
|
||||
case class PaymentFailed(paymentHash: Sha256Digest, failures: Vector[String])
|
||||
extends WebSocketEvent
|
||||
|
||||
case class PaymentSent(
|
||||
amount: MilliSatoshis,
|
||||
|
@ -349,11 +362,13 @@ object WebSocketEvent {
|
|||
paymentHash: Sha256Digest,
|
||||
paymentPreimage: PaymentPreimage,
|
||||
toChannelId: FundedChannelId,
|
||||
timestamp: FiniteDuration) extends WebSocketEvent
|
||||
timestamp: FiniteDuration)
|
||||
extends WebSocketEvent
|
||||
|
||||
case class PaymentSettlingOnchain(
|
||||
amount: MilliSatoshis,
|
||||
paymentHash: Sha256Digest,
|
||||
timestamp: FiniteDuration) extends WebSocketEvent
|
||||
timestamp: FiniteDuration)
|
||||
extends WebSocketEvent
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,14 +122,13 @@ object JsonReaders {
|
|||
description <- (jsValue \ "description").validate[String]
|
||||
paymentHash <- (jsValue \ "paymentHash").validate[Sha256Digest]
|
||||
expiry <- (jsValue \ "expiry").validate[Long]
|
||||
} yield
|
||||
InvoiceResult(prefix,
|
||||
timestamp.seconds,
|
||||
nodeId,
|
||||
serialized,
|
||||
description,
|
||||
paymentHash,
|
||||
expiry.seconds)
|
||||
} yield InvoiceResult(prefix,
|
||||
timestamp.seconds,
|
||||
nodeId,
|
||||
serialized,
|
||||
description,
|
||||
paymentHash,
|
||||
expiry.seconds)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,13 +144,12 @@ object JsonReaders {
|
|||
localMsat <- (jsValue \ "data" \ "commitments" \ "localCommit" \ "spec" \ "toLocalMsat")
|
||||
.validate[MilliSatoshis]
|
||||
|
||||
} yield
|
||||
OpenChannelInfo(nodeId = nodeId,
|
||||
shortChannelId = shortChannelId,
|
||||
channelId = channelId,
|
||||
localMsat = localMsat,
|
||||
remoteMsat = remoteMsat,
|
||||
state = state)
|
||||
} yield OpenChannelInfo(nodeId = nodeId,
|
||||
shortChannelId = shortChannelId,
|
||||
channelId = channelId,
|
||||
localMsat = localMsat,
|
||||
remoteMsat = remoteMsat,
|
||||
state = state)
|
||||
}
|
||||
|
||||
implicit val baseChannelInfoReads: Reads[BaseChannelInfo] = Reads { jsValue =>
|
||||
|
@ -164,12 +162,11 @@ object JsonReaders {
|
|||
localMsat <- (jsValue \ "data" \ "commitments" \ "localCommit" \ "spec" \ "toLocalMsat")
|
||||
.validate[MilliSatoshis]
|
||||
|
||||
} yield
|
||||
BaseChannelInfo(nodeId = nodeId,
|
||||
channelId = channelId,
|
||||
localMsat = localMsat,
|
||||
remoteMsat = remoteMsat,
|
||||
state = state)
|
||||
} yield BaseChannelInfo(nodeId = nodeId,
|
||||
channelId = channelId,
|
||||
localMsat = localMsat,
|
||||
remoteMsat = remoteMsat,
|
||||
state = state)
|
||||
}
|
||||
|
||||
implicit val channelInfoReads: Reads[ChannelInfo] = Reads { jsValue =>
|
||||
|
@ -220,13 +217,12 @@ object JsonReaders {
|
|||
feeProportional <- (js \ "data" \ "channelUpdate" \ "feeProportionalMillionths")
|
||||
.validateOpt[FeeProportionalMillionths]
|
||||
data <- (js \ "data").validate[JsObject]
|
||||
} yield
|
||||
ChannelResult(nodeId = nodeId,
|
||||
state = state,
|
||||
channelId = channelId,
|
||||
feeBaseMsat = feeBaseMsat,
|
||||
feeProportionalMillionths = feeProportional,
|
||||
data = data)
|
||||
} yield ChannelResult(nodeId = nodeId,
|
||||
state = state,
|
||||
channelId = channelId,
|
||||
feeBaseMsat = feeBaseMsat,
|
||||
feeProportionalMillionths = feeProportional,
|
||||
data = data)
|
||||
}
|
||||
|
||||
implicit val lnInvoiceReads: Reads[LnInvoice] =
|
||||
|
|
|
@ -39,15 +39,15 @@ class NodeAppConfigTest extends BitcoinSUnitTest {
|
|||
val tempDir = Files.createTempDirectory("bitcoin-s")
|
||||
val tempFile = Files.createFile(tempDir.resolve("bitcoin-s.conf"))
|
||||
val confStr = """
|
||||
| bitcoin-s {
|
||||
| network = testnet3
|
||||
|
|
||||
| logging {
|
||||
| level = off
|
||||
|
|
||||
| p2p = warn
|
||||
| }
|
||||
| }
|
||||
| bitcoin-s {
|
||||
| network = testnet3
|
||||
|
|
||||
| logging {
|
||||
| level = off
|
||||
|
|
||||
| p2p = warn
|
||||
| }
|
||||
| }
|
||||
""".stripMargin
|
||||
val _ = Files.write(tempFile, confStr.getBytes())
|
||||
|
||||
|
|
|
@ -29,3 +29,5 @@ addSbtPlugin("org.scalameta" % "sbt-mdoc" % "1.3.2")
|
|||
|
||||
// SQL migrations
|
||||
addSbtPlugin("io.github.davidmweber" % "flyway-sbt" % "6.0.0")
|
||||
|
||||
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.1")
|
||||
|
|
|
@ -17,11 +17,11 @@ object BitcoinSTestAppConfig {
|
|||
def getTestConfig(config: Config*): BitcoinSAppConfig = {
|
||||
val overrideConf = ConfigFactory.parseString {
|
||||
"""
|
||||
|bitcoin-s {
|
||||
| logging {
|
||||
| level = WARN
|
||||
| }
|
||||
|}
|
||||
|bitcoin-s {
|
||||
| logging {
|
||||
| level = WARN
|
||||
| }
|
||||
|}
|
||||
""".stripMargin
|
||||
}
|
||||
val tmpDir = Files.createTempDirectory("bitcoin-s-")
|
||||
|
@ -47,12 +47,12 @@ object BitcoinSTestAppConfig {
|
|||
def memConfigForProject(project: ProjectType): String = {
|
||||
val name = project.toString().toLowerCase()
|
||||
s"""
|
||||
| $name.db {
|
||||
| url = "jdbc:sqlite:file:$name.db:?mode=memory&cache=shared"
|
||||
| connectionPool = disabled
|
||||
| keepAliveConnection = true
|
||||
| }
|
||||
|""".stripMargin
|
||||
| $name.db {
|
||||
| url = "jdbc:sqlite:file:$name.db:?mode=memory&cache=shared"
|
||||
| connectionPool = disabled
|
||||
| keepAliveConnection = true
|
||||
| }
|
||||
|""".stripMargin
|
||||
}
|
||||
|
||||
val confStr = project match {
|
||||
|
@ -60,10 +60,10 @@ object BitcoinSTestAppConfig {
|
|||
case Some(p) => memConfigForProject(p)
|
||||
}
|
||||
val nestedConfStr = s"""
|
||||
| bitcoin-s {
|
||||
| $confStr
|
||||
| }
|
||||
|""".stripMargin
|
||||
| bitcoin-s {
|
||||
| $confStr
|
||||
| }
|
||||
|""".stripMargin
|
||||
ConfigFactory.parseString(nestedConfStr)
|
||||
}
|
||||
|
||||
|
|
|
@ -72,13 +72,12 @@ sealed abstract class BlockchainElementsGenerator {
|
|||
merkleRootHash = Merkle.computeMerkleRoot(txs)
|
||||
time <- NumberGenerator.uInt32s
|
||||
nonce <- NumberGenerator.uInt32s
|
||||
} yield
|
||||
BlockHeader(version,
|
||||
previousBlockHash,
|
||||
merkleRootHash,
|
||||
time,
|
||||
nBits,
|
||||
nonce)
|
||||
} yield BlockHeader(version,
|
||||
previousBlockHash,
|
||||
merkleRootHash,
|
||||
time,
|
||||
nBits,
|
||||
nonce)
|
||||
|
||||
/** Generates a [[org.bitcoins.core.protocol.blockchain.BlockHeader BlockHeader]] that has a merkle root
|
||||
* hash corresponding to the given txs */
|
||||
|
|
|
@ -105,11 +105,10 @@ object HDGenerators {
|
|||
accountIndex <- NumberGenerator.positiveInts
|
||||
addressIndex <- NumberGenerator.positiveInts
|
||||
chainType <- hdChainType
|
||||
} yield
|
||||
LegacyHDPath(coinType = coinType,
|
||||
addressIndex = addressIndex,
|
||||
accountIndex = accountIndex,
|
||||
chainType = chainType)
|
||||
} yield LegacyHDPath(coinType = coinType,
|
||||
addressIndex = addressIndex,
|
||||
accountIndex = accountIndex,
|
||||
chainType = chainType)
|
||||
|
||||
def segwithHdPath: Gen[SegWitHDPath] =
|
||||
for {
|
||||
|
@ -117,11 +116,10 @@ object HDGenerators {
|
|||
accountIndex <- NumberGenerator.positiveInts
|
||||
addressIndex <- NumberGenerator.positiveInts
|
||||
chainType <- hdChainType
|
||||
} yield
|
||||
SegWitHDPath(coinType = coinType,
|
||||
addressIndex = addressIndex,
|
||||
accountIndex = accountIndex,
|
||||
chainType = chainType)
|
||||
} yield SegWitHDPath(coinType = coinType,
|
||||
addressIndex = addressIndex,
|
||||
accountIndex = accountIndex,
|
||||
chainType = chainType)
|
||||
|
||||
def nestedSegwithHdPath: Gen[NestedSegWitHDPath] =
|
||||
for {
|
||||
|
@ -129,11 +127,10 @@ object HDGenerators {
|
|||
accountIndex <- NumberGenerator.positiveInts
|
||||
addressIndex <- NumberGenerator.positiveInts
|
||||
chainType <- hdChainType
|
||||
} yield
|
||||
NestedSegWitHDPath(coinType = coinType,
|
||||
addressIndex = addressIndex,
|
||||
accountIndex = accountIndex,
|
||||
chainType = chainType)
|
||||
} yield NestedSegWitHDPath(coinType = coinType,
|
||||
addressIndex = addressIndex,
|
||||
accountIndex = accountIndex,
|
||||
chainType = chainType)
|
||||
|
||||
def hdPath: Gen[HDPath] =
|
||||
Gen.oneOf(legacyHdPath, segwithHdPath, nestedSegwithHdPath)
|
||||
|
@ -143,12 +140,11 @@ object HDGenerators {
|
|||
def hdPathWithConstructor: Gen[(HDPath, HDPathConstructor)] =
|
||||
for {
|
||||
path <- hdPath
|
||||
} yield
|
||||
path match {
|
||||
case legacy: LegacyHDPath => (legacy, LegacyHDPath(_))
|
||||
case nested: NestedSegWitHDPath => (nested, NestedSegWitHDPath(_))
|
||||
case segwit: SegWitHDPath => (segwit, SegWitHDPath(_))
|
||||
}
|
||||
} yield path match {
|
||||
case legacy: LegacyHDPath => (legacy, LegacyHDPath(_))
|
||||
case nested: NestedSegWitHDPath => (nested, NestedSegWitHDPath(_))
|
||||
case segwit: SegWitHDPath => (segwit, SegWitHDPath(_))
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a pair of paths that can be diffed.
|
||||
|
|
|
@ -37,11 +37,10 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger {
|
|||
val signatures: Gen[Seq[ECDigitalSignature]] = for {
|
||||
numKeys <- Gen.choose(1, Consensus.maxPublicKeysPerMultiSig)
|
||||
hash <- CryptoGenerators.doubleSha256Digest
|
||||
} yield
|
||||
for {
|
||||
_ <- 0 until numKeys
|
||||
privKey = ECPrivateKey()
|
||||
} yield privKey.sign(hash)
|
||||
} yield for {
|
||||
_ <- 0 until numKeys
|
||||
privKey = ECPrivateKey()
|
||||
} yield privKey.sign(hash)
|
||||
signatures.map(sigs => MultiSignatureScriptSignature(sigs))
|
||||
}
|
||||
|
||||
|
@ -414,35 +413,34 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger {
|
|||
(scriptPubKey, privKeys) <- randomNonLockTimeNonP2SHScriptPubKey
|
||||
hashType <- CryptoGenerators.hashType
|
||||
cltv = CLTVScriptPubKey(cltvLockTime, scriptPubKey)
|
||||
} yield
|
||||
scriptPubKey match {
|
||||
case m: MultiSignatureScriptPubKey =>
|
||||
val requiredSigs = m.requiredSigs
|
||||
val cltvScriptSig = lockTimeHelper(Some(lockTime),
|
||||
sequence,
|
||||
cltv,
|
||||
privKeys,
|
||||
Some(requiredSigs),
|
||||
hashType)
|
||||
(cltvScriptSig.asInstanceOf[CLTVScriptSignature], cltv, privKeys)
|
||||
case _: P2PKHScriptPubKey | _: P2PKScriptPubKey =>
|
||||
val cltvScriptSig = lockTimeHelper(Some(lockTime),
|
||||
sequence,
|
||||
cltv,
|
||||
privKeys,
|
||||
None,
|
||||
hashType)
|
||||
(cltvScriptSig.asInstanceOf[CLTVScriptSignature], cltv, privKeys)
|
||||
case _: UnassignedWitnessScriptPubKey | _: WitnessScriptPubKeyV0 =>
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot created a witness scriptPubKey for a CSVScriptSig since we do not have a witness")
|
||||
case _: P2SHScriptPubKey | _: CLTVScriptPubKey | _: CSVScriptPubKey |
|
||||
_: NonStandardScriptPubKey | _: WitnessCommitment |
|
||||
EmptyScriptPubKey =>
|
||||
throw new IllegalArgumentException(
|
||||
"We only " +
|
||||
"want to generate P2PK, P2PKH, and MultiSig ScriptSignatures when creating a CSVScriptSignature")
|
||||
}
|
||||
} yield scriptPubKey match {
|
||||
case m: MultiSignatureScriptPubKey =>
|
||||
val requiredSigs = m.requiredSigs
|
||||
val cltvScriptSig = lockTimeHelper(Some(lockTime),
|
||||
sequence,
|
||||
cltv,
|
||||
privKeys,
|
||||
Some(requiredSigs),
|
||||
hashType)
|
||||
(cltvScriptSig.asInstanceOf[CLTVScriptSignature], cltv, privKeys)
|
||||
case _: P2PKHScriptPubKey | _: P2PKScriptPubKey =>
|
||||
val cltvScriptSig = lockTimeHelper(Some(lockTime),
|
||||
sequence,
|
||||
cltv,
|
||||
privKeys,
|
||||
None,
|
||||
hashType)
|
||||
(cltvScriptSig.asInstanceOf[CLTVScriptSignature], cltv, privKeys)
|
||||
case _: UnassignedWitnessScriptPubKey | _: WitnessScriptPubKeyV0 =>
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot created a witness scriptPubKey for a CSVScriptSig since we do not have a witness")
|
||||
case _: P2SHScriptPubKey | _: CLTVScriptPubKey | _: CSVScriptPubKey |
|
||||
_: NonStandardScriptPubKey | _: WitnessCommitment |
|
||||
EmptyScriptPubKey =>
|
||||
throw new IllegalArgumentException(
|
||||
"We only " +
|
||||
"want to generate P2PK, P2PKH, and MultiSig ScriptSignatures when creating a CSVScriptSignature")
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a signed `CLTVScriptSignature` that spends
|
||||
|
@ -461,31 +459,30 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger {
|
|||
(scriptPubKey, privKeys) <- randomNonLockTimeNonP2SHScriptPubKey
|
||||
hashType <- CryptoGenerators.hashType
|
||||
csv = CSVScriptPubKey(csvScriptNum, scriptPubKey)
|
||||
} yield
|
||||
scriptPubKey match {
|
||||
case m: MultiSignatureScriptPubKey =>
|
||||
val requiredSigs = m.requiredSigs
|
||||
val csvScriptSig = lockTimeHelper(None,
|
||||
sequence,
|
||||
csv,
|
||||
privKeys,
|
||||
Some(requiredSigs),
|
||||
hashType)
|
||||
(csvScriptSig.asInstanceOf[CSVScriptSignature], csv, privKeys)
|
||||
case _: P2PKHScriptPubKey | _: P2PKScriptPubKey =>
|
||||
val csvScriptSig =
|
||||
lockTimeHelper(None, sequence, csv, privKeys, None, hashType)
|
||||
(csvScriptSig.asInstanceOf[CSVScriptSignature], csv, privKeys)
|
||||
case _: UnassignedWitnessScriptPubKey | _: WitnessScriptPubKeyV0 =>
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot created a witness scriptPubKey for a CSVScriptSig since we do not have a witness")
|
||||
case _: P2SHScriptPubKey | _: CLTVScriptPubKey | _: CSVScriptPubKey |
|
||||
_: NonStandardScriptPubKey | _: WitnessCommitment |
|
||||
EmptyScriptPubKey =>
|
||||
throw new IllegalArgumentException(
|
||||
"We only " +
|
||||
"want to generate P2PK, P2PKH, and MultiSig ScriptSignatures when creating a CLTVScriptSignature.")
|
||||
}
|
||||
} yield scriptPubKey match {
|
||||
case m: MultiSignatureScriptPubKey =>
|
||||
val requiredSigs = m.requiredSigs
|
||||
val csvScriptSig = lockTimeHelper(None,
|
||||
sequence,
|
||||
csv,
|
||||
privKeys,
|
||||
Some(requiredSigs),
|
||||
hashType)
|
||||
(csvScriptSig.asInstanceOf[CSVScriptSignature], csv, privKeys)
|
||||
case _: P2PKHScriptPubKey | _: P2PKScriptPubKey =>
|
||||
val csvScriptSig =
|
||||
lockTimeHelper(None, sequence, csv, privKeys, None, hashType)
|
||||
(csvScriptSig.asInstanceOf[CSVScriptSignature], csv, privKeys)
|
||||
case _: UnassignedWitnessScriptPubKey | _: WitnessScriptPubKeyV0 =>
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot created a witness scriptPubKey for a CSVScriptSig since we do not have a witness")
|
||||
case _: P2SHScriptPubKey | _: CLTVScriptPubKey | _: CSVScriptPubKey |
|
||||
_: NonStandardScriptPubKey | _: WitnessCommitment |
|
||||
EmptyScriptPubKey =>
|
||||
throw new IllegalArgumentException(
|
||||
"We only " +
|
||||
"want to generate P2PK, P2PKH, and MultiSig ScriptSignatures when creating a CLTVScriptSignature.")
|
||||
}
|
||||
|
||||
def signedCSVScriptSignature: Gen[
|
||||
(CSVScriptSignature, CSVScriptPubKey, Seq[ECPrivateKey])] =
|
||||
|
@ -543,10 +540,9 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger {
|
|||
|
||||
val txSignatures: Seq[ECDigitalSignature] = for {
|
||||
i <- 0 until requiredSigs.getOrElse(1)
|
||||
} yield
|
||||
TransactionSignatureCreator.createSig(txSignatureComponent,
|
||||
privateKeys(i),
|
||||
hashType)
|
||||
} yield TransactionSignatureCreator.createSig(txSignatureComponent,
|
||||
privateKeys(i),
|
||||
hashType)
|
||||
|
||||
lock match {
|
||||
case csv: CSVScriptPubKey =>
|
||||
|
@ -572,12 +568,11 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger {
|
|||
p2shScriptPubKey = P2SHScriptPubKey(wtxSigComponent.scriptPubKey)
|
||||
p2shScriptSig = P2SHScriptSignature(
|
||||
wtxSigComponent.scriptPubKey.asInstanceOf[WitnessScriptPubKey])
|
||||
} yield
|
||||
(p2shScriptSig,
|
||||
p2shScriptPubKey,
|
||||
privKeys,
|
||||
witness,
|
||||
wtxSigComponent.amount)
|
||||
} yield (p2shScriptSig,
|
||||
p2shScriptPubKey,
|
||||
privKeys,
|
||||
witness,
|
||||
wtxSigComponent.amount)
|
||||
|
||||
def signedP2SHP2WSHScriptSignature: Gen[
|
||||
(
|
||||
|
@ -590,12 +585,11 @@ sealed abstract class ScriptGenerators extends BitcoinSLogger {
|
|||
(witness, wtxSigComponent, privKeys) <- WitnessGenerators.signedP2WSHTransactionWitness
|
||||
p2shScriptPubKey = P2SHScriptPubKey(wtxSigComponent.scriptPubKey)
|
||||
p2shScriptSig = P2SHScriptSignature(wtxSigComponent.scriptPubKey)
|
||||
} yield
|
||||
(p2shScriptSig,
|
||||
p2shScriptPubKey,
|
||||
privKeys,
|
||||
witness,
|
||||
wtxSigComponent.amount)
|
||||
} yield (p2shScriptSig,
|
||||
p2shScriptPubKey,
|
||||
privKeys,
|
||||
witness,
|
||||
wtxSigComponent.amount)
|
||||
|
||||
/**
|
||||
* This function chooses a random signed `ScriptSignature`
|
||||
|
|
|
@ -355,12 +355,11 @@ object TransactionGenerators extends BitcoinSLogger {
|
|||
for {
|
||||
(signedScriptSig, csvScriptPubKey, privateKeys) <- ScriptGenerators
|
||||
.signedCSVScriptSignature(csvScriptNum, sequence)
|
||||
} yield
|
||||
lockTimeTxHelper(signedScriptSig,
|
||||
csvScriptPubKey,
|
||||
privateKeys,
|
||||
sequence,
|
||||
None)
|
||||
} yield lockTimeTxHelper(signedScriptSig,
|
||||
csvScriptPubKey,
|
||||
privateKeys,
|
||||
sequence,
|
||||
None)
|
||||
|
||||
/** Generates a [[org.bitcoins.core.protocol.transaction.WitnessTransaction WitnessTransaction]] that has all of
|
||||
* it's inputs signed correctly */
|
||||
|
|
|
@ -192,10 +192,9 @@ sealed abstract class WitnessGenerators extends BitcoinSLogger {
|
|||
val requiredSigs = scriptPubKey.requiredSigs
|
||||
val txSignatures = for {
|
||||
i <- 0 until requiredSigs
|
||||
} yield
|
||||
TransactionSignatureCreator.createSig(unsignedWtxSigComponent,
|
||||
privateKeys(i),
|
||||
hashType)
|
||||
} yield TransactionSignatureCreator.createSig(unsignedWtxSigComponent,
|
||||
privateKeys(i),
|
||||
hashType)
|
||||
|
||||
//add the signature to the scriptSig instead of having an empty scriptSig
|
||||
val signedScriptSig = MultiSignatureScriptSignature(txSignatures)
|
||||
|
|
|
@ -101,16 +101,15 @@ sealed abstract class LnInvoiceGen {
|
|||
for {
|
||||
paymentHash <- paymentHashTag
|
||||
descOrHashTag <- descriptionOrDescriptionHashTag
|
||||
} yield
|
||||
LnTaggedFields(
|
||||
paymentHash = paymentHash,
|
||||
descriptionOrHash = descOrHashTag,
|
||||
expiryTime = None,
|
||||
cltvExpiry = None,
|
||||
fallbackAddress = None,
|
||||
nodeId = None,
|
||||
routingInfo = None
|
||||
)
|
||||
} yield LnTaggedFields(
|
||||
paymentHash = paymentHash,
|
||||
descriptionOrHash = descOrHashTag,
|
||||
expiryTime = None,
|
||||
cltvExpiry = None,
|
||||
fallbackAddress = None,
|
||||
nodeId = None,
|
||||
routingInfo = None
|
||||
)
|
||||
}
|
||||
|
||||
def optionalTags(nodeIdOpt: Option[NodeId]): Gen[LnTaggedFields] = {
|
||||
|
@ -123,16 +122,15 @@ sealed abstract class LnInvoiceGen {
|
|||
cltvExpiry <- Gen.option(cltvExpiry)
|
||||
fallbackAddress <- Gen.option(fallbackAddress)
|
||||
routes <- Gen.option(routingInfo)
|
||||
} yield
|
||||
LnTaggedFields(
|
||||
paymentHash = paymentHash,
|
||||
descriptionOrHash = descOrHashTag,
|
||||
expiryTime = expiryTime,
|
||||
cltvExpiry = cltvExpiry,
|
||||
fallbackAddress = fallbackAddress,
|
||||
nodeId = nodeIdOpt.map(NodeIdTag(_)),
|
||||
routingInfo = routes
|
||||
)
|
||||
} yield LnTaggedFields(
|
||||
paymentHash = paymentHash,
|
||||
descriptionOrHash = descOrHashTag,
|
||||
expiryTime = expiryTime,
|
||||
cltvExpiry = cltvExpiry,
|
||||
fallbackAddress = fallbackAddress,
|
||||
nodeId = nodeIdOpt.map(NodeIdTag(_)),
|
||||
routingInfo = routes
|
||||
)
|
||||
}
|
||||
|
||||
def allTags(nodeIdOpt: Option[NodeId]): Gen[LnTaggedFields] = {
|
||||
|
@ -145,16 +143,15 @@ sealed abstract class LnInvoiceGen {
|
|||
cltvExpiry <- cltvExpiry
|
||||
fallbackAddress <- fallbackAddress
|
||||
routes <- routingInfo
|
||||
} yield
|
||||
LnTaggedFields(
|
||||
paymentHash = paymentHash,
|
||||
descriptionOrHash = descOrHashTag,
|
||||
expiryTime = Some(expiryTime),
|
||||
cltvExpiry = Some(cltvExpiry),
|
||||
fallbackAddress = Some(fallbackAddress),
|
||||
nodeId = nodeIdOpt.map(NodeIdTag(_)),
|
||||
routingInfo = Some(routes)
|
||||
)
|
||||
} yield LnTaggedFields(
|
||||
paymentHash = paymentHash,
|
||||
descriptionOrHash = descOrHashTag,
|
||||
expiryTime = Some(expiryTime),
|
||||
cltvExpiry = Some(cltvExpiry),
|
||||
fallbackAddress = Some(fallbackAddress),
|
||||
nodeId = nodeIdOpt.map(NodeIdTag(_)),
|
||||
routingInfo = Some(routes)
|
||||
)
|
||||
}
|
||||
|
||||
/** Generated a tagged fields with an explicit
|
||||
|
|
|
@ -39,12 +39,11 @@ trait LnRouteGen {
|
|||
baseFee <- feeBaseMSat
|
||||
feeProp <- feeProportionalMillionths
|
||||
cltvExpiryDelta <- NumberGenerator.positiveShort
|
||||
} yield
|
||||
LnRoute(pubkey = pubKey,
|
||||
shortChannelID = id,
|
||||
feeBaseMsat = baseFee,
|
||||
feePropMilli = feeProp,
|
||||
cltvExpiryDelta = cltvExpiryDelta)
|
||||
} yield LnRoute(pubkey = pubKey,
|
||||
shortChannelID = id,
|
||||
feeBaseMsat = baseFee,
|
||||
feePropMilli = feeProp,
|
||||
cltvExpiryDelta = cltvExpiryDelta)
|
||||
|
||||
def routes: Gen[Vector[LnRoute]] = {
|
||||
Gen
|
||||
|
|
|
@ -38,13 +38,12 @@ object ControlMessageGenerator {
|
|||
for {
|
||||
fee <- CurrencyUnitGenerator.feeUnit.suchThat(
|
||||
!_.isInstanceOf[SatoshisPerVirtualByte])
|
||||
} yield
|
||||
fee match {
|
||||
case fee: SatoshisPerByte => FeeFilterMessage(fee)
|
||||
case fee: SatoshisPerKiloByte => FeeFilterMessage(fee)
|
||||
case SatoshisPerVirtualByte(_) =>
|
||||
throw new RuntimeException(s"We cannot end up here")
|
||||
}
|
||||
} yield fee match {
|
||||
case fee: SatoshisPerByte => FeeFilterMessage(fee)
|
||||
case fee: SatoshisPerKiloByte => FeeFilterMessage(fee)
|
||||
case SatoshisPerVirtualByte(_) =>
|
||||
throw new RuntimeException(s"We cannot end up here")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,22 +66,21 @@ object ControlMessageGenerator {
|
|||
userAgent <- StringGenerators.genString
|
||||
startHeight <- NumberGenerator.int32s
|
||||
relay = scala.util.Random.nextInt() % 2 == 0
|
||||
} yield
|
||||
VersionMessage(
|
||||
version,
|
||||
identifier,
|
||||
timestamp,
|
||||
addressReceiveServices,
|
||||
addressReceiveIpAddress,
|
||||
addressReceivePort,
|
||||
addressTransServices,
|
||||
addressTransIpAddress,
|
||||
addressTransPort,
|
||||
nonce,
|
||||
userAgent,
|
||||
startHeight,
|
||||
relay
|
||||
)
|
||||
} yield VersionMessage(
|
||||
version,
|
||||
identifier,
|
||||
timestamp,
|
||||
addressReceiveServices,
|
||||
addressReceiveIpAddress,
|
||||
addressReceivePort,
|
||||
addressTransServices,
|
||||
addressTransIpAddress,
|
||||
addressTransPort,
|
||||
nonce,
|
||||
userAgent,
|
||||
startHeight,
|
||||
relay
|
||||
)
|
||||
|
||||
/**
|
||||
* Generates a [[org.bitcoins.core.p2p.PingMessage]]
|
||||
|
@ -154,8 +152,10 @@ object ControlMessageGenerator {
|
|||
hashFuncs <- Gen.choose(0, 50)
|
||||
tweak <- NumberGenerator.uInt32s
|
||||
flags <- BloomFilterGenerator.bloomFlag
|
||||
} yield
|
||||
FilterLoadMessage(ByteVector(filter), UInt32(hashFuncs), tweak, flags)
|
||||
} yield FilterLoadMessage(ByteVector(filter),
|
||||
UInt32(hashFuncs),
|
||||
tweak,
|
||||
flags)
|
||||
|
||||
/**
|
||||
* Creates a [[org.bitcoins.core.p2p.FilterAddMessage]]
|
||||
|
|
|
@ -27,7 +27,7 @@ abstract class BitcoindRpcTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
sys.error {
|
||||
val msg =
|
||||
s""""bitcoind binary directory (${BitcoindRpcTestUtil.binaryDirectory}) is empty.
|
||||
|Run 'sbt downloadBitcoind' to fetch needed binaries""".stripMargin
|
||||
|Run 'sbt downloadBitcoind' to fetch needed binaries""".stripMargin
|
||||
msg
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,10 +38,10 @@ class WalletAppConfigTest extends BitcoinSUnitTest {
|
|||
|
||||
it should "not matter how the overrides are passed in" in {
|
||||
val overrider = ConfigFactory.parseString(s"""
|
||||
|bitcoin-s {
|
||||
| network = mainnet
|
||||
|}
|
||||
|""".stripMargin)
|
||||
|bitcoin-s {
|
||||
| network = mainnet
|
||||
|}
|
||||
|""".stripMargin)
|
||||
|
||||
val throughConstuctor = WalletAppConfig(tempDir, overrider)
|
||||
val throughWithOverrides = config.withOverrides(overrider)
|
||||
|
@ -82,15 +82,15 @@ class WalletAppConfigTest extends BitcoinSUnitTest {
|
|||
val tempDir = Files.createTempDirectory("bitcoin-s")
|
||||
val tempFile = Files.createFile(tempDir.resolve("bitcoin-s.conf"))
|
||||
val confStr = """
|
||||
| bitcoin-s {
|
||||
| network = testnet3
|
||||
|
|
||||
| logging {
|
||||
| level = off
|
||||
|
|
||||
| p2p = warn
|
||||
| }
|
||||
| }
|
||||
| bitcoin-s {
|
||||
| network = testnet3
|
||||
|
|
||||
| logging {
|
||||
| level = off
|
||||
|
|
||||
| p2p = warn
|
||||
| }
|
||||
| }
|
||||
""".stripMargin
|
||||
val _ = Files.write(tempFile, confStr.getBytes())
|
||||
|
||||
|
|
|
@ -91,11 +91,11 @@ class WalletStorageTest
|
|||
it must "fail to read a mnemonic that has bad JSON in it" in { _ =>
|
||||
val badJson =
|
||||
"""
|
||||
| {
|
||||
| "iv":"ba7722683dad8067df8d069ee04530cc",
|
||||
| "cipherText":,
|
||||
| "salt":"2b7e7d718139518070a87fbbda03ea33cdcda83b555020e9344774e6e7d08af2"
|
||||
| }
|
||||
| {
|
||||
| "iv":"ba7722683dad8067df8d069ee04530cc",
|
||||
| "cipherText":,
|
||||
| "salt":"2b7e7d718139518070a87fbbda03ea33cdcda83b555020e9344774e6e7d08af2"
|
||||
| }
|
||||
""".stripMargin
|
||||
Files.write(datadir.resolve(WalletStorage.ENCRYPTED_SEED_FILE_NAME),
|
||||
badJson.getBytes())
|
||||
|
|
|
@ -25,12 +25,11 @@ class SpendingInfoDAOTest extends BitcoinSWalletTest with WalletDAOFixture {
|
|||
for {
|
||||
created <- WalletTestUtil.insertSegWitUTXO(daos)
|
||||
read <- utxoDAO.read(created.id.get)
|
||||
} yield
|
||||
read match {
|
||||
case None => fail(s"Did not read back a UTXO")
|
||||
case Some(_: SegwitV0SpendingInfo) => succeed
|
||||
case Some(other) => fail(s"did not get segwit UTXO: $other")
|
||||
}
|
||||
} yield read match {
|
||||
case None => fail(s"Did not read back a UTXO")
|
||||
case Some(_: SegwitV0SpendingInfo) => succeed
|
||||
case Some(other) => fail(s"did not get segwit UTXO: $other")
|
||||
}
|
||||
}
|
||||
|
||||
it should "insert a legacy UTXO and read it" in { daos =>
|
||||
|
@ -38,12 +37,11 @@ class SpendingInfoDAOTest extends BitcoinSWalletTest with WalletDAOFixture {
|
|||
for {
|
||||
created <- WalletTestUtil.insertLegacyUTXO(daos)
|
||||
read <- utxoDAO.read(created.id.get)
|
||||
} yield
|
||||
read match {
|
||||
case None => fail(s"Did not read back a UTXO")
|
||||
case Some(_: LegacySpendingInfo) => succeed
|
||||
case Some(other) => fail(s"did not get a legacy UTXO: $other")
|
||||
}
|
||||
} yield read match {
|
||||
case None => fail(s"Did not read back a UTXO")
|
||||
case Some(_: LegacySpendingInfo) => succeed
|
||||
case Some(other) => fail(s"did not get a legacy UTXO: $other")
|
||||
}
|
||||
}
|
||||
|
||||
it should "find incoming outputs being spent, given a TX" in { daos =>
|
||||
|
|
|
@ -47,11 +47,10 @@ private[wallet] trait AddressHandling extends KeyHandlingLogger {
|
|||
Vector[(TransactionOutput, TransactionOutPoint)]] =
|
||||
for {
|
||||
spks <- listSPKs()
|
||||
} yield
|
||||
transaction.outputs.zipWithIndex.collect {
|
||||
case (out, index) if spks.contains(out.scriptPubKey) =>
|
||||
(out, TransactionOutPoint(transaction.txId, UInt32(index)))
|
||||
}.toVector
|
||||
} yield transaction.outputs.zipWithIndex.collect {
|
||||
case (out, index) if spks.contains(out.scriptPubKey) =>
|
||||
(out, TransactionOutPoint(transaction.txId, UInt32(index)))
|
||||
}.toVector
|
||||
|
||||
/**
|
||||
* Derives a new address in the wallet for the
|
||||
|
|
|
@ -134,13 +134,12 @@ private[wallet] trait UtxoHandling extends KeyHandlingLogger {
|
|||
addressDbEitherF.flatMap { addressDbE =>
|
||||
val biasedE: CompatEither[AddUtxoError, Future[SpendingInfoDb]] = for {
|
||||
addressDb <- addressDbE
|
||||
} yield
|
||||
writeUtxo(txid = transaction.txIdBE,
|
||||
confirmations = confirmations,
|
||||
spent = spent,
|
||||
output,
|
||||
outPoint,
|
||||
addressDb)
|
||||
} yield writeUtxo(txid = transaction.txIdBE,
|
||||
confirmations = confirmations,
|
||||
spent = spent,
|
||||
output,
|
||||
outPoint,
|
||||
addressDb)
|
||||
|
||||
EitherUtil.liftRightBiasedFutureE(biasedE)
|
||||
} map {
|
||||
|
|
|
@ -19,20 +19,18 @@ import scodec.bits.ByteVector
|
|||
* @param rawBlockListener
|
||||
*/
|
||||
class ZMQSubscriber(
|
||||
socket: InetSocketAddress,
|
||||
hashTxListener: Option[ByteVector => Unit],
|
||||
hashBlockListener: Option[ByteVector => Unit],
|
||||
rawTxListener: Option[ByteVector => Unit],
|
||||
rawBlockListener: Option[ByteVector => Unit])
|
||||
extends BitcoinSLogger {
|
||||
socket: InetSocketAddress,
|
||||
hashTxListener: Option[ByteVector => Unit],
|
||||
hashBlockListener: Option[ByteVector => Unit],
|
||||
rawTxListener: Option[ByteVector => Unit],
|
||||
rawBlockListener: Option[ByteVector => Unit])
|
||||
extends BitcoinSLogger {
|
||||
|
||||
private var running = true
|
||||
private val context = ZMQ.context(1)
|
||||
|
||||
private val subscriber: ZMQ.Socket = context.socket(SocketType.SUB)
|
||||
|
||||
|
||||
|
||||
private val uri = socket.getHostString + ":" + socket.getPort
|
||||
|
||||
private case object SubscriberRunnable extends Runnable {
|
||||
|
@ -91,7 +89,8 @@ class ZMQSubscriber(
|
|||
}
|
||||
|
||||
private val subscriberThread = new Thread(SubscriberRunnable)
|
||||
subscriberThread.setName(s"ZMQSubscriber-thread-${System.currentTimeMillis()}")
|
||||
subscriberThread.setName(
|
||||
s"ZMQSubscriber-thread-${System.currentTimeMillis()}")
|
||||
subscriberThread.setDaemon(true)
|
||||
|
||||
def start(): Unit = {
|
||||
|
|
Loading…
Add table
Reference in a new issue