Skip to content

Commit

Permalink
Merge pull request #2088 from ergoplatform/hashcode
Browse files Browse the repository at this point in the history
Fix for block sections hashcode
  • Loading branch information
kushti committed Dec 22, 2023
2 parents 8999d02 + b53bdd2 commit d443431
Show file tree
Hide file tree
Showing 22 changed files with 150 additions and 161 deletions.
55 changes: 0 additions & 55 deletions ergo-core/src/main/scala/org/ergoplatform/NodeViewModifier.scala

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.ergoplatform.consensus

import org.ergoplatform.PersistentNodeViewModifier
import org.ergoplatform.modifiers.NetworkObjectTypeId
import org.ergoplatform.modifiers.{BlockSection, NetworkObjectTypeId}
import org.ergoplatform.utils.ScorexEncoder
import scorex.util.ModifierId

Expand All @@ -14,11 +13,11 @@ import scorex.util.ModifierId
* @param toDownload - modifiers to download from other nodes
* @tparam PM - type of used modifier
*/
case class ProgressInfo[PM <: PersistentNodeViewModifier](branchPoint: Option[ModifierId],
toRemove: Seq[PM],
toApply: Seq[PM],
toDownload: Seq[(NetworkObjectTypeId.Value, ModifierId)])
(implicit encoder: ScorexEncoder) {
case class ProgressInfo[PM <: BlockSection](branchPoint: Option[ModifierId],
toRemove: Seq[PM],
toApply: Seq[PM],
toDownload: Seq[(NetworkObjectTypeId.Value, ModifierId)])
(implicit encoder: ScorexEncoder) {

if (toRemove.nonEmpty)
require(branchPoint.isDefined, s"Branch point should be defined for non-empty `toRemove`")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package org.ergoplatform.modifiers

import io.circe.Encoder
import org.ergoplatform.PersistentNodeViewModifier
import org.ergoplatform.modifiers.history.extension.Extension
import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.history.{ADProofs, BlockTransactions}


/**
* Block section, so a header, or block transactions, or extension, or ADProofs.
*/
trait BlockSection extends PersistentNodeViewModifier with ErgoNodeViewModifier
trait BlockSection extends ErgoNodeViewModifier {
/**
* Id of another block section of the same type, which should be applied to the node view before this modifier
*/
def parentId: scorex.util.ModifierId

}

object BlockSection {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package org.ergoplatform.modifiers

import io.circe.syntax._
import io.circe.{Decoder, Encoder, HCursor, Json}
import org.ergoplatform.TransactionsCarryingPersistentNodeViewModifier
import org.ergoplatform.http.api.ApiCodecs
import org.ergoplatform.modifiers.history.extension.Extension
import org.ergoplatform.modifiers.history.header.Header
Expand All @@ -15,8 +14,7 @@ case class ErgoFullBlock(header: Header,
blockTransactions: BlockTransactions,
extension: Extension,
adProofs: Option[ADProofs])
extends BlockSection
with TransactionsCarryingPersistentNodeViewModifier {
extends TransactionsCarryingBlockSection {

override type M = ErgoFullBlock

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,61 @@
package org.ergoplatform.modifiers

import org.ergoplatform.core.BytesSerializable
import org.ergoplatform.utils.ScorexEncoding
import scorex.util.{ModifierId, bytesToId}
import scorex.utils.Ints

trait ErgoNodeViewModifier { self: BytesSerializable =>
/**
* Basic trait for entities which are modifying internal blockchain view of the node, such as
* unconfirmed transactions, block sections
*/
trait ErgoNodeViewModifier extends BytesSerializable with ScorexEncoding {

/**
* @return cryptographically strong unique identifier of an object
*/
def serializedId: Array[Byte]

/**
* identifier which can is friendly to data structures such as maps etc
*/
lazy val id: ModifierId = bytesToId(serializedId)

/**
* Type of node view modifier (transaction, header etc)
*/
val modifierTypeId: NetworkObjectTypeId.Value

/**
* Size of binary representation provided during object construction (to avoid serialization just to get the value)
*/
val sizeOpt: Option[Int]

/**
* Cached size of binary representation
*/
lazy val size: Int = sizeOpt.getOrElse(bytes.length)

def serializedId: Array[Byte]
/**
* @return readable representation of `id`, as `id` is a hex-encoded string now, just identity functions is used
*/
def encodedId: String = id

override def equals(obj: scala.Any): Boolean = obj match {
case that: ErgoNodeViewModifier => (that.id == id) && (that.modifierTypeId == modifierTypeId)
case _ => false
}

override def hashCode(): Int = {
Ints.fromByteArray(serializedId)
}

}

object ErgoNodeViewModifier {
/**
* It is assumed that all the modifiers (offchain transactions, blocks, blockheaders etc)
* have identifiers of the some length fixed with the ModifierIdSize constant
*/
val ModifierIdSize: Int = 32 // in bytes
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.ergoplatform.modifiers

import org.ergoplatform.modifiers.mempool.ErgoTransaction

/**
* Block section which contains transactions
*/
trait TransactionsCarryingBlockSection extends BlockSection {

def transactions: Seq[ErgoTransaction]

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ package org.ergoplatform.modifiers.history

import io.circe.syntax._
import io.circe.{Decoder, Encoder, HCursor}
import org.ergoplatform.TransactionsCarryingPersistentNodeViewModifier
import org.ergoplatform.http.api.ApiCodecs
import org.ergoplatform.modifiers.{BlockTransactionsTypeId, NetworkObjectTypeId, NonHeaderBlockSection}
import org.ergoplatform.modifiers.{BlockTransactionsTypeId, NetworkObjectTypeId, NonHeaderBlockSection, TransactionsCarryingBlockSection}
import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.mempool.{ErgoTransaction, ErgoTransactionSerializer}
import org.ergoplatform.nodeView.mempool.TransactionMembershipProof
Expand Down Expand Up @@ -33,7 +32,7 @@ case class BlockTransactions(headerId: ModifierId,
blockVersion: Version,
txs: Seq[ErgoTransaction],
override val sizeOpt: Option[Int] = None)
extends NonHeaderBlockSection with TransactionsCarryingPersistentNodeViewModifier {
extends NonHeaderBlockSection with TransactionsCarryingBlockSection {

assert(txs.nonEmpty, "Block should always contain at least 1 coinbase-like transaction")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.ergoplatform.modifiers.history.header.{Header, HeaderSerializer}
import org.ergoplatform.serialization.ErgoSerializer
import scorex.util.serialization.{Reader, Writer}
import scorex.util.Extensions.LongOps
import scorex.util.ScorexLogging

/**
* A structure representing NiPoPow proof as a persistent modifier.
Expand All @@ -28,7 +29,7 @@ case class NipopowProof(popowAlgos: NipopowAlgos,
prefix: Seq[PoPowHeader],
suffixHead: PoPowHeader,
suffixTail: Seq[Header],
continuous: Boolean) {
continuous: Boolean) extends ScorexLogging {

lazy val serializer: ErgoSerializer[NipopowProof] = new NipopowProofSerializer(popowAlgos)

Expand All @@ -47,13 +48,20 @@ case class NipopowProof(popowAlgos: NipopowAlgos,
* @return whether this PoPoW proof is better than "that"
*/
def isBetterThan(that: NipopowProof): Boolean = {
if (this.isValid && that.isValid) {
popowAlgos.lowestCommonAncestor(headersChain, that.headersChain)
.map(h => headersChain.filter(_.height > h.height) -> that.headersChain.filter(_.height > h.height))
.exists({ case (thisDivergingChain, thatDivergingChain) =>
popowAlgos.bestArg(thisDivergingChain)(m) > popowAlgos.bestArg(thatDivergingChain)(m) })
} else {
this.isValid
try {
if (this.isValid && that.isValid) {
popowAlgos.lowestCommonAncestor(headersChain, that.headersChain)
.map(h => headersChain.filter(_.height > h.height) -> that.headersChain.filter(_.height > h.height))
.exists({ case (thisDivergingChain, thatDivergingChain) =>
popowAlgos.bestArg(thisDivergingChain)(m) > popowAlgos.bestArg(thatDivergingChain)(m)
})
} else {
this.isValid
}
} catch {
case t: Throwable =>
log.error(s"Nipopow proofs comparison (isBetter) failed due to ${t.getMessage}: ", t)
false
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package org.ergoplatform.modifiers.mempool

import io.circe.syntax._
import org.ergoplatform.{DataInput, ErgoBox, ErgoBoxCandidate, ErgoLikeTransaction, ErgoLikeTransactionSerializer, Input}
import org.ergoplatform.ErgoBox.BoxId
import org.ergoplatform.SigmaConstants.{MaxBoxSize, MaxPropositionBytes}
import org.ergoplatform.{EphemerealNodeViewModifier, _}
import org.ergoplatform.http.api.ApiCodecs
import org.ergoplatform.mining.emission.EmissionRules
import org.ergoplatform.modifiers.history.header.Header
import org.ergoplatform.modifiers.mempool.ErgoTransaction.unresolvedIndices
import org.ergoplatform.modifiers.transaction.Transaction
import org.ergoplatform.modifiers.transaction.Signable
import org.ergoplatform.modifiers.{ErgoNodeViewModifier, NetworkObjectTypeId, TransactionTypeId}
import org.ergoplatform.nodeView.ErgoContext
import org.ergoplatform.nodeView.state.ErgoStateContext
Expand Down Expand Up @@ -57,11 +57,12 @@ case class ErgoTransaction(override val inputs: IndexedSeq[Input],
override val outputCandidates: IndexedSeq[ErgoBoxCandidate],
override val sizeOpt: Option[Int] = None)
extends ErgoLikeTransaction(inputs, dataInputs, outputCandidates)
with Transaction
with EphemerealNodeViewModifier
with Signable
with ErgoNodeViewModifier
with ScorexLogging {

override val modifierTypeId: NetworkObjectTypeId.Value = TransactionTypeId.value

override val serializedId: Array[Byte] = Algos.hash(messageToSign)

override lazy val id: ModifierId = bytesToId(serializedId)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.ergoplatform.modifiers.transaction


/**
* A basic trait for entities which can be signed
*/
trait Signable {

/**
* Bytes to be signed
*/
val messageToSign: Array[Byte]

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.ergoplatform.nodeView.history

import org.ergoplatform.NodeViewModifier
import org.ergoplatform.consensus.SyncInfo
import org.ergoplatform.modifiers.ErgoNodeViewModifier
import org.ergoplatform.modifiers.history.header.{Header, HeaderSerializer}
import org.ergoplatform.network.message.SyncInfoMessageSpec
import org.ergoplatform.serialization.ErgoSerializer
Expand Down Expand Up @@ -100,7 +100,7 @@ object ErgoSyncInfoSerializer extends ErgoSerializer[ErgoSyncInfo] with ScorexLo
}
} else { // parse v1 sync message
require(length <= ErgoSyncInfo.MaxBlockIds + 1, "Too many block ids in sync info")
val ids = (1 to length).map(_ => bytesToId(r.getBytes(NodeViewModifier.ModifierIdSize)))
val ids = (1 to length).map(_ => bytesToId(r.getBytes(ErgoNodeViewModifier.ModifierIdSize)))
ErgoSyncInfoV1(ids)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ class Parameters(val height: Height,
case _ => false
}

override def hashCode(): Height = height.hashCode() + parametersTable.hashCode()
override def hashCode(): Int = height.hashCode() + parametersTable.hashCode()
}

object Parameters {
Expand Down

0 comments on commit d443431

Please sign in to comment.