Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NODE-2616 Refactored validation of transaction version #3906

Merged
merged 20 commits into from
Nov 29, 2023
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Simplified name
  • Loading branch information
xrtm000 committed Nov 28, 2023
commit a941491d8a5b2ba7e885bb1c9212ed84dde749cf
4 changes: 2 additions & 2 deletions node/src/main/scala/com/wavesplatform/database/package.scala
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ import com.wavesplatform.state.StateHash.SectionId
import com.wavesplatform.state.reader.LeaseDetails
import com.wavesplatform.transaction.Asset.IssuedAsset
import com.wavesplatform.transaction.lease.LeaseTransaction
import com.wavesplatform.transaction.{EthereumTransaction, PBSince, Transaction, TransactionParsers, TxValidationError, VersionedTransaction}
import com.wavesplatform.transaction.{EthereumTransaction, PBSince, Transaction, TransactionParsers, TxValidationError, Versioned}
import com.wavesplatform.utils.*
import monix.eval.Task
import monix.reactive.Observable
@@ -639,7 +639,7 @@ package object database {
def writeTransaction(v: (TxMeta, Transaction)): Array[Byte] = {
val (m, tx) = v
val ptx = tx match {
case lps: PBSince with VersionedTransaction if PBSince.affects(lps) => TD.WavesTransaction(PBTransactions.protobuf(tx))
case lps: PBSince with Versioned if PBSince.affects(lps) => TD.WavesTransaction(PBTransactions.protobuf(tx))
case et: EthereumTransaction => TD.EthereumTransaction(ByteString.copyFrom(et.bytes()))
case _ => TD.LegacyBytes(ByteString.copyFrom(tx.bytes()))
}
Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@ import com.wavesplatform.state.*
import com.wavesplatform.state.diffs.invoke.InvokeDiffsCommon
import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves}
import com.wavesplatform.transaction.TxValidationError.*
import com.wavesplatform.transaction.VersionedTransaction.{ConstV1, ToV2, ToV3}
import com.wavesplatform.transaction.assets.*
import com.wavesplatform.transaction.assets.exchange.*
import com.wavesplatform.transaction.lease.*
@@ -172,25 +171,23 @@ object CommonValidation {

}

def generic1or2Barrier(t: VersionedTransaction): Either[ActivationError, T] = {
def generic1or2Barrier(t: Versioned): Either[ActivationError, T] = {
if (t.version == 1.toByte) Right(tx)
else if (t.version == 2.toByte) activationBarrier(BlockchainFeatures.SmartAccounts)
else Right(tx)
}

def versionIsCorrect(tx: Transaction & VersionedTransaction): Boolean = {
val maxVersion = VersionedTransaction.maxVersion(tx)
tx.version > 0 && tx.version <= maxVersion
}
def versionIsCorrect(tx: Versioned): Boolean =
tx.version > 0 && tx.version <= Versioned.maxVersion(tx)

val versionsBarrier = tx match {
case v: VersionedTransaction if !versionIsCorrect(v) && blockchain.isFeatureActivated(LightNode) =>
case v: Versioned if !versionIsCorrect(v) && blockchain.isFeatureActivated(LightNode) =>
Left(UnsupportedTypeAndVersion(v.tpe.id.toByte, v.version))

case p: PBSince with VersionedTransaction if PBSince.affects(p) =>
case p: PBSince with Versioned if PBSince.affects(p) =>
activationBarrier(BlockchainFeatures.BlockV5)

case v: VersionedTransaction if !versionIsCorrect(v) =>
case v: Versioned if !versionIsCorrect(v) =>
Left(UnsupportedTypeAndVersion(v.tpe.id.toByte, v.version))

case _ =>
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ final case class CreateAliasTransaction(
chainId: Byte
) extends Transaction(TransactionType.CreateAlias)
with SigProofsSwitch
with VersionedTransaction.ToV3
with Versioned.ToV3
with TxWithFee.InWaves
with PBSince.V3 {

Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ case class DataTransaction(
chainId: Byte
) extends Transaction(TransactionType.Data)
with ProvenTransaction
with VersionedTransaction.ToV2
with Versioned.ToV2
with TxWithFee.InWaves
with FastHashId
with PBSince.V2 {
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ final case class EthereumTransaction(
override val chainId: Byte
) extends Transaction(TransactionType.Ethereum)
with Authorized
with VersionedTransaction.ConstV1
with Versioned.ConstV1
with PBSince.V1 { self =>
import EthereumTransaction.*

Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ import scala.util.Try

case class GenesisTransaction(recipient: Address, amount: TxNonNegativeAmount, timestamp: TxTimestamp, signature: ByteStr, chainId: Byte)
extends Transaction(TransactionType.Genesis)
with VersionedTransaction.ConstV1 {
with Versioned.ConstV1 {
override val assetFee: (Asset, Long) = (Waves, 0)
override val id: Coeval[ByteStr] = Coeval.evalOnce(signature)

Original file line number Diff line number Diff line change
@@ -14,6 +14,6 @@ object PBSince {
case _: V3 => TxVersion.V3
}

def affects(tx: PBSince & VersionedTransaction): Boolean =
def affects(tx: PBSince & Versioned): Boolean =
tx.version >= version(tx)
}
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ case class PaymentTransaction(
chainId: Byte
) extends Transaction(TransactionType.Payment)
with ProvenTransaction
with VersionedTransaction.ConstV1
with Versioned.ConstV1
with TxWithFee.InWaves {

val bodyBytes: Coeval[Array[Byte]] = Coeval.evalOnce(PaymentTxSerializer.bodyBytes(this))
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.wavesplatform.transaction

trait SigProofsSwitch extends ProvenTransaction { self: Transaction with VersionedTransaction =>
trait SigProofsSwitch extends ProvenTransaction { self: Transaction with Versioned =>
def usesLegacySignature: Boolean =
self.version == Transaction.V1
}
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ import com.wavesplatform.transaction.validation.TxValidator
import scala.util.Try

trait TransactionParser {
type TransactionT <: Transaction with VersionedTransaction
type TransactionT <: Transaction with Versioned

def typeId: TxType

Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package com.wavesplatform.transaction

sealed trait VersionedTransaction {
sealed trait Versioned {
val version: TxVersion
}

object VersionedTransaction {
trait ConstV1 extends VersionedTransaction {
object Versioned {
trait ConstV1 extends Versioned {
val version: TxVersion = TxVersion.V1
}
trait ToV2 extends VersionedTransaction
trait ToV3 extends VersionedTransaction
trait ToV2 extends Versioned
trait ToV3 extends Versioned

def maxVersion(tx: Transaction): TxVersion =
def maxVersion(tx: Versioned): TxVersion =
tx match {
case _: ConstV1 => TxVersion.V1
case _: ToV2 => TxVersion.V2
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ final case class BurnTransaction(
chainId: Byte
) extends Transaction(TransactionType.Burn, Seq(asset))
with ProvenTransaction
with VersionedTransaction.ToV3
with Versioned.ToV3
with SigProofsSwitch
with TxWithFee.InWaves
with FastHashId
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ case class IssueTransaction(
proofs: Proofs,
chainId: Byte
) extends Transaction(TransactionType.Issue)
with VersionedTransaction.ToV3
with Versioned.ToV3
with ProvenTransaction
with FastHashId
with SigProofsSwitch
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ case class ReissueTransaction(
proofs: Proofs,
chainId: Byte
) extends Transaction(TransactionType.Reissue, Seq(asset))
with VersionedTransaction.ToV3
with Versioned.ToV3
with ProvenTransaction
with SigProofsSwitch
with TxWithFee.InWaves
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ case class SetAssetScriptTransaction(
proofs: Proofs,
chainId: Byte
) extends Transaction(TransactionType.SetAssetScript, Seq(asset))
with VersionedTransaction.ToV2
with Versioned.ToV2
with ProvenTransaction
with TxWithFee.InWaves
with FastHashId
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ case class SponsorFeeTransaction(
chainId: Byte
) extends Transaction(TransactionType.SponsorFee, Seq(asset))
with ProvenTransaction
with VersionedTransaction.ToV2
with Versioned.ToV2
with TxWithFee.InWaves
with FastHashId
with PBSince.V2 {
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ case class UpdateAssetInfoTransaction(
proofs: Proofs,
chainId: Byte
) extends Transaction(TransactionType.UpdateAssetInfo, Seq(assetId))
with VersionedTransaction.ConstV1
with Versioned.ConstV1
with FastHashId
with ProvenTransaction
with PBSince.V1 { self =>
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ case class ExchangeTransaction(
proofs: Proofs,
chainId: Byte
) extends Transaction(TransactionType.Exchange, order1.assetPair.checkedAssets)
with VersionedTransaction.ToV3
with Versioned.ToV3
with ProvenTransaction
with TxWithFee.InWaves
with FastHashId
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ final case class LeaseCancelTransaction(
chainId: Byte
) extends Transaction(TransactionType.LeaseCancel)
with SigProofsSwitch
with VersionedTransaction.ToV3
with Versioned.ToV3
with TxWithFee.InWaves
with FastHashId
with PBSince.V3 {
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ final case class LeaseTransaction(
chainId: Byte
) extends Transaction(TransactionType.Lease)
with SigProofsSwitch
with VersionedTransaction.ToV3
with Versioned.ToV3
with TxWithFee.InWaves
with FastHashId
with PBSince.V3 {
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.wavesplatform.transaction.serialization.impl

import com.wavesplatform.transaction.{PBSince, ProvenTransaction, SigProofsSwitch, Transaction, VersionedTransaction}
import com.wavesplatform.transaction.{PBSince, ProvenTransaction, SigProofsSwitch, Transaction, Versioned}
import play.api.libs.json.{JsArray, JsObject, JsString, Json}

object BaseTxJson {
@@ -12,10 +12,10 @@ object BaseTxJson {
"feeAssetId" -> tx.assetFee._1.maybeBase58Repr,
"timestamp" -> tx.timestamp
) ++ (tx match {
case v: VersionedTransaction => Json.obj("version" -> v.version)
case v: Versioned => Json.obj("version" -> v.version)
case _ => Json.obj()
}) ++ (tx match {
case pbs: PBSince with VersionedTransaction if PBSince.affects(pbs) => Json.obj("chainId" -> tx.chainId)
case pbs: PBSince with Versioned if PBSince.affects(pbs) => Json.obj("chainId" -> tx.chainId)
case _ => Json.obj()
}) ++ (tx match {
case p: ProvenTransaction =>
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ case class InvokeExpressionTransaction(
chainId: Byte
) extends Transaction(TransactionType.InvokeExpression, Nil)
with InvokeTransaction
with VersionedTransaction.ConstV1
with Versioned.ConstV1
with PBSince.V1 {

lazy val expressionBytes: ByteStr = expression.bytes.value()
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ case class InvokeScriptTransaction(
chainId: Byte
) extends Transaction(TransactionType.InvokeScript, payments.collect(InvokeScriptLike.IssuedAssets))
with InvokeTransaction
with VersionedTransaction.ToV2
with Versioned.ToV2
with PBSince.V2 {

override def root: InvokeScriptTransactionLike = this
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ object RealTransactionWrapper {
private def header(tx: Transaction, txIdOpt: Option[ByteStr] = None): Header = {
val v = tx match {
case _: EthereumTransaction => 0.toByte
case vt: VersionedTransaction => vt.version
case vt: Versioned => vt.version
case _ => TxVersion.V1
}
Header(txIdOpt.getOrElse(ByteStr(tx.id().arr)), tx.fee, tx.timestamp, v)
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ case class SetScriptTransaction(
chainId: Byte
) extends Transaction(TransactionType.SetScript)
with ProvenTransaction
with VersionedTransaction.ToV2
with Versioned.ToV2
with TxWithFee.InWaves
with FastHashId
with PBSince.V2 {
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@ case class MassTransferTransaction(
}
)
with ProvenTransaction
with VersionedTransaction.ToV2
with Versioned.ToV2
with TxWithFee.InWaves
with FastHashId
with PBSince.V2 {
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ case class TransferTransaction(
}
)
with TransferTransactionLike
with VersionedTransaction.ToV3
with Versioned.ToV3
with FastHashId
with SigProofsSwitch
with TxWithFee.InCustomAsset
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ import com.wavesplatform.lang.ValidationError
import com.wavesplatform.transaction.TxValidationError.GenericError
import com.wavesplatform.transaction.assets.IssueTransaction
import com.wavesplatform.transaction.transfer.TransferTransaction
import com.wavesplatform.transaction.{Asset, TxValidationError, TxVersion, VersionedTransaction}
import com.wavesplatform.transaction.{Asset, TxValidationError, TxVersion, Versioned}

import scala.util.Try

@@ -29,14 +29,14 @@ object TxConstraints {
if (cond) Valid(())
else Invalid(err).toValidatedNel

def byVersionSet[T <: VersionedTransaction](tx: T)(f: (Set[TxVersion], () => ValidatedV[Any])*): ValidatedV[T] = {
def byVersionSet[T <: Versioned](tx: T)(f: (Set[TxVersion], () => ValidatedV[Any])*): ValidatedV[T] = {
seq(tx)(f.collect {
case (v, func) if v.contains(tx.version) =>
func()
}*)
}

def byVersion[T <: VersionedTransaction](tx: T)(f: (TxVersion, () => ValidatedV[Any])*): ValidatedV[T] =
def byVersion[T <: Versioned](tx: T)(f: (TxVersion, () => ValidatedV[Any])*): ValidatedV[T] =
byVersionSet(tx)(f.map { case (v, f) => (Set(v), f) }*)

def fee(fee: Long): ValidatedV[Long] = {
Original file line number Diff line number Diff line change
@@ -452,7 +452,7 @@ class ProtoVersionTransactionsSpec
(updateAssetInfoTx.json() \ "version").as[Byte] shouldBe TxVersion.V1
}

def checkProofs(response: HttpResponse, tx: VersionedTransaction): (Proofs, JsObject) = {
def checkProofs(response: HttpResponse, tx: Versioned): (Proofs, JsObject) = {
response.status shouldBe StatusCodes.OK

(responseAs[JsObject] \ "version").as[Byte] shouldBe tx.version
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ import com.wavesplatform.state.Blockchain
import com.wavesplatform.transaction.smart.BlockchainContext.In
import com.wavesplatform.transaction.smart.{BlockchainContext, buildThisValue}
import com.wavesplatform.transaction.transfer.TransferTransaction
import com.wavesplatform.transaction.{Authorized, DataTransaction, EthereumTransaction, Proofs, ProvenTransaction, Transaction, VersionedTransaction}
import com.wavesplatform.transaction.{Authorized, DataTransaction, EthereumTransaction, Proofs, ProvenTransaction, Transaction, Versioned}
import com.wavesplatform.utils.EmptyBlockchain
import monix.eval.Coeval
import shapeless.Coproduct
@@ -209,7 +209,7 @@ package object predef {
def provenPart(t: Transaction with Authorized, emptyBodyBytes: Boolean = false, checkProofs: Boolean = true): String = {
val version = t match {
case _: EthereumTransaction => 0
case v: VersionedTransaction => v.version
case v: Versioned => v.version
case _ => 1
}
val proofs = t match {