Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
phearnot committed Nov 20, 2023
1 parent d731e01 commit b672ff8
Show file tree
Hide file tree
Showing 36 changed files with 245 additions and 419 deletions.
1 change: 0 additions & 1 deletion node/src/main/scala/com/wavesplatform/Application.scala
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,6 @@ class Application(val actorSystem: ActorSystem, val settings: WavesSettings, con
settings.restAPISettings,
serverRequestTimeout,
wallet,
transactionPublisher,
blockchainUpdater,
() => blockchainUpdater.snapshotBlockchain,
time,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,8 @@ object CommonAccountsApi {
leaseId,
ld.sourceId,
ld.sender.toAddress,
blockchain.resolveAlias(ld.recipient).orElse(resolveDisabledAlias(leaseId)).explicitGet(),
ld.amount,
blockchain.resolveAlias(ld.recipientAddress).orElse(resolveDisabledAlias(leaseId)).explicitGet(),
ld.amount.value,
ld.height,
ld.status match {
case Status.Active => LeaseInfo.Status.Active
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ final case class TransactionJsonSerializer(blockchain: Blockchain, commonApi: Co
): LeaseRef = {
val detailsOpt = blockchain.leaseDetails(leaseId)
val txMetaOpt = detailsOpt.flatMap(d => blockchain.transactionMeta(d.sourceId))
val recipientOpt = recipientParamOpt.orElse(detailsOpt.map(_.recipient))
val recipientOpt = recipientParamOpt.orElse(detailsOpt.map(_.recipientAddress))
val resolvedRecipientOpt = recipientOpt.flatMap(r => blockchain.resolveAlias(r).toOption)

val statusOpt = detailsOpt.map(_.status)
Expand All @@ -464,7 +464,7 @@ final case class TransactionJsonSerializer(blockchain: Blockchain, commonApi: Co
detailsOpt.map(_.sourceId),
detailsOpt.map(_.sender.toAddress),
resolvedRecipientOpt,
amountOpt orElse detailsOpt.map(_.amount),
amountOpt orElse detailsOpt.map(_.amount.value),
txMetaOpt.map(_.height),
status,
statusDataOpt.flatMap(_._1),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import com.wavesplatform.api.http.assets.AssetsApiRoute.{
}
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.network.TransactionPublisher
import com.wavesplatform.settings.RestAPISettings
import com.wavesplatform.state.{AssetDescription, AssetScriptInfo, Blockchain, TxMeta}
import com.wavesplatform.transaction.Asset.IssuedAsset
Expand All @@ -51,7 +50,6 @@ case class AssetsApiRoute(
settings: RestAPISettings,
serverRequestTimeout: FiniteDuration,
wallet: Wallet,
transactionPublisher: TransactionPublisher,
blockchain: Blockchain,
compositeBlockchain: () => Blockchain,
time: Time,
Expand Down
2 changes: 1 addition & 1 deletion node/src/main/scala/com/wavesplatform/database/Keys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ object Keys {
Key(LeaseBalance, addressId.toByteArray, readLeaseBalance, writeLeaseBalance)

def leaseDetailsHistory(leaseId: ByteStr): Key[Seq[Int]] = historyKey(LeaseDetailsHistory, leaseId.arr)
def leaseDetails(leaseId: ByteStr)(height: Int): Key[Option[Either[Boolean, LeaseDetails]]] =
def leaseDetails(leaseId: ByteStr)(height: Int): Key[Option[LeaseDetails]] =
Key.opt(LeaseDetailsTag, Ints.toByteArray(height) ++ leaseId.arr, readLeaseDetails, writeLeaseDetails)

def filledVolumeAndFeeAt(orderId: ByteStr, height: Height): Key[VolumeAndFeeNode] =
Expand Down
35 changes: 8 additions & 27 deletions node/src/main/scala/com/wavesplatform/database/RocksDBWriter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -484,15 +484,8 @@ class RocksDBWriter(
expiredKeys ++= updateHistory(rw, Keys.assetDetailsHistory(asset), threshold, Keys.assetDetails(asset))
}

val txLeases = for {
(_, txInfo) <- snapshot.transactions
(id, lease) <- txInfo.snapshot.leaseStates
} yield (Some(txInfo.transaction), id, lease)
val txLeaseIdSet = txLeases.map(_._2).toSet
val allLeases = txLeases ++ snapshot.leaseStates.collect { case (id, lease) if !txLeaseIdSet.contains(id) => (None, id, lease) }
allLeases.foreach { case (txOpt, id, lease) =>
val details = lease.toDetails(this, txOpt, leaseDetails(id))
rw.put(Keys.leaseDetails(id)(height), Some(Right(details)))
for ((id, details) <- snapshot.leaseStates) {
rw.put(Keys.leaseDetails(id)(height), Some(details))
expiredKeys ++= updateHistory(rw, Keys.leaseDetailsHistory(id), threshold, Keys.leaseDetails(id))
}

Expand Down Expand Up @@ -523,7 +516,10 @@ class RocksDBWriter(
val txId = TransactionId(id)

val size = rw.put(Keys.transactionAt(Height(height), num, rdb.txHandle), Some((meta, tx)))
rw.put(Keys.transactionStateSnapshotAt(Height(height), num, rdb.txSnapshotHandle), Some(PBSnapshots.toProtobuf(txInfo.snapshot, txInfo.status)))
rw.put(
Keys.transactionStateSnapshotAt(Height(height), num, rdb.txSnapshotHandle),
Some(PBSnapshots.toProtobuf(txInfo.snapshot, txInfo.status))
)
rw.put(Keys.transactionMetaById(txId, rdb.txMetaHandle), Some(TransactionMeta(height, num, tx.tpe.id, meta.status.protobuf, 0, size)))
targetBf.put(id.arr)

Expand Down Expand Up @@ -953,23 +949,8 @@ class RocksDBWriter(

override def leaseDetails(leaseId: ByteStr): Option[LeaseDetails] = readOnly { db =>
for {
h <- db.get(Keys.leaseDetailsHistory(leaseId)).headOption
detailsOrFlag <- db.get(Keys.leaseDetails(leaseId)(h))
details <- detailsOrFlag.fold(
isActive =>
transactionInfo(leaseId, db).collect { case (txm, lt: LeaseTransaction) =>
LeaseDetails(
lt.sender,
lt.recipient,
lt.amount.value,
if (isActive) LeaseDetails.Status.Active
else LeaseDetails.Status.Cancelled(h, None),
leaseId,
txm.height
)
},
Some(_)
)
h <- db.get(Keys.leaseDetailsHistory(leaseId)).headOption
details <- db.get(Keys.leaseDetails(leaseId)(h))
} yield details
}

Expand Down
112 changes: 49 additions & 63 deletions node/src/main/scala/com/wavesplatform/database/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,16 @@ import com.wavesplatform.state.*
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, GenesisTransaction, PBSince, PaymentTransaction, Transaction, TransactionParsers, TxValidationError}
import com.wavesplatform.transaction.{
EthereumTransaction,
GenesisTransaction,
PBSince,
PaymentTransaction,
Transaction,
TransactionParsers,
TxPositiveAmount,
TxValidationError
}
import com.wavesplatform.utils.*
import monix.eval.Task
import monix.reactive.Observable
Expand Down Expand Up @@ -135,47 +143,39 @@ package object database {
def writeLeaseBalance(lb: CurrentLeaseBalance): Array[Byte] =
Longs.toByteArray(lb.in) ++ Longs.toByteArray(lb.out) ++ Ints.toByteArray(lb.height) ++ Ints.toByteArray(lb.prevHeight)

def writeLeaseDetails(lde: Either[Boolean, LeaseDetails]): Array[Byte] =
lde.fold(
_ => throw new IllegalArgumentException("Can not write boolean flag instead of LeaseDetails"),
ld =>
pb.LeaseDetails(
ByteString.copyFrom(ld.sender.arr),
Some(PBRecipients.create(ld.recipient)),
ld.amount,
ByteString.copyFrom(ld.sourceId.arr),
ld.height,
ld.status match {
case LeaseDetails.Status.Active => pb.LeaseDetails.Status.Active(com.google.protobuf.empty.Empty())
case LeaseDetails.Status.Cancelled(height, cancelTxId) =>
pb.LeaseDetails.Status
.Cancelled(pb.LeaseDetails.Cancelled(height, cancelTxId.fold(ByteString.EMPTY)(id => ByteString.copyFrom(id.arr))))
case LeaseDetails.Status.Expired(height) => pb.LeaseDetails.Status.Expired(pb.LeaseDetails.Expired(height))
}
).toByteArray
)
def writeLeaseDetails(ld: LeaseDetails): Array[Byte] =
pb.LeaseDetails(
ByteString.copyFrom(ld.sender.arr),
Some(PBRecipients.create(ld.recipientAddress)),
ld.amount.value,
ByteString.copyFrom(ld.sourceId.arr),
ld.height,
ld.status match {
case LeaseDetails.Status.Active => pb.LeaseDetails.Status.Active(com.google.protobuf.empty.Empty())
case LeaseDetails.Status.Cancelled(height, cancelTxId) =>
pb.LeaseDetails.Status
.Cancelled(pb.LeaseDetails.Cancelled(height, cancelTxId.fold(ByteString.EMPTY)(id => ByteString.copyFrom(id.arr))))
case LeaseDetails.Status.Expired(height) => pb.LeaseDetails.Status.Expired(pb.LeaseDetails.Expired(height))
}
).toByteArray

def readLeaseDetails(data: Array[Byte]): Either[Boolean, LeaseDetails] =
if (data.length == 1) Left(data(0) == 1)
else {
val d = pb.LeaseDetails.parseFrom(data)
Right(
LeaseDetails(
d.senderPublicKey.toPublicKey,
PBRecipients.toAddressOrAlias(d.recipient.get, AddressScheme.current.chainId).explicitGet(),
d.amount,
d.status match {
case pb.LeaseDetails.Status.Active(_) => LeaseDetails.Status.Active
case pb.LeaseDetails.Status.Expired(pb.LeaseDetails.Expired(height, _)) => LeaseDetails.Status.Expired(height)
case pb.LeaseDetails.Status.Cancelled(pb.LeaseDetails.Cancelled(height, transactionId, _)) =>
LeaseDetails.Status.Cancelled(height, Some(transactionId.toByteStr).filter(!_.isEmpty))
case pb.LeaseDetails.Status.Empty => ???
},
d.sourceId.toByteStr,
d.height
)
)
}
def readLeaseDetails(data: Array[Byte]): LeaseDetails = {
val d = pb.LeaseDetails.parseFrom(data)
LeaseDetails(
d.senderPublicKey.toPublicKey,
PBRecipients.toAddress(d.recipient.get, AddressScheme.current.chainId).explicitGet(),
TxPositiveAmount.unsafeFrom(d.amount),
d.status match {
case pb.LeaseDetails.Status.Active(_) => LeaseDetails.Status.Active
case pb.LeaseDetails.Status.Expired(pb.LeaseDetails.Expired(height, _)) => LeaseDetails.Status.Expired(height)
case pb.LeaseDetails.Status.Cancelled(pb.LeaseDetails.Cancelled(height, transactionId, _)) =>
LeaseDetails.Status.Cancelled(height, Some(transactionId.toByteStr).filter(!_.isEmpty))
case pb.LeaseDetails.Status.Empty => ???
},
d.sourceId.toByteStr,
d.height
)
}

def readVolumeAndFeeNode(data: Array[Byte]): VolumeAndFeeNode = if (data != null && data.length == 20)
VolumeAndFeeNode(Longs.fromByteArray(data.take(8)), Longs.fromByteArray(data.slice(8, 16)), Height(Ints.fromByteArray(data.takeRight(4))))
Expand Down Expand Up @@ -247,17 +247,6 @@ package object database {
).toByteArray
}

def readAssetStaticInfo(bb: Array[Byte]): AssetStaticInfo = {
val sai = pb.StaticAssetInfo.parseFrom(bb)
AssetStaticInfo(
sai.id.toByteStr,
TransactionId(sai.sourceId.toByteStr),
PublicKey(sai.issuerPublicKey.toByteArray),
sai.decimals,
sai.isNft
)
}

def writeBlockMeta(data: pb.BlockMeta): Array[Byte] = data.toByteArray

def readBlockMeta(bs: Array[Byte]): pb.BlockMeta = pb.BlockMeta.parseFrom(bs)
Expand Down Expand Up @@ -700,16 +689,13 @@ package object database {
Height(pbStaticInfo.height)
)

def loadActiveLeases(rdb: RDB, fromHeight: Int, toHeight: Int): Seq[LeaseTransaction] = rdb.db.withResource { r =>
def loadActiveLeases(rdb: RDB, fromHeight: Int, toHeight: Int): Map[ByteStr, LeaseDetails] = rdb.db.withResource { r =>
(for {
id <- loadLeaseIds(r, fromHeight, toHeight, includeCancelled = false)
details <- fromHistory(r, Keys.leaseDetailsHistory(id), Keys.leaseDetails(id))
if details.exists(_.fold(identity, _.isActive))
tm <- r.get(Keys.transactionMetaById(TransactionId(id), rdb.txMetaHandle))
tx <- r.get(Keys.transactionAt(Height(tm.height), TxNum(tm.num.toShort), rdb.txHandle))
} yield tx).collect {
case (ltm, lt: LeaseTransaction) if ltm.status == TxMeta.Status.Succeeded => lt
}.toSeq
id <- loadLeaseIds(r, fromHeight, toHeight, includeCancelled = false)
maybeNewDetails <- fromHistory(r, Keys.leaseDetailsHistory(id), Keys.leaseDetails(id))
newDetails <- maybeNewDetails
if newDetails.isActive
} yield (id, newDetails)).toMap
}

def loadLeaseIds(resource: DBResource, fromHeight: Int, toHeight: Int, includeCancelled: Boolean): Set[ByteStr] = {
Expand All @@ -726,7 +712,7 @@ package object database {
iterator.seek(KeyTags.LeaseDetails.prefixBytes ++ Ints.toByteArray(fromHeight))
while (iterator.isValid && keyInRange()) {
val leaseId = ByteStr(iterator.key().drop(6))
if (includeCancelled || readLeaseDetails(iterator.value()).fold(identity, _.isActive))
if (includeCancelled || readLeaseDetails(iterator.value()).isActive)
leaseIds += leaseId
else
leaseIds -= leaseId
Expand Down
26 changes: 11 additions & 15 deletions node/src/main/scala/com/wavesplatform/protobuf/PBSnapshots.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ 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.crypto.KeyLength
import com.wavesplatform.lang.script.ScriptReader
import com.wavesplatform.protobuf.snapshot.TransactionStateSnapshot
import com.wavesplatform.protobuf.snapshot.TransactionStateSnapshot.AssetStatic
import com.wavesplatform.protobuf.transaction.{PBAmounts, PBTransactions}
import com.wavesplatform.state.*
import com.wavesplatform.state.reader.LeaseDetails
import com.wavesplatform.state.reader.LeaseDetails.Status
import com.wavesplatform.transaction.Asset
import com.wavesplatform.transaction.Asset.IssuedAsset
import com.wavesplatform.transaction.{Asset, TxPositiveAmount}

import scala.collection.immutable.VectorMap

Expand Down Expand Up @@ -46,10 +45,10 @@ object PBSnapshots {
orderFills.map { case (orderId, VolumeAndFee(volume, fee)) =>
S.OrderFill(orderId.toByteString, volume, fee)
}.toSeq,
leaseStates.map { case (leaseId, LeaseSnapshot(sender, recipient, amount, status)) =>
val pbStatus = status match {
leaseStates.map { case (leaseId, ld) =>
val pbStatus = ld.status match {
case Status.Active =>
S.LeaseState.Status.Active(S.LeaseState.Active(amount, sender.toByteString, recipient.asInstanceOf[Address].toByteString))
S.LeaseState.Status.Active(S.LeaseState.Active(ld.amount.value, ld.sender.toByteString, ld.recipientAddress.toByteString))
case _: Status.Cancelled | _: Status.Expired =>
S.LeaseState.Status.Cancelled(S.LeaseState.Cancelled())
}
Expand Down Expand Up @@ -116,23 +115,20 @@ object PBSnapshots {
.map(s => s.assetId.toIssuedAssetId -> SponsorshipValue(s.minFee))
.toMap

val leaseStates: Map[ByteStr, LeaseSnapshot] =
val leaseStates: Map[ByteStr, LeaseDetails] =
pbSnapshot.leaseStates.map { ls =>
ls.status match {
case TransactionStateSnapshot.LeaseState.Status.Active(value) =>
ls.leaseId.toByteStr -> LeaseSnapshot(
ls.leaseId.toByteStr -> LeaseDetails(
value.sender.toPublicKey,
value.recipient.toAddress(),
value.amount,
LeaseDetails.Status.Active
TxPositiveAmount.unsafeFrom(value.amount),
LeaseDetails.Status.Active,
txId,
height
)
case _: TransactionStateSnapshot.LeaseState.Status.Cancelled | TransactionStateSnapshot.LeaseState.Status.Empty =>
ls.leaseId.toByteStr -> LeaseSnapshot(
PublicKey(ByteStr.fill(KeyLength)(0)),
Address(Array.fill(Address.HashLength)(0)),
0,
LeaseDetails.Status.Cancelled(0, None)
)
ls.leaseId.toByteStr -> ???
}
}.toMap

Expand Down
Loading

0 comments on commit b672ff8

Please sign in to comment.