All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.wavesplatform.protobuf.PBSnapshots.scala Maven / Gradle / Ivy

The newest version!
package com.wavesplatform.protobuf

import com.google.protobuf.ByteString
import com.wavesplatform.account.{Address, Alias, PublicKey}
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.common.utils.EitherExt2
import com.wavesplatform.lang.script.ScriptReader
import com.wavesplatform.protobuf.snapshot.TransactionStateSnapshot
import com.wavesplatform.protobuf.snapshot.TransactionStateSnapshot.NewAsset
import com.wavesplatform.protobuf.transaction.{PBAmounts, PBTransactions}
import com.wavesplatform.state.*
import com.wavesplatform.transaction.Asset.IssuedAsset
import com.wavesplatform.transaction.{Asset, TxPositiveAmount}

import scala.collection.immutable.VectorMap

object PBSnapshots {

  import com.wavesplatform.protobuf.snapshot.TransactionStateSnapshot as S

  def toProtobuf(snapshot: StateSnapshot, txStatus: TxMeta.Status): TransactionStateSnapshot = {
    import snapshot.*
    TransactionStateSnapshot(
      balances.map { case ((address, asset), balance) =>
        S.Balance(address.toByteString, Some(PBAmounts.fromAssetAndAmount(asset, balance)))
      }.toSeq,
      leaseBalances.map { case (address, balance) =>
        S.LeaseBalance(address.toByteString, balance.in, balance.out)
      }.toSeq,
      newLeases = snapshot.newLeases.view.map { case (id, ld) =>
        S.NewLease(id.toByteString, ld.sender.toByteString, ld.recipientAddress.toByteString, ld.amount.value)
      }.toSeq,
      cancelledLeases = snapshot.cancelledLeases.view.map { case (id, _) =>
        S.CancelledLease(id.toByteString)
      }.toSeq,
      assetStatics.map { case (id, (st, idx)) =>
        (idx, NewAsset(id.id.toByteString, st.issuer.toByteString, st.decimals, st.nft))
      }.toSeq.sortBy(_._1).map(_._2),
      assetVolumes.map { case (asset, info) =>
        S.AssetVolume(asset.id.toByteString, info.isReissuable, ByteString.copyFrom(info.volume.toByteArray))
      }.toSeq,
      assetNamesAndDescriptions.map { case (asset, info) =>
        S.AssetNameAndDescription(asset.id.toByteString, info.name.toStringUtf8, info.description.toStringUtf8)
      }.toSeq,
      assetScripts.map { case (asset, script) =>
        S.AssetScript(asset.id.toByteString, script.script.bytes().toByteString)
      }.headOption,
      aliases.map { case (alias, address) => S.Alias(address.toByteString, alias.name) }.headOption,
      orderFills.map { case (orderId, VolumeAndFee(volume, fee)) =>
        S.OrderFill(orderId.toByteString, volume, fee)
      }.toSeq,
      accountScripts.map { case (publicKey, scriptOpt) =>
        scriptOpt.fold(
          S.AccountScript(publicKey.toByteString)
        )(script =>
          S.AccountScript(
            publicKey.toByteString,
            script.script.bytes().toByteString,
            script.verifierComplexity
          )
        )
      }.headOption,
      accountData.map { case (address, data) =>
        S.AccountData(address.toByteString, data.values.map(PBTransactions.toPBDataEntry).toSeq)
      }.toSeq,
      sponsorships.collect { case (asset, SponsorshipValue(minFee)) =>
        S.Sponsorship(asset.id.toByteString, minFee)
      }.toSeq,
      txStatus.protobuf
    )
  }

