Skip to content

Commit

Permalink
NODE-2331: Fix leases json format (REST API) (#3509)
Browse files Browse the repository at this point in the history
  • Loading branch information
Karasiq authored Jun 21, 2021
1 parent ce6f143 commit 37f1b02
Show file tree
Hide file tree
Showing 5 changed files with 416 additions and 126 deletions.
36 changes: 28 additions & 8 deletions node/src/main/scala/com/wavesplatform/api/http/DebugApiRoute.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ import com.wavesplatform.lang.ValidationError
import com.wavesplatform.mining.{Miner, MinerDebugInfo}
import com.wavesplatform.network.{PeerDatabase, PeerInfo, _}
import com.wavesplatform.settings.{RestAPISettings, WavesSettings}
import com.wavesplatform.state.{Blockchain, LeaseBalance, NG, Portfolio, StateHash}
import com.wavesplatform.state.{Blockchain, Height, LeaseBalance, NG, Portfolio, StateHash}
import com.wavesplatform.state.diffs.TransactionDiffer
import com.wavesplatform.state.reader.CompositeBlockchain
import com.wavesplatform.transaction._
import com.wavesplatform.transaction.Asset.IssuedAsset
import com.wavesplatform.transaction.TxValidationError.{GenericError, InvalidRequestSignature}
import com.wavesplatform.transaction.smart.script.trace.TracedResult
import com.wavesplatform.transaction.smart.script.trace.{InvokeScriptTrace, TracedResult}
import com.wavesplatform.transaction.smart.InvokeScriptTransaction
import com.wavesplatform.utils.{ScorexLogging, Time}
import com.wavesplatform.utx.UtxPool
import com.wavesplatform.wallet.Wallet
Expand Down Expand Up @@ -241,18 +243,36 @@ case class DebugApiRoute(
case Left(err) => Some(err)
}

val transactionJson = parsedTransaction match {
case Right(tx) => tx.json()
case Left(_) => jsv
}
val transactionJson = parsedTransaction.fold(_ => jsv, _.json())

val serializer = tracedDiff.resultE
.fold(_ => this.serializer, { case (_, diff) =>
val compositeBlockchain = CompositeBlockchain(blockchain, diff)
this.serializer.copy(blockchain = compositeBlockchain)
})

val extendedJson = tracedDiff.resultE
.fold(_ => jsv, { case (tx, diff) =>
val meta = tx match {
case ist: InvokeScriptTransaction =>
val result = diff.scriptResults.get(ist.id())
TransactionMeta.Invoke(Height(blockchain.height), ist, succeeded = true, result)
case tx => TransactionMeta.Default(Height(blockchain.height), tx, succeeded = true)
}
serializer.transactionWithMetaJson(meta)
})

val response = Json.obj(
"valid" -> error.isEmpty,
"validationTime" -> (System.nanoTime() - startTime).nanos.toMillis,
"trace" -> tracedDiff.trace.map(_.loggedJson)
"trace" -> tracedDiff.trace.map {
case ist: InvokeScriptTrace => ist.maybeLoggedJson(logged = true)(serializer.invokeScriptResultWrites)
case trace => trace.loggedJson
},
"height" -> blockchain.height
)

error.fold(response ++ transactionJson)(
error.fold(response ++ extendedJson)(
err => response + ("error" -> JsString(ApiError.fromValidationError(err).message)) + ("transaction" -> transactionJson)
)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.wavesplatform.features.BlockchainFeatures
import com.wavesplatform.network.TransactionPublisher
import com.wavesplatform.settings.RestAPISettings
import com.wavesplatform.state.{Blockchain, InvokeScriptResult}
import com.wavesplatform.state.reader.LeaseDetails
import com.wavesplatform.transaction._
import com.wavesplatform.transaction.lease._
import com.wavesplatform.utils.Time
Expand Down Expand Up @@ -230,7 +231,7 @@ object TransactionsApiRoute {

//noinspection TypeAnnotation
object LeaseStatus extends Enumeration {
val active = Value(1)
val active = Value(1)
val canceled = Value(0)

def apply(bool: Boolean): LeaseStatus = if (bool) active else canceled
Expand Down Expand Up @@ -322,7 +323,14 @@ object TransactionsApiRoute {
val ld = blockchain.leaseDetails(leaseId).get
val (height, _) = blockchain.transactionMeta(ld.sourceId).get
val recipient = blockchain.resolveAlias(ld.recipient).explicitGet()
LeaseRef(leaseId, ld.sourceId, ld.sender.toAddress, recipient, ld.amount, height, LeaseStatus(ld.isActive))

val (status, cancelHeight, cancelTxId) = ld.status match {
case LeaseDetails.Status.Active => (true, None, None)
case LeaseDetails.Status.Cancelled(height, txId) => (false, Some(height), txId)
case LeaseDetails.Status.Expired(height) => (false, Some(height), None)
}

LeaseRef(leaseId, ld.sourceId, ld.sender.toAddress, recipient, ld.amount, height, LeaseStatus(status), cancelHeight, cancelTxId)
}

private[http] implicit val leaseWrites: OWrites[InvokeScriptResult.Lease] =
Expand All @@ -332,23 +340,35 @@ object TransactionsApiRoute {
LeaseRef.jsonWrites.contramap((l: InvokeScriptResult.LeaseCancel) => leaseIdToLeaseRef(l.id))

// To override nested InvokeScriptResult writes
private[http] implicit lazy val invocationWrites: OWrites[InvokeScriptResult.Invocation] = (i: InvokeScriptResult.Invocation) => Json.obj(
"dApp" -> i.dApp,
"call" -> i.call,
"payment" -> i.payments,
"stateChanges" -> invokeScriptResultWrites.writes(i.stateChanges)
)
private[http] implicit lazy val invocationWrites: OWrites[InvokeScriptResult.Invocation] = (i: InvokeScriptResult.Invocation) =>
Json.obj(
"dApp" -> i.dApp,
"call" -> i.call,
"payments" -> i.payments,
"stateChanges" -> invokeScriptResultWrites.writes(i.stateChanges)
)

private[http] implicit lazy val invokeScriptResultWrites: OWrites[InvokeScriptResult] = {
import InvokeScriptResult.{issueFormat, reissueFormat, burnFormat, sponsorFeeFormat}
Json.writes[InvokeScriptResult]
}
}

private[this] final case class LeaseRef(id: ByteStr, originTransactionId: ByteStr, sender: Address, recipient: Address, amount: TxAmount, height: Int, status: LeaseStatus = LeaseStatus.active)
private[this] final case class LeaseRef(
id: ByteStr,
originTransactionId: ByteStr,
sender: Address,
recipient: Address,
amount: TxAmount,
height: Int,
status: LeaseStatus = LeaseStatus.active,
cancelHeight: Option[Int] = None,
cancelTransactionId: Option[ByteStr] = None
)
private[this] object LeaseRef {
implicit val jsonWrites: OWrites[LeaseRef] = {
import com.wavesplatform.utils.byteStrFormat
implicit val config = JsonConfiguration(optionHandlers = OptionHandlers.WritesNull)
Json.writes[LeaseRef]
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ case class InvokeScriptTrace(
override lazy val json: JsObject = maybeLoggedJson(false)
override lazy val loggedJson: JsObject = maybeLoggedJson(true)

private[this] def maybeLoggedJson(logged: Boolean): JsObject = {
def maybeLoggedJson(logged: Boolean)(implicit invokeResultWrites: OWrites[InvokeScriptResult] = InvokeScriptResult.jsonFormat): JsObject = {
Json.obj(
"type" -> "dApp",
"id" -> dAppAddressOrAlias.stringRepr,
Expand All @@ -97,7 +97,7 @@ case class InvokeScriptTrace(
}

object TraceStep {
private[trace] def scriptResultJson(invokeId: ByteStr, v: ScriptResult): JsObject =
private[trace] def scriptResultJson(invokeId: ByteStr, v: ScriptResult)(implicit invokeResultWrites: OWrites[InvokeScriptResult]): JsObject =
Json.toJsObject(InvokeScriptResult.fromLangResult(invokeId, v))

private[trace] def maybeErrorJson(errorOpt: Option[ValidationError]): JsObject =
Expand Down
Loading

0 comments on commit 37f1b02

Please sign in to comment.