From c0876185106fae0bb59cdb779354b70521d4d33d Mon Sep 17 00:00:00 2001 From: Artyom Sayadyan Date: Wed, 29 Nov 2023 16:26:03 +0300 Subject: [PATCH] NODE-2616 Refactored validation of transaction version (#3906) --- .../it/api/AsyncNetworkApi.scala | 7 ++- .../freecall/InvokeExpressionSuite.scala | 5 +-- .../api/http/TransactionJsonSerializer.scala | 6 +-- .../com/wavesplatform/database/package.scala | 20 +++------ .../state/diffs/CommonValidation.scala | 11 +++-- .../state/diffs/FeeValidation.scala | 2 +- .../diffs/invoke/InvokeDiffsCommon.scala | 2 +- .../transaction/CreateAliasTransaction.scala | 5 +-- .../transaction/DataTransaction.scala | 21 +++++---- .../transaction/EthereumTransaction.scala | 1 - .../transaction/GenesisTransaction.scala | 3 +- .../wavesplatform/transaction/PBSince.scala | 30 ++++++------- .../transaction/PaymentTransaction.scala | 6 +-- .../transaction/SigProofsSwitch.scala | 2 +- .../transaction/TransactionParser.scala | 2 - .../transaction/TransactionParsers.scala | 34 ++++----------- .../wavesplatform/transaction/Versioned.scala | 20 +++++++++ .../transaction/VersionedTransaction.scala | 11 ----- .../transaction/assets/BurnTransaction.scala | 9 ++-- .../transaction/assets/IssueTransaction.scala | 5 +-- .../assets/ReissueTransaction.scala | 5 +-- .../assets/SetAssetScriptTransaction.scala | 10 ++--- .../assets/SponsorFeeTransaction.scala | 9 ++-- .../assets/UpdateAssetInfoTransaction.scala | 8 ++-- .../assets/exchange/ExchangeTransaction.scala | 4 +- .../lease/LeaseCancelTransaction.scala | 7 ++- .../transaction/lease/LeaseTransaction.scala | 5 +-- .../serialization/impl/BaseTxJson.scala | 14 +++--- .../serialization/impl/DataTxSerializer.scala | 6 +-- .../impl/InvokeScriptTxSerializer.scala | 5 +-- .../impl/MassTransferTxSerializer.scala | 6 +-- .../impl/SetAssetScriptTxSerializer.scala | 4 +- .../impl/SetScriptTxSerializer.scala | 4 +- .../impl/SponsorFeeTxSerializer.scala | 4 +- .../smart/InvokeExpressionTransaction.scala | 6 +-- .../smart/InvokeScriptTransaction.scala | 6 +-- .../transaction/smart/InvokeTransaction.scala | 10 +---- .../smart/RealTransactionWrapper.scala | 2 +- .../smart/SetScriptTransaction.scala | 8 ++-- .../transfer/MassTransferTransaction.scala | 34 ++++++++------- .../transfer/TransferTransaction.scala | 22 +++++----- .../validation/TxConstraints.scala | 6 +-- .../validation/impl/ExchangeTxValidator.scala | 6 +-- .../impl/InvokeScriptTxValidator.scala | 7 +-- .../api/http/requests/RequestsSpec.scala | 5 +-- .../http/ProtoVersionTransactionsSpec.scala | 26 +++++------ .../http/TransactionsRouteSpec.scala | 3 +- .../diffs/freecall/InvokeExpressionTest.scala | 2 +- .../state/diffs/smart/predef/package.scala | 4 +- .../transaction/ChainIdSpecification.scala | 43 +++++++++---------- ...MassTransferTransactionSpecification.scala | 4 +- project/Dependencies.scala | 2 +- 52 files changed, 223 insertions(+), 266 deletions(-) create mode 100644 node/src/main/scala/com/wavesplatform/transaction/Versioned.scala delete mode 100644 node/src/main/scala/com/wavesplatform/transaction/VersionedTransaction.scala diff --git a/node-it/src/test/scala/com/wavesplatform/it/api/AsyncNetworkApi.scala b/node-it/src/test/scala/com/wavesplatform/it/api/AsyncNetworkApi.scala index fc7c065dcfa..a1a881d92ee 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/api/AsyncNetworkApi.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/api/AsyncNetworkApi.scala @@ -18,8 +18,11 @@ object AsyncNetworkApi { s"it-client-to-${node.name}", nonce ) - sender.connect(node.networkAddress).map { ch => - if (ch.isActive) sender.send(ch, messages*).map(_ => sender.close()) else sender.close() + sender.connect(node.networkAddress).flatMap { ch => + if (ch.isActive) sender.send(ch, messages*).map(_ => sender.close()) else { + sender.close() + Future.failed(new Exception("Channel is inactive")) + } } } } diff --git a/node-it/src/test/scala/com/wavesplatform/it/sync/smartcontract/freecall/InvokeExpressionSuite.scala b/node-it/src/test/scala/com/wavesplatform/it/sync/smartcontract/freecall/InvokeExpressionSuite.scala index e1d67fd94c6..297ee0c6813 100644 --- a/node-it/src/test/scala/com/wavesplatform/it/sync/smartcontract/freecall/InvokeExpressionSuite.scala +++ b/node-it/src/test/scala/com/wavesplatform/it/sync/smartcontract/freecall/InvokeExpressionSuite.scala @@ -5,14 +5,13 @@ import com.wavesplatform.api.http.ApiError.StateCheckFailed import com.wavesplatform.features.BlockchainFeatures.ContinuationTransaction import com.wavesplatform.it.NodeConfigs import com.wavesplatform.it.NodeConfigs.Default -import com.wavesplatform.it.api.{PutDataResponse, StateChangesDetails, Transaction, TransactionInfo} import com.wavesplatform.it.api.SyncHttpApi.* +import com.wavesplatform.it.api.{PutDataResponse, StateChangesDetails, Transaction, TransactionInfo} import com.wavesplatform.it.sync.invokeExpressionFee import com.wavesplatform.it.transactions.BaseTransactionSuite import com.wavesplatform.lang.directives.values.V6 import com.wavesplatform.lang.script.v1.ExprScript import com.wavesplatform.lang.v1.compiler.TestCompiler -import com.wavesplatform.transaction.smart.InvokeExpressionTransaction import org.scalatest.{Assertion, CancelAfterFailure} class InvokeExpressionSuite extends BaseTransactionSuite with CancelAfterFailure { @@ -55,7 +54,7 @@ class InvokeExpressionSuite extends BaseTransactionSuite with CancelAfterFailure } test("reject on illegal fields") { - val unsupportedVersion = InvokeExpressionTransaction.supportedVersions.max + 1 + val unsupportedVersion = 4 assertApiError( sender.invokeExpression(firstKeyPair, expr, version = unsupportedVersion.toByte), AssertiveApiError(StateCheckFailed.Id, s"Transaction version $unsupportedVersion has not been activated yet", matchMessage = true) diff --git a/node/src/main/scala/com/wavesplatform/api/http/TransactionJsonSerializer.scala b/node/src/main/scala/com/wavesplatform/api/http/TransactionJsonSerializer.scala index d5e510ca02b..d2b180f326c 100644 --- a/node/src/main/scala/com/wavesplatform/api/http/TransactionJsonSerializer.scala +++ b/node/src/main/scala/com/wavesplatform/api/http/TransactionJsonSerializer.scala @@ -262,7 +262,7 @@ final case class TransactionJsonSerializer(blockchain: Blockchain, commonApi: Co tx.assetFee._1.maybeBase58Repr.foreach(gen.writeStringField("feeAssetId", _)) gen.writeNumberField("timestamp", tx.timestamp, numbersAsString) gen.writeNumberField("version", tx.version, numbersAsString) - if (tx.asInstanceOf[PBSince].isProtobufVersion) gen.writeNumberField("chainId", tx.chainId, numbersAsString) + if (PBSince.affects(tx)) gen.writeNumberField("chainId", tx.chainId, numbersAsString) gen.writeStringField("sender", tx.sender.toAddress(tx.chainId).toString) gen.writeStringField("senderPublicKey", tx.sender.toString) gen.writeArrayField("proofs")(gen => tx.proofs.proofs.foreach(p => gen.writeString(p.toString))) @@ -290,8 +290,8 @@ final case class TransactionJsonSerializer(blockchain: Blockchain, commonApi: Co gen.writeNumberField("fee", tx.assetFee._2, numbersAsString) tx.assetFee._1.maybeBase58Repr.foreach(gen.writeStringField("feeAssetId", _)) gen.writeNumberField("timestamp", tx.timestamp, numbersAsString) - gen.writeNumberField("version", tx.version, numbersAsString) - if (tx.isProtobufVersion) gen.writeNumberField("chainId", tx.chainId, numbersAsString) + gen.writeNumberField("version", 1, numbersAsString) + gen.writeNumberField("chainId", tx.chainId, numbersAsString) gen.writeStringField("bytes", EthEncoding.toHexString(tx.bytes())) gen.writeStringField("sender", tx.senderAddress().toString) gen.writeStringField("senderPublicKey", tx.signerPublicKey().toString) diff --git a/node/src/main/scala/com/wavesplatform/database/package.scala b/node/src/main/scala/com/wavesplatform/database/package.scala index ba312758032..b632c7086bb 100644 --- a/node/src/main/scala/com/wavesplatform/database/package.scala +++ b/node/src/main/scala/com/wavesplatform/database/package.scala @@ -23,16 +23,8 @@ import com.wavesplatform.protobuf.{ByteStringExt, PBSnapshots} import com.wavesplatform.state.* import com.wavesplatform.state.StateHash.SectionId import com.wavesplatform.transaction.Asset.IssuedAsset -import com.wavesplatform.transaction.{ - EthereumTransaction, - GenesisTransaction, - PBSince, - PaymentTransaction, - Transaction, - TransactionParsers, - TxPositiveAmount, - TxValidationError -} + +import com.wavesplatform.transaction.{EthereumTransaction, PBSince, Transaction, TransactionParsers,TxPositiveAmount, TxValidationError, Versioned} import com.wavesplatform.utils.* import monix.eval.Task import monix.reactive.Observable @@ -628,11 +620,9 @@ package object database { def writeTransaction(v: (TxMeta, Transaction)): Array[Byte] = { val (m, tx) = v val ptx = tx match { - case lps: PBSince if !lps.isProtobufVersion => TD.LegacyBytes(ByteString.copyFrom(tx.bytes())) - case _: GenesisTransaction => TD.LegacyBytes(ByteString.copyFrom(tx.bytes())) - case _: PaymentTransaction => TD.LegacyBytes(ByteString.copyFrom(tx.bytes())) - case et: EthereumTransaction => TD.EthereumTransaction(ByteString.copyFrom(et.bytes())) - case _ => 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())) } pb.TransactionData(ptx, m.status.protobuf, m.spentComplexity).toByteArray } diff --git a/node/src/main/scala/com/wavesplatform/state/diffs/CommonValidation.scala b/node/src/main/scala/com/wavesplatform/state/diffs/CommonValidation.scala index 66cc7a4043a..59412cd2a68 100644 --- a/node/src/main/scala/com/wavesplatform/state/diffs/CommonValidation.scala +++ b/node/src/main/scala/com/wavesplatform/state/diffs/CommonValidation.scala @@ -171,20 +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: Versioned): Boolean = + tx.version > 0 && tx.version <= Versioned.maxVersion(tx) + val versionsBarrier = tx match { - case v: VersionedTransaction if !TransactionParsers.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 if p.isProtobufVersion => + case p: PBSince with Versioned if PBSince.affects(p) => activationBarrier(BlockchainFeatures.BlockV5) - case v: VersionedTransaction if !TransactionParsers.versionIsCorrect(v) => + case v: Versioned if !versionIsCorrect(v) => Left(UnsupportedTypeAndVersion(v.tpe.id.toByte, v.version)) case _ => diff --git a/node/src/main/scala/com/wavesplatform/state/diffs/FeeValidation.scala b/node/src/main/scala/com/wavesplatform/state/diffs/FeeValidation.scala index 95fcbaea82d..3c52774e02b 100644 --- a/node/src/main/scala/com/wavesplatform/state/diffs/FeeValidation.scala +++ b/node/src/main/scala/com/wavesplatform/state/diffs/FeeValidation.scala @@ -82,7 +82,7 @@ object FeeValidation { case tx: DataTransaction => val payloadLength = if (blockchain.isFeatureActivated(BlockchainFeatures.RideV6)) DataTxValidator.realUserPayloadSize(tx.data) - else if (tx.isProtobufVersion) tx.protoDataPayload.length + else if (PBSince.affects(tx)) tx.protoDataPayload.length else if (blockchain.isFeatureActivated(BlockchainFeatures.SmartAccounts)) tx.bodyBytes().length else tx.bytes().length diff --git a/node/src/main/scala/com/wavesplatform/state/diffs/invoke/InvokeDiffsCommon.scala b/node/src/main/scala/com/wavesplatform/state/diffs/invoke/InvokeDiffsCommon.scala index 5618d892161..f8c2e1b4775 100644 --- a/node/src/main/scala/com/wavesplatform/state/diffs/invoke/InvokeDiffsCommon.scala +++ b/node/src/main/scala/com/wavesplatform/state/diffs/invoke/InvokeDiffsCommon.scala @@ -377,7 +377,7 @@ object InvokeDiffsCommon { tx.enableEmptyKeys || dataEntries.forall(_.key.nonEmpty), (), { val versionInfo = tx.root match { - case s: PBSince => s" in tx version >= ${s.protobufVersion}" + case s: PBSince => s" in tx version >= ${PBSince.version(s)}" case _ => "" } s"Empty keys aren't allowed$versionInfo" diff --git a/node/src/main/scala/com/wavesplatform/transaction/CreateAliasTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/CreateAliasTransaction.scala index 55f63e4bca0..1a9787e9ca6 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/CreateAliasTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/CreateAliasTransaction.scala @@ -24,7 +24,7 @@ final case class CreateAliasTransaction( chainId: Byte ) extends Transaction(TransactionType.CreateAlias) with SigProofsSwitch - with VersionedTransaction + with Versioned.ToV3 with TxWithFee.InWaves with PBSince.V3 { @@ -45,8 +45,7 @@ final case class CreateAliasTransaction( object CreateAliasTransaction extends TransactionParser { type TransactionT = CreateAliasTransaction - val supportedVersions: Set[TxVersion] = Set(1, 2, 3) - val typeId: TxType = 10: Byte + val typeId: TxType = 10: Byte implicit val validator: TxValidator[CreateAliasTransaction] = CreateAliasTxValidator diff --git a/node/src/main/scala/com/wavesplatform/transaction/DataTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/DataTransaction.scala index 79ae84d1007..eb041144a24 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/DataTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/DataTransaction.scala @@ -1,17 +1,17 @@ package com.wavesplatform.transaction -import scala.util.Try - import com.wavesplatform.account.{AddressScheme, KeyPair, PrivateKey, PublicKey} import com.wavesplatform.crypto import com.wavesplatform.lang.ValidationError import com.wavesplatform.protobuf.transaction.PBTransactions -import com.wavesplatform.state._ +import com.wavesplatform.state.* import com.wavesplatform.transaction.serialization.impl.DataTxSerializer import com.wavesplatform.transaction.validation.TxValidator import com.wavesplatform.transaction.validation.impl.DataTxValidator import monix.eval.Coeval -import play.api.libs.json._ +import play.api.libs.json.* + +import scala.util.Try case class DataTransaction( version: TxVersion, @@ -23,7 +23,7 @@ case class DataTransaction( chainId: Byte ) extends Transaction(TransactionType.Data) with ProvenTransaction - with VersionedTransaction + with Versioned.ToV2 with TxWithFee.InWaves with FastHashId with PBSince.V2 { @@ -38,13 +38,12 @@ case class DataTransaction( object DataTransaction extends TransactionParser { type TransactionT = DataTransaction - val MaxBytes: Int = 150 * 1024 // uses for RIDE CONST_STRING and CONST_BYTESTR - val MaxProtoBytes: Int = 165890 // uses for RIDE CONST_BYTESTR - val MaxRideV6Bytes: Int = 165835 // (DataEntry.MaxPBKeySize + DataEntry.MaxValueSize) * 5 - val MaxEntryCount: Int = 100 + val MaxBytes: Int = 150 * 1024 // uses for RIDE CONST_STRING and CONST_BYTESTR + val MaxProtoBytes: Int = 165890 // uses for RIDE CONST_BYTESTR + val MaxRideV6Bytes: Int = 165835 // (DataEntry.MaxPBKeySize + DataEntry.MaxValueSize) * 5 + val MaxEntryCount: Int = 100 - override val typeId: TxType = 12: Byte - override val supportedVersions: Set[TxVersion] = Set(1, 2) + override val typeId: TxType = 12: Byte implicit val validator: TxValidator[DataTransaction] = DataTxValidator diff --git a/node/src/main/scala/com/wavesplatform/transaction/EthereumTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/EthereumTransaction.scala index d30e63acbfb..39bc2f15436 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/EthereumTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/EthereumTransaction.scala @@ -39,7 +39,6 @@ final case class EthereumTransaction( override val chainId: Byte ) extends Transaction(TransactionType.Ethereum) with Authorized - with VersionedTransaction.ConstV1 with PBSince.V1 { self => import EthereumTransaction.* diff --git a/node/src/main/scala/com/wavesplatform/transaction/GenesisTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/GenesisTransaction.scala index ae5758263ef..b57bfd7849f 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/GenesisTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/GenesisTransaction.scala @@ -26,8 +26,7 @@ case class GenesisTransaction(recipient: Address, amount: TxNonNegativeAmount, t object GenesisTransaction extends TransactionParser { type TransactionT = GenesisTransaction - override val typeId: TxType = 1: Byte - override val supportedVersions: Set[TxVersion] = Set(1) + override val typeId: TxType = 1: Byte override def parseBytes(bytes: Array[TxVersion]): Try[GenesisTransaction] = GenesisTxSerializer.parseBytes(bytes) diff --git a/node/src/main/scala/com/wavesplatform/transaction/PBSince.scala b/node/src/main/scala/com/wavesplatform/transaction/PBSince.scala index 69ebdc017e6..3ab627c9d25 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/PBSince.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/PBSince.scala @@ -1,25 +1,19 @@ package com.wavesplatform.transaction -import com.wavesplatform.protobuf.transaction.PBTransactions - -trait PBSince { self: Transaction with VersionedTransaction => - def protobufVersion: TxVersion - final def isProtobufVersion: Boolean = self.version >= protobufVersion - - override def bytesSize: Int = - if (isProtobufVersion) PBTransactions.protobuf(self).serializedSize else bytes().length -} +sealed trait PBSince object PBSince { - trait V1 extends PBSince { self: Transaction with VersionedTransaction => - override def protobufVersion: TxVersion = TxVersion.V1 - } + trait V1 extends PBSince + trait V2 extends PBSince + trait V3 extends PBSince - trait V2 extends PBSince { self: Transaction with VersionedTransaction => - override def protobufVersion: TxVersion = TxVersion.V2 - } + def version(tx: PBSince): TxVersion = + tx match { + case _: V1 => TxVersion.V1 + case _: V2 => TxVersion.V2 + case _: V3 => TxVersion.V3 + } - trait V3 extends PBSince { self: Transaction with VersionedTransaction => - override def protobufVersion: TxVersion = TxVersion.V3 - } + def affects(tx: PBSince & Versioned): Boolean = + tx.version >= version(tx) } diff --git a/node/src/main/scala/com/wavesplatform/transaction/PaymentTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/PaymentTransaction.scala index 0f24102e8e4..84f3cafeb19 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/PaymentTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/PaymentTransaction.scala @@ -1,6 +1,5 @@ package com.wavesplatform.transaction -import scala.util.Try import com.wavesplatform.account.{Address, KeyPair, PublicKey} import com.wavesplatform.common.state.ByteStr import com.wavesplatform.crypto @@ -11,6 +10,8 @@ import com.wavesplatform.transaction.validation.impl.PaymentTxValidator import monix.eval.Coeval import play.api.libs.json.JsObject +import scala.util.Try + case class PaymentTransaction( sender: PublicKey, recipient: Address, @@ -36,8 +37,7 @@ case class PaymentTransaction( object PaymentTransaction extends TransactionParser { type TransactionT = PaymentTransaction - override val typeId: TxType = 2: Byte - override val supportedVersions: Set[TxVersion] = Set(1) + override val typeId: TxType = 2: Byte override def parseBytes(bytes: Array[TxVersion]): Try[PaymentTransaction] = PaymentTxSerializer.parseBytes(bytes) diff --git a/node/src/main/scala/com/wavesplatform/transaction/SigProofsSwitch.scala b/node/src/main/scala/com/wavesplatform/transaction/SigProofsSwitch.scala index d4241a18862..a49c3743692 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/SigProofsSwitch.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/SigProofsSwitch.scala @@ -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 } diff --git a/node/src/main/scala/com/wavesplatform/transaction/TransactionParser.scala b/node/src/main/scala/com/wavesplatform/transaction/TransactionParser.scala index c93747e2f62..90477cf20ce 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/TransactionParser.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/TransactionParser.scala @@ -9,8 +9,6 @@ trait TransactionParser { def typeId: TxType - def supportedVersions: Set[TxVersion] - def parseBytes(bytes: Array[Byte]): Try[TransactionT] implicit def validator: TxValidator[TransactionT] diff --git a/node/src/main/scala/com/wavesplatform/transaction/TransactionParsers.scala b/node/src/main/scala/com/wavesplatform/transaction/TransactionParsers.scala index afeb7cd4ef8..50045bc80ad 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/TransactionParsers.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/TransactionParsers.scala @@ -3,13 +3,13 @@ package com.wavesplatform.transaction import com.wavesplatform.transaction.assets.* import com.wavesplatform.transaction.assets.exchange.ExchangeTransaction import com.wavesplatform.transaction.lease.{LeaseCancelTransaction, LeaseTransaction} -import com.wavesplatform.transaction.smart.{InvokeExpressionTransaction, InvokeScriptTransaction, SetScriptTransaction} +import com.wavesplatform.transaction.smart.{InvokeScriptTransaction, SetScriptTransaction} import com.wavesplatform.transaction.transfer.* import scala.util.{Failure, Try} object TransactionParsers { - private[this] val old: Map[Byte, TransactionParser] = Seq[TransactionParser]( + private[this] val old: Map[TxType, TransactionParser] = Seq[TransactionParser]( GenesisTransaction, PaymentTransaction, IssueTransaction, @@ -21,11 +21,9 @@ object TransactionParsers { CreateAliasTransaction, MassTransferTransaction, TransferTransaction - ).map { x => - x.typeId -> x - }.toMap + ).map { x => x.typeId -> x }.toMap - private[this] val modern: Map[(Byte, Byte), TransactionParser] = Seq[TransactionParser]( + private[this] val modern: Map[TxType, TransactionParser] = Seq[TransactionParser]( DataTransaction, SetScriptTransaction, IssueTransaction, @@ -38,22 +36,10 @@ object TransactionParsers { SponsorFeeTransaction, SetAssetScriptTransaction, InvokeScriptTransaction, - TransferTransaction, - InvokeExpressionTransaction, - UpdateAssetInfoTransaction - ).flatMap { x => - x.supportedVersions.map { version => - ((x.typeId, version), x) - } - }.toMap - - val all: Map[(Byte, Byte), TransactionParser] = old.flatMap { case (typeId, builder) => - builder.supportedVersions.map { version => - ((typeId, version), builder) - } - } ++ modern + TransferTransaction + ).map { x => (x.typeId, x) }.toMap - def by(typeId: Byte, version: TxVersion): Option[TransactionParser] = all.get((typeId, version)) + val all: Map[TxType, TransactionParser] = old ++ modern def parseBytes(bytes: Array[Byte]): Try[Transaction] = { def validate(parser: TransactionParser)(tx: parser.TransactionT): Try[Transaction] = { @@ -63,7 +49,7 @@ object TransactionParsers { def modernParseBytes: Try[Transaction] = { val typeId = bytes(1) val version = bytes(2) - modern.get((typeId, version)) match { + modern.get(typeId) match { case Some(parser) => parser.parseBytes(bytes).flatMap(validate(parser)) case None => Failure[Transaction](UnknownTypeAndVersion(typeId, version)) } @@ -74,13 +60,9 @@ object TransactionParsers { case None => Failure[Transaction](UnknownType(bytes(0))) } } - for { _ <- Either.cond(bytes.length > 2, (), BufferUnderflow).toTry tx <- if (bytes(0) == 0) modernParseBytes else oldParseBytes } yield tx } - - def versionIsCorrect(tx: Transaction & VersionedTransaction): Boolean = - TransactionParsers.all.contains((tx.tpe.id.toByte, tx.version)) } diff --git a/node/src/main/scala/com/wavesplatform/transaction/Versioned.scala b/node/src/main/scala/com/wavesplatform/transaction/Versioned.scala new file mode 100644 index 00000000000..eb0b7b4dc6f --- /dev/null +++ b/node/src/main/scala/com/wavesplatform/transaction/Versioned.scala @@ -0,0 +1,20 @@ +package com.wavesplatform.transaction + +sealed trait Versioned { + val version: TxVersion +} + +object Versioned { + trait ConstV1 extends Versioned { + val version: TxVersion = TxVersion.V1 + } + trait ToV2 extends Versioned + trait ToV3 extends Versioned + + def maxVersion(tx: Versioned): TxVersion = + tx match { + case _: ConstV1 => TxVersion.V1 + case _: ToV2 => TxVersion.V2 + case _: ToV3 => TxVersion.V3 + } +} diff --git a/node/src/main/scala/com/wavesplatform/transaction/VersionedTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/VersionedTransaction.scala deleted file mode 100644 index 79a93b97a58..00000000000 --- a/node/src/main/scala/com/wavesplatform/transaction/VersionedTransaction.scala +++ /dev/null @@ -1,11 +0,0 @@ -package com.wavesplatform.transaction - -trait VersionedTransaction { - def version: TxVersion -} - -object VersionedTransaction { - trait ConstV1 extends VersionedTransaction { - def version: TxVersion = TxVersion.V1 - } -} \ No newline at end of file diff --git a/node/src/main/scala/com/wavesplatform/transaction/assets/BurnTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/assets/BurnTransaction.scala index d0461c9034d..4e036cff382 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/assets/BurnTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/assets/BurnTransaction.scala @@ -22,8 +22,9 @@ final case class BurnTransaction( timestamp: TxTimestamp, proofs: Proofs, chainId: Byte -) extends Transaction(TransactionType.Burn, Seq(asset)) with ProvenTransaction - with VersionedTransaction +) extends Transaction(TransactionType.Burn, Seq(asset)) + with ProvenTransaction + with Versioned.ToV3 with SigProofsSwitch with TxWithFee.InWaves with FastHashId @@ -36,9 +37,7 @@ final case class BurnTransaction( object BurnTransaction extends TransactionParser { type TransactionT = BurnTransaction - - override val typeId: TxType = 6: Byte - override val supportedVersions: Set[TxVersion] = Set(1, 2, 3) + override val typeId: TxType = 6: Byte implicit val validator: TxValidator[BurnTransaction] = BurnTxValidator diff --git a/node/src/main/scala/com/wavesplatform/transaction/assets/IssueTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/assets/IssueTransaction.scala index af1ca6b0f21..193ecc0d419 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/assets/IssueTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/assets/IssueTransaction.scala @@ -30,7 +30,7 @@ case class IssueTransaction( proofs: Proofs, chainId: Byte ) extends Transaction(TransactionType.Issue) - with VersionedTransaction + with Versioned.ToV3 with ProvenTransaction with FastHashId with SigProofsSwitch @@ -50,8 +50,7 @@ object IssueTransaction extends TransactionParser { val MaxAssetDescriptionLength = 1000 val MaxAssetDecimals = 8 - override val typeId: TxType = 3: Byte - override val supportedVersions: Set[TxVersion] = Set(1, 2, 3) + override val typeId: TxType = 3: Byte implicit val validator: TxValidator[IssueTransaction] = IssueTxValidator implicit def sign(tx: IssueTransaction, privateKey: PrivateKey): IssueTransaction = diff --git a/node/src/main/scala/com/wavesplatform/transaction/assets/ReissueTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/assets/ReissueTransaction.scala index 42db148d6db..f73402d7499 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/assets/ReissueTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/assets/ReissueTransaction.scala @@ -24,7 +24,7 @@ case class ReissueTransaction( proofs: Proofs, chainId: Byte ) extends Transaction(TransactionType.Reissue, Seq(asset)) - with VersionedTransaction + with Versioned.ToV3 with ProvenTransaction with SigProofsSwitch with TxWithFee.InWaves @@ -39,8 +39,7 @@ case class ReissueTransaction( object ReissueTransaction extends TransactionParser { type TransactionT = ReissueTransaction - override val typeId: TxType = 5: Byte - override def supportedVersions: Set[TxVersion] = Set(1, 2, 3) + override val typeId: TxType = 5: Byte implicit val validator: TxValidator[ReissueTransaction] = ReissueTxValidator implicit def sign(tx: ReissueTransaction, privateKey: PrivateKey): ReissueTransaction = diff --git a/node/src/main/scala/com/wavesplatform/transaction/assets/SetAssetScriptTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/assets/SetAssetScriptTransaction.scala index afe6c8d1ffc..c445da9fe97 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/assets/SetAssetScriptTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/assets/SetAssetScriptTransaction.scala @@ -1,11 +1,11 @@ package com.wavesplatform.transaction.assets -import com.wavesplatform.account._ +import com.wavesplatform.account.* import com.wavesplatform.crypto import com.wavesplatform.lang.ValidationError import com.wavesplatform.lang.script.Script +import com.wavesplatform.transaction.* import com.wavesplatform.transaction.Asset.IssuedAsset -import com.wavesplatform.transaction._ import com.wavesplatform.transaction.serialization.impl.SetAssetScriptTxSerializer import com.wavesplatform.transaction.validation.TxValidator import com.wavesplatform.transaction.validation.impl.SetAssetScriptTxValidator @@ -24,7 +24,7 @@ case class SetAssetScriptTransaction( proofs: Proofs, chainId: Byte ) extends Transaction(TransactionType.SetAssetScript, Seq(asset)) - with VersionedTransaction + with Versioned.ToV2 with ProvenTransaction with TxWithFee.InWaves with FastHashId @@ -37,9 +37,7 @@ case class SetAssetScriptTransaction( object SetAssetScriptTransaction extends TransactionParser { type TransactionT = SetAssetScriptTransaction - - override val typeId: TxType = 15: Byte - override val supportedVersions: Set[TxVersion] = Set(1, 2) + override val typeId: TxType = 15: Byte implicit val validator: TxValidator[SetAssetScriptTransaction] = SetAssetScriptTxValidator diff --git a/node/src/main/scala/com/wavesplatform/transaction/assets/SponsorFeeTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/assets/SponsorFeeTransaction.scala index 42ff42a7f40..02a0d53e181 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/assets/SponsorFeeTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/assets/SponsorFeeTransaction.scala @@ -24,8 +24,9 @@ case class SponsorFeeTransaction( timestamp: TxTimestamp, proofs: Proofs, chainId: Byte -) extends Transaction(TransactionType.SponsorFee, Seq(asset)) with ProvenTransaction - with VersionedTransaction +) extends Transaction(TransactionType.SponsorFee, Seq(asset)) + with ProvenTransaction + with Versioned.ToV2 with TxWithFee.InWaves with FastHashId with PBSince.V2 { @@ -37,9 +38,7 @@ case class SponsorFeeTransaction( object SponsorFeeTransaction extends TransactionParser { type TransactionT = SponsorFeeTransaction - - override val typeId: TxType = 14: Byte - override val supportedVersions: Set[TxVersion] = Set(1, 2) + override val typeId: TxType = 14: Byte implicit val validator: TxValidator[SponsorFeeTransaction] = SponsorFeeTxValidator diff --git a/node/src/main/scala/com/wavesplatform/transaction/assets/UpdateAssetInfoTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/assets/UpdateAssetInfoTransaction.scala index dacd9923750..75dc0c047d5 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/assets/UpdateAssetInfoTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/assets/UpdateAssetInfoTransaction.scala @@ -15,7 +15,7 @@ import play.api.libs.json.{JsObject, Json} import scala.util.{Failure, Success, Try} case class UpdateAssetInfoTransaction( - version: TxVersion, + override val version: TxVersion, sender: PublicKey, assetId: IssuedAsset, name: String, @@ -26,7 +26,7 @@ case class UpdateAssetInfoTransaction( proofs: Proofs, chainId: Byte ) extends Transaction(TransactionType.UpdateAssetInfo, Seq(assetId)) - with VersionedTransaction + with Versioned.ConstV1 with FastHashId with ProvenTransaction with PBSince.V1 { self => @@ -49,9 +49,7 @@ case class UpdateAssetInfoTransaction( object UpdateAssetInfoTransaction extends TransactionParser { type TransactionT = UpdateAssetInfoTransaction - - override val typeId: TxType = 17: Byte - override val supportedVersions: Set[TxVersion] = Set(1) + override val typeId: TxType = 17: Byte implicit def sign(tx: UpdateAssetInfoTransaction, privateKey: PrivateKey): UpdateAssetInfoTransaction = tx.copy(proofs = Proofs(crypto.sign(privateKey, tx.bodyBytes()))) diff --git a/node/src/main/scala/com/wavesplatform/transaction/assets/exchange/ExchangeTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/assets/exchange/ExchangeTransaction.scala index 3e97ec447c7..37e221117c2 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/assets/exchange/ExchangeTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/assets/exchange/ExchangeTransaction.scala @@ -27,7 +27,7 @@ case class ExchangeTransaction( proofs: Proofs, chainId: Byte ) extends Transaction(TransactionType.Exchange, order1.assetPair.checkedAssets) - with VersionedTransaction + with Versioned.ToV3 with ProvenTransaction with TxWithFee.InWaves with FastHashId @@ -65,8 +65,6 @@ object ExchangeTransaction extends TransactionParser { override def parseBytes(bytes: Array[TxVersion]): Try[ExchangeTransaction] = ExchangeTxSerializer.parseBytes(bytes) - override def supportedVersions: Set[TxVersion] = Set(1, 2, 3) - val typeId: TxType = 7: Byte def create( diff --git a/node/src/main/scala/com/wavesplatform/transaction/lease/LeaseCancelTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/lease/LeaseCancelTransaction.scala index 11bc5838e0b..70607f6eaee 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/lease/LeaseCancelTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/lease/LeaseCancelTransaction.scala @@ -4,7 +4,7 @@ import com.wavesplatform.account.{AddressScheme, KeyPair, PrivateKey, PublicKey} import com.wavesplatform.common.state.ByteStr import com.wavesplatform.crypto import com.wavesplatform.lang.ValidationError -import com.wavesplatform.transaction._ +import com.wavesplatform.transaction.* import com.wavesplatform.transaction.serialization.impl.LeaseCancelTxSerializer import com.wavesplatform.transaction.validation.TxValidator import com.wavesplatform.transaction.validation.impl.LeaseCancelTxValidator @@ -23,7 +23,7 @@ final case class LeaseCancelTransaction( chainId: Byte ) extends Transaction(TransactionType.LeaseCancel) with SigProofsSwitch - with VersionedTransaction + with Versioned.ToV3 with TxWithFee.InWaves with FastHashId with PBSince.V3 { @@ -35,8 +35,7 @@ final case class LeaseCancelTransaction( object LeaseCancelTransaction extends TransactionParser { type TransactionT = LeaseCancelTransaction - val supportedVersions: Set[TxVersion] = Set(1, 2, 3) - val typeId: TxType = 9: Byte + val typeId: TxType = 9: Byte implicit val validator: TxValidator[LeaseCancelTransaction] = LeaseCancelTxValidator diff --git a/node/src/main/scala/com/wavesplatform/transaction/lease/LeaseTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/lease/LeaseTransaction.scala index b81bbbc4cc7..aea45ea0107 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/lease/LeaseTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/lease/LeaseTransaction.scala @@ -23,7 +23,7 @@ final case class LeaseTransaction( chainId: Byte ) extends Transaction(TransactionType.Lease) with SigProofsSwitch - with VersionedTransaction + with Versioned.ToV3 with TxWithFee.InWaves with FastHashId with PBSince.V3 { @@ -35,8 +35,7 @@ final case class LeaseTransaction( object LeaseTransaction extends TransactionParser { type TransactionT = LeaseTransaction - val supportedVersions: Set[TxVersion] = Set(1, 2, 3) - val typeId: TxType = 8: Byte + val typeId: TxType = 8: Byte implicit val validator: TxValidator[LeaseTransaction] = LeaseTxValidator diff --git a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/BaseTxJson.scala b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/BaseTxJson.scala index ff6ff28cbf0..26ee50dbacf 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/BaseTxJson.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/BaseTxJson.scala @@ -1,6 +1,6 @@ package com.wavesplatform.transaction.serialization.impl -import com.wavesplatform.transaction.{PBSince, ProvenTransaction, SigProofsSwitch, Transaction, VersionedTransaction} +import com.wavesplatform.transaction.{EthereumTransaction, PBSince, ProvenTransaction, SigProofsSwitch, Transaction, Versioned} import play.api.libs.json.{JsArray, JsObject, JsString, Json} object BaseTxJson { @@ -12,15 +12,17 @@ object BaseTxJson { "feeAssetId" -> tx.assetFee._1.maybeBase58Repr, "timestamp" -> tx.timestamp ) ++ (tx match { - case v: VersionedTransaction => Json.obj("version" -> v.version) - case _ => Json.obj() + case v: Versioned => Json.obj("version" -> v.version) + case _: EthereumTransaction => Json.obj("version" -> 1) + case _ => Json.obj() }) ++ (tx match { - case pbs: PBSince if pbs.isProtobufVersion => Json.obj("chainId" -> tx.chainId) - case _ => Json.obj() + case pbs: PBSince with Versioned if PBSince.affects(pbs) => Json.obj("chainId" -> tx.chainId) + case e: EthereumTransaction => Json.obj("chainId" -> e.chainId) + case _ => Json.obj() }) ++ (tx match { case p: ProvenTransaction => Json.obj( - "sender" -> p.sender.toAddress(p.chainId), + "sender" -> p.sender.toAddress(p.chainId), "senderPublicKey" -> p.sender, "proofs" -> JsArray(p.proofs.proofs.map(p => JsString(p.toString))) ) ++ (tx match { diff --git a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/DataTxSerializer.scala b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/DataTxSerializer.scala index 6b4eb1038e2..e429ee299c0 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/DataTxSerializer.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/DataTxSerializer.scala @@ -5,10 +5,10 @@ import java.nio.charset.StandardCharsets.UTF_8 import com.google.common.primitives.{Bytes, Longs, Shorts} import com.wavesplatform.common.state.ByteStr import com.wavesplatform.account.AddressScheme -import com.wavesplatform.serialization._ +import com.wavesplatform.serialization.* import com.wavesplatform.state.DataEntry.Type import com.wavesplatform.state.{BinaryDataEntry, BooleanDataEntry, DataEntry, IntegerDataEntry, StringDataEntry} -import com.wavesplatform.transaction.{DataTransaction, TxPositiveAmount, TxVersion} +import com.wavesplatform.transaction.{DataTransaction, PBSince, TxPositiveAmount, TxVersion} import com.wavesplatform.utils.StringBytes import play.api.libs.json.{JsObject, Json} @@ -51,7 +51,7 @@ object DataTxSerializer { } def toBytes(tx: DataTransaction): Array[Byte] = - if (tx.isProtobufVersion) PBTransactionSerializer.bytes(tx) + if (PBSince.affects(tx)) PBTransactionSerializer.bytes(tx) else Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes()) def parseBytes(bytes: Array[Byte]): Try[DataTransaction] = Try { diff --git a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/InvokeScriptTxSerializer.scala b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/InvokeScriptTxSerializer.scala index 7086a56794f..4059d42e610 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/InvokeScriptTxSerializer.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/InvokeScriptTxSerializer.scala @@ -1,7 +1,6 @@ package com.wavesplatform.transaction.serialization.impl import java.nio.ByteBuffer - import com.google.common.primitives.{Bytes, Longs} import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.* @@ -11,7 +10,7 @@ import com.wavesplatform.lang.v1.serialization.SerdeV1 import com.wavesplatform.serialization.* import com.wavesplatform.transaction.smart.InvokeScriptTransaction import com.wavesplatform.transaction.smart.InvokeScriptTransaction.Payment -import com.wavesplatform.transaction.{Asset, TxPositiveAmount, TxVersion} +import com.wavesplatform.transaction.{Asset, PBSince, TxPositiveAmount, TxVersion} import play.api.libs.json.{JsArray, JsObject, JsString, Json} import scala.util.Try @@ -69,7 +68,7 @@ object InvokeScriptTxSerializer { } def toBytes(tx: InvokeScriptTransaction): Array[Byte] = - if (tx.isProtobufVersion) PBTransactionSerializer.bytes(tx) + if (PBSince.affects(tx)) PBTransactionSerializer.bytes(tx) else Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes()) def parseBytes(bytes: Array[Byte]): Try[InvokeScriptTransaction] = Try { diff --git a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/MassTransferTxSerializer.scala b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/MassTransferTxSerializer.scala index f1b7125c593..121acbb9875 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/MassTransferTxSerializer.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/MassTransferTxSerializer.scala @@ -4,8 +4,8 @@ import java.nio.ByteBuffer import com.google.common.primitives.{Bytes, Longs, Shorts} import com.wavesplatform.account.AddressScheme import com.wavesplatform.common.state.ByteStr -import com.wavesplatform.serialization._ -import com.wavesplatform.transaction.{TxNonNegativeAmount, TxPositiveAmount, TxVersion} +import com.wavesplatform.serialization.* +import com.wavesplatform.transaction.{PBSince, TxNonNegativeAmount, TxPositiveAmount, TxVersion} import com.wavesplatform.transaction.transfer.MassTransferTransaction import com.wavesplatform.transaction.transfer.MassTransferTransaction.{ParsedTransfer, Transfer} import com.wavesplatform.utils.byteStrFormat @@ -51,7 +51,7 @@ object MassTransferTxSerializer { } def toBytes(tx: MassTransferTransaction): Array[Byte] = - if (tx.isProtobufVersion) PBTransactionSerializer.bytes(tx) + if (PBSince.affects(tx)) PBTransactionSerializer.bytes(tx) else Bytes.concat(this.bodyBytes(tx), tx.proofs.bytes()) // No zero mark def parseBytes(bytes: Array[Byte]): Try[MassTransferTransaction] = Try { diff --git a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/SetAssetScriptTxSerializer.scala b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/SetAssetScriptTxSerializer.scala index 2d9b2680262..5122a1c8b6e 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/SetAssetScriptTxSerializer.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/SetAssetScriptTxSerializer.scala @@ -4,7 +4,7 @@ import java.nio.ByteBuffer import com.google.common.primitives.{Bytes, Longs} import com.wavesplatform.account.AddressScheme import com.wavesplatform.serialization.{ByteBufferOps, Deser} -import com.wavesplatform.transaction.{TxPositiveAmount, TxVersion} +import com.wavesplatform.transaction.{PBSince, TxPositiveAmount, TxVersion} import com.wavesplatform.transaction.assets.SetAssetScriptTransaction import play.api.libs.json.{JsObject, Json} @@ -38,7 +38,7 @@ object SetAssetScriptTxSerializer { } def toBytes(tx: SetAssetScriptTransaction): Array[Byte] = - if (tx.isProtobufVersion) PBTransactionSerializer.bytes(tx) + if (PBSince.affects(tx)) PBTransactionSerializer.bytes(tx) else Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes()) def parseBytes(bytes: Array[Byte]): Try[SetAssetScriptTransaction] = Try { diff --git a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/SetScriptTxSerializer.scala b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/SetScriptTxSerializer.scala index 3475e0867c2..77e406ab37b 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/SetScriptTxSerializer.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/SetScriptTxSerializer.scala @@ -4,7 +4,7 @@ import java.nio.ByteBuffer import com.google.common.primitives.{Bytes, Longs} import com.wavesplatform.account.AddressScheme import com.wavesplatform.serialization.{ByteBufferOps, Deser} -import com.wavesplatform.transaction.{TxPositiveAmount, TxVersion} +import com.wavesplatform.transaction.{PBSince, TxPositiveAmount, TxVersion} import com.wavesplatform.transaction.smart.SetScriptTransaction import play.api.libs.json.{JsObject, Json} @@ -36,7 +36,7 @@ object SetScriptTxSerializer { } def toBytes(tx: SetScriptTransaction): Array[Byte] = { - if (tx.isProtobufVersion) PBTransactionSerializer.bytes(tx) + if (PBSince.affects(tx)) PBTransactionSerializer.bytes(tx) else Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes()) } diff --git a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/SponsorFeeTxSerializer.scala b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/SponsorFeeTxSerializer.scala index 6501d793459..6a6db4be5e7 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/SponsorFeeTxSerializer.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/serialization/impl/SponsorFeeTxSerializer.scala @@ -4,7 +4,7 @@ import java.nio.ByteBuffer import com.google.common.primitives.{Bytes, Longs} import com.wavesplatform.account.AddressScheme import com.wavesplatform.serialization.ByteBufferOps -import com.wavesplatform.transaction.{TxPositiveAmount, TxVersion} +import com.wavesplatform.transaction.{PBSince, TxPositiveAmount, TxVersion} import com.wavesplatform.transaction.assets.SponsorFeeTransaction import play.api.libs.json.{JsObject, Json} @@ -38,7 +38,7 @@ object SponsorFeeTxSerializer { } def toBytes(tx: SponsorFeeTransaction): Array[Byte] = { - if (tx.isProtobufVersion) PBTransactionSerializer.bytes(tx) + if (PBSince.affects(tx)) PBTransactionSerializer.bytes(tx) else Bytes.concat(Array(0: Byte, tx.tpe.id.toByte, tx.version), this.bodyBytes(tx), tx.proofs.bytes()) // [typeId, version] appears twice } diff --git a/node/src/main/scala/com/wavesplatform/transaction/smart/InvokeExpressionTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/smart/InvokeExpressionTransaction.scala index 669eac1e013..ce03551608d 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/smart/InvokeExpressionTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/smart/InvokeExpressionTransaction.scala @@ -16,7 +16,7 @@ import play.api.libs.json.{JsObject, Json} import scala.util.{Failure, Success, Try} case class InvokeExpressionTransaction( - version: TxVersion, + override val version: TxVersion, sender: PublicKey, expression: ExprScript, fee: TxPositiveAmount, @@ -26,6 +26,7 @@ case class InvokeExpressionTransaction( chainId: Byte ) extends Transaction(TransactionType.InvokeExpression, Nil) with InvokeTransaction + with Versioned.ConstV1 with PBSince.V1 { lazy val expressionBytes: ByteStr = expression.bytes.value() @@ -50,8 +51,7 @@ case class InvokeExpressionTransaction( object InvokeExpressionTransaction extends TransactionParser { type TransactionT = InvokeExpressionTransaction - override val typeId: TxType = 18: Byte - override val supportedVersions: Set[TxVersion] = Set(1) + override val typeId: TxType = 18: Byte implicit def sign(tx: InvokeExpressionTransaction, privateKey: PrivateKey): InvokeExpressionTransaction = tx.copy(proofs = Proofs(crypto.sign(privateKey, tx.bodyBytes()))) diff --git a/node/src/main/scala/com/wavesplatform/transaction/smart/InvokeScriptTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/smart/InvokeScriptTransaction.scala index 7f84764e81c..e848fa972d5 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/smart/InvokeScriptTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/smart/InvokeScriptTransaction.scala @@ -16,7 +16,7 @@ import play.api.libs.json.* import scala.util.Try case class InvokeScriptTransaction( - version: TxVersion, + override val version: TxVersion, sender: PublicKey, dApp: AddressOrAlias, funcCallOpt: Option[FUNCTION_CALL], @@ -28,6 +28,7 @@ case class InvokeScriptTransaction( chainId: Byte ) extends Transaction(TransactionType.InvokeScript, payments.collect(InvokeScriptLike.IssuedAssets)) with InvokeTransaction + with Versioned.ToV2 with PBSince.V2 { override def root: InvokeScriptTransactionLike = this @@ -42,8 +43,7 @@ case class InvokeScriptTransaction( object InvokeScriptTransaction extends TransactionParser { type TransactionT = InvokeScriptTransaction - override val typeId: TxType = 16: Byte - override val supportedVersions: Set[TxVersion] = Set(1, 2) + override val typeId: TxType = 16: Byte implicit val validator: TxValidator[InvokeScriptTransaction] = InvokeScriptTxValidator diff --git a/node/src/main/scala/com/wavesplatform/transaction/smart/InvokeTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/smart/InvokeTransaction.scala index b78fb3e34f2..c8aee7d3c89 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/smart/InvokeTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/smart/InvokeTransaction.scala @@ -3,15 +3,9 @@ import com.wavesplatform.lang.v1.FunctionHeader.User import com.wavesplatform.lang.v1.compiler.Terms.FUNCTION_CALL import com.wavesplatform.lang.v1.evaluator.ContractEvaluator import com.wavesplatform.state.diffs.invoke.InvokeScriptTransactionLike -import com.wavesplatform.transaction.{Asset, FastHashId, ProvenTransaction, Transaction, TxWithFee, VersionedTransaction} +import com.wavesplatform.transaction.{Asset, FastHashId, ProvenTransaction, Transaction, TxWithFee} -trait InvokeTransaction - extends Transaction - with InvokeScriptTransactionLike - with ProvenTransaction - with TxWithFee.InCustomAsset - with FastHashId - with VersionedTransaction { +trait InvokeTransaction extends Transaction with InvokeScriptTransactionLike with ProvenTransaction with TxWithFee.InCustomAsset with FastHashId { override val checkedAssets: Seq[Asset.IssuedAsset] = super[InvokeScriptTransactionLike].checkedAssets } diff --git a/node/src/main/scala/com/wavesplatform/transaction/smart/RealTransactionWrapper.scala b/node/src/main/scala/com/wavesplatform/transaction/smart/RealTransactionWrapper.scala index 9aa5819bf61..d07174266fa 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/smart/RealTransactionWrapper.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/smart/RealTransactionWrapper.scala @@ -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) diff --git a/node/src/main/scala/com/wavesplatform/transaction/smart/SetScriptTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/smart/SetScriptTransaction.scala index 9df4c37d735..8f21e7ac3b3 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/smart/SetScriptTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/smart/SetScriptTransaction.scala @@ -21,8 +21,9 @@ case class SetScriptTransaction( timestamp: TxTimestamp, proofs: Proofs, chainId: Byte -) extends Transaction(TransactionType.SetScript) with ProvenTransaction - with VersionedTransaction +) extends Transaction(TransactionType.SetScript) + with ProvenTransaction + with Versioned.ToV2 with TxWithFee.InWaves with FastHashId with PBSince.V2 { @@ -35,8 +36,7 @@ case class SetScriptTransaction( object SetScriptTransaction extends TransactionParser { type TransactionT = SetScriptTransaction - override val typeId: TxType = 13: Byte - override val supportedVersions: Set[TxVersion] = Set(1, 2) + override val typeId: TxType = 13: Byte implicit val validator: TxValidator[SetScriptTransaction] = SetScriptTxValidator diff --git a/node/src/main/scala/com/wavesplatform/transaction/transfer/MassTransferTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/transfer/MassTransferTransaction.scala index 2d24c240684..f1cf5c1b8b5 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/transfer/MassTransferTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/transfer/MassTransferTransaction.scala @@ -1,6 +1,5 @@ package com.wavesplatform.transaction.transfer -import scala.util.{Either, Try} import cats.instances.list.* import cats.syntax.traverse.* import com.wavesplatform.account.* @@ -17,6 +16,8 @@ import com.wavesplatform.transaction.validation.impl.MassTransferTxValidator import monix.eval.Coeval import play.api.libs.json.{JsObject, Json, OFormat} +import scala.util.{Either, Try} + case class MassTransferTransaction( version: TxVersion, sender: PublicKey, @@ -27,12 +28,15 @@ case class MassTransferTransaction( attachment: ByteStr, proofs: Proofs, chainId: Byte -) extends Transaction(TransactionType.MassTransfer, assetId match { - case Waves => Seq() - case a: IssuedAsset => Seq(a) - }) +) extends Transaction( + TransactionType.MassTransfer, + assetId match { + case Waves => Seq() + case a: IssuedAsset => Seq(a) + } + ) with ProvenTransaction - with VersionedTransaction + with Versioned.ToV2 with TxWithFee.InWaves with FastHashId with PBSince.V2 { @@ -57,8 +61,7 @@ object MassTransferTransaction extends TransactionParser { val MaxTransferCount = 100 - override val typeId: TxType = 11: Byte - override val supportedVersions: Set[TxVersion] = Set(1, 2) + override val typeId: TxType = 11: Byte implicit val validator: TxValidator[MassTransferTransaction] = MassTransferTxValidator @@ -121,14 +124,13 @@ object MassTransferTransaction extends TransactionParser { signed(version, sender.publicKey, assetId, transfers, fee, timestamp, attachment, sender.privateKey, chainId) def parseTransfersList(transfers: List[Transfer]): Validation[List[ParsedTransfer]] = - transfers.traverse { - case Transfer(recipient, amount) => - for { - addressOrAlias <- AddressOrAlias.fromString(recipient) - transferAmount <- TxNonNegativeAmount(amount)(NegativeAmount(amount, "asset")) - } yield { - ParsedTransfer(addressOrAlias, transferAmount) - } + transfers.traverse { case Transfer(recipient, amount) => + for { + addressOrAlias <- AddressOrAlias.fromString(recipient) + transferAmount <- TxNonNegativeAmount(amount)(NegativeAmount(amount, "asset")) + } yield { + ParsedTransfer(addressOrAlias, transferAmount) + } } } diff --git a/node/src/main/scala/com/wavesplatform/transaction/transfer/TransferTransaction.scala b/node/src/main/scala/com/wavesplatform/transaction/transfer/TransferTransaction.scala index e96535f6e42..b67c2aae32c 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/transfer/TransferTransaction.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/transfer/TransferTransaction.scala @@ -1,13 +1,13 @@ package com.wavesplatform.transaction.transfer -import com.wavesplatform.account._ +import com.wavesplatform.account.* import com.wavesplatform.common.state.ByteStr import com.wavesplatform.crypto import com.wavesplatform.lang.ValidationError +import com.wavesplatform.transaction.* import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves} -import com.wavesplatform.transaction._ import com.wavesplatform.transaction.serialization.impl.TransferTxSerializer -import com.wavesplatform.transaction.validation._ +import com.wavesplatform.transaction.validation.* import com.wavesplatform.transaction.validation.impl.TransferTxValidator import com.wavesplatform.utils.base58Length import monix.eval.Coeval @@ -27,12 +27,15 @@ case class TransferTransaction( timestamp: TxTimestamp, proofs: Proofs, chainId: Byte -) extends Transaction(TransactionType.Transfer, assetId match { - case Waves => Seq() - case a: IssuedAsset => Seq(a) - }) +) extends Transaction( + TransactionType.Transfer, + assetId match { + case Waves => Seq() + case a: IssuedAsset => Seq(a) + } + ) with TransferTransactionLike - with VersionedTransaction + with Versioned.ToV3 with FastHashId with SigProofsSwitch with TxWithFee.InCustomAsset @@ -57,8 +60,7 @@ object TransferTransaction extends TransactionParser { val MaxAttachmentSize = 140 val MaxAttachmentStringSize: Int = base58Length(MaxAttachmentSize) - val typeId: TxType = 4: Byte - val supportedVersions: Set[TxVersion] = Set(1, 2, 3) + val typeId: TxType = 4: Byte implicit val validator: TxValidator[TransferTransaction] = TransferTxValidator diff --git a/node/src/main/scala/com/wavesplatform/transaction/validation/TxConstraints.scala b/node/src/main/scala/com/wavesplatform/transaction/validation/TxConstraints.scala index f6fea245ae9..406605bb975 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/validation/TxConstraints.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/validation/TxConstraints.scala @@ -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] = { diff --git a/node/src/main/scala/com/wavesplatform/transaction/validation/impl/ExchangeTxValidator.scala b/node/src/main/scala/com/wavesplatform/transaction/validation/impl/ExchangeTxValidator.scala index 51bf02b5622..ffd8a212b67 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/validation/impl/ExchangeTxValidator.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/validation/impl/ExchangeTxValidator.scala @@ -3,19 +3,19 @@ package com.wavesplatform.transaction.validation.impl import cats.data.ValidatedNel import com.wavesplatform.lang.ValidationError import com.wavesplatform.transaction.TxValidationError.{GenericError, OrderValidationError} -import com.wavesplatform.transaction.TxVersion import com.wavesplatform.transaction.assets.exchange.{ExchangeTransaction, Order, OrderType} import com.wavesplatform.transaction.validation.TxValidator +import com.wavesplatform.transaction.{PBSince, TxVersion} object ExchangeTxValidator extends TxValidator[ExchangeTransaction] { override def validate(tx: ExchangeTransaction): ValidatedNel[ValidationError, ExchangeTransaction] = { - import tx._ + import tx.* V.seq(tx)( V.cond(sellMatcherFee <= Order.MaxAmount, GenericError("sellMatcherFee too large")), V.cond(buyMatcherFee <= Order.MaxAmount, GenericError("buyMatcherFee too large")), V.cond(fee.value <= Order.MaxAmount, GenericError("fee too large")), - V.cond(isProtobufVersion || order1.orderType == OrderType.BUY, GenericError("order1 should have OrderType.BUY")), + V.cond(PBSince.affects(tx) || order1.orderType == OrderType.BUY, GenericError("order1 should have OrderType.BUY")), V.cond(buyOrder.orderType == OrderType.BUY, GenericError("buyOrder should has OrderType.BUY")), V.cond(sellOrder.orderType == OrderType.SELL, GenericError("sellOrder should has OrderType.SELL")), V.cond(buyOrder.matcherPublicKey == sellOrder.matcherPublicKey, GenericError("buyOrder.matcher should be the same as sellOrder.matcher")), diff --git a/node/src/main/scala/com/wavesplatform/transaction/validation/impl/InvokeScriptTxValidator.scala b/node/src/main/scala/com/wavesplatform/transaction/validation/impl/InvokeScriptTxValidator.scala index 0621ca97acb..333a5916bc2 100644 --- a/node/src/main/scala/com/wavesplatform/transaction/validation/impl/InvokeScriptTxValidator.scala +++ b/node/src/main/scala/com/wavesplatform/transaction/validation/impl/InvokeScriptTxValidator.scala @@ -2,15 +2,16 @@ package com.wavesplatform.transaction.validation.impl import cats.data.NonEmptyList import cats.data.Validated.{Invalid, Valid} -import cats.syntax.either._ +import cats.syntax.either.* import com.wavesplatform.lang.v1.compiler.Terms.FUNCTION_CALL import com.wavesplatform.lang.v1.{ContractLimits, FunctionHeader} import com.wavesplatform.protobuf.transaction.PBTransactions +import com.wavesplatform.transaction.PBSince import com.wavesplatform.transaction.TxValidationError.{GenericError, NonPositiveAmount} import com.wavesplatform.transaction.smart.InvokeScriptTransaction import com.wavesplatform.transaction.smart.InvokeScriptTransaction.Payment import com.wavesplatform.transaction.validation.{TxValidator, ValidatedNV, ValidatedV} -import com.wavesplatform.utils._ +import com.wavesplatform.utils.* import scala.util.Try @@ -27,7 +28,7 @@ object InvokeScriptTxValidator extends TxValidator[InvokeScriptTransaction] { def checkLength: Either[GenericError, Unit] = { val length = - if (tx.isProtobufVersion) + if (PBSince.affects(tx)) PBTransactions.toPBInvokeScriptData(tx.dApp, tx.funcCallOpt, tx.payments).toByteArray.length else tx.bytes().length diff --git a/node/src/test/scala/com/wavesplatform/api/http/requests/RequestsSpec.scala b/node/src/test/scala/com/wavesplatform/api/http/requests/RequestsSpec.scala index b1d3fbb1ff9..aa4ea164eed 100644 --- a/node/src/test/scala/com/wavesplatform/api/http/requests/RequestsSpec.scala +++ b/node/src/test/scala/com/wavesplatform/api/http/requests/RequestsSpec.scala @@ -3,10 +3,9 @@ package com.wavesplatform.api.http.requests import com.wavesplatform.account.KeyPair import com.wavesplatform.common.utils.EitherExt2 import com.wavesplatform.test.FreeSpec -import com.wavesplatform.transaction.transfer.TransferTransaction import org.scalacheck.Gen import org.scalatest.OptionValues -import play.api.libs.json._ +import play.api.libs.json.* class RequestsSpec extends FreeSpec with OptionValues { private def transferRequestGen(version: Int): Gen[(KeyPair, JsObject)] = @@ -33,7 +32,7 @@ class RequestsSpec extends FreeSpec with OptionValues { "TransferRequest" - { "accepts proofs for version >= 2" in { - TransferTransaction.supportedVersions.filter(_ >= 2).foreach { version => + Seq(2, 3).foreach { version => forAll(transferRequestGen(version)) { case (sender, json) => val request = json.as[TransferRequest] diff --git a/node/src/test/scala/com/wavesplatform/http/ProtoVersionTransactionsSpec.scala b/node/src/test/scala/com/wavesplatform/http/ProtoVersionTransactionsSpec.scala index 9004252c75f..bf1c804f309 100644 --- a/node/src/test/scala/com/wavesplatform/http/ProtoVersionTransactionsSpec.scala +++ b/node/src/test/scala/com/wavesplatform/http/ProtoVersionTransactionsSpec.scala @@ -157,9 +157,9 @@ class ProtoVersionTransactionsSpec (reissueTx.json() \ "chainId").asOpt[Byte].value shouldBe reissueTx.chainId (burnTx.json() \ "chainId").asOpt[Byte].value shouldBe burnTx.chainId - issueTx.isProtobufVersion shouldBe true - reissueTx.isProtobufVersion shouldBe true - burnTx.isProtobufVersion shouldBe true + PBSince.affects(issueTx) shouldBe true + PBSince.affects(reissueTx) shouldBe true + PBSince.affects(burnTx) shouldBe true } "DataTransaction" in { @@ -182,7 +182,7 @@ class ProtoVersionTransactionsSpec (dataTx.json() \ "chainId").asOpt[Byte].value shouldBe dataTx.chainId - dataTx.isProtobufVersion shouldBe true + PBSince.affects(dataTx) shouldBe true } "ExchangeTransaction" in { @@ -209,7 +209,7 @@ class ProtoVersionTransactionsSpec (exchangeTx.json() \ "chainId").asOpt[Byte].value shouldBe exchangeTx.chainId - exchangeTx.isProtobufVersion shouldBe true + PBSince.affects(exchangeTx) shouldBe true } "InvokeScriptTransaction" in { @@ -246,7 +246,7 @@ class ProtoVersionTransactionsSpec (invokeScriptTx.json() \ "chainId").asOpt[Byte].value shouldBe invokeScriptTx.chainId - invokeScriptTx.isProtobufVersion shouldBe true + PBSince.affects(invokeScriptTx) shouldBe true } "LeaseTransaction/LeaseCancelTransaction" in { @@ -286,8 +286,8 @@ class ProtoVersionTransactionsSpec (leaseTx.json() \ "chainId").asOpt[Byte].value shouldBe leaseTx.chainId (leaseCancelTx.json() \ "chainId").asOpt[Byte].value shouldBe leaseCancelTx.chainId - leaseTx.isProtobufVersion shouldBe true - leaseCancelTx.isProtobufVersion shouldBe true + PBSince.affects(leaseTx) shouldBe true + PBSince.affects(leaseCancelTx) shouldBe true } "TransferTransaction" in { @@ -315,7 +315,7 @@ class ProtoVersionTransactionsSpec (transferTx.json() \ "chainId").asOpt[Byte].value shouldBe transferTx.chainId - transferTx.isProtobufVersion shouldBe true + PBSince.affects(transferTx) shouldBe true } "MassTransferTransaction" in { @@ -343,7 +343,7 @@ class ProtoVersionTransactionsSpec (massTransferTx.json() \ "chainId").asOpt[Byte].value shouldBe massTransferTx.chainId - massTransferTx.isProtobufVersion shouldBe true + PBSince.affects(massTransferTx) shouldBe true } "SetScriptTransaction" in { @@ -388,7 +388,7 @@ class ProtoVersionTransactionsSpec decode(base64Str) shouldBe setAssetScriptTx - setAssetScriptTx.isProtobufVersion shouldBe true + PBSince.affects(setAssetScriptTx) shouldBe true } "SponsorshipTransaction" in { @@ -413,7 +413,7 @@ class ProtoVersionTransactionsSpec (sponsorshipTx.json() \ "chainId").asOpt[Byte].value shouldBe sponsorshipTx.chainId - sponsorshipTx.isProtobufVersion shouldBe true + PBSince.affects(sponsorshipTx) shouldBe true } "UpdateAssetInfoTransaction" in { @@ -451,7 +451,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 diff --git a/node/src/test/scala/com/wavesplatform/http/TransactionsRouteSpec.scala b/node/src/test/scala/com/wavesplatform/http/TransactionsRouteSpec.scala index fae6c84f9f4..916fd75ac9b 100644 --- a/node/src/test/scala/com/wavesplatform/http/TransactionsRouteSpec.scala +++ b/node/src/test/scala/com/wavesplatform/http/TransactionsRouteSpec.scala @@ -33,7 +33,6 @@ import com.wavesplatform.transaction.utils.Signed import com.wavesplatform.transaction.{Asset, AssetIdLength, EthTxGenerator, TxHelpers, TxVersion} import com.wavesplatform.utils.{EthEncoding, EthHelpers, SharedSchedulerMixin} import com.wavesplatform.{BlockGen, TestValues, crypto} -import org.scalacheck.Gen import org.scalacheck.Gen.* import org.scalatest.{Assertion, OptionValues} import play.api.libs.json.* @@ -773,7 +772,7 @@ class TransactionsRouteSpec def invoke(func: JsObject, expectedArgsLength: Int): Unit = { val ist = Json.obj( "type" -> InvokeScriptTransaction.typeId, - "version" -> Gen.oneOf(InvokeScriptTransaction.supportedVersions.toSeq).sample.get, + "version" -> 3, "sender" -> acc1.toAddress, "dApp" -> acc2.toAddress, "call" -> func, diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/freecall/InvokeExpressionTest.scala b/node/src/test/scala/com/wavesplatform/state/diffs/freecall/InvokeExpressionTest.scala index 30594e40f70..055f1ae7608 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/freecall/InvokeExpressionTest.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/freecall/InvokeExpressionTest.scala @@ -261,7 +261,7 @@ class InvokeExpressionTest extends PropSpec with ScalaCheckPropertyChecks with W } ignore("available versions") { // TODO check is commented in CommonValidation - val unsupportedVersion = InvokeExpressionTransaction.supportedVersions.max + 1 + val unsupportedVersion = 4 val (genesisTxs, invoke) = scenario(version = unsupportedVersion.toByte) withDomain(ContinuationTransaction) { d => d.appendBlock(genesisTxs*) diff --git a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/package.scala b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/package.scala index 89c5bae26d0..a454344ab20 100644 --- a/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/package.scala +++ b/node/src/test/scala/com/wavesplatform/state/diffs/smart/predef/package.scala @@ -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 { diff --git a/node/src/test/scala/com/wavesplatform/transaction/ChainIdSpecification.scala b/node/src/test/scala/com/wavesplatform/transaction/ChainIdSpecification.scala index 4e0134f9739..f36d379cc86 100644 --- a/node/src/test/scala/com/wavesplatform/transaction/ChainIdSpecification.scala +++ b/node/src/test/scala/com/wavesplatform/transaction/ChainIdSpecification.scala @@ -19,24 +19,21 @@ import com.wavesplatform.transaction.transfer.{MassTransferTransaction, Transfer import org.scalacheck.Gen class ChainIdSpecification extends PropSpec { - private val otherChainId = 'W'.toByte private val aliasFromOther = Alias.createWithChainId("sasha", otherChainId, Some(otherChainId)).explicitGet() private val addressFromOther = Address.fromBytes(Base58.tryDecodeWithLimit("3P3oxTkpCWJgCr6SJrBzdP5N8jFqHCiy7L2").get, Some(otherChainId)).explicitGet() private val addressOrAlias = Gen.oneOf(aliasFromOther, addressFromOther) - private def addressOrAliasWithVersion( - vs: Set[TxVersion] - ): Gen[(AddressOrAlias, TxVersion, KeyPair, TxPositiveAmount, TxPositiveAmount, TxTimestamp)] = + private def addressOrAliasWithVersion: Gen[(AddressOrAlias, TxVersion, KeyPair, TxPositiveAmount, TxPositiveAmount, TxTimestamp)] = for { addressOrAlias <- addressOrAlias - version <- Gen.oneOf(vs.toSeq) + version <- Gen.oneOf(1, 2, 3) sender <- accountGen amount <- Gen.choose(1, 10000000L) fee <- Gen.choose(1000000L, 10000000L) ts <- Gen.choose(1, 1000000L) - } yield (addressOrAlias, version, sender, TxPositiveAmount.unsafeFrom(amount), TxPositiveAmount.unsafeFrom(fee), ts) + } yield (addressOrAlias, version.toByte, sender, TxPositiveAmount.unsafeFrom(amount), TxPositiveAmount.unsafeFrom(fee), ts) private def validateFromOtherNetwork(tx: Transaction): Unit = { tx.chainId should not be AddressScheme.current.chainId @@ -53,7 +50,7 @@ class ChainIdSpecification extends PropSpec { } property("TransferTransaction validation") { - forAll(addressOrAliasWithVersion(TransferTransaction.supportedVersions)) { case (addressOrAlias, version, sender, amount, fee, ts) => + forAll(addressOrAliasWithVersion) { case (addressOrAlias, version, sender, amount, fee, ts) => TransferTransaction( version, sender.publicKey, @@ -87,7 +84,7 @@ class ChainIdSpecification extends PropSpec { } property("PaymentTransaction validation") { - forAll(addressOrAliasWithVersion(PaymentTransaction.supportedVersions)) { case (_, _, sender, amount, fee, ts) => + forAll(addressOrAliasWithVersion) { case (_, _, sender, amount, fee, ts) => PaymentTransaction( sender.publicKey, addressFromOther, @@ -113,7 +110,7 @@ class ChainIdSpecification extends PropSpec { } property("LeaseTransaction validation") { - forAll(addressOrAliasWithVersion(LeaseTransaction.supportedVersions)) { case (addressOrAlias, version, sender, amount, fee, ts) => + forAll(addressOrAliasWithVersion) { case (addressOrAlias, version, sender, amount, fee, ts) => LeaseTransaction( version, sender.publicKey, @@ -141,7 +138,7 @@ class ChainIdSpecification extends PropSpec { } property("InvokeScriptTransaction validation") { - forAll(addressOrAliasWithVersion(InvokeScriptTransaction.supportedVersions)) { case (addressOrAlias, version, sender, _, fee, ts) => + forAll(addressOrAliasWithVersion) { case (addressOrAlias, version, sender, _, fee, ts) => InvokeScriptTransaction( version, sender.publicKey, @@ -173,7 +170,7 @@ class ChainIdSpecification extends PropSpec { } property("GenesisTransaction validation") { - forAll(addressOrAliasWithVersion(GenesisTransaction.supportedVersions)) { case (_, _, _, amount, _, ts) => + forAll(addressOrAliasWithVersion) { case (_, _, _, amount, _, ts) => GenesisTransaction( addressFromOther, TxNonNegativeAmount.unsafeFrom(amount.value), @@ -185,7 +182,7 @@ class ChainIdSpecification extends PropSpec { } property("BurnTransaction validation") { - forAll(addressOrAliasWithVersion(BurnTransaction.supportedVersions)) { case (_, _, sender, amount, fee, ts) => + forAll(addressOrAliasWithVersion) { case (_, _, sender, amount, fee, ts) => validateFromOtherNetwork( BurnTransaction( TxVersion.V3, @@ -202,7 +199,7 @@ class ChainIdSpecification extends PropSpec { } property("CreateAliasTransaction validation") { - forAll(addressOrAliasWithVersion(CreateAliasTransaction.supportedVersions)) { case (_, _, sender, _, fee, ts) => + forAll(addressOrAliasWithVersion) { case (_, _, sender, _, fee, ts) => validateFromOtherNetwork( CreateAliasTransaction( TxVersion.V3, @@ -218,7 +215,7 @@ class ChainIdSpecification extends PropSpec { } property("DataTransaction validation") { - forAll(addressOrAliasWithVersion(DataTransaction.supportedVersions)) { case (_, _, sender, _, fee, ts) => + forAll(addressOrAliasWithVersion) { case (_, _, sender, _, fee, ts) => validateFromOtherNetwork( DataTransaction( TxVersion.V2, @@ -234,7 +231,7 @@ class ChainIdSpecification extends PropSpec { } property("ExchangeTransaction validation") { - forAll(addressOrAliasWithVersion(ExchangeTransaction.supportedVersions)) { case (_, _, sender, amount, fee, ts) => + forAll(addressOrAliasWithVersion) { case (_, _, sender, amount, fee, ts) => val pair = AssetPair(Waves, IssuedAsset(ByteStr(bytes32gen.sample.get))) validateFromOtherNetwork( ExchangeTransaction( @@ -255,7 +252,7 @@ class ChainIdSpecification extends PropSpec { } property("IssueTransaction validation") { - forAll(addressOrAliasWithVersion(IssueTransaction.supportedVersions)) { case (_, _, sender, quantity, fee, ts) => + forAll(addressOrAliasWithVersion) { case (_, _, sender, quantity, fee, ts) => validateFromOtherNetwork( IssueTransaction( TxVersion.V3, @@ -276,7 +273,7 @@ class ChainIdSpecification extends PropSpec { } property("LeaseCancelTransaction validation") { - forAll(addressOrAliasWithVersion(LeaseCancelTransaction.supportedVersions)) { case (_, _, sender, _, fee, ts) => + forAll(addressOrAliasWithVersion) { case (_, _, sender, _, fee, ts) => validateFromOtherNetwork( LeaseCancelTransaction( TxVersion.V3, @@ -292,7 +289,7 @@ class ChainIdSpecification extends PropSpec { } property("MassTransferTransaction validation") { - forAll(addressOrAliasWithVersion(MassTransferTransaction.supportedVersions)) { case (addressOrAlias, _, sender, amount, fee, ts) => + forAll(addressOrAliasWithVersion) { case (addressOrAlias, _, sender, amount, fee, ts) => validateFromOtherNetwork( MassTransferTransaction( TxVersion.V2, @@ -310,7 +307,7 @@ class ChainIdSpecification extends PropSpec { } property("ReissueTransaction validation") { - forAll(addressOrAliasWithVersion(ReissueTransaction.supportedVersions)) { case (_, _, sender, quantity, fee, ts) => + forAll(addressOrAliasWithVersion) { case (_, _, sender, quantity, fee, ts) => validateFromOtherNetwork( ReissueTransaction( TxVersion.V3, @@ -328,7 +325,7 @@ class ChainIdSpecification extends PropSpec { } property("SetAssetScriptTransaction validation") { - forAll(addressOrAliasWithVersion(SetAssetScriptTransaction.supportedVersions)) { case (_, _, sender, _, fee, ts) => + forAll(addressOrAliasWithVersion) { case (_, _, sender, _, fee, ts) => validateFromOtherNetwork( SetAssetScriptTransaction( TxVersion.V2, @@ -345,7 +342,7 @@ class ChainIdSpecification extends PropSpec { } property("SetScriptTransaction validation") { - forAll(addressOrAliasWithVersion(SetScriptTransaction.supportedVersions)) { case (_, _, sender, _, fee, ts) => + forAll(addressOrAliasWithVersion) { case (_, _, sender, _, fee, ts) => validateFromOtherNetwork( SetScriptTransaction( TxVersion.V2, @@ -361,7 +358,7 @@ class ChainIdSpecification extends PropSpec { } property("SponsorFeeTransaction validation") { - forAll(addressOrAliasWithVersion(SponsorFeeTransaction.supportedVersions)) { case (_, _, sender, _, fee, ts) => + forAll(addressOrAliasWithVersion) { case (_, _, sender, _, fee, ts) => validateFromOtherNetwork( SponsorFeeTransaction( TxVersion.V2, @@ -378,7 +375,7 @@ class ChainIdSpecification extends PropSpec { } property("UpdateAssetInfoTransaction validation") { - forAll(addressOrAliasWithVersion(UpdateAssetInfoTransaction.supportedVersions)) { case (_, version, sender, _, fee, ts) => + forAll(addressOrAliasWithVersion) { case (_, version, sender, _, fee, ts) => validateFromOtherNetwork( UpdateAssetInfoTransaction( version, diff --git a/node/src/test/scala/com/wavesplatform/transaction/MassTransferTransactionSpecification.scala b/node/src/test/scala/com/wavesplatform/transaction/MassTransferTransactionSpecification.scala index f688277c1e0..bfd762e24ee 100644 --- a/node/src/test/scala/com/wavesplatform/transaction/MassTransferTransactionSpecification.scala +++ b/node/src/test/scala/com/wavesplatform/transaction/MassTransferTransactionSpecification.scala @@ -67,7 +67,7 @@ class MassTransferTransactionSpecification extends PropSpec { ) val bytes = tx.bytes() val recovered = { - if (tx.isProtobufVersion) PBTransactionSerializer.parseBytes(bytes) + if (PBSince.affects(tx)) PBTransactionSerializer.parseBytes(bytes) else MassTransferTransaction.parseBytes(bytes) }.get recovered shouldEqual tx @@ -125,7 +125,7 @@ class MassTransferTransactionSpecification extends PropSpec { proofs = Proofs(proofs), chainId = chainId ) - if (!tx.isProtobufVersion && tx.chainId == AddressScheme.current.chainId) { + if (!PBSince.affects(tx) && tx.chainId == AddressScheme.current.chainId) { val recovered = TransactionParsers.parseBytes(tx.bytes()).get recovered.bytes() shouldEqual tx.bytes() } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 1c5115023f8..1b502ecd74d 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,7 +6,7 @@ import scalapb.compiler.Version.scalapbVersion object Dependencies { // Node protobuf schemas private[this] val protoSchemasLib = - "com.wavesplatform" % "protobuf-schemas" % "1.5.1-85-SNAPSHOT" classifier "protobuf-src" intransitive () + "com.wavesplatform" % "protobuf-schemas" % "1.5.1-SNAPSHOT" classifier "protobuf-src" intransitive () private def akkaModule(module: String) = "com.typesafe.akka" %% s"akka-$module" % "2.6.21"