diff --git a/.gitignore b/.gitignore index e194b0dcd2..47dc20e13e 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,9 @@ ergo-tests/ # spam test's checkout location spam-tests/ + +# metals, bloop, vscode +.bloop/ +.metals/ +.vscode/ +project/metals.sbt \ No newline at end of file diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoBoxAssets.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoBoxAssets.scala new file mode 100644 index 0000000000..8efe6601ea --- /dev/null +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoBoxAssets.scala @@ -0,0 +1,17 @@ +package org.ergoplatform + +import scorex.util.ModifierId + +trait ErgoBoxAssets { + def value: Long + def tokens: Map[ModifierId, Long] +} + +final case class ErgoBoxAssetsHolder( + val value: Long, + val tokens: Map[ModifierId, Long] +) extends ErgoBoxAssets + +object ErgoBoxAssetsHolder { + def apply(value: Long): ErgoBoxAssetsHolder = ErgoBoxAssetsHolder(value, Map()) +} \ No newline at end of file diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala index 12c332b40c..a937fb4824 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala @@ -5,7 +5,7 @@ import java.util import org.ergoplatform.ErgoBox._ import org.ergoplatform.settings.ErgoAlgos import scorex.crypto.hash.Digest32 -import scorex.util.ModifierId +import scorex.util.{bytesToId, idToBytes, ModifierId} import sigmastate.Values._ import sigmastate._ import sigmastate.SType.AnyOps @@ -39,7 +39,8 @@ class ErgoBoxCandidate(val value: Long, val ergoTree: ErgoTree, val creationHeight: Int, val additionalTokens: Coll[(TokenId, Long)] = Colls.emptyColl, - val additionalRegisters: Map[NonMandatoryRegisterId, _ <: EvaluatedValue[_ <: SType]] = Map()) { + val additionalRegisters: Map[NonMandatoryRegisterId, _ <: EvaluatedValue[_ <: SType]] = Map()) + extends ErgoBoxAssets { def proposition: BoolValue = ergoTree.toProposition(ergoTree.isConstantSegregation).asBoolValue @@ -77,6 +78,12 @@ class ErgoBoxCandidate(val value: Long, override def toString: Idn = s"ErgoBoxCandidate($value, $ergoTree," + s"tokens: (${additionalTokens.map(t => ErgoAlgos.encode(t._1) + ":" + t._2).toArray.mkString(", ")}), " + s"$additionalRegisters, creationHeight: $creationHeight)" + + lazy val tokens: Map[ModifierId, Long] = + additionalTokens + .toArray + .map(t => bytesToId(t._1) -> t._2) + .toMap } object ErgoBoxCandidate { diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala index 4b1f9aee38..c5d850d457 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala @@ -120,7 +120,10 @@ object ErgoLikeTransactionSerializer extends SigmaSerializer[ErgoLikeTransaction for (input <- tx.dataInputs) { w.putBytes(input.boxId) } - // serialize distinct ids of tokens in transaction outputs + // Serialize distinct ids of tokens in transaction outputs. + // This optimization is crucial to allow up to MaxTokens (== 255) in a box. + // Without it total size of all token ids 255 * 32 = 8160, + // way beyond MaxBoxSize (== 4K) val tokenIds = tx.outputCandidates.toColl .flatMap(box => box.additionalTokens.map(t => t._1))