Skip to content
This repository has been archived by the owner on Apr 13, 2022. It is now read-only.

Commit

Permalink
Merge pull request #147 from ScorexFoundation/assert
Browse files Browse the repository at this point in the history
Assert and ensuring usage
  • Loading branch information
catena2w committed Jan 11, 2018
2 parents a3a7522 + 61c1433 commit 35db410
Show file tree
Hide file tree
Showing 15 changed files with 48 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package examples.curvepos.transaction

import java.nio.ByteBuffer

import examples.curvepos.{Nonce, Value}
import examples.curvepos.transaction.SimpleState.EmptyVersion
import examples.curvepos.{Nonce, Value}
import scorex.core.VersionTag
import scorex.core.transaction.box.Box
import scorex.core.transaction.box.proposition.{Proposition, PublicKey25519Proposition}
Expand All @@ -18,7 +18,7 @@ case class TransactionChanges[P <: Proposition, BX <: Box[P]](toRemove: Set[BX],

case class SimpleState(override val version: VersionTag = EmptyVersion,
storage: Map[ByteBuffer, PublicKey25519NoncedBox] = Map()) extends ScorexLogging
with BoxMinimalState[PublicKey25519Proposition, PublicKey25519NoncedBox, SimpleTransaction, SimpleBlock, SimpleState]{
with BoxMinimalState[PublicKey25519Proposition, PublicKey25519NoncedBox, SimpleTransaction, SimpleBlock, SimpleState] {

def isEmpty: Boolean = version sameElements EmptyVersion

Expand All @@ -45,8 +45,7 @@ case class SimpleState(override val version: VersionTag = EmptyVersion,
val rmap = change.toRemove.foldLeft(storage) { case (m, r) => m - ByteBuffer.wrap(r.boxId) }

val amap = change.toAppend.foldLeft(rmap) { case (m, a) =>
val b = a.box
assert(b.value >= 0)
val b = a.box.ensuring(_.value >= 0)
m + (ByteBuffer.wrap(b.id) -> b)
}
SimpleState(newVersion, amap)
Expand Down Expand Up @@ -75,7 +74,8 @@ case class SimpleState(override val version: VersionTag = EmptyVersion,
val newSenderBox = oldSenderBox.copy(nonce = Nonce @@ (oldSenderBox.nonce + 1),
value = Value @@ Math.addExact(Math.addExact(oldSenderBox.value, -tx.amount), -tx.fee))
val toRemove = Set(oldSenderBox) ++ oldRecipientBox
val toAppend = Set(newRecipientBox, newSenderBox).ensuring(_.forall(_.value >= 0))
val toAppend = Set(newRecipientBox, newSenderBox)
if (!toAppend.forall(_.value >= 0)) throw new Error(s"Trying to create negative output in ${toAppend}")

TransactionChanges[PublicKey25519Proposition, PublicKey25519NoncedBox](toRemove, toAppend, tx.fee)
}
Expand Down Expand Up @@ -103,16 +103,14 @@ case class SimpleState(override val version: VersionTag = EmptyVersion,
PublicKey25519NoncedBox(gen, Nonce @@ 1L, Value @@ generatorReward)
}
val toAppend = (withoutGenerator ++ Seq(generatorBox)).map(b =>
Insertion[PublicKey25519Proposition, PublicKey25519NoncedBox](b))
assert(toAppend.forall(_.box.value >= 0))
Insertion[PublicKey25519Proposition, PublicKey25519NoncedBox](b)).ensuring(_.forall(_.box.value >= 0))

BoxStateChanges[PublicKey25519Proposition, PublicKey25519NoncedBox](toRemove ++ toAppend)
}

override def semanticValidity(tx: SimpleTransaction): Try[Unit] = Success()

override def validate(mod: SimpleBlock): Try[Unit] =
Try(mod.transactions.foreach(tx => validate(tx).ensuring(_.isSuccess)))
override def validate(mod: SimpleBlock): Try[Unit] = Try(mod.transactions.foreach(tx => validate(tx).get))
}

object SimpleState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ object HybridNodeViewHolder extends ScorexLogging {

//propositions with wallet seed genesisoo, genesiso1, ..., genesis48, genesis49
val icoMembers: IndexedSeq[PublicKey25519Proposition] = IndexedSeq("6sYyiTguyQ455w2dGEaNbrwkAWAEYV1Zk6FtZMknWDKQ", "7BDhJv6Wh2MekgJLvQ98ot9xiw5x3N4b3KipURdrW8Ge", "Ei8oY3eg5vM26QUBhyFiAdPN1C23RJEV9irrykNmSAFV", "8LNhm5QagL88sWggvJKGDiZ5bBCG4ajV7R6vAKz4czA9", "EakiCSw1rfmL5DFTPNmSJZEEAEGtTp3DN12wVPJVsURS", "AEQ8bZRuAxAp8DV9VZnTrSudGPdNyzY2HXjPBCGy8igf", "DSL6bvb6j1v6SnvKjqc6fJWdsRjZ85YboH8FkzonUPiT", "419sTmWKAXb5526naQ93xJZL4YAYtpVkbLmzMb6k5X9m", "GydWCS1GwExoDNuEiW6fBLYr7cs4vwdLpk1kzDeKHq6A", "G8xVDYow1YcSb4cuAHwcpYSEKxFpYwC9GqYChMvbCWn5", "9E4F53GSXMPqwuPWEVoUQe9B1z4A8v9Y6tAQdKK779km", "5XtHBDxXCudA38FJnoWm1BVG8aV67AiQKnPuwYbWZCb3", "8Sp3v5vtYtkM9Z2K2B7PuZbWmWQE9bfiUFCvkmsdauGj", "8XTUXeLiHPbMNXedWQh5xHQtq4xUHU3pZZGqRQzC2eyj", "ftqJXjSXrWQXmumNVVaRiNB7TZuCy4GCvz9V4GJGhAv", "GMAYWvbBmssCr55m9bcq8cKzfczSKKxidtVrukBM1KFN", "3nFprwUuqGH9BpvJMQeCb5AwHdaXuxKin1WSxWc9PTkY", "HfYNA96cGebFGgAhGUbxvRJYyLFchQJZpJTQMXztE6gZ", "EPbo8xRWARg2znJAqevKnQMskxnemmCdimPiVFhr8eLd", "4pygr1SPEe5KbU1R8XgMmYaW7YfTH818wd113mF6bhsP", "52gwahUytUXv7wfKs4j6YeKeepc38sYsUi4jp4z4jVym", "Hi3Q1ZQbD2zztq6ajm5yUKfFccxmj3yZn79GUjhFvPSW", "G1yK5iwPQKNXnqU4Drg83et3gKhRW5CogqiekKEYDcrt", "Hf8XcEAVMCiWbu376rGS48FhwH5NgteivfsTsvX1XpbA", "3FAskwxrbqiX2KGEnFPuD3z89aubJvvdxZTKHCrMFjxQ", "GgahaaNBaHRnyUtvEu3k7N5BnW3dvhVCXyxMP6uijdhh", "7R9waVeAKuHKNQY5uTYBp6zNLNo6wSDvj9XfQCyRWmDF", "E4AoFDANgDFL83gTS6A7kjWbLmqWcPr6DqEgMG7cqU18", "AEkuiLFdudYmUwZ9dSa64rakqUgJZf6pKFFwwm6CZFQz", "3QzGZvvTQbcUdhd5BL9ofEK3GdzbmqUnYA1pYTAdVY44", "EjpGvdZETt3SuZpcuwKvZS4jgWCockDHzFQLoeYNW4R", "C85c1uMAiHKDgcqxF6EaiCGQyWgQEYATbpo8M7XEnx3R", "8V5y1CSC1gCGD1jai3ns5FJNW7tAzf7BGd4iwmBv7V44", "CJ9udTDT61ckSHMd6YNpjeNdsN2fGwmJ6Ry6YERXmGa7", "7eboeRCeeBCFwtzPtB4vKPnaYMPL52BjfiEpqSRWfkgx", "E3JJCTMouTys5BSwFyHTV3Ht55mYWfNUAverrNaVo4jE", "9PLHPwnHyA5jf6GPGRjJt7HNd93rw4gWTBi7LBNL4Wwt", "2YM2FQ4HfMiV3LFkiwop2xFznbPVEHbhahVvcrhfZtXq", "3oTzYXjwdr684FUzaJEVVuXBztysNgR8M8iV9QykaM9C", "J6bgGpwDMqKFrde2mpdS6dasRyn9WFV6jKgWAkHSN91q", "4wtQpa1BVgAt9CA4FUuHZHCYGBYtvudPqa1sAddfAPii", "DaSXwzkAU2WfH39zxMfuXpExsVfKk6JzeYbdW9RLiXr4", "6BtXEZE6GcxtEtSLAHXkE3mkcTG1u8WuoQxZG7R8BR5X", "39Z9VaCAeqoWajHyku29argf7zmVqs2vVJM8zYe7YLXy", "7focbpSdsNNE4x9h7eyXSkvXE6dtxsoVyZMpTpuThLoH", "CBdnTL6C4A7nsacxCP3VL3TqUokEraFy49ckQ196KU46", "CfvbDC8dxGeLXzYhDpNpCF2Ar9Q5LKs8QrfcMYAV59Lt", "GFseSi5squ8GRRkj6RknbGj9Hyz82HxKkcn8NKW1e5CF", "FuTHJNKaPTneEYRkjKAC3MkSttvAC7NtBeb2uNGS8mg3", "5hhPGEFCZM2HL6DNKs8KvUZAH3wC47rvMXBGftw9CCA5").map(s => PublicKey25519Proposition(PublicKey @@ Base58.decode(s).get))
.ensuring(_.length == GenesisAccountsNum)

val genesisAccount = PrivateKey25519Companion.generateKeys("genesis".getBytes)
val genesisAccountPriv = genesisAccount._1
Expand All @@ -82,10 +83,9 @@ object HybridNodeViewHolder extends ScorexLogging {
IndexedSeq(genesisAccountPriv -> Nonce @@ 0L),
icoMembers.map(_ -> GenesisBalance),
0L,
0L))
0L)).ensuring(t => Base58.encode(t.head.id) == "EKuWxCuUAg9XgVWKxsnehP9FLsF3zPSyn9yczqeBHD8S")