  def fromProtobuf(pbSnapshot: TransactionStateSnapshot, txId: ByteStr, height: Int): (StateSnapshot, TxMeta.Status) = {
    val balances: VectorMap[(Address, Asset), Long] =
      VectorMap() ++ pbSnapshot.balances.map(b => (b.address.toAddress(), b.getAmount.assetId.toAssetId) -> b.getAmount.amount)

    val leaseBalances: Map[Address, LeaseBalance] =
      pbSnapshot.leaseBalances
        .map(b => b.address.toAddress() -> LeaseBalance(b.in, b.out))
        .toMap

    val assetScripts: Map[IssuedAsset, AssetScriptInfo] =
      pbSnapshot.assetScripts.map { s =>
        s.assetId.toIssuedAssetId -> AssetScriptInfo(ScriptReader.fromBytes(s.script.toByteArray).explicitGet(), 0)
      }.toMap

    val assetStatics: Map[IssuedAsset, (AssetStaticInfo, Int)] =
      pbSnapshot.assetStatics.zipWithIndex.map { case (info, idx) =>
        info.assetId.toIssuedAssetId -> (AssetStaticInfo(
          info.assetId.toByteStr,
          TransactionId(txId),
          PublicKey(info.issuerPublicKey.toByteStr),
          info.decimals,
          info.nft
        ), idx + 1)
      }.toMap

    val assetVolumes: Map[IssuedAsset, AssetVolumeInfo] =
      pbSnapshot.assetVolumes
        .map(v => v.assetId.toIssuedAssetId -> AssetVolumeInfo(v.reissuable, BigInt(v.volume.toByteArray)))
        .toMap

    val assetNamesAndDescriptions: Map[IssuedAsset, AssetInfo] =
      pbSnapshot.assetNamesAndDescriptions
        .map(i => i.assetId.toIssuedAssetId -> AssetInfo(i.name, i.description, Height @@ height))
        .toMap

    val sponsorships: Map[IssuedAsset, SponsorshipValue] =
      pbSnapshot.sponsorships
        .map(s => s.assetId.toIssuedAssetId -> SponsorshipValue(s.minFee))
        .toMap

    val newLeases = pbSnapshot.newLeases.map { l =>
      l.leaseId.toByteStr ->
        LeaseStaticInfo(l.senderPublicKey.toPublicKey, l.recipientAddress.toAddress(), TxPositiveAmount.unsafeFrom(l.amount), txId, height)
    }.toMap

    val cancelledLeases = pbSnapshot.cancelledLeases.map { cl =>
      cl.leaseId.toByteStr -> LeaseDetails.Status.Cancelled(height, Some(txId))
    }.toMap

    val aliases: Map[Alias, Address] =
      pbSnapshot.aliases
        .map(a => Alias.create(a.alias).explicitGet() -> a.address.toAddress())
        .toMap

    val orderFills: Map[ByteStr, VolumeAndFee] =
      pbSnapshot.orderFills
        .map(of => of.orderId.toByteStr -> VolumeAndFee(of.volume, of.fee))
        .toMap

    val accountScripts: Map[PublicKey, Option[AccountScriptInfo]] =
      pbSnapshot.accountScripts.map { pbInfo =>
        val info =
          if (pbInfo.script.isEmpty)
            None
          else
            Some(
              AccountScriptInfo(
                pbInfo.senderPublicKey.toPublicKey,
                ScriptReader.fromBytes(pbInfo.script.toByteArray).explicitGet(),
                pbInfo.verifierComplexity
              )
            )
        pbInfo.senderPublicKey.toPublicKey -> info
      }.toMap

    val accountData: Map[Address, Map[String, DataEntry[?]]] =
      pbSnapshot.accountData.map { data =>
        val entries =
          data.entries.map { pbEntry =>
            val entry = PBTransactions.toVanillaDataEntry(pbEntry)
            entry.key -> entry
          }.toMap
        data.address.toAddress() -> entries
      }.toMap

    (
      StateSnapshot(
        VectorMap(),
        balances,
        leaseBalances,
        assetStatics,
        assetVolumes,
        assetNamesAndDescriptions,
        assetScripts,
        sponsorships,
        newLeases,
        cancelledLeases,
        aliases,
        orderFills,
        accountScripts,
        accountData
      ),
      TxMeta.Status.fromProtobuf(pbSnapshot.transactionStatus)
    )
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy