Skip to content

Commit

Permalink
Merge branch 'master' into i248-yaml-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vovapolu committed Oct 15, 2018
2 parents 03a86ca + 9d66a1f commit 096f87f
Show file tree
Hide file tree
Showing 149 changed files with 2,385 additions and 2,149 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Network node is build on top of [Tendermint](http://tendermint.com/), is written
* [Standard Library](doc/ref/vm/stdlib.md)
* [Meta information](doc/ref/vm/meta.md)
* [DApp API specification](doc/dapp-api.md)
* [Node API specification](doc/node-api.md)
* [Dotnet](doc/ref/dotnet)
* [Dotnet translation](doc/ref/dotnet/translation.md)
* [Dotnet classes translation](doc/ref/dotnet/classes-translation.md)
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ lazy val node = (project in file("node"))
"com.expload" %% "scala-abci-server" % "0.9.2",
"com.github.pureconfig" %% "pureconfig" % "0.9.1",
// Marshalling
"com.tethys-json" %% "tethys" % "0.6.2",
"com.tethys-json" %% "tethys" % "0.7.0.2",
"org.json4s" %% "json4s-ast" % "3.5.3",
"io.suzaku" %% "boopickle" % "1.2.6",
"com.lightbend.akka" %% "akka-stream-alpakka-unix-domain-socket" % "0.17",
Expand Down
31 changes: 16 additions & 15 deletions cli/src/main/scala/pravda/cli/PravdaArgsParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,11 @@ object PravdaArgsParser extends CommandLine[PravdaConfig] {
.text("Compile Pravda programs.")
.action(_ => PravdaConfig.Compile(CompileMode.Nope))
.children(
opt[File]('i', "input")
opt[Seq[File]]('i', "input")
.text("Input file")
.action {
case (file, config: PravdaConfig.Compile) =>
config.copy(input = Some(file.getAbsolutePath))
case (files, config: PravdaConfig.Compile) =>
config.copy(input = files.map(_.getAbsolutePath).toList)
case (_, otherwise) => otherwise
},
opt[File]('o', "output")
Expand Down Expand Up @@ -151,17 +151,11 @@ object PravdaArgsParser extends CommandLine[PravdaConfig] {
"By default read from stdin and print to stdout")
.action(_ => PravdaConfig.Compile(PravdaConfig.CompileMode.DotNet))
.children(
opt[Unit]("visualize")
.text("Visualize translation. Prints asm commands along with source CIL opcodes.")
.action {
case ((), config: PravdaConfig.Compile) =>
config.copy(compiler = PravdaConfig.CompileMode.DotNetVisualize)
},
opt[File]("pdb")
.text("Pdb file with debug information obtained from .NET compilation.")
opt[String]("main-class")
.text("Full name of class that should be compile to Pravda program")
.action {
case (file, config: PravdaConfig.Compile) =>
config.copy(pdb = Some(file.getAbsolutePath))
case (s, config: PravdaConfig.Compile) =>
config.copy(mainClass = Some(s))
case (_, otherwise) => otherwise
}
)
Expand All @@ -181,15 +175,15 @@ object PravdaArgsParser extends CommandLine[PravdaConfig] {
.action {
case (hex,
config @ PravdaConfig
.Broadcast(mode: PravdaConfig.Broadcast.Mode.Transfer, _, _, _, _, _, _)) =>
.Broadcast(mode: PravdaConfig.Broadcast.Mode.Transfer, _, _, _, _, _, _, _)) =>
config.copy(mode = mode.copy(to = Some(hex)))
case (_, otherwise) => otherwise
},
opt[Long]('a', "amount")
.action {
case (amount,
config @ PravdaConfig
.Broadcast(mode: PravdaConfig.Broadcast.Mode.Transfer, _, _, _, _, _, _)) =>
.Broadcast(mode: PravdaConfig.Broadcast.Mode.Transfer, _, _, _, _, _, _, _)) =>
config.copy(mode = mode.copy(amount = Some(amount)))
case (_, otherwise) => otherwise
}
Expand Down Expand Up @@ -237,6 +231,13 @@ object PravdaArgsParser extends CommandLine[PravdaConfig] {
config.copy(wallet = Some(file.getAbsolutePath))
case (_, otherwise) => otherwise
},
opt[File]("watt-payer-wallet")
.text("File with watt payer wallet. Format same as for wallet.")
.action {
case (file, config: PravdaConfig.Broadcast) =>
config.copy(wattPayerWallet = Some(file.getAbsolutePath))
case (_, otherwise) => otherwise
},
opt[Long]('l', "limit")
.text(s"Watt limit (${DefaultValues.Broadcast.WATT_LIMIT} by default).") // FIXME what to do with default values?
.action {
Expand Down
16 changes: 8 additions & 8 deletions cli/src/main/scala/pravda/cli/PravdaConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,10 @@ object PravdaConfig {
sealed trait CompileMode

object CompileMode {
case object Nope extends CompileMode
case object Asm extends CompileMode
case object Disasm extends CompileMode
case object DotNet extends CompileMode
case object DotNetVisualize extends CompileMode
case object Nope extends CompileMode
case object Asm extends CompileMode
case object Disasm extends CompileMode
case object DotNet extends CompileMode
}

case object Nope extends PravdaConfig
Expand All @@ -42,14 +41,15 @@ object PravdaConfig {
object Broadcast {
val WATT_LIMIT = 300L
val WATT_PRICE = NativeCoin.amount(1)
val ENDPOINT = "http://localhost:8080/api/public/broadcast"
val ENDPOINT = "http://localhost:8080/api/public"
}
}

final case class GenAddress(output: Option[String] = None) extends PravdaConfig

final case class Broadcast(mode: Broadcast.Mode = Broadcast.Mode.Nope,
wallet: Option[String] = None,
wattPayerWallet: Option[String] = None,
input: Option[String] = None,
dryRun: Boolean = false,
wattLimit: Long = DefaultValues.Broadcast.WATT_LIMIT,
Expand All @@ -72,9 +72,9 @@ object PravdaConfig {
}

final case class Compile(compiler: CompileMode,
input: Option[String] = None,
input: List[String] = List.empty,
output: Option[String] = None,
pdb: Option[String] = None)
mainClass: Option[String] = None)
extends PravdaConfig

final case class RunBytecode(storage: Option[String] = None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,5 @@ trait CompilersLanguage[F[_]] {
def asm(fileName: String, source: String): F[Either[String, ByteString]]
def asm(source: String): F[Either[String, ByteString]]
def disasm(source: ByteString): F[String]
def dotnet(source: ByteString, pdb: Option[ByteString]): F[Either[String, ByteString]]
def dotnetVisualize(source: ByteString, pdb: Option[ByteString]): F[Either[String, (ByteString, String)]]
def dotnet(sources: Seq[(ByteString, Option[ByteString])], mainClass: Option[String]): F[Either[String, ByteString]]
}
4 changes: 4 additions & 0 deletions cli/src/main/scala/pravda/cli/languages/IoLanguage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ trait IoLanguage[F[_]] {
def mkdirs(path: String): F[Unit]
def pwd(): F[String]
def isDirectory(path: String): F[Option[Boolean]]
def isFile(path: String): F[Option[Boolean]]
def listFiles(dir: String): F[List[String]]
def listDirs(dir: String): F[List[String]]
def absolutePath(path: String): F[Option[String]]
def createTmpDir(): F[String]
def readFromStdin(): F[ByteString]
def concatPath(parent: String, child: String): F[String]
Expand Down
5 changes: 3 additions & 2 deletions cli/src/main/scala/pravda/cli/languages/NodeLanguage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
package pravda.cli.languages

import com.google.protobuf.ByteString
import pravda.common.domain.NativeCoin
import pravda.common.domain.{Address, NativeCoin}

import scala.language.higherKinds

Expand All @@ -29,8 +29,9 @@ trait NodeLanguage[F[_]] {
def singAndBroadcastTransaction(uriPrefix: String,
address: ByteString,
privateKey: ByteString,
wattPayerPrivateKey: Option[ByteString],
wattLimit: Long,
wattPrice: NativeCoin,
dryRun: Boolean,
wattPayer: Option[Address],
data: ByteString): F[Either[String, String]]
}
5 changes: 1 addition & 4 deletions cli/src/main/scala/pravda/cli/languages/VmLanguage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,5 @@ import scala.language.higherKinds

trait VmLanguage[F[_]] {

def run(program: ByteString,
executor: ByteString,
storagePath: String,
wattLimit: Long): F[Either[String, ExecutionResult]]
def run(program: ByteString, executor: ByteString, storagePath: String, wattLimit: Long): F[ExecutionResult]
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,10 @@ package pravda.cli.languages
package impl

import com.google.protobuf.ByteString
import pravda.dotnet.parser.{FileParser => DotnetParser}
import pravda.dotnet.translation.{Translator => DotnetTranslator, TranslationVisualizer => DotnetVisualizer}
import pravda.dotnet.parser.FileParser
import pravda.dotnet.translation.{Translator => DotnetTranslator}
import pravda.vm.asm.PravdaAssembler

import cats.instances.either._
import cats.instances.option._
import cats.syntax.traverse._
import cats.implicits._

import scala.concurrent.{ExecutionContext, Future}

Expand All @@ -41,27 +38,19 @@ final class CompilersLanguageImpl(implicit executionContext: ExecutionContext) e
}

def disasm(source: ByteString): Future[String] = Future {
PravdaAssembler.render(PravdaAssembler.disassemble(source))
PravdaAssembler.render(PravdaAssembler.disassemble(source).map(_._2))
}

def dotnet(source: ByteString, pdb: Option[ByteString]): Future[Either[String, ByteString]] = Future {
def dotnet(sources: Seq[(ByteString, Option[ByteString])],
mainClass: Option[String]): Future[Either[String, ByteString]] = Future {
for {
pe <- DotnetParser.parsePe(source.toByteArray)
pdb <- pdb.map(p => DotnetParser.parsePdb(p.toByteArray).map(_._2)).sequence
(_, cilData, methods, signatures) = pe
ops <- DotnetTranslator.translateAsm(methods, cilData, signatures, pdb).left.map(_.mkString)
files <- sources
.map {
case (pe, pdb) => FileParser.parseDotnetFile(pe.toByteArray, pdb.map(_.toByteArray))
}
.toList
.sequence
ops <- DotnetTranslator.translateAsm(files, mainClass).left.map(_.mkString)
} yield PravdaAssembler.assemble(ops, saveLabels = true)
}

def dotnetVisualize(source: ByteString, pdb: Option[ByteString]): Future[Either[String, (ByteString, String)]] =
Future {
for {
pe <- DotnetParser.parsePe(source.toByteArray)
pdb <- pdb.map(p => DotnetParser.parsePdb(p.toByteArray).map(_._2)).sequence
(_, cilData, methods, signatures) = pe
translation <- DotnetTranslator.translateVerbose(methods, cilData, signatures, pdb).left.map(_.mkString)
asm = DotnetTranslator.translationToAsm(translation)
code = PravdaAssembler.assemble(asm, saveLabels = true)
} yield (code, DotnetVisualizer.visualize(translation))
}
}
30 changes: 30 additions & 0 deletions cli/src/main/scala/pravda/cli/languages/impl/IoLanguageImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ class IoLanguageImpl(implicit executionContext: ExecutionContext) extends IoLang
else None
}

def isFile(path: String): Future[Option[Boolean]] = Future {
val file = new File(path)
if (file.exists()) Some(file.isFile)
else None
}

def concatPath(parent: String, child: String): Future[String] = Future {
new File(new File(parent), child).getAbsolutePath
}
Expand Down Expand Up @@ -96,4 +102,28 @@ class IoLanguageImpl(implicit executionContext: ExecutionContext) extends IoLang
def exit(code: Int): Future[Unit] = Future {
sys.exit(code)
}

def listFiles(dir: String): Future[List[String]] = Future {
val file = new File(dir)
if (file.exists && file.isDirectory) {
file.listFiles().toList.filter(_.isFile).map(_.getAbsolutePath)
} else {
List.empty
}
}

def listDirs(dir: String): Future[List[String]] = Future {
val file = new File(dir)
if (file.exists && file.isDirectory) {
file.listFiles().toList.filter(_.isDirectory).map(_.getAbsolutePath)
} else {
List.empty
}
}

def absolutePath(path: String): Future[Option[String]] = Future {
val file = new File(path)
if (file.exists()) Some(file.getAbsolutePath)
else None
}
}
30 changes: 18 additions & 12 deletions cli/src/main/scala/pravda/cli/languages/impl/NodeLanguageImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,14 @@ final class NodeLanguageImpl(implicit system: ActorSystem,
def singAndBroadcastTransaction(uriPrefix: String,
address: ByteString,
privateKey: ByteString,
wattPayerPrivateKey: Option[ByteString],
wattLimit: Long,
wattPrice: NativeCoin,
dryRun: Boolean,
wattPayer: Option[Address],
data: ByteString): Future[Either[String, String]] = {

val fromHex = bytes.byteString2hex(address)
val request = if (dryRun) {
HttpRequest(
method = HttpMethods.POST,
uri = s"$uriPrefix/dryRun?from=$fromHex",
entity = HttpEntity(data.toByteArray)
)
} else {
val request = {
val tx = UnsignedTransaction(
from = Address @@ address,
program = TransactionData @@ data,
Expand All @@ -71,13 +66,24 @@ final class NodeLanguageImpl(implicit system: ActorSystem,
nonce = Random.nextInt()
)

val stx = cryptography.signTransaction(PrivateKey @@ privateKey, tx)
val signatureHex = bytes.byteString2hex(stx.signature)
val stx = {
val one = cryptography.signTransaction(PrivateKey @@ privateKey, tx)
wattPayerPrivateKey match {
case Some(pk) => cryptography.addWattPayerSignature(PrivateKey @@ pk, one.copy(wattPayer = wattPayer))
case None => one
}
}

HttpRequest(
method = HttpMethods.POST,
uri =
s"$uriPrefix?from=$fromHex&signature=$signatureHex&nonce=${tx.nonce}&wattLimit=${tx.wattLimit}&wattPrice=${tx.wattPrice}",
uri = uriPrefix +
s"?from=$fromHex" +
s"&signature=${bytes.byteString2hex(stx.signature)}" +
s"&nonce=${tx.nonce}" +
s"&wattLimit=${tx.wattLimit}" +
s"&wattPrice=${tx.wattPrice}" +
wattPayer.fold("")(wp => s"&wattPayer=${bytes.byteString2hex(wp)}") +
stx.wattPayerSignature.fold("")(s => s"&wattPayerSignature=${bytes.byteString2hex(s)}"),
entity = HttpEntity(data.toByteArray)
)
}
Expand Down
28 changes: 11 additions & 17 deletions cli/src/main/scala/pravda/cli/languages/impl/VmLanguageImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,21 @@ import pravda.node.data.common.TransactionId
import pravda.node.db.DB
import pravda.node.servers
import pravda.vm.ExecutionResult
import pravda.vm.impl.{MemoryImpl, VmImpl, WattCounterImpl}
import pravda.vm.impl.VmImpl

import scala.concurrent.{ExecutionContext, Future}

final class VmLanguageImpl(implicit executionContext: ExecutionContext) extends VmLanguage[Future] {

def run(program: ByteString,
executor: ByteString,
storagePath: String,
wattLimit: Long): Future[Either[String, ExecutionResult]] = Future {
def run(program: ByteString, executor: ByteString, storagePath: String, wattLimit: Long): Future[ExecutionResult] =
Future {

val executorAddress = Address @@ executor
val envProvider = new servers.Abci.BlockDependentEnvironment(DB(storagePath, None))
val env = envProvider.transactionEnvironment(executorAddress, TransactionId.forEncodedTransaction(program))
val vm = new VmImpl()
val memory = MemoryImpl.empty
val wattCounter = new WattCounterImpl(wattLimit)
val result = vm.spawn(program, env, memory, wattCounter, executorAddress)
envProvider.commit(0, Vector(executorAddress)) // TODO retrieve block height from db
result.error
.map(_.mkString)
.toLeft(result)
}
val executorAddress = Address @@ executor
val envProvider = new servers.Abci.BlockDependentEnvironment(DB(storagePath, None))
val env = envProvider.transactionEnvironment(executorAddress, TransactionId.forEncodedTransaction(program))
val vm = new VmImpl()
val result = vm.spawn(program, env, wattLimit)
envProvider.commit(0, Vector(executorAddress)) // TODO retrieve block height from db
result
}
}
Loading

0 comments on commit 096f87f

Please sign in to comment.