log.debug(s"Initialize state with transaction ${genesisTxs.head} with boxes ${genesisTxs.head.newBoxes}")
assert(icoMembers.length == GenesisAccountsNum)
assert(Base58.encode(genesisTxs.head.id) == "EKuWxCuUAg9XgVWKxsnehP9FLsF3zPSyn9yczqeBHD8S", Base58.encode(genesisTxs.head.id))

val genesisBox = PublicKey25519NoncedBox(genesisAccountPriv.publicImage, Nonce @@ 0L, GenesisBalance)
val attachment = "genesis attachment".getBytes
Expand All @@ -97,9 +97,8 @@ object HybridNodeViewHolder extends ScorexLogging {

val gs = HBoxStoredState.genesisState(settings, Seq(posGenesis, powGenesis))
val gw = HWallet.genesisWallet(settings, Seq(posGenesis, powGenesis))
assert(!Base58.encode(settings.wallet.seed.arr).startsWith("genesis") || gw.boxes().map(_.box.value.toLong).sum >= GenesisBalance)

assert(gw.boxes().forall(b => gs.closedBox(b.box.id).isDefined))
.ensuring(_.boxes().map(_.box.value.toLong).sum >= GenesisBalance || !Base58.encode(settings.wallet.seed.arr).startsWith("genesis"))
.ensuring(_.boxes().forall(b => gs.closedBox(b.box.id).isDefined))

(history, gs, gw, SimpleBoxTransactionMemPool.emptyPool)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ class HybridHistory(val storage: HistoryStorage,
(newPowDiff, newPosDiff)
} else {
//Same difficulty as in previous block
assert(modifierById(posBlock.parentId).isDefined)
assert(modifierById(posBlock.parentId).isDefined, "Parent should always be in history")
val parentPoSId: ModifierId = modifierById(posBlock.parentId).get.asInstanceOf[PowBlock].prevPosId
(storage.getPoWDifficulty(Some(parentPoSId)), storage.getPoSDifficulty(parentPoSId))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,16 @@ case class HBoxStoredState(store: LSMStore, override val version: VersionTag) ex
override def applyChanges(changes: BoxStateChanges[PublicKey25519Proposition, PublicKey25519NoncedBox],
newVersion: VersionTag): Try[HBoxStoredState] = Try {
val boxIdsToRemove = changes.toRemove.map(_.boxId).map(ByteArrayWrapper.apply)
.ensuring(_.forall(i => closedBox(i.data).isDefined) || store.lastVersionID.isEmpty)
val boxesToAdd = changes.toAppend.map(_.box).map(b => ByteArrayWrapper(b.id) -> ByteArrayWrapper(b.bytes))

log.trace(s"Update HBoxStoredState from version $lastVersionString to version ${Base58.encode(newVersion)}. " +
s"Removing boxes with ids ${boxIdsToRemove.map(b => Base58.encode(b.data))}, " +
s"adding boxes ${boxesToAdd.map(b => Base58.encode(b._1.data))}")
assert(store.lastVersionID.isEmpty || boxIdsToRemove.forall(i => closedBox(i.data).isDefined))
store.update(ByteArrayWrapper(newVersion), boxIdsToRemove, boxesToAdd)
val newSt = HBoxStoredState(store, newVersion)
assert(boxIdsToRemove.forall(box => newSt.closedBox(box.data).isEmpty), s"Removed box is still in state")
newSt
} ensuring { r => if (r.isSuccess) { r.get.version sameElements newVersion } else true }
HBoxStoredState(store, newVersion)
.ensuring(st => boxIdsToRemove.forall(box => st.closedBox(box.data).isEmpty), s"Removed box is still in state")
} ensuring { r => r.toOption.forall(_.version sameElements newVersion )}

override def maxRollbackDepth: Int = store.keepVersions

Expand Down
2 changes: 1 addition & 1 deletion examples/src/main/scala/examples/spv/SpvAlgos.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ object SpvAlgos {
acc
} else {
val inC: Seq[Header] = constructInnerChain(suffix.head, i, boundary, headerById)
assert(inC.forall(h => h.realDifficulty >= i * Constants.InitialDifficulty))
.ensuring(_.forall(h => h.realDifficulty >= i * Constants.InitialDifficulty))
val (newIn, newB) = if (inC.length >= m) {
(constructInnerChain(suffix.head, i, inC(inC.length - m), headerById), inC(inC.length - m))
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ case class InMemoryAuthenticatedUtxo(size: Int, proverOpt: Option[ProverType], o
case _ =>
}
mod match {
case block: TBlock => block.transactions.foreach (tx => validate (tx).ensuring (_.isSuccess) )
case block: TBlock => block.transactions.foreach (tx => validate(tx).get)
case _ => ;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ object OneMinerSimulation extends App with Simulators {

var miningHeight = 0
var miningUtxo = InMemoryAuthenticatedUtxo(genesisBoxes.size, None, defaultId).applyChanges(genesisChanges, defaultId).get

assert(currentUtxo.rootHash sameElements miningUtxo.rootHash)
.ensuring(_.rootHash sameElements currentUtxo.rootHash)

var generatingBoxes: Seq[PublicKey25519NoncedBox] = genesisBoxes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ case class PersistentAuthenticatedUtxo(store: LSMStore,
case _ =>
}
mod match {
case b: TBlock => b.transactions.foreach(tx => validate(tx).ensuring(_.isSuccess))
case b: TBlock => b.transactions.foreach(tx => validate(tx).get)
case _ =>
}
}
Expand All @@ -117,7 +117,6 @@ case class PersistentAuthenticatedUtxo(store: LSMStore,
prover.performOneOperation(Insert(b.id, ADValue @@ b.bytes))
(btr, bta :+ b)
case Removal(bid) =>
assert(store.get(ByteArrayWrapper(bid)).isDefined)
prover.performOneOperation(Remove(bid))
(btr :+ bid, bta)
}
Expand All @@ -134,10 +133,9 @@ case class PersistentAuthenticatedUtxo(store: LSMStore,

store.update(ByteArrayWrapper(newVersion), toRemove, toAdd)

val newSt = PersistentAuthenticatedUtxo(store, size + toAdd.size - toRemove.size, Some(prover), newVersion)
assert(boxIdsToRemove.forall(box => newSt.closedBox(box).isEmpty), s"Removed box is still in state")
newSt
} ensuring { r => if (r.isSuccess) { r.get.version sameElements newVersion } else true }
PersistentAuthenticatedUtxo(store, size + toAdd.size - toRemove.size, Some(prover), newVersion)
.ensuring(newSt => boxIdsToRemove.forall(box => newSt.closedBox(box).isEmpty), s"Removed box is still in state")
} ensuring { _.toOption.forall(_.version sameElements newVersion) }

override def maxRollbackDepth: Int = store.keepVersions

Expand Down
14 changes: 7 additions & 7 deletions examples/src/test/scala/hybrid/HistoryGenerators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ package hybrid

import examples.hybrid.blocks.PowBlock
import examples.hybrid.history.{HistoryStorage, HybridHistory}
import examples.hybrid.mining.{HybridMiningSettings, HybridSettings}
import examples.hybrid.mining.HybridSettings
import org.scalacheck.Gen
import scorex.core.transaction.box.proposition.PublicKey25519Proposition
import scorex.crypto.signatures.PublicKey

trait HistoryGenerators { this: StoreGenerators =>
trait HistoryGenerators {
this: StoreGenerators =>

def settings: HybridSettings

private val historyTimestamp = 1478164225796L
private val historyNonce = -308545845552064644L
private val historyBrothersCount = 0
private val historyBrothersHash = Array.fill(32)(0: Byte)
private val historyBrothersHash = Array.fill(32)(0: Byte)
private val historyBrothers = Seq.empty
private val historyProposition = PublicKey25519Proposition(PublicKey @@ scorex.utils.Random.randomBytes(32))

Expand All @@ -32,9 +33,8 @@ trait HistoryGenerators { this: StoreGenerators =>
val storage = new HistoryStorage(blockStorage, settings.mining)
//we don't care about validation here
val validators = Seq()
var history = new HybridHistory(storage, settings.mining, validators, None)
history = history.append(genesisBlock).get._1
assert(history.modifierById(genesisBlock.id).isDefined)
history
new HybridHistory(storage, settings.mining, validators, None)
.append(genesisBlock).get._1
.ensuring(_.modifierById(genesisBlock.id).isDefined)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ class HybridHistorySpecification extends PropSpec
}

property("History comparison") {
assert(history.height >= HybridHistory.DifficultyRecalcPeriod)
(history.height >= HybridHistory.DifficultyRecalcPeriod) shouldBe true
//TODO test for completed pairs
assert(!history.pairCompleted)
history.pairCompleted shouldBe false
testHistory(history)

//complete pair
Expand All @@ -78,7 +78,7 @@ class HybridHistorySpecification extends PropSpec
}
}

assert(history.pairCompleted)
history.pairCompleted shouldBe true
testHistory(history)

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ class SerializationTests extends PropSpec
property("PowBlock serialization") {
forAll(powBlockGen) { b: PowBlock =>
val parsed = b.serializer.parseBytes(b.bytes).get
assert(parsed.brothersCount == b.brothersCount)
assert(parsed.brothersHash sameElements b.brothersHash)
assert(parsed.brothers.headOption.forall(ph => ph.brothersHash sameElements b.brothers.head.brothersHash))
parsed.brothersCount shouldBe b.brothersCount
parsed.brothersHash shouldEqual b.brothersHash
parsed.brothers.headOption.forall(ph => ph.brothersHash sameElements b.brothers.head.brothersHash) shouldBe true
parsed.bytes shouldEqual b.bytes
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class TransactionSuite extends PropSpec
val inputs = boxesWithKeysIn.map { case (box, k) => k -> box.nonce }.toIndexedSeq

boxesWithKeysIn.foreach { case (box, k) =>
assert(PrivateKey25519Companion.owns(k, box))
PrivateKey25519Companion.owns(k, box) shouldBe true
}

val boxIds = boxesWithKeysIn.map(_._1.id).map(ByteArrayWrapper.apply)
Expand All @@ -34,7 +34,7 @@ class TransactionSuite extends PropSpec
val outKeys = boxesWithKeysOut.map(_._2).map(_.publicKeyBytes).map(ByteArrayWrapper.apply)

tx.newBoxes.foreach { newBox =>
assert(outKeys.contains(ByteArrayWrapper(newBox.proposition.pubKeyBytes)))
outKeys.contains(ByteArrayWrapper(newBox.proposition.pubKeyBytes)) shouldBe true
}

tx.boxIdsToOpen.map(ByteArrayWrapper.apply).forall { bid =>
Expand Down
7 changes: 3 additions & 4 deletions src/main/scala/scorex/core/network/NetworkController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class NetworkController(settings: NetworkSettings,

//check own declared address for validity
if (!settings.localOnly) {
settings.declaredAddress.forall { myAddress =>
settings.declaredAddress.foreach { myAddress =>
Try {
val uri = new URI("http://" + myAddress)
val myHost = uri.getHost
Expand All @@ -65,9 +65,8 @@ class NetworkController(settings: NetworkSettings,
}
}.recover { case t: Throwable =>
log.error("Declared address validation failed: ", t)
false
}.getOrElse(false)
}.ensuring(b => b, "Declared address isn't valid")
}
}
}

lazy val localAddress = settings.bindAddress
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ case class PeerConnectionHandler(settings: NetworkSettings,
connection ! Close

case HandshakeDone =>
assert(receivedHandshake.isDefined)
require(receivedHandshake.isDefined)
peerManager ! Handshaked(remote, receivedHandshake.get)
handshakeTimeoutCancellableOpt.map(_.cancel())
connection ! ResumeReading
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,15 @@ case class MessageHandler(specs: Seq[MessageSpec[_]]) {
val digest = Blake2b256.hash(data).take(Message.ChecksumLength)

//CHECK IF CHECKSUM MATCHES
assert(checksum.sameElements(digest), s"Invalid data checksum length = $length")
if(!checksum.sameElements(digest)) throw new Error(s"Invalid data checksum length = $length")
data
}
else Array()

val spec = specsMap.get(msgCode).ensuring(_.isDefined, s"No message handler found for $msgCode").get
val spec = specsMap.get(msgCode) match {
case Some(h) => h
case None => throw new Error(s"No message handler found for $msgCode")
}

Message(spec, Left(msgData), sourceOpt)
}
Expand Down

0 comments on commit 35db410

Please sign in to comment.