mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-26 21:42:48 +01:00
Remove CompatEither, it was needed for historical purposes to support… (#2394)
* Remove CompatEither, it was needed for historical purposes to support Scala 2.11.x * Revert files from another change
This commit is contained in:
parent
2db21fc3d2
commit
719fab23b7
7 changed files with 70 additions and 272 deletions
|
@ -1,53 +0,0 @@
|
|||
package org.bitcoins.core.compat
|
||||
|
||||
import org.bitcoins.testkit.util.BitcoinSUnitTest
|
||||
|
||||
import scala.annotation.nowarn
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
class CompatEitherTest extends BitcoinSUnitTest {
|
||||
|
||||
it should "create left and right" in {
|
||||
|
||||
val right = Right("Right")
|
||||
val compatRight = CompatEither(right)
|
||||
assert(compatRight.isInstanceOf[CompatRight[Nothing, String]])
|
||||
assert(compatRight.toTry == Success("Right"))
|
||||
|
||||
val exception = new RuntimeException("Left")
|
||||
val left = Left(exception)
|
||||
val compatLeft = CompatEither(left)
|
||||
assert(compatLeft.isInstanceOf[CompatLeft[RuntimeException, Nothing]])
|
||||
assert(compatLeft.toTry == Failure(exception))
|
||||
}
|
||||
|
||||
it should "do traverse operations" in {
|
||||
val mappedRight = CompatEither(Right(12)).map(_ => "flower")
|
||||
assert(mappedRight == CompatEither(Right("flower")))
|
||||
@nowarn val mappedLeft = CompatEither(Left(12)).map(_ => "flower")
|
||||
assert(mappedLeft == CompatEither(Left(12)))
|
||||
|
||||
val flatmappedRight: CompatEither[Int, String] =
|
||||
CompatEither(Right(12)).flatMap(_ => CompatEither(Right("flower")))
|
||||
assert(flatmappedRight == CompatRight("flower"))
|
||||
@nowarn val flatmappedLeft =
|
||||
CompatEither(Left(12)).flatMap(_ => CompatEither(Left("21")))
|
||||
assert(flatmappedLeft == CompatLeft(12))
|
||||
|
||||
@nowarn val foldedRight = CompatEither(Right(12)).fold({ _ =>
|
||||
"left"
|
||||
},
|
||||
{ _ =>
|
||||
"right"
|
||||
})
|
||||
assert(foldedRight == "right")
|
||||
@nowarn val foldedLeft = CompatEither(Left(12)).fold({ _ =>
|
||||
"left"
|
||||
},
|
||||
{ _ =>
|
||||
"right"
|
||||
})
|
||||
assert(foldedLeft == "left")
|
||||
}
|
||||
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
package org.bitcoins.core.compat
|
||||
|
||||
import scala.util.{Failure, Success, Try}
|
||||
|
||||
/** This is an implementation of (parts of)
|
||||
* `scala.util.Either`, compatible with Scala 2.11,
|
||||
* 2.12 and 2.13. It is in large parts cribbed from
|
||||
* the Scala 2.12 standard library.
|
||||
*/
|
||||
sealed private[bitcoins] trait CompatEither[+A, +B] {
|
||||
|
||||
protected val underlying: Either[A, B]
|
||||
|
||||
/** The given function is applied if this is a `Right`.
|
||||
*
|
||||
* {{{
|
||||
* Right(12).map(x => "flower") // Result: Right("flower")
|
||||
* Left(12).map(x => "flower") // Result: Left(12)
|
||||
* }}}
|
||||
*/
|
||||
def map[B1](f: B => B1): CompatEither[A, B1] =
|
||||
underlying match {
|
||||
case Right(b) => CompatRight(f(b))
|
||||
case _ => this.asInstanceOf[CompatEither[A, B1]]
|
||||
}
|
||||
|
||||
/** Binds the given function across `Right`.
|
||||
*
|
||||
* @param f The function to bind across `Right`.
|
||||
*/
|
||||
def flatMap[A1 >: A, B1](f: B => CompatEither[A1, B1]): CompatEither[A1, B1] =
|
||||
underlying match {
|
||||
case Right(b) =>
|
||||
f(b) match {
|
||||
case CompatLeft(value) => CompatLeft(value)
|
||||
case CompatRight(value) => CompatRight(value)
|
||||
|
||||
}
|
||||
case Left(l) => CompatLeft(l)
|
||||
}
|
||||
|
||||
def toTry(implicit ev: A <:< Throwable): Try[B] =
|
||||
underlying match {
|
||||
case Right(b) => Success(b)
|
||||
case Left(a) => Failure(a)
|
||||
}
|
||||
|
||||
/** Applies `fa` if this is a `Left` or `fb` if this is a `Right`.
|
||||
*
|
||||
* @example {{{
|
||||
* val result = util.Try("42".toInt).toEither
|
||||
* result.fold(
|
||||
* e => s"Operation failed with $e",
|
||||
* v => s"Operation produced value: $v"
|
||||
* )
|
||||
* }}}
|
||||
*
|
||||
* @param fa the function to apply if this is a `Left`
|
||||
* @param fb the function to apply if this is a `Right`
|
||||
* @return the results of applying the function
|
||||
*/
|
||||
def fold[C](fa: A => C, fb: B => C): C =
|
||||
underlying match {
|
||||
case Right(b) => fb(b)
|
||||
case Left(a) => fa(a)
|
||||
}
|
||||
}
|
||||
|
||||
object CompatEither {
|
||||
|
||||
/** Converts the given `scala.util.Either` to a `CompatEither` */
|
||||
def apply[A, B](either: Either[A, B]): CompatEither[A, B] =
|
||||
either match {
|
||||
case Left(value) => CompatLeft(value)
|
||||
case Right(value) => CompatRight(value)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Analogous to `scala.util.Left` */
|
||||
case class CompatLeft[A, B](value: A) extends CompatEither[A, B] {
|
||||
val underlying = scala.util.Left[A, B](value)
|
||||
|
||||
}
|
||||
|
||||
/** Analogous to `scala.util.Right` */
|
||||
case class CompatRight[A, B](value: B) extends CompatEither[A, B] {
|
||||
val underlying = scala.util.Right[A, B](value)
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package org.bitcoins.core.util
|
||||
|
||||
import org.bitcoins.core.compat.{CompatEither, CompatLeft, CompatRight}
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
/**
|
||||
* @define liftBiasedFut Given a [[scala.Either Either]] that contains a
|
||||
* [[scala.concurrent.Future Future[L | R] ]] only on one side,
|
||||
* transforms it into a future [[scala.Either Either[L, R] ]]
|
||||
*/
|
||||
object EitherUtil {
|
||||
|
||||
/**
|
||||
* Flattens a nested `Either[Foo, Future[Foo, Bar]]` into
|
||||
* a `Future[Either[Foo, Bar]]`. This is EitherUtiluseful for situtations
|
||||
* where the right hand side of an either is asynchronous.
|
||||
*/
|
||||
def flattenFutureE[L, R](
|
||||
either: CompatEither[L, Future[CompatEither[L, R]]]
|
||||
): Future[CompatEither[L, R]] = {
|
||||
|
||||
def ifLeft(left: L): Future[CompatEither[L, R]] =
|
||||
Future.successful(CompatLeft(left))
|
||||
def ifRight(
|
||||
rightF: Future[CompatEither[L, R]]): Future[CompatEither[L, R]] =
|
||||
rightF
|
||||
|
||||
either.fold(ifLeft, ifRight)
|
||||
}
|
||||
|
||||
/** $liftBiasedFut */
|
||||
def liftRightBiasedFutureE[L, R](
|
||||
either: CompatEither[L, Future[R]]
|
||||
)(implicit ec: ExecutionContext): Future[CompatEither[L, R]] =
|
||||
either match {
|
||||
case CompatRight(fut) => fut.map(elem => CompatRight(elem))
|
||||
case CompatLeft(l) => Future.successful(CompatLeft(l))
|
||||
}
|
||||
|
||||
/** $liftBiasedFut */
|
||||
def listLeftBiasedFutureE[L, R](
|
||||
either: Either[Future[L], R]
|
||||
)(implicit ec: ExecutionContext): Future[Either[L, R]] =
|
||||
either match {
|
||||
case Left(fut) => fut.map(Left(_))
|
||||
case Right(l) => Future.successful(Right(l))
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package org.bitcoins.keymanager
|
||||
|
||||
import org.bitcoins.core.compat.CompatEither
|
||||
import org.bitcoins.core.crypto._
|
||||
import org.bitcoins.crypto.{AesCrypt, AesEncryptedData, AesPassword, AesSalt}
|
||||
import scodec.bits.ByteVector
|
||||
|
@ -48,7 +47,7 @@ case class EncryptedSeed(
|
|||
private def decryptStr(password: AesPassword): Try[String] = {
|
||||
val key = password.toKey(salt)
|
||||
val either = AesCrypt.decrypt(value, key)
|
||||
CompatEither(either).toTry.flatMap { decrypted =>
|
||||
either.toTry.flatMap { decrypted =>
|
||||
decrypted.decodeUtf8 match {
|
||||
case Left(_) =>
|
||||
// when failing to decode this to a UTF-8 string
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package org.bitcoins.keymanager
|
||||
|
||||
import org.bitcoins.core.compat._
|
||||
import org.bitcoins.core.crypto._
|
||||
import org.bitcoins.crypto._
|
||||
import scodec.bits.ByteVector
|
||||
|
@ -156,22 +155,22 @@ object WalletStorage extends KeyManagerLogger {
|
|||
}
|
||||
|
||||
private def readJsonFromDisk(
|
||||
seedPath: Path): CompatEither[ReadMnemonicError, Value] = {
|
||||
seedPath: Path): Either[ReadMnemonicError, Value] = {
|
||||
if (Files.isRegularFile(seedPath)) {
|
||||
val rawJson = Files.readAllLines(seedPath).asScala.mkString("\n")
|
||||
logger.debug(s"Read raw mnemonic from $seedPath")
|
||||
|
||||
Try(ujson.read(rawJson)) match {
|
||||
case Failure(ujson.ParseException(clue, _, _, _)) =>
|
||||
CompatLeft(ReadMnemonicError.JsonParsingError(clue))
|
||||
Left(ReadMnemonicError.JsonParsingError(clue))
|
||||
case Failure(exception) => throw exception
|
||||
case Success(value) =>
|
||||
logger.debug(s"Parsed $seedPath into valid json")
|
||||
CompatRight(value)
|
||||
Right(value)
|
||||
}
|
||||
} else {
|
||||
logger.error(s"Mnemonic not found at $seedPath")
|
||||
CompatLeft(ReadMnemonicError.NotFoundError)
|
||||
Left(ReadMnemonicError.NotFoundError)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,14 +178,14 @@ object WalletStorage extends KeyManagerLogger {
|
|||
* performing no decryption
|
||||
*/
|
||||
private def readEncryptedMnemonicFromDisk(
|
||||
seedPath: Path): CompatEither[ReadMnemonicError, EncryptedSeed] = {
|
||||
seedPath: Path): Either[ReadMnemonicError, EncryptedSeed] = {
|
||||
|
||||
val jsonE = readJsonFromDisk(seedPath)
|
||||
|
||||
import MnemonicJsonKeys._
|
||||
import ReadMnemonicError._
|
||||
|
||||
val readJsonTupleEither: CompatEither[
|
||||
val readJsonTupleEither: Either[
|
||||
ReadMnemonicError,
|
||||
(String, String, String, Long)] = jsonE.flatMap { json =>
|
||||
logger.trace(s"Read encrypted mnemonic JSON: $json")
|
||||
|
@ -197,13 +196,13 @@ object WalletStorage extends KeyManagerLogger {
|
|||
val rawSaltString = json(SALT).str
|
||||
(ivString, cipherTextString, rawSaltString, creationTimeNum)
|
||||
} match {
|
||||
case Success(value) => CompatRight(value)
|
||||
case Success(value) => Right(value)
|
||||
case Failure(exception) =>
|
||||
CompatLeft(JsonParsingError(exception.getMessage))
|
||||
Left(JsonParsingError(exception.getMessage))
|
||||
}
|
||||
}
|
||||
|
||||
val encryptedEither: CompatEither[ReadMnemonicError, EncryptedSeed] =
|
||||
val encryptedEither: Either[ReadMnemonicError, EncryptedSeed] =
|
||||
readJsonTupleEither.flatMap {
|
||||
case (rawIv, rawCipherText, rawSalt, rawCreationTime) =>
|
||||
val encryptedOpt = for {
|
||||
|
@ -217,39 +216,38 @@ object WalletStorage extends KeyManagerLogger {
|
|||
salt,
|
||||
Instant.ofEpochSecond(rawCreationTime))
|
||||
}
|
||||
val toRight: Option[CompatRight[ReadMnemonicError, EncryptedSeed]] =
|
||||
val toRight: Option[Right[ReadMnemonicError, EncryptedSeed]] =
|
||||
encryptedOpt
|
||||
.map(CompatRight(_))
|
||||
.map(Right(_))
|
||||
|
||||
toRight.getOrElse(
|
||||
CompatLeft(JsonParsingError("JSON contents was not hex strings")))
|
||||
Left(JsonParsingError("JSON contents was not hex strings")))
|
||||
}
|
||||
encryptedEither
|
||||
}
|
||||
|
||||
/** Reads the raw unencrypted mnemonic from disk */
|
||||
private def readUnencryptedMnemonicFromDisk(
|
||||
seedPath: Path): CompatEither[ReadMnemonicError, DecryptedMnemonic] = {
|
||||
seedPath: Path): Either[ReadMnemonicError, DecryptedMnemonic] = {
|
||||
|
||||
val jsonE = readJsonFromDisk(seedPath)
|
||||
|
||||
import MnemonicJsonKeys._
|
||||
import ReadMnemonicError._
|
||||
|
||||
val readJsonTupleEither: CompatEither[
|
||||
ReadMnemonicError,
|
||||
(Vector[String], Long)] = jsonE.flatMap { json =>
|
||||
logger.trace(s"Read mnemonic JSON: Masked(json)")
|
||||
Try {
|
||||
val creationTimeNum = parseCreationTime(json)
|
||||
val words = json(MNEMONIC_SEED).arr.toVector.map(_.str)
|
||||
(words, creationTimeNum)
|
||||
} match {
|
||||
case Success(value) => CompatRight(value)
|
||||
case Failure(exception) =>
|
||||
CompatLeft(JsonParsingError(exception.getMessage))
|
||||
val readJsonTupleEither: Either[ReadMnemonicError, (Vector[String], Long)] =
|
||||
jsonE.flatMap { json =>
|
||||
logger.trace(s"Read mnemonic JSON: Masked(json)")
|
||||
Try {
|
||||
val creationTimeNum = parseCreationTime(json)
|
||||
val words = json(MNEMONIC_SEED).arr.toVector.map(_.str)
|
||||
(words, creationTimeNum)
|
||||
} match {
|
||||
case Success(value) => Right(value)
|
||||
case Failure(exception) =>
|
||||
Left(JsonParsingError(exception.getMessage))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
readJsonTupleEither.flatMap {
|
||||
case (words, rawCreationTime) =>
|
||||
|
@ -261,25 +259,25 @@ object WalletStorage extends KeyManagerLogger {
|
|||
Instant.ofEpochSecond(rawCreationTime))
|
||||
}
|
||||
|
||||
val toRight: Try[CompatRight[ReadMnemonicError, DecryptedMnemonic]] =
|
||||
val toRight: Try[Right[ReadMnemonicError, DecryptedMnemonic]] =
|
||||
decryptedMnemonicT
|
||||
.map(CompatRight(_))
|
||||
.map(Right(_))
|
||||
|
||||
toRight.getOrElse(
|
||||
CompatLeft(JsonParsingError("JSON contents was correctly formatted")))
|
||||
Left(JsonParsingError("JSON contents was correctly formatted")))
|
||||
}
|
||||
}
|
||||
|
||||
/** Reads the raw unencrypted xprv from disk */
|
||||
private def readUnencryptedSeedFromDisk(
|
||||
seedPath: Path): CompatEither[ReadMnemonicError, DecryptedExtPrivKey] = {
|
||||
seedPath: Path): Either[ReadMnemonicError, DecryptedExtPrivKey] = {
|
||||
|
||||
val jsonE = readJsonFromDisk(seedPath)
|
||||
|
||||
import MnemonicJsonKeys._
|
||||
import ReadMnemonicError._
|
||||
|
||||
val readJsonTupleEither: CompatEither[ReadMnemonicError, (String, Long)] =
|
||||
val readJsonTupleEither: Either[ReadMnemonicError, (String, Long)] =
|
||||
jsonE.flatMap { json =>
|
||||
logger.trace(s"Read mnemonic JSON: Masked(json)")
|
||||
Try {
|
||||
|
@ -287,9 +285,9 @@ object WalletStorage extends KeyManagerLogger {
|
|||
val xprvStr = json(XPRV).str
|
||||
(xprvStr, creationTimeNum)
|
||||
} match {
|
||||
case Success(value) => CompatRight(value)
|
||||
case Success(value) => Right(value)
|
||||
case Failure(exception) =>
|
||||
CompatLeft(JsonParsingError(exception.getMessage))
|
||||
Left(JsonParsingError(exception.getMessage))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,12 +298,12 @@ object WalletStorage extends KeyManagerLogger {
|
|||
DecryptedExtPrivKey(xprv, Instant.ofEpochSecond(rawCreationTime))
|
||||
}
|
||||
|
||||
val toRight: Try[CompatRight[ReadMnemonicError, DecryptedExtPrivKey]] =
|
||||
val toRight: Try[Right[ReadMnemonicError, DecryptedExtPrivKey]] =
|
||||
decryptedExtPrivKeyT
|
||||
.map(CompatRight(_))
|
||||
.map(Right(_))
|
||||
|
||||
toRight.getOrElse(
|
||||
CompatLeft(JsonParsingError("JSON contents was correctly formatted")))
|
||||
Left(JsonParsingError("JSON contents was correctly formatted")))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,7 +316,7 @@ object WalletStorage extends KeyManagerLogger {
|
|||
passphraseOpt: Option[AesPassword]): Either[
|
||||
ReadMnemonicError,
|
||||
DecryptedSeedState] = {
|
||||
val decryptedEither: CompatEither[ReadMnemonicError, DecryptedSeedState] =
|
||||
val decryptedEither: Either[ReadMnemonicError, DecryptedSeedState] =
|
||||
passphraseOpt match {
|
||||
case Some(passphrase) =>
|
||||
val encryptedEither = readEncryptedMnemonicFromDisk(seedPath)
|
||||
|
@ -329,32 +327,29 @@ object WalletStorage extends KeyManagerLogger {
|
|||
encrypted.toExtPrivKey(passphrase) match {
|
||||
case Failure(exc) =>
|
||||
logger.error(s"Error when decrypting $encrypted: $exc")
|
||||
CompatLeft(ReadMnemonicError.DecryptionError)
|
||||
Left(ReadMnemonicError.DecryptionError)
|
||||
case Success(xprv) =>
|
||||
logger.debug(s"Decrypted $encrypted successfully")
|
||||
val decryptedExtPrivKey =
|
||||
DecryptedExtPrivKey(xprv, encrypted.creationTime)
|
||||
CompatRight(decryptedExtPrivKey)
|
||||
Right(decryptedExtPrivKey)
|
||||
}
|
||||
case Success(mnemonic) =>
|
||||
logger.debug(s"Decrypted $encrypted successfully")
|
||||
val decryptedMnemonic =
|
||||
DecryptedMnemonic(mnemonic, encrypted.creationTime)
|
||||
CompatRight(decryptedMnemonic)
|
||||
Right(decryptedMnemonic)
|
||||
}
|
||||
}
|
||||
case None =>
|
||||
readUnencryptedMnemonicFromDisk(seedPath) match {
|
||||
case CompatLeft(_) =>
|
||||
case Left(_) =>
|
||||
readUnencryptedSeedFromDisk(seedPath)
|
||||
case CompatRight(mnemonic) => CompatRight(mnemonic)
|
||||
case Right(mnemonic) => Right(mnemonic)
|
||||
}
|
||||
}
|
||||
|
||||
decryptedEither match {
|
||||
case CompatLeft(value) => Left(value)
|
||||
case CompatRight(value) => Right(value)
|
||||
}
|
||||
decryptedEither
|
||||
}
|
||||
|
||||
def changeAesPassword(
|
||||
|
|
|
@ -5,7 +5,6 @@ import org.bitcoins.core.api.keymanager.{
|
|||
BIP39KeyManagerCreateApi,
|
||||
KeyManagerApi
|
||||
}
|
||||
import org.bitcoins.core.compat.{CompatEither, CompatLeft, CompatRight}
|
||||
import org.bitcoins.core.crypto._
|
||||
import org.bitcoins.core.hd.{HDAccount, HDPath}
|
||||
import org.bitcoins.core.util.{BitcoinSLogger, HDUtil, TimeUtil}
|
||||
|
@ -99,26 +98,24 @@ object BIP39KeyManager
|
|||
|
||||
val time = TimeUtil.now
|
||||
|
||||
val writtenToDiskE: CompatEither[KeyManagerInitializeError, KeyManagerApi] =
|
||||
val writtenToDiskE: Either[KeyManagerInitializeError, KeyManagerApi] =
|
||||
if (Files.notExists(seedPath)) {
|
||||
logger.info(
|
||||
s"Seed path parent directory does not exist, creating ${seedPath.getParent}")
|
||||
Files.createDirectories(seedPath.getParent)
|
||||
|
||||
val mnemonicT = Try(MnemonicCode.fromEntropy(entropy))
|
||||
val mnemonicE: CompatEither[KeyManagerInitializeError, MnemonicCode] =
|
||||
val mnemonicE: Either[KeyManagerInitializeError, MnemonicCode] =
|
||||
mnemonicT match {
|
||||
case Success(mnemonic) =>
|
||||
logger.info(s"Created mnemonic from entropy")
|
||||
CompatEither(Right(mnemonic))
|
||||
Right(mnemonic)
|
||||
case Failure(err) =>
|
||||
logger.error(s"Could not create mnemonic from entropy! $err")
|
||||
CompatEither(Left(InitializeKeyManagerError.BadEntropy))
|
||||
Left(InitializeKeyManagerError.BadEntropy)
|
||||
}
|
||||
|
||||
val writableMnemonicE: CompatEither[
|
||||
KeyManagerInitializeError,
|
||||
SeedState] =
|
||||
val writableMnemonicE: Either[KeyManagerInitializeError, SeedState] =
|
||||
mnemonicE.map { mnemonic =>
|
||||
val decryptedMnemonic = DecryptedMnemonic(mnemonic, time)
|
||||
aesPasswordOpt match {
|
||||
|
@ -148,16 +145,16 @@ object BIP39KeyManager
|
|||
WalletStorage.decryptSeedFromDisk(kmParams.seedPath,
|
||||
aesPasswordOpt) match {
|
||||
case Right(mnemonic: DecryptedMnemonic) =>
|
||||
CompatRight(
|
||||
Right(
|
||||
fromMnemonic(mnemonic = mnemonic.mnemonicCode,
|
||||
kmParams = kmParams,
|
||||
bip39PasswordOpt = bip39PasswordOpt,
|
||||
creationTime = mnemonic.creationTime))
|
||||
case Right(xprv: DecryptedExtPrivKey) =>
|
||||
val km = new BIP39KeyManager(xprv.xprv, kmParams, xprv.creationTime)
|
||||
CompatRight(km)
|
||||
Right(km)
|
||||
case Left(err) =>
|
||||
CompatLeft(
|
||||
Left(
|
||||
InitializeKeyManagerError.FailedToReadWrittenSeed(
|
||||
JsonParsingError(err.toString)))
|
||||
}
|
||||
|
@ -169,7 +166,7 @@ object BIP39KeyManager
|
|||
bip39PasswordOpt,
|
||||
kmParams = kmParams)
|
||||
|
||||
val biasedFinalE: CompatEither[KeyManagerInitializeError, BIP39KeyManager] =
|
||||
val biasedFinalE: Either[KeyManagerInitializeError, BIP39KeyManager] =
|
||||
for {
|
||||
kmBeforeWrite <- writtenToDiskE
|
||||
invariant <- unlocked match {
|
||||
|
@ -178,20 +175,20 @@ object BIP39KeyManager
|
|||
unlockedKeyManager == kmBeforeWrite,
|
||||
s"We could not read the key manager we just wrote! $kmBeforeWrite != $unlockedKeyManager"
|
||||
)
|
||||
CompatRight(unlockedKeyManager)
|
||||
Right(unlockedKeyManager)
|
||||
|
||||
case Left(err) =>
|
||||
CompatLeft(InitializeKeyManagerError.FailedToReadWrittenSeed(err))
|
||||
Left(InitializeKeyManagerError.FailedToReadWrittenSeed(err))
|
||||
}
|
||||
} yield {
|
||||
invariant
|
||||
}
|
||||
|
||||
biasedFinalE match {
|
||||
case CompatRight(initSuccess) =>
|
||||
case Right(initSuccess) =>
|
||||
logger.info(s"Successfully initialized wallet")
|
||||
Right(initSuccess)
|
||||
case CompatLeft(err) =>
|
||||
case Left(err) =>
|
||||
logger.error(s"Failed to initialize key manager with err=$err")
|
||||
Left(err)
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import org.bitcoins.core.api.wallet.{
|
|||
AddUtxoResult,
|
||||
AddUtxoSuccess
|
||||
}
|
||||
import org.bitcoins.core.compat._
|
||||
import org.bitcoins.core.consensus.Consensus
|
||||
import org.bitcoins.core.hd.HDAccount
|
||||
import org.bitcoins.core.number.UInt32
|
||||
|
@ -22,7 +21,7 @@ import org.bitcoins.core.protocol.transaction.{
|
|||
TransactionOutPoint,
|
||||
TransactionOutput
|
||||
}
|
||||
import org.bitcoins.core.util.{EitherUtil, FutureUtil}
|
||||
import org.bitcoins.core.util.FutureUtil
|
||||
import org.bitcoins.core.wallet.utxo._
|
||||
import org.bitcoins.crypto.DoubleSha256DigestBE
|
||||
import org.bitcoins.wallet.{Wallet, WalletLogger}
|
||||
|
@ -164,14 +163,14 @@ private[wallet] trait UtxoHandling extends WalletLogger {
|
|||
* it in our address table
|
||||
*/
|
||||
private def findAddress(
|
||||
spk: ScriptPubKey): Future[CompatEither[AddUtxoError, AddressDb]] =
|
||||
spk: ScriptPubKey): Future[Either[AddUtxoError, AddressDb]] =
|
||||
BitcoinAddress.fromScriptPubKeyT(spk, networkParameters) match {
|
||||
case Success(address) =>
|
||||
addressDAO.findAddress(address).map {
|
||||
case Some(addrDb) => CompatRight(addrDb)
|
||||
case None => CompatLeft(AddUtxoError.AddressNotFound)
|
||||
case Some(addrDb) => Right(addrDb)
|
||||
case None => Left(AddUtxoError.AddressNotFound)
|
||||
}
|
||||
case Failure(_) => Future.successful(CompatLeft(AddUtxoError.BadSPK))
|
||||
case Failure(_) => Future.successful(Left(AddUtxoError.BadSPK))
|
||||
}
|
||||
|
||||
/** Constructs a DB level representation of the given UTXO, and persist it to disk */
|
||||
|
@ -257,12 +256,13 @@ private[wallet] trait UtxoHandling extends WalletLogger {
|
|||
|
||||
// second check: do we have an address associated with the provided
|
||||
// output in our DB?
|
||||
def addressDbEitherF: Future[CompatEither[AddUtxoError, AddressDb]] =
|
||||
def addressDbEitherF: Future[Either[AddUtxoError, AddressDb]] = {
|
||||
findAddress(output.scriptPubKey)
|
||||
}
|
||||
|
||||
// insert the UTXO into the DB
|
||||
addressDbEitherF.flatMap { addressDbE =>
|
||||
def biasedE: CompatEither[AddUtxoError, Future[SpendingInfoDb]] =
|
||||
addressDbEitherF
|
||||
.map { addressDbE =>
|
||||
for {
|
||||
addressDb <- addressDbE
|
||||
} yield writeUtxo(tx = transaction,
|
||||
|
@ -271,12 +271,11 @@ private[wallet] trait UtxoHandling extends WalletLogger {
|
|||
outPoint = outPoint,
|
||||
addressDb = addressDb,
|
||||
blockHash = blockHash)
|
||||
|
||||
EitherUtil.liftRightBiasedFutureE(biasedE)
|
||||
} map {
|
||||
case CompatRight(utxo) => AddUtxoSuccess(utxo)
|
||||
case CompatLeft(e) => e
|
||||
}
|
||||
}
|
||||
.flatMap {
|
||||
case Right(utxoF) => utxoF.map(AddUtxoSuccess(_))
|
||||
case Left(e) => Future.successful(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue