Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 39 additions & 14 deletions src/main/scala/encry/Starter.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package encry

import java.io.File
import java.net.InetSocketAddress
import java.nio.file.Files
import akka.actor.{ Actor, ActorRef }
import akka.http.scaladsl.Http
import cats.Functor
Expand All @@ -12,8 +14,8 @@ import cats.syntax.either._
import cats.syntax.option._
import cats.syntax.validated._
import encry.Starter.InitNodeResult
import encry.api.http.DataHolderForApi
import encry.api.http.DataHolderForApi.PassForStorage
import encry.api.http.{ AccStorage, DataHolderForApi, SettingsStorage }
import encry.cli.ConsoleListener
import encry.cli.ConsoleListener.{ prompt, StartListening }
import encry.local.miner.Miner
Expand Down Expand Up @@ -65,7 +67,10 @@ class Starter(settings: EncryAppSettings,
self ! res
}

def startNonEmptyNode: Either[Throwable, InitNodeResult] =
def startNonEmptyNode: Either[Throwable, InitNodeResult] = {
val storage = SettingsStorage.init(settings)
val newSettings: EncryAppSettings = storage.getSettings.getOrElse(settings)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

incorrect behavior

storage.close()
for {
walletPassword <- {
println("Please, enter wallet password:")
Expand All @@ -75,16 +80,17 @@ class Starter(settings: EncryAppSettings,
InitNodeResult(
"",
walletPassword,
settings.node.offlineGeneration,
newSettings.node.offlineGeneration,
fastSync = false,
settings.snapshotSettings.enableSnapshotCreation,
settings.network.knownPeers,
settings.network.connectOnlyWithKnownPeers.getOrElse(false),
newSettings.snapshotSettings.enableSnapshotCreation,
newSettings.network.knownPeers,
newSettings.network.connectOnlyWithKnownPeers.getOrElse(false),
"",
settings.network.nodeName.getOrElse(""),
settings.network.declaredAddress,
settings.network.bindAddress
newSettings.network.nodeName.getOrElse(""),
newSettings.network.declaredAddress,
newSettings.network.bindAddress
)
}

def startEmptyNode: Either[Throwable, InitNodeResult] =
for {
Expand Down Expand Up @@ -141,8 +147,21 @@ class Starter(settings: EncryAppSettings,
.fold(handleError, handleResult)
}

def validatePassword(password: String): Validated[NonEmptyChain[String], String] =
if (password.nonEmpty) password.validNec else "Password is empty".invalidNec
def validatePassword(password: String): Validated[NonEmptyChain[String], String] = {
val passExists = Files.exists(new File(s"${settings.directory}/userKeys").toPath)
if (password.nonEmpty && !passExists) password.validNec
else if (password.nonEmpty && passExists) {
val storage = AccStorage.init(settings)
if (storage.verifyPassword(password)) {
storage.close()
password.validNec
} else {
storage.close()
"Incorrect password, please try again.".invalidNec
}
}
else "You can't use empty password, please think of another one.".invalidNec
}

def validateNodeName(nodeName: String): Validated[NonEmptyChain[String], String] =
if (nodeName.nonEmpty) nodeName.validNec else "Node name is empty".invalidNec
Expand Down Expand Up @@ -380,9 +399,11 @@ class Starter(settings: EncryAppSettings,
bindAddr) =>
import scala.concurrent.duration._
Functor[Option].compose[Future].map(initHttpApiServer)(_.terminate(3.seconds))
val storage = AccStorage.init(settings)
storage.setPassword(password)
storage.close()
if (mnemonic.nonEmpty) AccountManager.init(mnemonic, password, settings)
val walletSettings: Option[WalletSettings] = settings.wallet.map(_.copy(password = password))
val nodeSettings: NodeSettings = settings.node.copy(offlineGeneration = offlineGeneration)
val nodeSettings: NodeSettings = settings.node.copy(offlineGeneration = offlineGeneration)
val networkSettings: NetworkSettings =
settings.network.copy(knownPeers = peers,
connectOnlyWithKnownPeers = connectWithOnlyKnownPeers.some,
Expand All @@ -395,11 +416,15 @@ class Starter(settings: EncryAppSettings,
enableSnapshotCreation = snapshotCreation
)
val newSettings = settings.copy(
wallet = walletSettings,
node = nodeSettings,
network = networkSettings,
snapshotSettings = snapshotSettings
)
if (!Files.exists(new File(s"${settings.directory}/state").toPath)) {
val storage: SettingsStorage = SettingsStorage.init(newSettings)
storage.putSettings(newSettings)
storage.close()
}
val influxRef: Option[ActorRef] = newSettings.influxDB.map { influxSettings =>
context.system
.actorOf(StatsSender.props(influxSettings, newSettings.network, newSettings.constants), "statsSender")
Expand Down
6 changes: 5 additions & 1 deletion src/main/scala/encry/api/http/AccStorage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ object AccStorage extends StrictLogging {
val PasswordHashKey: StorageKey = StorageKey @@ Algos.hash("Password_Key")
val SaltKey: StorageKey = StorageKey @@ Algos.hash("Salt_Key")

def getDirStorage(settings: EncryAppSettings): File = new File(s"${settings.directory}/userKeys")
def getDirStorage(settings: EncryAppSettings): File = {
val dir = new File(s"${settings.directory}/userKeys")
dir.mkdirs()
dir
}

def init(settings: EncryAppSettings): AccStorage = new AccStorage {
override val storage: DB = LevelDbFactory.factory.open(getDirStorage(settings), new Options)
Expand Down
79 changes: 79 additions & 0 deletions src/main/scala/encry/api/http/SettingsStorage.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package encry.api.http

import java.io.{ByteArrayInputStream, ByteArrayOutputStream, File, ObjectInputStream, ObjectOutputStream}
import com.typesafe.scalalogging.StrictLogging
import encry.settings.EncryAppSettings
import org.encryfoundation.common.utils.Algos
import org.iq80.leveldb.{DB, Options}
import scorex.crypto.hash.Digest32
import encry.storage.levelDb.versionalLevelDB.LevelDbFactory

trait SettingsStorage extends StrictLogging with AutoCloseable {

val storage: DB

val SettingsKey: Digest32 = Algos.hash(s"Settings_Key")

def getSettings: Option[EncryAppSettings] = deserialise(storage.get(SettingsKey))

def putSettings(settings: EncryAppSettings): Unit = {
val batch = storage.createWriteBatch()
try {
val serialisedSettings: Array[Byte] = serialise(settings)
batch.put(SettingsKey, serialisedSettings)
storage.write(batch)
} catch {
case err: Throwable => throw new Exception(s"Error during saving settings cause of $err")
} finally {
batch.close()
}
}

private final def serialise(value: EncryAppSettings): Array[Byte] = {
val stream: ByteArrayOutputStream = new ByteArrayOutputStream()
val oos = new ObjectOutputStream(stream)
try {
oos.writeObject(value)
stream.toByteArray
} catch {
case err: Throwable => throw new Exception(s"Error during serialisation cause of $err")
} finally {
oos.close()
}
}

private final def deserialise(bytes: Array[Byte]): Option[EncryAppSettings] = {
val ois = new ObjectInputStream(new ByteArrayInputStream(bytes))
try {
val value = ois.readObject
val deserialised: Option[EncryAppSettings] = value match {
case set: EncryAppSettings =>
logger.info(s"Deserialisation ended successfully")
Some(set)
}
deserialised
} catch {
case err: Throwable => throw new Exception(s"Error during serialisation cause of $err")
} finally {
ois.close()
}
}

override def close(): Unit = storage.close()

}

object SettingsStorage extends StrictLogging {

def getDirStorage(settings: EncryAppSettings): File = {
val dir = new File(s"${settings.directory}/userSettings")
dir.mkdirs()
dir
}


def init(settings: EncryAppSettings): SettingsStorage = new SettingsStorage {
override val storage: DB = LevelDbFactory.factory.open(getDirStorage(settings), new Options)
}

}