Skip to content
This repository was archived by the owner on Apr 13, 2022. It is now read-only.
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
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
package examples.commons

import scorex.core.transaction.MemoryPool
import akka.actor.{ActorRef, ActorSystem}
import scorex.core.transaction.{ReferenceMempool, ReferenceMempoolActor}
import scorex.util.ModifierId

import scala.collection.concurrent.TrieMap
import scala.util.{Success, Try}


case class SimpleBoxTransactionMemPool(unconfirmed: TrieMap[ModifierId, SimpleBoxTransaction])
extends MemoryPool[SimpleBoxTransaction, SimpleBoxTransactionMemPool] {
override type NVCT = SimpleBoxTransactionMemPool
extends ReferenceMempool[SimpleBoxTransaction, SimpleBoxTransactionMemPool] {

//getters
override def modifierById(id: ModifierId): Option[SimpleBoxTransaction] = unconfirmed.get(id)

override def contains(id: ModifierId): Boolean = unconfirmed.contains(id)

override def getAll(ids: Seq[ModifierId]): Seq[SimpleBoxTransaction] = ids.flatMap(getById)
override def getAll(ids: Seq[ModifierId]): Seq[SimpleBoxTransaction] = ids.flatMap(modifierById)

//modifiers
override def put(tx: SimpleBoxTransaction): Try[SimpleBoxTransactionMemPool] = Success {
unconfirmed.put(tx.id, tx)
this
}

//todo
override def put(txs: Iterable[SimpleBoxTransaction]): Try[SimpleBoxTransactionMemPool] = Success(putWithoutCheck(txs))

override def putWithoutCheck(txs: Iterable[SimpleBoxTransaction]): SimpleBoxTransactionMemPool = {
txs.foreach(tx => unconfirmed.put(tx.id, tx))
override def putWithoutCheck(tx: SimpleBoxTransaction): SimpleBoxTransactionMemPool = {
unconfirmed.put(tx.id, tx)
this
}

Expand All @@ -38,9 +35,9 @@ case class SimpleBoxTransactionMemPool(unconfirmed: TrieMap[ModifierId, SimpleBo
}

override def take(limit: Int): Iterable[SimpleBoxTransaction] =
unconfirmed.values.toSeq.sortBy(-_.fee).take(limit)
unconfirmed.values.toSeq.sortBy(_.fee)(Ordering[Long].reverse).take(limit)

override def filter(condition: SimpleBoxTransaction => Boolean): SimpleBoxTransactionMemPool = {
override def filterBy(condition: SimpleBoxTransaction => Boolean): SimpleBoxTransactionMemPool = {
unconfirmed.retain { (_, v) =>
condition(v)
}
Expand All @@ -50,7 +47,10 @@ case class SimpleBoxTransactionMemPool(unconfirmed: TrieMap[ModifierId, SimpleBo
override def size: Int = unconfirmed.size
}


object SimpleBoxTransactionMemPool {
lazy val emptyPool: SimpleBoxTransactionMemPool = SimpleBoxTransactionMemPool(TrieMap())
def emptyPool: SimpleBoxTransactionMemPool = SimpleBoxTransactionMemPool(TrieMap())

def createMempoolActor(implicit system: ActorSystem): ActorRef = {
ReferenceMempoolActor[SimpleBoxTransaction, SimpleBoxTransactionMemPool](emptyPool)
}
}
279 changes: 175 additions & 104 deletions examples/src/main/scala/examples/hybrid/HybridNodeViewHolder.scala

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ import scala.util.Try
*/
object PrivateChain extends App with ScorexLogging with ScorexEncoding {

val proposition: PublicKey25519Proposition = PublicKey25519Proposition(PublicKey @@ scorex.utils.Random.randomBytes(32))

def genesisState(): (HybridHistory, HBoxStoredState, HBoxWallet, SimpleBoxTransactionMemPool) = {
HybridNodeViewHolder.generateGenesisState(hybridSettings, new NetworkTimeProvider(settings.ntp))
val proposition: PublicKey25519Proposition = {
PublicKey25519Proposition(PublicKey @@ scorex.utils.Random.randomBytes(32))
}

def generatePow(h: HybridHistory, brother: Boolean, hashesPerSecond: Int): PowBlock = {
Expand Down Expand Up @@ -64,8 +62,12 @@ object PrivateChain extends App with ScorexLogging with ScorexEncoding {

Path.apply(settings.dataDir).deleteRecursively()

var (history, _, wallet, _) = genesisState()

val timeProvider = new NetworkTimeProvider(settings.ntp)
val genesisPow = HybridNodeViewHolder.generateGenesisPow(hybridSettings)
val genesisPos = HybridNodeViewHolder.generateGenesisPos(genesisPow)
var history = HybridNodeViewHolder.generateGenesisHistory(hybridSettings, timeProvider, genesisPow, genesisPos)
val genesisState = HybridNodeViewHolder.generateGenesisState(hybridSettings, genesisPow, genesisPos)
val wallet = HybridNodeViewHolder.generateGenesisWallet(hybridSettings, genesisState, genesisPow, genesisPos)
val boxes = wallet.boxes().map(_.box).take(adversarialStakePercent)
val boxKeys = boxes.flatMap(b => wallet.secretByPublicImage(b.proposition).map(s => (b, s)))

Expand Down
6 changes: 3 additions & 3 deletions examples/src/test/scala/hybrid/HybridGenerators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import examples.hybrid.state.HBoxStoredState
import org.scalacheck.rng.Seed
import org.scalacheck.{Arbitrary, Gen}
import scorex.core.block.Block._
import scorex.core.transaction.MempoolReader
import scorex.core.transaction.box.proposition.PublicKey25519Proposition
import scorex.core.transaction.proof.Signature25519
import scorex.core.transaction.state._
Expand Down Expand Up @@ -169,9 +170,8 @@ trait HybridGenerators extends ExamplesCommonGenerators
} yield PosBlock.create(id, timestamp, txs, box.copy(proposition = generator.publicImage), attach, generator)
}.apply(Gen.Parameters.default, Seed.random()).get


def modifierWithTransactions(memoryPoolOpt: Option[SimpleBoxTransactionMemPool],
customTransactionsOpt: Option[Seq[SimpleBoxTransaction]]): PosBlock = {
def modifierWithTransactions(memoryPoolOpt: Option[MempoolReader[TX]],
customTransactionsOpt: Option[Seq[TX]]): PosBlock = {

val (id, timestamp, box, attach, generator) = (for {
id <- modifierIdGen
Expand Down
12 changes: 7 additions & 5 deletions examples/src/test/scala/hybrid/HybridSanity.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package hybrid

import akka.actor.{ActorRef, ActorSystem}
import examples.commons.{PublicKey25519NoncedBox, SimpleBoxTransaction, SimpleBoxTransactionMemPool}
import examples.hybrid.blocks.{HybridBlock, PosBlock}
import examples.hybrid.history.{HybridHistory, HybridSyncInfo}
Expand All @@ -19,14 +20,15 @@ class HybridSanity extends BlockchainSanity[PublicKey25519Proposition,
SimpleBoxTransactionMemPool,
HBoxStoredState,
HybridHistory] with BlockchainPerformance[SimpleBoxTransaction, HybridBlock, HybridSyncInfo,
SimpleBoxTransactionMemPool, HBoxStoredState, HybridHistory]
HBoxStoredState, HybridHistory]
with HybridGenerators {

private val walletSettings = originalSettings.walletSettings.copy(seed = "p")

//Node view components
override lazy val memPool: SimpleBoxTransactionMemPool = SimpleBoxTransactionMemPool.emptyPool
override lazy val memPoolGenerator: Gen[SimpleBoxTransactionMemPool] = emptyMemPoolGen
override protected def createMempoolActor(system: ActorSystem): ActorRef = {
SimpleBoxTransactionMemPool.createMempoolActor(system)
}

override lazy val transactionGenerator: Gen[TX] = simpleBoxTransactionGen
override lazy val wallet = (0 until 100).foldLeft(HBoxWallet.readOrGenerate(walletSettings))((w, _) => w.generateNewSecret())
}
}
24 changes: 17 additions & 7 deletions examples/src/test/scala/hybrid/NodeViewHolderGenerators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,25 @@ trait NodeViewHolderGenerators {

class NodeViewHolderForTests(h: HT, s: ST) extends HybridNodeViewHolder(settings, new NetworkTimeProvider(settings.scorexSettings.ntp)) {

override protected def genesisState: (HIS, MS, VL, MP) = {
@SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
val store = lsmStoreGen.sample.get
override protected def genesisHistory(): History = h

override protected def genesisState(): State = s

override protected def genesisVault(): Vault = {
val store = lsmStoreGen.sample.getOrElse(throw new Exception("lsmStoreGen.sample is None"))
val seed = Array.fill(10)(1: Byte)
val gw = new HBoxWallet(seed, store)
(h, s, gw, SimpleBoxTransactionMemPool.emptyPool)
new HBoxWallet(seed, store)
}

override def restoreState(): Option[(HIS, MS, VL, MP)] = None
override def genesisMempool(): MPool = SimpleBoxTransactionMemPool.emptyPool

override def restoreHistory(): Option[History] = None

override def restoreState(): Option[State] = None

override def restoreVault(): Option[Vault] = None

override def restoreMempool(): Option[MPool] = None
}

object NodeViewHolderForTests {
Expand All @@ -45,4 +55,4 @@ trait NodeViewHolderGenerators {
val eventListener = TestProbe()
(ref, eventListener, m, s, h)
}
}
}
61 changes: 36 additions & 25 deletions examples/src/test/scala/hybrid/NodeViewSynchronizerGenerators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,29 @@ package hybrid
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.testkit.TestProbe
import commons.ExamplesCommonGenerators
import examples.commons.SimpleBoxTransactionMemPool
import examples.commons.{SimpleBoxTransaction, SimpleBoxTransactionMemPool}
import examples.hybrid.HybridApp
import examples.hybrid.history.HybridSyncInfoMessageSpec
import examples.hybrid.blocks.HybridBlock
import examples.hybrid.history.{HybridSyncInfo, HybridSyncInfoMessageSpec}
import io.iohk.iodb.ByteArrayWrapper
import scorex.core._
import scorex.core.app.Version
import scorex.core.network.NodeViewSynchronizer.ReceivableMessages.{ChangedHistory, ChangedMempool}
import scorex.core.network._
import scorex.core.transaction.ReferenceMempoolActor
import scorex.core.utils.NetworkTimeProvider
import scorex.testkit.generators.CoreGenerators
import scorex.testkit.properties.SynchronizerFixture
import scorex.testkit.utils.SysId

import scala.concurrent.ExecutionContext.Implicits.global

@SuppressWarnings(Array("org.wartremover.warts.TraversableOps"))
trait NodeViewSynchronizerGenerators {
this: ModifierGenerators with StateGenerators with HistoryGenerators with HybridTypes with CoreGenerators with ExamplesCommonGenerators =>
this: ModifierGenerators
with StateGenerators
with HistoryGenerators
with HybridTypes
with CoreGenerators
with ExamplesCommonGenerators =>

object NodeViewSynchronizerForTests {
def props(networkControllerRef: ActorRef,
Expand All @@ -31,31 +38,35 @@ trait NodeViewSynchronizerGenerators {
HybridApp.modifierSerializers)
}

def nodeViewSynchronizer(implicit system: ActorSystem):
(ActorRef, HSI, PM, TX, ConnectedPeer, TestProbe, TestProbe, TestProbe, TestProbe) = {
@SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
val h = historyGen.sample.get
@SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
val sRaw = stateGen.sample.get
def createFixture(): SynchronizerFixture[SimpleBoxTransaction, HybridBlock, HybridSyncInfo] = {
implicit val system: ActorSystem = ActorSystem("WithIsoFix-%d".format(SysId.incrementAndGet()))
val h = historyGen.sample.getOrElse(throw new Exception("Empty historyGen.sample"))
val sRaw = stateGen.sample.getOrElse(throw new Exception("Empty stateGen.sample"))
val mempool = SimpleBoxTransactionMemPool.emptyPool
val v = h.openSurfaceIds().last
val v = h.openSurfaceIds().lastOption.getOrElse(throw new Exception("Empty history.openSurfaceIds"))
sRaw.store.update(ByteArrayWrapper(idToBytes(v)), Seq(), Seq())
val s = sRaw.copy(version = idToVersion(v))

val ncProbe = TestProbe("NetworkControllerProbe")
val vhProbe = TestProbe("ViewHolderProbe")
val pchProbe = TestProbe("PeerHandlerProbe")
val eventListener = TestProbe("EventListener")

val ref = system.actorOf(NodeViewSynchronizerForTests.props(ncProbe.ref, vhProbe.ref))
ref ! ChangedHistory(h)
ref ! ChangedMempool(mempool)
val m = totallyValidModifier(h, s)
@SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
val tx = simpleBoxTransactionGen.sample.get
@SuppressWarnings(Array("org.wartremover.warts.OptionPartial"))
val p: ConnectedPeer = connectedPeerGen(pchProbe.ref).sample.get

(ref, h.syncInfo, m, tx, p, pchProbe, ncProbe, vhProbe, eventListener)

val syncRef = system.actorOf(NodeViewSynchronizerForTests.props(ncProbe.ref, vhProbe.ref))
syncRef ! ChangedHistory(h)
syncRef ! ChangedMempool(mempool)

new SynchronizerFixture(
system,
node = syncRef,
memoryPool = ReferenceMempoolActor[TX, SimpleBoxTransactionMemPool](mempool),
syncInfo = h.syncInfo,
mod = totallyValidModifier(h, s),
tx = simpleBoxTransactionGen.sample.getOrElse(throw new Exception("Empty simpleBoxTransactionGen.sample")),
peer = connectedPeerGen(pchProbe.ref).sample.getOrElse(throw new Exception("Empty connectedPeerGen.sample")),
pchProbe,
ncProbe,
vhProbe,
eventListener = TestProbe("EventListener")
)
}
}
}
7 changes: 2 additions & 5 deletions examples/src/test/scala/hybrid/NodeViewSynchronizerSpec.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package hybrid

import examples.commons.{SimpleBoxTransaction, SimpleBoxTransactionMemPool}
import examples.commons.SimpleBoxTransaction
import examples.hybrid.blocks.HybridBlock
import examples.hybrid.history.{HybridHistory, HybridSyncInfo}
import examples.hybrid.state.HBoxStoredState
import scorex.testkit.properties.NodeViewSynchronizerTests

class NodeViewSynchronizerSpec
extends NodeViewSynchronizerTests[SimpleBoxTransaction, HybridBlock, HBoxStoredState, HybridSyncInfo,
HybridHistory, SimpleBoxTransactionMemPool] with HybridGenerators {

override lazy val memPool: SimpleBoxTransactionMemPool = SimpleBoxTransactionMemPool.emptyPool
}
HybridHistory] with HybridGenerators
8 changes: 8 additions & 0 deletions src/main/scala/scorex/core/NodeViewComponent.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@ trait NodeViewComponent {

type NVCT >: self.type <: NodeViewComponent
}

object NodeViewComponent {
trait ComponentType
object StateComponent extends ComponentType
object HistoryComponent extends ComponentType
object MempoolComponent extends ComponentType
object VaultComponent extends ComponentType
}
18 changes: 18 additions & 0 deletions src/main/scala/scorex/core/NodeViewComponentOperation.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package scorex.core

import scorex.core.NodeViewComponent.ComponentType

/** Base trait for all node view operations, which should be sent to a memory node view component
*/
trait NodeViewComponentOperation

object NodeViewComponentOperation {

/** Get the reader for the memory pool, returns a component reader instance
*/
case class GetReader(componentType: ComponentType) extends NodeViewComponentOperation

/** Mode for the memory pool operation
*/
trait OperationMode[Op <: NodeViewComponentOperation]
}
Loading