Skip to content

Commit

Permalink
Merge pull request #90 from spectrum-finance/remove-explorer-deps
Browse files Browse the repository at this point in the history
Remove explorer deps from bots
  • Loading branch information
oskin1 authored Nov 28, 2023
2 parents 018cee1 + c84af97 commit f1622a4
Show file tree
Hide file tree
Showing 24 changed files with 431 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import cats.Id
import cats.effect.{Blocker, Resource}
import fs2.kafka.RecordDeserializer
import fs2.kafka.serde._
import fs2.kafka.serde.ser._
import org.ergoplatform.ErgoAddressEncoder
import org.ergoplatform.common.EnvApp
import org.ergoplatform.common.streaming._
Expand Down Expand Up @@ -78,9 +79,9 @@ object App extends EnvApp[AppContext] {
Resource.eval(N2TV3.make[InitF, RunF](configs.exchange, configs.monetary, context))
implicit0(n2tInt: InterpreterV3[T2T_CFMM, RunF]) <-
Resource.eval(T2TV3.make[InitF, RunF](configs.exchange, configs.monetary, context))
implicit0(interpreter: CFMMInterpreter[CFMMType, RunF]) <-Resource.eval(CFMMInterpreter.make[InitF, RunF])
implicit0(execution: Execution[RunF]) <- Resource.eval(Execution.make[InitF, RunF])
executor <- Resource.eval(Executor.make[InitF, StreamF, RunF])
implicit0(interpreter: CFMMInterpreter[CFMMType, RunF]) <- Resource.eval(CFMMInterpreter.make[InitF, RunF])
implicit0(execution: Execution[RunF]) <- Resource.eval(Execution.make[InitF, RunF])
executor <- Resource.eval(Executor.make[InitF, StreamF, RunF])
} yield List(executor.run, networkContextUpdater.run) -> ctx

private def makeBackend(
Expand Down
13 changes: 8 additions & 5 deletions modules/dex-core/src/main/scala/fs2/kafka/serde.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ object serde {
Deserializer.lift(decoder.decode)
}

implicit def serializerViaCirceEncoder[F[_]: Sync, A: Encoder]: RecordSerializer[F, A] =
RecordSerializer.lift {
Serializer.lift { a =>
a.asJson.noSpacesSortKeys.getBytes(charset).pure
object ser {

implicit def serializerViaCirceEncoder[F[_]: Sync, A: Encoder]: RecordSerializer[F, A] =
RecordSerializer.lift {
Serializer.lift { a =>
a.asJson.noSpacesSortKeys.getBytes(charset).pure
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import derevo.cats.show
import derevo.circe.{decoder, encoder}
import derevo.derive
import doobie.{Get, Put}
import fs2.kafka.serde.{deserializerViaKafkaDecoder, serializerViaCirceEncoder}
import fs2.kafka.serde.deserializerViaKafkaDecoder
import fs2.kafka.serde.ser._
import fs2.kafka.{RecordDeserializer, RecordSerializer}
import io.estatico.newtype.macros.newtype
import org.ergoplatform.common.HexString
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import derevo.circe.{decoder, encoder}
import derevo.derive
import doobie.{Get, Put}
import fs2.kafka.serde._
import fs2.kafka.serde.ser._
import fs2.kafka.{RecordDeserializer, RecordSerializer}
import io.estatico.newtype.macros.newtype
import org.ergoplatform.ergo.BoxId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import io.circe.{Decoder, Encoder}
import io.estatico.newtype.ops._
import org.ergoplatform.dex.domain.PairId
import org.ergoplatform.dex.protocol.instances._
import fs2.kafka.serde.ser._
import org.ergoplatform.ergo.TokenId
import tofu.logging.{Loggable, _}

Expand Down Expand Up @@ -74,7 +75,7 @@ object Order {
io.circe.derivation.deriveDecoder[AnyOrder]

implicit def recordSerializer[F[_]: Sync]: RecordSerializer[F, AnyOrder] =
fs2.kafka.serde.serializerViaCirceEncoder
fs2.kafka.serde.ser.serializerViaCirceEncoder

implicit def recordDeserializer[F[_]: Sync]: RecordDeserializer[F, AnyOrder] =
fs2.kafka.serde.deserializerViaKafkaDecoder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ object Trade {
implicit def decoder: Decoder[AnyTrade] = io.circe.derivation.deriveDecoder

implicit def recordSerializer[F[_]: Sync]: RecordSerializer[F, AnyTrade] =
fs2.kafka.serde.serializerViaCirceEncoder
fs2.kafka.serde.ser.serializerViaCirceEncoder

implicit def recordDeserializer[F[_]: Sync]: RecordDeserializer[F, AnyTrade] =
fs2.kafka.serde.deserializerViaKafkaDecoder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package org.ergoplatform.dex.domain

import cats.effect.Sync
import doobie.{Get, Put}
import fs2.kafka.serde.{deserializerViaKafkaDecoder, serializerViaCirceEncoder}
import fs2.kafka.serde.{deserializerViaKafkaDecoder}
import fs2.kafka.serde.ser._
import fs2.kafka.{RecordDeserializer, RecordSerializer}
import io.circe.{Decoder, Encoder}
import io.estatico.newtype.macros.newtype
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import derevo.cats.show
import derevo.circe.{decoder, encoder}
import derevo.derive
import doobie.util.Write
import org.ergoplatform.ErgoBox
import org.ergoplatform.ergo.TokenId
import shapeless.Lazy
import tofu.logging.derivation.loggable
import org.ergoplatform.ergo.services.explorer.models.{BoxAsset => ExplorerBoxAsset}
import org.ergoplatform.ergo.services.node.models.{BoxAsset => NodeAsset}
import scorex.util.encode.Base16

@derive(show, encoder, decoder, loggable)
final case class BoxAsset(
Expand All @@ -19,6 +21,9 @@ final case class BoxAsset(
object BoxAsset {
implicit def write: Write[BoxAsset] = Lazy(implicitly[Write[BoxAsset]]).value

def fromErgo(id: ErgoBox.TokenId, amount: Long): BoxAsset =
BoxAsset(TokenId.fromStringUnsafe(Base16.encode(id)), amount)

def fromExplorer(a: ExplorerBoxAsset): BoxAsset =
BoxAsset(a.tokenId, a.amount)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import derevo.cats.show
import derevo.circe.{decoder, encoder}
import derevo.derive
import org.ergoplatform.ErgoBox
import org.ergoplatform.ErgoBox.NonMandatoryRegisterId
import org.ergoplatform.dex.domain.DexOperatorOutput
import org.ergoplatform.dex.protocol.ErgoTreeSerializer.default._
import org.ergoplatform.ergo.domain.sigma.renderEvaluatedValue
import org.ergoplatform.ergo.services.explorer.models.{Output => ExplorerOutput}
import org.ergoplatform.ergo.services.node.models.{Output => NodeOutput}
import org.ergoplatform.ergo.state.{Predicted, Traced}
import org.ergoplatform.ergo.{BoxId, SErgoTree, TokenId, TxId}
import scorex.crypto.authds.ADKey
import org.ergoplatform.ergo.{BoxId, SErgoTree, TxId}
import scorex.util.ModifierId
import scorex.util.encode.Base16
import sigmastate.SType
import sigmastate.Values.EvaluatedValue
import tofu.logging.derivation.loggable

@derive(show, encoder, decoder, loggable)
Expand All @@ -27,6 +30,7 @@ final case class Output(
)

object Output {

def predicted(output: Output, prevBoxId: BoxId): Traced[Predicted[DexOperatorOutput]] =
Traced(Predicted(DexOperatorOutput(output)), prevBoxId)

Expand Down Expand Up @@ -54,17 +58,25 @@ object Output {
Map.empty // todo
)

def fromErgoBox(b: ErgoBox): Output = {
val bId = ADKey !@@ b.id
def fromErgoBox(box: ErgoBox): Output =
Output(
BoxId(Base16.encode(bId)),
TxId(ModifierId !@@ b.transactionId),
b.value,
b.index,
b.creationHeight,
SErgoTree.fromBytes(b.ergoTree.bytes),
b.additionalTokens.toMap.map { case (id, l) => BoxAsset(TokenId.fromBytes(id), l) }.toList,
Map.empty
BoxId.fromErgo(box.id),
TxId(ModifierId !@@ box.transactionId),
box.value,
box.index,
box.creationHeight,
serialize(box.ergoTree),
box.additionalTokens.toArray.toList.map { case (id, amount) => BoxAsset.fromErgo(id, amount) },
parseRegisters(box.additionalRegisters)
)
}

private def parseRegisters(
additionalRegisters: Map[NonMandatoryRegisterId, EvaluatedValue[SType]]
): Map[RegisterId, SConstant] =
additionalRegisters.flatMap { case (k, v) =>
for {
register <- RegisterId.withNameOption(s"R${k.number}")
sConstant <- renderEvaluatedValue(v).map { case (t, eval) => SConstant.fromRenderValue(t, eval) }
} yield (register, sConstant)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,85 @@ package org.ergoplatform.ergo.domain
import derevo.cats.show
import derevo.circe.encoder
import derevo.derive
import io.circe.Decoder
import io.circe.{Decoder, Encoder, Json}
import org.ergoplatform.common.HexString
import org.ergoplatform.ergo.PubKey
import org.ergoplatform.ergo.domain.SigmaType.SimpleKindSigmaType._
import org.ergoplatform.ergo.domain.SigmaType._
import tofu.logging.derivation.loggable
import io.circe.syntax._

@derive(show, encoder, loggable)
@derive(show, loggable)
sealed trait SConstant

object SConstant {

@derive(show, encoder, loggable)
@derive(loggable, show)
final case class IntConstant(value: Int) extends SConstant

@derive(show, encoder, loggable)
@derive(loggable, show)
final case class LongConstant(value: Long) extends SConstant

@derive(show, encoder, loggable)
@derive(loggable, show)
final case class ByteaConstant(value: HexString) extends SConstant

@derive(show, encoder, loggable)
@derive(loggable, show)
final case class SigmaPropConstant(value: PubKey) extends SConstant

@derive(show, encoder, loggable)
@derive(loggable, show)
final case class UnresolvedConstant(raw: String) extends SConstant

implicit val decoder: Decoder[SConstant] = { c =>
@derive(loggable, show)
final case class IntsConstant(value: List[Int]) extends SConstant

implicit val encoderSConstant: Encoder[SConstant] = { c =>
val (renderedValue, sigmaType: SigmaType) = c match {
case IntConstant(value) => value.toString -> SInt
case LongConstant(value) => value.toString -> SLong
case ByteaConstant(value) => value.value.value -> SCollection(SByte)
case IntsConstant(value) => "[" ++ value.mkString(",") ++ "]" -> SCollection(SInt)
case SigmaPropConstant(value) => value.value.value.value -> SSigmaProp
case UnresolvedConstant(raw) => raw -> SAny
}
Json.obj("renderedValue" -> Json.fromString(renderedValue), "sigmaType" -> sigmaType.asJson)
}

implicit val decoderSConstant: Decoder[SConstant] = { c =>
c.downField("renderedValue").as[String].flatMap { value =>
c.downField("sigmaType").as[SigmaType].map {
case SInt => IntConstant(value.toInt)
case SLong => LongConstant(value.toLong)
case SSigmaProp => SigmaPropConstant(PubKey.unsafeFromString(value))
case SCollection(SByte) => ByteaConstant(HexString.unsafeFromString(value))
case SCollection(SInt) => parseSInt(value)
case _ => UnresolvedConstant(value)
}
}
}

def fromRenderValue(sType: SigmaType, value: String): SConstant =
sType match {
case SInt => IntConstant(value.toInt)
case SLong => LongConstant(value.toLong)
case SSigmaProp => SigmaPropConstant(PubKey.unsafeFromString(value))
case SCollection(SByte) => ByteaConstant(HexString.unsafeFromString(value))
case SCollection(SInt) => parseSInt(value)
case _ => UnresolvedConstant(value)
}

def parseSInt(value: String): IntsConstant = {
val split = value.split(",")
if (split.length == 1) {
val splitHeadTail = split.headOption.map(_.drop(1).dropRight(1)).getOrElse("")
if (splitHeadTail.isEmpty) IntsConstant(List.empty)
else IntsConstant(List(splitHeadTail).map(_.toInt))
} else {
val splitHead = split.headOption.map(_.drop(1)).getOrElse("")
val splitTail = split.lastOption.map(_.dropRight(1)).getOrElse("")
val splitList = split.drop(1).dropRight(1).toList
val splitTotal = (splitHead :: splitList) :+ splitTail
IntsConstant(splitTotal.map(_.toInt))
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.ergoplatform.ergo.domain

import cats.Eval
import cats.data.OptionT
import cats.syntax.traverse._
import scorex.util.encode.Base16
import sigmastate.Values.{Constant, ConstantNode, EvaluatedValue, SigmaPropConstant}
import sigmastate._
import sigmastate.basics.DLogProtocol.ProveDlogProp

object sigma {

@inline def renderEvaluatedValue[T <: SType](ev: EvaluatedValue[T]): Option[(SigmaType, String)] = {
def goRender[T0 <: SType](ev0: EvaluatedValue[T0]): OptionT[Eval, (SigmaType, String)] =
ev0.tpe match {
case SSigmaProp | SGroupElement =>
ev0 match {
case SigmaPropConstant(ProveDlogProp(dlog)) =>
OptionT.some(SigmaType.SimpleKindSigmaType.SSigmaProp -> Base16.encode(dlog.pkBytes))
case ConstantNode(groupElem, SGroupElement) =>
OptionT.some(
SigmaType.SimpleKindSigmaType.SGroupElement ->
Base16.encode(groupElem.asInstanceOf[SGroupElement.WrappedType].getEncoded.toArray)
)
case _ => OptionT.none
}
case prim: SPrimType =>
val typeTerm = prim.toString.replaceAll("\\$", "")
OptionT.fromOption[Eval](SigmaType.parse(typeTerm)).map(_ -> ev0.value.toString)
case tuple: STuple =>
val typeTerm = tuple.toString.replaceAll("\\$", "")
OptionT.fromOption[Eval](SigmaType.parse(typeTerm)).flatMap { tp =>
val untypedElems = ev0.value match {
case (a, b) => List(a, b)
case _ => ev0.value.asInstanceOf[tuple.WrappedType].toArray.toList
}
val elems =
untypedElems.zip(tuple.items).map { case (vl, tp) =>
Constant[SType](vl.asInstanceOf[tp.WrappedType], tp)
}
elems.traverse(e => goRender(e).map(_._2)).map { xs =>
tp -> ("[" + xs.mkString(",") + "]")
}
}
case SCollectionType(SByte) =>
OptionT.some(
SigmaType.SCollection(SigmaType.SimpleKindSigmaType.SByte) ->
Base16.encode(ev0.value.asInstanceOf[SCollection[SByte.type]#WrappedType].toArray)
)
case coll: SCollection[_] =>
val typeTerm = coll.toString.replaceAll("\\$", "")
OptionT.fromOption[Eval](SigmaType.parse(typeTerm)).flatMap { tp =>
val elems = ev0.value.asInstanceOf[coll.WrappedType].toArray.toList.map(Constant(_, coll.elemType))
elems.traverse(e => goRender(e).map(_._2)).map { xs =>
tp -> ("[" + xs.mkString(",") + "]")
}
}
case option: SOption[_] =>
OptionT.fromOption[Eval](SigmaType.parse(option.toTermString)).flatMap { tp =>
val elem = ev0.value.asInstanceOf[option.WrappedType].map(Constant(_, option.elemType))
elem match {
case Some(value) => OptionT(Eval.defer(goRender(value).value)).map(r => tp -> r._2)
case None => OptionT.some(tp -> "null")
}
}
case _ => OptionT.none
}

goRender(ev).value.value
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import cats.effect.{Blocker, Clock, Resource}
import fs2.Chunk
import fs2.kafka.RecordDeserializer
import fs2.kafka.serde._
import fs2.kafka.serde.ser._
import org.ergoplatform.ErgoAddressEncoder
import org.ergoplatform.common.EnvApp
import org.ergoplatform.common.cache.{MakeRedisTransaction, Redis}
Expand Down
8 changes: 8 additions & 0 deletions modules/utxo-tracker/src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,11 @@ network.explorer-uri = "https://api.ergoplatform.com"
network.node-uri = "http://localhost:9053"

redis.uri = "redis://redis:6379"

mempool-tx-consumer.group-id = "ergo-mempool"
mempool-tx-consumer.client-id = "ergo-mempool-1"
mempool-tx-consumer.topic-id = "dex.amm.cfmm.mempool.events"

ledger-tx-consumer.group-id = "ergo-ledger"
ledger-tx-consumer.client-id = "ergo-ledger-1"
ledger-tx-consumer.topic-id = "dex.amm.cfmm.ledger.events"
Loading

0 comments on commit f1622a4

Please sign in to comment.